Esanders has uploaded a new change for review. https://gerrit.wikimedia.org/r/322598
Change subject: [BREAKING CHANGE] Allow target widgets to be re-used ...................................................................... [BREAKING CHANGE] Allow target widgets to be re-used * Introduce #setDocument that re-creates the surface but keeps the toolbar. * Make initial doc an optional config parameter. * Re-emit history event so user doesn't have to re-bind when surface is changed. This is a breaking change as it changes the constructor signature. Change-Id: I5ed0591048a17e84077bde5490e05c0467d0394a --- M src/init/ve.init.Target.js M src/ui/widgets/ve.ui.TargetWidget.js 2 files changed, 98 insertions(+), 31 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor refs/changes/98/322598/1 diff --git a/src/init/ve.init.Target.js b/src/init/ve.init.Target.js index 4db6b00..ccd20cf 100644 --- a/src/init/ve.init.Target.js +++ b/src/init/ve.init.Target.js @@ -348,12 +348,11 @@ * Create a target widget. * * @method - * @param {ve.dm.Document} dmDoc Document model * @param {Object} [config] Configuration options * @return {ve.ui.TargetWidget} */ -ve.init.Target.prototype.createTargetWidget = function ( dmDoc, config ) { - return new ve.ui.TargetWidget( dmDoc, config ); +ve.init.Target.prototype.createTargetWidget = function ( config ) { + return new ve.ui.TargetWidget( config ); }; /** diff --git a/src/ui/widgets/ve.ui.TargetWidget.js b/src/ui/widgets/ve.ui.TargetWidget.js index e2cd95d..2d846a0 100644 --- a/src/ui/widgets/ve.ui.TargetWidget.js +++ b/src/ui/widgets/ve.ui.TargetWidget.js @@ -7,20 +7,23 @@ /** * Creates an ve.ui.TargetWidget object. * + * User must call #initialize after the widget has been attached + * to the DOM, and also after the document is changed with #setDocument. + * * @class * @abstract * @extends OO.ui.Widget * * @constructor - * @param {ve.dm.Document} doc Document model * @param {Object} [config] Configuration options + * @cfg {ve.dm.Document} [doc] Initial document model * @cfg {Object[]} [tools] Toolbar configuration * @cfg {string[]|null} [includeCommands] List of commands to include, null for all registered commands * @cfg {string[]} [excludeCommands] List of commands to exclude * @cfg {Object} [importRules] Import rules * @cfg {string} [inDialog] The name of the dialog this surface widget is in */ -ve.ui.TargetWidget = function VeUiTargetWidget( doc, config ) { +ve.ui.TargetWidget = function VeUiTargetWidget( config ) { // Config initialization config = config || {}; @@ -32,30 +35,25 @@ this.sequenceRegistry = config.sequenceRegistry || ve.init.target.getSurface().sequenceRegistry; this.dataTransferHandlerFactory = config.dataTransferHandlerFactory || ve.init.target.getSurface().dataTransferHandlerFactory; // TODO: Override document/targetTriggerListener + this.tools = config.tools; + this.includeCommands = config.includeCommands; + this.excludeCommands = config.excludeCommands; + this.importRules = config.importRules; + this.inDialog = config.inDialog; - this.surface = ve.init.target.createSurface( doc, { - inTargetWidget: true, - commandRegistry: this.commandRegistry, - sequenceRegistry: this.sequenceRegistry, - dataTransferHandlerFactory: this.dataTransferHandlerFactory, - includeCommands: config.includeCommands, - excludeCommands: config.excludeCommands, - importRules: config.importRules, - inDialog: config.inDialog - } ); + this.surface = null; + this.toolbar = null; // TODO: Use a TargetToolbar when trigger listeners are set here - this.toolbar = new ve.ui.Toolbar(); + this.$surfaceContainer = $( '<div>' ).addClass( 've-ui-targetWidget-surface' ); + this.$toolbarContainer = $( '<div>' ).addClass( 've-ui-targetWidget-toolbar' ); + + if ( config.doc ) { + this.setDocument( config.doc ); + } // Initialization - this.surface.$element.addClass( 've-ui-targetWidget-surface' ); - this.toolbar.$element.addClass( 've-ui-targetWidget-toolbar' ); - this.toolbar.$bar.append( this.surface.getToolbarDialogs().$element ); - this.$element - .addClass( 've-ui-targetWidget' ) - .append( this.toolbar.$element, this.surface.$element ); - if ( config.tools ) { - this.toolbar.setup( config.tools, this.surface ); - } + this.$element.addClass( 've-ui-targetWidget' ) + .append( this.$toolbarContainer, this.$surfaceContainer ); }; /* Inheritance */ @@ -65,10 +63,75 @@ /* Methods */ /** + * The target's surface has been changed. + * + * @event change + */ + +/** + * Set the document to edit + * + * @param {ve.dm.Document} doc Document + */ +ve.ui.TargetWidget.prototype.setDocument = function ( doc ) { + // Destroy the previous surface + if ( this.surface ) { + this.surface.destroy(); + } + // Toolbars can be re-used + if ( !this.toolbar ) { + this.toolbar = new ve.ui.Toolbar(); + this.$toolbarContainer.append( this.toolbar.$element ); + } + this.surface = ve.init.target.createSurface( doc, { + inTargetWidget: true, + commandRegistry: this.commandRegistry, + sequenceRegistry: this.sequenceRegistry, + dataTransferHandlerFactory: this.dataTransferHandlerFactory, + includeCommands: this.includeCommands, + excludeCommands: this.excludeCommands, + importRules: this.importRules, + inDialog: this.inDialog + } ); + + // Events + this.getSurface().getModel().connect( this, { history: 'onSurfaceModelHistory' } ); + + // DOM changes + this.$surfaceContainer.append( this.surface.$element ); + this.toolbar.$bar.append( this.surface.getToolbarDialogs().$element ); + + // Setup toolbar with new surface + if ( this.tools ) { + this.toolbar.setup( this.tools, this.surface ); + } +}; + +/** + * Handle history events from the surface model. + * + * @fires change + */ +ve.ui.TargetWidget.prototype.onSurfaceModelHistory = function () { + // Rethrow this event so users don't have to re-bind to + // surface model 'history' when the surface is changed in #setDocument + this.emit( 'change' ); +}; + +/** + * Check if the surface has been modified. + * + * @return {boolean} The surface has been modified + */ +ve.ui.TargetWidget.prototype.hasBeenModified = function () { + return !!this.getSurface() && this.getSurface().getModel().hasBeenModified(); +}; + +/** * Get surface. * * @method - * @return {ve.ui.Surface} Surface + * @return {ve.ui.Surface|null} Surface */ ve.ui.TargetWidget.prototype.getSurface = function () { return this.surface; @@ -102,8 +165,10 @@ * @method */ ve.ui.TargetWidget.prototype.initialize = function () { - this.toolbar.initialize(); - this.surface.initialize(); + if ( this.surface ) { + this.toolbar.initialize(); + this.surface.initialize(); + } }; /** @@ -111,19 +176,22 @@ * * @method */ -ve.ui.TargetWidget.prototype.destroy = function () { +ve.ui.TargetWidget.prototype.clear = function () { if ( this.surface ) { this.surface.destroy(); + this.surface = null; } if ( this.toolbar ) { this.toolbar.destroy(); + this.toolbar = null; } - this.$element.remove(); }; /** * Focus the surface. */ ve.ui.TargetWidget.prototype.focus = function () { - this.surface.getView().focus(); + if ( this.surface ) { + this.surface.getView().focus(); + } }; -- To view, visit https://gerrit.wikimedia.org/r/322598 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I5ed0591048a17e84077bde5490e05c0467d0394a Gerrit-PatchSet: 1 Gerrit-Project: VisualEditor/VisualEditor Gerrit-Branch: master Gerrit-Owner: Esanders <esand...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits