r98496 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r98495‎ | r98496 | r98497 >
Date:00:48, 30 September 2011
Author:tparscal
Status:deferred
Tags:
Comment:
Some cleanup and documentation
Added getData to DocumentModel
Modified paths:
  • /trunk/parsers/wikidom/lib/hype/bases/es.DocumentModelNode.js (modified) (history)
  • /trunk/parsers/wikidom/lib/hype/es.js (modified) (history)
  • /trunk/parsers/wikidom/lib/hype/models/es.DocumentModel.js (modified) (history)

Diff [purge]

Index: trunk/parsers/wikidom/lib/hype/es.js
@@ -73,23 +73,48 @@
7474 };
7575
7676 /**
77 - * Gets a recursive copy of an object's string, number and plain-object property.
 77+ * Gets a deep copy of an array's string, number, array and plain-object contents.
7878 *
7979 * @static
8080 * @method
 81+ * @param source {Array} Array to copy
 82+ * @returns {Array} Copy of source array
 83+ */
 84+es.copyArray = function( source ) {
 85+ var destination = [];
 86+ for ( var i = 0; i < source.length; i++ ) {
 87+ sourceValue = source[i];
 88+ sourceType = typeof sourceValue;
 89+ if ( sourceType === 'string' || sourceType === 'number' ) {
 90+ destination.push( sourceValue );
 91+ } else if ( $.isPlainObject( sourceValue ) ) {
 92+ destination.push( es.copyObject( sourceValue ) );
 93+ } else if ( $.isArray( sourceValue ) ) {
 94+ destination.push( es.copyArray( sourceValue ) );
 95+ }
 96+ }
 97+ return destination;
 98+};
 99+
 100+/**
 101+ * Gets a deep copy of an object's string, number, array and plain-object properties.
 102+ *
 103+ * @static
 104+ * @method
81105 * @param source {Object} Object to copy
82106 * @returns {Object} Copy of source object
83107 */
84108 es.copyObject = function( source ) {
85109 var destination = {};
86 - var key;
87 - for ( key in source ) {
 110+ for ( var key in source ) {
88111 sourceValue = source[key];
89112 sourceType = typeof sourceValue;
90113 if ( sourceType === 'string' || sourceType === 'number' ) {
91114 destination[key] = sourceValue;
92115 } else if ( $.isPlainObject( sourceValue ) ) {
93116 destination[key] = es.copyObject( sourceValue );
 117+ } else if ( $.isArray( sourceValue ) ) {
 118+ destination[key] = es.copyArray( sourceValue );
94119 }
95120 }
96121 return destination;
Index: trunk/parsers/wikidom/lib/hype/models/es.DocumentModel.js
@@ -14,43 +14,123 @@
1515
1616 /* Static Methods */
1717
18 -es.DocumentModel.isContent = function( content ) {
19 - return typeof content === 'string' || $.isArray( content );
 18+/**
 19+ * Checks if a data at a given offset is content.
 20+ *
 21+ * @static
 22+ * @method
 23+ * @param {Integer} offset Offset in data to check
 24+ * @returns {Boolean} If data at offset is content
 25+ */
 26+es.DocumentModel.isContent = function( offset ) {
 27+ return typeof this.data[offset] === 'string' || $.isArray( this.data[offset] );
2028 };
2129
22 -es.DocumentModel.isElement = function( content ) {
23 - return content.type !== undefined;
 30+/**
 31+ * Checks if a data at a given offset is an element.
 32+ *
 33+ * @static
 34+ * @method
 35+ * @param {Integer} offset Offset in data to check
 36+ * @returns {Boolean} If data at offset is an element
 37+ */
 38+es.DocumentModel.isElement = function( offset ) {
 39+ // TODO: Is there a safer way to check if it's a plain object without sacrificing speed?
 40+ return this.data[offset].type !== undefined;
2441 };
2542
 43+/**
 44+ * Flatten a plain node object into a data array, recursively.
 45+ *
 46+ * TODO: where do we document this whole structure - aka "WikiDom"?
 47+ *
 48+ * @static
 49+ * @method
 50+ * @param {Object} obj Plain node object to flatten
 51+ * @returns {Array} Flattened version of obj
 52+ */
 53+es.DocumentModel.flattenPlainObjectNode = function( obj ) {
 54+ var i, data = [];
 55+ // Open element
 56+ data.push( { 'type': obj.type, 'attributes': es.copyObject( obj.attributes ), 'node': null } );
 57+ if ( obj.content !== undefined ) {
 58+ // Add content
 59+ data = data.concat( es.ContentModel.newFromPlainObject( obj.content ).data );
 60+ } else {
 61+ // Add children - only do this if there is no content property
 62+ for ( i = 0; i < obj.children.length; i++ ) {
 63+ // TODO: Figure out if all this concatenating is inefficient. I think it is
 64+ data = data.concat( flattenNode( obj.children[i] ) );
 65+ }
 66+ }
 67+ // Close element - TODO: Do we need attributes here or not?
 68+ data.push( { 'type': '/' + obj.type, 'node': null } );
 69+ return data;
 70+};
 71+
2672 /* Methods */
2773
28 -es.DocumentModel.prototype.findElement = function( node, root ) {
29 - for ( var i = 0; i < this.data.length; i++ ) {
30 - if ( es.DocumentModel.isElement( this.data[i] ) ) {
31 - if ( content.node === node ) {
32 - return i;
 74+/**
 75+ * Gets copy of the document data.
 76+ *
 77+ * @method
 78+ * @param {es.Range} [range] Range of data to get, all data will be given by default
 79+ * @param {Boolean} [deep=false] Whether to return a deep copy (WARNING! This may be very slow)
 80+ * @returns {Array} Copy of document data
 81+ */
 82+es.DocumentModel.prototype.getData = function( range, deep ) {
 83+ var start = 0,
 84+ end = undefined;
 85+ if ( range !== undefined ) {
 86+ range.normalize();
 87+ start = Math.max( 0, Math.min( this.data.length, range.start ) );
 88+ end = Math.max( 0, Math.min( this.data.length, range.end ) );
 89+ }
 90+ var data = this.data.slice( start, end );
 91+ return deep ? es.copyArray( data ) : data;
 92+};
 93+
 94+/**
 95+ * Gets the content offset of a node.
 96+ *
 97+ * @method
 98+ * @param {es.DocumentModelNode} node Node to get offset of
 99+ * @param {Boolean} deep Whether to scan recursively
 100+ * @param {es.DocumentModelNode} [from=this] Node to look within
 101+ * @returns {Integer|false} Offset of node or null of node was not found
 102+ */
 103+es.DocumentModel.prototype.offsetOf = function( node, deep, from ) {
 104+ if ( from === undefined ) {
 105+ from = this;
 106+ }
 107+ var offset = 0;
 108+ for ( var i = 0; i < this.length; i++ ) {
 109+ if ( node === this[i] ) {
 110+ return offset;
 111+ }
 112+ if ( deep && node.length ) {
 113+ var length = this.findElement( node, deep, node );
 114+ if ( length !== null ) {
 115+ return offset + length;
33116 }
34 - // If we are looking for a root node, we can skip over the contents of this one
35 - if ( root ) {
36 - i += node.getContentLength() + 2;
37 - }
38117 }
 118+ offset += node.getContentLength() + 2;
39119 }
40 - return null;
 120+ return false;
41121 };
42122
43123 /**
44124 * Gets the element object of a node.
45125 *
46126 * @method
47 - * @param {es.DocumentModelNode} node Reference to node object to get element object for
48 - * @param {Boolean} root Whether to only scan root nodes
 127+ * @param {es.DocumentModelNode} node Node to get element object for
 128+ * @param {Boolean} deep Whether to scan recursively
49129 * @returns {Object|null} Element object
50130 */
51 -es.DocumentModel.prototype.getElement = function( node, root ) {
52 - var index = this.findNode( node, root );
53 - if ( index !== null ) {
54 - return this.data[index];
 131+es.DocumentModel.prototype.getElement = function( node, deep ) {
 132+ var offset = this.offsetOf( node, deep );
 133+ if ( offset !== false ) {
 134+ return this.data[offset];
55135 }
56136 return null;
57137 };
@@ -59,14 +139,14 @@
60140 * Gets the content data of a node.
61141 *
62142 * @method
63 - * @param {es.DocumentModelNode} node Reference to node object to get content data for
64 - * @param {Boolean} root Whether to only scan root nodes
 143+ * @param {es.DocumentModelNode} node Node to get content data for
 144+ * @param {Boolean} deep Whether to scan recursively
65145 * @returns {Array|null} List of content and elements inside node or null if node is not found
66146 */
67 -es.DocumentModel.prototype.getContent = function( node, root ) {
68 - var index = this.findNode( node, root );
69 - if ( index !== null ) {
70 - return this.data.slice( index + 1, index + node.getContentLength() );
 147+es.DocumentModel.prototype.getContent = function( node, deep ) {
 148+ var offset = this.offsetOf( node, deep );
 149+ if ( offset !== false ) {
 150+ return this.data.slice( offset + 1, offset + node.getContentLength() );
71151 }
72152 return null;
73153 };
@@ -169,33 +249,7 @@
170250 */
171251
172252 es.DocumentModel.newFromPlainObject = function( obj ) {
173 - /*
174 - * Flatten a node and its children into a data array, recursively.
175 - *
176 - * @param obj {Object} A plain node object //TODO where do we document this whole structure?
177 - * @return {Array} Array to append the flattened version of obj to
178 - */
179 - function flattenNode( obj ) {
180 - var i, data = [];
181 - // Open element
182 - // TODO do we need to copy the attributes object or can we use a reference?
183 - data.push( { 'type': obj.type, 'attributes': obj.attributes, 'node': null } );
184 - if ( obj.content !== undefined ) {
185 - // Add content
186 - data = data.concat( es.ContentModel.newFromPlainObject( obj.content ).data );
187 - } else {
188 - // Add children. Only do this if there is no content property
189 - for ( i = 0; i < obj.children.length; i++ ) {
190 - //TODO figure out if all this concatting is inefficent. I think it is
191 - data = data.concat( flattenNode( obj.children[i] ) );
192 - }
193 - }
194 - // Close element // TODO do we need attributes here or not?
195 - data.push( { 'type': '/' + obj.type, 'node': null } );
196 - return data;
197 - }
198 -
199 - return new es.DocumentModel( flattenNode( obj ) );
 253+ return new es.DocumentModel( es.DocumentModel.flattenPlainObjectNode( obj ) );
200254 };
201255
202256 /*
Index: trunk/parsers/wikidom/lib/hype/bases/es.DocumentModelNode.js
@@ -20,10 +20,6 @@
2121 return this.contentLength;
2222 };
2323
24 -es.DocumentModelNode.getElementLength = function() {
25 - return this.contentLength + 2;
26 -};
27 -
2824 /* Inheritance */
2925
3026 es.extend( es.DocumentModelNode, es.ModelNode );

Status & tagging log