Finishing first take on node meta attributes editing
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Tue, 2 Jul 2013 11:26:56 +0000 (13:26 +0200)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Tue, 2 Jul 2013 11:26:56 +0000 (13:26 +0200)
modules/documentCanvas/canvasNode.js
modules/documentCanvas/classAttributes.js [new file with mode: 0644]
modules/documentCanvas/tests/canvasNode.test.js
modules/documentCanvas/tests/classAttributes.test.js [new file with mode: 0644]

index 1ef5628..5f7efb9 100644 (file)
@@ -1,8 +1,14 @@
-define(['libs/jquery-1.9.1.min', 'libs/underscore-min'], function($, _) {
+define([
+'libs/jquery-1.9.1.min',
+'libs/underscore-min',
+'modules/documentCanvas/classAttributes'
+], function($, _, classAttributes) {
 
 'use strict';
 
 
+
+
 var tagSelector = '[wlxml-tag]';
 
 var CanvasNode = function(desc) {
@@ -22,7 +28,9 @@ var CanvasNode = function(desc) {
             this.dom.text(desc.content);
         if(desc.meta) {
             var c = this;
-            _.keys(desc.meta).forEach(function(key) {
+            _.keys(desc.meta)
+            .filter(function(key) {return classAttributes.hasMetaAttr(c.getClass(), key);})
+            .forEach(function(key) {
                 c.dom.attr('wlxml-meta-'+key, desc.meta[key]);
             });
         }
@@ -40,13 +48,13 @@ CanvasNode.prototype.getClass = function() {
 
 CanvasNode.prototype.setClass = function(klass) {
     if(klass != this.getClass()) {
-        this.dom.attr('wlxml-class', klass);
         var c = this;
         this.getMetaAttrs().forEach(function(attr) {
             c.dom.removeAttr('wlxml-meta-' + attr.name);
         });
+        this.dom.attr('wlxml-class', klass);
     }
-}
+};
 
 CanvasNode.prototype.getId = function() {
     return this.dom.attr('id');
@@ -101,13 +109,13 @@ CanvasNode.prototype.getMetaAttrs = function() {
     var toret = [];
     var metaAttrPrefix = 'wlxml-meta-';
 
-    var attrs = this.dom.get(0).attributes;
-    for(var i = 0; i < attrs.length; i++) {
-        var attr = attrs[i];
-        if(attr.name.substr(0, metaAttrPrefix.length) === metaAttrPrefix) {
-            toret.push({name: attr.name.substr(metaAttrPrefix.length), value: attr.value});    
-        }
-    }
+    var attrList = classAttributes.getMetaAttrsList(this.getClass());
+    var c = this;
+    attrList.all.forEach(function(attr) {
+        toret.push({name: attr.name, value: c.getMetaAttr(attr.name) || ''});  
+    });
+
+
     return toret;
 };
 
diff --git a/modules/documentCanvas/classAttributes.js b/modules/documentCanvas/classAttributes.js
new file mode 100644 (file)
index 0000000..fe7409a
--- /dev/null
@@ -0,0 +1,64 @@
+define([], function() {
+    
+'use strict';
+
+var wlxmlDict = {
+    'uri': {
+        'uri': 'string'
+    }
+};
+
+var hasMetaAttr = function(klass, attrName, dict) {
+    dict = dict || wlxmlDict;
+    if(!klass)
+        return false;
+
+    var parts = klass.split('-');
+    var partialClass = '';
+    for(var i = 0; i < parts.length; i++) {
+        partialClass += (partialClass === '' ? '' : '-') + parts[i];
+        if(dict[partialClass] && dict[partialClass][attrName])
+            return true;
+    }
+    return false;
+};
+
+var getMetaAttrsList = function(klass, dict) {
+    dict = dict || wlxmlDict;
+    klass = klass || '';
+
+    var toret = {own: [], inheritedFrom: {}, all: []};
+    var parts = klass.split('-');
+    var partialClass = '';
+    
+    var generate = function(klass) {
+        var toret = [],
+            desc = dict[klass];
+
+        if(!desc)
+            return toret;
+        
+        _.keys(desc).forEach(function(key) {
+            toret.push({name: key, type: desc[key]});
+        });
+        return toret;
+    };
+
+    toret.own = generate(klass);
+    for(var i = 0; i < parts.length; i++) {
+        partialClass += (partialClass === '' ? '' : '-') + parts[i];
+        var list = generate(partialClass);
+        if(list.length > 0) {
+            toret.inheritedFrom[partialClass] = generate(partialClass);
+            toret.all = toret.all.concat(toret.inheritedFrom[partialClass]);
+        }
+    }
+    return toret;
+};
+
+return {
+    hasMetaAttr: hasMetaAttr,
+    getMetaAttrsList: getMetaAttrsList
+};
+
+});
\ No newline at end of file
index 0077d46..444ee0f 100644 (file)
@@ -20,15 +20,15 @@ suite('Create canvas node', function() {
     test('from description', function() {
         var node = canvasNode.create({
             tag: 'header',
-            klass: 'some-class',
+            klass: 'uri',
             content: 'some text content',
             meta: {uri: 'some uri'}
         });
         assert.equal(node.getTag(), 'header');
-        assert.equal(node.getClass(), 'some-class');
+        assert.equal(node.getClass(), 'uri');
         assert.equal(node.getContent(), 'some text content');
         assert.equal(node.getMetaAttr('uri'), 'some uri');
-        assertDomEqual($('<div wlxml-tag="header" wlxml-class="some-class" wlxml-meta-uri="some uri">some text content</div>'), node.dom);
+        assertDomEqual($('<div wlxml-tag="header" wlxml-class="uri" wlxml-meta-uri="some uri">some text content</div>'), node.dom);
     });
     
     test('from dom object', function() {
@@ -67,22 +67,27 @@ suite('comparing nodes', function() {
 
 suite('meta attributes', function() {
     test('get list of node\'s meta attributes', function() {
-        var node = canvasNode.create({tag: 'tag', klass: 'klass', meta: {a:1, b:2}});
+        var node = canvasNode.create({tag: 'span', klass: 'uri', meta: {uri:'http://some.uri.com'}});
         var attrs = node.getMetaAttrs();
-        var expected = [{name: 'a', value: '1'}, {name:'b', value: '2'}];
+        var expected = [{name: 'uri', value: 'http://some.uri.com'}];
+
+        assert.deepEqual(attrs.sort(), expected.sort());
+    });
 
+    test('get list of node\'s meta attributes when attributes not set', function() {
+        var node = canvasNode.create({tag: 'span', klass: 'uri'});
+        var attrs = node.getMetaAttrs();
+        var expected = [{name: 'uri', value: ''}];
         assert.deepEqual(attrs.sort(), expected.sort());
     });
 
     test('set meta attribute', function() {
-        var node = canvasNode.create({tag: 'tag', meta: {a:'1'}});
-        node.setMetaAttr('a', '2');
-        assert.equal(node.dom.attr('wlxml-meta-a'), '2');
+        var node = canvasNode.create({tag: 'tag', klass: 'uri', meta: {'uri': 'some uri'}});
+        node.setMetaAttr('uri', 'some uri 2');
+        assert.equal(node.dom.attr('wlxml-meta-uri'), 'some uri 2');
     });
-});
 
-suite('modifing node', function() {
-    test('changing class removes meta attributes', function() {
+    test('changing class changes meta attributes', function() {
         var node = canvasNode.create({tag: 'span', klass: 'uri', meta: {uri: 'http://some.uri.com'}});
         
         assert.equal(node.getMetaAttr('uri'), 'http://some.uri.com');
@@ -90,7 +95,7 @@ suite('modifing node', function() {
         node.setClass('author');
 
         assert.equal(node.getMetaAttr('uri'), undefined);
-    })
-})
+    });
+});
 
 });
\ No newline at end of file
diff --git a/modules/documentCanvas/tests/classAttributes.test.js b/modules/documentCanvas/tests/classAttributes.test.js
new file mode 100644 (file)
index 0000000..4f2157c
--- /dev/null
@@ -0,0 +1,58 @@
+define([
+'libs/chai',
+'modules/documentCanvas/classAttributes'
+], function(chai, classAttributes) {
+   
+var stubDict = {
+    'klass': {
+        'prop': 'string'
+    },
+    'klass-sub1': {
+        'prop1': 'string'
+    },
+    'klass-sub1-sub2': {
+        'prop2': 'string'
+    }
+};
+
+var assert = chai.assert;
+
+suite('Class attributes', function() {
+    test('class has own attribute', function() {
+        assert.ok(classAttributes.hasMetaAttr('klass-sub1-sub2', 'prop2', stubDict));
+    });
+
+    test('class has attributes from parent classes', function() {
+        assert.ok(classAttributes.hasMetaAttr('klass-sub1-sub2', 'prop', stubDict));
+        assert.ok(classAttributes.hasMetaAttr('klass-sub1-sub2', 'prop1', stubDict));
+    });
+
+    test('list of class meta attributes', function() {
+        var attrList = classAttributes.getMetaAttrsList('klass-sub1-sub2', stubDict);
+
+        assert.deepEqual(attrList.own, [{name: 'prop2', type: 'string'}]);
+        assert.deepEqual(attrList.inheritedFrom['klass-sub1'], [{name: 'prop1', type: 'string'}]);
+        assert.deepEqual(attrList.inheritedFrom.klass, [{name: 'prop', type: 'string'}]);
+        assert.deepEqual(attrList.all.sort(), [
+            {name: 'prop', type: 'string'},
+            {name: 'prop1', type: 'string'},
+            {name: 'prop2', type: 'string'}
+            ].sort(), 'all values');
+    });
+
+    test('class without meta attrs', function() {
+        var attrList = classAttributes.getMetaAttrsList('some-class', {});
+        assert.deepEqual(attrList.own, [], 'empty own list');
+        assert.deepEqual(attrList.inheritedFrom, {}, 'empty inherited dict');
+        assert.deepEqual(attrList.all, [], 'empty all list');
+    });
+
+    test('empty class', function() {
+        var attrList = classAttributes.getMetaAttrsList('', {});
+        assert.deepEqual(attrList.own, [], 'empty own list');
+        assert.deepEqual(attrList.inheritedFrom, {}, 'empty inherited dict');
+        assert.deepEqual(attrList.all, [], 'empty all list');
+    });
+});
+
+});
\ No newline at end of file