/*global expect, describe, afterEach, beforeEach, it */ expect = expect.clone() .addType({ name: 'SquireRTE', base: 'object', identify: function (value) { return value instanceof Squire; }, inspect: function (value) { return 'Squire RTE: ' + value.getHTML(); } }) .addAssertion('[not] to contain HTML', function (expect, editor, expectedValue) { this.errorMode = 'bubble'; var actualHTML = editor.getHTML().replace(/
/g, ''); // BR tags are inconsistent across browsers. Removing them allows cross-browser testing. expect(actualHTML, '[not] to be', expectedValue); }); describe('Squire RTE', function () { var doc, editor; beforeEach(function () { var iframe = document.getElementById('testFrame'); doc = iframe.contentDocument; editor = new Squire(doc); }); function selectAll(editor) { doc.getSelection().removeAllRanges() var range = doc.createRange(); range.setStart(doc.body.childNodes.item(0), 0); range.setEnd(doc.body.childNodes.item(0), doc.body.childNodes.item(0).childNodes.length); editor.setSelection(range); } describe('hasFormat', function () { var startHTML; beforeEach( function () { startHTML = '
one two three four five
'; editor.setHTML(startHTML); }); it('returns false when range not touching format', function () { var range = doc.createRange(); range.setStart(doc.body.childNodes.item(0), 0); range.setEnd(doc.body.childNodes.item(0), 1); editor.setSelection(range); expect(editor.hasFormat('b'), 'to be false'); }); it('returns false when range inside other format', function () { var range = doc.createRange(); range.setStart(doc.querySelector('i').childNodes[0], 1); range.setEnd(doc.querySelector('i').childNodes[0], 2); editor.setSelection(range); expect(editor.hasFormat('b'), 'to be false'); }); it('returns false when range covers anything outside format', function () { var range = doc.createRange(); range.setStart(doc.querySelector('b').previousSibling, 2); range.setEnd(doc.querySelector('b').childNodes[0], 8); editor.setSelection(range); expect(editor.hasFormat('b'), 'to be false'); }); it('returns true when range inside format', function () { var range = doc.createRange(); range.setStart(doc.querySelector('b').childNodes[0], 2); range.setEnd(doc.querySelector('b').childNodes[0], 8); editor.setSelection(range); expect(editor.hasFormat('b'), 'to be true'); }); it('returns true when range covers start of format', function () { var range = doc.createRange(); range.setStartBefore(doc.querySelector('b')); range.setEnd(doc.querySelector('b').childNodes[0], 8); editor.setSelection(range); expect(editor.hasFormat('b'), 'to be true'); }); it('returns true when range covers start of format, even in weird cases', function () { var range = doc.createRange(); var prev = doc.querySelector('b').previousSibling; range.setStart(prev, prev.length); range.setEnd(doc.querySelector('b').childNodes[0], 8); editor.setSelection(range); expect(editor.hasFormat('b'), 'to be true'); }); it('returns true when range covers end of format', function () { var range = doc.createRange(); range.setStart(doc.querySelector('b').childNodes[0], 2); range.setEndAfter(doc.querySelector('b')); editor.setSelection(range); expect(editor.hasFormat('b'), 'to be true'); }); it('returns true when range covers end of format, even in weird cases', function () { var range = doc.createRange(); range.setStart(doc.querySelector('b').childNodes[0], 2); var next = doc.querySelector('b').nextSibling; range.setEnd(next, 0); editor.setSelection(range); expect(editor.hasFormat('b'), 'to be true'); }); it('returns true when range covers all of format', function () { var range = doc.createRange(); range.setStartBefore(doc.querySelector('b')); range.setEndAfter(doc.querySelector('b')); editor.setSelection(range); expect(editor.hasFormat('b'), 'to be true'); }); }); describe('removeAllFormatting', function () { // Trivial cases it('removes inline styles', function () { var startHTML = '
one two three four five
'; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); selectAll(editor); editor.removeAllFormatting(); expect(editor, 'to contain HTML', '
one two three four five
'); }); it('removes block styles', function () { var startHTML = '
one
' + '
  1. three
fourfive
'; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); selectAll(editor); editor.removeAllFormatting(); var expectedHTML = '
one
two
three
four
five
'; expect(editor, 'to contain HTML', expectedHTML); }); // Potential bugs it('removes styles that begin inside the range', function () { var startHTML = '
one two three four five
'; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); var range = doc.createRange(); range.setStart(doc.body.childNodes.item(0), 0); range.setEnd(doc.getElementsByTagName('i').item(0).childNodes.item(0), 4); editor.removeAllFormatting(range); expect(editor, 'to contain HTML', '
one two three four five
'); }); it('removes styles that end inside the range', function () { var startHTML = '
one two three four five
'; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); var range = doc.createRange(); range.setStart(doc.getElementsByTagName('i').item(0).childNodes.item(0), 13); range.setEnd(doc.body.childNodes.item(0), doc.body.childNodes.item(0).childNodes.length); editor.removeAllFormatting(range); expect(editor, 'to contain HTML', '
one two three four five
'); }); it('removes styles enclosed by the range', function () { var startHTML = '
one two three four five
'; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); var range = doc.createRange(); range.setStart(doc.body.childNodes.item(0), 0); range.setEnd(doc.body.childNodes.item(0), doc.body.childNodes.item(0).childNodes.length); editor.removeAllFormatting(range); expect(editor, 'to contain HTML', '
one two three four five
'); }); it('removes styles enclosing the range', function () { var startHTML = '
one two three four five
'; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); var range = doc.createRange(); range.setStart(doc.getElementsByTagName('i').item(0).childNodes.item(0), 4); range.setEnd(doc.getElementsByTagName('i').item(0).childNodes.item(0), 18); editor.removeAllFormatting(range); expect(editor, 'to contain HTML', '
one two three four five
'); }); it('removes nested styles and closes tags correctly', function () { var startHTML = '
one
twothree
fourfive
'; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); var range = doc.createRange(); range.setStart(doc.getElementsByTagName('td').item(1), 0); range.setEnd(doc.getElementsByTagName('td').item(2), doc.getElementsByTagName('td').item(2).childNodes.length); editor.removeAllFormatting(range); expect(editor, 'to contain HTML', '
one
' + '
two
' + '
three
' + '
fourfive
'); }); }); describe('getPath', function () { var startHTML; beforeEach( function () { startHTML = '
one two three four five
'; editor.setHTML(startHTML); var range = doc.createRange(); range.setStart(doc.body.childNodes.item(0), 0); range.setEnd(doc.body.childNodes.item(0), 1); editor.setSelection(range); }); it('returns the path to the selection', function () { var range = doc.createRange(); range.setStart(doc.body.childNodes.item(0).childNodes.item(1), 0); range.setEnd(doc.body.childNodes.item(0).childNodes.item(1), 0); editor.setSelection(range); //Manually tell it to update the path editor._updatePath(range); expect(editor.getPath(), 'to be', 'DIV>B'); }); it('includes id in the path', function () { editor.insertHTML('
Text
'); expect(editor.getPath(), 'to be', 'DIV#spanId'); }); it('includes class name in the path', function () { editor.insertHTML('
Text
'); expect(editor.getPath(), 'to be', 'DIV.myClass'); }); it('includes all class names in the path', function () { editor.insertHTML('
Text
'); expect(editor.getPath(), 'to be', 'DIV.myClass.myClass2.myClass3'); }); it('includes direction in the path', function () { editor.insertHTML('
Text
'); expect(editor.getPath(), 'to be', 'DIV[dir=rtl]'); }); it('includes highlight value in the path', function () { editor.insertHTML('
Text
'); expect(editor.getPath(), 'to be', 'DIV.highlight[backgroundColor=rgb(255,0,0)]'); }); it('includes color value in the path', function () { editor.insertHTML('
Text
'); expect(editor.getPath(), 'to be', 'DIV.colour[color=rgb(255,0,0)]'); }); it('includes font family value in the path', function () { editor.insertHTML('
Text
'); expect(editor.getPath(), 'to be', 'DIV.font[fontFamily=Arial,sans-serif]'); }); it('includes font size value in the path', function () { editor.insertHTML('
Text
'); expect(editor.getPath(), 'to be', 'DIV.size[fontSize=12pt]'); }); it('is (selection) when the selection is a range', function() { var range = doc.createRange(); range.setStart(doc.body.childNodes.item(0).childNodes.item(0), 0); range.setEnd(doc.body.childNodes.item(0).childNodes.item(3), 0); editor.setSelection(range); //Manually tell it to update the path editor._updatePath(range); expect(editor.getPath(), 'to be', '(selection)'); }); }); describe('multi-level lists', function () { it('increases list indentation', function() { var startHTML = ''; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); var range = doc.createRange(); var textNode = doc.getElementsByTagName('li').item(1).childNodes[0].childNodes[0] range.setStart(textNode, 0); range.setEnd(textNode, 0); editor.setSelection(range); editor.increaseListLevel() expect(editor, 'to contain HTML', ''); }); it('increases list indentation 2', function() { var startHTML = ''; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); var range = doc.createRange(); var textNode = doc.getElementsByTagName('li').item(1).childNodes[0].childNodes[0] range.setStart(textNode, 0); range.setEnd(textNode, 0); editor.setSelection(range); editor.increaseListLevel() editor.increaseListLevel() expect(editor, 'to contain HTML', ''); }); it('decreases list indentation', function() { var startHTML = ''; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); var range = doc.createRange(); var textNode = doc.getElementsByTagName('li').item(1).childNodes[0].childNodes[0] range.setStart(textNode, 0); range.setEnd(textNode, 0); editor.setSelection(range); editor.decreaseListLevel() expect(editor, 'to contain HTML', ''); }); it('decreases list indentation 2', function() { var startHTML = ''; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); var range = doc.createRange(); var textNode = doc.getElementsByTagName('li').item(1).childNodes[0].childNodes[0] range.setStart(textNode, 0); range.setEnd(textNode, 0); editor.setSelection(range); editor.decreaseListLevel() editor.decreaseListLevel() expect(editor, 'to contain HTML', ''); }); it('removes lists', function() { var startHTML = ''; editor.setHTML(startHTML); expect(editor, 'to contain HTML', startHTML); var range = doc.createRange(); var textNode = doc.getElementsByTagName('li').item(1).childNodes[0].childNodes[0] range.setStart(textNode, 0); range.setEnd(textNode, 0); editor.setSelection(range); editor.removeList() expect(editor, 'to contain HTML', '
bar
'); }) }); describe('insertHTML', function() { it('fix CF_HTML incomplete table', function() { editor.insertHTML('
text
'); expect(editor.getHTML(), 'to contain', '
text
'); editor.setHTML(''); editor.insertHTML('
text1text2
'); expect(editor.getHTML(), 'to contain', '
text1
text2
'); }); var LINK_MAP = { "dewdw@fre.fr": "mailto:dewdw@fre.fr", "dew@free.fr?dew=dew": "mailto:dew@free.fr?dew=dew", "dew@free.fr?subject=dew": "mailto:dew@free.fr?subject=dew", "test@example.com?subject=foo&body=bar": "mailto:test@example.com?subject=foo&body=bar", "dew@fre.fr dewdwe @dew": "mailto:dew@fre.fr", "http://free.fr": "http://free.fr", "http://google.com": "http://google.com", "https://google.com": "https://google.com", "https://www.google.com": "https://www.google.com", "https://www.google.com/": "https://www.google.com/", "https://google.com/?": "https://google.com/", "https://google.com?": "https://google.com", "https://google.com?a": "https://google.com/?a", "https://google.com?a=": "https://google.com/?a=", "https://google.com?a=b": "https://google.com/?a=b", "https://google.com?a=b?": "https://google.com/?a=b", "https://google.com?a=b&": "https://google.com/?a=b&", "https://google.com?a=b&c": "https://google.com/?a=b&c", "https://google.com?a=b&c=": "https://google.com/?a=b&c=", "https://google.com?a=b&c=d": "https://google.com/?a=b&c=", "https://google.com?a=b&c=d?": "https://google.com/?a=b&c=d", "https://google.com?a=b&c=d&": "https://google.com/?a=b&c=d&", "https://google.com?a=b&c=d&e=": "https://google.com/?a=b&c=d&e=", "https://google.com?a=b&c=d&e=f": "https://google.com/?a=b&c=d&e=f" }; Object.keys(LINK_MAP).forEach((input) => { it('should auto convert links to anchor: ' + input, function() { editor.insertHTML(input); var link = editor.getDocument().querySelector('a'); expect(link.href, 'to contain', LINK_MAP[input]); editor.setHTML(''); }); }); it('should auto convert a part of the link to an anchor', function() { editor.insertHTML(` dew@fre.fr dewdwe @dew `); var link = editor.getDocument().querySelector('a'); expect(link.textContent, 'to be', 'dew@fre.fr'); expect(link.href, 'to be', 'mailto:dew@fre.fr'); editor.setHTML(''); }); it('should not auto convert non links to anchor', function() { editor.insertHTML(` dewdwe @dew deww.de monique.fre google.com `); var link = editor.getDocument().querySelector('a'); expect(link, 'to be', null); editor.setHTML(''); }); }); afterEach(function () { editor = null; var iframe = document.getElementById('testFrame'); iframe.src = 'blank.html'; }); });