4 'libs/text!./templates/main.html',
 
   5 'libs/text!./templates/item.html'
 
   6 ], function($, _, mainTemplate, itemTemplate) {
 
  10 return function(sandbox) {
 
  16         node: $(_.template(mainTemplate)()),
 
  19             var metaTable = this.metaTable = this.node.find('table');
 
  21             this.node.find('.rng-module-metadataEditor-addBtn').click(function() {
 
  23                 currentNode.getMetadata().add('','');
 
  26             this.metaTable.on('click', '.rng-visualEditor-metaRemoveBtn', function(e) {
 
  27                 $(e.target).closest('tr').data('row').remove();
 
  30             this.metaTable.on('keydown', '[contenteditable]', function(e) {
 
  31                 /* globals document */
 
  33                     if($(document.activeElement).hasClass('rng-module-metadataEditor-metaItemKey')) {
 
  34                         metaTable.find('.rng-module-metadataEditor-metaItemValue').focus();
 
  36                         var input = $('<input>');
 
  37                         input.appendTo('body').focus();
 
  38                         view.node.find('.rng-module-metadataEditor-addBtn').focus();
 
  45             this.metaTable.on('keyup', '[contenteditable]', _.throttle(function(e) {
 
  47                     var editable = $(e.target),
 
  48                         toSet = editable.text(),
 
  49                         row = editable.parents('tr').data('row'),
 
  50                         isKey = _.last(editable.attr('class').split('-')) === 'metaItemKey',
 
  51                         method = isKey ? 'setKey' : 'setValue';
 
  58         setMetadata: function(node) {
 
  60                 this.metaTable.html('');
 
  64                 metadata = node.getMetadata();
 
  65             this.metaTable.find('tr').remove();
 
  66             metadata.forEach(function(row) {
 
  67                 view.addMetadataRow(row);
 
  70         addMetadataRow: function(row) {
 
  71             var newRow = $(_.template(itemTemplate)({key: row.getKey() || '', value: row.getValue() || ''}));
 
  72             newRow.appendTo(this.metaTable);
 
  73             newRow.data('row', row);
 
  75                 $(newRow.find('td div')[0]).focus();
 
  80         updateMetadataRow: function(row) {
 
  81             this._getRowTr(row, function(tr) {
 
  82                 var tds = tr.find('td > div'),
 
  86                 if(keyTd.text() !== row.getKey()) {
 
  87                     keyTd.text(row.getKey());
 
  89                 if(valueTd.text() !== row.getValue()) {
 
  90                     valueTd.text(row.getValue());
 
  94         removeMetadataRow: function(row) {
 
  95             this._getRowTr(row, function(tr) {
 
  99         _getRowTr: function(row, callback) {
 
 100             this.metaTable.find('tr').each(function() {
 
 102                 if(tr.data('row') === row) {
 
 114             sandbox.publish('ready');
 
 116         setDocument: function(document) {
 
 117             document.on('change', function(event) {
 
 118                 if(event.type === 'metadataAdded' && event.meta.node.sameNode(currentNode)) {
 
 119                     view.addMetadataRow(event.meta.row);
 
 121                 if(event.type === 'metadataChanged' && event.meta.node.sameNode(currentNode)) {
 
 122                     view.updateMetadataRow(event.meta.row);
 
 124                 if(event.type === 'metadataRemoved' && event.meta.node.sameNode(currentNode)) {
 
 125                     view.removeMetadataRow(event.meta.row);
 
 127                 if(event.type === 'nodeDetached' && event.meta.node.sameNode(currentNode)) {
 
 128                     view.setMetadata(null);
 
 132         setNodeElement: function(node) {
 
 133             if(currentNode && currentNode.sameNode(node)) {
 
 137             view.setMetadata(node);
 
 139         getView: function() {