Przeglądaj źródła

show warning before unsaved exit

mizozobu 7 lat temu
rodzic
commit
5d57f98194

+ 23 - 3
src/client/js/components/PageEditor.js

@@ -38,6 +38,7 @@ export default class PageEditor extends React.Component {
     this.setCaretLine = this.setCaretLine.bind(this);
     this.focusToEditor = this.focusToEditor.bind(this);
     this.onMarkdownChanged = this.onMarkdownChanged.bind(this);
+    this.onSave = this.onSave.bind(this);
     this.onUpload = this.onUpload.bind(this);
     this.onEditorScroll = this.onEditorScroll.bind(this);
     this.onEditorScrollCursorIntoView = this.onEditorScrollCursorIntoView.bind(this);
@@ -45,6 +46,7 @@ export default class PageEditor extends React.Component {
     this.saveDraft = this.saveDraft.bind(this);
     this.clearDraft = this.clearDraft.bind(this);
     this.apiErrorHandler = this.apiErrorHandler.bind(this);
+    this.showUnsavedWarning = this.showUnsavedWarning.bind(this);
 
     // for scrolling
     this.lastScrolledDateWithCursor = null;
@@ -62,6 +64,20 @@ export default class PageEditor extends React.Component {
   componentWillMount() {
     // initial rendering
     this.renderPreview(this.state.markdown);
+
+    this.props.crowi.window.addEventListener('beforeunload', this.showUnsavedWarning);
+  }
+
+  componentWillUnmount() {
+    this.props.crowi.window.removeEventListener('beforeunload', this.showUnsavedWarning);
+  }
+
+  showUnsavedWarning(e) {
+    if (!this.props.crowi.getIsDocSaved()) {
+      // display browser default message
+      e.returnValue = '';
+      return '';
+    }
   }
 
   getMarkdown() {
@@ -111,6 +127,12 @@ export default class PageEditor extends React.Component {
   onMarkdownChanged(value) {
     this.renderPreviewWithDebounce(value);
     this.saveDraftWithDebounce();
+    this.props.crowi.setIsDocSaved(false);
+  }
+
+  onSave() {
+    this.props.onSaveWithShortcut(this.state.markdown);
+    this.props.crowi.setIsDocSaved(true);
   }
 
   /**
@@ -330,9 +352,7 @@ export default class PageEditor extends React.Component {
             onScrollCursorIntoView={this.onEditorScrollCursorIntoView}
             onChange={this.onMarkdownChanged}
             onUpload={this.onUpload}
-            onSave={() => {
-              this.props.onSaveWithShortcut(this.state.markdown);
-            }}
+            onSave={this.onSave}
           />
         </div>
         <div className="col-md-6 hidden-sm hidden-xs page-editor-preview-container">

+ 1 - 0
src/client/js/components/SavePageControls.jsx

@@ -47,6 +47,7 @@ class SavePageControls extends React.PureComponent {
   }
 
   submit() {
+    this.props.crowi.setIsDocSaved(true);
     this.props.onSubmit();
   }
 

+ 9 - 0
src/client/js/util/Crowi.js

@@ -30,6 +30,7 @@ export default class Crowi {
     this.socketClientId = Math.floor(Math.random() * 100000);
     this.page = undefined;
     this.pageEditor = undefined;
+    this.isDocSaved = true;
 
     this.fetchUsers = this.fetchUsers.bind(this);
     this.apiGet = this.apiGet.bind(this);
@@ -79,6 +80,14 @@ export default class Crowi {
     this.pageEditor = pageEditor;
   }
 
+  setIsDocSaved(isSaved) {
+    this.isDocSaved = isSaved;
+  }
+
+  getIsDocSaved() {
+    return this.isDocSaved;
+  }
+
   getWebSocket() {
     return this.socket;
   }