From: Aleksander Ɓukasz Date: Fri, 22 Nov 2013 14:16:06 +0000 (+0100) Subject: wlxml: inheritance in meta attributes keys, sligthly changed meta attrs api X-Git-Url: https://git.mdrn.pl/fnpeditor.git/commitdiff_plain/275952d30bfcd6f5aecc2710a0df0cd489ea71f6?ds=inline;hp=bc95fc1358ca35ecbd410d50b3c8c40e1afe0fa9 wlxml: inheritance in meta attributes keys, sligthly changed meta attrs api --- diff --git a/src/wlxml/wlxml.js b/src/wlxml/wlxml.js index 9b852ae..fb5b328 100644 --- a/src/wlxml/wlxml.js +++ b/src/wlxml/wlxml.js @@ -1,7 +1,8 @@ define([ 'libs/jquery', + 'libs/underscore', 'smartxml/smartxml' -], function($, smartxml) { +], function($, _, smartxml) { 'use strict'; @@ -13,6 +14,13 @@ var isMetaAttribute = function(attrName) { // +var AttributesList = function() {}; +AttributesList.prototype = Object.create({}); +AttributesList.prototype.keys = function() { + return _.keys(this); +}; + + var WLXMLElementNode = function(nativeNode, document) { smartxml.ElementNode.call(this, nativeNode, document); }; @@ -20,18 +28,25 @@ WLXMLElementNode.prototype = Object.create(smartxml.ElementNode.prototype); $.extend(WLXMLElementNode.prototype, smartxml.ElementNode.prototype, { getClass: function() { - return this.getAttr('class'); + return this.getAttr('class') || ''; }, setClass: function(klass) { return this.setAttr('class', klass); }, getMetaAttributes: function() { - var toret = []; - this.getAttrs().forEach(function(attr) { - if(isMetaAttribute(attr.name)) { - toret.push({name: attr.name.substr(5), value: attr.value}); + var toret = new AttributesList(), + classParts = [''].concat(this.getClass().split('.')), + classCurrent, classDesc; + + classParts.forEach(function(part) { + classCurrent = classCurrent ? classCurrent + '.' + part : part; + classDesc = this.document.options.wlxmlClasses[classCurrent]; + if(classDesc) { + _.keys(classDesc.attrs).forEach(function(attrName) { + toret[attrName] = _.extend({value: this.getAttr('meta-' + attrName)}, classDesc.attrs[attrName]); + }.bind(this)); } - }); + }.bind(this)); return toret; }, getOtherAttributes: function() { @@ -95,8 +110,9 @@ $.extend(WLXMLElementNode.prototype, smartxml.ElementNode.prototype, { -var WLXMLDocument = function(xml) { +var WLXMLDocument = function(xml, options) { smartxml.Document.call(this, xml); + this.options = options; }; var formatter_prefix = '_wlxml_formatter_'; @@ -194,10 +210,16 @@ $.extend(WLXMLDocument.prototype, { }); +var wlxmlClasses = { + 'uri': { + attrs: {uri: {type: 'string'}} + } +}; return { - WLXMLDocumentFromXML: function(xml) { - return new WLXMLDocument(xml); + WLXMLDocumentFromXML: function(xml, options) { + options = _.extend({wlxmlClasses: wlxmlClasses}, options); + return new WLXMLDocument(xml, options); }, WLXMLElementNodeFromXML: function(xml) { diff --git a/src/wlxml/wlxml.test.js b/src/wlxml/wlxml.test.js index c210a71..c802ae3 100644 --- a/src/wlxml/wlxml.test.js +++ b/src/wlxml/wlxml.test.js @@ -5,6 +5,7 @@ define([ 'use strict'; +/* jshint expr:true */ /* global it, describe */ var expect = chai.expect; @@ -13,8 +14,8 @@ var nodeFromXML = function(xml) { return wlxml.WLXMLElementNodeFromXML(xml); }; -var getDocumentFromXML = function(xml) { - return wlxml.WLXMLDocumentFromXML(xml); +var getDocumentFromXML = function(xml, options) { + return wlxml.WLXMLDocumentFromXML(xml, options || {}); }; @@ -26,17 +27,81 @@ describe('WLXMLDocument', function() { expect(node.getClass()).to.equal('class.subclass'); }); - it('returns its attributes as dict', function() { - var node = nodeFromXML(''); - expect(node.getMetaAttributes()).to.eql([{name: 'attr1', value: 'val1'}, {name: 'attr2', value: 'val2'}]); - }); - it('returns attributes other than class and meta-* as other attributes', function() { var node = nodeFromXML(''); expect(node.getOtherAttributes()).to.eql({attr1: 'val1', attr2: 'val2'}); }); }); + describe('WLXML node meta attributes', function() { + + it('inherits keys from super classes', function() { + var testClasses = { + '': { + attrs: {'common': {type: 'string'}} + }, + 'a': { + attrs: {'a_attr': {type: 'string'}} + }, + 'a.b': { + attrs: {'a_b_attr': {type: 'string'}} + }, + 'a.b.c': { + attrs: {'a_b_c_attr': {type: 'string'}} + } + }, + doc = getDocumentFromXML('
', {wlxmlClasses: testClasses}), + section = doc.root; + + expect(section.getMetaAttributes().keys()).to.eql(['common']); + + section.setClass('a'); + expect(section.getMetaAttributes().keys().sort()).to.eql(['common', 'a_attr'].sort()); + + section.setClass('a.b'); + expect(section.getMetaAttributes().keys().sort()).to.eql(['common', 'a_attr', 'a_b_attr'].sort()); + + section.setClass('a.b.c'); + expect(section.getMetaAttributes().keys().sort()).to.eql(['common', 'a_attr', 'a_b_attr', 'a_b_c_attr'].sort()); + }); + + describe('api', function() { + it('returns meta attributes as a dict', function() { + var testClasses = { + 'test': { + attrs: { + attr1: {type: 'string'}, + attr2: {type: 'date'} + } + } + }, + node = getDocumentFromXML( + '', + {wlxmlClasses: testClasses} + ).root, + attrs = node.getMetaAttributes(); + + expect(attrs.keys().sort()).to.eql(['attr1', 'attr2'].sort()); + expect(attrs.attr1.value).to.equal('val1'); + expect(attrs.attr1.type).to.equal('string'); + expect(attrs.attr2.value).to.equal('2014-01-01'); + expect(attrs.attr2.type).to.equal('date'); + }); + it('returns undefined value if attribute is missing', function() { + var testClasses = { + 'test': { + attrs: { + attr1: {type: 'string'}, + } + } + }, + node = getDocumentFromXML('', {wlxmlClasses: testClasses}).root, + attrs = node.getMetaAttributes(); + expect(attrs.attr1.value).to.be.undefined; + }); + }); + }); + describe('White space handling', function() { it('ignores white space surrounding block elements', function() { var node = nodeFromXML('
'),