Divec has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/405827 )
Change subject: Create ve.EventEmitter with emitCatch, and use it throughout ve.dm ...................................................................... Create ve.EventEmitter with emitCatch, and use it throughout ve.dm Bug: T185546 Change-Id: I3175a9e985d4ecffa282d9078352523bfbdf4982 --- M .jsduck/categories.json M build/modules.json M demos/ve/desktop.html M demos/ve/mobile.html M src/dm/nodes/ve.dm.TableNode.js M src/dm/nodes/ve.dm.TableRowNode.js M src/dm/nodes/ve.dm.TableSectionNode.js M src/dm/ve.dm.APIResultsProvider.js M src/dm/ve.dm.APIResultsQueue.js M src/dm/ve.dm.Document.js M src/dm/ve.dm.InternalList.js M src/dm/ve.dm.MetaItem.js M src/dm/ve.dm.MetaList.js M src/dm/ve.dm.Node.js M src/dm/ve.dm.Scalable.js M src/dm/ve.dm.Surface.js M src/dm/ve.dm.SurfaceSynchronizer.js M src/dm/ve.dm.TableMatrix.js M src/ve.Document.js A src/ve.EventEmitter.js M tests/index.html 21 files changed, 126 insertions(+), 81 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor refs/changes/27/405827/1 diff --git a/.jsduck/categories.json b/.jsduck/categories.json index a7b1fbe..bafa206 100644 --- a/.jsduck/categories.json +++ b/.jsduck/categories.json @@ -9,6 +9,7 @@ "ve.Range", "ve.PositionStep", "ve.SelectionState", + "ve.EventEmitter", "ve.EventSequencer", "ve.Filibuster", "ve.TriggerListener", diff --git a/build/modules.json b/build/modules.json index d808fa1..7ce11c2 100644 --- a/build/modules.json +++ b/build/modules.json @@ -249,6 +249,7 @@ }, "visualEditor.core.build": { "scripts": [ + "src/ve.EventEmitter.js", "src/ve.Range.js", "src/ve.SelectionState.js", "src/ve.Node.js", diff --git a/demos/ve/desktop.html b/demos/ve/desktop.html index f8dc64e..94cbd41 100644 --- a/demos/ve/desktop.html +++ b/demos/ve/desktop.html @@ -190,6 +190,7 @@ <script src="../../lib/oojs-ui/oojs-ui-apex.js"></script> <!-- visualEditor.core.build --> + <script src="../../src/ve.EventEmitter.js"></script> <script src="../../src/ve.Range.js"></script> <script src="../../src/ve.SelectionState.js"></script> <script src="../../src/ve.Node.js"></script> diff --git a/demos/ve/mobile.html b/demos/ve/mobile.html index b5e6346..88aa00d 100644 --- a/demos/ve/mobile.html +++ b/demos/ve/mobile.html @@ -190,6 +190,7 @@ <script src="../../lib/oojs-ui/oojs-ui-wikimediaui.js"></script> <!-- visualEditor.core.build --> + <script src="../../src/ve.EventEmitter.js"></script> <script src="../../src/ve.Range.js"></script> <script src="../../src/ve.SelectionState.js"></script> <script src="../../src/ve.Node.js"></script> diff --git a/src/dm/nodes/ve.dm.TableNode.js b/src/dm/nodes/ve.dm.TableNode.js index 64caa96..8a7ce63 100644 --- a/src/dm/nodes/ve.dm.TableNode.js +++ b/src/dm/nodes/ve.dm.TableNode.js @@ -65,7 +65,7 @@ * @fires cellAttributeChange */ ve.dm.TableNode.prototype.onCellAttributeChange = function ( cell ) { - this.emit( 'cellAttributeChange', cell ); + this.emitCatch( 'cellAttributeChange', cell ); }; /** @@ -113,14 +113,14 @@ * e.g., providing consecutive row indexes. * * @class - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * * @constructor * @param {ve.dm.TableNode} tableNode Table node to iterate through */ ve.dm.TableNodeCellIterator = function VeDmTableNodeCellIterator( tableNode ) { // Mixin constructors - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); this.table = tableNode; @@ -141,7 +141,7 @@ /* Inheritance */ -OO.mixinClass( ve.dm.TableNodeCellIterator, OO.EventEmitter ); +OO.mixinClass( ve.dm.TableNodeCellIterator, ve.EventEmitter ); /* Events */ @@ -200,7 +200,7 @@ if ( sectionNode instanceof ve.dm.TableSectionNode ) { this.sectionNode = sectionNode; this.rowCount = this.sectionNode.children.length; - this.emit( 'newSection', this.sectionNode ); + this.emitCatch( 'newSection', this.sectionNode ); } else { this.nextSection(); return; @@ -229,7 +229,7 @@ if ( rowNode instanceof ve.dm.TableRowNode ) { this.rowNode = rowNode; this.cellCount = this.rowNode.children.length; - this.emit( 'newRow', this.rowNode ); + this.emitCatch( 'newRow', this.rowNode ); } else { this.nextRow(); return; diff --git a/src/dm/nodes/ve.dm.TableRowNode.js b/src/dm/nodes/ve.dm.TableRowNode.js index 6245b3a..758f582 100644 --- a/src/dm/nodes/ve.dm.TableRowNode.js +++ b/src/dm/nodes/ve.dm.TableRowNode.js @@ -92,7 +92,7 @@ * @fires cellAttributeChange */ ve.dm.TableRowNode.prototype.onCellAttributeChange = function ( cell ) { - this.emit( 'cellAttributeChange', cell ); + this.emitCatch( 'cellAttributeChange', cell ); }; /* Registration */ diff --git a/src/dm/nodes/ve.dm.TableSectionNode.js b/src/dm/nodes/ve.dm.TableSectionNode.js index bedc0ee..88ce039 100644 --- a/src/dm/nodes/ve.dm.TableSectionNode.js +++ b/src/dm/nodes/ve.dm.TableSectionNode.js @@ -90,7 +90,7 @@ * @fires cellAttributeChange */ ve.dm.TableSectionNode.prototype.onCellAttributeChange = function ( cell ) { - this.emit( 'cellAttributeChange', cell ); + this.emitCatch( 'cellAttributeChange', cell ); }; /* Registration */ diff --git a/src/dm/ve.dm.APIResultsProvider.js b/src/dm/ve.dm.APIResultsProvider.js index aa882a4..95864c6 100644 --- a/src/dm/ve.dm.APIResultsProvider.js +++ b/src/dm/ve.dm.APIResultsProvider.js @@ -8,7 +8,7 @@ * API Results Provider object. * * @class - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * * @constructor * @param {string} apiurl The URL to the api @@ -38,11 +38,11 @@ this.toggleDepleted( false ); // Mixin constructors - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); }; /* Setup */ -OO.mixinClass( ve.dm.APIResultsProvider, OO.EventEmitter ); +OO.mixinClass( ve.dm.APIResultsProvider, ve.EventEmitter ); /* Methods */ diff --git a/src/dm/ve.dm.APIResultsQueue.js b/src/dm/ve.dm.APIResultsQueue.js index c3650e8..8b5684b 100644 --- a/src/dm/ve.dm.APIResultsQueue.js +++ b/src/dm/ve.dm.APIResultsQueue.js @@ -8,7 +8,7 @@ * API Results Queue object. * * @class - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * * @constructor * @param {Object} [config] Configuration options @@ -31,11 +31,11 @@ this.setThreshold( config.threshold || 10 ); // Mixin constructors - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); }; /* Setup */ -OO.mixinClass( ve.dm.APIResultsQueue, OO.EventEmitter ); +OO.mixinClass( ve.dm.APIResultsQueue, ve.EventEmitter ); /* Methods */ diff --git a/src/dm/ve.dm.Document.js b/src/dm/ve.dm.Document.js index d571bf9..8b16e41 100644 --- a/src/dm/ve.dm.Document.js +++ b/src/dm/ve.dm.Document.js @@ -311,11 +311,11 @@ if ( transaction.hasBeenApplied() ) { throw new Error( 'Cannot commit a transaction that has already been committed' ); } - this.emit( 'precommit', transaction ); + this.emitCatch( 'precommit', transaction ); new ve.dm.TransactionProcessor( this, transaction, isStaging ).process(); this.completeHistory.push( transaction ); this.storeLengthAtHistoryLength[ this.completeHistory.length ] = this.store.getLength(); - this.emit( 'transact', transaction ); + this.emitCatch( 'transact', transaction ); }; /** diff --git a/src/dm/ve.dm.InternalList.js b/src/dm/ve.dm.InternalList.js index 5534203..bce7e24 100644 --- a/src/dm/ve.dm.InternalList.js +++ b/src/dm/ve.dm.InternalList.js @@ -8,14 +8,14 @@ * DataModel meta item. * * @class - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * * @constructor * @param {ve.dm.Document} doc Document model */ ve.dm.InternalList = function VeDmInternalList( doc ) { // Mixin constructors - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); // Properties this.document = doc; @@ -35,7 +35,7 @@ /* Inheritance */ -OO.mixinClass( ve.dm.InternalList, OO.EventEmitter ); +OO.mixinClass( ve.dm.InternalList, ve.EventEmitter ); /* Events */ @@ -376,7 +376,7 @@ for ( i = 0; i < this.groupsChanged.length; i++ ) { this.sortGroupIndexes( this.nodes[ this.groupsChanged[ i ] ] ); } - this.emit( 'update', this.groupsChanged ); + this.emitCatch( 'update', this.groupsChanged ); this.groupsChanged = []; } }; diff --git a/src/dm/ve.dm.MetaItem.js b/src/dm/ve.dm.MetaItem.js index 1df631c..1be156c 100644 --- a/src/dm/ve.dm.MetaItem.js +++ b/src/dm/ve.dm.MetaItem.js @@ -11,7 +11,7 @@ * @class * @abstract * @extends ve.dm.LeafNode - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * * @constructor * @param {Object} element Reference to element in meta-linmod @@ -20,7 +20,7 @@ // Parent constructor ve.dm.MetaItem.super.apply( this, arguments ); // Mixin - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); // Properties this.list = null; }; @@ -29,7 +29,7 @@ OO.inheritClass( ve.dm.MetaItem, ve.dm.LeafNode ); -OO.mixinClass( ve.dm.MetaItem, OO.EventEmitter ); +OO.mixinClass( ve.dm.MetaItem, ve.EventEmitter ); /* Static members */ diff --git a/src/dm/ve.dm.MetaList.js b/src/dm/ve.dm.MetaList.js index d183c1e..98ca9d2 100644 --- a/src/dm/ve.dm.MetaList.js +++ b/src/dm/ve.dm.MetaList.js @@ -8,7 +8,7 @@ * DataModel meta item. * * @class - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * * @constructor * @param {ve.dm.Surface} surface Surface model @@ -18,7 +18,7 @@ metaList = this; // Mixin constructors - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); this.surface = surface; this.document = surface.getDocument(); @@ -42,7 +42,7 @@ /* Inheritance */ -OO.mixinClass( ve.dm.MetaList, OO.EventEmitter ); +OO.mixinClass( ve.dm.MetaList, ve.EventEmitter ); /* Events */ @@ -72,7 +72,7 @@ }, true ); this.items.splice( i, 0, node ); node.attachToMetaList( this ); - this.emit( 'insert', node ); + this.emitCatch( 'insert', node ); } }; @@ -88,7 +88,7 @@ if ( i !== -1 ) { node.detachFromMetaList( this ); this.items.splice( i, 1 ); - this.emit( 'remove', node ); + this.emitCatch( 'remove', node ); } } }; diff --git a/src/dm/ve.dm.Node.js b/src/dm/ve.dm.Node.js index 85d4fd5..bc1e45b 100644 --- a/src/dm/ve.dm.Node.js +++ b/src/dm/ve.dm.Node.js @@ -9,7 +9,7 @@ * * @abstract * @extends ve.dm.Model - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * @mixins ve.Node * * @constructor @@ -21,7 +21,7 @@ // Mixin constructors ve.Node.call( this ); - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); // Properties this.length = 0; @@ -44,7 +44,7 @@ OO.mixinClass( ve.dm.Node, ve.Node ); -OO.mixinClass( ve.dm.Node, OO.EventEmitter ); +OO.mixinClass( ve.dm.Node, ve.EventEmitter ); /* Static Properties */ @@ -616,8 +616,8 @@ this.parent.adjustLength( diff ); } // Emit events - this.emit( 'lengthChange', diff ); - this.emit( 'update' ); + this.emitCatch( 'lengthChange', diff ); + this.emitCatch( 'update' ); }; /** diff --git a/src/dm/ve.dm.Scalable.js b/src/dm/ve.dm.Scalable.js index 2a2ddde..ffbb243 100644 --- a/src/dm/ve.dm.Scalable.js +++ b/src/dm/ve.dm.Scalable.js @@ -8,7 +8,7 @@ * Scalable object. * * @class - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * * @constructor * @param {Object} [config] Configuration options @@ -30,7 +30,7 @@ }, config ); // Mixin constructors - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); // Computed properties this.ratio = null; @@ -71,7 +71,7 @@ /* Inheritance */ -OO.mixinClass( ve.dm.Scalable, OO.EventEmitter ); +OO.mixinClass( ve.dm.Scalable, ve.EventEmitter ); /* Events */ @@ -238,7 +238,7 @@ this.setRatioFromDimensions( this.getCurrentDimensions() ); } this.valid = null; - this.emit( 'currentSizeChange', this.getCurrentDimensions() ); + this.emitCatch( 'currentSizeChange', this.getCurrentDimensions() ); } }; @@ -261,7 +261,7 @@ this.setRatioFromDimensions( this.getOriginalDimensions() ); } this.valid = null; - this.emit( 'originalSizeChange', this.getOriginalDimensions() ); + this.emitCatch( 'originalSizeChange', this.getOriginalDimensions() ); } }; @@ -278,7 +278,7 @@ ) { this.defaultDimensions = ve.copy( dimensions ); this.valid = null; - this.emit( 'defaultSizeChange', this.isDefault() ); + this.emitCatch( 'defaultSizeChange', this.isDefault() ); } }; @@ -291,7 +291,7 @@ if ( this.defaultDimensions !== null ) { this.defaultDimensions = null; this.valid = null; - this.emit( 'defaultSizeChange', this.isDefault() ); + this.emitCatch( 'defaultSizeChange', this.isDefault() ); } }; @@ -304,7 +304,7 @@ if ( this.originalDimensions !== null ) { this.originalDimensions = null; this.valid = null; - this.emit( 'originalSizeChange', this.isDefault() ); + this.emitCatch( 'originalSizeChange', this.isDefault() ); } }; @@ -325,7 +325,7 @@ this.getDefaultDimensions() ); } - this.emit( 'defaultSizeChange', this.isDefault() ); + this.emitCatch( 'defaultSizeChange', this.isDefault() ); } }; @@ -342,7 +342,7 @@ ) { this.minDimensions = ve.copy( dimensions ); this.valid = null; - this.emit( 'minSizeChange', dimensions ); + this.emitCatch( 'minSizeChange', dimensions ); } }; @@ -358,7 +358,7 @@ !ve.compare( dimensions, this.getMaxDimensions() ) ) { this.maxDimensions = ve.copy( dimensions ); - this.emit( 'maxSizeChange', dimensions ); + this.emitCatch( 'maxSizeChange', dimensions ); this.valid = null; } }; @@ -372,7 +372,7 @@ if ( this.minDimensions !== null ) { this.minDimensions = null; this.valid = null; - this.emit( 'minSizeChange', this.minDimensions ); + this.emitCatch( 'minSizeChange', this.minDimensions ); } }; @@ -385,7 +385,7 @@ if ( this.maxDimensions !== null ) { this.maxDimensions = null; this.valid = null; - this.emit( 'maxSizeChange', this.maxDimensions ); + this.emitCatch( 'maxSizeChange', this.maxDimensions ); } }; diff --git a/src/dm/ve.dm.Surface.js b/src/dm/ve.dm.Surface.js index 1c2fad1..b0d46bc 100644 --- a/src/dm/ve.dm.Surface.js +++ b/src/dm/ve.dm.Surface.js @@ -8,7 +8,7 @@ * DataModel surface. * * @class - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * * @constructor * @param {ve.dm.Document} doc Document model to create surface for @@ -19,7 +19,7 @@ config = config || {}; // Mixin constructors - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); // Properties this.documentModel = doc; @@ -53,7 +53,7 @@ /* Inheritance */ -OO.mixinClass( ve.dm.Surface, OO.EventEmitter ); +OO.mixinClass( ve.dm.Surface, ve.EventEmitter ); /* Events */ @@ -107,7 +107,7 @@ ve.dm.Surface.prototype.disable = function () { this.stopHistoryTracking(); this.enabled = false; - this.emit( 'history' ); + this.emitCatch( 'history' ); }; /** @@ -118,7 +118,7 @@ ve.dm.Surface.prototype.enable = function () { this.enabled = true; this.startHistoryTracking(); - this.emit( 'history' ); + this.emitCatch( 'history' ); }; /** @@ -128,7 +128,7 @@ */ ve.dm.Surface.prototype.initialize = function () { this.startHistoryTracking(); - this.emit( 'contextChange' ); + this.emitCatch( 'contextChange' ); }; /** @@ -231,7 +231,7 @@ // Set a breakpoint to make sure newTransactions is clear this.breakpoint(); this.stopHistoryTracking(); - this.emit( 'history' ); + this.emitCatch( 'history' ); } this.stagingStack.push( { transactions: [], @@ -266,7 +266,7 @@ if ( !this.isStaging() ) { this.startHistoryTracking(); - this.emit( 'history' ); + this.emitCatch( 'history' ); } return transactions; @@ -302,7 +302,8 @@ if ( !this.isStaging() ) { this.startHistoryTracking(); - this.emit( 'history' ); + this.emitCatch( 'history' ); + } }; @@ -357,8 +358,8 @@ annotations.clone() : new ve.dm.AnnotationSet( this.getDocument().getStore() ); - this.emit( 'insertionAnnotationsChange', this.insertionAnnotations ); - this.emit( 'contextChange' ); + this.emitCatch( 'insertionAnnotationsChange', this.insertionAnnotations ); + this.emitCatch( 'contextChange' ); }; /** @@ -380,8 +381,8 @@ throw new Error( 'Invalid annotations' ); } - this.emit( 'insertionAnnotationsChange', this.insertionAnnotations ); - this.emit( 'contextChange' ); + this.emitCatch( 'insertionAnnotationsChange', this.insertionAnnotations ); + this.emitCatch( 'contextChange' ); }; /** @@ -403,8 +404,8 @@ throw new Error( 'Invalid annotations' ); } - this.emit( 'insertionAnnotationsChange', this.insertionAnnotations ); - this.emit( 'contextChange' ); + this.emitCatch( 'insertionAnnotationsChange', this.insertionAnnotations ); + this.emitCatch( 'contextChange' ); }; /** @@ -543,7 +544,7 @@ if ( this.queueingContextChanges ) { this.contextChangeQueued = true; } else { - this.emit( 'contextChange' ); + this.emitCatch( 'contextChange' ); } }; @@ -560,7 +561,7 @@ this.queueingContextChanges = false; if ( this.contextChangeQueued ) { this.contextChangeQueued = false; - this.emit( 'contextChange' ); + this.emitCatch( 'contextChange' ); } } }; @@ -741,12 +742,13 @@ // If selection changed emit a select if ( selectionChange ) { - this.emit( 'select', this.selection.clone() ); + this.emitCatch( 'select', this.selection.clone() ); if ( oldSelection.isNull() ) { - this.emit( 'focus' ); + this.emitCatch( 'focus' ); + } if ( selection.isNull() ) { - this.emit( 'blur' ); + this.emitCatch( 'blur' ); } } @@ -859,7 +861,7 @@ } } this.transacting = false; - this.emit( 'history' ); + this.emitCatch( 'history' ); } selectionAfter = this.selection; @@ -878,7 +880,7 @@ !selectionBefore.equals( selectionAfter ) && selectionAfter.equals( this.selection ) ) { - this.emit( 'select', this.selection.clone() ); + this.emitCatch( 'select', this.selection.clone() ); } if ( contextChange ) { @@ -967,7 +969,7 @@ */ ve.dm.Surface.prototype.onDocumentTransact = function ( tx ) { this.setSelection( this.getSelection().translateByTransactionWithAuthor( tx, this.authorId ) ); - this.emit( 'documentUpdate', tx ); + this.emitCatch( 'documentUpdate', tx ); }; /** diff --git a/src/dm/ve.dm.SurfaceSynchronizer.js b/src/dm/ve.dm.SurfaceSynchronizer.js index 651f952..44edc38 100644 --- a/src/dm/ve.dm.SurfaceSynchronizer.js +++ b/src/dm/ve.dm.SurfaceSynchronizer.js @@ -9,7 +9,7 @@ * DataModel surface synchronizer. * * @class - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * @mixins ve.dm.RebaseClient * * @constructor @@ -22,7 +22,7 @@ config = config || {}; // Mixin constructors - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); ve.dm.RebaseClient.call( this ); // Properties @@ -61,7 +61,7 @@ /* Inheritance */ -OO.mixinClass( ve.dm.SurfaceSynchronizer, OO.EventEmitter ); +OO.mixinClass( ve.dm.SurfaceSynchronizer, ve.EventEmitter ); OO.mixinClass( ve.dm.SurfaceSynchronizer, ve.dm.RebaseClient ); /* Events */ @@ -242,14 +242,14 @@ } if ( !translatedSelection.equals( this.authorSelections[ authorId ] ) ) { this.authorSelections[ authorId ] = translatedSelection; - this.emit( 'authorSelect', authorId ); + this.emitCatch( 'authorSelect', authorId ); } } }; ve.dm.SurfaceSynchronizer.prototype.onNameChange = function ( data ) { this.authorNames[ data.authorId ] = data.authorName; - this.emit( 'authorNameChange', data.authorId ); + this.emitCatch( 'authorNameChange', data.authorId ); }; ve.dm.SurfaceSynchronizer.prototype.changeName = function ( newName ) { @@ -258,7 +258,7 @@ ve.dm.SurfaceSynchronizer.prototype.onAuthorDisconnect = function ( authorId ) { delete this.authorSelections[ authorId ]; - this.emit( 'authorDisconnect', authorId ); + this.emitCatch( 'authorDisconnect', authorId ); }; /** diff --git a/src/dm/ve.dm.TableMatrix.js b/src/dm/ve.dm.TableMatrix.js index 7474442..f8ec560 100644 --- a/src/dm/ve.dm.TableMatrix.js +++ b/src/dm/ve.dm.TableMatrix.js @@ -29,13 +29,13 @@ * and P[1] a PlaceHolder instance owned by that cell. * * @class - * @mixins OO.EventEmitter + * @mixins ve.EventEmitter * @constructor * @param {ve.dm.TableNode} tableNode Reference to a table instance */ ve.dm.TableMatrix = function VeDmTableMatrix( tableNode ) { // Mixin constructors - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); this.tableNode = tableNode; // Do not access these directly as they get invalidated on structural changes @@ -46,7 +46,7 @@ /* Inheritance */ -OO.mixinClass( ve.dm.TableMatrix, OO.EventEmitter ); +OO.mixinClass( ve.dm.TableMatrix, ve.EventEmitter ); /** * @event structureChange @@ -62,7 +62,7 @@ ve.dm.TableMatrix.prototype.invalidate = function () { this.matrix = null; this.rowNodes = null; - this.emit( 'structureChange' ); + this.emitCatch( 'structureChange' ); }; /** diff --git a/src/ve.Document.js b/src/ve.Document.js index 5e47b5f..ef2fcae 100644 --- a/src/ve.Document.js +++ b/src/ve.Document.js @@ -15,7 +15,7 @@ */ ve.Document = function VeDocument( documentNode ) { // Mixin constructors - OO.EventEmitter.call( this ); + ve.EventEmitter.call( this ); // Properties this.documentNode = documentNode; @@ -24,7 +24,7 @@ /* Inheritance */ -OO.mixinClass( ve.Document, OO.EventEmitter ); +OO.mixinClass( ve.Document, ve.EventEmitter ); /* Events */ diff --git a/src/ve.EventEmitter.js b/src/ve.EventEmitter.js new file mode 100644 index 0000000..de592d3 --- /dev/null +++ b/src/ve.EventEmitter.js @@ -0,0 +1,38 @@ +/*! + * VisualEditor EventEmitter class. + * + * @copyright 2011-2018 VisualEditor Team and others; see http://ve.mit-license.org + */ + +/** + * EventEmitter class. + * + * @class + * @abstract + * @mixins OO.EventEmitter + * @constructor + */ +ve.EventEmitter = function VeEventEmitter() { + // Mix-in constructor + OO.EventEmitter.apply( this, arguments ); +}; + +OO.mixinClass( ve.EventEmitter, OO.EventEmitter ); + +/* Methods */ + +/** + * Emit an event, catching (and ignoring) errors in handlers + * + * @param {string} event Type of event + * @param {...Mixed} args First in a list of variadic arguments passed to event handler (optional) + * @return {boolean} Whether the event was handled by at least one listener + */ +ve.EventEmitter.prototype.emitCatch = function () { + // TODO: Consider wrapping each handler call in a separate try/catch + try { + return this.emit.apply( this, arguments ); + } catch ( ex ) { + return true; + } +}; diff --git a/tests/index.html b/tests/index.html index a9f781b..c7c4bf2 100644 --- a/tests/index.html +++ b/tests/index.html @@ -100,6 +100,7 @@ <script src="../lib/oojs-ui/oojs-ui-apex.js"></script> <!-- visualEditor.core.build --> + <script src="../src/ve.EventEmitter.js"></script> <script src="../src/ve.Range.js"></script> <script src="../src/ve.SelectionState.js"></script> <script src="../src/ve.Node.js"></script> -- To view, visit https://gerrit.wikimedia.org/r/405827 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3175a9e985d4ecffa282d9078352523bfbdf4982 Gerrit-PatchSet: 1 Gerrit-Project: VisualEditor/VisualEditor Gerrit-Branch: master Gerrit-Owner: Divec <da...@troi.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits