Catrope has uploaded a new change for review.
https://gerrit.wikimedia.org/r/93920
Change subject: Guard against detached nodes in
ve.ce.GeneratedContentNode#doneGenerating
......................................................................
Guard against detached nodes in ve.ce.GeneratedContentNode#doneGenerating
The generation promise can get resolved (e.g. AJAX request can complete)
after the node has been detached. In that case accessing this.model.doc
will fail, so check for this in doneGenerating().
Also attempt to abort the pending promise on teardown.
Bug: 56649
Change-Id: Ia55f1c2c8dc3a3619c0b50795e50fcae4bc6471f
---
M modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js
1 file changed, 33 insertions(+), 16 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor
refs/changes/20/93920/1
diff --git a/modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js
b/modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js
index c2b7223..8d2a8a1 100644
--- a/modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js
+++ b/modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js
@@ -22,6 +22,7 @@
// Events
this.model.connect( this, { 'update': 'onGeneratedContentNodeUpdate' }
);
+ this.connect( this, { 'teardown': 'abortGenerating' } );
// Initialization
this.update();
@@ -181,19 +182,10 @@
*/
ve.ce.GeneratedContentNode.prototype.forceUpdate = function ( config ) {
var promise, node = this;
- if ( this.generatingPromise ) {
- // Abort the currently pending generation process if possible
- // Unset this.generatingPromise first so that if the promise is
resolved or rejected
- // when we abort, this is ignored as it should be
- promise = this.generatingPromise;
- this.generatingPromise = null;
- if ( $.isFunction( promise.abort ) ) {
- promise.abort();
- }
- } else {
- // Only call startGenerating() if we weren't generating before
- this.startGenerating();
- }
+
+ // Abort the currently pending generation process if possible
+ this.abortGenerating();
+ this.startGenerating();
// Create a new promise
promise = this.generatingPromise = this.generateContents( config );
@@ -225,6 +217,25 @@
};
/**
+ * Abort the currently pending generation, if any, and remove the generating
CSS class.
+ *
+ * This invokes .abort() on the pending promise if the promise has that
method. It also ensures
+ * that if the promise does get resolved or rejected later, this is ignored.
+ */
+ve.ce.GeneratedContentNode.prototype.abortGenerating = function () {
+ var promise = this.generatingPromise;
+ if ( promise ) {
+ // Unset this.generatingPromise first so that if the promise is
resolved or rejected
+ // from within .abort(), this is ignored as it should be
+ this.generatingPromise = null;
+ if ( $.isFunction( promise.abort ) ) {
+ promise.abort();
+ }
+ }
+ this.$element.removeClass( 've-ce-generatedContentNode-generating' );
+};
+
+/**
* Called when the node successfully finishes generating new content.
*
* @method
@@ -232,10 +243,16 @@
* @param {Object} [config] Config object passed to forceUpdate()
*/
ve.ce.GeneratedContentNode.prototype.doneGenerating = function (
generatedContents, config ) {
- var store = this.model.doc.getStore(),
- hash = OO.getHash( [ this.model, config ] );
+ var store, hash;
- store.index( generatedContents, hash );
+ // Because doneGenerating is invoked asynchronously, the model node may
have become detached
+ // in the meantime. Handle this gracefully.
+ if ( this.model.doc ) {
+ store = this.model.doc.getStore();
+ hash = OO.getHash( [ this.model, config ] );
+ store.index( generatedContents, hash );
+ }
+
this.$element.removeClass( 've-ce-generatedContentNode-generating' );
this.generatingPromise = null;
this.render( generatedContents );
--
To view, visit https://gerrit.wikimedia.org/r/93920
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia55f1c2c8dc3a3619c0b50795e50fcae4bc6471f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Catrope <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits