r98931 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r98930‎ | r98931 | r98932 >
Date:21:49, 4 October 2011
Author:tparscal
Status:deferred
Tags:
Comment:
es.DocumentModel.offsetOf is broken
Modified paths:
  • /trunk/parsers/wikidom/lib/hype/bases/es.DocumentModelNode.js (modified) (history)
  • /trunk/parsers/wikidom/lib/hype/bases/es.ModelNode.js (modified) (history)
  • /trunk/parsers/wikidom/lib/hype/models/es.DocumentModel.js (modified) (history)
  • /trunk/parsers/wikidom/tests/hype/es.DocumentModel.test.js (modified) (history)

Diff [purge]

Index: trunk/parsers/wikidom/tests/hype/es.DocumentModel.test.js
@@ -204,4 +204,5 @@
205205
206206 deepEqual( documentModel.getData(), data, 'Flattening plain objects results in correct data' );
207207 deepEqual( documentModel.slice( 0 ), tree, 'Nodes contain correct lengths' );
 208+ equal( documentModel[2].getContent(), ['a'], 'Content can be extracted from document' );
208209 } );
Index: trunk/parsers/wikidom/lib/hype/models/es.DocumentModel.js
@@ -20,6 +20,13 @@
2121 // Initialization
2222 node.rebuildChildNodes();
2323
 24+ // Sparse array of offsets and nodes located at those offsets
 25+ node.offsetCache = [];
 26+ node.on( 'update', function() {
 27+ // Clear offset cache when content is changed
 28+ node.offsetCache = [];
 29+ } );
 30+
2431 return node;
2532 };
2633
@@ -252,6 +259,10 @@
253260 /**
254261 * Gets the content offset of a node.
255262 *
 263+ * This method uses a cache (this.offsetCache) to make repeated lookups for the same node quicker,
 264+ * but this cache is cleared when the document is updated, so be careful to consolidate update
 265+ * events if possible when depending on this method to be fast.
 266+ *
256267 * @method
257268 * @param {es.DocumentModelNode} node Node to get offset of
258269 * @param {Boolean} [deep=false] Whether to scan recursively
@@ -262,20 +273,27 @@
263274 if ( from === undefined ) {
264275 from = this;
265276 }
 277+ var cachedOffset = this.offsetCache.indexOf( node );
 278+ if ( cachedOffset !== -1 ) {
 279+ return cachedOffset;
 280+ }
266281 var offset = 0;
267 - for ( var i = 0; i < this.length; i++ ) {
268 - if ( node === this[i] ) {
 282+ for ( var i = 0; i < from.length; i++ ) {
 283+ if ( node === from[i] ) {
 284+ this.offsetCache[offset] = node;
269285 return offset;
270286 }
271 - if ( deep && node.length ) {
272 - var length = this.offsetOf( node, deep, node );
273 - if ( length !== null ) {
274 - return offset + length;
 287+ if ( deep && from[i].length ) {
 288+ var length = this.offsetOf( node, true, from[i] );
 289+ if ( length !== -1 ) {
 290+ offset += length;
 291+ this.offsetCache[offset] = node;
 292+ return offset;
275293 }
276294 }
277 - offset += node.getContentLength() + 2;
 295+ offset += from[i].getElementLength();
278296 }
279 - return false;
 297+ return -1;
280298 };
281299
282300 /**
@@ -302,11 +320,19 @@
303321 * @param {Boolean} [deep=false] Whether to scan recursively
304322 * @returns {Array|null} List of content and elements inside node or null if node is not found
305323 */
306 -es.DocumentModel.prototype.getContent = function( node, deep ) {
307 - var offset = this.offsetOf( node, deep );
308 - if ( offset !== false ) {
309 - return this.data.slice( offset + 1, offset + node.getContentLength() );
 324+es.DocumentModel.prototype.getContent = function( node, range ) {
 325+ if ( range ) {
 326+ range.normalize();
 327+ } else {
 328+ range = {
 329+ 'start': 0,
 330+ 'end': this.contentLength
 331+ };
310332 }
 333+ var offset = this.offsetOf( node, true );
 334+ if ( offset !== -1 ) {
 335+ return this.data.slice( offset + 1, offset + node.getContentLength() + 1 );
 336+ }
311337 return null;
312338 };
313339
Index: trunk/parsers/wikidom/lib/hype/bases/es.DocumentModelNode.js
@@ -130,3 +130,23 @@
131131 es.DocumentModelNode.prototype.getElementLength = function() {
132132 return this.contentLength + 2;
133133 };
 134+
 135+/**
 136+ * Gets the content length.
 137+ *
 138+ * FIXME: This method makes assumptions that a node with a data property is a DocumentModel, which
 139+ * may be an issue if sub-classes of DocumentModelNode other than DocumentModel have a data property
 140+ * as well. A safer way of determining this would be helpful in preventing future bugs.
 141+ *
 142+ * @method
 143+ * @param {es.Range} range Range of content to get
 144+ * @returns {Integer} Length of content
 145+ */
 146+es.DocumentModelNode.prototype.getContent = function( range ) {
 147+ // Find root
 148+ var root = this.data ? this : ( this.root.data ? this.root : null );
 149+ if ( root ) {
 150+ return root.getContent( this, range );
 151+ }
 152+ return [];
 153+};
Index: trunk/parsers/wikidom/lib/hype/bases/es.ModelNode.js
@@ -32,7 +32,7 @@
3333
3434 // Properties
3535 node.parent = undefined;
36 - node.root = this;
 36+ node.root = node;
3737
3838 return node;
3939 };
@@ -198,7 +198,7 @@
199199 * Gets the root node in the tree this node is currently attached to.
200200 *
201201 * @method
202 - * @returns {es.DocumentModelNode} Root node
 202+ * @returns {es.ModelNode} Root node
203203 */
204204 es.ModelNode.prototype.getRoot = function() {
205205 return this.root;

Status & tagging log