Divec has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/387511 )
Change subject: WIP: [BREAKING CHANGE] Refactor ve.dm.MetaList ...................................................................... WIP: [BREAKING CHANGE] Refactor ve.dm.MetaList Change-Id: I3fb657ffaabec47fd0b14a54576fc957afed5cc4 --- M src/dm/ve.dm.MetaList.js M src/ve.Node.js 2 files changed, 55 insertions(+), 107 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor refs/changes/11/387511/1 diff --git a/src/dm/ve.dm.MetaList.js b/src/dm/ve.dm.MetaList.js index 69d3716..4e28e75 100644 --- a/src/dm/ve.dm.MetaList.js +++ b/src/dm/ve.dm.MetaList.js @@ -11,31 +11,22 @@ * @mixins OO.EventEmitter * * @constructor - * @param {ve.dm.Surface} surface Surface model + * @param {ve.dm.Document} document Document model */ -ve.dm.MetaList = function VeDmMetaList( surface ) { - var i, metadata, item; - +ve.dm.MetaList = function VeDmMetaList( document ) { // Mixin constructors OO.EventEmitter.call( this ); - // Properties - this.surface = surface; - this.document = surface.getDocument(); - // A sparse array of meta items in document order + this.document = document; + + // Sorted array of attached ve.dm.MetaItem nodes in document order this.items = []; + *** TODO: group-related stuff *** - // Event handlers - this.document.connect( this, { transact: 'onTransact' } ); - - // Populate from document - metadata = this.document.getMetadata(); - for ( i in metadata ) { - if ( Object.prototype.hasOwnProperty.call( metadata, i ) ) { - item = metadata[ i ]; - this.items[ i ] = item; - } - } + this.document.connect( this, { + nodeAttached: 'onNodeAttached', + nodeDetached: 'onNodeDetached' + } ); }; /* Inheritance */ @@ -52,100 +43,37 @@ /** * @event remove * @param {ve.dm.MetaItem} item Item that was removed - * @param {number} offset Linear model offset that the item was at */ /* Methods */ /** - * Event handler for transactions on the document. - * - * When a transaction occurs, update this list to account for it: - * - insert items for new metadata that was inserted - * - remove items for metadata that was removed - * - translate offsets and recompute indices for metadata that has shifted - * - * @param {ve.dm.Transaction} tx Transaction that was applied to the document - * @fires insert - * @fires remove + * If a ve.dm.MetaItem was attached, insert it into items in document order */ -ve.dm.MetaList.prototype.onTransact = function ( tx ) { - var i, len, op, - newPosition = 0; - for ( i = 0, len = tx.operations.length; i < len; i++ ) { - op = tx.operations[ i ]; - if ( op.type === 'retain' ) { - newPosition += op.length; - } else if ( op.type === 'replace' ) { - ve.sparseSplice( - this.items, - newPosition, - op.remove.length, - this.document.getMetadata( new ve.Range( - newPosition, - newPosition + op.insert.length - ) ) - ); - newPosition += op.insert.length; - } else if ( op.type !== 'annotate' && op.type !== 'attribute' ) { - throw new Error( 'Unknown operation type: ' + op.type ); +ve.dm.MetaList.prototype.onNodeAttached = function ( node ) { + var i, + offsetPath = node.getOffsetPath(); + if ( node instanceof ve.dm.MetaItem ) { + i = OO.binarySearch( this.items, function searchFunc( other ) { + return ve.compareTuples( + offsetPath, + other.getOffsetPath() + }, true ); + this.items.splice( i, 0, node ); + *** TODO: emit an event *** + } +}; + +/** + * If a ve.dm.MetaItem was detached, remove it from items + */ +ve.dm.MetaList.prototype.onNodeDetached = function ( node ) { + var i; + if ( node instanceof ve.dm.MetaItem ) { + i = this.items.indexOf( node ); + if ( i !== -1 ) { + this.items.splice( i, 1 ); + *** TODO: emit an event *** } } -}; - -/** - * Get the item at a given offset, if there is one. - * - * @param {number} offset Offset in the linear model - * @return {ve.dm.MetaItem|null} The item at offset, or null if not found - */ -ve.dm.MetaList.prototype.getItemAt = function ( offset ) { - return this.items[ offset ] || null; -}; - -/** - * Get all items in a group. - * - * This function returns a shallow copy, so the array isn't returned by reference but the items - * themselves are. - * - * @param {string} group Group - * @return {ve.dm.MetaItem[]} Array of items in the group (shallow copy) - */ -ve.dm.MetaList.prototype.getItemsInGroup = function ( group ) { - return this.items.filter( function ( item ) { return item.getGroup() === group; } ); -}; - -/** - * Get all items in the list. - * - * This function returns a shallow copy, so the array isn't returned by reference but the items - * themselves are. - * - * @return {ve.dm.MetaItem[]} Array of items in the list - */ -ve.dm.MetaList.prototype.getAllItems = function () { - return this.items.filter( function () { return true; } ); -}; - -/** - * Insert new metadata into the document. This builds and processes a transaction that inserts - * metadata into the document. - * - * Pass a plain object rather than a MetaItem into this function unless you know what you're doing. - * - * @param {Object|ve.dm.MetaItem} meta Metadata element (or MetaItem) to insert - * @param {number} [offset] Offset to insert the new metadata, or undefined to add to the end - */ -ve.dm.MetaList.prototype.insertMeta = function ( meta, offset ) { - var tx, closeMeta; - if ( meta instanceof ve.dm.MetaItem ) { - meta = meta.getElement(); - } - closeMeta = { type: '/' + meta.type }; - if ( offset === undefined ) { - offset = this.document.getInternalList().getListNode().getOuterRange().start; - } - tx = ve.dm.TransactionBuilder.static.newFromInsertion( this.document, offset, [ meta, closeMeta ] ); - this.surface.change( tx ); }; diff --git a/src/ve.Node.js b/src/ve.Node.js index e9b278d..d05f5e5 100644 --- a/src/ve.Node.js +++ b/src/ve.Node.js @@ -428,3 +428,23 @@ return !( node instanceof type ); } ); }; + +/** + * Get the offset path from the document node to this node + * + * @return {number[]|null} The offset path, or null if not attached to a ve.dm.DocumentNode + */ +ve.Node.prototype.getOffsetPath = function () { + var node = this, + path = []; + while ( true ) { + if ( node instanceof ve.dm.DocumentNode ) { + return path; + } + if ( !node.parent ) { + return null; + } + path.unshift( node.parent.indexOf( node ) ); + node = node.parent; + } +}; -- To view, visit https://gerrit.wikimedia.org/r/387511 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3fb657ffaabec47fd0b14a54576fc957afed5cc4 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