X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/7775c06d48eb6f310a8ba03d476fd9fcd36b3bc8..ab1445aee3c066a08d0602dd8b2e6996646d986f:/src/editor/plugins/core/core.test.js
diff --git a/src/editor/plugins/core/core.test.js b/src/editor/plugins/core/core.test.js
index 99f49f4..27a7254 100644
--- a/src/editor/plugins/core/core.test.js
+++ b/src/editor/plugins/core/core.test.js
@@ -1,9 +1,11 @@
define(function(require) {
'use strict';
-/* globals describe, it */
-var _ = require('libs/underscore'),
+/* globals describe, it, afterEach */
+
+var $ = require('libs/jquery'),
+ _ = require('libs/underscore'),
chai = require('libs/chai'),
sinon = require('libs/sinon'),
wlxml = require('wlxml/wlxml'),
@@ -23,7 +25,15 @@ var getDocumentFromXML = function(xml, options) {
var getCanvasFromXML = function(xml, elements) {
- return canvas.fromXMLDocument(getDocumentFromXML(xml), elements);
+ var c = canvas.fromXMLDocument(getDocumentFromXML(xml), elements),
+ view = c.view();
+ view.attr('canvas-test', true);
+ /* globals document */
+ $(document.body).append(view);
+ return c;
+};
+var removeCanvas = function() {
+ $('[canvas-test]').remove();
};
var getTextNodes = function(text, doc) {
@@ -153,7 +163,7 @@ describe('Document extensions', function() {
});
});
-describe.only('Keyboard interactions', function() {
+describe('Keyboard interactions', function() {
var Keyboard = function(canvas) {
this.canvas = canvas;
@@ -199,6 +209,8 @@ describe.only('Keyboard interactions', function() {
});
describe('deleting text with selection', function() {
+ afterEach(removeCanvas);
+
[K.BACKSPACE, K.DELETE].forEach(function(key) {
it('deletes text withing a single text element ' + key, function() {
var c = getCanvasFromXML(''),
@@ -206,6 +218,12 @@ describe.only('Keyboard interactions', function() {
k.withSelection('A|lice', 'Alic|e').press(key);
expect(c.wlxmlDocument.root.contents()[0].contents()[0].getText()).to.equal('Ae');
+
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.getText()).to.equal('Ae');
+ expect(selection.offset).to.equal(1);
});
it('deletes text across two paragraphs ' + key, function() {
var c = getCanvasFromXML(''),
@@ -217,6 +235,10 @@ describe.only('Keyboard interactions', function() {
expect(rootContents.length).to.equal(2);
expect(rootContents[0].contents()[0].getText()).to.equal('A');
expect(rootContents[1].contents()[0].getText()).to.equal('at');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.wlxmlNode.getText()).to.equal(key === K.BACKSPACE ? 'A' : 'at');
});
it('keeps an empty paragraph after deleting its whole text ' + key, function() {
@@ -228,31 +250,19 @@ describe.only('Keyboard interactions', function() {
expect(rootContents.length).to.equal(1);
expect(rootContents[0].contents()[0].getText()).to.equal('');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.wlxmlNode.parent().sameNode(c.wlxmlDocument.root.contents()[0]));
});
});
});
- // describe('deleting with a caret', function() {
- // it('keeps an empty paragraph after deleteing last letter with backspace', function() {
- // var c = getCanvasFromXML(''),
- // k = new Keyboard(c);
- // k.withCaret('A|').press(K.BACKSPACE);
- // var rootContents = c.wlxmlDocument.root.contents();
+ describe('backspace at the beginning of a block', function() {
+ afterEach(removeCanvas);
- // expect(rootContents.length).to.equal(1);
- // expect(rootContents[0].contents()[0].getText()).to.equal('');
- // });
- // // it('removes a paragraph on yet another delete' + key, function() {
-
- // // });
- // });
-
-
- // + empty when bck/ins + l===1
-
- describe('backspace at the beginning', function() {
it('merges two adjacent paragraphs', function() {
var c = getCanvasFromXML(''),
k = new Keyboard(c);
@@ -263,6 +273,11 @@ describe.only('Keyboard interactions', function() {
expect(rootContents.length).to.equal(1);
expect(rootContents[0].getClass()).to.equal('p');
expect(rootContents[0].contents()[0].getText()).to.equal('AB');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('AB', c))).to.equal(true);
+ expect(selection.offset).to.equal(1);
});
it('merges a paragraph with a header', function() {
var c = getCanvasFromXML(''),
@@ -274,6 +289,11 @@ describe.only('Keyboard interactions', function() {
expect(rootContents.length).to.equal(1);
expect(rootContents[0].getTagName()).to.equal('header');
expect(rootContents[0].contents()[0].getText()).to.equal('AB');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('AB', c))).to.equal(true);
+ expect(selection.offset).to.equal(1);
});
it('merges two adjacent headers', function() {
var c = getCanvasFromXML(''),
@@ -284,6 +304,11 @@ describe.only('Keyboard interactions', function() {
expect(rootContents.length).to.equal(1);
expect(rootContents[0].getTagName()).to.equal('header');
expect(rootContents[0].contents()[0].getText()).to.equal('AB');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('AB', c))).to.equal(true);
+ expect(selection.offset).to.equal(1);
});
it('merges a header with a paragraph', function() {
var c = getCanvasFromXML(''),
@@ -295,6 +320,11 @@ describe.only('Keyboard interactions', function() {
expect(rootContents.length).to.equal(1);
expect(rootContents[0].is('p')).to.equal(true);
expect(rootContents[0].contents()[0].getText()).to.equal('AB');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('AB', c))).to.equal(true);
+ expect(selection.offset).to.equal(1);
});
it('merges a paragraph into a last list item', function() {
var c = getCanvasFromXML(''),
@@ -310,6 +340,11 @@ describe.only('Keyboard interactions', function() {
var items = list.contents();
expect(items.length).to.equal(1);
expect(items[0].contents()[0].getText()).to.equal('itemparagraph');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('itemparagraph', c))).to.equal(true);
+ expect(selection.offset).to.equal(4);
});
it('merges a list item with a list item', function() {
var c = getCanvasFromXML(''),
@@ -327,6 +362,11 @@ describe.only('Keyboard interactions', function() {
expect(items.length).to.equal(1);
expect(items[0].contents()[0].getText()).to.equal('item1item2');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('item1item2', c))).to.equal(true);
+ expect(selection.offset).to.equal(5);
});
it('creates a new paragraph preceding the list from a first list item', function() {
var c = getCanvasFromXML(''),
@@ -342,6 +382,11 @@ describe.only('Keyboard interactions', function() {
expect(rootContents[0].contents()[0].getText()).to.equal('item1');
expect(rootContents[1].sameNode(list)).to.equal(true);
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('item1', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
});
it('removes list after moving up its only item', function() {
var c = getCanvasFromXML(''),
@@ -353,9 +398,377 @@ describe.only('Keyboard interactions', function() {
expect(rootContents[0].getClass()).to.equal('p');
expect(rootContents[0].contents()[0].getText()).to.equal('item');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('item', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+ });
+
+ describe('backspace at the beginning of a span', function() {
+ afterEach(removeCanvas);
+
+ it('deletes span if it contains only one character', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('h|').press(K.BACKSPACE);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(1);
+ expect(rootContents[0].getText()).to.equal('Alicea cat');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('Alicea cat', c))).to.equal(true);
+ expect(selection.offset).to.equal(5);
+ });
+
+ it('deletes from the end of the preceding text element', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('|has a cat').press(K.BACKSPACE);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(2);
+ expect(rootContents[0].getText()).to.equal('Alic');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('has a cat', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+
+ it('deletes from the end of the preceding text element - multiple spans', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('|has a cat').press(K.BACKSPACE);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(2);
+ expect(rootContents[0].getText()).to.equal('Alic');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('has a cat', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+
+ it('deletes from the end of the preceding span element content', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('|has a cat').press(K.BACKSPACE);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(2);
+ expect(rootContents[0].is({tagName: 'span'})).to.equal(true);
+ expect(rootContents[0].contents()[0].getText()).to.equal('Alic');
+
+ expect(rootContents[1].contents()[0].getText()).to.equal('has a cat');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('has a cat', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+
+ it('deletes from the end of the preceding span element content - multiple spans', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('|has a cat').press(K.BACKSPACE);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(2);
+ expect(rootContents[0].is({tagName: 'span'})).to.equal(true);
+ expect(rootContents[0].contents()[0].getText()).to.equal('Alic');
+
+ var outerSpan = rootContents[1];
+ expect(outerSpan.is({tagName: 'span'})).to.equal(true);
+
+ var innerSpan = outerSpan.contents()[0];
+ expect(innerSpan.contents()[0].getText()).to.equal('has a cat');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('has a cat', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+
+ it('merges two paragrahps if span is a first content of the second paragraph', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('|Alice').press(K.BACKSPACE);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+
+ expect(rootContents.length).to.equal(1, 'single paragraph left');
+
+ var p = rootContents[0],
+ pContents = p.contents();
+
+ expect(p.is('p')).to.equal(true);
+
+ expect(pContents.length).to.equal(3);
+ expect(pContents[0].getText()).to.equal('para');
+ expect(pContents[1].contents().length).to.equal(1);
+ expect(pContents[1].contents()[0].getText()).to.equal('Alice');
+
+ expect(pContents[2].getText()).to.equal(' has a cat');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('Alice', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+ });
+
+ describe('backspace before a span', function() {
+ it('deletes from the end of a span', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('|has a cat').press(K.BACKSPACE);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(2);
+ expect(rootContents[0].is({tagName: 'span'})).to.equal(true);
+ expect(rootContents[0].contents()[0].getText()).to.equal('Alic');
+ expect(rootContents[1].getText()).to.equal('has a cat');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('has a cat', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+ it('deletes span if it contains only one character (1)', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('| a cat').press(K.BACKSPACE);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(1);
+ expect(rootContents[0].getText()).to.equal('Alice a cat');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('Alice a cat', c))).to.equal(true);
+ expect(selection.offset).to.equal(6);
+ });
+ it('deletes span if it contains only one character (2)', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('|b').press(K.BACKSPACE);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(1);
+ expect(rootContents[0].contents()[0].getText()).to.equal('b');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('b', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
});
});
+ describe('splitting with enter', function() {
+ afterEach(removeCanvas);
+
+ it('splits paragraph into two in the middle', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('para|graph').press(K.ENTER);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(2);
+ expect(rootContents[0].is({tagName: 'div', klass: 'p'})).to.equal(true);
+ expect(rootContents[0].contents()[0].getText()).to.equal('para');
+ expect(rootContents[1].is({tagName: 'div', klass: 'p'})).to.equal(true);
+ expect(rootContents[1].contents()[0].getText()).to.equal('graph');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('graph', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+ it('splits paragraph into two at the beginning', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('|paragraph').press(K.ENTER);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(2);
+ expect(rootContents[0].is({tagName: 'div', klass: 'p'})).to.equal(true);
+ expect(rootContents[0].contents()[0].getText()).to.equal('');
+ expect(rootContents[1].is({tagName: 'div', klass: 'p'})).to.equal(true);
+ expect(rootContents[1].contents()[0].getText()).to.equal('paragraph');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+ it('splits paragraph into two at the end', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('paragraph|').press(K.ENTER);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(2);
+ expect(rootContents[0].is({tagName: 'div', klass: 'p'})).to.equal(true);
+ expect(rootContents[0].contents()[0].getText()).to.equal('paragraph');
+ expect(rootContents[1].is({tagName: 'div', klass: 'p'})).to.equal(true);
+ expect(rootContents[1].contents()[0].getText()).to.equal('');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+
+ it('does nothing on an empty paragraph', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c),
+ spy = sinon.spy();
+
+ k.withCaret('a|').press(K.BACKSPACE);
+ c.wlxmlDocument.on('change', spy);
+ k.press(K.ENTER);
+ expect(spy.callCount).to.equal(0);
+ });
+
+ it('splits its parent box if inside a span', function() {
+ var c = getCanvasFromXML(''),
+ 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(''),
+ 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);
+ });
+ });
+
+ describe('Enter on a list items', function() {
+ afterEach(removeCanvas);
+
+ it('creates a paragraph after a list if hitting enter on the last and empty list item', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('item|').press(K.ENTER).press(K.ENTER);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(2);
+ expect(rootContents[0].is('list')).to.equal(true);
+ expect(rootContents[1].is('p')).to.equal(true);
+
+ var list = rootContents[0];
+ expect(list.contents().length).to.equal(1);
+
+ var selection = c.getSelection();
+ expect(selection.element.wlxmlNode.sameNode(rootContents[1].contents()[0])).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+ });
+
+ describe('Deleting text from a node', function() {
+ it('deletes last character with backspace', function() {
+ var c = getCanvasFromXML(''),
+ k = new Keyboard(c);
+
+ k.withCaret('b|').press(K.BACKSPACE);
+
+ var rootContents = c.wlxmlDocument.root.contents();
+ expect(rootContents.length).to.equal(2);
+ expect(rootContents[0].is({tagName: 'div', klass: 'p'})).to.equal(true);
+ expect(rootContents[0].contents()[0].getText()).to.equal('a');
+ expect(rootContents[1].is({tagName: 'div', klass: 'p'})).to.equal(true);
+ expect(rootContents[1].contents()[0].getText()).to.equal('');
+
+ var selection = c.getSelection();
+ expect(selection.type).to.equal('caret');
+ expect(selection.element.sameNode(getTextElement('', c))).to.equal(true);
+ expect(selection.offset).to.equal(0);
+ });
+ });
});