From: Aleksander Ɓukasz Date: Mon, 7 Oct 2013 13:01:13 +0000 (+0200) Subject: wip: first integration of rewritten engine into canvas X-Git-Url: https://git.mdrn.pl/fnpeditor.git/commitdiff_plain/71b7ba4d1d17adc39165914016fa892671cc4316?ds=sidebyside wip: first integration of rewritten engine into canvas --- diff --git a/src/editor/entrypoint.js b/src/editor/entrypoint.js index 5e546ef..851ced3 100644 --- a/src/editor/entrypoint.js +++ b/src/editor/entrypoint.js @@ -6,7 +6,10 @@ paths: { 'fnpjs': '../fnpjs', - 'libs': '../../libs' + 'libs': '../../libs', + 'smartxml': '../smartxml', + 'wlxml': '../wlxml', + }, map: { diff --git a/src/editor/modules/data/data.js b/src/editor/modules/data/data.js index 9b2f163..896fc56 100644 --- a/src/editor/modules/data/data.js +++ b/src/editor/modules/data/data.js @@ -1,4 +1,8 @@ -define(['./saveDialog'], function(saveDialog) { +define([ + './saveDialog', + 'wlxml/wlxml' + +], function(saveDialog, wlxml) { 'use strict'; @@ -9,6 +13,7 @@ return function(sandbox) { var document_version = sandbox.getBootstrappedData().version; var history = sandbox.getBootstrappedData().history; + var wlxmlDocument = wlxml.WLXMLDocumentFromXML(sandbox.getBootstrappedData().document); if(doc === '') { doc = '').addClass('canvas-wrapper').attr('contenteditable', true); + this.wrapper.append(canvasDOM); + this.d = this.wrapper.children(0); + this.setupEventHandling(); + }, + + generateCanvasDOM: function(wlxmlNode) { + // var element = this.createNodeElement2({ + // tag: wlxmlNode.getTagName(), + // klass: wlxmlNode.getClass(), //currentTag.attr('class'), + // meta: wlxmlNode.getMetaAttributes(), //meta, + // others: wlxmlNode.getOtherAttributes(), // ~ //others, + // rawChildren: wlxmlNode.contents(), + // prepopulateOnEmpty: true + // }); //->create2 + + var element = documentElement.DocumentNodeElement.create2(wlxmlNode, this); + + + ['orig-before', 'orig-after', 'orig-begin', 'orig-end'].forEach(function(attr) { + element.data(attr, ''); + }); + return element.dom(); + }, + loadWlxml: function(wlxml) { var d = wlxml ? $($.trim(wlxml)) : null; if(d) { @@ -142,62 +174,67 @@ $.extend(Canvas.prototype, { this.d = this.wrapper.children(0); - this.wrapper.on('keyup keydown keypress', function(e) { - keyboard.handleKey(e, this); - }.bind(this)); - - this.wrapper.on('click', '[document-node-element], [document-text-element]', function(e) { - e.stopPropagation(); - canvas.setCurrentElement(canvas.getDocumentElement(e.currentTarget), {caretTo: false}); - }); + this.setupEventHandling(); - var observer = new MutationObserver(function(mutations) { - mutations.forEach(function(mutation) { - if(documentElement.DocumentTextElement.isContentContainer(mutation.target)) { - observer.disconnect(); - if(mutation.target.data === '') - mutation.target.data = utils.unicode.ZWS; - else if(mutation.oldValue === utils.unicode.ZWS) { - mutation.target.data = mutation.target.data.replace(utils.unicode.ZWS, ''); - canvas._moveCaretToTextElement(canvas.getDocumentElement(mutation.target), 'end'); - } - observer.observe(canvas.d[0], config); - canvas.publisher('contentChanged'); - } - }); - }); - var config = { attributes: false, childList: false, characterData: true, subtree: true, characterDataOldValue: true}; - observer.observe(this.d[0], config); + } else { + this.d = null; + } + }, + setupEventHandling: function() { + var canvas = this; + this.wrapper.on('keyup keydown keypress', function(e) { + keyboard.handleKey(e, this); + }.bind(this)); - this.wrapper.on('mouseover', '[document-node-element], [document-text-element]', function(e) { - var el = canvas.getDocumentElement(e.currentTarget); - if(!el) - return; - e.stopPropagation(); - if(el instanceof documentElement.DocumentTextElement) - el = el.parent(); - el.toggleLabel(true); - }); - this.wrapper.on('mouseout', '[document-node-element], [document-text-element]', function(e) { - var el = canvas.getDocumentElement(e.currentTarget); - if(!el) - return; - e.stopPropagation(); - if(el instanceof documentElement.DocumentTextElement) - el = el.parent(); - el.toggleLabel(false); - }); + this.wrapper.on('click', '[document-node-element], [document-text-element]', function(e) { + e.stopPropagation(); + canvas.setCurrentElement(canvas.getDocumentElement(e.currentTarget), {caretTo: false}); + }); - this.eventBus.on('elementToggled', function(toggle, element) { - if(!toggle) { - canvas.setCurrentElement(element.getPreviousTextElement()); + var observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if(documentElement.DocumentTextElement.isContentContainer(mutation.target)) { + observer.disconnect(); + if(mutation.target.data === '') + mutation.target.data = utils.unicode.ZWS; + else if(mutation.oldValue === utils.unicode.ZWS) { + mutation.target.data = mutation.target.data.replace(utils.unicode.ZWS, ''); + canvas._moveCaretToTextElement(canvas.getDocumentElement(mutation.target), 'end'); + } + observer.observe(canvas.d[0], config); + canvas.publisher('contentChanged'); } - }) + }); + }); + var config = { attributes: false, childList: false, characterData: true, subtree: true, characterDataOldValue: true}; + observer.observe(this.d[0], config); + + + this.wrapper.on('mouseover', '[document-node-element], [document-text-element]', function(e) { + var el = canvas.getDocumentElement(e.currentTarget); + if(!el) + return; + e.stopPropagation(); + if(el instanceof documentElement.DocumentTextElement) + el = el.parent(); + el.toggleLabel(true); + }); + this.wrapper.on('mouseout', '[document-node-element], [document-text-element]', function(e) { + var el = canvas.getDocumentElement(e.currentTarget); + if(!el) + return; + e.stopPropagation(); + if(el instanceof documentElement.DocumentTextElement) + el = el.parent(); + el.toggleLabel(false); + }); - } else { - this.d = null; - } + this.eventBus.on('elementToggled', function(toggle, element) { + if(!toggle) { + canvas.setCurrentElement(element.getPreviousTextElement()); + } + }); }, view: function() { @@ -651,6 +688,9 @@ $.extend(Cursor.prototype, { return { fromXML: function(xml, publisher) { return new Canvas(xml, publisher); + }, + fromXML2: function(wlxmlNode, publisher) { + return new Canvas(wlxmlNode, publisher, 2); } }; diff --git a/src/editor/modules/documentCanvas/canvas/canvas2.test.js b/src/editor/modules/documentCanvas/canvas/canvas2.test.js new file mode 100644 index 0000000..279e1e0 --- /dev/null +++ b/src/editor/modules/documentCanvas/canvas/canvas2.test.js @@ -0,0 +1,29 @@ +define([ +'libs/chai', +'modules/documentCanvas/canvas/canvas', +'modules/documentCanvas/canvas/documentElement', +'modules/documentCanvas/canvas/utils', +'wlxml/wlxml' +], function(chai, canvas, documentElement, utils, wlxml) { + +'use strict'; + +var expect = chai.expect; + + +var nodeFromXML = function(xml) { + return wlxml.WLXMLElementNodeFromXML(xml); +}; + + +describe('new Canvas', function() { + it('abc', function() { + var doc = wlxml.WLXMLDocumentFromXML('
Alice has a cat!'), + c = canvas.fromXML2(doc); + + expect(c.doc().children()).to.have.length(3) + }); +}) + + +}); \ No newline at end of file diff --git a/src/editor/modules/documentCanvas/canvas/documentElement.js b/src/editor/modules/documentCanvas/canvas/documentElement.js index 0627bc1..ee340f1 100644 --- a/src/editor/modules/documentCanvas/canvas/documentElement.js +++ b/src/editor/modules/documentCanvas/canvas/documentElement.js @@ -23,13 +23,21 @@ var elementTypeFromParams = function(params) { }; +var elementTypeFromNode = function(wlxmlNode) { + return wlxmlNode.nodeType === Node.TEXT_NODE ? DocumentTextElement : DocumentNodeElement; +} + $.extend(DocumentElement, { create: function(params, canvas) { return elementTypeFromParams(params).create(params); }, - createDOM: function(params) { - return elementTypeFromParams(params).createDOM(params); + create2: function(node, canvas) { + return elementTypeFromNode(node).create2(node, canvas); + }, + + createDOM: function(wlxmlNode) { + return elementTypeFromParams(wlxmlNode).createDOM(params); }, fromHTMLElement: function(htmlElement, canvas) { @@ -176,6 +184,59 @@ $.extend(DocumentNodeElement, { fromHTMLElement: function(htmlElement, canvas) { return new this(htmlElement, canvas); + }, + + createDOM2: function(wlxmlNode, canvas) { + + // tag: wlxmlNode.getTagName(), + // klass: wlxmlNode.getClass(), //currentTag.attr('class'), + // meta: wlxmlNode.getMetaAttributes(), //meta, + // others: wlxmlNode.getOtherAttributes(), // ~ //others, + // rawChildren: wlxmlNode.contents(), + // prepopulateOnEmpty: true + + var dom = $('
') + .attr('document-node-element', ''), + widgetsContainer = $('
') + .addClass('canvas-widgets') + .attr('contenteditable', false), + container = $('
') + .attr('document-element-content', ''); + + dom.append(widgetsContainer, container); + // Make sure widgets aren't navigable with arrow keys + widgetsContainer.find('*').add(widgetsContainer).attr('tabindex', -1); + + var element = this.fromHTMLElement(dom[0], canvas); + + element.setWlxml({tag: wlxmlNode.getTagName(), klass: wlxmlNode.getClass()}); + + _.keys(wlxmlNode.getMetaAttributes()).forEach(function(key) { + element.setWlxmlMetaAttr(key, params.meta[key]); + }); + + //element.data('other-attrs', params.others); + + // element.contents + + wlxmlNode.contents().forEach((function(node) { + container.append(DocumentElement.create2(node).dom()); + }).bind(this)); + + // if(params.rawChildren && params.rawChildren.length) { + // container.append(params.rawChildren); + // } else if(params.prepopulateOnEmpty) { + // element.append(DocumentTextElement.create({text: ''})); + // } + return dom; + }, + + create2: function(params, canvas) { + return this.fromHTMLElement2(this.createDOM2(params, canvas)[0], canvas); + }, + + fromHTMLElement2: function(htmlElement, canvas) { + return new this(htmlElement, canvas); } }); @@ -484,10 +545,20 @@ $.extend(DocumentTextElement, { .text(params.text || utils.unicode.ZWS); }, + createDOM2: function(wlxmlTextNode) { + return $('
') + .attr('document-text-element', '') + .text(wlxmlTextNode.getText() || utils.unicode.ZWS); + }, + create: function(params, canvas) { return this.fromHTMLElement(this.createDOM(params)[0]); }, + create2: function(wlxmlTextNode, canvas) { + return this.fromHTMLElement(this.createDOM2(wlxmlTextNode)[0]); + }, + fromHTMLElement: function(htmlElement, canvas) { return new this(htmlElement, canvas); }, diff --git a/src/editor/modules/documentCanvas/documentCanvas.js b/src/editor/modules/documentCanvas/documentCanvas.js index 3ebab2e..4104784 100644 --- a/src/editor/modules/documentCanvas/documentCanvas.js +++ b/src/editor/modules/documentCanvas/documentCanvas.js @@ -42,6 +42,11 @@ return function(sandbox) { canvasWrapper.find('#rng-module-documentCanvas-content').empty().append(canvas.view()); sandbox.publish('documentSet'); }, + setDocument2: function(wlxmlDocument) { + canvas.loadWlxmlDocument(wlxmlDocument); + canvasWrapper.find('#rng-module-documentCanvas-content').empty().append(canvas.view()); + sandbox.publish('documentSet'); + }, getDocument: function() { return canvas.toXML(); }, diff --git a/src/editor/modules/rng/rng.js b/src/editor/modules/rng/rng.js index 59652a7..6b10293 100644 --- a/src/editor/modules/rng/rng.js +++ b/src/editor/modules/rng/rng.js @@ -190,7 +190,7 @@ return function(sandbox) { eventHandlers.documentCanvas = { ready: function() { - sandbox.getModule('documentCanvas').setDocument(sandbox.getModule('data').getDocument()); + sandbox.getModule('documentCanvas').setDocument2(sandbox.getModule('data').getDocument2()); views.visualEditing.setView('leftColumn', sandbox.getModule('documentCanvas').getView()); }, documentSet: function() { diff --git a/tests/main.js b/tests/main.js index a05c379..c3da0df 100644 --- a/tests/main.js +++ b/tests/main.js @@ -14,7 +14,8 @@ paths: { 'fnpjs': '../fnpjs', 'libs': '../../libs', - 'smartxml': '../smartxml' + 'smartxml': '../smartxml', + 'wlxml': '../wlxml' }, map: {