https://www.mediawiki.org/wiki/Special:Code/MediaWiki/113530

Revision: 113530
Author:   tparscal
Date:     2012-03-09 21:54:00 +0000 (Fri, 09 Mar 2012)
Log Message:
-----------
Removed duplicate static methods and members that were copied to ve.dm - lets 
just leave them in ve.dm.DocumentNode for now.

Modified Paths:
--------------
    trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.js

Modified: trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.js
===================================================================
--- trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.js        2012-03-09 
21:50:24 UTC (rev 113529)
+++ trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.js        2012-03-09 
21:54:00 UTC (rev 113530)
@@ -3,549 +3,4 @@
  * 
  * All classes and functions will be attached to this object to keep the 
global namespace clean.
  */
-ve.dm = {
-
-       /* Static Members */
-
-       /**
-        * Mapping of symbolic names and node model constructors.
-        */
-       'nodeModels': {},
-       /**
-        * Mapping of symbolic names and nesting rules.
-        * 
-        * Each rule is an object with the follwing properties:
-        *     parents and children properties may contain one of two possible 
values:
-        *         {Array} List symbolic names of allowed element types (if 
empty, none will be allowed)
-        *         {Null} Any element type is allowed (as long as the other 
element also allows it)
-        * 
-        * @example Paragraph rules
-        *     {
-        *         'parents': null,
-        *         'children': []
-        *     }
-        * @example List rules
-        *     {
-        *         'parents': null,
-        *         'children': ['listItem']
-        *     }
-        * @example ListItem rules
-        *     {
-        *         'parents': ['list'],
-        *         'children': null
-        *     }
-        * @example TableCell rules
-        *     {
-        *         'parents': ['tableRow'],
-        *         'children': null
-        *     }
-        */
-       'nodeRules': {
-               'document': {
-                       'parents': null,
-                       'children': null
-               }
-       },
-
-       /* Static Methods */
-
-       /*
-        * Create child nodes from an array of data.
-        * 
-        * These child nodes are used for the model tree, which is a space 
partitioning data structure
-        * in which each node contains the length of itself (1 for opening, 1 
for closing) and the
-        * lengths of it's child nodes.
-        */
-       'createNodesFromData': function( data ) {
-               var currentNode = new ve.dm.BranchNode();
-               for ( var i = 0, length = data.length; i < length; i++ ) {
-                       if ( data[i].type !== undefined ) {
-                               // It's an element, figure out it's type
-                               var element = data[i],
-                                       type = element.type,
-                                       open = type.charAt( 0 ) !== '/';
-                               // Trim the "/" off the beginning of closing 
tag types
-                               if ( !open ) {
-                                       type = type.substr( 1 );
-                               }
-                               if ( open ) {
-                                       // Validate the element type
-                                       if ( !( type in 
ve.dm.DocumentNode.nodeModels ) ) {
-                                               throw 'Unsuported element 
error. No class registered for element type: ' +
-                                                       type;
-                                       }
-                                       // Create a model node for the element
-                                       var newNode = new 
ve.dm.DocumentNode.nodeModels[element.type]( element, 0 );
-                                       // Add the new model node as a child
-                                       currentNode.push( newNode );
-                                       // Descend into the new model node
-                                       currentNode = newNode;
-                               } else {
-                                       // Return to the parent node
-                                       currentNode = currentNode.getParent();
-                                       if ( currentNode === null ) {
-                                               throw 'createNodesFromData() 
received unbalanced data: found closing ' +
-                                                       'without matching 
opening at index ' + i;
-                                       }
-                               }
-                       } else {
-                               // It's content, let's start tracking the length
-                               var start = i;
-                               // Move forward to the next object, tracking 
the length as we go
-                               while ( data[i].type === undefined && i < 
length ) {
-                                       i++;
-                               }
-                               // Now we know how long the current node is
-                               currentNode.setContentLength( i - start );
-                               // The while loop left us 1 element to far
-                               i--;
-                       }
-               }
-               return currentNode.getChildren().slice( 0 );
-       },
-       /**
-        * Creates a document model from a plain object.
-        * 
-        * @static
-        * @method
-        * @param {Object} obj Object to create new document model from
-        * @returns {ve.dm.DocumentNode} Document model created from obj
-        */
-       'newFromPlainObject': function( obj ) {
-               if ( obj.type === 'document' ) {
-                       var data = [],
-                               attributes = ve.isPlainObject( obj.attributes ) 
?
-                                       ve.copyObject( obj.attributes ) : {};
-                       for ( var i = 0; i < obj.children.length; i++ ) {
-                               data = data.concat(
-                                       
ve.dm.DocumentNode.flattenPlainObjectElementNode( obj.children[i] )
-                               );
-                       }
-                       return new ve.dm.DocumentNode( data, attributes );
-               }
-               throw 'Invalid object error. Object is not a valid document 
object.';
-       },
-       /**
-        * Generates a hash of an annotation object based on it's name and data.
-        * 
-        * @static
-        * @method
-        * @param {Object} annotation Annotation object to generate hash for
-        * @returns {String} Hash of annotation
-        */
-       'getHash': ( window.JSON && typeof JSON.stringify === 'function' ) ?
-               JSON.stringify : ve.dm.JsonSerializer.stringify,
-       /**
-        * Gets the index of the first instance of a given annotation.
-        * 
-        * This method differs from ve.inArray because it compares hashes 
instead of references.
-        * 
-        * @static
-        * @method
-        * @param {Array} annotations Annotations to search through
-        * @param {Object} annotation Annotation to search for
-        * @param {Boolean} typeOnly Whether to only consider the type
-        * @returns {Integer} Index of annotation in annotations, or -1 if 
annotation was not found
-        */
-       'getIndexOfAnnotation': function( annotations, annotation, typeOnly ) {
-               if ( annotation === undefined || annotation.type === undefined 
) {
-                       throw 'Invalid annotation error. Can not find 
non-annotation data in character.';
-               }
-               if ( ve.isArray( annotations ) ) {
-                       // Find the index of a comparable annotation (checking 
for same value, not reference)
-                       for ( var i = 0; i < annotations.length; i++ ) {
-                               // Skip over character data - used when this is 
called on a content data item
-                               if ( typeof annotations[i] === 'string' ) {
-                                       continue;
-                               }
-                               if (
-                                       (
-                                               typeOnly && 
-                                               annotations[i].type === 
annotation.type
-                                       ) ||
-                                       (
-                                               !typeOnly &&
-                                               annotations[i].hash === (
-                                                       annotation.hash || 
ve.dm.DocumentNode.getHash( annotation )
-                                               )
-                                       )
-                               ) {
-                                       return i;
-                               }
-                       }
-               }
-               return -1;
-       },
-       /**
-        * Gets a list of indexes of annotations that match a regular 
expression.
-        * 
-        * @static
-        * @method
-        * @param {Array} annotations Annotations to search through
-        * @param {RegExp} pattern Regular expression pattern to match with
-        * @returns {Integer[]} List of indexes in annotations that match
-        */
-       'getMatchingAnnotations': function( annotations, pattern ) {
-               if ( !( pattern instanceof RegExp ) ) {
-                       throw 'Invalid annotation error. Can not find 
non-annotation data in character.';
-               }
-               var matches = [];
-               if ( ve.isArray( annotations ) ) {
-                       // Find the index of a comparable annotation (checking 
for same value, not reference)
-                       for ( var i = 0; i < annotations.length; i++ ) {
-                               // Skip over character data - used when this is 
called on a content data item
-                               if ( typeof annotations[i] === 'string' ) {
-                                       continue;
-                               }
-                               if ( pattern.test( annotations[i].type ) ) {
-                                       matches.push( annotations[i] );
-                               }
-                       }
-               }
-               return matches;
-       },
-       /**
-        * Sorts annotations of a character.
-        * 
-        * This method modifies data in place. The string portion of the 
annotation character will always
-        * remain at the beginning.
-        * 
-        * @static
-        * @method
-        * @param {Array} character Annotated character to be sorted
-        */
-       'sortCharacterAnnotations': function( character ) {
-               if ( !ve.isArray( character ) ) {
-                       return;
-               }
-               character.sort( function( a, b ) {
-                       var aHash = a.hash || ve.dm.DocumentNode.getHash( a ),
-                               bHash = b.hash || ve.dm.DocumentNode.getHash( b 
);
-                       return typeof a === 'string' ? -1 :
-                               ( typeof b === 'string' ? 1 : ( aHash == bHash 
? 0 : ( aHash < bHash ? -1 : 1 ) ) );
-               } );
-       },
-       /**
-        * Adds annotation hashes to content data.
-        * 
-        * This method modifies data in place.
-        * 
-        * @method
-        * @param {Array} data Data to add annotation hashes to
-        */
-       'addAnnotationHashesToData': function( data ) {
-               for ( var i = 0; i < data.length; i++ ) {
-                       if ( ve.isArray( data[i] ) ) {
-                               for ( var j = 1; j < data.length; j++ ) {
-                                       if ( data[i][j].hash === undefined ) {
-                                               data[i][j].hash = 
ve.dm.DocumentNode.getHash( data[i][j] );
-                                       }
-                               }
-                       }
-               }
-       },
-       /**
-        * Applies annotations to content data.
-        * 
-        * This method modifies data in place.
-        * 
-        * @method
-        * @param {Array} data Data to remove annotations from
-        * @param {Array} annotations Annotations to apply
-        */
-       'addAnnotationsToData': function( data, annotations ) {
-               if ( annotations && annotations.length ) {
-                       for ( var i = 0; i < data.length; i++ ) {
-                               if ( ve.isArray( data[i] ) ) {
-                                       data[i] = [data[i]];
-                               }
-                               data[i] = [data[i]].concat( annotations );
-                       }
-               }
-       },
-       /**
-        * Removes annotations from content data.
-        * 
-        * This method modifies data in place.
-        * 
-        * @method
-        * @param {Array} data Data to remove annotations from
-        * @param {Array} [annotations] Annotations to remove (all will be 
removed if undefined)
-        */
-       'removeAnnotationsFromData': function( data, annotations ) {
-               for ( var i = 0; i < data.length; i++ ) {
-                       if ( ve.isArray( data[i] ) ) {
-                               data[i] = data[i][0];
-                       }
-               }
-       },
-       /**
-        * Creates an ve.ContentModel object from a plain content object.
-        * 
-        * A plain content object contains plain text and a series of 
annotations to be applied to ranges of
-        * the text.
-        * 
-        * @example
-        * {
-        *     'text': '1234',
-        *     'annotations': [
-        *         // Makes "23" bold
-        *         {
-        *             'type': 'bold',
-        *             'range': {
-        *                 'start': 1,
-        *                 'end': 3
-        *             }
-        *         }
-        *     ]
-        * }
-        * 
-        * @static
-        * @method
-        * @param {Object} obj Plain content object, containing a "text" 
property and optionally
-        * an "annotations" property, the latter of which being an array of 
annotation objects including
-        * range information
-        * @returns {Array}
-        */
-       'flattenPlainObjectContentNode': function( obj ) {
-               if ( !ve.isPlainObject( obj ) ) {
-                       // Use empty content
-                       return [];
-               } else {
-                       // Convert string to array of characters
-                       var data = obj.text.split('');
-                       // Render annotations
-                       if ( ve.isArray( obj.annotations ) ) {
-                               for ( var i = 0, length = 
obj.annotations.length; i < length; i++ ) {
-                                       var src = obj.annotations[i];
-                                       // Build simplified annotation object
-                                       var dst = { 'type': src.type };
-                                       if ( 'data' in src ) {
-                                               dst.data = ve.copyObject( 
src.data );
-                                       }
-                                       // Add a hash to the annotation for 
faster comparison
-                                       dst.hash = ve.dm.DocumentNode.getHash( 
dst );
-                                       // Apply annotation to range
-                                       if ( src.range.start < 0 ) {
-                                               // TODO: The start can not be 
lower than 0! Throw error?
-                                               // Clamp start value
-                                               src.range.start = 0;
-                                       }
-                                       if ( src.range.end > data.length ) {
-                                               // TODO: The end can not be 
higher than the length! Throw error?
-                                               // Clamp end value
-                                               src.range.end = data.length;
-                                       }
-                                       for ( var j = src.range.start; j < 
src.range.end; j++ ) {
-                                               // Auto-convert to array
-                                               if ( typeof data[j] === 
'string' ) {
-                                                       data[j] = [data[j]];
-                                               }
-                                               // Append 
-                                               data[j].push( dst );
-                                       }
-                               }
-                       }
-                       return data;
-               }
-       },
-       /**
-        * Flatten a plain node object into a data array, recursively.
-        * 
-        * TODO: where do we document this whole structure - aka "WikiDom"?
-        * 
-        * @static
-        * @method
-        * @param {Object} obj Plain node object to flatten
-        * @returns {Array} Flattened version of obj
-        */
-       'flattenPlainObjectElementNode': function( obj ) {
-               var i,
-                       data = [],
-                       element = { 'type': obj.type };
-               if ( ve.isPlainObject( obj.attributes ) ) {
-                       element.attributes = ve.copyObject( obj.attributes );
-               }
-               // Open element
-               data.push( element );
-               if ( ve.isPlainObject( obj.content ) ) {
-                       // Add content
-                       data = data.concat( 
ve.dm.DocumentNode.flattenPlainObjectContentNode( obj.content ) );
-               } else if ( ve.isArray( obj.children ) ) {
-                       // Add children - only do this if there is no content 
property
-                       for ( i = 0; i < obj.children.length; i++ ) {
-                               // TODO: Figure out if all this concatenating 
is inefficient. I think it is
-                               data = data.concat( 
ve.dm.DocumentNode.flattenPlainObjectElementNode( obj.children[i] ) );
-                       }
-               }
-               // Close element - TODO: Do we need attributes here or not?
-               data.push( { 'type': '/' + obj.type } );
-               return data;
-       },
-       /**
-        * Get a plain object representation of content data.
-        * 
-        * @method
-        * @returns {Object} Plain object representation
-        */
-       'getExpandedContentData': function( data ) {
-               var stack = [];
-               // Text and annotations
-               function start( offset, annotation ) {
-                       // Make a new verion of the annotation object and push 
it to the stack
-                       var obj = {
-                               'type': annotation.type,
-                               'range': { 'start': offset }
-                       };
-                       if ( annotation.data ) {
-                               obj.data = ve.copyObject( annotation.data );
-                       }
-                       stack.push( obj );
-               }
-               function end( offset, annotation ) {
-                       for ( var i = stack.length - 1; i >= 0; i-- ) {
-                               if ( !stack[i].range.end ) {
-                                       if ( annotation ) {
-                                               // We would just compare 
hashes, but the stack doesn't contain any
-                                               if ( stack[i].type === 
annotation.type &&
-                                                               
ve.compareObjects( stack[i].data, annotation.data ) ) {
-                                                       stack[i].range.end = 
offset;
-                                                       break;
-                                               }
-                                       } else {
-                                               stack[i].range.end = offset;
-                                       }
-                               }
-                       }
-               }
-               var left = '',
-                       right,
-                       leftPlain,
-                       rightPlain,
-                       obj = { 'text': '' },
-                       offset = 0,
-                       i,
-                       j;
-               for ( i = 0; i < data.length; i++ ) {
-                       right = data[i];
-                       leftPlain = typeof left === 'string';
-                       rightPlain = typeof right === 'string';
-                       // Open or close annotations
-                       if ( !leftPlain && rightPlain ) {
-                               // [formatted][plain] pair, close any 
annotations for left
-                               end( i - offset );
-                       } else if ( leftPlain && !rightPlain ) {
-                               // [plain][formatted] pair, open any 
annotations for right
-                               for ( j = 1; j < right.length; j++ ) {
-                                       start( i - offset, right[j] );
-                               }
-                       } else if ( !leftPlain && !rightPlain ) {
-                               // [formatted][formatted] pair, open/close any 
differences
-                               for ( j = 1; j < left.length; j++ ) {
-                                       if ( 
ve.dm.DocumentNode.getIndexOfAnnotation( data[i] , left[j], true ) === -1 ) {
-                                               end( i - offset, left[j] );
-                                       }
-                               }
-                               for ( j = 1; j < right.length; j++ ) {
-                                       if ( 
ve.dm.DocumentNode.getIndexOfAnnotation( data[i - 1], right[j], true ) === -1 ) 
{
-                                               start( i - offset, right[j] );
-                                       }
-                               }
-                       }
-                       obj.text += rightPlain ? right : right[0];
-                       left = right;           
-               }
-               if ( data.length ) {
-                       end( i - offset );
-               }
-               if ( stack.length ) {
-                       obj.annotations = stack;
-               }
-               // Copy attributes if there are any set
-               if ( !ve.isEmptyObject( this.attributes ) ) {
-                       obj.attributes = ve.extendObject( true, {}, 
this.attributes );
-               }
-               return obj;
-       },
-       /**
-        * Checks if a data at a given offset is content.
-        * 
-        * @example Content data:
-        *      <paragraph> a b c </paragraph> <list> <listItem> d e f 
</listItem> </list>
-        *                 ^ ^ ^                                ^ ^ ^
-        * 
-        * @static
-        * @method
-        * @param {Array} data Data to evaluate offset within
-        * @param {Integer} offset Offset in data to check
-        * @returns {Boolean} If data at offset is content
-        */
-       'isContentData': function( data, offset ) {
-               // Shortcut: if there's already content there, we will trust 
it's supposed to be there
-               return typeof data[offset] === 'string' || ve.isArray( 
data[offset] );
-       },
-       /**
-        * Checks if a data at a given offset is an element.
-        * 
-        * @example Element data:
-        *      <paragraph> a b c </paragraph> <list> <listItem> d e f 
</listItem> </list>
-        *     ^                 ^            ^      ^                ^         
  ^
-        * 
-        * @static
-        * @method
-        * @param {Array} data Data to evaluate offset within
-        * @param {Integer} offset Offset in data to check
-        * @returns {Boolean} If data at offset is an element
-        */
-       'isElementData': function( data, offset ) {
-               // TODO: Is there a safer way to check if it's a plain object 
without sacrificing speed?
-               return offset >= 0 && offset < data.length && data[offset].type 
!== undefined;
-       },
-       /**
-        * Checks if an offset within given data is structural.
-        * 
-        * Structural offsets are those at the beginning, end or surrounded by 
elements. This differs
-        * from a location at which an element is present in that elements can 
be safely inserted at a
-        * structural location, but not nessecarily where an element is present.
-        * 
-        * @example Structural offsets:
-        *      <paragraph> a b c </paragraph> <list> <listItem> d e f 
</listItem> </list>
-        *     ^                              ^      ^                          
  ^       ^
-        * 
-        * @static
-        * @method
-        * @param {Array} data Data to evaluate offset within
-        * @param {Integer} offset Offset to check
-        * @returns {Boolean} Whether offset is structural or not
-        */
-       'isStructuralOffset': function( data, offset ) {
-               // Edges are always structural
-               if ( offset === 0 || offset === data.length ) {
-                       return true;
-               }
-               // Structual offsets will have elements on each side
-               if ( data[offset - 1].type !== undefined && data[offset].type 
!== undefined ) {
-                       if ( '/' + data[offset - 1].type === data[offset].type 
) {
-                               return false;
-                       }
-                       return true;
-               }
-               return false;
-       },
-       /**
-        * Checks if elements are present within data.
-        * 
-        * @static
-        * @method
-        * @param {Array} data Data to look for elements within
-        * @returns {Boolean} If elements exist in data
-        */
-       'containsElementData': function( data ) {
-               for ( var i = 0, length = data.length; i < length; i++ ) {
-                       if ( data[i].type !== undefined ) {
-                               return true;
-                       }
-               }
-               return false;
-       }
-};
+ve.dm = {};


_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to