Adding jshint grunt task
[fnpeditor.git] / modules / documentCanvas / canvas.js
index 5de60f4..23cdf0a 100644 (file)
@@ -2,87 +2,105 @@ define([
 'libs/jquery-1.9.1.min',\r
 'libs/underscore-min',\r
 'modules/documentCanvas/transformations',\r
 'libs/jquery-1.9.1.min',\r
 'libs/underscore-min',\r
 'modules/documentCanvas/transformations',\r
-'modules/documentCanvas/wlxmlNode',\r
+'modules/documentCanvas/canvasNode',\r
 'libs/text!./template.html'\r
 'libs/text!./template.html'\r
-], function($, _, transformations, wlxmlNode, template) {\r
+], function($, _, transformations, canvasNode, template) {\r
 \r
 'use strict';\r
 \r
 \r
 'use strict';\r
 \r
-var Canvas = function(xml) {\r
+var Canvas = function(html) {\r
     this.dom = $(template);\r
     this.content = this.dom.find('#rng-module-documentCanvas-content');\r
     this.dom = $(template);\r
     this.content = this.dom.find('#rng-module-documentCanvas-content');\r
-    this.setXML(xml);\r
-}\r
+    this.setHTML(html);\r
+};\r
 \r
 \r
-Canvas.prototype.setXML = function(xml) {\r
-    this.xml = xml;\r
-    this.content.html(transformations.fromXML.getHTMLTree(xml));  \r
-}\r
+Canvas.prototype.setHTML = function(html) {\r
+    if(html) {\r
+        this.content.html(html);\r
+    }\r
+};\r
 \r
 \r
-Canvas.prototype.toXML = function() {\r
-    return transformations.toXML.getXML(this.content.html());\r
-}\r
+Canvas.prototype.getContent = function() {\r
+    return this.content.contents();\r
+};\r
 \r
 \r
-Canvas.prototype.getNode = function(desc) {\r
+Canvas.prototype.findNodes = function(desc) {\r
     var selector = '';\r
     var selector = '';\r
-    if(desc.klass)\r
-        selector += '[wlxml-class=' + desc.klass + ']';\r
-    if(desc.tag)\r
-        selector += '[wlxml-tag=' + desc.tag + ']';\r
+    if(typeof desc === 'string') {\r
+        selector = desc;\r
+    }\r
+    else {\r
+        if(desc.klass)\r
+            selector += '[wlxml-class=' + desc.klass + ']';\r
+        if(desc.tag)\r
+            selector += '[wlxml-tag=' + desc.tag + ']';\r
+    }\r
     var toret = [];\r
     this.content.find(selector).each(function() {\r
     var toret = [];\r
     this.content.find(selector).each(function() {\r
-        toret.push(new wlxmlNode.Node($(this)));\r
+        toret.push(canvasNode.create($(this)));\r
     });\r
     return toret;\r
     });\r
     return toret;\r
-}\r
+};\r
 \r
 \r
-Canvas.prototype.getPreviousNode = function(options) {\r
-    var element = $(this.content.find('#' + options.node.id).get(0));\r
-    var prev = element.prev()\r
-    if(prev.length === 0)\r
-        prev = element.parent();\r
-    return new wlxmlNode.Node(prev);\r
+Canvas.prototype.getNodeById = function(id) {\r
+    return canvasNode.create($(this.content.find('#' +id)));\r
 }\r
 \r
 }\r
 \r
-Canvas.prototype._createNode = function(wlxmlTag, wlxmlClass) {\r
-            var toBlock = ['div', 'document', 'section', 'header'];\r
-            var htmlTag = _.contains(toBlock, wlxmlTag) ? 'div' : 'span';\r
-            var toret = $('<' + htmlTag + '>');\r
-            toret.attr('wlxml-tag', wlxmlTag);\r
-            if(wlxmlClass)\r
-                toret.attr('wlxml-class', wlxmlClass);\r
-            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);}));\r
-            return toret;\r
-        };\r
-\r
-Canvas.prototype.insertNode = function(options) {\r
-    var element = $(this.content.find('#' + options.context.id).get(0));\r
-    if(options.place == 'after') {\r
-        var node = this._createNode(options.tag, options.klass);\r
-        element[options.place](node);\r
-        return node;\r
+Canvas.prototype.nodeAppend = function(options) {\r
+    var element; // = $(this.content.find('#' + options.context.id).get(0));\r
+    if(options.to === 'root') {\r
+        element = this.content;\r
+    } else {\r
+        element = $(this.content.find('#' + options.to.getId()).get(0));\r
     }\r
     }\r
-    else if(options.place == 'wrapText') {\r
-        var elementContents = element.contents();\r
-        if(elementContents.length !== 1 || elementContents.get(0).nodeType != 3)\r
-            return false;\r
-        var textElement = elementContents.get(0);\r
-\r
-        var prefix = textElement.data.substr(0, options.offsetStart);\r
-        var suffix = textElement.data.substr(options.offsetEnd);\r
-        var core = textElement.data.substr(options.offsetStart, options.offsetEnd - options.offsetStart);\r
-        var newNode = this._createNode(options.tag, options.klass);\r
-        newNode.text(core);\r
-        $(textElement).replaceWith(newNode);\r
-        newNode.before(prefix);\r
-        newNode.after(suffix);\r
+    element.append(options.node.dom);\r
+};\r
+\r
+Canvas.prototype.nodeInsertAfter = function(options) {\r
+    var element = $(this.content.find('#' + options.after.getId()).get(0));\r
+    element.after(options.node.dom);\r
+};\r
+\r
+Canvas.prototype.nodeWrap = function(options) {\r
+    options = _.extend({textNodeIdx: 0}, options);\r
+    if(typeof options.textNodeIdx === 'number')\r
+        options.textNodeIdx = [options.textNodeIdx];\r
+    \r
+    var container = $(this.content.find('#' + options.inside.getId()).get(0)),\r
+        containerContent = container.contents(),\r
+        idx1 = Math.min.apply(Math, options.textNodeIdx),\r
+        idx2 = Math.max.apply(Math, options.textNodeIdx),\r
+        textNode1 = $(containerContent.get(idx1)),\r
+        textNode2 = $(containerContent.get(idx2)),\r
+        sameNode = textNode1.get(0) === textNode2.get(0),\r
+        prefixOutside = textNode1.text().substr(0, options.offsetStart),\r
+        prefixInside = textNode1.text().substr(options.offsetStart),\r
+        suffixInside = textNode2.text().substr(0, options.offsetEnd),\r
+        suffixOutside = textNode2.text().substr(options.offsetEnd)\r
+    ;\r
+    \r
+    textNode1.after(options._with.dom);\r
+    textNode1.detach();\r
+    \r
+    options._with.dom.before(prefixOutside);\r
+    if(sameNode) {\r
+        var core = textNode1.text().substr(options.offsetStart, options.offsetEnd - options.offsetStart);\r
+        options._with.setContent(core);\r
+    } else {\r
+        textNode2.detach();\r
+        options._with.dom.append(prefixInside);\r
+        for(var i = idx1 + 1; i < idx2; i++) {\r
+            options._with.dom.append(containerContent[i]);\r
+        }\r
+        options._with.dom.append(suffixInside);\r
     }\r
     }\r
-}\r
+    options._with.dom.after(suffixOutside);\r
+};\r
 \r
 \r
-Canvas.prototype.splitNode = function(options) {\r
+Canvas.prototype.nodeSplit = function(options) {\r
     options = _.extend({textNodeIdx: 0}, options);\r
     \r
     options = _.extend({textNodeIdx: 0}, options);\r
     \r
-    var nodeToSplit = $(this.content.find('#' + options.node.id).get(0));\r
+    var nodeToSplit = $(this.content.find('#' + options.node.getId()).get(0));\r
     \r
     var nodeContents = nodeToSplit.contents();\r
     if(nodeContents.length === 0 || \r
     \r
     var nodeContents = nodeToSplit.contents();\r
     if(nodeContents.length === 0 || \r
@@ -98,50 +116,56 @@ Canvas.prototype.splitNode = function(options) {
         var node = this;\r
         if(passed)\r
             succeedingNodes.push(node);\r
         var node = this;\r
         if(passed)\r
             succeedingNodes.push(node);\r
-        if(node.isSameNode(textNode.get(0)))\r
+        if(node === textNode.get(0))\r
             passed = true;\r
     });\r
     \r
             passed = true;\r
     });\r
     \r
-    var prefix = textNode.text().substr(0, options.offset);\r
-    var suffix = textNode.text().substr(options.offset);\r
+    var prefix = $.trim(textNode.text().substr(0, options.offset));\r
+    var suffix = $.trim(textNode.text().substr(options.offset));\r
     \r
     textNode.before(prefix);\r
     textNode.remove();\r
     \r
     \r
     textNode.before(prefix);\r
     textNode.remove();\r
     \r
-    var newNode = this._createNode(nodeToSplit.attr('wlxml-tag'), nodeToSplit.attr('wlxml-class'));\r
-    newNode.append(suffix);\r
+    var newNode = canvasNode.create({tag: nodeToSplit.attr('wlxml-tag'), klass: nodeToSplit.attr('wlxml-class')});\r
+    newNode.dom.append(suffix);\r
     succeedingNodes.forEach(function(node) {\r
     succeedingNodes.forEach(function(node) {\r
-        newNode.append(node)\r
+        newNode.dom.append(node)\r
     });\r
     });\r
-    nodeToSplit.after(newNode);\r
+    nodeToSplit.after(newNode.dom);\r
     return newNode;\r
     return newNode;\r
-}\r
+};\r
 \r
 \r
-Canvas.prototype.removeNode = function(options) {\r
-    var toRemove = $(this.content.find('#' + options.node.id).get(0));\r
+Canvas.prototype.nodeRemove = function(options) {\r
+    var toRemove = $(this.content.find('#' + options.node.getId()).get(0));\r
     toRemove.remove();\r
     toRemove.remove();\r
+};\r
 \r
 \r
-}\r
-\r
-Canvas.prototype.createList = function(options) {\r
-    var element1 = $(this.content.find('#' + options.start.id).get(0));\r
-    var element2 = $(this.content.find('#' + options.end.id).get(0));\r
-    if(!element1.parent().get(0).isSameNode(element2.parent().get(0)))\r
+Canvas.prototype.listCreate = function(options) {\r
+    var element1 = $(this.content.find('#' + options.start.getId()).get(0));\r
+    var element2 = $(this.content.find('#' + options.end.getId()).get(0));\r
+    if(!element1.parent().get(0) === element2.parent().get(0))\r
         return false;\r
         \r
     var parent = element1.parent();\r
         return false;\r
         \r
     var parent = element1.parent();\r
+    \r
+    if(parent.contents().index(element1) > parent.contents().index(element2)) {\r
+        var tmp = element1;\r
+        element1 = element2;\r
+        element2 = tmp;\r
+    }\r
+    \r
     var nodesToWrap = [];\r
     \r
     var place = 'before';\r
     var canvas = this;\r
     parent.contents().each(function() {\r
         var node = this;\r
     var nodesToWrap = [];\r
     \r
     var place = 'before';\r
     var canvas = this;\r
     parent.contents().each(function() {\r
         var node = this;\r
-        if(node.isSameNode(element1.get(0)))\r
+        if(node === element1.get(0))\r
             place = 'inside';\r
         if(place === 'inside') {\r
             var $node;\r
             if(node.nodeType === 3) {\r
             place = 'inside';\r
         if(place === 'inside') {\r
             var $node;\r
             if(node.nodeType === 3) {\r
-                $node = canvas._createNode('div').text(node.data);\r
+                $node = canvasNode.create({tag: 'div', content: $.trim(node.data)}).dom; //canvas._createNode('div').text(node.data);\r
                 $(node).remove();\r
             }\r
             else {\r
                 $(node).remove();\r
             }\r
             else {\r
@@ -150,23 +174,73 @@ Canvas.prototype.createList = function(options) {
             $node.attr('wlxml-class', 'item');\r
             nodesToWrap.push($node);\r
         }\r
             $node.attr('wlxml-class', 'item');\r
             nodesToWrap.push($node);\r
         }\r
-        if(node.isSameNode(element2.get(0)))\r
+        if(node === element2.get(0))\r
             return false;\r
     });\r
     \r
             return false;\r
     });\r
     \r
-    var list = this._createNode('div', 'list-items');\r
-    element1.before(list);\r
+    var list = canvasNode.create({tag: 'div', klass: 'list-items' + (options.type === 'enum' ? '-enum' : '')}).dom; //this._createNode('div', 'list-items');\r
+    \r
+    var parentNode = options.start.parent();\r
+    \r
+    var toret;\r
+    if(parentNode && parentNode.isOfClass('list-items')) {\r
+        list.wrap('<div wlxml-tag="div" wlxml-class="item" class="canvas-silent-item">');\r
+        toret = list.parent();\r
+    } else {\r
+        toret = list;\r
+    }\r
+        \r
+    \r
+    element1.before(toret);\r
     \r
     nodesToWrap.forEach(function(node) {\r
         node.remove();\r
         list.append(node);\r
     });\r
     \r
     nodesToWrap.forEach(function(node) {\r
         node.remove();\r
         list.append(node);\r
     });\r
+};\r
+\r
+Canvas.prototype.listRemove = function(options) {\r
+    var pointerElement = $(this.content.find('#' + options.pointer.getId()));\r
+    var listElement = options.pointer.getClass() === 'list-items' ? pointerElement : \r
+        pointerElement.parents('[wlxml-class|="list-items"][wlxml-tag]');\r
     \r
     \r
+    var nested = false;\r
+    if(listElement.length > 1) {\r
+        listElement = $(listElement[0]);\r
+        nested = true;\r
+    }\r
     \r
     \r
-    \r
-}\r
+    if(nested) {\r
+        listElement.unwrap();\r
+    } else {\r
+        listElement.find('[wlxml-class=item]').each(function() {\r
+            $(this).removeAttr('wlxml-class');\r
+        });\r
+    }\r
+    listElement.children().unwrap();\r
+};\r
+\r
+Canvas.prototype.getPrecedingNode = function(options) {\r
+    var element = $(this.content.find('#' + options.node.getId()).get(0));\r
+    var prev = element.prev()\r
+    if(prev.length === 0)\r
+        prev = element.parent();\r
+    return canvasNode.create(prev);\r
+};\r
+\r
+Canvas.prototype.nodeInsideList = function(options) {\r
+    if(options.node) {\r
+        if(options.node.isOfClass('list-items') || options.node.isOfClass('item'))\r
+            return true;\r
+        var pointerElement = $(this.content.find('#' + options.node.getId()));\r
+        return pointerElement.parents('[wlxml-class=list-items], [wlxml-class=item]').length > 0;\r
+    }\r
+    return false;\r
+};\r
 \r
 \r
 \r
 \r
-return {Canvas: Canvas, Node: Node};\r
+return {\r
+    create: function(desc) { return new Canvas(desc); }\r
+};\r
 \r
 });
\ No newline at end of file
 \r
 });
\ No newline at end of file