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 t.rowIndex = rowIndex;
21 t.propName = propName;
22 t.oldValue = row[propName];
23 row[propName] = value;
24 this.triggerChangeEvent('metadataChanged', {row:row});
27 var row = this.getMetadata().at(t.rowIndex);
28 row[t.propName] = t.oldValue;
29 this.triggerChangeEvent('metadataChanged', {row:row});
33 setKey: function(key) {
34 return this.metadata.node.transform(this.ChangeProperty, [this.getIndex(), 'key', key]);
39 setValue: function(value) {
40 return this.metadata.node.transform(this.ChangeProperty, [this.getIndex(), 'value', value]);
42 getValue: function() {
46 this.metadata.remove(this);
48 getIndex: function() {
49 return this.metadata.indexOf(this);
54 var Metadata = function(node) {
56 Object.defineProperty(this, 'length', {
58 return this._rows.length;
64 _.extend(Metadata.prototype, {
65 Add: smartxmlTransformations.createContextTransformation({
66 impl: function(t, rowDesc) {
67 var metadata = this.getMetadata(),
68 row = new Row(rowDesc.key, rowDesc.value, metadata);
69 metadata._rows.push(row);
70 t.rowIdx = row.getIndex();
71 this.triggerChangeEvent('metadataAdded', {row: row});
75 this.getMetadata().at(t.rowIdx).remove();
79 Remove: smartxmlTransformations.createContextTransformation({
80 impl: function(t, rowIdx) {
81 var metadata = this.getMetadata();
83 t.row = metadata.at(rowIdx);
84 metadata._rows.splice(rowIdx, 1);
85 this.triggerChangeEvent('metadataRemoved', {row: t.row});
88 var metadata = this.getMetadata(),
89 row = new Row(t.row.getKey(), t.row.getValue(), metadata);
90 metadata._rows.splice(t.rowIdx, 0, row);
91 this.triggerChangeEvent('metadataAdded', {row: row});
95 _iter: function(method, callback, key) {
97 .filter(function(row) { return !key || row.getKey() === key; })
98 [method](function(row) { return callback(row); });
100 forEach: function(callback, key) {
101 return this._iter('forEach', callback, key);
103 some: function(callback, key) {
104 return this._iter('some', callback, key);
106 add: function(rowDesc, options) {
108 options = _.extend({undoable: true}, options);
109 if(options.undoable) {
110 return this.node.transform(this.Add, [rowDesc]);
112 row = new Row(rowDesc.key, rowDesc.value, this);
113 this._rows.push(row);
118 return this._rows[idx];
120 indexOf: function(row) {
121 var idx = this._rows.indexOf(row);
127 remove: function(row) {
128 var idx = this.indexOf(row);
129 if(typeof idx !== 'undefined') {
130 this.node.transform(this.Remove, [idx]);
133 clone: function(node) {
134 var clone = new Metadata(node);
135 this._rows.forEach(function(row) {
136 clone._rows.push(new Row(row.getKey(), row.getValue(), clone));
146 getMetadata: function() {
147 if(!this.getData(metadataKey)) {
148 this.setData(metadataKey, new Metadata(this));
150 return this.getData(metadataKey);