X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/a09318d74185278fa556af4a997e94b0d6999193..c9ec6d3adaf0d2119ed2ef7eecc2e5b525f2f86d:/modules/visualEditor.js
diff --git a/modules/visualEditor.js b/modules/visualEditor.js
index 38f3302..39859a8 100644
--- a/modules/visualEditor.js
+++ b/modules/visualEditor.js
@@ -3,6 +3,7 @@ rng.modules.visualEditor = function(sandbox) {
var view = {
node: $(sandbox.getTemplate('main')()),
+ currentNode: null,
setup: function() {
var view = this;
@@ -14,37 +15,103 @@ rng.modules.visualEditor = function(sandbox) {
isDirty = true;
});
- this.node.on('mouseover', '.rng', function(e) { $(e.target).addClass('rng-hover')});
- this.node.on('mouseout', '.rng', function(e) { $(e.target).removeClass('rng-hover')});
- this.node.on('click', '.rng', function(e) {
+ this.node.on('mouseover', '[wlxml-tag]', function(e) { mediator.nodeHovered($(e.target));});
+ this.node.on('mouseout', '[wlxml-tag]', function(e) { mediator.nodeBlured($(e.target));});
+ this.node.on('click', '[wlxml-tag]', function(e) {
+ console.log('clicked node type: '+e.target.nodeType);
view._markSelected($(e.target));
});
- this.node.on('keyup', function(e) {
+ this.node.on('keyup', '#rng-visualEditor-contentWrapper', function(e) {
var anchor = $(window.getSelection().anchorNode);
if(anchor[0].nodeType === Node.TEXT_NODE)
anchor = anchor.parent();
- if(!anchor.hasClass('rng'))
+ if(!anchor.is('[wlxml-tag]'))
return;
view._markSelected(anchor);
- });
+ });
+
+ this.node.on('keydown', '#rng-visualEditor-contentWrapper', function(e) {
+ if(e.which === 13) {
+ e.preventDefault();
+ var anchor = $(window.getSelection().anchorNode);
+ if(anchor[0].nodeType === Node.TEXT_NODE)
+ anchor = anchor.parent();
+ var newNode = anchor.clone().empty();
+ newNode.attr('id', '');
+ anchor.after(newNode);
+ view.selectNode(newNode);
+ }
+ });
+
+
+ var metaTable = this.metaTable = this.node.find('#rng-visualEditor-meta table');
+
+ this.node.find('.rng-visualEditor-metaAddBtn').click(function() {
+ var newRow = view._addMetaRow('', '');
+ $(newRow.find('td div')[0]).focus();
+ isDirty = true;
+ });
+
+ this.metaTable.on('click', '.rng-visualEditor-metaRemoveBtn', function(e) {
+ $(e.target).closest('tr').remove();
+ isDirty = true;
+ });
+
+ this.metaTable.on('keydown', '[contenteditable]', function(e) {
+ console.log(e.which);
+ if(e.which === 13) {
+ if($(document.activeElement).hasClass('rng-visualEditor-metaItemKey')) {
+ metaTable.find('.rng-visualEditor-metaItemValue').focus();
+ } else {
+ var input = $('');
+ input.appendTo('body').focus()
+ view.node.find('.rng-visualEditor-metaAddBtn').focus();
+ input.remove();
+ }
+ e.preventDefault();
+ }
+
+ });
+
+
+ var observer = new MutationObserver(function(mutations) {
+ mutations.forEach(function(mutation) {
+ if(mutation.addedNodes.length > 0) {
+ console.log(mutation.addedNodes);
+ }
+ _.each(mutation.addedNodes, function(node) {
+ node = $(node);
+ node.parent().find('[wlxml-tag]').each(function() {
+ tag = $(this);
+ if(!tag.attr('id'))
+ tag.attr('id', 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = Math.random()*16|0,v=c=='x'?r:r&0x3|0x8;return v.toString(16);}));
+ });
+ });
+ });
+ });
+ var config = { attributes: true, childList: true, characterData: true, subtree: true };
+ observer.observe(this.node.find('#rng-visualEditor-contentWrapper')[0], config);
+
+ this.gridToggled = false;
},
getMetaData: function() {
var toret = {};
- this.node.find('#rng-visualEditor-meta table tr').each(function() {
+ this.metaTable.find('tr').each(function() {
var tr = $(this);
- var key = $(tr.find('td')[0]).html();
- var value = $(tr.find('td input')[0]).val();
+ var inputs = $(this).find('td [contenteditable]');
+ var key = $(inputs[0]).text();
+ var value = $(inputs[1]).text();
toret[key] = value;
});
console.log(toret);
return toret;
},
setMetaData: function(metadata) {
- var table = this.node.find('#rng-visualEditor-meta table');
- table.empty();
+ var view = this;
+ this.metaTable.find('tr').remove();
_.each(_.keys(metadata), function(key) {
- $(sandbox.getTemplate('metaItem')({key: key, value: metadata[key]})).appendTo(table);
+ view._addMetaRow(key, metadata[key]);
});
},
setBody: function(HTMLTree) {
@@ -54,13 +121,216 @@ rng.modules.visualEditor = function(sandbox) {
return this.node.find('#rng-visualEditor-content').html();
},
_markSelected: function(node) {
- this.node.find('.rng').removeClass('rng-current');
+ this.node.find('.rng-current').removeClass('rng-current');
node.addClass('rng-current');
+ this.currentNode = node;
+ mediator.nodeSelected(node);
+ },
+ selectNode: function(node) {
+ view._markSelected(node);
+ var range = document.createRange();
+ range.selectNodeContents(node[0]);
+ range.collapse(false);
+
+ var selection = document.getSelection();
+ selection.removeAllRanges()
+ selection.addRange(range);
+ },
+ selectNodeById: function(id) {
+ var node = this.node.find('#'+id);
+ if(node)
+ this.selectNode(node);
+ },
+ highlightNode: function(node) {
+ if(!this.gridToggled)
+ node.addClass('rng-hover');
+ },
+ dimNode: function(node) {
+ if(!this.gridToggled)
+ node.removeClass('rng-hover');
+ },
+ highlightNodeById: function(id) {
+ var node = this.node.find('#'+id);
+ if(node)
+ this.highlightNode(node);
+ },
+ dimNodeById: function(id) {
+ var node = this.node.find('#'+id);
+ if(node)
+ this.dimNode(node);
+ },
+ selectFirstNode: function() {
+ var firstNodeWithText = this.node.find('[wlxml-tag]').filter(function() {
+ return $(this).clone().children().remove().end().text().trim() !== '';
+ }).first();
+ var node;
+ if(firstNodeWithText.length)
+ node = $(firstNodeWithText[0])
+ else {
+ node = this.node.find('[wlxml-class|="p"]')
+ }
+ this.selectNode(node);
+ },
+ _addMetaRow: function(key, value) {
+ var newRow = $(sandbox.getTemplate('metaItem')({key: key || '', value: value || ''}));
+ newRow.appendTo(this.metaTable);
+ return newRow;
+ },
+ toggleGrid: function(toggle) {
+ this.node.find('[wlxml-tag]').toggleClass('rng-hover', toggle);
+ this.gridToggled = toggle;
}
};
+
+
+ var sideBarView = {
+ node: view.node.find('#rng-visualEditor-sidebar'),
+ setup: function() {
+ var view = this;
+ this.node.find('#rng-visualEditor-sidebarButtons a').click(function(e) {
+ e.preventDefault();
+ var target = $(e.currentTarget);
+ if(!target.attr('data-content-id'))
+ return;
+ view.selectTab(target.attr('data-content-id'));
+ });
+ view.selectTab('rng-visualEditor-edit');
+
+ view.node.on('change', '.rng-visualEditor-editPaneNodeForm select', function(e) {
+ var target = $(e.target);
+ var attr = target.attr('id').split('-')[2].split('editPane')[1].substr(0,3) === 'Tag' ? 'tag' : 'class';
+ mediator.getCurrentNode().attr('wlxml-'+attr, target.val());
+ isDirty = true;
+ });
+
+ view.node.on('change', '.rng-visualEditor-editPaneSelectionForm select', function(e) {
+ var target = $(e.target);
+ var selection = window.getSelection();
+ if(selection.anchorNode === selection.focusNode && selection.anchorNode.nodeType === Node.TEXT_NODE) {
+ var startOffset = selection.anchorOffset;
+ var endOffset = selection.focusOffset;
+ if(startOffset > endOffset) {
+ var tmp = startOffset;
+ startOffset = endOffset;
+ endOffset = tmp;
+ }
+ var node = selection.anchorNode;
+ var prefix = node.data.substr(0, startOffset);
+ var suffix = node.data.substr(endOffset);
+ var core = node.data.substr(startOffset, endOffset - startOffset);
+ var newNode = $('' + core + '');
+ $(node).replaceWith(newNode);
+ newNode.before(prefix);
+ newNode.after(suffix);
+ mediator.nodeCreated(newNode);
+ isDirty = true;
+ }
+ });
+
+ view.node.on('click', '.rng-visualEditor-editPaneSurrouding a', function(e) {
+ var target = $(e.target);
+ mediator.nodeDimmedById(target.attr('data-id'));
+ mediator.nodeSelectedById(target.attr('data-id'));
+ });
+
+ view.node.on('mouseenter', '.rng-visualEditor-editPaneSurrouding a', function(e) {
+ var target = $(e.target);
+ mediator.nodeHighlightedById(target.attr('data-id'));
+ });
+ view.node.on('mouseleave', '.rng-visualEditor-editPaneSurrouding a', function(e) {
+ var target = $(e.target);
+ mediator.nodeDimmedById(target.attr('data-id'));
+ });
+ },
+ selectTab: function(id) {
+ this.node.find('.rng-visualEditor-sidebarContentItem').hide();
+ this.node.find('#'+id).show();
+ this.node.find('#rng-visualEditor-sidebarButtons li').removeClass('active');
+ this.node.find('#rng-visualEditor-sidebarButtons li a[data-content-id=' + id + ']').parent().addClass('active');
+
+ },
+ updateEditPane: function(node) {
+ var pane = this.node.find('#rng-visualEditor-edit');
+ pane.html( $(sandbox.getTemplate('editPane')({tag: node.attr('wlxml-tag'), klass: node.attr('wlxml-class')})));
+
+ var parent = {
+ repr: node.parent().attr('wlxml-tag') + ' / ' + (node.parent().attr('wlxml-class') || '[[no class]]'),
+ id: node.parent().attr('id')
+ }
+ var children = [];
+ node.children().each(function() {
+ var child = $(this);
+ children.push({repr: child.attr('wlxml-tag') + ' / ' + (child.attr('wlxml-class') || '[[no class]]'), id: child.attr('id')});
+ });
+ var naviTemplate = sandbox.getTemplate('editPaneNavigation')({parent: parent, children: children});
+ pane.find('.rng-visualEditor-editPaneSurrouding > div').html($(naviTemplate));
+ },
+ highlightNode: function(id) {
+ var pane = this.node.find('#rng-visualEditor-edit');
+ pane.find('a[data-id="'+id+'"]').addClass('rng-hover');
+ },
+ dimNode: function(id) {
+ var pane = this.node.find('#rng-visualEditor-edit');
+ pane.find('a[data-id="' +id+'"]').removeClass('rng-hover');
+ }
+ }
+
+ var toolbarView = {
+ node: view.node.find('#rng-visualEditor-toolbar'),
+ setup: function() {
+ var view = this;
+
+ view.node.find('button').click(function(e) {
+ var btn = $(e.currentTarget);
+ if(btn.attr('data-btn-type') === 'toggle') {
+ btn.toggleClass('active')
+ mediator.toolbarButtonToggled(btn.attr('data-btn'), btn.hasClass('active'));
+ }
+ });
+ }
+ }
+
view.setup();
+ sideBarView.setup();
+ toolbarView.setup();
+
+ var mediator = {
+ getCurrentNode: function() {
+ return view.currentNode;
+ },
+ nodeCreated: function(node) {
+ view.selectNode(node);
+
+ },
+ nodeSelected: function(node) {
+ sideBarView.updateEditPane(node);
+ },
+ nodeSelectedById: function(id) {
+ view.selectNodeById(id);
+ },
+ nodeHighlightedById: function(id) {
+ view.highlightNodeById(id);
+ },
+ nodeDimmedById: function(id) {
+ view.dimNodeById(id);
+ },
+ toolbarButtonToggled: function(btn, toggle) {
+ if(btn === 'grid')
+ view.toggleGrid(toggle);
+ },
+ nodeHovered: function(node) {
+ view.highlightNode(node);
+ sideBarView.highlightNode(node.attr('id'));
+ },
+ nodeBlured: function(node) {
+ view.dimNode(node);
+ sideBarView.dimNode(node.attr('id'));
+ }
+
+ }
var isDirty = false;
+ var wasShownAlready = false;
return {
@@ -84,6 +354,12 @@ rng.modules.visualEditor = function(sandbox) {
},
setDirty: function(dirty) {
isDirty = dirty;
+ },
+ onShowed: function() {
+ if(!wasShownAlready) {
+ wasShownAlready = true;
+ view.selectFirstNode();
+ }
}
}