Re-enable composer empty body checking and draft save timer.

* src/client/composer/composer-web-view.vala (ClientWebView): Add a
  ::document_modified signal and a documentModified JS message listener,
  fire it when the JS message is receieved. Update value of ::is_empty
  based on whether a non-empty HTML body was provided in the first place,
  and if it has been subsequently modified. Update related doc comments a
  bit.

* src/client/composer/composer-widget.vala (ComposerWidget): Rename
  `blank` property to `is_blank`, fix sense of editor.is_blank check,
  update call sites. Convert ::can_save method into a property, include
  the this.is_blank check since there's no point saving a blank message,
  updtae call sites. Replace use of GLib.Timeout with
  Geary.TimeoutManager, tidy up resulting code, hook up timer to new
  document_modified signal.

* ui/composer-web-view.js: Use body mutation observer to send
  documentModified messages to the client, coalescing consecutive events
  over a period of 1s into a single message.
This commit is contained in:
Michael James Gratton 2017-01-06 10:48:40 +11:00
parent 8d479cf437
commit fcf5be297e
4 changed files with 92 additions and 80 deletions

View file

@ -38,8 +38,15 @@ ComposerPageState.prototype = {
}
}, true);
let modifiedId = null;
this.bodyObserver = new MutationObserver(function() {
state.checkCommandStack();
if (modifiedId == null) {
modifiedId = window.setTimeout(function() {
state.documentModified();
state.checkCommandStack();
modifiedId = null;
}, 1000);
}
});
},
loaded: function() {
@ -88,7 +95,13 @@ ComposerPageState.prototype = {
// Enable editing and observation machinery only after
// modifying the body above.
this.messageBody.contentEditable = true;
this.setBodyObserverEnabled(true);
let config = {
attributes: true,
childList: true,
characterData: true,
subtree: true
};
this.bodyObserver.observe(this.messageBody, config);
// Chain up here so we continue to a preferred size update
// after munging the HTML above.
@ -133,28 +146,10 @@ ComposerPageState.prototype = {
document.body.classList.add("plain");
}
},
setBodyObserverEnabled: function(enabled) {
if (enabled) {
let config = {
attributes: true,
childList: true,
characterData: true,
subtree: true
};
this.bodyObserver.observe(this.messageBody, config);
} else {
this.bodyObserver.disconnect();
}
},
checkCommandStack: function() {
let canUndo = document.queryCommandEnabled("undo");
let canRedo = document.queryCommandEnabled("redo");
// Update the body observer - if we can undo we don't need to
// keep an eye on mutations any more, until we can't undo
// again.
this.setBodyObserverEnabled(!canUndo);
if (canUndo != this.undoEnabled || canRedo != this.redoEnabled) {
this.undoEnabled = canUndo;
this.redoEnabled = canRedo;
@ -173,6 +168,9 @@ ComposerPageState.prototype = {
element.setAttribute("type", "cite");
}
},
documentModified: function(element) {
window.webkit.messageHandlers.documentModified.postMessage(null);
},
linkClicked: function(element) {
window.getSelection().selectAllChildren(element);
},