Index: trunk/parsers/wikidom/tests/hype/es.DocumentNode.test.js |
— | — | @@ -0,0 +1,60 @@ |
| 2 | +module( 'Bases' ); |
| 3 | + |
| 4 | +function DocumentNodeStub( items, name, size ) { |
| 5 | + this.name = name; |
| 6 | + this.size = size; |
| 7 | + return es.extendObject( new es.DocumentNode( items ), this ); |
| 8 | +} |
| 9 | + |
| 10 | +DocumentNodeStub.prototype.getElementLength = function() { |
| 11 | + // Mimic document data which has an opening and closing around the content |
| 12 | + return this.size + 2; |
| 13 | +}; |
| 14 | + |
| 15 | +test( 'es.DocumentNode', function() { |
| 16 | + strictEqual( |
| 17 | + ( new DocumentNodeStub( [], 'a', 0 ) ).getElementLength(), |
| 18 | + 2, |
| 19 | + 'DocumentNodeStub.getElementLength() returns initialized length plus 2 for elements' |
| 20 | + ); |
| 21 | + var a = new DocumentNodeStub( [], 'a', 0 ), |
| 22 | + b = new DocumentNodeStub( [], 'b', 1 ), |
| 23 | + c = new DocumentNodeStub( [], 'c', 2 ), |
| 24 | + d = new DocumentNodeStub( [], 'd', 3 ), |
| 25 | + e = new DocumentNodeStub( [], 'e', 4 ), |
| 26 | + root1 = new DocumentNodeStub( [a, b, c, d, e], 'root1', 20 ), |
| 27 | + i; |
| 28 | + |
| 29 | + var getNodeFromOffsetTests = [ |
| 30 | + { 'input': -1, 'output': null }, |
| 31 | + { 'input': 0, 'output': a }, |
| 32 | + { 'input': 1, 'output': a }, |
| 33 | + { 'input': 2, 'output': b }, |
| 34 | + { 'input': 3, 'output': b }, |
| 35 | + { 'input': 4, 'output': b }, |
| 36 | + { 'input': 5, 'output': c }, |
| 37 | + { 'input': 6, 'output': c }, |
| 38 | + { 'input': 7, 'output': c }, |
| 39 | + { 'input': 8, 'output': c }, |
| 40 | + { 'input': 9, 'output': d }, |
| 41 | + { 'input': 10, 'output': d }, |
| 42 | + { 'input': 11, 'output': d }, |
| 43 | + { 'input': 12, 'output': d }, |
| 44 | + { 'input': 13, 'output': d }, |
| 45 | + { 'input': 14, 'output': e }, |
| 46 | + { 'input': 15, 'output': e }, |
| 47 | + { 'input': 16, 'output': e }, |
| 48 | + { 'input': 17, 'output': e }, |
| 49 | + { 'input': 18, 'output': e }, |
| 50 | + { 'input': 19, 'output': e }, |
| 51 | + { 'input': 20, 'output': null } |
| 52 | + ]; |
| 53 | + |
| 54 | + for ( i = 0; i < getNodeFromOffsetTests.length; i++ ) { |
| 55 | + strictEqual( |
| 56 | + root1.getNodeFromOffset( getNodeFromOffsetTests[i].input ), |
| 57 | + getNodeFromOffsetTests[i].output, |
| 58 | + 'getNodeFromOffset finds the right item or returns null when out of range' |
| 59 | + ); |
| 60 | + } |
| 61 | +} ); |
Index: trunk/parsers/wikidom/tests/hype/index.html |
— | — | @@ -29,6 +29,7 @@ |
30 | 30 | <script src="../../lib/hype/models/es.TableRowModel.js"></script> |
31 | 31 | <script src="es.test.js"></script> |
32 | 32 | <script src="es.ModelNode.test.js"></script> |
| 33 | + <script src="es.DocumentNode.test.js"></script> |
33 | 34 | <script src="es.DocumentModel.test.js"></script> |
34 | 35 | </body> |
35 | 36 | </html> |
Index: trunk/parsers/wikidom/lib/hype/es.js |
— | — | @@ -31,7 +31,7 @@ |
32 | 32 | * @param {Function} dst Class to extend |
33 | 33 | * @param {Function} src Base class to use methods from |
34 | 34 | */ |
35 | | -es.extend = function( dst, src ) { |
| 35 | +es.extendClass = function( dst, src ) { |
36 | 36 | var base = new src(); |
37 | 37 | for ( var method in base ) { |
38 | 38 | if ( typeof base[method] === 'function' && !( method in dst.prototype ) ) { |
— | — | @@ -40,6 +40,12 @@ |
41 | 41 | } |
42 | 42 | }; |
43 | 43 | |
| 44 | +es.extendObject = $.extend; |
| 45 | + |
| 46 | +es.isPlainObject = $.isPlainObject; |
| 47 | + |
| 48 | +es.isArray = $.isArray; |
| 49 | + |
44 | 50 | /** |
45 | 51 | * Recursively compares string and number property between two objects. |
46 | 52 | * |
— | — | @@ -64,7 +70,7 @@ |
65 | 71 | bType = typeof bValue; |
66 | 72 | if ( aType !== bType || |
67 | 73 | ( ( aType === 'string' || aType === 'number' ) && aValue !== bValue ) || |
68 | | - ( $.isPlainObject( aValue ) && !es.compareObjects( aValue, bValue ) ) ) { |
| 74 | + ( es.isPlainObject( aValue ) && !es.compareObjects( aValue, bValue ) ) ) { |
69 | 75 | return false; |
70 | 76 | } |
71 | 77 | } |
— | — | @@ -87,9 +93,9 @@ |
88 | 94 | sourceType = typeof sourceValue; |
89 | 95 | if ( sourceType === 'string' || sourceType === 'number' ) { |
90 | 96 | destination.push( sourceValue ); |
91 | | - } else if ( $.isPlainObject( sourceValue ) ) { |
| 97 | + } else if ( es.isPlainObject( sourceValue ) ) { |
92 | 98 | destination.push( es.copyObject( sourceValue ) ); |
93 | | - } else if ( $.isArray( sourceValue ) ) { |
| 99 | + } else if ( es.isArray( sourceValue ) ) { |
94 | 100 | destination.push( es.copyArray( sourceValue ) ); |
95 | 101 | } |
96 | 102 | } |
— | — | @@ -111,9 +117,9 @@ |
112 | 118 | sourceType = typeof sourceValue; |
113 | 119 | if ( sourceType === 'string' || sourceType === 'number' ) { |
114 | 120 | destination[key] = sourceValue; |
115 | | - } else if ( $.isPlainObject( sourceValue ) ) { |
| 121 | + } else if ( es.isPlainObject( sourceValue ) ) { |
116 | 122 | destination[key] = es.copyObject( sourceValue ); |
117 | | - } else if ( $.isArray( sourceValue ) ) { |
| 123 | + } else if ( es.isArray( sourceValue ) ) { |
118 | 124 | destination[key] = es.copyArray( sourceValue ); |
119 | 125 | } |
120 | 126 | } |
Index: trunk/parsers/wikidom/lib/hype/models/es.DocumentModel.js |
— | — | @@ -10,12 +10,12 @@ |
11 | 11 | * @param {Object} attributes Document attributes |
12 | 12 | */ |
13 | 13 | es.DocumentModel = function( data, attributes ) { |
14 | | - // Inheritance |
15 | | - var node = $.extend( new es.DocumentModelNode( null, length ), this ); |
| 14 | + // Extension |
| 15 | + var node = es.extendObject( new es.DocumentModelNode( null, length ), this ); |
16 | 16 | |
17 | 17 | // Properties |
18 | | - node.data = $.isArray( data ) ? data : []; |
19 | | - node.attributes = $.isPlainObject( attributes ) ? attributes : {}; |
| 18 | + node.data = es.isArray( data ) ? data : []; |
| 19 | + node.attributes = es.isPlainObject( attributes ) ? attributes : {}; |
20 | 20 | |
21 | 21 | // Auto-generate model tree |
22 | 22 | var nodes = es.DocumentModel.createNodesFromData( node.data ); |
— | — | @@ -178,7 +178,7 @@ |
179 | 179 | } |
180 | 180 | for ( j = this.cursor; j < to; j++ ) { |
181 | 181 | // Auto-convert to array |
182 | | - if ( $.isArray( this.data[j] ) ) { |
| 182 | + if ( es.isArray( this.data[j] ) ) { |
183 | 183 | this.data[j].push( annotation ); |
184 | 184 | } else { |
185 | 185 | this.data[j] = [this.data[j], annotation]; |
— | — | @@ -327,7 +327,7 @@ |
328 | 328 | es.DocumentModel.newFromPlainObject = function( obj ) { |
329 | 329 | if ( obj.type === 'document' ) { |
330 | 330 | var data = [], |
331 | | - attributes = $.isPlainObject( obj.attributes ) ? es.copyObject( obj.attributes ) : {}; |
| 331 | + attributes = es.isPlainObject( obj.attributes ) ? es.copyObject( obj.attributes ) : {}; |
332 | 332 | for ( var i = 0; i < obj.children.length; i++ ) { |
333 | 333 | data = data.concat( es.DocumentModel.flattenPlainObjectElementNode( obj.children[i] ) ); |
334 | 334 | } |
— | — | @@ -363,7 +363,7 @@ |
364 | 364 | if ( annotation === undefined || annotation.type === undefined ) { |
365 | 365 | throw 'Invalid annotation error. Can not find non-annotation data in character.'; |
366 | 366 | } |
367 | | - if ( $.isArray( annotations ) ) { |
| 367 | + if ( es.isArray( annotations ) ) { |
368 | 368 | // Find the index of a comparable annotation (checking for same value, not reference) |
369 | 369 | for ( var i = 0; i < annotations.length; i++ ) { |
370 | 370 | // Skip over character data - used when this is called on a content data item |
— | — | @@ -407,14 +407,14 @@ |
408 | 408 | * @returns {Array} |
409 | 409 | */ |
410 | 410 | es.DocumentModel.flattenPlainObjectContentNode = function( obj ) { |
411 | | - if ( !$.isPlainObject( obj ) ) { |
| 411 | + if ( !es.isPlainObject( obj ) ) { |
412 | 412 | // Use empty content |
413 | 413 | return []; |
414 | 414 | } else { |
415 | 415 | // Convert string to array of characters |
416 | 416 | var data = obj.text.split(''); |
417 | 417 | // Render annotations |
418 | | - if ( $.isArray( obj.annotations ) ) { |
| 418 | + if ( es.isArray( obj.annotations ) ) { |
419 | 419 | for ( var i = 0, length = obj.annotations.length; i < length; i++ ) { |
420 | 420 | var src = obj.annotations[i]; |
421 | 421 | // Build simplified annotation object |
— | — | @@ -463,15 +463,15 @@ |
464 | 464 | var i, |
465 | 465 | data = [], |
466 | 466 | element = { 'type': obj.type }; |
467 | | - if ( $.isPlainObject( obj.attributes ) ) { |
| 467 | + if ( es.isPlainObject( obj.attributes ) ) { |
468 | 468 | element.attributes = es.copyObject( obj.attributes ); |
469 | 469 | } |
470 | 470 | // Open element |
471 | 471 | data.push( element ); |
472 | | - if ( $.isPlainObject( obj.content ) ) { |
| 472 | + if ( es.isPlainObject( obj.content ) ) { |
473 | 473 | // Add content |
474 | 474 | data = data.concat( es.DocumentModel.flattenPlainObjectContentNode( obj.content ) ); |
475 | | - } else if ( $.isArray( obj.children ) ) { |
| 475 | + } else if ( es.isArray( obj.children ) ) { |
476 | 476 | // Add children - only do this if there is no content property |
477 | 477 | for ( i = 0; i < obj.children.length; i++ ) { |
478 | 478 | // TODO: Figure out if all this concatenating is inefficient. I think it is |
— | — | @@ -502,7 +502,7 @@ |
503 | 503 | // Content can't exist at the edges |
504 | 504 | if ( offset > 0 && offset < data.length ) { |
505 | 505 | // Shortcut: if there's already content there, we will trust it's supposed to be there |
506 | | - if ( typeof data[offset] === 'string' || $.isArray( data[offset] ) ) { |
| 506 | + if ( typeof data[offset] === 'string' || es.isArray( data[offset] ) ) { |
507 | 507 | return true; |
508 | 508 | } |
509 | 509 | // Empty elements will have an opening and a closing next to each other |
— | — | @@ -1042,4 +1042,4 @@ |
1043 | 1043 | |
1044 | 1044 | /* Inheritance */ |
1045 | 1045 | |
1046 | | -es.extend( es.DocumentModel, es.DocumentModelNode ); |
| 1046 | +es.extendClass( es.DocumentModel, es.DocumentModelNode ); |
Index: trunk/parsers/wikidom/lib/hype/models/es.TableRowModel.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | */ |
8 | 8 | es.TableRowModel = function( element, length ) { |
9 | 9 | // Extension |
10 | | - return $.extend( new es.DocumentModelNode( element, length ), this ); |
| 10 | + return es.extendObject( new es.DocumentModelNode( element, length ), this ); |
11 | 11 | }; |
12 | 12 | |
13 | 13 | /* Methods */ |
Index: trunk/parsers/wikidom/lib/hype/models/es.ParagraphModel.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | */ |
8 | 8 | es.ParagraphModel = function( element, length ) { |
9 | 9 | // Extension |
10 | | - return $.extend( new es.DocumentModelNode( element, length ), this ); |
| 10 | + return es.extendObject( new es.DocumentModelNode( element, length ), this ); |
11 | 11 | }; |
12 | 12 | |
13 | 13 | /* Methods */ |
Index: trunk/parsers/wikidom/lib/hype/models/es.TableCellModel.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | */ |
8 | 8 | es.TableCellModel = function( element, length ) { |
9 | 9 | // Extension |
10 | | - return $.extend( new es.DocumentModelNode( element, length ), this ); |
| 10 | + return es.extendObject( new es.DocumentModelNode( element, length ), this ); |
11 | 11 | }; |
12 | 12 | |
13 | 13 | /* Methods */ |
Index: trunk/parsers/wikidom/lib/hype/models/es.TableModel.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | */ |
8 | 8 | es.TableModel = function( element, length ) { |
9 | 9 | // Extension |
10 | | - return $.extend( new es.DocumentModelNode( element, length ), this ); |
| 10 | + return es.extendObject( new es.DocumentModelNode( element, length ), this ); |
11 | 11 | }; |
12 | 12 | |
13 | 13 | /* Methods */ |
Index: trunk/parsers/wikidom/lib/hype/models/es.ListItemModel.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | */ |
8 | 8 | es.ListItemModel = function( element, length ) { |
9 | 9 | // Extension |
10 | | - return $.extend( new es.DocumentModelNode( element, length ), this ); |
| 10 | + return es.extendObject( new es.DocumentModelNode( element, length ), this ); |
11 | 11 | }; |
12 | 12 | |
13 | 13 | /* Methods */ |
Index: trunk/parsers/wikidom/lib/hype/models/es.ListModel.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | */ |
8 | 8 | es.ListModel = function( element, length ) { |
9 | 9 | // Extension |
10 | | - return $.extend( new es.DocumentModelNode( element, length ), this ); |
| 10 | + return es.extendObject( new es.DocumentModelNode( element, length ), this ); |
11 | 11 | }; |
12 | 12 | |
13 | 13 | /* Methods */ |
Index: trunk/parsers/wikidom/lib/hype/es.Transaction.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | * @constructor |
8 | 8 | */ |
9 | 9 | es.Transaction = function() { |
10 | | - return $.extend( [], this ); |
| 10 | + return es.extendObject( [], this ); |
11 | 11 | }; |
12 | 12 | |
13 | 13 | /* Methods */ |
Index: trunk/parsers/wikidom/lib/hype/bases/es.ViewNode.js |
— | — | @@ -27,7 +27,7 @@ |
28 | 28 | } |
29 | 29 | |
30 | 30 | // Extension |
31 | | - var node = $.extend( [], this ); |
| 31 | + var node = es.extendObject( [], this ); |
32 | 32 | |
33 | 33 | // Properties |
34 | 34 | node.model = model; |
— | — | @@ -185,4 +185,4 @@ |
186 | 186 | |
187 | 187 | /* Inheritance */ |
188 | 188 | |
189 | | -es.extend( es.ViewNode, es.EventEmitter ); |
| 189 | +es.extendClass( es.ViewNode, es.EventEmitter ); |
Index: trunk/parsers/wikidom/lib/hype/bases/es.DocumentNode.js |
— | — | @@ -2,11 +2,7 @@ |
3 | 3 | * Creates an es.DocumentNode object. |
4 | 4 | */ |
5 | 5 | es.DocumentNode = function( nodes ) { |
6 | | - if ( nodes === undefined ) { |
7 | | - nodes = []; |
8 | | - } |
9 | | - $.extend( nodes, this ); |
10 | | - return nodes; |
| 6 | + return es.extendObject( nodes === undefined ? [] : nodes, this ); |
11 | 7 | }; |
12 | 8 | |
13 | 9 | /** |
Index: trunk/parsers/wikidom/lib/hype/bases/es.DocumentModelNode.js |
— | — | @@ -12,7 +12,7 @@ |
13 | 13 | */ |
14 | 14 | es.DocumentModelNode = function( element, contents ) { |
15 | 15 | // Extension |
16 | | - var node = $.extend( new es.DocumentNode( new es.ModelNode() ), this ); |
| 16 | + var node = es.extendObject( new es.DocumentNode( new es.ModelNode() ), this ); |
17 | 17 | |
18 | 18 | // Observe add and remove operations to keep lengths up to date |
19 | 19 | node.addListenerMethods( node, { |
— | — | @@ -31,7 +31,7 @@ |
32 | 32 | throw 'Invalid content length error. Content length can not be less than 0.'; |
33 | 33 | } |
34 | 34 | node.contentLength = contents; |
35 | | - } else if ( $.isArray( contents ) ) { |
| 35 | + } else if ( es.isArray( contents ) ) { |
36 | 36 | for ( var i = 0; i < contents.length; i++ ) { |
37 | 37 | node.push( contents[i] ); |
38 | 38 | } |
Index: trunk/parsers/wikidom/lib/hype/bases/es.ModelNode.js |
— | — | @@ -16,7 +16,7 @@ |
17 | 17 | es.EventEmitter.call( this ); |
18 | 18 | |
19 | 19 | // Extension |
20 | | - var node = $.extend( [], this ); |
| 20 | + var node = es.extendObject( [], this ); |
21 | 21 | |
22 | 22 | // Reusable function for passing update events upstream |
23 | 23 | node.emitUpdate = function() { |
— | — | @@ -24,7 +24,7 @@ |
25 | 25 | }; |
26 | 26 | |
27 | 27 | // Children |
28 | | - if ( $.isArray( children ) ) { |
| 28 | + if ( es.isArray( children ) ) { |
29 | 29 | for ( var i = 0; i < children.length; i++ ) { |
30 | 30 | node.push( children[i] ); |
31 | 31 | } |
— | — | @@ -245,4 +245,4 @@ |
246 | 246 | |
247 | 247 | /* Inheritance */ |
248 | 248 | |
249 | | -es.extend( es.ModelNode, es.EventEmitter ); |
| 249 | +es.extendClass( es.ModelNode, es.EventEmitter ); |
Index: trunk/parsers/wikidom/lib/hype/bases/es.DocumentViewLeafNode.js |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | */ |
11 | 11 | es.DocumentViewLeafNode = function( model, $element ) { |
12 | 12 | // Extension |
13 | | - var node = $.extend( new es.DocumentNode( new es.ViewNode( model, $element ) ), this ); |
| 13 | + var node = es.extendObject( new es.DocumentNode( new es.ViewNode( model, $element ) ), this ); |
14 | 14 | |
15 | 15 | // Content |
16 | 16 | node.contentView = new es.ContentView( node.$, model ); |
Index: trunk/parsers/wikidom/lib/hype/bases/es.DocumentViewBranchNode.js |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | */ |
11 | 11 | es.DocumentViewBranchNode = function( model, $element ) { |
12 | 12 | // Extension |
13 | | - return $.extend( new es.DocumentNode( new es.ViewNode( model, $element ) ), this ); |
| 13 | + return es.extendObject( new es.DocumentNode( new es.ViewNode( model, $element ) ), this ); |
14 | 14 | }; |
15 | 15 | |
16 | 16 | /* Methods */ |
Index: trunk/parsers/wikidom/lib/hype/views/es.ParagraphView.js |
— | — | @@ -7,5 +7,5 @@ |
8 | 8 | */ |
9 | 9 | es.ParagraphView = function( model ) { |
10 | 10 | // Extension |
11 | | - return $.extend( new es.DocumentViewLeafNode( model ), this ); |
| 11 | + return es.extendObject( new es.DocumentViewLeafNode( model ), this ); |
12 | 12 | }; |
Index: trunk/parsers/wikidom/lib/hype/views/es.TableCellView.js |
— | — | @@ -7,5 +7,5 @@ |
8 | 8 | */ |
9 | 9 | es.TableCellView = function( model ) { |
10 | 10 | // Extension |
11 | | - return $.extend( new es.DocumentViewBranchNode( model ), this ); |
| 11 | + return es.extendObject( new es.DocumentViewBranchNode( model ), this ); |
12 | 12 | }; |
Index: trunk/parsers/wikidom/lib/hype/views/es.TableView.js |
— | — | @@ -7,5 +7,5 @@ |
8 | 8 | */ |
9 | 9 | es.TableView = function( model ) { |
10 | 10 | // Extension |
11 | | - return $.extend( new es.DocumentViewBranchNode( model ), this ); |
| 11 | + return es.extendObject( new es.DocumentViewBranchNode( model ), this ); |
12 | 12 | }; |
Index: trunk/parsers/wikidom/lib/hype/views/es.ContentView.js |
— | — | @@ -840,4 +840,4 @@ |
841 | 841 | |
842 | 842 | /* Inheritance */ |
843 | 843 | |
844 | | -es.extend( es.ContentView, es.EventEmitter ); |
| 844 | +es.extendClass( es.ContentView, es.EventEmitter ); |
Index: trunk/parsers/wikidom/lib/hype/views/es.ListItemView.js |
— | — | @@ -7,5 +7,5 @@ |
8 | 8 | */ |
9 | 9 | es.ListItemView = function( model ) { |
10 | 10 | // Extension |
11 | | - return $.extend( new es.DocumentViewLeafNode( model ), this ); |
| 11 | + return es.extendObject( new es.DocumentViewLeafNode( model ), this ); |
12 | 12 | }; |
Index: trunk/parsers/wikidom/lib/hype/views/es.ListView.js |
— | — | @@ -7,5 +7,5 @@ |
8 | 8 | */ |
9 | 9 | es.ListView = function( model ) { |
10 | 10 | // Extension |
11 | | - return $.extend( new es.DocumentViewBranchNode( model ), this ); |
| 11 | + return es.extendObject( new es.DocumentViewBranchNode( model ), this ); |
12 | 12 | }; |
Index: trunk/parsers/wikidom/lib/hype/views/es.DocumentView.js |
— | — | @@ -1,5 +1,5 @@ |
2 | 2 | es.DocumentView = function( documentModel, surfaceView ) { |
3 | | - var node = $.extend( new es.DocumentViewBranchNode( documentModel ), this ); |
| 3 | + var node = es.extendObject( new es.DocumentViewBranchNode( documentModel ), this ); |
4 | 4 | node.$.addClass( 'editSurface-document' ); |
5 | 5 | node.surfaceView = surfaceView; |
6 | 6 | return node; |
Index: trunk/parsers/wikidom/lib/hype/views/es.TableRowView.js |
— | — | @@ -7,5 +7,5 @@ |
8 | 8 | */ |
9 | 9 | es.TableRowView = function( model ) { |
10 | 10 | // Extension |
11 | | - return $.extend( new es.DocumentViewBranchNode( model ), this ); |
| 11 | + return es.extendObject( new es.DocumentViewBranchNode( model ), this ); |
12 | 12 | }; |