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 <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits