mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 02:23:58 +00:00
Added test data and fixed test suite links
Change-Id: Idb5de70b58c525a67f16b21f7adc53214af9b486
This commit is contained in:
parent
d4a99f2d26
commit
44fe109f14
30
modules/ve2/dm/nodes/ve.dm.ImageNode.js
Normal file
30
modules/ve2/dm/nodes/ve.dm.ImageNode.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Data model node for a document.
|
||||
*
|
||||
* @class
|
||||
* @constructor
|
||||
* @extends {ve.dm.LeafNode}
|
||||
* @param {Integer} [length] Length of content data in document
|
||||
* @param {Object} [attributes] Reference to map of attribute key/value pairs
|
||||
*/
|
||||
ve.dm.ImageNode = function( length, attributes ) {
|
||||
// Inheritance
|
||||
ve.dm.LeafNode.call( this, 'image', length, attributes );
|
||||
};
|
||||
|
||||
/* Static Members */
|
||||
|
||||
ve.dm.ImageNode.rules = {
|
||||
'canHaveChildren': false,
|
||||
'canHaveGrandchildren': false,
|
||||
'childNodeTypes': [],
|
||||
'parentNodeTypes': null
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.dm.factory.register( 'image', ve.dm.ImageNode );
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
ve.extendClass( ve.dm.ImageNode, ve.dm.LeafNode );
|
29
modules/ve2/dm/nodes/ve.dm.TextNode.js
Normal file
29
modules/ve2/dm/nodes/ve.dm.TextNode.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Data model node for a document.
|
||||
*
|
||||
* @class
|
||||
* @constructor
|
||||
* @extends {ve.dm.LeafNode}
|
||||
* @param {Integer} [length] Length of content data in document
|
||||
*/
|
||||
ve.dm.TextNode = function( length ) {
|
||||
// Inheritance
|
||||
ve.dm.LeafNode.call( this, 'text', length );
|
||||
};
|
||||
|
||||
/* Static Members */
|
||||
|
||||
ve.dm.TextNode.rules = {
|
||||
'canHaveChildren': false,
|
||||
'canHaveGrandchildren': false,
|
||||
'childNodeTypes': [],
|
||||
'parentNodeTypes': null
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.dm.factory.register( 'text', ve.dm.TextNode );
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
ve.extendClass( ve.dm.TextNode, ve.dm.LeafNode );
|
|
@ -45,7 +45,7 @@ ve.dm.Document = function( data ) {
|
|||
* @param {Integer} newLength Length of data in linear model to rebuild or insert nodes for
|
||||
* @returns {ve.dm.Node[]} Array containing the rebuilt/inserted nodes
|
||||
*/
|
||||
ve.dm.DocumentNode.prototype.rebuildNodes = function( parent, index, numNodes, offset, newLength ) {
|
||||
ve.dm.Document.prototype.rebuildNodes = function( parent, index, numNodes, offset, newLength ) {
|
||||
// Compute the length of the old nodes (so we can splice their offsets out of the offset map)
|
||||
var oldLength = 0;
|
||||
for ( var i = index; i < index + numNodes; i++ ) {
|
||||
|
@ -58,7 +58,7 @@ ve.dm.DocumentNode.prototype.rebuildNodes = function( parent, index, numNodes, o
|
|||
// Get generated child nodes from the document fragment
|
||||
var nodes = fragment.getRootNode().getChildren();
|
||||
// Replace nodes in the model tree
|
||||
ve.batchedSplice( parent, index, numNodes, nodes );
|
||||
ve.batchedSplice( parent.children, index, numNodes, nodes );
|
||||
// Update offset map
|
||||
ve.batchedSplice( this.offsetMap, offset, oldLength, fragment.getOffsetMap() );
|
||||
// Return inserted nodes
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
* @class
|
||||
* @constructor
|
||||
* @param {Array} data Linear model data to start with
|
||||
* @param {ve.dm.Document} [parentDocument] Document to use as root for created nodes
|
||||
*/
|
||||
ve.dm.DocumentFragment = function( parentDocument, data ) {
|
||||
ve.dm.DocumentFragment = function( data, parentDocument ) {
|
||||
// Properties
|
||||
this.parentDocument = parentDocument;
|
||||
this.data = data || [];
|
||||
this.rootNode = new ve.dm.DocumentNode();
|
||||
this.offsets = new Array( data.length );
|
||||
this.offsetMap = new Array( this.data.length );
|
||||
|
||||
// Initialization
|
||||
var root = parentDocument ? parentDocument.getRootNode() : this.rootNode;
|
||||
|
@ -52,7 +53,7 @@ ve.dm.DocumentFragment = function( parentDocument, data ) {
|
|||
// 3. data[i] is content, so offset i is in the middle of an element,
|
||||
// so obviously we need currentNode, which won't be changed by this
|
||||
// iteration
|
||||
this.offsets[i] = currentNode;
|
||||
this.offsetMap[i] = currentNode;
|
||||
|
||||
if ( this.data[i].type === undefined ) {
|
||||
// Text node
|
||||
|
@ -100,14 +101,16 @@ ve.dm.DocumentFragment = function( parentDocument, data ) {
|
|||
currentStack = parentStack;
|
||||
parentStack = stack[stack.length - 2];
|
||||
// Attach the children to the node
|
||||
ve.batchedSplice( currentNode, 0, 0, children );
|
||||
if ( children.length ) {
|
||||
ve.batchedSplice( currentNode.children, 0, 0, children );
|
||||
}
|
||||
currentNode = parentStack[parentStack.length - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
// The end state is stack = [ [this.rootNode] [ array, of, its, children ] ]
|
||||
// so attach all nodes in stack[1] to the root node
|
||||
ve.batchedSplice( this.rootNode, 0, 0, stack[1] );
|
||||
ve.batchedSplice( this.rootNode.children, 0, 0, stack[1] );
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
@ -120,7 +123,7 @@ ve.dm.DocumentFragment = function( parentDocument, data ) {
|
|||
* @param {Boolean} [deep=false] Whether to return a deep copy (WARNING! This may be very slow)
|
||||
* @returns {Array} Slice or copy of document data
|
||||
*/
|
||||
ve.dm.DocumentNode.prototype.getData = function( range, deep ) {
|
||||
ve.dm.DocumentFragment.prototype.getData = function( range, deep ) {
|
||||
var start = 0,
|
||||
end;
|
||||
if ( range !== undefined ) {
|
||||
|
|
9
tests/ve2/dm/ve.dm.Document.test.js
Normal file
9
tests/ve2/dm/ve.dm.Document.test.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
module( 've.dm.Document' );
|
||||
|
||||
/* Tests */
|
||||
|
||||
/*
|
||||
test( 'rebuildNodes', 1, function() {
|
||||
//
|
||||
} );
|
||||
*/
|
23
tests/ve2/dm/ve.dm.DocumentFragment.test.js
Normal file
23
tests/ve2/dm/ve.dm.DocumentFragment.test.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
module( 've.dm.Document' );
|
||||
|
||||
/* Tests */
|
||||
|
||||
test( 'getData', 1, function() {
|
||||
var parentDocument = new ve.dm.Document(),
|
||||
fragment = new ve.dm.DocumentFragment( ve.dm.example.data, parentDocument );
|
||||
deepEqual( fragment.getData(), ve.dm.example.data );
|
||||
} );
|
||||
|
||||
/*
|
||||
test( 'getOffsetMap', 1, function() {
|
||||
//
|
||||
} );
|
||||
|
||||
test( 'getRootNode', 1, function() {
|
||||
//
|
||||
} );
|
||||
|
||||
test( 'getNodeFromOffset', 1, function() {
|
||||
//
|
||||
} );
|
||||
*/
|
291
tests/ve2/dm/ve.dm.example.js
Normal file
291
tests/ve2/dm/ve.dm.example.js
Normal file
|
@ -0,0 +1,291 @@
|
|||
/* Static Members */
|
||||
|
||||
ve.dm.example = {};
|
||||
|
||||
/**
|
||||
* Serialized HTML.
|
||||
*
|
||||
* This is what the parser will emit.
|
||||
*/
|
||||
ve.dm.example.html =
|
||||
'<h1>a<b>b</b><i>c</i></h1>' +
|
||||
'<table>' +
|
||||
'<tr>' +
|
||||
'<td>' +
|
||||
'<p>d</p>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'<p>e</p>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'<p>f</p>' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<ol>' +
|
||||
'<li>' +
|
||||
'<p>g</p>' +
|
||||
'</li>' +
|
||||
'</ol>' +
|
||||
'</td>' +
|
||||
'</tr>' +
|
||||
'</table>' +
|
||||
'<pre>h<img src="image.png">i</pre>';
|
||||
|
||||
/*
|
||||
* Linear data.
|
||||
*
|
||||
* This is what we convert serialized HTML from the parser into so we can work with it more easily.
|
||||
*
|
||||
* There are three types of components in content data:
|
||||
*
|
||||
* {String} Plain text character
|
||||
*
|
||||
* {Array} Annotated character
|
||||
* 0: {String} Character
|
||||
* 1: {Object} List of references to immutable annotation objects, keyed by JSON
|
||||
* serializations of their values (hashes)
|
||||
*
|
||||
* {Object} Opening or closing structural element
|
||||
* type: {String} Symbolic node type name, if closing element first character will be "/"
|
||||
* [attributes]: {Object} List of symbolic attribute name and literal value pairs
|
||||
*/
|
||||
ve.dm.example.data = [
|
||||
// 0 - Beginning of heading
|
||||
{ 'type': 'heading', 'attributes': { 'level': 1 } },
|
||||
// 1 - Plain "a"
|
||||
'a',
|
||||
// 2 - Bold "b"
|
||||
['b', { '{"type":"textStyle/bold"}': { 'type': 'textStyle/bold' } }],
|
||||
// 3 - Italic "c"
|
||||
['c', { '{"type":"textStyle/italic"}': { 'type': 'textStyle/italic' } }],
|
||||
// 4 - End of heading
|
||||
{ 'type': '/heading' },
|
||||
// 5 - Beginning of table
|
||||
{ 'type': 'table' },
|
||||
// 6 - Beginning of row
|
||||
{ 'type': 'tableRow' },
|
||||
// 7 - Beginning of cell
|
||||
{ 'type': 'tableCell' },
|
||||
// 8 - Beginning of paragraph
|
||||
{ 'type': 'paragraph' },
|
||||
// 9 - Plain "d"
|
||||
'd',
|
||||
// 10 - End of paragraph
|
||||
{ 'type': '/paragraph' },
|
||||
// 11 - Beginning of bullet list
|
||||
{ 'type': 'list', 'attributes': { 'styles': ['bullet'] } },
|
||||
// 12 - Beginning of list item
|
||||
{ 'type': 'listItem' },
|
||||
// 13 - Beginning of paragraph
|
||||
{ 'type': 'paragraph' },
|
||||
// 14 - Plain "e"
|
||||
'e',
|
||||
// 15 - End of paragraph
|
||||
{ 'type': '/paragraph' },
|
||||
// 17 - Beginning of nested bullet list
|
||||
{ 'type': 'list', 'attributes': { 'styles': ['bullet'] } },
|
||||
// 18 - Beginning of nested bullet list item
|
||||
{ 'type': 'listItem' },
|
||||
// 19 - Beginning of paragraph
|
||||
{ 'type': 'paragraph' },
|
||||
// 20 - Plain "f"
|
||||
'f',
|
||||
// 21 - End of paragraph
|
||||
{ 'type': '/paragraph' },
|
||||
// 22 - End of nested bullet list item
|
||||
{ 'type': '/listItem' },
|
||||
// 23 - End of nested bullet list
|
||||
{ 'type': '/list' },
|
||||
// 24 - End of bullet list item
|
||||
{ 'type': '/listItem' },
|
||||
// 25 - End of bullet list
|
||||
{ 'type': '/list' },
|
||||
// 26 - Beginning of numbered list
|
||||
{ 'type': 'list', 'attributes': { 'styles': ['number'] } },
|
||||
// 27 - Beginning of numbered list item
|
||||
{ 'type': 'listItem' },
|
||||
// 28 - Beginning of paragraph
|
||||
{ 'type': 'paragraph' },
|
||||
// 29 - Plain "g"
|
||||
'g',
|
||||
// 30 - End of paragraph
|
||||
{ 'type': '/paragraph' },
|
||||
// 31 - End of item
|
||||
{ 'type': '/listItem' },
|
||||
// 32 - End of list
|
||||
{ 'type': '/list' },
|
||||
// 33 - End of cell
|
||||
{ 'type': '/tableCell' },
|
||||
// 34 - End of row
|
||||
{ 'type': '/tableRow' },
|
||||
// 35 - End of table
|
||||
{ 'type': '/table' },
|
||||
// 36 - Beginning of preformatted
|
||||
{ 'type': 'preformatted' },
|
||||
// 37 - Plain "h"
|
||||
'h',
|
||||
// 38 - Beginning of inline image
|
||||
{ 'type': 'image', 'attributes': { 'html/src': 'image.png' } },
|
||||
// 39 - End of inline image
|
||||
{ 'type': '/image' },
|
||||
// 40 - Plain "i"
|
||||
'i',
|
||||
// 41 - End of preformatted
|
||||
{ 'type': '/preformatted' }
|
||||
];
|
||||
|
||||
/**
|
||||
* Sample content data index.
|
||||
*
|
||||
* This is part of what a ve.dm.DocumentFragment generates when given linear data.
|
||||
*/
|
||||
ve.dm.example.tree = [
|
||||
// Heading with "abc"
|
||||
new ve.dm.HeadingNode( [new ve.dm.TextNode( 3 )], ve.dm.example.data[0].attributes ),
|
||||
new ve.dm.TableNode( [
|
||||
new ve.dm.TableRowNode( [
|
||||
new ve.dm.TableCellNode( [
|
||||
// Paragraph with "d"
|
||||
new ve.dm.ParagraphNode( [new ve.dm.TextNode( 1 )] ),
|
||||
new ve.dm.ListNode( [
|
||||
// 1st level bullet list item with "e"
|
||||
new ve.dm.ListItemNode( [
|
||||
new ve.dm.ParagraphNode( [new ve.dm.TextNode( 1 )] )
|
||||
] ),
|
||||
new ve.dm.ListNode( [
|
||||
// 2nd level bullet list item with "f"
|
||||
new ve.dm.ListItemNode( [
|
||||
new ve.dm.ParagraphNode( [new ve.dm.TextNode( 1 )] )
|
||||
] )
|
||||
], ve.dm.example.data[17].attributes )
|
||||
], ve.dm.example.data[11].attributes ),
|
||||
new ve.dm.ListNode( [
|
||||
// Numbered list item with "g"
|
||||
new ve.dm.ListItemNode( [
|
||||
new ve.dm.ParagraphNode( [new ve.dm.TextNode( 1 )] )
|
||||
] )
|
||||
], ve.dm.example.data[26].attributes )
|
||||
] )
|
||||
] )
|
||||
] ),
|
||||
// Preformatted with "h[image.png]i"
|
||||
new ve.dm.PreformattedNode( [
|
||||
new ve.dm.TextNode( 1 ),
|
||||
new ve.dm.ImageNode( [], ve.dm.example.data[38].attributes ),
|
||||
new ve.dm.TextNode( 1 )
|
||||
] )
|
||||
];
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Creates an offset map that references a node tree.
|
||||
*
|
||||
* This is part of what a ve.dm.DocumentFragment generates when given linear data.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.dm.DocumentNode} root Document node to reference
|
||||
*/
|
||||
ve.dm.example.getOffsets = function( root ) {
|
||||
/**
|
||||
* Looks up a value in a node tree.
|
||||
*
|
||||
* @method
|
||||
* @param {Integer} [...] Index path
|
||||
* @param {ve.Node} Node at given path
|
||||
*/
|
||||
function lookup() {
|
||||
var node = root;
|
||||
for ( var i = 0; i < arguments.length; i++ ) {
|
||||
node = node.children[arguments[i]];
|
||||
}
|
||||
return node;
|
||||
}
|
||||
return [
|
||||
lookup(), // 0 - document
|
||||
// <h1>
|
||||
lookup( 0 ), // 1 - heading
|
||||
// a
|
||||
lookup( 0 ), // 2 - heading
|
||||
// b (bold)
|
||||
lookup( 0 ), // 3 - heading
|
||||
// c (italic)
|
||||
lookup( 0 ), // 4 - heading
|
||||
// </h1>
|
||||
lookup(), // 5 - document
|
||||
// <table>
|
||||
lookup( 1 ), // 6 - table
|
||||
// <tr>
|
||||
lookup( 1, 0 ), // 7 - tableRow
|
||||
// <td>
|
||||
lookup( 1, 0, 0 ), // 8 - tableCell
|
||||
// <p>
|
||||
lookup( 1, 0, 0, 0 ), // 9 - paragraph
|
||||
// d
|
||||
lookup( 1, 0, 0, 0 ), // 10 - paragraph
|
||||
// </p>
|
||||
lookup( 1, 0, 0 ), // 11 - tableCell
|
||||
// <ul>
|
||||
lookup( 1, 0, 0, 1 ), // 12 - list
|
||||
// <li>
|
||||
lookup( 1, 0, 0, 1, 0 ), // 13 - listItem
|
||||
// <p>
|
||||
lookup( 1, 0, 0, 1, 0, 0 ), // 14 - paragraph
|
||||
// e
|
||||
lookup( 1, 0, 0, 1, 0, 0 ), // 15 - paragraph
|
||||
// </p>
|
||||
lookup( 1, 0, 0, 1, 0 ), // 16 - listItem
|
||||
// <ul>
|
||||
lookup( 1, 0, 0, 1 ), // 17 - list
|
||||
// <li>
|
||||
lookup( 1, 0, 0, 1, 0, 1, 0 ), // 18 - listItem
|
||||
// <p>
|
||||
lookup( 1, 0, 0, 1, 0, 1, 0, 0 ), // 19 - paragraph
|
||||
// f
|
||||
lookup( 1, 0, 0, 1, 0, 1, 0, 0 ), // 20 - paragraph
|
||||
// </p>
|
||||
lookup( 1, 0, 0, 1, 0, 1, 0 ), // 21 - listItem
|
||||
// </li>
|
||||
lookup( 1, 0, 0, 1, 0, 1 ), // 22 - list
|
||||
// </ul>
|
||||
lookup( 1, 0, 0, 1, 0 ), // 23 - listItem
|
||||
// </li>
|
||||
lookup( 1, 0, 0, 1 ), // 24 - list
|
||||
// </ul>
|
||||
lookup( 1, 0, 0 ), // 25 - tableCell
|
||||
// <ul>
|
||||
lookup( 1, 0, 0, 2 ), // 26 - list
|
||||
// <li>
|
||||
lookup( 1, 0, 0, 2, 0 ), // 27 - listItem
|
||||
// <p>
|
||||
lookup( 1, 0, 0, 2, 0, 0 ), // 28 - paragraph
|
||||
// g
|
||||
lookup( 1, 0, 0, 2, 0, 0 ), // 29 - paragraph
|
||||
// </p>
|
||||
lookup( 1, 0, 0, 2, 0 ), // 30 - listItem
|
||||
// </li>
|
||||
lookup( 1, 0, 0, 2 ), // 31 - list
|
||||
// </ul>
|
||||
lookup( 1, 0, 0 ), // 32 - tableCell
|
||||
// </td>
|
||||
lookup( 1, 0 ), // 33 - tableRow
|
||||
// </tr>
|
||||
lookup( 1 ), // 34 - table
|
||||
// </table>
|
||||
lookup(), // 35- document
|
||||
// <pre>
|
||||
lookup( 2 ), // 36 - preformatted
|
||||
// h
|
||||
lookup( 2 ), // 37 - preformatted
|
||||
// <img>
|
||||
lookup( 2 ), // 38 - preformatted
|
||||
// </img>
|
||||
lookup( 2 ), // 39 - preformatted
|
||||
// i
|
||||
lookup( 2 ), // 40 - preformatted
|
||||
// </pre>
|
||||
lookup() // 41 - document
|
||||
];
|
||||
};
|
|
@ -21,28 +21,48 @@
|
|||
<script src="../../modules/ve2/ve.EventEmitter.js"></script>
|
||||
<script src="../../modules/ve2/ve.Node.js"></script>
|
||||
<script src="../../modules/ve2/ve.BranchNode.js"></script>
|
||||
<script src="../../modules/ve2/ve.TwigNode.js"></script>
|
||||
<script src="../../modules/ve2/ve.LeafNode.js"></script>
|
||||
<script src="../../modules/ve2/ve.NodeFactory.js"></script>
|
||||
<script src="../../modules/ve2/ve.Position.js"></script>
|
||||
<script src="../../modules/ve2/ve.Range.js"></script>
|
||||
<script src="../../modules/ve2/ve.Surface.js"></script>
|
||||
|
||||
<!-- VisualEditor DataModel -->
|
||||
<script src="../../modules/ve2/dm/ve.dm.js"></script>
|
||||
<script src="../../modules/ve2/dm/ve.dm.Node.js"></script>
|
||||
<script src="../../modules/ve2/dm/ve.dm.BranchNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/ve.dm.TwigNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/ve.dm.LeafNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/ve.dm.DocumentFragment.js"></script>
|
||||
<script src="../../modules/ve2/dm/ve.dm.Document.js"></script>
|
||||
<script src="../../modules/ve2/dm/ve.dm.Transaction.js"></script>
|
||||
|
||||
<!-- Tests -->
|
||||
<!-- VisualEditor DataModel Nodes -->
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.AlienNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.DocumentNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.HeadingNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.ImageNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.ListItemNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.ListNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.ParagraphNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.PreformattedNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.TableCellNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.TableNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.TableRowNode.js"></script>
|
||||
<script src="../../modules/ve2/dm/nodes/ve.dm.TextNode.js"></script>
|
||||
|
||||
<!-- VisualEditor Tests -->
|
||||
<script src="ve.Node.test.js"></script>
|
||||
<script src="ve.BranchNode.test.js"></script>
|
||||
<script src="ve.TwigNode.test.js"></script>
|
||||
<script src="ve.LeafNode.test.js"></script>
|
||||
<script src="ve.NodeFactory.test.js"></script>
|
||||
|
||||
<!-- VisualEditor DataModel Tests -->
|
||||
<script src="dm/ve.dm.example.js"></script>
|
||||
<script src="dm/ve.dm.Node.test.js"></script>
|
||||
<script src="dm/ve.dm.BranchNode.test.js"></script>
|
||||
<script src="dm/ve.dm.TwigNode.test.js"></script>
|
||||
<script src="dm/ve.dm.LeafNode.test.js"></script>
|
||||
<script src="dm/ve.dm.Document.test.js"></script>
|
||||
<script src="dm/ve.dm.DocumentFragment.test.js"></script>
|
||||
<script src="dm/ve.dm.Transaction.test.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in a new issue