r98952 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r98951‎ | r98952 | r98953 >
Date:23:42, 4 October 2011
Author:tparscal
Status:deferred
Tags:
Comment:
Fixed some issues with EventEmitter that was causing events to not be correctly triggered and thus causing contentLength to not be adjusted as items were pushed, which in turn was causing offsetOf to not have a correct model to work with and return crazy numbers.
Modified paths:
  • /trunk/parsers/wikidom/lib/hype/bases/es.DocumentModelNode.js (modified) (history)
  • /trunk/parsers/wikidom/lib/hype/bases/es.EventEmitter.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,5 +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' );
 208+ deepEqual( documentModel[2].getContent(), ['a'], 'Content can be extracted from document' );
209209 } );
Index: trunk/parsers/wikidom/lib/hype/models/es.DocumentModel.js
@@ -201,28 +201,36 @@
202202 var currentNode = this;
203203 for ( var i = 0, length = this.data.length; i < length; i++ ) {
204204 if ( this.data[i].type !== undefined ) {
205 - // It's an element
 205+ // It's an element, figure out it's type
206206 var type = this.data[i].type,
207207 open = type[0] !== '/';
 208+ // Trim the "/" off the beginning of closing tag types
208209 if ( !open ) {
209210 type = type.substr( 1 );
210211 }
211 - if ( !( type in es.DocumentModel.nodeModels ) ) {
212 - throw 'Unsuported element error. No class registered for element type: ' + type;
213 - }
214212 if ( open ) {
 213+ // Validate the element type
 214+ if ( !( type in es.DocumentModel.nodeModels ) ) {
 215+ throw 'Unsuported element error. No class registered for element type: ' + type;
 216+ }
 217+ // Create a model node for the element
215218 var newNode = new es.DocumentModel.nodeModels[this.data[i].type]();
 219+ // Add the new model node as a child
216220 currentNode.push( newNode );
 221+ // Descend into the new model node
217222 currentNode = newNode;
218223 } else {
 224+ // Return to the parent node
219225 currentNode = currentNode.getParent();
220226 }
221227 } else {
222 - // It's content
 228+ // It's content, let's start tracking the length
223229 var start = i;
 230+ // Move forward to the next object, tracking the length as we go
224231 while ( this.data[i].type === undefined && i < length ) {
225232 i++;
226233 }
 234+ // Now we know how long the current node is
227235 currentNode.setContentLength( i - start );
228236 i--;
229237 }
@@ -255,6 +263,8 @@
256264 * This method is pretty expensive. If you need to get different slices of the same content, get
257265 * the content first, then slice it up locally.
258266 *
 267+ * TODO: Rewrite this method to not use recursion, because the function call overhead is expensive
 268+ *
259269 * @method
260270 * @param {es.DocumentModelNode} node Node to get offset of
261271 * @param {Boolean} [deep=false] Whether to scan recursively
@@ -315,6 +325,7 @@
316326 };
317327 }
318328 var offset = this.offsetOf( node, true );
 329+ console.log( offset );
319330 if ( offset !== -1 ) {
320331 return this.data.slice( offset + 1, offset + node.getContentLength() + 1 );
321332 }
Index: trunk/parsers/wikidom/lib/hype/bases/es.DocumentModelNode.js
@@ -11,7 +11,7 @@
1212 */
1313 es.DocumentModelNode = function( contents ) {
1414 // Extension
15 - var node = $.extend( new es.ModelNode( $.isArray( contents ) ? contents : [] ), this );
 15+ var node = $.extend( new es.ModelNode(), this );
1616
1717 // Observe add and remove operations to keep lengths up to date
1818 node.addListenerMethods( node, {
@@ -23,18 +23,15 @@
2424 } );
2525
2626 // Properties
 27+ node.contentLength = 0;
2728 if ( typeof contents === 'number' ) {
2829 if ( contents < 0 ) {
2930 throw 'Invalid content length error. Content length can not be less than 0.';
3031 }
3132 node.contentLength = contents;
32 - } else {
33 - node.contentLength = 0;
34 - // If contents was an array, some items were added, which we need to account for
35 - if ( node.length ) {
36 - for ( var i = 0; i < node.length; i++ ) {
37 - node.contentLength += node[i].getElementLength();
38 - }
 33+ } else if ( $.isArray( contents ) ) {
 34+ for ( var i = 0; i < contents.length; i++ ) {
 35+ node.push( contents[i] );
3936 }
4037 }
4138
Index: trunk/parsers/wikidom/lib/hype/bases/es.EventEmitter.js
@@ -71,22 +71,35 @@
7272 };
7373
7474 /**
 75+ * Add a listener, mapped to a method on a target object.
 76+ *
 77+ * @method
 78+ * @param target {Object} Object to call methods on when events occur
 79+ * @param event {String} Name of event to trigger on
 80+ * @param method {String} Name of method to call
 81+ * @returns {es.EventEmitter} This object
 82+ */
 83+es.EventEmitter.prototype.addListenerMethod = function( target, event, method ) {
 84+ return this.addListener( event, function() {
 85+ if ( typeof target[method] === 'function' ) {
 86+ target[method].apply( target, Array.prototype.slice.call( arguments, 0 ) );
 87+ } else {
 88+ throw 'Listener method error. Target has no such method: ' + method;
 89+ }
 90+ } );
 91+};
 92+
 93+/**
7594 * Add multiple listeners, each mapped to a method on a target object.
7695 *
7796 * @method
78 - * @param context {Object} Object to call methods on when events occur
 97+ * @param target {Object} Object to call methods on when events occur
7998 * @param methods {Object} List of event/method name pairs
8099 * @returns {es.EventEmitter} This object
81100 */
82 -es.EventEmitter.prototype.addListenerMethods = function( context, methods ) {
 101+es.EventEmitter.prototype.addListenerMethods = function( target, methods ) {
83102 for ( var event in methods ) {
84 - this.addListener( event, function() {
85 - if ( methods[event] in context ) {
86 - context[methods[event]].apply( context, Array.prototype.slice( arguments, 1 ) );
87 - } else {
88 - throw 'Listener method error. Context has no such method: ' + methods[event];
89 - }
90 - } );
 103+ this.addListenerMethod( target, event, methods[event] );
91104 }
92105 return this;
93106 };
@@ -110,7 +123,7 @@
111124 var eventEmitter = this;
112125 return this.addListener( type, function listenerWrapper() {
113126 eventEmitter.removeListener( type, listenerWrapper );
114 - listener.apply( eventEmitter, arguments );
 127+ listener.apply( eventEmitter, Array.prototype.slice.call( arguments, 0 ) );
115128 } );
116129 };
117130

Status & tagging log