From: Aleksander Ɓukasz Date: Tue, 30 Jul 2013 09:47:54 +0000 (+0200) Subject: wip: putting node children into internal container X-Git-Url: https://git.mdrn.pl/fnpeditor.git/commitdiff_plain/b2f1929ee729de25d516b0f9cdb49f265ce2d848 wip: putting node children into internal container not working: - synchronization of display style between nodeElement main node and internal container - clicks on canvas that don't land directly inside container (Chrome) --- diff --git a/modules/documentCanvas/canvas/canvas.js b/modules/documentCanvas/canvas/canvas.js index 0449a9a..a89a148 100644 --- a/modules/documentCanvas/canvas/canvas.js +++ b/modules/documentCanvas/canvas/canvas.js @@ -38,17 +38,22 @@ $.extend(Canvas.prototype, { tag: currentTag.prop('tagName').toLowerCase(), klass: currentTag.attr('class'), meta: meta, - others: others + others: others, + rawChildren: currentTag.contents() }); - element.dom().append(currentTag.contents()); ['orig-before', 'orig-after', 'orig-begin', 'orig-end'].forEach(function(attr) { element.data(attr, ''); }); return element.dom(); }); - var FIRST_CONTENT_INDEX = 1; + var FIRST_CONTENT_INDEX = 0; + + // @@ TODO - refactor! + var getNode = function(element) { + return element.children('[document-element-content]'); + } this.wrapper.find(':not(iframe)').addBack().contents() .filter(function() {return this.nodeType === Node.TEXT_NODE}) @@ -60,8 +65,8 @@ $.extend(Canvas.prototype, { text = {original: el.text(), trimmed: $.trim(el.text())}, elParent = el.parent(), hasSpanParent = elParent.attr('wlxml-tag') === 'span', - hasSpanBefore = el.prev().length > 0 && $(el.prev()[0]).attr('wlxml-tag') === 'span', - hasSpanAfter = el.next().length > 0 && $(el.next()[0]).attr('wlxml-tag') === 'span'; + hasSpanBefore = el.prev().length > 0 && getNode($(el.prev()[0])).attr('wlxml-tag') === 'span', + hasSpanAfter = el.next().length > 0 && getNode($(el.next()[0])).attr('wlxml-tag') === 'span'; if(el.parent().hasClass('canvas-widget')) return true; // continue @@ -74,10 +79,10 @@ $.extend(Canvas.prototype, { target, key; if(where === 'above') { - target = prev ? $(prev) : elParent; + target = prev ? $(prev) : elParent.parent(); key = prev ? 'orig-after' : 'orig-begin'; } else if(where === 'below') { - target = next ? $(next) : elParent; + target = next ? $(next) : elParent.parent(); key = next ? 'orig-before' : 'orig-end'; } else { throw new Object;} @@ -93,7 +98,7 @@ $.extend(Canvas.prototype, { + text.trimmed + (endSpace && (hasSpanParent || hasSpanAfter) ? ' ' : ''); } else { - if(text.trimmed.length === 0 && text.original.length > 0 && elParent.contents().length === 2) + if(text.trimmed.length === 0 && text.original.length > 0 && elParent.contents().length === 1) text.transformed = ' '; } diff --git a/modules/documentCanvas/canvas/canvas.test3.js b/modules/documentCanvas/canvas/canvas.test3.js index b649b9a..3b14b19 100644 --- a/modules/documentCanvas/canvas/canvas.test3.js +++ b/modules/documentCanvas/canvas/canvas.test3.js @@ -19,13 +19,13 @@ describe('Canvas', function() { expect(dom.prop('tagName')).to.equal('DIV', tagName + ' is represented as div'); }); }); - it('has wlxml tag put into wlxml-tag attribute', function() { + it('has wlxml tag put into wlxml-tag attribute of its internal container', function() { var dom = canvas.fromXML('
').doc().dom(); - expect(dom.attr('wlxml-tag')).to.equal('section'); + expect(dom.children('[document-element-content]').attr('wlxml-tag')).to.equal('section'); }); - it('has wlxml class put into wlxml-class, dots replaced with dashes', function() { + it('has wlxml class put into wlxml-class attribute of its internal containr, dots replaced with dashes', function() { var dom = canvas.fromXML('
').doc().dom(); - expect(dom.attr('wlxml-class')).to.equal('some-class'); + expect(dom.children('[document-element-content]').attr('wlxml-class')).to.equal('some-class'); }); }); @@ -996,6 +996,15 @@ describe('Canvas', function() { var getSelection; + var findTextNode = function(inside, text) { + var nodes = inside.find(':not(iframe)').addBack().contents().filter(function() { + return this.nodeType === Node.TEXT_NODE && this.data === text; + }); + if(nodes.length) + return nodes[0]; + return null; + } + beforeEach(function() { getSelection = sinon.stub(window, 'getSelection'); }); @@ -1007,7 +1016,7 @@ describe('Canvas', function() { it('returns position when browser selection collapsed', function() { var c = canvas.fromXML('
Alice has a cat
'), dom = c.doc().dom(), - text = $(dom.contents()[1]).contents()[0]; + text = findTextNode(dom, 'Alice has a cat'); expect(text.nodeType).to.equal(Node.TEXT_NODE, 'correct node selected'); expect($(text).text()).to.equal('Alice has a cat'); @@ -1042,9 +1051,9 @@ describe('Canvas', function() { var c = canvas.fromXML('
Alice has a big cat
'), dom = c.doc().dom(), text = { - alice: dom.contents()[1], - has: $(dom.contents()[2]).contents()[1], - cat: dom.contents()[5] + alice: findTextNode(dom, 'Alice '), + has: findTextNode(dom, 'has'), + cat: findTextNode(dom, ' cat') }, cursor = c.getCursor(), aliceElement = c.getDocumentElement(text.alice), @@ -1075,11 +1084,11 @@ describe('Canvas', function() { var c = canvas.fromXML('
Alice has a big cat
'), dom = c.doc().dom(), text = { - alice: dom.contents()[1], - has: $(dom.contents()[2]).contents()[1], - a: dom.contents()[3], - big: $(dom.contents()[4]).contents()[1], - cat: dom.contents()[5] + alice: findTextNode(dom, 'Alice '), + has: findTextNode(dom, 'has'), + a: findTextNode(dom, ' a '), + big: findTextNode(dom, 'big'), + cat: findTextNode(dom, ' cat'), }, cursor = c.getCursor(); diff --git a/modules/documentCanvas/canvas/documentElement.js b/modules/documentCanvas/canvas/documentElement.js index 425978f..1354a84 100644 --- a/modules/documentCanvas/canvas/documentElement.js +++ b/modules/documentCanvas/canvas/documentElement.js @@ -32,7 +32,7 @@ $.extend(DocumentElement, { fromHTMLElement: function(htmlElement, canvas) { var $element = $(htmlElement); - if(htmlElement.nodeType === Node.ELEMENT_NODE && $element.attr('wlxml-tag')) + if(htmlElement.nodeType === Node.ELEMENT_NODE && $element.attr('document-node-element') !== undefined) return DocumentNodeElement.fromHTMLElement(htmlElement, canvas); if($element.attr('wlxml-text') !== undefined || (htmlElement.nodeType === Node.TEXT_NODE && $element.parent().attr('wlxml-text') !== undefined)) return DocumentTextElement.fromHTMLElement(htmlElement, canvas); @@ -48,7 +48,7 @@ $.extend(DocumentElement.prototype, { return this.$element; }, parent: function() { - var parents = this.$element.parents('[wlxml-tag]'); + var parents = this.$element.parents('[document-node-element]'); if(parents.length) return DocumentElement.fromHTMLElement(parents[0], this.canvas); return null; @@ -114,10 +114,12 @@ var DocumentNodeElement = function(htmlElement, canvas) { $.extend(DocumentNodeElement, { createDOM: function(params) { - var dom = $('
') - .attr('wlxml-tag', params.tag); + var dom = $('
'), + container = $('
'); + + container.attr('wlxml-tag', params.tag); if(params.klass) - dom.attr('wlxml-class', params.klass.replace(/\./g, '-')); + container.attr('wlxml-class', params.klass.replace(/\./g, '-')); if(params.meta) { _.keys(params.meta).forEach(function(key) { dom.attr('wlxml-meta-'+key, params.meta[key]); @@ -132,6 +134,11 @@ $.extend(DocumentNodeElement, { // Make sure widgets aren't navigable with arrow keys widgets.find('*').add(widgets).attr('tabindex', -1); + dom.append(container); + + if(params.rawChildren) { + container.append(params.rawChildren); + } return dom; }, @@ -151,7 +158,8 @@ var manipulate = function(e, params, action) { } else { element = DocumentElement.create(params); } - e.dom()[action](element.dom()); + var target = action === 'append' ? e._container() : e.dom(); + target[action](element.dom()); return element; }; @@ -159,6 +167,9 @@ DocumentNodeElement.prototype = new DocumentElement(); $.extend(DocumentNodeElement.prototype, { + _container: function() { + return this.dom().children('[document-element-content]'); + }, data: function() { var dom = this.dom(), args = Array.prototype.slice.call(arguments, 0); @@ -252,13 +263,13 @@ $.extend(DocumentNodeElement.prototype, { return toret; - var elementContent = this.dom().contents(); + var elementContent = this._container().contents(); var element = this; elementContent.each(function(idx) { var childElement = DocumentElement.fromHTMLElement(this, element.canvas); if(childElement === undefined) return true; - if(idx === 1 && elementContent.length > 2 && elementContent[1].nodeType === Node.ELEMENT_NODE && (childElement instanceof DocumentTextElement) && $.trim($(this).text()) === '') + if(idx === 0 && elementContent.length > 1 && 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()) === '') @@ -280,13 +291,13 @@ $.extend(DocumentNodeElement.prototype, { return toret; }, getWlxmlTag: function() { - return this.dom().attr('wlxml-tag'); + return this._container().attr('wlxml-tag'); }, setWlxmlTag: function(tag) { - this.dom().attr('wlxml-tag', tag); + this._container().attr('wlxml-tag', tag); }, getWlxmlClass: function() { - var klass = this.dom().attr('wlxml-class'); + var klass = this._container().attr('wlxml-class'); if(klass) return klass.replace(/-/g, '.'); return undefined; @@ -298,9 +309,9 @@ $.extend(DocumentNodeElement.prototype, { }, this); if(klass) - this.dom().attr('wlxml-class', klass.replace(/\./g, '-')); + this._container().attr('wlxml-class', klass.replace(/\./g, '-')); else - this.dom().removeAttr('wlxml-class'); + this._container().removeAttr('wlxml-class'); }, is: function(what) { if(what === 'list' && _.contains(['list.items', 'list.items.enum'], this.getWlxmlClass())) diff --git a/modules/documentCanvas/documentCanvas.less b/modules/documentCanvas/documentCanvas.less index 8a1dc68..fdc7bab 100644 --- a/modules/documentCanvas/documentCanvas.less +++ b/modules/documentCanvas/documentCanvas.less @@ -96,4 +96,9 @@ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; padding: 0 5px; text-indent: 0; +} + +[document-node-element] { + position:relative; + border: 1px solid white; } \ No newline at end of file diff --git a/modules/documentCanvas/nodes.less b/modules/documentCanvas/nodes.less index 9128290..1b325d6 100644 --- a/modules/documentCanvas/nodes.less +++ b/modules/documentCanvas/nodes.less @@ -47,11 +47,11 @@ color: blue; } -[wlxml-tag=header] > [wlxml-class=author] { +[wlxml-tag=header] [wlxml-class=author] { font-size: 14px; } -[wlxml-tag=header] > [wlxml-class=title] { +[wlxml-tag=header] [wlxml-class=title] { font-size:18px; } @@ -74,7 +74,7 @@ [wlxml-class="list-items"] { - > [wlxml-class="item"] { + [wlxml-class="item"] { display: list-item; margin-left: 10px; padding-left: 5px; @@ -82,7 +82,7 @@ } [wlxml-class="item"] { - > [wlxml-class="list-items"] { + [wlxml-class="list-items"] { display: block; } }