From ae032450627538fabf7df31fbda6cf7bd097b94f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksander=20=C5=81ukasz?= Date: Fri, 17 Jan 2014 15:09:37 +0100 Subject: [PATCH] wlxml: metadata wip - first approach --- src/wlxml/wlxml.js | 59 +++++++++++++++++++++++++++++++++++++---- src/wlxml/wlxml.test.js | 33 ++++++++++++++++++++++- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/src/wlxml/wlxml.js b/src/wlxml/wlxml.js index 820b95f..c3ed84f 100644 --- a/src/wlxml/wlxml.js +++ b/src/wlxml/wlxml.js @@ -8,6 +8,7 @@ define([ 'use strict'; /* globals Node */ +var metadataKey = 'wlxml.metadata'; var AttributesList = function() {}; @@ -78,8 +79,29 @@ $.extend(WLXMLElementNode.prototype, smartxml.ElementNode.prototype, { return attrName !== 'class' &&_.contains(_.keys(this.getMetaAttributes()), attrName); }, + getMetadata: function() { + return this.getData(metadataKey) || []; + }, + + addMetadataRow: function(row) { + this.setMetadataRow(null, row); + }, + + setMetadataRow: function(index, row) { + var metadata = this.getData(metadataKey) || []; + if(typeof index !== 'number' || index > metadata.length - 1) { + metadata.push(row); + index = metadata.length - 1; + } else { + metadata[index] = _.extend(metadata[index], row); + } + this.setData(metadataKey, metadata); + this.triggerChangeEvent('metadataChange', {index: index}); + }, + _getXMLDOMToDump: function() { - var DOM = this._$.clone(true, true); + var DOM = this._$.clone(true, true), + doc = this.document; DOM.find('*').addBack().each(function() { var el = $(this), @@ -89,7 +111,7 @@ $.extend(WLXMLElementNode.prototype, smartxml.ElementNode.prototype, { data = el.data(); - var txt; + var txt, documentNode, metaNode; if(data[formatter_prefix+ 'orig_before']) { txt = idx > 0 && contents[idx-1].nodeType === Node.TEXT_NODE ? contents[idx-1] : null; @@ -119,8 +141,23 @@ $.extend(WLXMLElementNode.prototype, smartxml.ElementNode.prototype, { el.append(data[formatter_prefix+ 'orig_end']); } } + + + if(this.nodeType === Node.ELEMENT_NODE) { + documentNode = doc.createDocumentNode(this); + metaNode = $(''); + documentNode.getMetadata().forEach(function(row) { + metaNode.append('' + row.value + ''); + }); + if(metaNode.children().length) { + $(this).prepend(metaNode); + } + } + }); + + return DOM; } }); @@ -143,11 +180,10 @@ var WLXMLDocumentNode = function() { WLXMLDocumentNode.prototype = Object.create(smartxml.DocumentNode.prototype); var WLXMLDocument = function(xml, options) { - smartxml.Document.call(this, xml); - this.options = options; - this.classMethods = {}; this.classTransformations = {}; + smartxml.Document.call(this, xml); + this.options = options; }; var formatter_prefix = '_wlxml_formatter_'; @@ -162,6 +198,9 @@ $.extend(WLXMLDocument.prototype, { }, normalizeXML: function(nativeNode) { + var doc = this, + prefixLength = 'dc:'.length; + $(nativeNode).find(':not(iframe)').addBack().contents() .filter(function() {return this.nodeType === Node.TEXT_NODE;}) .each(function() { @@ -244,6 +283,16 @@ $.extend(WLXMLDocument.prototype, { /* globals document */ el.replaceWith(document.createTextNode(text.transformed)); }); + + $(nativeNode).find('metadata').each(function() { + var metadataNode = $(this), + owner = doc.createDocumentNode(metadataNode.parent()[0]); + + metadataNode.children().each(function() { + owner.addMetadataRow({key: (this.tagName).toLowerCase().substr(prefixLength), value: $(this).text()}); + }); + metadataNode.remove(); + }); }, registerClassTransformation: function(Transformation, className) { diff --git a/src/wlxml/wlxml.test.js b/src/wlxml/wlxml.test.js index 516b47c..7eb8efb 100644 --- a/src/wlxml/wlxml.test.js +++ b/src/wlxml/wlxml.test.js @@ -1,7 +1,8 @@ define([ + 'libs/jquery', 'libs/chai', './wlxml.js' -], function(chai, wlxml) { +], function($, chai, wlxml) { 'use strict'; @@ -291,8 +292,38 @@ describe('WLXMLDocument', function() { expect(testClassNode.object.testTransformation().sameNode(testClassNode)).to.equal(true, '1'); expect(testClassNode.object.testTransformation2().sameNode(testClassNode)).to.equal(true, '1'); }); + }); + + describe.only('Metadata API', function() { + it('allows to set metadata on an element node', function() { + var doc = getDocumentFromXML('
'); + expect(doc.root.getMetadata()).to.deep.equal([]); + doc.root.addMetadataRow({key: 'key', value: 'value'}); + expect(doc.root.getMetadata()).to.deep.equal([{key: 'key', value: 'value'}]); + }); + + it('reads node\'s metadata from its metadata child node', function() { + var doc = getDocumentFromXML('
value
'); + expect(doc.root.getMetadata()).to.deep.equal([{key: 'key', value: 'value'}]); + }); + it('serializes node\'s metadata to its metadata child node', function() { + var doc = getDocumentFromXML('
'); + doc.root.addMetadataRow({key: 'key', value: 'value'}); + + var metadataNodes = $(doc.toXML()).children('metadata'), + keyNodes = metadataNodes.children(); + + expect(metadataNodes).to.have.length(1); + expect(keyNodes).to.have.length(1); + expect(keyNodes[0].tagName.toLowerCase()).to.equal('dc:key'); + expect($(keyNodes[0]).text()).to.equal('value'); + }); + it('doesnt show metadata node on nodes contents', function() { + var doc = getDocumentFromXML('
value
'); + expect(doc.root.contents()).to.have.length(0); + }); }); }); -- 2.20.1