From c986f6ebfd3d20bdc75ce00ee09bd2c716e0cb16 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksander=20=C5=81ukasz?= Date: Thu, 27 Jun 2013 09:41:49 +0200 Subject: [PATCH 1/1] WIP: Refactoring canvas api - canvas, canvasNode + tests todo: integration into the rest of the documentCanvas module and its helper modules --- modules/documentCanvas/canvas.js | 190 ++++++------ modules/documentCanvas/canvasNode.js | 56 ++++ modules/documentCanvas/template.html | 3 +- modules/documentCanvas/tests/canvas.test.js | 278 +++++++++--------- .../documentCanvas/tests/canvasNode.test.js | 47 +++ modules/documentCanvas/tests/utils.js | 24 +- 6 files changed, 357 insertions(+), 241 deletions(-) create mode 100644 modules/documentCanvas/canvasNode.js create mode 100644 modules/documentCanvas/tests/canvasNode.test.js diff --git a/modules/documentCanvas/canvas.js b/modules/documentCanvas/canvas.js index 0d4ad75..c2f6c85 100644 --- a/modules/documentCanvas/canvas.js +++ b/modules/documentCanvas/canvas.js @@ -2,88 +2,79 @@ define([ 'libs/jquery-1.9.1.min', 'libs/underscore-min', 'modules/documentCanvas/transformations', -'modules/documentCanvas/wlxmlNode', +'modules/documentCanvas/canvasNode', 'libs/text!./template.html' -], function($, _, transformations, wlxmlNode, template) { +], function($, _, transformations, canvasNode, template) { 'use strict'; -var Canvas = function(xml) { +var Canvas = function(html) { this.dom = $(template); this.content = this.dom.find('#rng-module-documentCanvas-content'); - this.setXML(xml); -} - -Canvas.prototype.setXML = function(xml) { - this.xml = $.trim(xml); - this.content.html(transformations.fromXML.getHTMLTree(this.xml)); -} + if(html) { + this.content.html(html); + } +}; -Canvas.prototype.toXML = function() { - return transformations.toXML.getXML(this.content.html()); -} +Canvas.prototype.getContent = function() { + return this.content.contents(); +}; -Canvas.prototype.getNode = function(desc) { +Canvas.prototype.findNodes = function(desc) { var selector = ''; - if(desc.klass) - selector += '[wlxml-class=' + desc.klass + ']'; - if(desc.tag) - selector += '[wlxml-tag=' + desc.tag + ']'; + if(typeof desc === 'string') { + selector = desc; + } + else { + if(desc.klass) + selector += '[wlxml-class=' + desc.klass + ']'; + if(desc.tag) + selector += '[wlxml-tag=' + desc.tag + ']'; + } var toret = []; this.content.find(selector).each(function() { - toret.push(new wlxmlNode.Node($(this))); + toret.push(canvasNode.create($(this))); }); return toret; -} - -Canvas.prototype.getPreviousNode = function(options) { - var element = $(this.content.find('#' + options.node.id).get(0)); - var prev = element.prev() - if(prev.length === 0) - prev = element.parent(); - return new wlxmlNode.Node(prev); -} - -Canvas.prototype._createNode = function(wlxmlTag, wlxmlClass) { - var toBlock = ['div', 'document', 'section', 'header']; - var htmlTag = _.contains(toBlock, wlxmlTag) ? 'div' : 'span'; - var toret = $('<' + htmlTag + '>'); - toret.attr('wlxml-tag', wlxmlTag); - if(wlxmlClass) - toret.attr('wlxml-class', wlxmlClass); - toret.attr('id', 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = Math.random()*16|0,v=c=='x'?r:r&0x3|0x8;return v.toString(16);})); - return toret; - }; - -Canvas.prototype.insertNode = function(options) { - var element = $(this.content.find('#' + options.context.id).get(0)); - if(options.place == 'after') { - var node = this._createNode(options.tag, options.klass); - element[options.place](node); - return node; - } - else if(options.place == 'wrapText') { - var elementContents = element.contents(); - if(elementContents.length !== 1 || elementContents.get(0).nodeType != 3) - return false; - var textElement = elementContents.get(0); - - var prefix = textElement.data.substr(0, options.offsetStart); - var suffix = textElement.data.substr(options.offsetEnd); - var core = textElement.data.substr(options.offsetStart, options.offsetEnd - options.offsetStart); - var newNode = this._createNode(options.tag, options.klass); - newNode.text(core); - $(textElement).replaceWith(newNode); - newNode.before(prefix); - newNode.after(suffix); - return newNode; +}; + +Canvas.prototype.nodeAppend = function(options) { + var element; // = $(this.content.find('#' + options.context.id).get(0)); + if(options.to === 'root') { + element = this.content; + } else { + element = $(this.content.find('#' + options.to.getId()).get(0)); } -} + element.append(options.node.dom); +}; + +Canvas.prototype.nodeInsertAfter = function(options) { + var element = $(this.content.find('#' + options.after.getId()).get(0)); + element.after(options.node.dom); +}; + +Canvas.prototype.nodeWrap = function(options) { + var element = $(this.content.find('#' + options.inside.getId()).get(0)); -Canvas.prototype.splitNode = function(options) { + var elementContents = element.contents(); + if(elementContents.length !== 1 || elementContents.get(0).nodeType != 3) + return false; + var textElement = elementContents.get(0); + + var prefix = textElement.data.substr(0, options.offsetStart); + var suffix = textElement.data.substr(options.offsetEnd); + var core = textElement.data.substr(options.offsetStart, options.offsetEnd - options.offsetStart); + options._with.setContent(core); + + $(textElement).replaceWith(options._with.dom); + options._with.dom.before(prefix); + options._with.dom.after(suffix); +}; + +Canvas.prototype.nodeSplit = function(options) { options = _.extend({textNodeIdx: 0}, options); - var nodeToSplit = $(this.content.find('#' + options.node.id).get(0)); + var nodeToSplit = $(this.content.find('#' + options.node.getId()).get(0)); var nodeContents = nodeToSplit.contents(); if(nodeContents.length === 0 || @@ -103,30 +94,29 @@ Canvas.prototype.splitNode = function(options) { passed = true; }); - var prefix = textNode.text().substr(0, options.offset); - var suffix = textNode.text().substr(options.offset); + var prefix = $.trim(textNode.text().substr(0, options.offset)); + var suffix = $.trim(textNode.text().substr(options.offset)); textNode.before(prefix); textNode.remove(); - var newNode = this._createNode(nodeToSplit.attr('wlxml-tag'), nodeToSplit.attr('wlxml-class')); - newNode.append(suffix); + var newNode = canvasNode.create({tag: nodeToSplit.attr('wlxml-tag'), klass: nodeToSplit.attr('wlxml-class')}); + newNode.dom.append(suffix); succeedingNodes.forEach(function(node) { - newNode.append(node) + newNode.dom.append(node) }); - nodeToSplit.after(newNode); + nodeToSplit.after(newNode.dom); return newNode; -} +}; -Canvas.prototype.removeNode = function(options) { - var toRemove = $(this.content.find('#' + options.node.id).get(0)); +Canvas.prototype.nodeRemove = function(options) { + var toRemove = $(this.content.find('#' + options.node.getId()).get(0)); toRemove.remove(); +}; -} - -Canvas.prototype.createList = function(options) { - var element1 = $(this.content.find('#' + options.start.id).get(0)); - var element2 = $(this.content.find('#' + options.end.id).get(0)); +Canvas.prototype.listCreate = function(options) { + var element1 = $(this.content.find('#' + options.start.getId()).get(0)); + var element2 = $(this.content.find('#' + options.end.getId()).get(0)); if(!element1.parent().get(0).isSameNode(element2.parent().get(0))) return false; @@ -137,7 +127,6 @@ Canvas.prototype.createList = function(options) { element1 = element2; element2 = tmp; } - var nodesToWrap = []; @@ -150,7 +139,7 @@ Canvas.prototype.createList = function(options) { if(place === 'inside') { var $node; if(node.nodeType === 3) { - $node = canvas._createNode('div').text(node.data); + $node = canvasNode.create({tag: 'div', content: $.trim(node.data)}).dom; //canvas._createNode('div').text(node.data); $(node).remove(); } else { @@ -163,38 +152,47 @@ Canvas.prototype.createList = function(options) { return false; }); - var list = this._createNode('div', 'list-items'); + var list = canvasNode.create({tag: 'div', klass: 'list-items'}).dom; //this._createNode('div', 'list-items'); element1.before(list); nodesToWrap.forEach(function(node) { node.remove(); list.append(node); }); -} +}; -Canvas.prototype.removeList = function(options) { - var pointerElement = $(this.content.find('#' + options.pointer.id)); - var listElement = options.pointer.klass === 'list-items' ? pointerElement : +Canvas.prototype.listRemove = function(options) { + var pointerElement = $(this.content.find('#' + options.pointer.getId())); + var listElement = options.pointer.getClass() === 'list-items' ? pointerElement : pointerElement.parent('[wlxml-class="list-items"][wlxml-tag]'); listElement.find('[wlxml-class=item]').each(function() { - $(this).attr('wlxml-class', ''); - });; + $(this).removeAttr('wlxml-class'); + }); listElement.children().unwrap(); - -} +}; + +Canvas.prototype.getPrecedingNode = function(options) { + var element = $(this.content.find('#' + options.node.getId()).get(0)); + var prev = element.prev() + if(prev.length === 0) + prev = element.parent(); + return canvasNode.create(prev); +}; -Canvas.prototype.insideList = function(options) { +Canvas.prototype.nodeInsideList = function(options) { if(options.pointer) { - if(options.pointer.klass === 'list-items' || options.pointer.klass === 'item') + if(options.pointer.getClass() === 'list-items' || options.pointer.getClass() === 'item') return true; - var pointerElement = $(this.content.find('#' + options.pointer.id)); - return pointerElement.parents('list-items').length > 0; + var pointerElement = $(this.content.find('#' + options.pointer.getId())); + return pointerElement.parents('list-items, item').length > 0; } return false; -} +}; -return {Canvas: Canvas, Node: Node}; +return { + create: function(desc) { return new Canvas(desc); } +}; }); \ No newline at end of file diff --git a/modules/documentCanvas/canvasNode.js b/modules/documentCanvas/canvasNode.js new file mode 100644 index 0000000..0bfd358 --- /dev/null +++ b/modules/documentCanvas/canvasNode.js @@ -0,0 +1,56 @@ +define(['libs/jquery-1.9.1.min'], function($) { + +'use strict'; + +var CanvasNode = function(desc) { + if(desc instanceof $) { + this.dom = desc; + if(!this.dom.attr('id')) { + this.dom.attr('id', 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = Math.random()*16|0,v=c=='x'?r:r&0x3|0x8;return v.toString(16);})); + } + } else { + var toBlock = ['div', 'document', 'section', 'header']; + var htmlTag = _.contains(toBlock, desc.tag) ? 'div' : 'span'; + this.dom = $('<' + htmlTag + '>'); + this.dom.attr('wlxml-tag', desc.tag); + if(desc.klass) + this.dom.attr('wlxml-class', desc.klass); + if(desc.content) + this.dom.text(desc.content); + this.dom.attr('id', 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = Math.random()*16|0,v=c=='x'?r:r&0x3|0x8;return v.toString(16);})); + } +}; + +CanvasNode.prototype.getTag = function() { + return this.dom.attr('wlxml-tag'); +} + +CanvasNode.prototype.getClass = function() { + return this.dom.attr('wlxml-class'); +} + +CanvasNode.prototype.getId = function() { + return this.dom.attr('id'); +} + +CanvasNode.prototype.getContent = function() { + return this.dom.text(); +} + +CanvasNode.prototype.setContent = function(content) { + this.dom.text(content); +} + +CanvasNode.prototype.isSame = function(other) { + return this.dom.get(0).isSameNode(other.dom.get(0)); +} + +return { + create: function(desc) { + return new CanvasNode(desc); + } + +} + + +}); \ No newline at end of file diff --git a/modules/documentCanvas/template.html b/modules/documentCanvas/template.html index b4d7dd7..c973f1b 100644 --- a/modules/documentCanvas/template.html +++ b/modules/documentCanvas/template.html @@ -1,8 +1,7 @@
-
-
+
\ No newline at end of file diff --git a/modules/documentCanvas/tests/canvas.test.js b/modules/documentCanvas/tests/canvas.test.js index 53bd35d..0589c11 100644 --- a/modules/documentCanvas/tests/canvas.test.js +++ b/modules/documentCanvas/tests/canvas.test.js @@ -2,181 +2,177 @@ define([ 'libs/jquery-1.9.1.min', 'libs/chai', './utils.js', -'modules/documentCanvas/canvas' -], function($, chai, utils, canvas) { +'modules/documentCanvas/canvas', +'modules/documentCanvas/canvasNode' +], function($, chai, utils, canvas, canvasNode) { 'use strict'; var assert = chai.assert; + var assertDomEqual = utils.assertDomEqual; - assert.xmlEqual = function(lhsText, rhsText) { - var cleanLhs = utils.cleanUp(lhsText); - var cleanRhs = utils.cleanUp(rhsText); - - var lhs = $(cleanLhs); - var rhs = $(cleanRhs); - - this.equal(lhs.length, 1); - this.equal(rhs.length, 1); - - lhs = lhs.get(0); - rhs = rhs.get(0); - - var test = lhs.isEqualNode(rhs); - if(!test) { - console.log(cleanLhs); - console.log(cleanRhs); - } - return this.ok(test, 'xmls are equal'); - }; - var retrievingTest = function(title, xml) { - test(title, function() { - var c = new canvas.Canvas(xml); - assert.xmlEqual(c.toXML(), xml); + suite('Quering nodes', function() { + test('getting preceding node', function() { + var c = canvas.create('
a
b
'); + var secondP = c.findNodes({tag: 'p'})[1]; + var firstP = c.getPrecedingNode({node: secondP}); + assert.equal(firstP.getContent(), 'a'); }); - }; - - suite('Basic document retrieving', function() { - test('empty document', function() { - var c = new canvas.Canvas(''); - assert.equal(c.toXML(), ''); + + test('pervious node of node without "previous siblings" is its parent', function() { + var c = canvas.create('
a
'); + var paragraph = c.findNodes({tag: 'p'})[0]; + assert.equal(c.getPrecedingNode({node: paragraph}).getTag(), 'section'); }); - retrievingTest('empty tag', '
'); - retrievingTest('tag with content', '
Some text
'); - retrievingTest('tag with class', '
'); + }); - suite('Nodes', function() { - test('getting nodes via selector', function() { - var c = new canvas.Canvas('
Header 1
'); - var header = c.getNode({tag: 'header'})[0]; - assert.equal(header.tag, 'header'); - assert.equal(header.klass, 'some-class'); - }); + + suite('Inserting nodes', function() { + test('append node to root', function() { + var c = canvas.create(); + var node = canvasNode.create({tag: 'header', klass: 'some-class'}); + c.nodeAppend({node: node, to: 'root'}); + assertDomEqual(c.getContent(), '
'); + }); - test('getting previous node', function() { - var c = new canvas.Canvas('
Div 1
Div 2
'); - var secondDiv = c.getNode({tag: 'div'})[1]; - var firstDiv = c.getPreviousNode({node: secondDiv}); - assert.equal(firstDiv.klass, 'some-class'); - }) + test('append node to another node', function() { + var c = canvas.create('
'); + var node = canvasNode.create({tag: 'header', klass: 'some-class'}); + var to = c.findNodes('div')[0]; + c.nodeAppend({node: node, to: to}); + assertDomEqual(c.getContent(), '
'); + }); - test('pervious node of node without "previous siblings" is its parent', function() { - var c = new canvas.Canvas('
Div 1
'); - var div = c.getNode({tag: 'div'})[0]; - var section = c.getPreviousNode({node: div}); - assert.equal(section.tag, 'section'); - }) - - test('inserting after', function() { - var c = new canvas.Canvas('
Header 1
'); - var header = c.getNode({tag: 'header'})[0]; - c.insertNode({place: 'after', context: header, tag: 'div', klass: 'some.class'}); - assert.xmlEqual(c.toXML(), '
Header 1
'); + test('insert node after another node', function() { + var c = canvas.create('
'); + var node = canvasNode.create({tag: 'header', klass: 'some-class'}); + var after = c.findNodes('div')[0]; + c.nodeInsertAfter({node: node, after: after}); + assertDomEqual(c.getContent(), '
'); }); test('wrap text in node', function() { - var c = new canvas.Canvas('
Header 1
'); - var header = c.getNode({tag: 'header'})[0]; - c.insertNode({place: 'wrapText', context: header, tag: 'span', klass: 'url', offsetStart: 1, offsetEnd: 6}); - assert.xmlEqual(c.toXML(), '
Header 1
'); + var c = canvas.create('
Header 1
'); + var header = c.findNodes({tag: 'header'})[0]; + var wrapper = canvasNode.create({tag: 'aside'}); + c.nodeWrap({inside: header, _with: wrapper, offsetStart: 1, offsetEnd: 6}) + assertDomEqual(c.getContent(), '
Header 1
'); }); test('split node', function() { - var c = new canvas.Canvas('
Header 1
'); - var header = c.getNode({tag: 'header'})[0]; - c.splitNode({node: header, offset: 4}); - assert.xmlEqual(c.toXML(), '\ -
\ -
Head
\ -
er 1
\ -
' - ); + var c = canvas.create('
Header 1
'); + var header = c.findNodes({tag: 'header'})[0]; + var newNode = c.nodeSplit({node: header, offset: 4}); + assertDomEqual(c.getContent(), utils.cleanUp('\ +
\ +
Head
\ +
er 1
\ +
')); + assert.ok(newNode.isSame(c.findNodes({tag: 'header'})[1])); + }); + + test('split root node', function() { + var c = canvas.create('
cat
'); + var header = c.findNodes({tag: 'header'})[0]; + var newNode = c.nodeSplit({node: header, offset: 1}); + assertDomEqual(c.getContent(), utils.cleanUp('\ +
c
\ +
at
')); + assert.ok(newNode.isSame(c.findNodes({tag: 'header'})[1])); }); test('split node with subnodes', function() { - var c = new canvas.Canvas('
Fancy and nice header 1
'); - var header = c.getNode({tag: 'header'})[0]; - c.splitNode({node: header, textNodeIdx: 0, offset: 5}); - assert.xmlEqual(c.toXML(), '\ -
\ -
Fancy
\ -
and nice header 1
\ -
' - ); + var c = canvas.create(utils.cleanUp('\ +
\ +
Fancy and niceheader 1
\ +
')); + var header = c.findNodes({tag: 'header'})[0]; + var newNode = c.nodeSplit({node: header, offset: 5}); + assertDomEqual(c.getContent(), utils.cleanUp('\ +
\ +
Fancy
\ +
and niceheader 1
\ +
')); }); test('remove node', function() { - var c = new canvas.Canvas('
Fancy and nice header 1
'); - var span = c.getNode({tag: 'span'})[0]; - var siblings = c.removeNode({node:span}); - assert.xmlEqual(c.toXML(), '\ -
\ -
Fancy and nice 1
\ -
' - ); + var c = canvas.create('
some text
'); + var span = c.findNodes({tag: 'span'})[0]; + c.nodeRemove({node: span}); + assertDomEqual(c.getContent(), '
'); }); - - test('create list from existing nodes', function() { - var c = new canvas.Canvas('
Alice
has
a cat
some text
'); - var div1 = c.getNode({tag:'div'})[0]; - var div2 = c.getNode({tag:'div'})[1]; + }); + + + suite('Lists', function() { + test('create from existing nodes', function() { + var c = canvas.create(utils.cleanUp('\ +
\ +
alice
\ + has\ +
a
\ +
cat
\ +
or not
\ +
' + )); + + var div_alice = c.findNodes({tag: 'div'})[0]; + var div_cat = c.findNodes({tag:'div'})[2]; - c.createList({start: div1, end: div2}); + c.listCreate({start: div_alice, end: div_cat}); - assert.xmlEqual(c.toXML(), '\ -
\ -
\ -
Alice
\ -
has
\ -
a cat
\ + assertDomEqual(c.getContent(), utils.cleanUp('\ +
\ +
\ +
alice
\ +
has
\ +
a
\ +
cat
\
\ -
some text
\ -
'); - +
or not
\ +
')); }); - test('create list from existing nodes reverse', function() { - var c = new canvas.Canvas('
Alice
has
a cat
some text
'); - var div1 = c.getNode({tag:'div'})[0]; - var div2 = c.getNode({tag:'div'})[1]; - - c.createList({start: div2, end: div1}); + test('create from existing nodes - start/end order doesn\'t matter', function() { + var html = utils.cleanUp('\ +
alice
\ +
cat
'); + var expected = utils.cleanUp('\ +
\ +
alice
\ +
cat
\ +
'); + + var c = canvas.create(html); + var div_alice = c.findNodes({tag: 'div'})[0]; + var div_cat = c.findNodes({tag:'div'})[1]; + c.listCreate({start: div_cat, end: div_alice}); + assertDomEqual(c.getContent(), expected); - assert.xmlEqual(c.toXML(), '\ -
\ -
\ -
Alice
\ -
has
\ -
a cat
\ -
\ -
some text
\ -
'); - + c = canvas.create(html); + div_alice = c.findNodes({tag: 'div'})[0]; + div_cat = c.findNodes({tag:'div'})[1]; + c.listCreate({start: div_alice, end: div_cat}); + assertDomEqual(c.getContent(), expected); }); - test('remove list', function() { - var xml = '\ -
\ -
\ -
Alice
\ -
has
\ -
a cat
\ + test('remove', function() { + var c = canvas.create(utils.cleanUp('\ +
\ +
\ +
alice
\ +
cat
\
\ -
some text
\ -
'; - var c = new canvas.Canvas(xml); - var item = c.getNode({klass: 'item'})[1]; - c.removeList({pointer: item}); - assert.xmlEqual(c.toXML(), '\ -
\ -
Alice
\ -
has
\ -
a cat
\ -
some text
\ -
'); + ')); + var item = c.findNodes({klass: 'item'})[1]; + c.listRemove({pointer: item}); + assertDomEqual(c.getContent(), utils.cleanUp('\ +
\ +
alice
\ +
cat
\ +
')); }); }); - }); \ No newline at end of file diff --git a/modules/documentCanvas/tests/canvasNode.test.js b/modules/documentCanvas/tests/canvasNode.test.js new file mode 100644 index 0000000..bc11a80 --- /dev/null +++ b/modules/documentCanvas/tests/canvasNode.test.js @@ -0,0 +1,47 @@ +define([ +'libs/jquery-1.9.1.min', +'libs/chai', +'./utils.js', +'modules/documentCanvas/canvasNode' +], function($, chai, utils, canvasNode) { + +'use strict'; + +var assert = chai.assert; + +var assertDomEqual = function(lhs, rhs) { + lhs.attr('id', ''); + rhs.attr('id', ''); + return assert.ok(lhs[0].isEqualNode(rhs[0]), 'nodes are equal'); + +} + +suite('Create canvas node', function() { + test('from description', function() { + var node = canvasNode.create({tag: 'header', klass: 'some-class', content: 'some text content'}); + assert.equal(node.getTag(), 'header'); + assert.equal(node.getClass(), 'some-class'); + assert.equal(node.getContent(), 'some text content'); + assertDomEqual($('
some text content
'), node.dom); + }); + + test('from dom object', function() { + var node = canvasNode.create($('
')); + assert.equal(node.getTag(), 'header'); + assert.equal(node.getClass(), 'some-class'); + //assertDomEqual($('
'), node.dom); + }); +}); + +suite('comparing nodes', function() { + test('isSame', function() { + var html = '
'; + var dom1 = $(html); + var dom2 = $(html); + assert.ok(canvasNode.create(dom1).isSame(canvasNode.create(dom1))); + assert.notOk(canvasNode.create(dom1).isSame(canvasNode.create(dom2))); + }); +}); + + +}); \ No newline at end of file diff --git a/modules/documentCanvas/tests/utils.js b/modules/documentCanvas/tests/utils.js index e23808c..cf1f7c2 100644 --- a/modules/documentCanvas/tests/utils.js +++ b/modules/documentCanvas/tests/utils.js @@ -1,7 +1,6 @@ -define(['libs/jquery-1.9.1.min'], function($) { +define(['libs/jquery-1.9.1.min', 'libs/chai'], function($, chai) { return { cleanUp: function(xml) { - var rmws = function(node) { if(node.nodeType === 3) { node.data = $.trim(node.data); @@ -24,6 +23,27 @@ define(['libs/jquery-1.9.1.min'], function($) { .replace(/(<\/.*>)\s*(<.*>)/gm, '$1$2'); return $.trim(toret);*/ return $('
').append(xml).html(); + }, + + assertDomEqual: function(lhs, rhs) { + lhs = lhs.clone(); + var rhsArr = $.parseHTML(rhs); + if(rhsArr.length === 1) { + rhs = $(rhsArr[0]); + } else { + rhs = $('
'); + $.each(rhsArr, function(i, el) { + rhs.append(el); + }); + } + if(lhs.length > 1) { + lhs = $('
').append(lhs); + } + lhs.attr('id', ''); + rhs.attr('id', ''); + lhs.find('*').each(function() {$(this).attr('id', '');}); + rhs.find('*').each(function() {$(this).attr('id', '');}); + return chai.assert.ok(lhs[0].isEqualNode(rhs[0]), 'nodes are equal'); } } }); \ No newline at end of file -- 2.20.1