From ec10eee3168f37beedfb5dea757a4bdec2f2f36e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksander=20=C5=81ukasz?= Date: Fri, 1 Aug 2014 14:33:36 +0200 Subject: [PATCH 1/1] splitting blocks from spans --- src/editor/plugins/core/core.js | 48 +++++++++++++++-- src/editor/plugins/core/core.test.js | 78 ++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 3 deletions(-) diff --git a/src/editor/plugins/core/core.js b/src/editor/plugins/core/core.js index 0ac9cff..425b161 100644 --- a/src/editor/plugins/core/core.js +++ b/src/editor/plugins/core/core.js @@ -19,6 +19,7 @@ plugin.documentExtension.textNode.transformations = { breakContent: { impl: function(args) { var node = this, + isSpan = node.parent().getTagName() === 'span', parentDescribingNodes = [], newNodes, emptyText; newNodes = node.split({offset: args.offset}); @@ -40,10 +41,51 @@ plugin.documentExtension.textNode.transformations = { parentDescribingNodes.forEach(function(node) { newNodes.first.append(node); }); + + var parent, newNode; + + var copyNode = function(n) { + var attrs = {}; + n.getAttrs().forEach(function(attr) { + attrs[attr.name] = attr.value; + }); + + return node.document.createDocumentNode({ + tagName: n.getTagName(), + attrs: attrs + }); + }; + + var move = function(node, to) { + var copy; + if(!node.containsNode(newNodes.second)) { + to.append(node); + return false; + } else { + if(!node.sameNode(newNodes.second)) { + copy = to.append(copyNode(node)); + node.contents().some(function(n) { + return move(n, copy); + }); + } + return true; + } + }; + + if(isSpan) { + newNodes.first.parents().some(function(p) { + if(p.getTagName() !== 'span') { + parent = p; + return true; + } + }); + newNode = parent.before({tagName: parent.getTagName(), attrs: {'class': parent.getClass()}}); + parent.contents().some(function(n) { + return move(n, newNode); + }); + } + return _.extend(newNodes, {emptyText: emptyText}); - }, - getChangeRoot: function() { - return this.context.parent().parent(); } }, mergeContentUp: function() { diff --git a/src/editor/plugins/core/core.test.js b/src/editor/plugins/core/core.test.js index 6a1bd32..62d734d 100644 --- a/src/editor/plugins/core/core.test.js +++ b/src/editor/plugins/core/core.test.js @@ -463,6 +463,84 @@ describe('Keyboard interactions', function() { expect(selection.element.sameNode(getTextElement('', c))).to.equal(true); expect(selection.offset).to.equal(0); }); + + it('splits its parent box if inside a span', function() { + var c = getCanvasFromXML('
this is a paragraph
'), + k = new Keyboard(c); + + k.withCaret('i|s').press(K.ENTER); + + var rootContents = c.wlxmlDocument.root.contents(); + + expect(rootContents.length).to.equal(2); + + var p1 = rootContents[0], + p2 = rootContents[1]; + + expect(p1.is({tagName: 'div', klass: 'p'})).to.equal(true); + expect(p2.is({tagName: 'div', klass: 'p'})).to.equal(true); + + var p1Contents = p1.contents(), + p2Contents = p2.contents(); + + expect(p1Contents[0].getText()).to.equal('this '); + expect(p1Contents[1].is({tagName: 'span'})).to.equal(true); + expect(p1Contents[1].contents()[0].getText()).to.equal('i'); + + + expect(p2Contents[0].is({tagName: 'span'})).to.equal(true); + expect(p2Contents[0].contents()[0].getText()).to.equal('s'); + expect(p2Contents[1].getText()).to.equal(' a paragraph'); + + var selection = c.getSelection(); + expect(selection.element.sameNode(getTextElement('s', c))).to.equal(true); + expect(selection.offset).to.equal(0); + }); + + it('splits its parent box if inside a double span', function() { + var c = getCanvasFromXML('
this is a paragraph
'), + k = new Keyboard(c); + + k.withCaret('i|s').press(K.ENTER); + + var rootContents = c.wlxmlDocument.root.contents(); + + expect(rootContents.length).to.equal(2); + + var p1 = rootContents[0], + p2 = rootContents[1]; + + expect(p1.is({tagName: 'div', klass: 'p'})).to.equal(true); + expect(p2.is({tagName: 'div', klass: 'p'})).to.equal(true); + + var p1Contents = p1.contents(), + p2Contents = p2.contents(); + + /* first paragraph */ + expect(p1Contents[0].getText()).to.equal('this '); + + var outer1 = p1Contents[1]; + expect(outer1.getAttr('test')).to.equal('outer'); + expect(outer1.contents().length).to.equal(1); + var inner1 = outer1.contents()[0]; + expect(inner1.getAttr('test')).to.equal('inner'); + expect(inner1.contents()[0].getText()).to.equal('i'); + + /* second paragraph */ + var outer2 = p2Contents[0]; + expect(outer2.getAttr('test')).to.equal('outer'); + expect(outer2.contents().length).to.equal(1); + var inner2 = outer2.contents()[0]; + expect(inner2.getAttr('test')).to.equal('inner'); + expect(inner2.contents()[0].getText()).to.equal('s'); + + expect(p2Contents[1].getText()).to.equal(' a paragraph'); + + /* caret */ + var selection = c.getSelection(); + expect(selection.element.sameNode(getTextElement('s', c))).to.equal(true); + expect(selection.offset).to.equal(0); + }); }); -- 2.20.1