widgets wip - widgets mechanism + label widget
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Sun, 28 Jul 2013 19:45:26 +0000 (21:45 +0200)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Mon, 5 Aug 2013 10:20:06 +0000 (12:20 +0200)
modules/documentCanvas/canvas/canvas.js
modules/documentCanvas/canvas/canvas.test3.js
modules/documentCanvas/canvas/documentElement.js
modules/documentCanvas/documentCanvas.less

index f9f3ee0..0449a9a 100644 (file)
@@ -48,9 +48,12 @@ $.extend(Canvas.prototype, {
                 return element.dom();
             });
 
+            var FIRST_CONTENT_INDEX = 1;
+
             this.wrapper.find(':not(iframe)').addBack().contents()
                 .filter(function() {return this.nodeType === Node.TEXT_NODE})
                 .each(function() {
+
                     // TODO: use DocumentElement API
 
                     var el = $(this),
@@ -60,11 +63,13 @@ $.extend(Canvas.prototype, {
                         hasSpanBefore = el.prev().length > 0  && $(el.prev()[0]).attr('wlxml-tag') === 'span',
                         hasSpanAfter = el.next().length > 0 && $(el.next()[0]).attr('wlxml-tag') === 'span';
 
+                    if(el.parent().hasClass('canvas-widget'))
+                        return true; // continue
 
                     var addInfo = function(toAdd, where) {
                         var parentContents = elParent.contents(),
                             idx = parentContents.index(el[0]),
-                            prev = idx > 0 ? parentContents[idx-1] : null,
+                            prev = idx > FIRST_CONTENT_INDEX ? parentContents[idx-1] : null,
                             next = idx < parentContents.length - 1 ? parentContents[idx+1] : null,
                             target, key;
 
@@ -88,7 +93,7 @@ $.extend(Canvas.prototype, {
                                     + text.trimmed
                                     + (endSpace && (hasSpanParent || hasSpanAfter) ? ' ' : '');
                     } else {
-                        if(text.trimmed.length === 0 && text.original.length > 0 && elParent.contents().length === 1)
+                        if(text.trimmed.length === 0 && text.original.length > 0 && elParent.contents().length === 2)
                             text.transformed = ' ';
                     }
 
@@ -201,7 +206,6 @@ $.extend(Canvas.prototype, {
                 canvas.setCurrentElement(canvas.getDocumentElement(e.target), {caretTo: false});
             });
 
-
             var observer = new MutationObserver(function(mutations) {
                 mutations.forEach(function(mutation) {
                     if(documentElement.DocumentTextElement.isContentContainer(mutation.target) && mutation.target.data === '')
@@ -211,6 +215,25 @@ $.extend(Canvas.prototype, {
             var config = { attributes: false, childList: false, characterData: true, subtree: true, characterDataOldValue: true};
             observer.observe(this.d[0], config);
 
+            this.wrapper.on('mouseover', '[wlxml-tag], [wlxml-text]', function(e) {
+                var el = canvas.getDocumentElement(e.target);
+                if(!el)
+                    return;
+                e.stopPropagation();
+                if(el instanceof documentElement.DocumentTextElement)
+                    el = el.parent();
+                el.toggleLabel(true);
+            });
+            this.wrapper.on('mouseout', '[wlxml-tag], [wlxml-text]', function(e) {
+                var el = canvas.getDocumentElement(e.target);
+                if(!el)
+                    return;
+                e.stopPropagation();
+                if(el instanceof documentElement.DocumentTextElement)
+                    el = el.parent();
+                el.toggleLabel(false);
+            });
+
         } else {
             this.d = null;
         }
index c969ba9..b649b9a 100644 (file)
@@ -12,38 +12,6 @@ var expect = chai.expect;
 
 describe('Canvas', function() {
 
-    describe('Internal HTML representation of a sample document', function() {
-        it('works', function() {
-            var c = canvas.fromXML('\
-                <section>\
-                    This is some text without its own wrapping tag.\
-                    <div class="p.subclass">\
-                        This is a paragraph.\
-                    </div>\
-                    <div>\
-                        This is text in a div <span>with some inline text</span>.\
-                    </div>\
-                    This is some text without its own wrapping tag.\
-                </section>\
-            ');
-            var expected = '<div wlxml-tag="section">'
-                            + '<div wlxml-text>This is some text without its own wrapping tag.</div>'
-                            + '<div wlxml-tag="div" wlxml-class="p-subclass">'
-                            +   '<div wlxml-text>This is a paragraph.</div>'
-                            + '</div>'
-                            + '<div wlxml-tag="div">'
-                            +   '<div wlxml-text>This is text in a div </div>'
-                            +   '<div wlxml-tag="span">'
-                            +       '<div wlxml-text>with some inline text</div>'
-                            +   '</div>'
-                            +   '<div wlxml-text>.</div>'
-                            + '</div>'
-                            + '<div wlxml-text>This is some text without its own wrapping tag.</div>'
-                            + '</div>';
-            expect(c.doc().dom()[0].isEqualNode($(expected)[0])).to.be.true;
-        });
-    });
-
     describe('Internal HTML representation of a DocumentNodeElement', function() {
         it('is always a div tag', function() {
             ['section', 'header', 'span', 'aside', 'figure'].forEach(function(tagName) {
@@ -1039,7 +1007,7 @@ describe('Canvas', function() {
         it('returns position when browser selection collapsed', function() {
             var c = canvas.fromXML('<section>Alice has a cat</section>'),
                 dom = c.doc().dom(),
-                text = $(dom.contents()[0]).contents()[0];
+                text = $(dom.contents()[1]).contents()[0];
 
             expect(text.nodeType).to.equal(Node.TEXT_NODE, 'correct node selected');
             expect($(text).text()).to.equal('Alice has a cat');
@@ -1074,9 +1042,9 @@ describe('Canvas', function() {
             var c = canvas.fromXML('<section>Alice <span>has</span> a <span>big</span> cat</section>'),
                 dom = c.doc().dom(),
                 text = {
-                    alice: dom.contents()[0],
-                    has: $(dom.contents()[1]).contents()[0],
-                    cat: dom.contents()[4]
+                    alice: dom.contents()[1],
+                    has: $(dom.contents()[2]).contents()[1],
+                    cat: dom.contents()[5]
                 },
                 cursor = c.getCursor(),
                 aliceElement = c.getDocumentElement(text.alice),
@@ -1107,11 +1075,11 @@ describe('Canvas', function() {
             var c = canvas.fromXML('<section>Alice <span>has</span> a <span>big</span> cat</section>'),
                 dom = c.doc().dom(),
                 text = {
-                    alice: dom.contents()[0],
-                    has: $(dom.contents()[1]).contents()[0],
-                    a: dom.contents()[2],
-                    big: $(dom.contents()[3]).contents()[0],
-                    cat: dom.contents()[4]
+                    alice: dom.contents()[1],
+                    has: $(dom.contents()[2]).contents()[1],
+                    a: dom.contents()[3],
+                    big: $(dom.contents()[4]).contents()[1],
+                    cat: dom.contents()[5]
                 },
                 cursor = c.getCursor();
 
index b516af1..425978f 100644 (file)
@@ -124,6 +124,14 @@ $.extend(DocumentNodeElement, {
             });
         }
         dom.data('other-attrs', params.others);
+
+        var widgets = $('<div class="canvas-widgets" contenteditable="false">');
+        widgets.append($('<span class="canvas-widget canvas-widget-label">').text(params.tag + (params.klass ? ' / ' + params.klass : '')));
+        dom.append(widgets);
+
+        // Make sure widgets aren't navigable with arrow keys
+        widgets.find('*').add(widgets).attr('tabindex', -1);
+        
         return dom;
     },
 
@@ -248,7 +256,9 @@ $.extend(DocumentNodeElement.prototype, {
         var element = this;
         elementContent.each(function(idx) {
             var childElement = DocumentElement.fromHTMLElement(this, element.canvas);
-            if(idx === 0 && elementContent.length > 1 && elementContent[1].nodeType === Node.ELEMENT_NODE && (childElement instanceof DocumentTextElement) && $.trim($(this).text()) === '')
+            if(childElement === undefined)
+                return true;
+            if(idx === 1 && elementContent.length > 2 && elementContent[1].nodeType === Node.ELEMENT_NODE && (childElement instanceof DocumentTextElement) && $.trim($(this).text()) === '')
                 return true;
             if(idx > 0 && childElement instanceof DocumentTextElement) {
                 if(toret[toret.length-1] instanceof DocumentNodeElement && $.trim($(this).text()) === '')
@@ -298,10 +308,10 @@ $.extend(DocumentNodeElement.prototype, {
         return false;
     },
 
-
     getWlxmlMetaAttr: function(attr) {
         return this.dom().attr('wlxml-meta-'+attr);
     },
+
     getWlxmlMetaAttrs: function() {
         var toret = [];
         var attrList = classAttributes.getMetaAttrsList(this.getWlxmlClass());
@@ -310,8 +320,16 @@ $.extend(DocumentNodeElement.prototype, {
         }, this);
         return toret;
     },
+
     setWlxmlMetaAttr: function(attr, value) {
         this.dom().attr('wlxml-meta-'+attr, value);
+    },
+    
+    toggleLabel: function(toggle) {
+        var displayCss = toggle ? 'inline-block' : 'none';
+        var label = this.dom().children('.canvas-widgets').find('.canvas-widget-label');
+        label.css('display', displayCss);
+        this.dom().toggleClass('highlighted-element');
     }
 });
 
index 6f70613..8a1dc68 100644 (file)
     .highlighted-element {
         border: 1px solid red;
     }
+
+
+    .canvas-widgets {
+        display: inline;
+    }
+
+    .canvas-widget {
+        display: none;
+    }
+
+    .canvas-widget-label {
+        position: absolute;
+        display: none;
+        top: -20px;
+        left:0;
+        background-color: red;
+        color: white;
+        font-size:12px;
+        font-weight: bold;
+        padding: 1px 3px;
+        //width:300px;
+        opacity: 0.65;
+        font-family: monospace;
+        z-index:9999;
+    }
 }
 
 .rng-module-documentCanvas-currentNode {