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

Reply via email to