1 define(function(require) {
5 var _ = require('libs/underscore'),
6 smartxmlTransformations = require('smartxml/transformations'),
7 metadataKey = 'wlxml.metadata';
10 var Row = function(key, value, metadata) {
12 this.value = value || '';
13 this.metadata = metadata;
16 _.extend(Row.prototype, {
17 ChangeProperty: smartxmlTransformations.createContextTransformation({
18 impl: function(t, rowIndex, propName, value) {
19 var row = this.getMetadata().at(rowIndex);
20 if(row.getValue() === value) {
23 t.rowIndex = rowIndex;
24 t.propName = propName;
25 t.oldValue = row[propName];
26 row[propName] = value;
27 this.triggerChangeEvent('metadataChanged', {row:row});
30 var row = this.getMetadata().at(t.rowIndex);
31 row[t.propName] = t.oldValue;
32 this.triggerChangeEvent('metadataChanged', {row:row});
36 setKey: function(key) {
37 return this.metadata.node.transform(this.ChangeProperty, [this.getIndex(), 'key', key]);
42 setValue: function(value) {
43 return this.metadata.node.transform(this.ChangeProperty, [this.getIndex(), 'value', value]);
45 getValue: function() {
49 this.metadata.remove(this);
51 getIndex: function() {
52 return this.metadata.indexOf(this);
57 var Metadata = function(node) {
59 Object.defineProperty(this, 'length', {
61 return this._rows.length;
67 _.extend(Metadata.prototype, {
68 Add: smartxmlTransformations.createContextTransformation({
69 impl: function(t, rowDesc) {
70 var metadata = this.getMetadata(),
71 row = new Row(rowDesc.key, rowDesc.value, metadata);
72 metadata._rows.push(row);
73 t.rowIdx = row.getIndex();
74 this.triggerChangeEvent('metadataAdded', {row: row});
78 this.getMetadata().at(t.rowIdx).remove();
82 Remove: smartxmlTransformations.createContextTransformation({
83 impl: function(t, rowIdx) {
84 var metadata = this.getMetadata();
86 t.row = metadata.at(rowIdx);
87 metadata._rows.splice(rowIdx, 1);
88 this.triggerChangeEvent('metadataRemoved', {row: t.row});
91 var metadata = this.getMetadata(),
92 row = new Row(t.row.getKey(), t.row.getValue(), metadata);
93 metadata._rows.splice(t.rowIdx, 0, row);
94 this.triggerChangeEvent('metadataAdded', {row: row});
98 _iter: function(method, callback, key) {
100 .filter(function(row) { return !key || row.getKey() === key; })
101 [method](function(row) { return callback(row); });
103 forEach: function(callback, key) {
104 return this._iter('forEach', callback, key);
106 some: function(callback, key) {
107 return this._iter('some', callback, key);
109 add: function(rowDesc, options) {
111 options = _.extend({undoable: true}, options);
112 if(options.undoable) {
113 return this.node.transform(this.Add, [rowDesc]);
115 row = new Row(rowDesc.key, rowDesc.value, this);
116 this._rows.push(row);
121 return this._rows[idx];
123 indexOf: function(row) {
124 var idx = this._rows.indexOf(row);
130 remove: function(row) {
131 var idx = this.indexOf(row);
132 if(typeof idx !== 'undefined') {
133 this.node.transform(this.Remove, [idx]);
136 clone: function(node) {
137 var clone = new Metadata(node);
138 this._rows.forEach(function(row) {
139 clone._rows.push(new Row(row.getKey(), row.getValue(), clone));
149 getMetadata: function() {
150 if(!this.getData(metadataKey)) {
151 this.setData(metadataKey, new Metadata(this));
153 return this.getData(metadataKey);