mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-12-01 17:36:35 +00:00
4ce69758cc
ce.GeneratedContentNode had an interesting bug where it called .append() directly on DOM elements stored in the store. They weren't cloned, which meant the previous rendering of the same node would just disappear, and they also weren't adopted into the correct document which would probably have caused other issues as well. Properly clone and transplant the nodes from the store before attaching them to the DOM. Change-Id: I423db85cb7c3851a9bf68de03c72aa22994d9474
95 lines
2.3 KiB
JavaScript
95 lines
2.3 KiB
JavaScript
/*!
|
|
* VisualEditor ContentEditable GeneratedContentNode class.
|
|
*
|
|
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
*/
|
|
|
|
/**
|
|
* ContentEditable generated content node.
|
|
*
|
|
* @class
|
|
* @abstract
|
|
*
|
|
* @constructor
|
|
*/
|
|
ve.ce.GeneratedContentNode = function VeCeGeneratedContentNode() {
|
|
// DOM Changes
|
|
this.$.addClass( 've-ce-generatedContentNode' );
|
|
this.$.attr( 'contenteditable', false );
|
|
|
|
// Events
|
|
this.model.connect( this, { 'update': 'onUpdate' } );
|
|
|
|
// Initialization
|
|
this.onUpdate();
|
|
};
|
|
|
|
/* Methods */
|
|
|
|
/**
|
|
* Handle update events.
|
|
*
|
|
* @method
|
|
*/
|
|
ve.ce.GeneratedContentNode.prototype.onUpdate = function () {
|
|
var doc = this.getElementDocument(),
|
|
store = this.model.doc.getStore(),
|
|
index = store.indexOfHash( ve.getHash( this.model ) );
|
|
if ( index !== null ) {
|
|
if ( this.live ) {
|
|
this.emit( 'teardown' );
|
|
}
|
|
this.$.empty().append(
|
|
this.$$( store.value( index ) ).map( function ( i, domElement ) {
|
|
return doc.importNode( domElement, true );
|
|
} )
|
|
);
|
|
if ( this.live ) {
|
|
this.emit( 'setup' );
|
|
}
|
|
} else {
|
|
this.startGenerating();
|
|
this.generateContents()
|
|
.done( ve.bind( this.doneGenerating, this ) )
|
|
.fail( ve.bind( this.failGenerating, this ) );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Start a deferred process to generate the contents of the node.
|
|
* @returns {jQuery.Promise} Promise object
|
|
*/
|
|
ve.ce.GeneratedContentNode.prototype.generateContents = function () {
|
|
throw new Error( 've.ce.GeneratedContentNode subclass must implement generateContents' );
|
|
};
|
|
|
|
/**
|
|
* Called when the node starts generating new content.
|
|
* @method
|
|
*/
|
|
ve.ce.GeneratedContentNode.prototype.startGenerating = function () {
|
|
// TODO: add 'generating' style
|
|
};
|
|
|
|
/**
|
|
* Called when the node successfully finishes generating new content.
|
|
*
|
|
* @method
|
|
* @param {HTMLElement[]} domElements Generated content
|
|
*/
|
|
ve.ce.GeneratedContentNode.prototype.doneGenerating = function ( domElements ) {
|
|
var store = this.model.doc.getStore(),
|
|
hash = ve.getHash( this.model );
|
|
store.index( domElements, hash );
|
|
// TODO: remove 'generating' style
|
|
this.onUpdate();
|
|
};
|
|
|
|
/**
|
|
* Called when the has failed to generate new content.
|
|
* @method
|
|
*/
|
|
ve.ce.GeneratedContentNode.prototype.failGenerating = function () {
|
|
// TODO: remove 'generating' style
|
|
}; |