X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/7234259fa025569d6a7682aa6c74fdcfb3ca7e17..58a70817b94ce86e550c93a9a36e635e47ea594e:/modules/documentCanvas/canvas.js diff --git a/modules/documentCanvas/canvas.js b/modules/documentCanvas/canvas.js index eb0fd0b..ab8a578 100644 --- a/modules/documentCanvas/canvas.js +++ b/modules/documentCanvas/canvas.js @@ -1,172 +1,314 @@ -define([ -'libs/jquery-1.9.1.min', -'libs/underscore-min', -'modules/documentCanvas/transformations', -'modules/documentCanvas/wlxmlNode', -'libs/text!./template.html' -], function($, _, transformations, wlxmlNode, template) { - -'use strict'; - -var Canvas = function(xml) { - this.dom = $(template); - this.content = this.dom.find('#rng-module-documentCanvas-content'); - this.setXML(xml); -} - -Canvas.prototype.setXML = function(xml) { - this.xml = xml; - this.content.html(transformations.fromXML.getHTMLTree(xml)); -} - -Canvas.prototype.toXML = function() { - return transformations.toXML.getXML(this.content.html()); -} - -Canvas.prototype.getNode = function(desc) { - var selector = ''; - if(desc.klass) - selector += '[wlxml-class=' + desc.klass + ']'; - if(desc.tag) - selector += '[wlxml-tag=' + desc.tag + ']'; - var toret = []; - this.content.find(selector).each(function() { - toret.push(new wlxmlNode.Node($(this))); - }); - return toret; -} - -Canvas.prototype.getPreviousNode = function(options) { - var element = $(this.content.find('#' + options.node.id).get(0)); - var prev = element.prev() - if(prev.length === 0) - prev = element.parent(); - return new wlxmlNode.Node(prev); -} - -Canvas.prototype._createNode = function(wlxmlTag, wlxmlClass) { - var toBlock = ['div', 'document', 'section', 'header']; - var htmlTag = _.contains(toBlock, wlxmlTag) ? 'div' : 'span'; - var toret = $('<' + htmlTag + '>'); - toret.attr('wlxml-tag', wlxmlTag); - if(wlxmlClass) - toret.attr('wlxml-class', wlxmlClass); - toret.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);})); - return toret; - }; - -Canvas.prototype.insertNode = function(options) { - var element = $(this.content.find('#' + options.context.id).get(0)); - if(options.place == 'after') { - var node = this._createNode(options.tag, options.klass); - element[options.place](node); - return node; - } - else if(options.place == 'wrapText') { - var elementContents = element.contents(); - if(elementContents.length !== 1 || elementContents.get(0).nodeType != 3) - return false; - var textElement = elementContents.get(0); - - var prefix = textElement.data.substr(0, options.offsetStart); - var suffix = textElement.data.substr(options.offsetEnd); - var core = textElement.data.substr(options.offsetStart, options.offsetEnd - options.offsetStart); - var newNode = this._createNode(options.tag, options.klass); - newNode.text(core); - $(textElement).replaceWith(newNode); - newNode.before(prefix); - newNode.after(suffix); - } -} - -Canvas.prototype.splitNode = function(options) { - options = _.extend({textNodeIdx: 0}, options); - - var nodeToSplit = $(this.content.find('#' + options.node.id).get(0)); - - var nodeContents = nodeToSplit.contents(); - if(nodeContents.length === 0 || - nodeContents.length - 1 < options.textNodeIdx || - nodeContents.get(options.textNodeIdx).nodeType != 3) - return false; - - var textNode = $(nodeContents.get(options.textNodeIdx)); - - var succeedingNodes = []; - var passed = false; - nodeContents.each(function() { - var node = this; - if(passed) - succeedingNodes.push(node); - if(node.isSameNode(textNode.get(0))) - passed = true; - }); - - var prefix = textNode.text().substr(0, options.offset); - var suffix = textNode.text().substr(options.offset); - - textNode.before(prefix); - textNode.remove(); - - var newNode = this._createNode(nodeToSplit.attr('wlxml-tag'), nodeToSplit.attr('wlxml-class')); - newNode.append(suffix); - succeedingNodes.forEach(function(node) { - newNode.append(node) - }); - nodeToSplit.after(newNode); - return newNode; -} - -Canvas.prototype.removeNode = function(options) { - var toRemove = $(this.content.find('#' + options.node.id).get(0)); - toRemove.remove(); - -} - -Canvas.prototype.createList = function(options) { - var element1 = $(this.content.find('#' + options.start.id).get(0)); - var element2 = $(this.content.find('#' + options.end.id).get(0)); - if(!element1.parent().get(0).isSameNode(element2.parent().get(0))) - return false; - - var parent = element1.parent(); - var nodesToWrap = []; - - var place = 'before'; - var canvas = this; - parent.contents().each(function() { - var node = this; - if(node.isSameNode(element1.get(0))) - place = 'inside'; - if(place === 'inside') { - var $node; - if(node.nodeType === 3) { - $node = canvas._createNode('div').text(node.data); - $(node).remove(); - } - else { - $node = $(node); - } - $node.attr('wlxml-class', 'list.item'); - nodesToWrap.push($node); - } - if(node.isSameNode(element2.get(0))) - return; - }); - - var list = this._createNode('div', 'list'); - element1.before(list); - - nodesToWrap.forEach(function(node) { - node.remove(); - list.append(node); - }); - - - -} - - -return {Canvas: Canvas, Node: Node}; - +define([ +'libs/jquery-1.9.1.min', +'libs/underscore-min', +'modules/documentCanvas/transformations', +'modules/documentCanvas/canvasNode', +'libs/text!./template.html' +], function($, _, transformations, canvasNode, template) { + +'use strict'; + +var Canvas = function(html) { + this.dom = $(template); + this.content = this.dom.find('#rng-module-documentCanvas-content'); + this.setHTML(html); +}; + +Canvas.prototype.setHTML = function(html) { + if(html) { + this.content.html(html); + } +}; + +Canvas.prototype.getContent = function() { + return this.content.contents(); +}; + +Canvas.prototype.findNodes = function(desc) { + var selector = ''; + if(typeof desc === 'string') { + selector = desc; + } + else { + if(desc.klass) + selector += '[wlxml-class=' + desc.klass + ']'; + if(desc.tag) + selector += '[wlxml-tag=' + desc.tag + ']'; + } + var toret = []; + this.content.find(selector).each(function() { + toret.push(canvasNode.create($(this))); + }); + return toret; +}; + +Canvas.prototype.getNodeById = function(id) { + return canvasNode.create($(this.content.find('#' +id))); +}; + +Canvas.prototype.nodeAppend = function(options) { + var element; // = $(this.content.find('#' + options.context.id).get(0)); + if(options.to === 'root') { + element = this.content; + } else { + element = $(this.content.find('#' + options.to.getId()).get(0)); + } + element.append(options.node.dom); +}; + +Canvas.prototype.nodeInsertAfter = function(options) { + var element = $(this.content.find('#' + options.after.getId()).get(0)); + element.after(options.node.dom); +}; + +Canvas.prototype.nodeWrap = function(options) { + options = _.extend({textNodeIdx: 0}, options); + if(typeof options.textNodeIdx === 'number') + options.textNodeIdx = [options.textNodeIdx]; + + var container = $(this.content.find('#' + options.inside.getId()).get(0)), + containerContent = container.contents(), + idx1 = Math.min.apply(Math, options.textNodeIdx), + idx2 = Math.max.apply(Math, options.textNodeIdx), + textNode1 = $(containerContent.get(idx1)), + textNode2 = $(containerContent.get(idx2)), + sameNode = textNode1.get(0) === textNode2.get(0), + prefixOutside = textNode1.text().substr(0, options.offsetStart), + prefixInside = textNode1.text().substr(options.offsetStart), + suffixInside = textNode2.text().substr(0, options.offsetEnd), + suffixOutside = textNode2.text().substr(options.offsetEnd) + ; + + textNode1.after(options._with.dom); + textNode1.detach(); + + options._with.dom.before(prefixOutside); + if(sameNode) { + var core = textNode1.text().substr(options.offsetStart, options.offsetEnd - options.offsetStart); + options._with.setContent(core); + } else { + textNode2.detach(); + options._with.dom.append(prefixInside); + for(var i = idx1 + 1; i < idx2; i++) { + options._with.dom.append(containerContent[i]); + } + options._with.dom.append(suffixInside); + } + options._with.dom.after(suffixOutside); +}; + +Canvas.prototype.nodeUnwrap = function(options) { + + var removeWithJoin = function(node) { + var contents = node.parent().contents(), + idx = contents.index(node), + prev = idx > 0 ? contents[idx-1] : null, + next = idx + 1 < contents.length ? contents[idx+1] : null; + + if(prev && prev.nodeType === 3 && next && next.nodeType === 3) { + prev.data = prev.data + next.data; + $(next).remove(); + } + node.remove(); + }; + + var toUnwrap = $(this.content.find('#' + options.node.getId()).get(0)); + + + var parent = toUnwrap.parent(); + var parentContents = parent.contents(); + + if(toUnwrap.contents().length !== 1 || toUnwrap.contents()[0].nodeType !== 3) + return false; + + var idx = parentContents.index(toUnwrap); + + var combineWith, + action; + + if(idx > 0 && parentContents[idx-1].nodeType === 3) { + combineWith = parentContents[idx-1]; + action = 'append'; + } else if(idx + 1 < parentContents.length && parentContents[idx+1].nodeType === 3) { + combineWith = parentContents[idx+1]; + action = 'prepend'; + } + + if(combineWith) { + var text = + (action === 'prepend' ? toUnwrap.text() : '') + + combineWith.data + + (action === 'append' ? toUnwrap.text() : '') + ; + combineWith.data = text; + removeWithJoin(toUnwrap); + } else { + if(parentContents.length === 1 || idx === 0) { + parent.append(toUnwrap.text()); + } else { + toUnwrap.prev().after(toUnwrap.text()); + } + toUnwrap.remove(); + } +}; + +Canvas.prototype.nodeSplit = function(options) { + options = _.extend({textNodeIdx: 0}, options); + + var nodeToSplit = $(this.content.find('#' + options.node.getId()).get(0)); + + var nodeContents = nodeToSplit.contents(); + if(nodeContents.length === 0 || + nodeContents.length - 1 < options.textNodeIdx || + nodeContents.get(options.textNodeIdx).nodeType != 3) + return false; + + var textNode = $(nodeContents.get(options.textNodeIdx)); + + var succeedingNodes = []; + var passed = false; + nodeContents.each(function() { + var node = this; + if(passed) + succeedingNodes.push(node); + if(node === textNode.get(0)) + passed = true; + }); + + var prefix = $.trim(textNode.text().substr(0, options.offset)); + var suffix = $.trim(textNode.text().substr(options.offset)); + + textNode.before(prefix); + textNode.remove(); + + var newNode = canvasNode.create({tag: nodeToSplit.attr('wlxml-tag'), klass: nodeToSplit.attr('wlxml-class')}); + newNode.dom.append(suffix); + succeedingNodes.forEach(function(node) { + newNode.dom.append(node); + }); + nodeToSplit.after(newNode.dom); + return newNode; +}; + +Canvas.prototype.nodeRemove = function(options) { + var toRemove = $(this.content.find('#' + options.node.getId()).get(0)); + toRemove.remove(); +}; + +Canvas.prototype.listCreate = function(options) { + var element1 = $(this.content.find('#' + options.start.getId()).get(0)); + var element2 = $(this.content.find('#' + options.end.getId()).get(0)); + if(element1.parent().get(0) !== element2.parent().get(0)) + return false; + + var parent = element1.parent(); + + if(parent.contents().index(element1) > parent.contents().index(element2)) { + var tmp = element1; + element1 = element2; + element2 = tmp; + } + + var nodesToWrap = []; + + var place = 'before'; + var canvas = this; + parent.contents().each(function() { + var node = this; + if(node === element1.get(0)) + place = 'inside'; + if(place === 'inside') { + var $node; + if(node.nodeType === 3) { + $node = canvasNode.create({tag: 'div', content: $.trim(node.data)}).dom; //canvas._createNode('div').text(node.data); + $(node).remove(); + } + else { + $node = $(node); + } + $node.attr('wlxml-class', 'item'); + nodesToWrap.push($node); + } + if(node === element2.get(0)) + return false; + }); + + var list = canvasNode.create({tag: 'div', klass: 'list-items' + (options.type === 'enum' ? '-enum' : '')}).dom; //this._createNode('div', 'list-items'); + + var parentNode = options.start.parent(); + + var toret; + if(parentNode && parentNode.isOfClass('list-items')) { + list.wrap('
'); + toret = list.parent(); + } else { + toret = list; + } + + + element1.before(toret); + + nodesToWrap.forEach(function(node) { + node.remove(); + list.append(node); + }); +}; + +Canvas.prototype.listRemove = function(options) { + var pointerElement = $(this.content.find('#' + options.pointer.getId())); + var listElement = options.pointer.isOfClass('list-items') ? pointerElement : + pointerElement.parents('[wlxml-class|="list-items"][wlxml-tag]'); + + var nested = false, + nestedLists; + if(listElement.length > 1) { + listElement = $(listElement[0]); + nested = true; + } + + if(nested) { + // We are only moving one level up + listElement.unwrap(); + } else { + // We are removing the whole list + nestedLists = listElement.find('[wlxml-class=item] > [wlxml-class|=list-items]'); + nestedLists.unwrap(); + listElement.find('[wlxml-class=item]').each(function() { + $(this).removeAttr('wlxml-class'); + }); + } + + listElement.children().unwrap(); + + var c = this; + if(nestedLists) { + nestedLists.each(function() { + c.listRemove({pointer: canvasNode.create($(this))}); + }); + } +}; + +Canvas.prototype.getPrecedingNode = function(options) { + var element = $(this.content.find('#' + options.node.getId()).get(0)); + var prev = element.prev(); + if(prev.length === 0) + prev = element.parent(); + return canvasNode.create(prev); +}; + +Canvas.prototype.nodeInsideList = function(options) { + if(options.node) { + if(options.node.isOfClass('list-items') || options.node.isOfClass('item')) + return true; + var pointerElement = $(this.content.find('#' + options.node.getId())); + return pointerElement.parents('[wlxml-class=list-items], [wlxml-class=item]').length > 0; + } + return false; +}; + + +return { + create: function(desc) { return new Canvas(desc); } +}; + }); \ No newline at end of file