integration wip: nodePane, familyTree, breadcrumbs
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Mon, 15 Jul 2013 08:12:15 +0000 (10:12 +0200)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Mon, 15 Jul 2013 08:12:15 +0000 (10:12 +0200)
- changing attrs via nodePane (todo: meta)
- highlighting/selecting elements via familiyTree, breadcrumbs
(todo: highlighting back via canvas)

modules/documentCanvas/canvas/canvas.js
modules/documentCanvas/canvas/documentElement.js
modules/documentCanvas/documentCanvas.js
modules/documentCanvas/documentCanvas.less
modules/documentCanvas/nodes.less
modules/nodeBreadCrumbs/nodeBreadCrumbs.js
modules/nodeBreadCrumbs/template.html
modules/nodeFamilyTree/nodeFamilyTree.js
modules/nodeFamilyTree/template.html
modules/nodePane/nodePane.js
modules/rng/rng.js

index ba86a32..0d92d55 100644 (file)
@@ -82,12 +82,12 @@ $.extend(Canvas.prototype, {
 
             this.wrapper.on('keyup', function(e) {
                 if(e.which >= 37 && e.which <= 40)
-                    canvas.markAsCurrent(canvas.getCursor().getPosition().element)
+                    canvas.setCurrentElement(canvas.getCursor().getPosition().element, {caretTo: false})
             });
 
             this.wrapper.on('click', '[wlxml-tag], [wlxml-text]', function(e) {
                 e.stopPropagation();
-                canvas.markAsCurrent(canvas.getCursor().getPosition().element)
+                canvas.setCurrentElement(canvas.getDocumentElement(e.target), {caretTo: false});
             });
 
         } else {
@@ -156,18 +156,84 @@ $.extend(Canvas.prototype, {
 
     list: {},
 
-    markAsCurrent: function(element) {
-        if(element instanceof documentElement.DocumentTextElement) {
+
+
+    highlightElement: function(element) {
+        this.wrapper.find('.highlighted-element').removeClass('highlighted-element');
+        element.dom().addClass('highlighted-element');
+    },
+
+    dimElement: function(element) {
+        element.dom().removeClass('highlighted-element');
+    },
+    
+    getCurrentNodeElement: function() {
+        return this.getDocumentElement(this.wrapper.find('.current-node-element')[0]);
+    },
+
+    getCurrentTextElement: function() {
+        return this.getDocumentElement(this.wrapper.find('.current-text-element')[0]);
+    },
+
+
+
+    setCurrentElement: function(element, params) {
+        params = _.extend({caretTo: 'end'}, params);
+        var findFirstDirectTextChild = function(e) {
+            var children = e.children();
+            for(var i = 0; i < children.length; i++) {
+                if(children[i] instanceof documentElement.DocumentTextElement)
+                    return children[i];
+            }
+            return null;
+        };
+        var _markAsCurrent = function(element) {
+            if(element instanceof documentElement.DocumentTextElement) {
+                this.wrapper.find('.current-text-element').removeClass('current-text-element');
+                element.dom().addClass('current-text-element');
+            } else {
+                this.wrapper.find('.current-node-element').removeClass('current-node-element')
+                element.dom().addClass('current-node-element');
+                this.publisher('currentElementChanged', element);
+            }
+        }.bind(this);
+        var _moveCaretToTextElement = function(element, where) {
+            var range = document.createRange();
+            range.selectNodeContents(element.dom().contents()[0]);
+            
+            var collapseArg = true;
+            if(where === 'end')
+                collapseArg = false;
+            range.collapse(collapseArg);
+            var selection = document.getSelection();
+            selection.removeAllRanges();
+            selection.addRange(range);
+        };
+
+        var isTextElement = element instanceof documentElement.DocumentTextElement,
+            textElementToLand = isTextElement ? element : findFirstDirectTextChild(element),
+            nodeElementToLand = isTextElement ? element.parent() : element,
+            currentTextElement = this.getCurrentTextElement(),
+            currentNodeElement = this.getCurrentNodeElement();
+
+        if(currentTextElement && !(currentTextElement.sameNode(textElementToLand)))
             this.wrapper.find('.current-text-element').removeClass('current-text-element');
-            element.dom().addClass('current-text-element');
-            this.markAsCurrent(element.parent());
-            this.publisher('currentTextElementChanged', element);
-        } else {
-            this.wrapper.find('.current-node-element').removeClass('current-node-element')
-            element.dom().addClass('current-node-element');
+
+        if(textElementToLand && !(textElementToLand.sameNode(currentTextElement))) {
+            _markAsCurrent(textElementToLand);
+            if(params.caretTo)
+                _moveCaretToTextElement(textElementToLand, params.caretTo); // as method on element?
+            this.publisher('currentTextElementSet', element);
         }
 
+        if(!(currentNodeElement && currentNodeElement.sameNode(nodeElementToLand))) {
+            _markAsCurrent(nodeElementToLand);
+            if(!textElementToLand)
+                document.getSelection().removeAllRanges();
+            this.publisher('currentNodeElementSet', nodeElementToLand);
+        }
     }
+
 });
 
 $.extend(Canvas.prototype.list, {
index 5ac22fd..3a89bd1 100644 (file)
@@ -52,6 +52,16 @@ $.extend(DocumentElement.prototype, {
         return null;
     },
 
+    parents: function() {
+        var parents = [],
+            parent = this.parent();
+        while(parent) {
+            parents.push(parent);
+            parent = parent.parent();
+        }
+        return parents;
+    },
+
     sameNode: function(other) {
         return other && (typeof other === typeof this) && other.dom()[0] === this.dom()[0];
     },
index 341f245..9488aed 100644 (file)
@@ -31,30 +31,19 @@ return function(sandbox) {
         getDocument: function() {
             return transformations.toXML.getXML(canvas.getContent());
         },
-        modifyCurrentNode: function(attr, value) {
-            if(manager.currentNode) {
-                if(attr === 'tag') {
-                    manager.getNodeElement(manager.currentNode).attr('wlxml-'+attr, value);
-                }
-                else if(attr === 'class') {
-                    manager.currentNode.setClass(value);
-                } else {
-                    // changing node meta attr
-                    manager.currentNode.setMetaAttr(attr, value);
-                }
-                sandbox.publish('contentChanged');
-                sandbox.publish('currentNodeChanged', manager.currentNode);
+        modifyCurrentNodeElement: function(attr, value) {
+            if(attr === 'class' || attr === 'tag') {
+                canvas.getCurrentNodeElement()['setWlxml'+(attr[0].toUpperCase() + attr.substring(1))](value);    
             }
         },
-        highlightNode: function(canvasNode) {
-            manager.highlightNode(canvasNode);
+        highlightElement: function(element) {
+            canvas.highlightElement(element);
         },
-        dimNode: function(canvasNode) {
-            manager.dimNode(canvasNode);
+        dimElement: function(element) {
+            canvas.dimElement(element);
         },
-        selectNode: function(canvasNode) {
-            if(!canvasNode.isSame(manager.currentNode))
-                manager.selectNode(canvasNode, {movecaret: true});
+        jumpToElement: function(element) {
+            canvas.setCurrentElement(element);
         },
         command: function(command, params) {
             manager.command(command, params);
index 9fc33fd..6f70613 100644 (file)
         border-style: solid;
         border-width: 1px;
     }
+
+    .highlighted-element {
+        border: 1px solid red;
+    }
 }
 
 .rng-module-documentCanvas-currentNode {
index bd80c00..9128290 100644 (file)
@@ -1,6 +1,7 @@
 [wlxml-text] {
     display: inline;
     margin: 0 1px;
+    border: 1px solid white;
 }
 
 [wlxml-tag] {
index e9fc107..9bf211e 100644 (file)
@@ -15,30 +15,29 @@ return function(sandbox) {
             var view = this;
             this.dom.on('mouseenter', 'a', function(e) {
                 var target = $(e.target);
-                sandbox.publish('nodeHighlighted', view.nodes[target.attr('data-id')]);
+                sandbox.publish('elementEntered', target.data('element'));
             });
             this.dom.on('mouseleave', 'a', function(e) {
                 var target = $(e.target);
-                sandbox.publish('nodeDimmed', view.nodes[target.attr('data-id')]);
+                sandbox.publish('elementLeft', target.data('element'));
             });
             this.dom.on('click', 'a', function(e) {
                 e.preventDefault();
                 var target = $(e.target);
-                sandbox.publish('nodeSelected', view.nodes[target.attr('data-id')]);
+                sandbox.publish('elementClicked', target.data('element'));
             });
         },
         
-        setNode: function(node) {
+        setNodeElement: function(nodeElement) {
             this.dom.empty();
-            var nodes = this.nodes = {};
-            this.currentNode = node;
-            this.nodes[node.getId()] = node;
-            var parents = node.parents();
-            parents.each(function() {
-                var parent = this;
-                nodes[parent.getId()] = parent;
+            this.currentNodeElement = nodeElement;
+            var parents = nodeElement.parents();
+            this.dom.html(template({node: nodeElement, parents: parents}));
+
+            this.dom.find('li > a[href="#"]').each(function(idx, a) {
+                $(a).data('element', parents[parents.length - 1 - idx]);
             });
-            this.dom.html(template({node: node, parents: parents}));
+            this.dom.find('a.active').data('element', nodeElement);
         },
         
         highlightNode: function(node) {
@@ -54,9 +53,9 @@ return function(sandbox) {
     return {
         start: function() { sandbox.publish('ready'); },
         getView: function() { return view.dom; },
-        setNode: function(canvasNode) {
-            if(!canvasNode.isSame(view.currentNode)) {
-                view.setNode(canvasNode);
+        setNodeElement: function(nodeElement) {
+            if(!nodeElement.sameNode(view.currentNodeElement)) {
+                view.setNodeElement(nodeElement);
             }
         },
         highlightNode: function(id) { view.highlightNode(id); },
index 2d980c3..6c46613 100644 (file)
@@ -2,9 +2,9 @@
     <ul class="breadcrumb">
     <% if(node && parents) { %>
         <% for(var i = parents.length - 1; i >= 0; i--) { %>
-            <li><a href="#" data-id="<%= parents[i].getId() %>"> <%= parents[i].getTag() %><% if(parents[i].getClass()) { %>.<%= parents[i].getClass() %> <% } %></a><span class="divider">/</span></li>
+            <li><a href="#"> <%= parents[i].getWlxmlTag() %><% if(parents[i].getWlxmlClass()) { %>.<%= parents[i].getWlxmlClass() %> <% } %></a><span class="divider">/</span></li>
         <% } %>
-            <li class="active"><span data-id="<%= node.getId() %>"><%= node.getTag() %><% if(node.getClass()) { %>.<%= node.getClass() %> <% } %></span></li>
+            <li class="active"><%= node.getWlxmlTag() %><% if(node.getWlxmlClass()) { %>.<%= node.getWlxmlClass() %> <% } %></span></li>
     <% } %>
     </ul>
 </div>
\ No newline at end of file
index 39ea20f..e47821e 100644 (file)
@@ -16,41 +16,54 @@ return function(sandbox) {
             var view = this;
             this.dom.on('click', 'a', function(e) {
                 var target = $(e.target);
-                sandbox.publish('nodeSelected', view.nodes[target.attr('data-id')]);
+                sandbox.publish('elementClicked', target.data('element'));
             });
             
             this.dom.on('mouseenter', 'a', function(e) {
                 var target = $(e.target);
-                sandbox.publish('nodeEntered', view.nodes[target.attr('data-id')]);
+                sandbox.publish('elementEntered', target.data('element'));
             });
             this.dom.on('mouseleave', 'a', function(e) {
                 var target = $(e.target);
-                sandbox.publish('nodeLeft', view.nodes[target.attr('data-id')]);
+                sandbox.publish('elementLeft', target.data('element'));
             });
         },
-        setNode: function(node) {
+        setElement: function(element) {
             console.log('familyTree sets node');
-            var nodes = this.nodes = {};
-            this.currentNode = node;
-            var parentNode = node.parent();
-            var parent;
+            var textElement = element.getText ? element : null,
+                nodeElement = element.getText ? element.parent() : element, // TODO: better type detection
+                nodeElementParent = nodeElement.parent(),
+                parent;
             
-            if(parentNode) {
+            this.currentNodeElement = nodeElement;
+
+            if(nodeElementParent) {
                 parent = {
-                    repr: parentNode.getTag() + (parentNode.getClass() ? ' / ' + parentNode.getClass() : ''),
-                    id: parentNode.getId()
+                    repr: nodeElementParent.getWlxmlTag() + (nodeElementParent.getWlxmlClass() ? ' / ' + nodeElementParent.getWlxmlClass() : '')
                 };
-                this.nodes[parentNode.getId()] = parentNode;
             }
         
-            var children = [];
-            node.children().each(function() {
-                var child = this;
-                children.push({repr: child.getTag() + (child.getClass() ? ' / ' + child.getClass() : ''), id: child.getId()});
-                nodes[child.getId()] = child;
+            var nodeChildren = nodeElement.children(),
+                children = [];
+            nodeChildren.forEach(function(child) {
+                if(child.getText) {
+                    var text = child.getText();
+                    if(text.length > 13)
+                        text = text.substr(0,13) + '...';
+                    children.push({repr: '"' + text + '"', bold: child.sameNode(textElement)});
+                } else {
+                    children.push({repr: child.getWlxmlTag() + (child.getWlxmlClass() ? ' / ' + child.getWlxmlClass() : '')});
+                }
             });
             this.dom.empty();
             this.dom.append($(template({parent: parent, children: children})));
+
+            if(parent) {
+                this.dom.find('.rng-module-nodeFamilyTree-parent').data('element', nodeElementParent)
+            }
+            this.dom.find('li a').each(function(idx, a) {
+                $(a).data('element', nodeChildren[idx]);
+            });
         },
         highlightNode: function(canvasNode) {
             this.dom.find('a[data-id="'+canvasNode.getId()+'"]').addClass('rng-common-hoveredNode');
@@ -66,9 +79,9 @@ return function(sandbox) {
         start: function() {
             sandbox.publish('ready');
         },
-        setNode: function(canvasNode) {
-            if(!canvasNode.isSame(view.currentNode))
-                view.setNode(canvasNode);
+        setElement: function(element) {
+            if(!(element.sameNode(view.currentNodeElement)))
+                view.setElement(element);
         },
         getView: function() {
             return view.dom;
index 8a7df5c..9bccfc3 100644 (file)
@@ -2,7 +2,7 @@
     <table class="table table-bordered">
         <tr>
             <td>powyżej</td>
-            <td><% if(parent) { %><a href="#" class="rng-module-nodeFamilyTree-parent" data-id="<%= parent.id %>"><%= parent.repr %></a><% } else { %>-<% } %></td>
+            <td><% if(parent) { %><a href="#" class="rng-module-nodeFamilyTree-parent"><%= parent.repr %></a><% } else { %>-<% } %></td>
         </tr>
         <tr>
             <td rowspan="0">poniżej</td>
@@ -10,7 +10,7 @@
                 <ul>
                 <% if(!children || children.length === 0) { %>-<% } else { %>
                     <% children.forEach(function(child) { %>
-                        <li><a href="#" data-id="<%= child.id %>"><%= child.repr %></a></li>
+                        <li><% if(child.bold) { %><strong><% } %><a href="#"><%= child.repr %></a><% if(child.bold) { %></strong><% } %></li>
                     <% }); %>
                 <% } %>
                 </ul>
index 39afbea..a1c2a81 100644 (file)
@@ -14,7 +14,7 @@ return function(sandbox) {
     view.on('change', 'select', function(e) {
         var target = $(e.target);
         var attr = target.attr('class').split('-')[3] === 'tagSelect' ? 'tag' : 'class';
-        sandbox.publish('nodeChanged', attr, target.val());
+        sandbox.publish('nodeElementChange', attr, target.val());
     });
     
     return {
@@ -24,15 +24,15 @@ return function(sandbox) {
         getView: function() {
             return view;
         },
-        setNode: function(canvasNode) {
-            view.find('.rng-module-nodePane-tagSelect').val(canvasNode.getTag());
-            view.find('.rng-module-nodePane-classSelect').val(canvasNode.getClass());
+        setNodeElement: function(nodeElement) {
+            view.find('.rng-module-nodePane-tagSelect').val(nodeElement.getWlxmlTag());
+            view.find('.rng-module-nodePane-classSelect').val(nodeElement.getWlxmlClass());
 
-            var widget = metaWidget.create({attrs:canvasNode.getMetaAttrs()});
-            widget.on('valueChanged', function(key, value) {
-                sandbox.publish('nodeChanged', key, value);
-            });
-            view.find('.metaFields').empty().append(widget.el);
+            //var widget = metaWidget.create({attrs:canvasNode.getMetaAttrs()});
+            //widget.on('valueChanged', function(key, value) {
+            //    sandbox.publish('nodeChanged', key, value);
+            //});
+            //view.find('.metaFields').empty().append(widget.el);
         }
     };
     
index d773c30..a3e746c 100644 (file)
@@ -50,26 +50,30 @@ return function(sandbox) {
     };
     
     var commands = {
-        highlightDocumentNode: function(canvasNode, origin) {
-            ['documentCanvas', 'nodeBreadCrumbs', 'nodeFamilyTree'].forEach(function(moduleName) {
+        highlightDocumentElement: function(element, origin) {
+            ///'nodeBreadCrumbs', 'nodeFamilyTree'
+            ['documentCanvas', ].forEach(function(moduleName) {
                 if(!origin || moduleName != origin)
-                    sandbox.getModule(moduleName).highlightNode(canvasNode);
+                    sandbox.getModule(moduleName).highlightElement(element);
             });
         },
-        dimDocumentNode: function(canvasNode, origin) {
-            ['documentCanvas', 'nodeBreadCrumbs', 'nodeFamilyTree'].forEach(function(moduleName) {
+        dimDocumentElement: function(element, origin) {
+            //'nodeBreadCrumbs', 'nodeFamilyTree'
+            ['documentCanvas'].forEach(function(moduleName) {
                 if(!origin || moduleName != origin)
-                    sandbox.getModule(moduleName).dimNode(canvasNode);
+                    sandbox.getModule(moduleName).dimElement(element);
             });
         },
-        selectNode: function(canvasNode, origin) {
-            sandbox.getModule('documentCanvas').selectNode(canvasNode);
-            this.updateNodesModules(canvasNode);           
+        jumpToDocumentElement: function(element) {
+            sandbox.getModule('documentCanvas').jumpToElement(element);
         },
-        updateNodesModules: function(canvasNode) {
-            sandbox.getModule('nodePane').setNode(canvasNode);
-            sandbox.getModule('nodeFamilyTree').setNode(canvasNode);
-            sandbox.getModule('nodeBreadCrumbs').setNode(canvasNode);
+        updateCurrentNodeElement: function(nodeElement) {
+            sandbox.getModule('nodePane').setNodeElement(nodeElement);
+            sandbox.getModule('nodeFamilyTree').setElement(nodeElement);
+            sandbox.getModule('nodeBreadCrumbs').setNodeElement(nodeElement);
+        },
+        updateCurrentTextElement: function(textElement) {
+            sandbox.getModule('nodeFamilyTree').setElement(textElement);
         },
         resetDocument: function(document, reason) {
             var modules = [];
@@ -193,17 +197,17 @@ return function(sandbox) {
             dirty.documentCanvas = false;
         },
         
-        nodeSelected: function(canvasNode) {
-            commands.selectNode(canvasNode);
+        currentTextElementSet: function(textElement) {
+            commands.updateCurrentTextElement(textElement);
+        },
+
+        currentNodeElementSet: function(nodeElement) {
+            commands.updateCurrentNodeElement(nodeElement);
         },
         
         contentChanged: function() {
             dirty.documentCanvas = true;
         },
-        
-        currentNodeChanged: function(canvasNode) {
-            commands.updateNodesModules(canvasNode);
-        },
 
         nodeHovered: function(canvasNode) {
             commands.highlightDocumentNode(canvasNode);
@@ -219,8 +223,8 @@ return function(sandbox) {
             views.currentNodePaneLayout.appendView(sandbox.getModule('nodePane').getView());
         },
         
-        nodeChanged: function(attr, value) {
-            sandbox.getModule('documentCanvas').modifyCurrentNode(attr, value);
+        nodeElementChange: function(attr, value) {
+            sandbox.getModule('documentCanvas').modifyCurrentNodeElement(attr, value);
         }
     };
     
@@ -241,14 +245,14 @@ return function(sandbox) {
         ready: function() {
             views.currentNodePaneLayout.appendView(sandbox.getModule('nodeFamilyTree').getView());
         },
-        nodeEntered: function(canvasNode) {
-            commands.highlightDocumentNode(canvasNode, 'nodeFamilyTree');
+        elementEntered: function(element) {
+            commands.highlightDocumentElement(element, 'nodeFamilyTree');
         },
-        nodeLeft: function(canvasNode) {
-            commands.dimDocumentNode(canvasNode, 'nodeFamilyTree');
+        elementLeft: function(element) {
+            commands.dimDocumentElement(element, 'nodeFamilyTree');
         },
-        nodeSelected: function(canvasNode) {
-            commands.selectNode(canvasNode);
+        elementClicked: function(element) {
+            commands.jumpToDocumentElement(element);
         }
     };
     
@@ -265,14 +269,14 @@ return function(sandbox) {
         ready: function() {
             views.visualEditing.setView('statusBar', sandbox.getModule('nodeBreadCrumbs').getView());
         },
-        nodeHighlighted: function(canvasNode) {
-            commands.highlightDocumentNode(canvasNode, 'nodeBreadCrumbs');
+        elementEntered: function(element) {
+            commands.highlightDocumentElement(element, 'nodeBreadCrumbs');
         },
-        nodeDimmed: function(canvasNode) {
-            commands.dimDocumentNode(canvasNode, 'nodeBreadCrumbs');
+        elementLeft: function(element) {
+            commands.dimDocumentElement(element, 'nodeBreadCrumbs');
         },
-        nodeSelected: function(canvasNode) {
-            commands.selectNode(canvasNode);
+        elementClicked: function(element) {
+            commands.jumpToDocumentElement(element);
         }        
     };