restore composer.json, add mysqli extension
This commit is contained in:
76
public/vendor/editor/test/base/Context.spec.js
vendored
Executable file
76
public/vendor/editor/test/base/Context.spec.js
vendored
Executable file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Context.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import chai from 'chai';
|
||||
import spies from 'chai-spies';
|
||||
import $ from 'jquery';// window.jQuery = $;
|
||||
import 'bootstrap';
|
||||
import chaidom from 'test/chaidom';
|
||||
import env from 'src/js/base/core/env';
|
||||
import Context from 'src/js/base/Context';
|
||||
import 'src/js/bs4/settings';
|
||||
|
||||
var expect = chai.expect;
|
||||
chai.use(spies);
|
||||
chai.use(chaidom);
|
||||
|
||||
describe('Context lifecycle', () => {
|
||||
it('should be initialized without calling callback', () => {
|
||||
var spy = chai.spy();
|
||||
var $note = $('<div><p>hello</p></div>');
|
||||
$note.on('summernote.change', spy);
|
||||
|
||||
var context = new Context($note, $.summernote.options);
|
||||
expect(spy).to.have.not.been.called();
|
||||
|
||||
// [workaround]
|
||||
// - IE8-11 can't create range in headless mode
|
||||
if (!env.isMSIE) {
|
||||
context.invoke('insertText', 'hello');
|
||||
expect(spy).to.have.been.called();
|
||||
}
|
||||
});
|
||||
|
||||
it('should preserve user events handler after destroy', () => {
|
||||
var spy = chai.spy();
|
||||
var $note = $('<div><p>hello</p></div>');
|
||||
$note.on('click', spy);
|
||||
|
||||
var context = new Context($note, $.summernote.options);
|
||||
context.destroy();
|
||||
|
||||
$note.trigger('click');
|
||||
expect(spy).to.have.been.called();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Context', () => {
|
||||
var context;
|
||||
beforeEach(() => {
|
||||
context = new Context($('<div><p>hello</p></div>'), $.summernote.options);
|
||||
});
|
||||
|
||||
it('should get or set contents with code', () => {
|
||||
expect(context.code()).to.equalsIgnoreCase('<p>hello</p>');
|
||||
context.code('<p>hello2</p>');
|
||||
expect(context.code()).to.equalsIgnoreCase('<p>hello2</p>');
|
||||
});
|
||||
|
||||
it('should enable or disable editor', () => {
|
||||
expect(context.isDisabled()).to.be.false;
|
||||
context.disable();
|
||||
expect(context.isDisabled()).to.be.true;
|
||||
context.enable();
|
||||
expect(context.isDisabled()).to.be.false;
|
||||
});
|
||||
|
||||
it('should preserve disabled status after reset', () => {
|
||||
expect(context.isDisabled()).to.be.false;
|
||||
context.disable();
|
||||
expect(context.isDisabled()).to.be.true;
|
||||
context.reset();
|
||||
expect(context.isDisabled()).to.be.true;
|
||||
});
|
||||
});
|
||||
343
public/vendor/editor/test/base/core/dom.spec.js
vendored
Executable file
343
public/vendor/editor/test/base/core/dom.spec.js
vendored
Executable file
@@ -0,0 +1,343 @@
|
||||
/**
|
||||
* dom.spec.js
|
||||
* (c) 2013~ Alan Hong
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import chai from 'chai';
|
||||
import chaidom from 'test/chaidom';
|
||||
import $ from 'jquery';
|
||||
import dom from 'src/js/base/core/dom';
|
||||
import func from 'src/js/base/core/func';
|
||||
|
||||
let expect = chai.expect;
|
||||
chai.use(chaidom);
|
||||
|
||||
describe('base:core.dom', () => {
|
||||
describe('ancestor', () => {
|
||||
let $cont, $b, txtB;
|
||||
before(() => {
|
||||
// basic case
|
||||
$cont = $('<div class="note-editable"><b>b</b><u>u</u><s>s</s><i>i</i></div>'); // busi
|
||||
$b = $cont.find('b');
|
||||
txtB = $b[0].firstChild;
|
||||
});
|
||||
|
||||
it('should find ancestor B', () => {
|
||||
expect(dom.ancestor(txtB, dom.isB)).to.deep.equal($b[0]);
|
||||
});
|
||||
|
||||
it('should find ancestor DIV', () => {
|
||||
expect(dom.ancestor(txtB, dom.isDiv)).to.deep.equal($cont[0]);
|
||||
});
|
||||
|
||||
it('should return null when finding ancestor U does not exist', () => {
|
||||
expect(dom.ancestor(txtB, dom.isU)).to.be.null;
|
||||
});
|
||||
|
||||
it('should return null when finding paragraph ancestor outsider note-editable', () => {
|
||||
expect(dom.ancestor(txtB, dom.isLi)).to.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
describe('listAncestor', () => {
|
||||
let $cont, $b, $u, $s, $i;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable"><i><s><u><b>b</b></u></s></i></div>'); // busi
|
||||
$b = $cont.find('b');
|
||||
$u = $cont.find('u');
|
||||
$s = $cont.find('s');
|
||||
$i = $cont.find('i');
|
||||
});
|
||||
|
||||
it('should return [$b, $u, $s, $i] from b to i', () => {
|
||||
let result = dom.listAncestor($b[0], (node) => { return node === $i[0]; });
|
||||
expect(result).to.deep.equal([$b[0], $u[0], $s[0], $i[0]]);
|
||||
});
|
||||
|
||||
it('should return [$u, $s] from u to s', () => {
|
||||
let result = dom.listAncestor($u[0], (node) => { return node === $s[0]; });
|
||||
expect(result).to.deep.equal([$u[0], $s[0]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('listDescendant', () => {
|
||||
let $cont, $b, $u, $s, $i;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable"><b></b><u></u><s></s><i></i></div>'); // busi
|
||||
$b = $cont.find('b');
|
||||
$u = $cont.find('u');
|
||||
$s = $cont.find('s');
|
||||
$i = $cont.find('i');
|
||||
});
|
||||
|
||||
it('should return an array of descendant elements', () => {
|
||||
expect(dom.listDescendant($cont[0])).to.deep.equal([$b[0], $u[0], $s[0], $i[0]]);
|
||||
});
|
||||
|
||||
it('should filter an array of descendant elements', () => {
|
||||
let result = dom.listDescendant($cont[0], (node) => {
|
||||
return node.nodeName === 'B' || node.nodeName === 'S';
|
||||
});
|
||||
expect(result).to.deep.equal([$b[0], $s[0]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('commonAncestor', () => {
|
||||
let $cont, $span, $div, $b, $u, $s;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable"><div><span><b>b</b><u>u</u></span><span><s>s</s><i>i</i></span></div></div>');
|
||||
$span = $cont.find('span');
|
||||
$div = $cont.find('div');
|
||||
$b = $cont.find('b');
|
||||
$u = $cont.find('u');
|
||||
$s = $cont.find('s');
|
||||
});
|
||||
|
||||
it('should return a common element in ancestors', () => {
|
||||
expect(dom.commonAncestor($b[0], $u[0])).to.deep.equal($span[0]);
|
||||
});
|
||||
|
||||
it('should return a common element in ancestors even if they have same nodeName', () => {
|
||||
expect(dom.commonAncestor($b[0], $s[0])).to.deep.equal($div[0]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('listNext', () => {
|
||||
let $cont, $u, $s, $i;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable"><b>b</b><u>u</u><s>s</s><i>i</i></div>'); // busi
|
||||
$u = $cont.find('u');
|
||||
$s = $cont.find('s');
|
||||
$i = $cont.find('i');
|
||||
});
|
||||
|
||||
it('should return an array of next sibling elements including itself', () => {
|
||||
expect(dom.listNext($u[0])).to.deep.equal([$u[0], $s[0], $i[0]]);
|
||||
});
|
||||
|
||||
it('should return itself if there are no next sibling', () => {
|
||||
expect(dom.listNext($i[0])).to.deep.equal([$i[0]]);
|
||||
});
|
||||
|
||||
it('should return an array of next sibling elements before predicate is true', () => {
|
||||
expect(dom.listNext($s[0], func.eq($i[0]))).to.deep.equal([$s[0]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('listPrev', () => {
|
||||
let $cont, $b, $u, $s, $i;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable"><b>b</b><u>u</u><s>s</s><i>i</i></div>'); // busi
|
||||
$b = $cont.find('b');
|
||||
$u = $cont.find('u');
|
||||
$s = $cont.find('s');
|
||||
$i = $cont.find('i');
|
||||
});
|
||||
|
||||
it('should return an array of previous sibling elements including itself', () => {
|
||||
expect(dom.listPrev($s[0])).to.deep.equal([$s[0], $u[0], $b[0]]);
|
||||
});
|
||||
|
||||
it('should return itself if there are no previous sibling', () => {
|
||||
expect(dom.listPrev($b[0])).to.deep.equal([$b[0]]);
|
||||
});
|
||||
|
||||
it('should return an array of previous sibling elements before predicate is true', () => {
|
||||
expect(dom.listPrev($i[0], func.eq($s[0]))).to.deep.equal([$i[0]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('position', () => {
|
||||
let $cont, $b, $u, $s, $i;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable"><b>b</b><u>u</u><s>s</s><i>i</i></div>'); // busi
|
||||
$b = $cont.find('b');
|
||||
$u = $cont.find('u');
|
||||
$s = $cont.find('s');
|
||||
$i = $cont.find('i');
|
||||
});
|
||||
|
||||
it('should return the position of element', () => {
|
||||
expect(dom.position($b[0])).to.be.equal(0);
|
||||
expect(dom.position($u[0])).to.be.equal(1);
|
||||
expect(dom.position($s[0])).to.be.equal(2);
|
||||
expect(dom.position($i[0])).to.be.equal(3);
|
||||
});
|
||||
|
||||
it('should return position 0 for text node in b', () => {
|
||||
expect(dom.position($b[0].firstChild)).to.be.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('makeOffsetPath', () => {
|
||||
let $cont, $b, $u, $s, $i;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable"><b>b</b><u>u</u><s>s</s><i>i</i></div>'); // busi
|
||||
$b = $cont.find('b');
|
||||
$u = $cont.find('u');
|
||||
$s = $cont.find('s');
|
||||
$i = $cont.find('i');
|
||||
});
|
||||
|
||||
it('should return empty array if two elements are same', () => {
|
||||
expect(dom.makeOffsetPath($cont[0], $cont[0])).to.deep.equal([]);
|
||||
});
|
||||
|
||||
it('should return offset path array between two elements #1', () => {
|
||||
expect(dom.makeOffsetPath($cont[0], $b[0])).to.deep.equal([0]);
|
||||
expect(dom.makeOffsetPath($cont[0], $b[0].firstChild)).to.deep.equal([0, 0]);
|
||||
});
|
||||
|
||||
it('should return offset path array between two elements #2', () => {
|
||||
expect(dom.makeOffsetPath($cont[0], $u[0])).to.deep.equal([1]);
|
||||
expect(dom.makeOffsetPath($cont[0], $u[0].firstChild)).to.deep.equal([1, 0]);
|
||||
});
|
||||
|
||||
it('should return offset path array between two elements #3', () => {
|
||||
expect(dom.makeOffsetPath($cont[0], $s[0])).to.deep.equal([2]);
|
||||
expect(dom.makeOffsetPath($cont[0], $s[0].firstChild)).to.deep.equal([2, 0]);
|
||||
});
|
||||
|
||||
it('should return offset path array between two elements #2', () => {
|
||||
expect(dom.makeOffsetPath($cont[0], $i[0])).to.deep.equal([3]);
|
||||
expect(dom.makeOffsetPath($cont[0], $i[0].firstChild)).to.deep.equal([3, 0]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fromOffsetPath', () => {
|
||||
let $cont, $b, $u, $s, $i;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable"><b>b</b><u>u</u><s>s</s><i>i</i></div>'); // busi
|
||||
$b = $cont.find('b');
|
||||
$u = $cont.find('u');
|
||||
$s = $cont.find('s');
|
||||
$i = $cont.find('i');
|
||||
});
|
||||
|
||||
it('should return the element by offsetPath', () => {
|
||||
let cont = $cont[0];
|
||||
$.each([$b[0], $u[0], $s[0], $i[0]], (idx, node) => {
|
||||
expect(dom.fromOffsetPath(cont, dom.makeOffsetPath(cont, node))).to.deep.equal(node);
|
||||
let child = node.firstChild;
|
||||
expect(dom.fromOffsetPath(cont, dom.makeOffsetPath(cont, child))).to.deep.equal(child);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('splitTree', () => {
|
||||
let $para;
|
||||
beforeEach(() => {
|
||||
let $busi = $('<div class="note-editable"><p><b>b</b><u>u</u><s>strike</s><i>i</i></p></div>'); // busi
|
||||
$para = $busi.clone().find('p');
|
||||
});
|
||||
|
||||
describe('element pivot case', () => {
|
||||
it('should be split by u tag with offset 0', () => {
|
||||
let $u = $para.find('u');
|
||||
dom.splitTree($para[0], { node: $u[0], offset: 0 });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b>b</b><u><br></u>');
|
||||
expect($para.next().html()).to.equalsIgnoreCase('<u>u</u><s>strike</s><i>i</i>');
|
||||
});
|
||||
|
||||
it('should be split by u tag with offset 1', () => {
|
||||
let $u = $para.find('u');
|
||||
dom.splitTree($para[0], { node: $u[0], offset: 1 });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b>b</b><u>u</u>');
|
||||
expect($para.next().html()).to.equalsIgnoreCase('<u><br></u><s>strike</s><i>i</i>');
|
||||
});
|
||||
|
||||
it('should be split by b tag with offset 0 (left edge case)', () => {
|
||||
let $b = $para.find('b');
|
||||
dom.splitTree($para[0], { node: $b[0], offset: 0 });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b><br></b>');
|
||||
expect($para.next().html()).to.equalsIgnoreCase('<b>b</b><u>u</u><s>strike</s><i>i</i>');
|
||||
});
|
||||
|
||||
it('should be split by i tag with offset 1 (right edge case)', () => {
|
||||
let $i = $para.find('i');
|
||||
dom.splitTree($para[0], { node: $i[0], offset: 1 });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b>b</b><u>u</u><s>strike</s><i>i</i>');
|
||||
expect($para.next().html()).to.equalsIgnoreCase('<i><br></i>');
|
||||
});
|
||||
|
||||
it('should discard first split if empty and isDiscardEmptySplits=true', () => {
|
||||
var $u = $para.find('u');
|
||||
dom.splitTree($para[0], { node: $u[0], offset: 0 }, { isDiscardEmptySplits: true });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b>b</b>');
|
||||
expect($para.next().html()).to.equalsIgnoreCase('<u>u</u><s>strike</s><i>i</i>');
|
||||
});
|
||||
|
||||
it('should discard second split if empty and isDiscardEmptySplits=true', () => {
|
||||
var $u = $para.find('u');
|
||||
dom.splitTree($para[0], { node: $u[0], offset: 1 }, { isDiscardEmptySplits: true });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b>b</b><u>u</u>');
|
||||
expect($para.next().html()).to.equalsIgnoreCase('<s>strike</s><i>i</i>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('textNode case', () => {
|
||||
it('should be split by s tag with offset 3 (middle case)', () => {
|
||||
let $s = $para.find('s');
|
||||
dom.splitTree($para[0], { node: $s[0].firstChild, offset: 3 });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b>b</b><u>u</u><s>str</s>');
|
||||
expect($para.next().html()).to.equalsIgnoreCase('<s>ike</s><i>i</i>');
|
||||
});
|
||||
|
||||
it('should be split by s tag with offset 0 (left edge case)', () => {
|
||||
let $s = $para.find('s');
|
||||
dom.splitTree($para[0], { node: $s[0].firstChild, offset: 0 });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b>b</b><u>u</u><s><br></s>');
|
||||
expect($para.next().html()).to.equalsIgnoreCase('<s>strike</s><i>i</i>');
|
||||
});
|
||||
|
||||
it('should be split by s tag with offset 6 (right edge case)', () => {
|
||||
let $s = $para.find('s');
|
||||
dom.splitTree($para[0], { node: $s[0].firstChild, offset: 6 });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b>b</b><u>u</u><s>strike</s>');
|
||||
expect($para.next().html()).to.equalsIgnoreCase('<s><br></s><i>i</i>');
|
||||
});
|
||||
|
||||
it('should be split by s tag with offset 3 (2 depth case)', () => {
|
||||
let $s = $para.find('s');
|
||||
dom.splitTree($s[0], { node: $s[0].firstChild, offset: 3 });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b>b</b><u>u</u><s>str</s><s>ike</s><i>i</i>');
|
||||
});
|
||||
|
||||
it('should be split by s tag with offset 3 (1 depth and textNode case)', () => {
|
||||
let $s = $para.find('s');
|
||||
dom.splitTree($s[0].firstChild, { node: $s[0].firstChild, offset: 3 });
|
||||
|
||||
expect($para.html()).to.equalsIgnoreCase('<b>b</b><u>u</u><s>strike</s><i>i</i>');
|
||||
});
|
||||
|
||||
it('should be split by span tag with offset 2 (1 depth and element case)', () => {
|
||||
let $cont = $('<div class="note-editable"><p><span><b>b</b><u>u</u><s>s</s><i>i</i></span></p></div>'); // busi
|
||||
let $span = $cont.find('span');
|
||||
dom.splitTree($span[0], { node: $span[0], offset: 2 });
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><span><b>b</b><u>u</u></span><span><s>s</s><i>i</i></span></p>');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('splitPoint', () => {
|
||||
it('should return rightNode and container for empty paragraph with inline', () => {
|
||||
let $editable = $('<div class="note-editable"><p><br></p></div>');
|
||||
let $para = $editable.clone().find('p');
|
||||
let $br = $para.find('br');
|
||||
|
||||
let result = dom.splitPoint({ node: $para[0], offset: 0 }, true);
|
||||
expect(result).to.deep.equal({ rightNode: $br[0], container: $para[0] });
|
||||
});
|
||||
});
|
||||
});
|
||||
152
public/vendor/editor/test/base/core/func.spec.js
vendored
Executable file
152
public/vendor/editor/test/base/core/func.spec.js
vendored
Executable file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* func.spec.js
|
||||
* (c) 2013~ Alan Hong
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import chai from 'chai';
|
||||
import func from 'src/js/base/core/func';
|
||||
|
||||
var expect = chai.expect;
|
||||
|
||||
describe('base:core.func', () => {
|
||||
describe('eq', () => {
|
||||
it('should return true if two values are same', () => {
|
||||
expect(func.eq(1)(1)).to.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('eq2', () => {
|
||||
it('should return true if two values are same', () => {
|
||||
expect(func.eq2(1, 1)).to.be.ok;
|
||||
});
|
||||
|
||||
it('should return false if two values are not same', () => {
|
||||
expect(func.eq2(1, '1')).to.be.not.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('peq2', () => {
|
||||
it('should return true when two properties are same', () => {
|
||||
expect(func.peq2('prop')({ prop: 'hello' }, { prop: 'hello' })).to.be.ok;
|
||||
});
|
||||
|
||||
it('should return false when two properties are not same', () => {
|
||||
expect(func.peq2('prop')({ prop: 'hello' }, { prop: 'world' })).to.be.not.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('ok', () => {
|
||||
it('should return true', () => {
|
||||
expect(func.ok()).to.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('fail', () => {
|
||||
it('should return false', () => {
|
||||
expect(func.fail()).to.be.not.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('not', () => {
|
||||
it('should return opposite function', () => {
|
||||
expect(func.not(func.ok)()).to.be.not.ok;
|
||||
expect(func.not(func.fail)()).to.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('and', () => {
|
||||
it('should return composite function', () => {
|
||||
expect(func.and(func.ok, func.ok)()).to.be.ok;
|
||||
expect(func.and(func.fail, func.ok)()).to.be.not.ok;
|
||||
expect(func.and(func.fail, func.fail)()).to.be.not.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('invoke', () => {
|
||||
it('should return function which invoke the method', () => {
|
||||
expect(func.invoke(func, 'ok')()).to.be.ok;
|
||||
expect(func.invoke(func, 'fail')()).to.be.not.ok;
|
||||
});
|
||||
});
|
||||
|
||||
describe('uniqueId', () => {
|
||||
it('should return uniqueId with the prefix as a parameter', () => {
|
||||
func.resetUniqueId();
|
||||
expect(func.uniqueId('note-')).to.be.equal('note-1');
|
||||
expect(func.uniqueId('note-')).to.be.equal('note-2');
|
||||
expect(func.uniqueId('note-')).to.be.equal('note-3');
|
||||
});
|
||||
});
|
||||
|
||||
describe('invertObject', () => {
|
||||
it('should return inverted object between keys and values', () => {
|
||||
expect(func.invertObject({ keyA: 'valueA', keyB: 'valueB' }))
|
||||
.to.deep.equal({ valueA: 'keyA', valueB: 'keyB' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('namespaceToCamel', () => {
|
||||
it('should return camelcase text', () => {
|
||||
expect(func.namespaceToCamel('upload.image')).to.be.equal('UploadImage');
|
||||
});
|
||||
|
||||
it('should return prefixed camelcase text', () => {
|
||||
expect(func.namespaceToCamel('upload.image', 'summernote')).to.be.equal('summernoteUploadImage');
|
||||
});
|
||||
});
|
||||
|
||||
describe('debounce', () => {
|
||||
it('shouldnt execute immediately', () => {
|
||||
var hasHappened = false;
|
||||
var fn = func.debounce(() => {
|
||||
hasHappened = true;
|
||||
}, 100);
|
||||
|
||||
expect(hasHappened).to.be.false;
|
||||
fn();
|
||||
expect(hasHappened).to.be.false;
|
||||
});
|
||||
|
||||
it('should execute after delay', (done) => {
|
||||
var hasHappened = false;
|
||||
var fn = func.debounce(() => {
|
||||
hasHappened = true;
|
||||
}, 100);
|
||||
|
||||
fn();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(hasHappened).to.be.true;
|
||||
done();
|
||||
}, 101);
|
||||
});
|
||||
|
||||
it('should only happen once', (done) => {
|
||||
var count = 0;
|
||||
var fn = func.debounce(() => {
|
||||
count += 1;
|
||||
}, 100);
|
||||
|
||||
fn();
|
||||
fn();
|
||||
fn();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(count).to.be.equal(1);
|
||||
done();
|
||||
}, 101);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isValidUrl', () => {
|
||||
it('should return true with valid URLs', () => {
|
||||
expect(func.isValidUrl('https://www.summernote.org')).to.be.ok;
|
||||
expect(func.isValidUrl('http://summernote.org')).to.be.ok;
|
||||
expect(func.isValidUrl('summernote.org')).to.be.ok;
|
||||
});
|
||||
|
||||
it('should return false with invalid URLs', () => {
|
||||
expect(func.isValidUrl('summernote')).to.be.not.ok;
|
||||
});
|
||||
});
|
||||
});
|
||||
25
public/vendor/editor/test/base/core/key.spec.js
vendored
Executable file
25
public/vendor/editor/test/base/core/key.spec.js
vendored
Executable file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* key.spec.js
|
||||
* (c) 2013~ Alan Hong
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import chai from 'chai';
|
||||
import key from 'src/js/base/core/key';
|
||||
|
||||
var expect = chai.expect;
|
||||
|
||||
describe('base:core.key', () => {
|
||||
describe('isEdit', () => {
|
||||
it('should return true for BACKSPACE', () => {
|
||||
expect(key.isEdit(key.code.BACKSPACE)).to.be.true;
|
||||
});
|
||||
it('should return true for DELETE', () => {
|
||||
expect(key.isEdit(key.code.DELETE)).to.be.true;
|
||||
});
|
||||
});
|
||||
describe('isMove', () => {
|
||||
it('should return true for LEFT', () => {
|
||||
expect(key.isMove(key.code.LEFT)).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
118
public/vendor/editor/test/base/core/lists.spec.js
vendored
Executable file
118
public/vendor/editor/test/base/core/lists.spec.js
vendored
Executable file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* lists.spec.js
|
||||
* (c) 2013~ Alan Hong
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import chai from 'chai';
|
||||
import $ from 'jquery';
|
||||
import lists from 'src/js/base/core/lists';
|
||||
|
||||
var expect = chai.expect;
|
||||
|
||||
describe('base:core.lists', () => {
|
||||
describe('head', () => {
|
||||
it('should return the first element', () => {
|
||||
expect(lists.head([1, 2, 3])).to.be.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('last', () => {
|
||||
it('should return the last element', () => {
|
||||
expect(lists.last([1, 2, 3])).to.be.equal(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('initial', () => {
|
||||
it('should exclude last element', () => {
|
||||
expect(lists.initial([1, 2, 3])).to.deep.equal([1, 2]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tail', () => {
|
||||
it('should exclude first element', () => {
|
||||
expect(lists.tail([1, 2, 3])).to.deep.equal([2, 3]);
|
||||
});
|
||||
});
|
||||
|
||||
function isEven(num) {
|
||||
return num % 2 === 0;
|
||||
}
|
||||
|
||||
describe('find', () => {
|
||||
it('should return first matched element', () => {
|
||||
expect(lists.find([1, 2, 3], isEven)).to.be.equal(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('all', () => {
|
||||
it('should return false if all elements are not even', () => {
|
||||
expect(lists.all([1, 2, 3], isEven)).to.be.false;
|
||||
});
|
||||
|
||||
it('should return true if all elements are even', () => {
|
||||
expect(lists.all([2, 4], isEven)).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('all', () => {
|
||||
it('should return false if the element is not contained', () => {
|
||||
expect(lists.contains([1, 2, 3], 4)).to.be.false;
|
||||
});
|
||||
|
||||
it('should return true if the element is contained', () => {
|
||||
expect(lists.contains([1, 2, 4], 4)).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('sum', () => {
|
||||
it('should return sum of all elements', () => {
|
||||
expect(lists.sum([1, 2, 3])).to.be.equal(6);
|
||||
});
|
||||
|
||||
it('should return sum of all elements iterated', () => {
|
||||
var result = lists.sum([1, 2, 3], (v) => { return v * 2; });
|
||||
expect(result).to.be.equal(12);
|
||||
});
|
||||
});
|
||||
|
||||
describe('from', () => {
|
||||
it('should return an array of childNodes', () => {
|
||||
var $cont, $b, $u, $s, $i;
|
||||
$cont = $('<div><b>b</b><u>u</u><s>s</s><i>i</i></div>'); // busi
|
||||
$b = $cont.find('b');
|
||||
$u = $cont.find('u');
|
||||
$s = $cont.find('s');
|
||||
$i = $cont.find('i');
|
||||
|
||||
expect(lists.from($cont[0].childNodes)).to.deep.equal([$b[0], $u[0], $s[0], $i[0]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('clusterBy', () => {
|
||||
it('should cluster by equality 1', () => {
|
||||
var aaClustered = lists.clusterBy([1, 1, 2, 2, 3], (itemA, itemB) => {
|
||||
return itemA === itemB;
|
||||
});
|
||||
expect(aaClustered).to.deep.equal([[1, 1], [2, 2], [3]]);
|
||||
});
|
||||
|
||||
it('should cluster by equality 2', () => {
|
||||
var aaClustered = lists.clusterBy([1, 2, 2, 1, 3], (itemA, itemB) => {
|
||||
return itemA === itemB;
|
||||
});
|
||||
expect(aaClustered).to.deep.equal([[1], [2, 2], [1], [3]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('compact', () => {
|
||||
it('should remove all elements has false value', () => {
|
||||
expect(lists.compact([0, 1, false, 2, '', 3])).to.deep.equal([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('unique', () => {
|
||||
it('should return duplicate-free version of array', () => {
|
||||
expect(lists.unique([1, 2, 3, 3, 2, 1])).to.deep.equal([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
});
|
||||
492
public/vendor/editor/test/base/core/range.spec.js
vendored
Executable file
492
public/vendor/editor/test/base/core/range.spec.js
vendored
Executable file
@@ -0,0 +1,492 @@
|
||||
/**
|
||||
* range.spec.js
|
||||
* (c) 2013~ Alan Hong
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
|
||||
import chai from 'chai';
|
||||
import chaidom from 'test/chaidom';
|
||||
import $ from 'jquery';
|
||||
import dom from 'src/js/base/core/dom';
|
||||
import range from 'src/js/base/core/range';
|
||||
|
||||
var expect = chai.expect;
|
||||
chai.use(chaidom);
|
||||
|
||||
describe('base:core.range', () => {
|
||||
describe('nodes', () => {
|
||||
describe('1 depth', () => {
|
||||
var $para;
|
||||
before(() => {
|
||||
var $cont = $('<div class="note-editable"><p>para1</p><p>para2</p></div>');
|
||||
$para = $cont.find('p');
|
||||
});
|
||||
|
||||
it('should return array of two paragraphs', () => {
|
||||
var rng = range.create($para[0].firstChild, 0, $para[1].firstChild, 1);
|
||||
expect(rng.nodes(dom.isPara, { includeAncestor: true })).to.have.length(2);
|
||||
});
|
||||
|
||||
it('should return array of a paragraph', () => {
|
||||
var rng = range.create($para[0].firstChild, 0, $para[0].firstChild, 0);
|
||||
expect(rng.nodes(dom.isPara, { includeAncestor: true })).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('multi depth', () => {
|
||||
it('should return array of a paragraph', () => {
|
||||
var $cont = $('<div class="note-editable"><p>p<b>ar</b>a1</p><p>para2</p></div>');
|
||||
var $b = $cont.find('b');
|
||||
var rng = range.create($b[0].firstChild, 0, $b[0].firstChild, 0);
|
||||
|
||||
expect(rng.nodes(dom.isPara, { includeAncestor: true })).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('on list, on heading', () => {
|
||||
it('should return array of list paragraphs', () => {
|
||||
var $cont = $('<div class="note-editable"><ul><li>para1</li><li>para2</li></ul></div>');
|
||||
var $li = $cont.find('li');
|
||||
var rng = range.create($li[0].firstChild, 0, $li[1].firstChild, 1);
|
||||
|
||||
expect(rng.nodes(dom.isPara, { includeAncestor: true })).to.have.length(2);
|
||||
});
|
||||
|
||||
it('should return array of list paragraphs', () => {
|
||||
var $cont = $('<div class="note-editable"><h1>heading1</h1><h2>heading2</h2></div>');
|
||||
var $h1 = $cont.find('h1');
|
||||
var $h2 = $cont.find('h2');
|
||||
var rng = range.create($h1[0].firstChild, 0, $h2[0].firstChild, 1);
|
||||
|
||||
expect(rng.nodes(dom.isPara, { includeAncestor: true })).to.have.length(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('commonAncestor', () => {
|
||||
var $cont;
|
||||
before(() => {
|
||||
$cont = $('<div><span><b>b</b><u>u</u></span></div>');
|
||||
});
|
||||
|
||||
it('should return <span> for <b>|b</b> and <u>u|</u>', () => {
|
||||
var $span = $cont.find('span');
|
||||
var $b = $cont.find('b');
|
||||
var $u = $cont.find('u');
|
||||
|
||||
var rng = range.create($b[0].firstChild, 0, $u[0].firstChild, 1);
|
||||
expect(rng.commonAncestor()).to.deep.equal($span[0]);
|
||||
});
|
||||
|
||||
it('should return b(#textNode) for <b>|b|</b>', () => {
|
||||
var $b = $cont.find('b');
|
||||
|
||||
var rng = range.create($b[0].firstChild, 0, $b[0].firstChild, 1);
|
||||
expect(rng.commonAncestor()).to.deep.equal($b[0].firstChild);
|
||||
});
|
||||
});
|
||||
|
||||
describe('expand', () => {
|
||||
it('should return <b>|b</b> ~ <u>u|</u> for <b>|b</b> with isAnchor', () => {
|
||||
var $cont = $('<div><a><b>b</b><u>u</u></a></div>');
|
||||
var $anchor = $cont.find('a');
|
||||
var $b = $cont.find('b');
|
||||
|
||||
var rng = range.create($b[0].firstChild, 0, $b[0].firstChild, 0).expand(dom.isAnchor);
|
||||
expect(rng.sc).to.deep.equal($anchor[0]);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($anchor[0]);
|
||||
expect(rng.eo).to.equal(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('collapse', () => {
|
||||
it('should return <u>u|</u> for <b>|b</b> ~ <u>u|</u>', () => {
|
||||
var $cont = $('<div><b>b</b><u>u</u></div>');
|
||||
var $b = $cont.find('b');
|
||||
var $u = $cont.find('u');
|
||||
|
||||
var rng = range.create($b[0].firstChild, 0, $u[0].firstChild, 1).collapse();
|
||||
expect(rng.sc).to.deep.equal($u[0].firstChild);
|
||||
expect(rng.so).to.equal(1);
|
||||
expect(rng.ec).to.deep.equal($u[0].firstChild);
|
||||
expect(rng.eo).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('normalize', () => {
|
||||
var $cont;
|
||||
before(() => {
|
||||
$cont = $('<div><p><b>b</b><u>u</u><s>s</s></p></div>');
|
||||
});
|
||||
|
||||
it('should return <b>|b</b> ~ <u>u|</u> for |<b>b</b> ~ <u>u</u>|', () => {
|
||||
var $p = $cont.find('p');
|
||||
var $b = $cont.find('b');
|
||||
var $u = $cont.find('u');
|
||||
|
||||
var rng = range.create($p[0], 0, $p[0], 2).normalize();
|
||||
expect(rng.sc).to.deep.equal($b[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($u[0].firstChild);
|
||||
expect(rng.eo).to.equal(1);
|
||||
});
|
||||
|
||||
it('should return <b>b|</b><u>u</u> for <b>b</b>|<u>u</u>', () => {
|
||||
var $p = $cont.find('p');
|
||||
var $b = $cont.find('b');
|
||||
|
||||
var rng = range.create($p[0], 1, $p[0], 1).normalize();
|
||||
expect(rng.sc).to.deep.equal($b[0].firstChild);
|
||||
expect(rng.so).to.equal(1);
|
||||
expect(rng.ec).to.deep.equal($b[0].firstChild);
|
||||
expect(rng.eo).to.equal(1);
|
||||
});
|
||||
|
||||
it('should return <b>b</b><u>|u|</u><s>s</s> for <b>b|</b><u>u</u><s>|s</s>', () => {
|
||||
var $b = $cont.find('b');
|
||||
var $u = $cont.find('u');
|
||||
var $s = $cont.find('s');
|
||||
|
||||
var rng = range.create($b[0].firstChild, 1, $s[0].firstChild, 0).normalize();
|
||||
expect(rng.sc).to.deep.equal($u[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($u[0].firstChild);
|
||||
expect(rng.eo).to.equal(1);
|
||||
});
|
||||
|
||||
it('should return <b>b|</b><u>u</u><s>s</s> for <b>b|</b><u>u</u><s>s</s>', () => {
|
||||
var $b = $cont.find('b');
|
||||
|
||||
var rng = range.create($b[0].firstChild, 1, $b[0].firstChild, 1).normalize();
|
||||
expect(rng.sc).to.deep.equal($b[0].firstChild);
|
||||
expect(rng.so).to.equal(1);
|
||||
expect(rng.ec).to.deep.equal($b[0].firstChild);
|
||||
expect(rng.eo).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('normalize (block mode)', () => {
|
||||
it('should return <p>text</p><p>|<br></p> for <p>text</p><p>|<br></p>', () => {
|
||||
var $cont = $('<div><p>text</p><p><br></p></div>');
|
||||
var $p = $cont.find('p');
|
||||
|
||||
var rng = range.create($p[1], 0, $p[1], 0).normalize();
|
||||
expect(rng.sc).to.deep.equal($p[1]);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($p[1]);
|
||||
expect(rng.eo).to.equal(0);
|
||||
});
|
||||
|
||||
it('should return <p>text</p><p>|text</p> for <p>text</p><p>|text</p>', () => {
|
||||
var $cont = $('<div><p>text</p><p>text</p></div>');
|
||||
var $p = $cont.find('p');
|
||||
|
||||
var rng = range.create($p[1], 0, $p[1], 0).normalize();
|
||||
expect(rng.sc).to.deep.equal($p[1].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($p[1].firstChild);
|
||||
expect(rng.eo).to.equal(0);
|
||||
});
|
||||
|
||||
it('should return <p>|text</p><p>text|</p> for |<p>text</p><p>text</p>|', () => {
|
||||
var $cont = $('<div class="note-editable"><p>text</p><p>text</p></div>');
|
||||
var $p = $cont.find('p');
|
||||
|
||||
var rng = range.create($cont[0], 0, $cont[0], 2).normalize();
|
||||
expect(rng.sc).to.deep.equal($p[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($p[1].firstChild);
|
||||
expect(rng.eo).to.equal(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('normalize (void element)', () => {
|
||||
it('should return <p><img>|<b>bold</b></p> for <p><img>|<b>bold</b></p>', () => {
|
||||
var $cont = $('<div><p><img><b>bold</b></p></div>');
|
||||
var $p = $cont.find('p');
|
||||
var $b = $cont.find('b');
|
||||
|
||||
var rng = range.create($p[0], 1, $p[0], 1).normalize();
|
||||
expect(rng.sc).to.deep.equal($b[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($b[0].firstChild);
|
||||
expect(rng.eo).to.equal(0);
|
||||
});
|
||||
|
||||
it('should return <p><img>|text></p> for <p><img>|text></p>', () => {
|
||||
var $cont = $('<div><p><img>bold</p></div>');
|
||||
var $img = $cont.find('img');
|
||||
var text = $img[0].nextSibling;
|
||||
|
||||
var rng = range.create(text, 0, text, 0).normalize();
|
||||
expect(rng.sc).to.equal(text);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.isCollapsed()).to.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('insertNode', () => {
|
||||
it('should split paragraph when inserting a block element', () => {
|
||||
var $cont = $('<div class="note-editable"><p><b>bold</b></p></div>');
|
||||
var $b = $cont.find('b');
|
||||
var $p2 = $('<p>p</p>');
|
||||
|
||||
var rng = range.create($b[0].firstChild, 2, $b[0].firstChild, 2);
|
||||
rng.insertNode($p2[0]);
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><b>bo</b></p><p>p</p><p><b>ld</b></p>');
|
||||
});
|
||||
|
||||
it('should not split paragraph when inserting an inline element', () => {
|
||||
var $cont = $('<div class="note-editable"><p>text</p></div>');
|
||||
var $p = $cont.find('p');
|
||||
var $u = $('<u>u</u>');
|
||||
|
||||
var rng = range.create($p[0].firstChild, 2, $p[0].firstChild, 2);
|
||||
rng.insertNode($u[0]);
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p>te<u>u</u>xt</p>');
|
||||
});
|
||||
|
||||
it('should not split paragraph when inserting an inline element case 2', () => {
|
||||
var $cont = $('<div class="note-editable"><p><b>bold</b></p></div>');
|
||||
var $b = $cont.find('b');
|
||||
var $u = $('<u>u</u>');
|
||||
|
||||
var rng = range.create($b[0].firstChild, 2, $b[0].firstChild, 2);
|
||||
rng.insertNode($u[0]);
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><b>bo</b><u>u</u><b>ld</b></p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('pasteHTML', () => {
|
||||
it('should not split a block element when inserting inline elements into it', () => {
|
||||
var $cont = $('<div class="note-editable"><p>text</p></div>');
|
||||
var $p = $cont.find('p');
|
||||
var markup = '<span>span</span><i>italic</i>';
|
||||
|
||||
var rng = range.create($p[0].firstChild, 2);
|
||||
rng.pasteHTML(markup);
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p>te<span>span</span><i>italic</i>xt</p>');
|
||||
});
|
||||
|
||||
it('should split an inline element when pasting inline elements into it', () => {
|
||||
var $cont = $('<div class="note-editable"><p><b>bold</b></p></div>');
|
||||
var $b = $cont.find('b');
|
||||
var markup = '<span>span</span><i>italic</i>';
|
||||
|
||||
var rng = range.create($b[0].firstChild, 2);
|
||||
rng.pasteHTML(markup);
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><b>bo</b><span>span</span><i>italic</i><b>ld</b></p>');
|
||||
});
|
||||
|
||||
it('should split inline node when pasting an inline node and a block node into it', () => {
|
||||
var $cont = $('<div class="note-editable"><p><b>bold</b></p></div>');
|
||||
var $b = $cont.find('b');
|
||||
var markup = '<span>span</span><p><i>italic</i></p>';
|
||||
|
||||
var rng = range.create($b[0].firstChild, 2);
|
||||
rng.pasteHTML(markup);
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><b>bo</b><span>span</span></p><p><i>italic</i></p><p><b>ld</b></p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('deleteContents', () => {
|
||||
var $cont, $b;
|
||||
beforeEach(() => {
|
||||
$cont = $('<div class="note-editable"><p><b>bold</b><u>u</u></p></div>');
|
||||
$b = $cont.find('b');
|
||||
});
|
||||
|
||||
it('should remove text only for partial text', () => {
|
||||
var rng = range.create($b[0].firstChild, 1, $b[0].firstChild, 3);
|
||||
rng.deleteContents();
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><b>bd</b><u>u</u></p>');
|
||||
});
|
||||
|
||||
it('should remove text for entire text', () => {
|
||||
var rng = range.create($b[0].firstChild, 0, $b[0].firstChild, 4);
|
||||
rng.deleteContents();
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><b></b><u>u</u></p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('wrapBodyInlineWithPara', () => {
|
||||
it('should insert an empty paragraph when there is no contents', () => {
|
||||
var $cont = $('<div class="note-editable"></div>');
|
||||
|
||||
var rng = range.create($cont[0], 0);
|
||||
rng.wrapBodyInlineWithPara();
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><br></p>');
|
||||
});
|
||||
|
||||
it('should wrap text with paragraph for text', () => {
|
||||
var $cont = $('<div class="note-editable">text</div>');
|
||||
|
||||
var rng = range.create($cont[0].firstChild, 2);
|
||||
rng.wrapBodyInlineWithPara();
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p>text</p>');
|
||||
});
|
||||
|
||||
it('should wrap an inline node with paragraph when selecting text in the inline node', () => {
|
||||
var $cont = $('<div class="note-editable"><b>bold</b></div>');
|
||||
var $b = $cont.find('b');
|
||||
|
||||
var rng = range.create($b[0].firstChild, 2);
|
||||
rng.wrapBodyInlineWithPara();
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><b>bold</b></p>');
|
||||
});
|
||||
|
||||
it('should wrap inline nodes with paragraph when selecting text in the inline nodes', () => {
|
||||
var $cont = $('<div class="note-editable"><b>b</b><i>i</i></div>');
|
||||
|
||||
var rng = range.create($cont[0], 0);
|
||||
rng.wrapBodyInlineWithPara();
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><b>b</b><i>i</i></p>');
|
||||
});
|
||||
|
||||
it('should wrap inline nodes with paragraph when selection some of text in the inline nodes #1', () => {
|
||||
var $cont = $('<div class="note-editable"><b>b</b><i>i</i></div>');
|
||||
|
||||
var rng = range.create($cont[0], 1);
|
||||
rng.wrapBodyInlineWithPara();
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><b>b</b><i>i</i></p>');
|
||||
});
|
||||
|
||||
it('should wrap inline nodes with paragraph when selection some of text in the inline nodes #2', () => {
|
||||
var $cont = $('<div class="note-editable"><b>b</b><i>i</i></div>');
|
||||
|
||||
var rng = range.create($cont[0], 2);
|
||||
rng.wrapBodyInlineWithPara();
|
||||
|
||||
expect($cont.html()).to.equalsIgnoreCase('<p><b>b</b><i>i</i></p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getWordRange', () => {
|
||||
var $cont;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable">super simple wysiwyg editor</div>');
|
||||
});
|
||||
|
||||
it('should return the range itself when there is no word before cursor', () => {
|
||||
var rng = range.create($cont[0].firstChild, 0).getWordRange();
|
||||
|
||||
expect(rng.sc).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.eo).to.equal(0);
|
||||
});
|
||||
|
||||
it('should return expanded range when there is a word before cursor', () => {
|
||||
var rng = range.create($cont[0].firstChild, 5).getWordRange();
|
||||
|
||||
expect(rng.sc).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.eo).to.equal(5);
|
||||
});
|
||||
|
||||
it('should return expanded range when there is a half word before cursor', () => {
|
||||
var rng = range.create($cont[0].firstChild, 3).getWordRange();
|
||||
|
||||
expect(rng.sc).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.eo).to.equal(3);
|
||||
});
|
||||
|
||||
it('should return expanded range when there are words before cursor', () => {
|
||||
var rng = range.create($cont[0].firstChild, 12).getWordRange();
|
||||
|
||||
expect(rng.sc).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.so).to.equal(6);
|
||||
expect(rng.ec).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.eo).to.equal(12);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getWordsRange', () => {
|
||||
var $cont;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable">super simple wysiwyg editor</div>');
|
||||
});
|
||||
|
||||
it('should return the range itself when there is no word before cursor', () => {
|
||||
var rng = range.create($cont[0].firstChild, 0).getWordsRange();
|
||||
|
||||
expect(rng.sc).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.eo).to.equal(0);
|
||||
});
|
||||
|
||||
it('should return expanded range when there is a word before cursor', () => {
|
||||
var rng = range.create($cont[0].firstChild, 5).getWordsRange();
|
||||
|
||||
expect(rng.sc).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.eo).to.equal(5);
|
||||
});
|
||||
|
||||
it('should return expanded range when there is a half word before cursor', () => {
|
||||
var rng = range.create($cont[0].firstChild, 3).getWordsRange();
|
||||
|
||||
expect(rng.sc).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.eo).to.equal(3);
|
||||
});
|
||||
|
||||
it('should return expanded range when there are words before cursor', () => {
|
||||
var rng = range.create($cont[0].firstChild, 14).getWordsRange();
|
||||
|
||||
expect(rng.sc).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.so).to.equal(0);
|
||||
expect(rng.ec).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.eo).to.equal(14);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getWordsMatchRange', () => {
|
||||
var $cont, regex;
|
||||
before(() => {
|
||||
$cont = $('<div class="note-editable">hi @Peter Pan. How are you?</div>');
|
||||
regex = /@[a-z ]+/i;
|
||||
});
|
||||
|
||||
it('should return null when there is no word before cursor', () => {
|
||||
var rng = range.create($cont[0].firstChild, 0).getWordsMatchRange(regex);
|
||||
expect(rng).to.be.a('null');
|
||||
});
|
||||
|
||||
it('should return expanded range when there are words before cursor', () => {
|
||||
var rng = range.create($cont[0].firstChild, 13).getWordsMatchRange(regex);
|
||||
|
||||
// range: 'hi @Peter Pan'
|
||||
// matched range: '@Peter Pan'
|
||||
expect(rng.sc).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.so).to.equal(3);
|
||||
expect(rng.ec).to.deep.equal($cont[0].firstChild);
|
||||
expect(rng.eo).to.equal(13);
|
||||
});
|
||||
|
||||
it('should return null when can not match', () => {
|
||||
var rng = range.create($cont[0].firstChild, 14).getWordsMatchRange(regex);
|
||||
|
||||
// range: 'hi @Peter Pan.'
|
||||
expect(rng).to.be.a('null');
|
||||
});
|
||||
});
|
||||
});
|
||||
555
public/vendor/editor/test/base/editing/Table.spec.js
vendored
Executable file
555
public/vendor/editor/test/base/editing/Table.spec.js
vendored
Executable file
@@ -0,0 +1,555 @@
|
||||
/**
|
||||
* Table.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import chai from 'chai';
|
||||
import chaidom from 'test/chaidom';
|
||||
import range from 'src/js/base/core/range';
|
||||
import Table from 'src/js/base/editing/Table';
|
||||
|
||||
var expect = chai.expect;
|
||||
chai.use(chaidom);
|
||||
|
||||
describe('base:editing.Table', () => {
|
||||
var table = new Table();
|
||||
describe('tableWorker', () => {
|
||||
it('should create simple 1x1 table', () => {
|
||||
var resultTable = table.createTable(1, 1);
|
||||
expect(1).to.deep.equal(resultTable.rows.length);
|
||||
expect(1).to.deep.equal(resultTable.rows[0].cells.length);
|
||||
});
|
||||
|
||||
it('should delete simple 1x1 table', () => {
|
||||
var $cont = $('<div class="note-editable"><table><tr><td>content</td></tr></table></div>');
|
||||
var $cell = $cont.find('td');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteTable(rng);
|
||||
expect('').to.deep.equal($cont.html());
|
||||
});
|
||||
|
||||
it('should add simple row to table on top', () => {
|
||||
var $cont = $('<div class="note-editable"><table><tr><td>content</td></tr></table></div>');
|
||||
var $cell = $cont.find('td');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addRow(rng, 'top');
|
||||
expect('<table><tbody><tr><td><br></td></tr><tr><td>content</td></tr></tbody></table>').to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add simple row to table on bottom', () => {
|
||||
var $cont = $('<div class="note-editable"><table><tr><td>content</td></tr></table></div>');
|
||||
var $cell = $cont.find('td');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addRow(rng, 'bottom');
|
||||
expect('<table><tbody><tr><td>content</td></tr><tr><td><br></td></tr></tbody></table>').to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add simple row to table on top between two rows', () => {
|
||||
var htmlContent = '<div class="note-editable"><table><tr><td>content1</td></tr><tr><td id="td2">content2</td></tr></table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
var $cell = $cont.find('#td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addRow(rng, 'top');
|
||||
var resultTable = $('<table><tbody><tr><td>content1</td></tr></tbody></table>');
|
||||
$(resultTable).append('<tr><td><br/></td></tr>');
|
||||
$(resultTable).append('<tr><td id="td2">content2</td></tr>');
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add simple row to table on bottom between two rows', () => {
|
||||
var baseTable = $('<table><tbody><tr><td id="td1">content1</td></tr></tbody></table>');
|
||||
$(baseTable).append('<tr><td id="td2">content2</td></tr>');
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
var $cell = $cont.find('#td1');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addRow(rng, 'bottom');
|
||||
|
||||
var resultTable = $('<table><tbody><tr><td id="td1">content1</td></tr></tbody></table>');
|
||||
$(resultTable).append('<tr><td><br/></td></tr>');
|
||||
$(resultTable).append('<tr><td id="td2">content2</td></tr>');
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add simple col to table on left between two cols', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table>');
|
||||
var baseTr = '<tr><td id="td1">content1</td><td id="td2">content2</td></tr>';
|
||||
baseTable.append(baseTr);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
var $cell = $cont.find('#td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addCol(rng, 'left');
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table>');
|
||||
$(resultTable).append('<tr><td id="td1">content1</td><td><br/></td><td id="td2">content2</td></tr>');
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add simple col to table on right between two cols', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table>');
|
||||
var baseTr = '<tr><td id="td1">content1</td><td id="td2">content2</td></tr>';
|
||||
baseTable.append(baseTr);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
var $cell = $cont.find('#td1');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addCol(rng, 'right');
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table>');
|
||||
$(resultTable).append('<tr><td id="td1">content1</td><td><br/></td><td id="td2">content2</td></tr>');
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should delete row to table between two other rows', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table>');
|
||||
var baseTr = '<tr><td id="td1">content1</td></tr>';
|
||||
baseTr += '<td id="td2">content2</td></tr>';
|
||||
baseTr += '<td id="td3">content3</td></tr>';
|
||||
baseTable.append(baseTr);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
var $cell = $cont.find('#td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteRow(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table>');
|
||||
$(resultTable).append('<tr><td id="td1">content1</td></tr><tr><td id="td3">content3</td></tr>');
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should delete col to table between two other cols', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table>');
|
||||
var baseTr = '<tr><td id="td1">content1</td><td id="td2">content2</td><td id="td3">content3</td></tr>';
|
||||
baseTable.append(baseTr);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
var $cell = $cont.find('#td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteCol(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table>');
|
||||
$(resultTable).append('<tr><td id="td1">content1</td><td id="td3">content3</td></tr>');
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should delete first col to table with colspan in column with colspan', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td colspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td1">Col1</td><td id="tr2td2">Col2</td><td id="tr2td3">Col3</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td1');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteCol(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td id="tr1td1"></td><td id="tr1td2">Col2</td></tr>';
|
||||
var resultTr2 = '<tr><td id="tr2td2">Col2</td><td id="tr2td3">Col3</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should delete second col to table with colspan in column', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td colspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td1">Col1</td><td id="tr2td2">Col2</td><td id="tr2td3">Col3</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr2td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteCol(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var resultTr2 = '<tr><td id="tr2td1">Col1</td><td id="tr2td3">Col3</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should delete second col to table with colspan in 3 columns', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td colspan="3" id="tr1td1">Col1-Span</td><td id="tr1td4">Col4</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td1">Col1</td><td id="tr2td2">Col2</td><td id="tr2td3">Col3</td><td id="tr2td4">Col4</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr2td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteCol(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td colspan="2" id="tr1td1">Col1-Span</td><td id="tr1td4">Col4</td></tr>';
|
||||
var resultTr2 = '<tr><td id="tr2td1">Col1</td><td id="tr2td3">Col3</td><td id="tr2td4">Col4</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should delete first row to table with rowspan in line with rowspan', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table>');
|
||||
var baseTr1 = '<tr><td class="test" rowspan="2" id="tr1td1">Row1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td2">Col2</td></tr>';
|
||||
var baseTr3 = '<tr><td id="tr3td1">Col1</td><td id="tr3td2">Col2</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
baseTable.append(baseTr3);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td1');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteRow(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1AndTr2 = '<tr><td class="test" id="tr1td1"></td><td id="tr2td2">Col2</td></tr>';
|
||||
var resultTr3 = '<tr><td id="tr3td1">Col1</td><td id="tr3td2">Col2</td></tr>';
|
||||
resultTable.append(resultTr1AndTr2);
|
||||
resultTable.append(resultTr3);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should delete second row to table with rowspan in line without rowspan', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table>');
|
||||
var baseTr1 = '<tr><td rowspan="3" id="tr1td1">Row1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td2">Col2</td></tr>';
|
||||
var baseTr3 = '<tr><td id="tr3td2">Col2</td></tr>';
|
||||
var baseTr4 = '<tr><td id="tr4td1">Col1</td><td id="tr4td2">Col2</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
baseTable.append(baseTr3);
|
||||
baseTable.append(baseTr4);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr2td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteRow(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table>');
|
||||
var resultTr1 = '<tr><td rowspan="2" id="tr1td1">Row1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var resultTr3 = '<tr><td id="tr3td2">Col2</td></tr>';
|
||||
var resultTr4 = '<tr><td id="tr4td1">Col1</td><td id="tr4td2">Col2</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr3);
|
||||
resultTable.append(resultTr4);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should delete second col to table with rowspan in 2 rows', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td2">Col2</td></tr>';
|
||||
var baseTr3 = '<tr><td id="tr3td1">Col1</td><td id="tr3td2">Col2</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
baseTable.append(baseTr3);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteCol(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td></tr>';
|
||||
var resultTr2 = '<tr></tr>';
|
||||
var resultTr3 = '<tr><td id="tr3td1">Col1</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
resultTable.append(resultTr3);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should delete second col to table with rowspan in 2 rows on second row', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td2">Col2</td></tr>';
|
||||
var baseTr3 = '<tr><td id="tr3td1">Col1</td><td id="tr3td2">Col2</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
baseTable.append(baseTr3);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr2td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteCol(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td></tr>';
|
||||
var resultTr2 = '<tr></tr>';
|
||||
var resultTr3 = '<tr><td id="tr3td1">Col1</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
resultTable.append(resultTr3);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add row on bottom rowspan cell.', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td2">Col2</td></tr>';
|
||||
var baseTr3 = '<tr><td id="tr3td1">Col1</td><td id="tr3td2">Col2</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
baseTable.append(baseTr3);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr2td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addRow(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td rowspan="3" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var resultTr2 = '<tr><td id="tr2td2">Col2</td></tr>';
|
||||
var resultTr3 = '<tr><td><br></td></tr>';
|
||||
var resultTr4 = '<tr><td id="tr3td1">Col1</td><td id="tr3td2">Col2</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
resultTable.append(resultTr3);
|
||||
resultTable.append(resultTr4);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add row on bottom colspan cell.', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td colspan="2" id="tr1td1">Col1-Span</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td1">Col1</td><td id="tr2td2">Col2</td></tr>';
|
||||
var baseTr3 = '<tr><td id="tr3td1">Col1</td><td id="tr3td2">Col2</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
baseTable.append(baseTr3);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td1');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addRow(rng, 'bottom');
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td colspan="2" id="tr1td1">Col1-Span</td></tr>';
|
||||
var resultTr2 = '<tr><td colspan="2"><br></td></tr>';
|
||||
var resultTr3 = '<tr><td id="tr2td1">Col1</td><td id="tr2td2">Col2</td></tr>';
|
||||
var resultTr4 = '<tr><td id="tr3td1">Col1</td><td id="tr3td2">Col2</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
resultTable.append(resultTr3);
|
||||
resultTable.append(resultTr4);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add row above rowspan cell.', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td2">Col1</td></tr>';
|
||||
var baseTr3 = '<tr><td id="tr3td1">Col1</td><td id="tr3td2">Col2</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
baseTable.append(baseTr3);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td1');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addRow(rng, 'top');
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td><br></td><td><br></td></tr>';
|
||||
var resultTr2 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var resultTr3 = '<tr><td id="tr2td2">Col1</td></tr>';
|
||||
var resultTr4 = '<tr><td id="tr3td1">Col1</td><td id="tr3td2">Col2</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
resultTable.append(resultTr3);
|
||||
resultTable.append(resultTr4);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add row on bottom rowspan cell and with aditional column.', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td2">Col1</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td1');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addRow(rng, 'bottom');
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td rowspan="3" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var resultTr2 = '<tr><td id="tr2td2">Col1</td></tr>';
|
||||
var resultTr3 = '<tr><td><br></td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
resultTable.append(resultTr3);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add column on right having rowspan cell and with aditional column.', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td2">Col1</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td2');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addCol(rng, 'right');
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td><td><br></td></tr>';
|
||||
var resultTr2 = '<tr><td id="tr2td2">Col1</td><td><br></td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add column on right having rowspan cell and with aditional column with focus on rowspan column.', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td><td id="tr1td2">Col2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td2">Col1</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td1');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addCol(rng, 'right');
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td rowspan="2" id="tr1td1">Col1-Span</td><td rowspan="2"><br></td><td id="tr1td2">Col2</td></tr>';
|
||||
var resultTr2 = '<tr><td id="tr2td2">Col1</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should remove column after colspan column.', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td id="tr1td1">Col1</td><td colspan="2" id="tr1td2">Col2-Span</td><td id="tr1td4">Col4</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td1">Col1</td><td id="tr2td2">Col2</td><td id="tr2td3">Col3</td><td id="tr2td4">Col4</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td4');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteCol(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td id="tr1td1">Col1</td><td colspan="2" id="tr1td2">Col2-Span</td></tr>';
|
||||
var resultTr2 = '<tr><td id="tr2td1">Col1</td><td id="tr2td2">Col2</td><td id="tr2td3">Col3</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should remove column before colspan column.', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td id="tr1td1">TR1TD1</td><td id="tr1td2" colspan="2">TR1TD2-COLSPAN</td>';
|
||||
baseTr1 += '<td id="tr1td4">TR1TD4</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td1">TR2TD1</td><td id="tr2td2">TR2TD2</td><td id="tr2td3">TR2TD3</td>';
|
||||
baseTr2 += '<td id="tr2td4">TR2TD4</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td1');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.deleteCol(rng);
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td id="tr1td2" colspan="2">TR1TD2-COLSPAN</td>';
|
||||
resultTr1 += '<td id="tr1td4">TR1TD4</td></tr>';
|
||||
var resultTr2 = '<tr><td id="tr2td2">TR2TD2</td><td id="tr2td3">TR2TD3</td><td id="tr2td4">TR2TD4</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
|
||||
it('should add column before colspan column.', () => {
|
||||
var baseTable = $('<table><tbody></tbody></table> ');
|
||||
var baseTr1 = '<tr><td id="tr1td1">TR1TD1</td><td id="tr1td2">TR1TD2</td></tr>';
|
||||
var baseTr2 = '<tr><td id="tr2td1" colspan="2">TR2TD1</td></tr>';
|
||||
baseTable.append(baseTr1);
|
||||
baseTable.append(baseTr2);
|
||||
var htmlContent = '<div class="note-editable"><table>' + $(baseTable).html() + '</table></div>';
|
||||
var $cont = $(htmlContent);
|
||||
|
||||
var $cell = $cont.find('#tr1td1');
|
||||
var rng = range.create($cell[0].firstChild, 1);
|
||||
table.addCol(rng, 'right');
|
||||
|
||||
var resultTable = $('<table><tbody></tbody></table> ');
|
||||
var resultTr1 = '<tr><td id="tr1td1">TR1TD1</td><td><br></td><td id="tr1td2">TR1TD2</td></tr>';
|
||||
var resultTr2 = '<tr><td id="tr2td1" colspan="3">TR2TD1</td></tr>';
|
||||
resultTable.append(resultTr1);
|
||||
resultTable.append(resultTr2);
|
||||
var expectedResult = '<table>' + $(resultTable).html() + '</table>';
|
||||
|
||||
expect(expectedResult).to.equalsIgnoreCase($cont.html());
|
||||
});
|
||||
});
|
||||
});
|
||||
73
public/vendor/editor/test/base/editing/Typing.spec.js
vendored
Executable file
73
public/vendor/editor/test/base/editing/Typing.spec.js
vendored
Executable file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Typing.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
/* jshint unused: false */
|
||||
/* jshint -W101 */
|
||||
import $ from 'jquery';
|
||||
import chai from 'chai';
|
||||
import chaidom from 'test/chaidom';
|
||||
import range from 'src/js/base/core/range';
|
||||
import Typing from 'src/js/base/editing/Typing';
|
||||
|
||||
var expect = chai.expect;
|
||||
chai.use(chaidom);
|
||||
|
||||
describe('base:editing.Style', () => {
|
||||
function typing(level) {
|
||||
return new Typing({ options: { blockquoteBreakingLevel: level } });
|
||||
}
|
||||
|
||||
describe('base:editing.Typing', () => {
|
||||
describe('insertParagraph', () => {
|
||||
describe('blockquote breaking support', () => {
|
||||
var $editable;
|
||||
|
||||
function check(html) {
|
||||
expect($editable.html()).to.equalsIgnoreCase(html);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
$editable = $('<div class="note-editable"><blockquote id="1">Part1<blockquote id="2">Part2.1<br>Part2.2</blockquote>Part3</blockquote></div>');
|
||||
});
|
||||
|
||||
it('should not break blockquote if blockquoteBreakingLevel=0', () => {
|
||||
typing(0).insertParagraph($editable, range.create($('#2', $editable)[0].firstChild, 1));
|
||||
|
||||
check('<blockquote id="1">Part1<blockquote id="2"><p>P</p><p>art2.1<br>Part2.2</p></blockquote>Part3</blockquote>');
|
||||
});
|
||||
|
||||
it('should break the first blockquote if blockquoteBreakingLevel=1', () => {
|
||||
typing(1).insertParagraph($editable, range.create($('#2', $editable)[0].firstChild, 1));
|
||||
|
||||
check('<blockquote id="1">Part1<blockquote id="2"><p>P</p></blockquote><p><br></p><blockquote id="2"><p>art2.1<br>Part2.2</p></blockquote>Part3</blockquote>');
|
||||
});
|
||||
|
||||
it('should break all blockquotes if blockquoteBreakingLevel=2', () => {
|
||||
typing(2).insertParagraph($editable, range.create($('#2', $editable)[0].firstChild, 1));
|
||||
|
||||
check('<blockquote id="1">Part1<blockquote id="2"><p>P</p></blockquote></blockquote><p><br></p><blockquote id="1"><blockquote id="2"><p>art2.1<br>Part2.2</p></blockquote>Part3</blockquote>');
|
||||
});
|
||||
|
||||
it('should remove leading BR from split, when breaking is on the right edge of a line', () => {
|
||||
typing(1).insertParagraph($editable, range.create($('#2', $editable)[0].firstChild, 7));
|
||||
|
||||
check('<blockquote id="1">Part1<blockquote id="2"><p>Part2.1</p></blockquote><p><br></p><blockquote id="2"><p>Part2.2</p></blockquote>Part3</blockquote>');
|
||||
});
|
||||
|
||||
it('should insert new paragraph after the blockquote, if break happens at the end of the blockquote', () => {
|
||||
typing(2).insertParagraph($editable, range.create($('#1', $editable)[0].lastChild, 5));
|
||||
|
||||
check('<blockquote id="1"><p>Part1<blockquote id="2">Part2.1<br>Part2.2</blockquote>Part3</p></blockquote><p><br></p>');
|
||||
});
|
||||
|
||||
it('should insert new paragraph before the blockquote, if break happens at the beginning of the blockquote', () => {
|
||||
typing(2).insertParagraph($editable, range.create($('#1', $editable)[0].firstChild, 0));
|
||||
|
||||
check('<p><br></p><blockquote id="1"><p>Part1<blockquote id="2">Part2.1<br>Part2.2</blockquote>Part3</p></blockquote>');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
92
public/vendor/editor/test/base/editing/style.spec.js
vendored
Executable file
92
public/vendor/editor/test/base/editing/style.spec.js
vendored
Executable file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Style.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
|
||||
import chai from 'chai';
|
||||
import $ from 'jquery';
|
||||
import range from 'src/js/base/core/range';
|
||||
import Style from 'src/js/base/editing/Style';
|
||||
|
||||
var expect = chai.expect;
|
||||
|
||||
describe('base:editing.Style', () => {
|
||||
var style = new Style();
|
||||
|
||||
describe('styleNodes', () => {
|
||||
it('should wrap selected text with span', () => {
|
||||
var $cont = $('<div class="note-editable"><p>text</p></div>');
|
||||
var $p = $cont.find('p');
|
||||
var rng = range.create($p[0].firstChild, 0, $p[0].firstChild, 4);
|
||||
style.styleNodes(rng);
|
||||
|
||||
expect($cont.html()).to.deep.equal('<p><span>text</span></p>');
|
||||
});
|
||||
|
||||
it('should split text and wrap selected text with span', () => {
|
||||
var $cont = $('<div class="note-editable"><p>text</p></div>');
|
||||
var $p = $cont.find('p');
|
||||
var rng = range.create($p[0].firstChild, 1, $p[0].firstChild, 3);
|
||||
style.styleNodes(rng);
|
||||
|
||||
expect($cont.html()).to.deep.equal('<p>t<span>ex</span>t</p>');
|
||||
});
|
||||
|
||||
it('should split text and insert span', () => {
|
||||
var $cont = $('<div class="note-editable"><p>text</p></div>');
|
||||
var $p = $cont.find('p');
|
||||
var rng = range.create($p[0].firstChild, 2, $p[0].firstChild, 2);
|
||||
style.styleNodes(rng);
|
||||
|
||||
expect($cont.html()).to.deep.equal('<p>te<span></span>xt</p>');
|
||||
});
|
||||
|
||||
it('should just return a parent span', () => {
|
||||
var $cont = $('<div class="note-editable"><p><span>text</span></p></div>');
|
||||
var $span = $cont.find('span');
|
||||
var rng = range.create($span[0].firstChild, 0, $span[0].firstChild, 4);
|
||||
style.styleNodes(rng);
|
||||
|
||||
expect($cont.html()).to.deep.equal('<p><span>text</span></p>');
|
||||
});
|
||||
|
||||
it('should wrap each texts with span', () => {
|
||||
var $cont = $('<div class="note-editable"><p><b>bold</b><span>span</span></p></div>');
|
||||
var $b = $cont.find('b');
|
||||
var $span = $cont.find('span');
|
||||
var rng = range.create($b[0].firstChild, 2, $span[0].firstChild, 2);
|
||||
style.styleNodes(rng);
|
||||
|
||||
expect($cont.html()).to.deep.equal('<p><b>bo<span>ld</span></b><span><span>sp</span>an</span></p>');
|
||||
});
|
||||
|
||||
it('should wrap each texts with span except not a single blood line', () => {
|
||||
var $cont = $('<div class="note-editable"><p><b>bold</b><span>span</span></p></div>');
|
||||
var $b = $cont.find('b');
|
||||
var $span = $cont.find('span');
|
||||
var rng = range.create($b[0].firstChild, 2, $span[0].firstChild, 4);
|
||||
style.styleNodes(rng);
|
||||
|
||||
expect($cont.html()).to.deep.equal('<p><b>bo<span>ld</span></b><span>span</span></p>');
|
||||
});
|
||||
|
||||
it('should expand b tag when providing the expandClosestSibling option', () => {
|
||||
var $cont = $('<div class="note-editable"><p>text<b>bold</b></p></div>');
|
||||
var $p = $cont.find('p');
|
||||
var rng = range.create($p[0].firstChild, 0, $p[0].firstChild, 4);
|
||||
style.styleNodes(rng, { nodeName: 'B', expandClosestSibling: true });
|
||||
|
||||
expect($cont.html()).to.deep.equal('<p><b>textbold</b></p>');
|
||||
});
|
||||
|
||||
it('should not expand b tag when providing the onlyPartialContains option', () => {
|
||||
var $cont = $('<div class="note-editable"><p>text<b>bold</b></p></div>');
|
||||
var $p = $cont.find('p');
|
||||
var rng = range.create($p[0].firstChild, 0, $p[0].firstChild, 4);
|
||||
style.styleNodes(rng, { nodeName: 'B', expandClosestSibling: true, onlyPartialContains: true });
|
||||
|
||||
expect($cont.html()).to.deep.equal('<p><b>text</b><b>bold</b></p>');
|
||||
});
|
||||
});
|
||||
});
|
||||
243
public/vendor/editor/test/base/module/Buttons.spec.js
vendored
Executable file
243
public/vendor/editor/test/base/module/Buttons.spec.js
vendored
Executable file
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* Buttons.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
|
||||
import $ from 'jquery';
|
||||
import chai from 'chai';
|
||||
import chaidom from 'test/chaidom';
|
||||
import env from 'src/js/base/core/env';
|
||||
import range from 'src/js/base/core/range';
|
||||
import Context from 'src/js/base/Context';
|
||||
import 'src/js/bs4/settings';
|
||||
|
||||
chai.use(chaidom);
|
||||
|
||||
describe('Buttons', () => {
|
||||
var expect = chai.expect;
|
||||
var assert = chai.assert;
|
||||
var context, $toolbar, $editable;
|
||||
|
||||
beforeEach(() => {
|
||||
$('body').empty(); // important !
|
||||
var $note = $('<div><p>hello</p></div>').appendTo('body');
|
||||
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.toolbar = [
|
||||
['font1', ['style', 'clear']],
|
||||
['font2', ['bold', 'underline', 'italic', 'superscript', 'subscript', 'strikethrough']],
|
||||
['font3', ['fontname', 'fontsize']],
|
||||
['color', ['color', 'forecolor', 'backcolor']],
|
||||
['para', ['ul', 'ol', 'paragraph']],
|
||||
['table', ['table']],
|
||||
['insert', ['link', 'picture', 'video']],
|
||||
['view', ['fullscreen', 'codeview', 'help']],
|
||||
];
|
||||
context = new Context($note, options);
|
||||
context.initialize();
|
||||
|
||||
$toolbar = context.layoutInfo.toolbar;
|
||||
$editable = context.layoutInfo.editable;
|
||||
|
||||
// Select the first paragraph
|
||||
range.createFromNode($editable.find('p')[0]).normalize().select();
|
||||
|
||||
// [workaround]
|
||||
// - IE8~11 can't create range in headless mode
|
||||
if (env.isMSIE) {
|
||||
this.skip();
|
||||
}
|
||||
});
|
||||
|
||||
describe('bold button', () => {
|
||||
it('should execute bold command when it is clicked', (done) => {
|
||||
$toolbar.find('.note-btn-bold').click();
|
||||
expect($editable.html()).await(done).to.equalsIgnoreCase('<p><b>hello</b></p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('bold button state updated', () => {
|
||||
it('should look toggled immediately when clicked', (done) => {
|
||||
var $button = $toolbar.find('.note-btn-bold');
|
||||
assert.isTrue($button.length === 1);
|
||||
assert.isFalse($button.hasClass('active'));
|
||||
$button.click();
|
||||
expect($button.hasClass('active')).await(done).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('italic button', () => {
|
||||
it('should execute italic command when it is clicked', (done) => {
|
||||
$toolbar.find('.note-btn-italic').click();
|
||||
expect($editable.html()).await(done).to.equalsIgnoreCase('<p><i>hello</i></p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('italic button state updated', () => {
|
||||
it('should look toggled immediately when clicked', (done) => {
|
||||
var $button = $toolbar.find('.note-btn-italic');
|
||||
assert.isTrue($button.length === 1);
|
||||
assert.isFalse($button.hasClass('active'));
|
||||
$button.click();
|
||||
expect($button.hasClass('active')).await(done).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('underline button', () => {
|
||||
it('should execute underline command when it is clicked', (done) => {
|
||||
$toolbar.find('.note-btn-underline').click();
|
||||
expect($editable.html()).await(done).to.equalsIgnoreCase('<p><u>hello</u></p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('underline button state updated', () => {
|
||||
it('should look toggled immediately when clicked', (done) => {
|
||||
var $button = $toolbar.find('.note-btn-underline');
|
||||
assert.isTrue($button.length === 1);
|
||||
assert.isFalse($button.hasClass('active'));
|
||||
$button.click();
|
||||
expect($button.hasClass('active')).await(done).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('superscript button', () => {
|
||||
it('should execute superscript command when it is clicked', (done) => {
|
||||
$toolbar.find('.note-btn-superscript').click();
|
||||
expect($editable.html()).await(done).to.equalsIgnoreCase('<p><sup>hello</sup></p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('superscript button state updated', () => {
|
||||
it('should look toggled immediately when clicked', (done) => {
|
||||
var $button = $toolbar.find('.note-btn-superscript');
|
||||
assert.isTrue($button.length === 1);
|
||||
assert.isFalse($button.hasClass('active'));
|
||||
$button.click();
|
||||
expect($button.hasClass('active')).await(done).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('subscript button', () => {
|
||||
it('should execute subscript command when it is clicked', (done) => {
|
||||
$toolbar.find('.note-btn-subscript').click();
|
||||
expect($editable.html()).await(done).to.equalsIgnoreCase('<p><sub>hello</sub></p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('subscript button state updated', () => {
|
||||
it('should look toggled immediately when clicked', (done) => {
|
||||
var $button = $toolbar.find('.note-btn-subscript');
|
||||
assert.isTrue($button.length === 1);
|
||||
assert.isFalse($button.hasClass('active'));
|
||||
$button.click();
|
||||
expect($button.hasClass('active')).await(done).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('strikethrough button', () => {
|
||||
it('should execute strikethrough command when it is clicked', (done) => {
|
||||
$toolbar.find('.note-btn-strikethrough').click();
|
||||
expect($editable.html()).await(done).to.equalsIgnoreCase('<p><strike>hello</strike></p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('strikethrough button state updated', () => {
|
||||
it('should look toggled immediately when clicked', (done) => {
|
||||
var $button = $toolbar.find('.note-btn-strikethrough');
|
||||
assert.isTrue($button.length === 1);
|
||||
assert.isFalse($button.hasClass('active'));
|
||||
$button.click();
|
||||
expect($button.hasClass('active')).await(done).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('clear button state not updated when clicked', () => {
|
||||
it('should never look toggled when clicked', (done) => {
|
||||
var $button = $toolbar.find('i.note-icon-eraser').parent();
|
||||
assert.isTrue($button.length === 1);
|
||||
assert.isFalse($button.hasClass('active'));
|
||||
$button.click();
|
||||
expect($button.hasClass('active')).await(done).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
/* Below test cannot be passed under Firefox
|
||||
describe('font family button', () => {
|
||||
it('should select the right font family name in the dropdown list when it is clicked', (done) => {
|
||||
var $li = $toolbar.find('.dropdown-fontname a[data-value="Comic Sans MS"]');
|
||||
var $span = $toolbar.find('span.note-current-fontname');
|
||||
assert.isTrue($li.length === 1);
|
||||
assert.isTrue($span.text() !== 'Comic Sans MS');
|
||||
$li.click();
|
||||
expect($span.text()).await(done).to.equalsIgnoreCase('Comic Sans MS');
|
||||
});
|
||||
});
|
||||
*/
|
||||
|
||||
describe('font family button', () => {
|
||||
it('should change font family when it is clicked', (done) => {
|
||||
var $li = $toolbar.find('.dropdown-fontname a[data-value="Comic Sans MS"]');
|
||||
var $span = $toolbar.find('span.note-current-fontname');
|
||||
assert.isTrue($li.length === 1);
|
||||
assert.isTrue($span.text() !== 'Comic Sans MS');
|
||||
$li.click();
|
||||
expect($editable.find('p').children().first()).await(done).to.be.equalsStyle('"Comic Sans MS"', 'font-family');
|
||||
});
|
||||
});
|
||||
|
||||
describe('recent color button in all color button', () => {
|
||||
it('should execute color command when it is clicked', (done) => {
|
||||
$toolbar.find('.note-color-all').find('.note-current-color-button').click();
|
||||
expect($editable.find('p').children().first()).await(done).to.be.equalsStyle('#FFFF00', 'background-color');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fore color button in all color button', () => {
|
||||
it('should execute fore color command when it is clicked', (done) => {
|
||||
var $button = $toolbar.find('.note-color-all .note-holder').find('.note-color-btn[data-event=foreColor]').eq(10);
|
||||
$button.click();
|
||||
expect($editable.find('p').children().first()).await(done).to.be.equalsStyle($button.data('value'), 'color');
|
||||
});
|
||||
});
|
||||
|
||||
describe('back color button in all color button', () => {
|
||||
it('should execute back color command when it is clicked', (done) => {
|
||||
var $button = $toolbar.find('.note-color-all .note-holder').find('.note-color-btn[data-event=backColor]').eq(10);
|
||||
$button.click();
|
||||
expect($editable.find('p').children().first()).await(done).to.be.equalsStyle($button.data('value'), 'background-color');
|
||||
});
|
||||
});
|
||||
|
||||
describe('color button in fore color button', () => {
|
||||
it('should execute fore color command when it is clicked', (done) => {
|
||||
var $button = $toolbar.find('.note-color-fore').find('.note-color-btn[data-event=foreColor]').eq(4);
|
||||
$button.click();
|
||||
expect($editable.find('p').children().first()).await(done).to.be.equalsStyle($button.data('value'), 'color');
|
||||
});
|
||||
});
|
||||
|
||||
describe('back color button in back color button', () => {
|
||||
it('should execute back color command when it is clicked', (done) => {
|
||||
var $button = $toolbar.find('.note-color-back').find('.note-color-btn[data-event=backColor]').eq(20);
|
||||
$button.click();
|
||||
expect($editable.find('p').children().first()).await(done).to.be.equalsStyle($button.data('value'), 'background-color');
|
||||
});
|
||||
});
|
||||
|
||||
describe('font size button', () => {
|
||||
it('should update font size button value when changing font size', (done) => {
|
||||
var $fontSizeDropdown = $toolbar.find('.dropdown-fontsize');
|
||||
var $fontSizeButton = $fontSizeDropdown.siblings('button');
|
||||
var $fontSizeList = $fontSizeDropdown.find('a');
|
||||
var selectedSize = '36';
|
||||
|
||||
// click on dropdown button
|
||||
$fontSizeButton.trigger('click');
|
||||
// select a font size
|
||||
$fontSizeList.filter('[data-value="' + selectedSize + '"]').trigger('click');
|
||||
|
||||
expect($fontSizeButton.text().trim()).await(done).to.equal(selectedSize);
|
||||
});
|
||||
});
|
||||
});
|
||||
67
public/vendor/editor/test/base/module/Codeview.spec.js
vendored
Executable file
67
public/vendor/editor/test/base/module/Codeview.spec.js
vendored
Executable file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Codeview.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import chai from 'chai';
|
||||
import chaidom from 'test/chaidom';
|
||||
import Context from 'src/js/base/Context';
|
||||
import Codeview from 'src/js/base/module/Codeview';
|
||||
import 'src/js/bs4/settings';
|
||||
|
||||
chai.use(chaidom);
|
||||
|
||||
describe('Codeview', () => {
|
||||
var expect = chai.expect;
|
||||
var options, codeview, context;
|
||||
|
||||
beforeEach(() => {
|
||||
options = $.extend({}, $.summernote.options);
|
||||
options.codeviewFilter = true;
|
||||
context = new Context($('<div><p>hello</p></div>'), options);
|
||||
codeview = new Codeview(context);
|
||||
});
|
||||
|
||||
it('should toggle codeview mode', () => {
|
||||
expect(codeview.isActivated()).to.be.false;
|
||||
codeview.toggle();
|
||||
expect(codeview.isActivated()).to.be.true;
|
||||
codeview.toggle();
|
||||
expect(codeview.isActivated()).to.be.false;
|
||||
});
|
||||
|
||||
it('should purify malicious codes', () => {
|
||||
expect(codeview.purify('<script>alert("summernote");</script>')).to.equalsIgnoreCase(
|
||||
'alert("summernote");'
|
||||
);
|
||||
expect(codeview.purify('<iframe frameborder="0" src="//www.youtube.com/embed/CXgsA98krxA" width="640" height="360" class="note-video-clip"></iframe>')).to.equalsIgnoreCase(
|
||||
'<iframe frameborder="0" src="//www.youtube.com/embed/CXgsA98krxA" width="640" height="360" class="note-video-clip"></iframe>'
|
||||
);
|
||||
expect(codeview.purify('<iframe frameborder="0" src="//wwwXyoutube.com/embed/CXgsA98krxA" width="640" height="360" class="note-video-clip">')).to.equalsIgnoreCase(
|
||||
''
|
||||
);
|
||||
expect(codeview.purify('<iframe frameborder="0" src="//www.fake-youtube.com/embed/CXgsA98krxA" width="640" height="360" class="note-video-clip">')).to.equalsIgnoreCase(
|
||||
''
|
||||
);
|
||||
expect(codeview.purify('<iframe frameborder="0" src="//www.youtube.com/embed/CXgsA98krxA" width="640" height="360" class="note-video-clip" src = "//www.fake-youtube.com/embed/CXgsA98krxA"/>')).to.equalsIgnoreCase(
|
||||
''
|
||||
);
|
||||
});
|
||||
|
||||
it('should purify can be customized', () => {
|
||||
codeview.options = options;
|
||||
codeview.options.codeviewIframeFilter = false;
|
||||
expect(codeview.purify('<iframe frameborder="0" src="//www.fake-youtube.com/embed/CXgsA98krxA" width="640" height="360" class="note-video-clip">')).to.equalsIgnoreCase(
|
||||
'<iframe frameborder="0" src="//www.fake-youtube.com/embed/CXgsA98krxA" width="640" height="360" class="note-video-clip">'
|
||||
);
|
||||
codeview.options = options;
|
||||
codeview.options.codeviewFilterRegex = /\d+/;
|
||||
expect(codeview.purify('<script>alert("summernote");</script>')).to.equalsIgnoreCase(
|
||||
'<script>alert("summernote");</script>'
|
||||
);
|
||||
expect(codeview.purify('<span>Tel: 012345678</span>')).to.equalsIgnoreCase(
|
||||
'<span>Tel: </span>'
|
||||
);
|
||||
});
|
||||
});
|
||||
557
public/vendor/editor/test/base/module/Editor.spec.js
vendored
Executable file
557
public/vendor/editor/test/base/module/Editor.spec.js
vendored
Executable file
@@ -0,0 +1,557 @@
|
||||
/**
|
||||
* Editor.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
|
||||
import chai from 'chai';
|
||||
import spies from 'chai-spies';
|
||||
import chaidom from 'test/chaidom';
|
||||
import $ from 'jquery';
|
||||
import env from 'src/js/base/core/env';
|
||||
import range from 'src/js/base/core/range';
|
||||
import Context from 'src/js/base/Context';
|
||||
import 'src/js/bs4/settings';
|
||||
|
||||
describe('Editor', () => {
|
||||
var expect = chai.expect;
|
||||
chai.use(spies);
|
||||
chai.use(chaidom);
|
||||
|
||||
var editor, context, $editable;
|
||||
|
||||
function expectContents(context, markup) {
|
||||
expect(context.layoutInfo.editable.html()).to.equalsIgnoreCase(markup);
|
||||
}
|
||||
|
||||
function expectContentsChain(context, markup, next) {
|
||||
setTimeout(() => {
|
||||
expect(context.layoutInfo.editable.html()).to.equalsIgnoreCase(markup);
|
||||
next();
|
||||
}, 10);
|
||||
}
|
||||
|
||||
function expectContentsAwait(context, markup, done) {
|
||||
expect(context.layoutInfo.editable.html()).await(done).to.equalsIgnoreCase(markup);
|
||||
}
|
||||
|
||||
function expectToHaveBeenCalled(context, customEvent, handler) {
|
||||
const $note = context.layoutInfo.note;
|
||||
const spy = chai.spy();
|
||||
$note.on(customEvent, spy);
|
||||
handler();
|
||||
expect(spy).to.have.been.called();
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
$('body').empty(); // important !
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.historyLimit = 5;
|
||||
context = new Context($('<div><p>hello</p></div>'), options);
|
||||
|
||||
editor = context.modules.editor;
|
||||
$editable = context.layoutInfo.editable;
|
||||
|
||||
// [workaround]
|
||||
// - IE8-11 can't create range in headless mode
|
||||
if (env.isMSIE) {
|
||||
this.skip();
|
||||
}
|
||||
});
|
||||
|
||||
describe('initialize', () => {
|
||||
it('should bind custom events', (done) => {
|
||||
[
|
||||
'keydown', 'keyup', 'blur', 'mousedown', 'mouseup', 'scroll', 'focusin', 'focusout',
|
||||
].forEach((eventName) => {
|
||||
expectToHaveBeenCalled(context, 'summernote.' + eventName, () => {
|
||||
$editable.trigger(eventName);
|
||||
});
|
||||
});
|
||||
|
||||
expectToHaveBeenCalled(context, 'summernote.change', () => {
|
||||
editor.insertText('hello');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('undo and redo', () => {
|
||||
it('should control history', (done) => {
|
||||
editor.insertText(' world');
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello world</p>');
|
||||
editor.undo();
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello</p>');
|
||||
editor.redo();
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello world</p>');
|
||||
done();
|
||||
}, 10);
|
||||
}, 10);
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it('should be limited by option.historyLimit value', (done) => {
|
||||
editor.insertText(' world');
|
||||
editor.insertText(' world');
|
||||
editor.insertText(' world');
|
||||
editor.insertText(' world');
|
||||
editor.insertText(' world');
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello world world world world world</p>');
|
||||
editor.undo();
|
||||
editor.undo();
|
||||
editor.undo();
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello world world</p>');
|
||||
editor.undo();
|
||||
editor.undo();
|
||||
editor.undo();
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello world</p>');
|
||||
done();
|
||||
}, 10);
|
||||
}, 10);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tab', () => {
|
||||
it('should insert tab', (done) => {
|
||||
editor.tab();
|
||||
expectContentsAwait(context, '<p>hello </p>', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('insertParagraph', () => {
|
||||
it('should insert paragraph', (done) => {
|
||||
editor.insertParagraph();
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello</p><p><br></p>');
|
||||
editor.insertParagraph();
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello</p><p><br></p><p><br></p>');
|
||||
done();
|
||||
}, 10);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('insertImage', () => {
|
||||
it('should insert image', () => {
|
||||
var source = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAF0lEQVQYGWP8////fwYsgAmLGFiIHhIAT+oECGHuN2UAAAAASUVORK5CYII=';
|
||||
return editor.insertImage(source, 'image').then(() => {
|
||||
expect($editable.find('img').attr('src')).to.equalsIgnoreCase(source);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('insertOrderedList and insertUnorderedList', () => {
|
||||
it('should toggle paragraph to list', (done) => {
|
||||
editor.insertOrderedList();
|
||||
expectContentsChain(context, '<ol><li>hello</li></ol>', () => {
|
||||
editor.insertUnorderedList();
|
||||
expectContentsChain(context, '<ul><li>hello</li></ul>', () => {
|
||||
editor.insertUnorderedList();
|
||||
expectContentsChain(context, '<p>hello</p>', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('indent and outdent', () => {
|
||||
// [workaround] style is different by browser
|
||||
it('should indent and outdent paragraph', (done) => {
|
||||
editor.indent();
|
||||
expectContentsChain(context, '<p style="margin-left: 25px;">hello</p>', () => {
|
||||
editor.outdent();
|
||||
expect($editable.find('p').css('margin-left')).await(done).to.be.empty;
|
||||
});
|
||||
});
|
||||
|
||||
it('should indent and outdent list', (done) => {
|
||||
editor.insertOrderedList();
|
||||
expectContentsChain(context, '<ol><li>hello</li></ol>', () => {
|
||||
editor.indent();
|
||||
expectContentsChain(context, '<ol><li><ol><li>hello</li></ol></li></ol>', () => {
|
||||
editor.indent();
|
||||
expectContentsChain(context, '<ol><li><ol><li><ol><li>hello</li></ol></li></ol></li></ol>', () => {
|
||||
editor.outdent();
|
||||
expectContentsChain(context, '<ol><li><ol><li>hello</li></ol></li></ol>', () => {
|
||||
editor.outdent();
|
||||
expectContentsChain(context, '<ol><li>hello</li></ol>', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('setLastRange', () => {
|
||||
it('should set last range', (done) => {
|
||||
document.body.click();
|
||||
editor.setLastRange();
|
||||
|
||||
expect(editor.lastRange.sc).await(done).to.equal(editor.editable.lastChild);
|
||||
});
|
||||
|
||||
it('should set last range without content', (done) => {
|
||||
context.layoutInfo.editable.html('');
|
||||
document.body.click();
|
||||
editor.setLastRange();
|
||||
|
||||
expect(editor.lastRange.sc).await(done).to.equal(editor.editable);
|
||||
});
|
||||
});
|
||||
|
||||
describe('insertNode', () => {
|
||||
it('should insert node', (done) => {
|
||||
editor.insertNode($('<span> world</span>')[0]);
|
||||
expectContentsAwait(context, '<p>hello<span> world</span></p>', done);
|
||||
});
|
||||
|
||||
it('should be limited', (done) => {
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.maxTextLength = 5;
|
||||
context = new Context($('<div><p>hello</p></div>'), options);
|
||||
editor = context.modules.editor;
|
||||
|
||||
editor.insertNode($('<span> world</span>')[0]);
|
||||
expectContentsAwait(context, '<p>hello</p>', done);
|
||||
});
|
||||
|
||||
it('should insert node in last focus', (done) => {
|
||||
$editable.appendTo('body');
|
||||
context.invoke('editor.focus');
|
||||
|
||||
setTimeout(() => {
|
||||
var textNode = $editable.find('p')[0].firstChild;
|
||||
editor.setLastRange(range.create(textNode, 0, textNode, 0).select());
|
||||
|
||||
setTimeout(() => {
|
||||
editor.insertNode($('<span> world</span>')[0]);
|
||||
setTimeout(() => {
|
||||
$('body').focus();
|
||||
editor.insertNode($('<span> hello</span>')[0]);
|
||||
setTimeout(() => {
|
||||
expectContentsAwait(context, '<p><span> world</span><span> hello</span>hello</p>', done);
|
||||
}, 10);
|
||||
}, 10);
|
||||
}, 10);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('insertText', () => {
|
||||
it('should insert text', (done) => {
|
||||
editor.insertText(' world');
|
||||
expectContentsAwait(context, '<p>hello world</p>', done);
|
||||
});
|
||||
|
||||
it('should be limited', (done) => {
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.maxTextLength = 5;
|
||||
context = new Context($('<div><p>hello</p></div>'), options);
|
||||
editor = context.modules.editor;
|
||||
|
||||
editor.insertText(' world');
|
||||
expectContentsAwait(context, '<p>hello</p>', done);
|
||||
});
|
||||
|
||||
it('should insert text in last focus', (done) => {
|
||||
$editable.appendTo('body');
|
||||
context.invoke('editor.focus');
|
||||
|
||||
var textNode = $editable.find('p')[0].firstChild;
|
||||
editor.setLastRange(range.create(textNode, 0, textNode, 0).select());
|
||||
|
||||
setTimeout(() => {
|
||||
editor.insertText(' world');
|
||||
setTimeout(() => {
|
||||
$('body').focus();
|
||||
setTimeout(() => {
|
||||
editor.insertText(' summernote');
|
||||
setTimeout(() => {
|
||||
expectContentsAwait(context, '<p> world summernotehello</p>', done);
|
||||
}, 10);
|
||||
}, 10);
|
||||
}, 10);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('pasteHTML', () => {
|
||||
it('should paste html', (done) => {
|
||||
editor.pasteHTML('<span> world</span>');
|
||||
expectContentsAwait(context, '<p>hello<span> world</span></p>', done);
|
||||
});
|
||||
|
||||
it('should not call change change event more than once per paste event', () => {
|
||||
var generateLargeHtml = () => {
|
||||
var html = '<div>';
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
html += '<p>HTML element #' + i + '</p>';
|
||||
}
|
||||
html += '</div>';
|
||||
return html;
|
||||
};
|
||||
var $note = context.layoutInfo.note;
|
||||
var spy = chai.spy();
|
||||
$note.on('summernote.change', spy);
|
||||
var html = generateLargeHtml();
|
||||
editor.pasteHTML(html);
|
||||
expect(spy).to.have.been.called.once;
|
||||
});
|
||||
|
||||
it('should be limited', (done) => {
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.maxTextLength = 5;
|
||||
context = new Context($('<div><p>hello</p></div>'), options);
|
||||
editor = context.modules.editor;
|
||||
|
||||
editor.pasteHTML('<span> world</span>');
|
||||
expectContentsAwait(context, '<p>hello</p>', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('insertHorizontalRule', () => {
|
||||
it('should insert horizontal rule', (done) => {
|
||||
editor.insertHorizontalRule();
|
||||
expectContentsAwait(context, '<p>hello</p><hr><p><br></p>', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('insertTable', () => {
|
||||
it('should insert table', (done) => {
|
||||
var markup = [
|
||||
'<p>hello</p>',
|
||||
'<table class="table table-bordered"><tbody>',
|
||||
'<tr><td><br></td><td><br></td></tr>',
|
||||
'<tr><td><br></td><td><br></td></tr>',
|
||||
'</tbody></table>',
|
||||
'<p><br></p>',
|
||||
].join('');
|
||||
editor.insertTable('2x2');
|
||||
expectContentsAwait(context, markup, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('empty', () => {
|
||||
it('should make contents empty', (done) => {
|
||||
editor.empty();
|
||||
expect(editor.isEmpty()).await(done).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('styleWithCSS', () => {
|
||||
it('should style with tag when it is false (default)', (done) => {
|
||||
$editable.appendTo('body');
|
||||
range.createFromNode($editable.find('p')[0]).normalize().select();
|
||||
editor.bold();
|
||||
expectContentsAwait(context, '<p><b>hello</b></p>', done);
|
||||
});
|
||||
|
||||
it('should style with CSS when it is true', (done) => {
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.styleWithCSS = true;
|
||||
|
||||
$('body').empty();
|
||||
context = new Context($('<div><p>hello</p></div>').appendTo('body'), options);
|
||||
editor = context.modules.editor;
|
||||
$editable = context.layoutInfo.editable;
|
||||
$editable.appendTo('body');
|
||||
|
||||
range.createFromNode($editable.find('p')[0]).normalize().select();
|
||||
editor.bold();
|
||||
expectContentsAwait(context, '<p><span style="font-weight: bold;">hello</span></p>', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatBlock', () => {
|
||||
it('should apply formatBlock', (done) => {
|
||||
$editable.appendTo('body');
|
||||
|
||||
var textNode = $editable.find('p')[0].firstChild;
|
||||
editor.setLastRange(range.create(textNode, 0, textNode, 0).select());
|
||||
|
||||
setTimeout(() => {
|
||||
editor.formatBlock('h1');
|
||||
expectContentsAwait(context, '<h1>hello</h1>', done);
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it('should apply multi formatBlock', (done) => {
|
||||
var codes = [
|
||||
'<p><a href="http://summernote.org">hello world</a></p>',
|
||||
'<p><a href="http://summernote.org">hello world</a></p>',
|
||||
'<p><a href="http://summernote.org">hello world</a></p>',
|
||||
];
|
||||
|
||||
context.invoke('code', codes.join(''));
|
||||
$editable.appendTo('body');
|
||||
|
||||
var startNode = $editable.find('p').first()[0];
|
||||
var endNode = $editable.find('p').last()[0];
|
||||
|
||||
// all p tags is wrapped
|
||||
range.create(startNode, 0, endNode, 1).normalize().select();
|
||||
|
||||
editor.formatBlock('h3');
|
||||
|
||||
var nodeName = $editable.children()[0].nodeName;
|
||||
expect(nodeName).to.equalsIgnoreCase('h3');
|
||||
|
||||
// p -> h3, p is none
|
||||
expect($editable.find('p').length).await(done).to.equals(0);
|
||||
});
|
||||
|
||||
it('should apply custom className in formatBlock', (done) => {
|
||||
var $target = $('<h4 class="customH4Class" />');
|
||||
$editable.appendTo('body');
|
||||
range.createFromNode($editable.find('p')[0]).normalize().select();
|
||||
editor.formatBlock('h4', $target);
|
||||
|
||||
// start <p>hello</p> => <h4 class="h4">hello</h4>
|
||||
expectContentsAwait(context, '<h4 class="customH4Class">hello</h4>', done);
|
||||
});
|
||||
|
||||
it('should find exact target in formatBlock', (done) => {
|
||||
var $target = $('<a class="dropdown-item" href="#" data-value="h6" role="listitem" aria-label="h6"><h6 class="customH6Class">H6</h6></a>');
|
||||
$editable.appendTo('body');
|
||||
range.createFromNode($editable.find('p')[0]).normalize().select();
|
||||
editor.formatBlock('h6', $target);
|
||||
|
||||
// start <p>hello</p> => <h6 class="h6">hello</h6>
|
||||
expectContentsAwait(context, '<h6 class="customH6Class">hello</h6>', done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createLink', () => {
|
||||
it('should create normal link', (done) => {
|
||||
var text = 'hello';
|
||||
var pNode = $editable.find('p')[0];
|
||||
var textNode = pNode.childNodes[0];
|
||||
var startIndex = textNode.wholeText.indexOf(text);
|
||||
var endIndex = startIndex + text.length;
|
||||
|
||||
range.create(textNode, startIndex, textNode, endIndex).normalize().select();
|
||||
|
||||
// check creation normal link
|
||||
editor.createLink({
|
||||
url: 'http://summernote.org',
|
||||
text: 'summernote',
|
||||
});
|
||||
|
||||
expectContentsAwait(context, '<p>hello<a href="http://summernote.org">summernote</a></p>', done);
|
||||
});
|
||||
|
||||
it('should create a link with range', (done) => {
|
||||
var text = 'hello';
|
||||
var pNode = $editable.find('p')[0];
|
||||
var textNode = pNode.childNodes[0];
|
||||
var startIndex = textNode.wholeText.indexOf(text);
|
||||
var endIndex = startIndex + text.length;
|
||||
|
||||
var rng = range.create(textNode, startIndex, textNode, endIndex);
|
||||
|
||||
editor.createLink({
|
||||
url: 'http://summernote.org',
|
||||
text: 'summernote',
|
||||
range: rng,
|
||||
});
|
||||
|
||||
expectContentsAwait(context, '<p><a href="http://summernote.org">summernote</a></p>', done);
|
||||
});
|
||||
|
||||
it('should create a link with isNewWindow', (done) => {
|
||||
var text = 'hello';
|
||||
var pNode = $editable.find('p')[0];
|
||||
var textNode = pNode.childNodes[0];
|
||||
var startIndex = textNode.wholeText.indexOf(text);
|
||||
var endIndex = startIndex + text.length;
|
||||
|
||||
var rng = range.create(textNode, startIndex, textNode, endIndex);
|
||||
|
||||
editor.createLink({
|
||||
url: 'http://summernote.org',
|
||||
text: 'summernote',
|
||||
range: rng,
|
||||
isNewWindow: true,
|
||||
});
|
||||
|
||||
expectContentsAwait(context, '<p><a href="http://summernote.org" target="_blank">summernote</a></p>', done);
|
||||
});
|
||||
|
||||
it('should create a relative link without scheme', (done) => {
|
||||
var text = 'hello';
|
||||
var pNode = $editable.find('p')[0];
|
||||
var textNode = pNode.childNodes[0];
|
||||
var startIndex = textNode.wholeText.indexOf(text);
|
||||
var endIndex = startIndex + text.length;
|
||||
|
||||
var rng = range.create(textNode, startIndex, textNode, endIndex);
|
||||
|
||||
editor.createLink({
|
||||
url: '/relative/url',
|
||||
text: 'summernote',
|
||||
range: rng,
|
||||
isNewWindow: true,
|
||||
});
|
||||
|
||||
expectContentsAwait(context, '<p><a href="/relative/url" target="_blank">summernote</a></p>', done);
|
||||
});
|
||||
|
||||
it('should modify a link', (done) => {
|
||||
context.invoke('code', '<p><a href="http://summernote.org">hello world</a></p>');
|
||||
|
||||
var anchorNode = $editable.find('a')[0];
|
||||
var rng = range.createFromNode(anchorNode);
|
||||
|
||||
editor.createLink({
|
||||
url: 'http://wow.summernote.org',
|
||||
text: 'summernote wow',
|
||||
range: rng,
|
||||
});
|
||||
|
||||
expectContentsAwait(context, '<p><a href="http://wow.summernote.org">summernote wow</a></p>', done);
|
||||
});
|
||||
|
||||
it('should be limited when creating a link', (done) => {
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.maxTextLength = 5;
|
||||
context = new Context($('<div><p>hello</p></div>'), options);
|
||||
editor = context.modules.editor;
|
||||
|
||||
editor.createLink({
|
||||
url: 'http://summernote.org',
|
||||
text: 'summernote',
|
||||
});
|
||||
expectContentsAwait(context, '<p>hello</p>', done);
|
||||
});
|
||||
|
||||
it('should be limited when modifying a link', (done) => {
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.maxTextLength = 5;
|
||||
context = new Context($('<p><a href="http://summernote.org">hello</a></p>'), options);
|
||||
|
||||
var editable = context.layoutInfo.editable;
|
||||
var anchorNode = editable.find('a')[0];
|
||||
var rng = range.createFromNode(anchorNode);
|
||||
editor = context.modules.editor;
|
||||
|
||||
editor.createLink({
|
||||
url: 'http://summernote.org',
|
||||
text: 'hello world',
|
||||
range: rng,
|
||||
});
|
||||
|
||||
expectContentsAwait(context, '<a href="http://summernote.org">hello</a>', done);
|
||||
});
|
||||
});
|
||||
});
|
||||
30
public/vendor/editor/test/base/module/Fullscreen.spec.js
vendored
Executable file
30
public/vendor/editor/test/base/module/Fullscreen.spec.js
vendored
Executable file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Fullscreen.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
|
||||
import chai from 'chai';
|
||||
import $ from 'jquery';
|
||||
import Context from 'src/js/base/Context';
|
||||
import Fullscreen from 'src/js/base/module/Fullscreen';
|
||||
import 'src/js/bs4/settings';
|
||||
|
||||
describe('Fullscreen', () => {
|
||||
var expect = chai.expect;
|
||||
var fullscreen, context;
|
||||
|
||||
beforeEach(() => {
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
context = new Context($('<div><p>hello</p></div>'), options);
|
||||
fullscreen = new Fullscreen(context);
|
||||
});
|
||||
|
||||
it('should toggle fullscreen mode', () => {
|
||||
expect(fullscreen.isFullscreen()).to.be.false;
|
||||
fullscreen.toggle();
|
||||
expect(fullscreen.isFullscreen()).to.be.true;
|
||||
fullscreen.toggle();
|
||||
expect(fullscreen.isFullscreen()).to.be.false;
|
||||
});
|
||||
});
|
||||
221
public/vendor/editor/test/base/module/HintPopover.spec.js
vendored
Executable file
221
public/vendor/editor/test/base/module/HintPopover.spec.js
vendored
Executable file
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
* HintPopover.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import chai from 'chai';
|
||||
import chaidom from 'test/chaidom';
|
||||
import Context from 'src/js/base/Context';
|
||||
import range from 'src/js/base/core/range';
|
||||
import env from 'src/js/base/core/env';
|
||||
import key from 'src/js/base/core/key';
|
||||
import 'src/js/bs4/settings';
|
||||
|
||||
chai.use(chaidom);
|
||||
|
||||
describe('HintPopover', () => {
|
||||
var expect = chai.expect;
|
||||
var $note, editor, context, $editable;
|
||||
|
||||
function expectContents(context, markup) {
|
||||
expect(context.layoutInfo.editable.html()).to.equalsIgnoreCase(markup);
|
||||
}
|
||||
|
||||
describe('Single word hint', () => {
|
||||
beforeEach(function() {
|
||||
$('body').empty(); // important !
|
||||
$note = $('<div><p>hello world</p></div>');
|
||||
$note.appendTo('body');
|
||||
|
||||
var options = $.extend({}, $.summernote.options, {
|
||||
hint: {
|
||||
mentions: ['jayden', 'sam', 'alvin', 'david'],
|
||||
match: /\B#(\w*)$/,
|
||||
search: function(keyword, callback) {
|
||||
callback($.grep(this.mentions, function(item) {
|
||||
return item.indexOf(keyword) === 0;
|
||||
}));
|
||||
},
|
||||
content: function(item) {
|
||||
return '#' + item;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
context = new Context($note, options);
|
||||
editor = context.modules.editor;
|
||||
$editable = context.layoutInfo.editable;
|
||||
|
||||
// [workaround]
|
||||
// - Safari does not popup hintpopover
|
||||
// - IE8-11 can't create range in headless mode
|
||||
if (env.isMSIE || env.isSafari) {
|
||||
this.skip();
|
||||
}
|
||||
});
|
||||
|
||||
it('should not be shown without matches', () => {
|
||||
$editable.keyup();
|
||||
expect($('.note-hint-popover').css('display')).to.equals('none');
|
||||
});
|
||||
|
||||
it('should be shown when it matches the given condition', (done) => {
|
||||
var textNode = $editable.find('p')[0].firstChild;
|
||||
editor.setLastRange(range.create(textNode, 5, textNode, 5).select());
|
||||
editor.insertText(' #');
|
||||
$editable.keyup();
|
||||
|
||||
setTimeout(() => {
|
||||
expect($('.note-hint-popover').css('display')).to.equals('block');
|
||||
done();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it('should select the best matched item with the given condition', (done) => {
|
||||
var textNode = $editable.find('p')[0].firstChild;
|
||||
editor.setLastRange(range.create(textNode, 5, textNode, 5).select());
|
||||
editor.insertText(' #al');
|
||||
$editable.keyup();
|
||||
|
||||
setTimeout(() => {
|
||||
// alvin should be activated
|
||||
const item = $('.note-hint-popover').find('.note-hint-item');
|
||||
expect(item.text()).to.equals('alvin');
|
||||
expect(item.hasClass('active')).to.be.true;
|
||||
done();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it('should be replaced with the selected hint', (done) => {
|
||||
var textNode = $editable.find('p')[0].firstChild;
|
||||
editor.setLastRange(range.create(textNode, 5, textNode, 5).select());
|
||||
editor.insertText(' #');
|
||||
$editable.keyup();
|
||||
|
||||
setTimeout(() => {
|
||||
var e = $.Event('keydown');
|
||||
e.keyCode = key.code.ENTER;
|
||||
$note.trigger('summernote.keydown', e);
|
||||
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello #jayden world</p>');
|
||||
done();
|
||||
}, 10);
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it('should move selection by pressing arrow key', (done) => {
|
||||
var textNode = $editable.find('p')[0].firstChild;
|
||||
editor.setLastRange(range.create(textNode, 5, textNode, 5).select());
|
||||
editor.insertText(' #');
|
||||
$editable.keyup();
|
||||
|
||||
setTimeout(() => {
|
||||
var e = $.Event('keydown');
|
||||
e.keyCode = key.code.DOWN;
|
||||
$note.trigger('summernote.keydown', e);
|
||||
e.keyCode = key.code.ENTER;
|
||||
$note.trigger('summernote.keydown', e);
|
||||
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello #sam world</p>');
|
||||
done();
|
||||
}, 10);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Multiple words hint', () => {
|
||||
beforeEach(function() {
|
||||
$('body').empty();
|
||||
$note = $('<div><p>hello world</p></div>');
|
||||
$note.appendTo('body');
|
||||
|
||||
var options = $.extend({}, $.summernote.options, {
|
||||
hintMode: 'words',
|
||||
hintSelect: 'next',
|
||||
hint: {
|
||||
mentions: [
|
||||
{
|
||||
name: 'Jayden Smith',
|
||||
url: 'http://example.org/person/jayden-smith',
|
||||
},
|
||||
{
|
||||
name: 'Peter Pan',
|
||||
url: 'http://example.org/person/peter-pan',
|
||||
},
|
||||
{
|
||||
name: 'Lorca',
|
||||
url: 'http://example.org/person/lorca',
|
||||
},
|
||||
{
|
||||
name: 'David Summer',
|
||||
url: 'http://example.org/person/david-summer',
|
||||
},
|
||||
],
|
||||
match: /\B@([a-z ]*)/i,
|
||||
search: function(keyword, callback) {
|
||||
callback($.grep(this.mentions, function(item) {
|
||||
return item.name.toLowerCase().indexOf(keyword.toLowerCase()) === 0;
|
||||
}));
|
||||
},
|
||||
template: function(item) {
|
||||
return item.name;
|
||||
},
|
||||
content: function(item) {
|
||||
return $('<a>')
|
||||
.attr('href', item.url)
|
||||
.text('@' + item.name)
|
||||
.get(0);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
context = new Context($note, options);
|
||||
editor = context.modules.editor;
|
||||
$editable = context.layoutInfo.editable;
|
||||
|
||||
// [workaround]
|
||||
// - Safari does not popup hintpopover
|
||||
// - IE8-11 can't create range in headless mode
|
||||
if (env.isMSIE || env.isSafari) {
|
||||
this.skip();
|
||||
}
|
||||
});
|
||||
|
||||
it('should select the best matched item with the given condition', (done) => {
|
||||
var textNode = $editable.find('p')[0].firstChild;
|
||||
editor.setLastRange(range.create(textNode, 5, textNode, 5).select());
|
||||
editor.insertText(' @David S');
|
||||
$editable.keyup();
|
||||
|
||||
setTimeout(() => {
|
||||
// David Summer should be activated
|
||||
const item = $('.note-hint-popover').find('.note-hint-item');
|
||||
expect(item.text()).to.equals('David Summer');
|
||||
expect(item.hasClass('active')).to.be.true;
|
||||
done();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it('should render hint result with given content', (done) => {
|
||||
var textNode = $editable.find('p')[0].firstChild;
|
||||
editor.setLastRange(range.create(textNode, 5, textNode, 5).select());
|
||||
editor.insertText(' @David S');
|
||||
$editable.keyup();
|
||||
|
||||
setTimeout(() => {
|
||||
// alvin should be activated
|
||||
var e = $.Event('keydown');
|
||||
e.keyCode = key.code.ENTER;
|
||||
$note.trigger('summernote.keydown', e);
|
||||
|
||||
setTimeout(() => {
|
||||
expectContents(context, '<p>hello <a href="http://example.org/person/david-summer">@David Summer</a> world</p>');
|
||||
done();
|
||||
}, 10);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
});
|
||||
110
public/vendor/editor/test/base/module/LinkDialog.spec.js
vendored
Executable file
110
public/vendor/editor/test/base/module/LinkDialog.spec.js
vendored
Executable file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* LinkDialog.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import chai from 'chai';
|
||||
import $ from 'jquery';
|
||||
import range from 'src/js/base/core/range';
|
||||
import Context from 'src/js/base/Context';
|
||||
import LinkDialog from 'src/js/base/module/LinkDialog';
|
||||
import 'src/js/bs4/settings';
|
||||
|
||||
describe('LinkDialog', () => {
|
||||
var expect = chai.expect;
|
||||
var context, dialog, $editable;
|
||||
|
||||
beforeEach(() => {
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.toolbar = [
|
||||
['insert', ['link']],
|
||||
];
|
||||
context = new Context(
|
||||
$('<div>' +
|
||||
'<p><a href="https://summernote.org/" target="_blank">hello</a></p>' +
|
||||
'<p><a href="https://summernote.org/">world</a></p>' +
|
||||
'<p><a href="summernote.org/">summer</a></p>' +
|
||||
'<p>summer</p>' +
|
||||
'<p>http://summer</p>' +
|
||||
'</div>'),
|
||||
options
|
||||
);
|
||||
context.initialize();
|
||||
|
||||
dialog = new LinkDialog(context);
|
||||
dialog.initialize();
|
||||
|
||||
$editable = context.layoutInfo.editable;
|
||||
$editable.appendTo('body');
|
||||
});
|
||||
|
||||
describe('LinkDialog', () => {
|
||||
// open-in-new-window
|
||||
it('should check new window when target=_blank', () => {
|
||||
range.createFromNode($editable.find('a')[0]).normalize().select();
|
||||
context.invoke('editor.setLastRange');
|
||||
dialog.show();
|
||||
|
||||
var checked = dialog.$dialog
|
||||
.find('.sn-checkbox-open-in-new-window input[type=checkbox]')
|
||||
.is(':checked');
|
||||
expect(checked).to.be.true;
|
||||
});
|
||||
|
||||
it('should uncheck new window without target=_blank', () => {
|
||||
range.createFromNode($editable.find('a')[1]).normalize().select();
|
||||
context.invoke('editor.setLastRange');
|
||||
dialog.show();
|
||||
|
||||
var checked = dialog.$dialog
|
||||
.find('.sn-checkbox-open-in-new-window input[type=checkbox]')
|
||||
.is(':checked');
|
||||
expect(checked).to.be.false;
|
||||
});
|
||||
|
||||
// use default protocol
|
||||
it('should uncheck default protocol if link (with protocol) exists', () => {
|
||||
range.createFromNode($editable.find('a')[1]).normalize().select();
|
||||
context.invoke('editor.setLastRange');
|
||||
dialog.show();
|
||||
|
||||
var checked = dialog.$dialog
|
||||
.find('.sn-checkbox-use-protocol input[type=checkbox]')
|
||||
.is(':checked');
|
||||
expect(checked).to.be.false;
|
||||
});
|
||||
|
||||
it('should uncheck default protocol if link (without protocol) exists', () => {
|
||||
range.createFromNode($editable.find('a')[2]).normalize().select();
|
||||
context.invoke('editor.setLastRange');
|
||||
dialog.show();
|
||||
|
||||
var checked = dialog.$dialog
|
||||
.find('.sn-checkbox-use-protocol input[type=checkbox]')
|
||||
.is(':checked');
|
||||
expect(checked).to.be.false;
|
||||
});
|
||||
|
||||
it('should check default protocol if link not exists', () => {
|
||||
range.createFromNode($editable.find('p')[3]).normalize().select();
|
||||
context.invoke('editor.setLastRange');
|
||||
dialog.show();
|
||||
|
||||
var checked = dialog.$dialog
|
||||
.find('.sn-checkbox-use-protocol input[type=checkbox]')
|
||||
.is(':checked');
|
||||
expect(checked).to.be.true;
|
||||
});
|
||||
|
||||
it('should check default protocol if link not exists although it has protocol', () => {
|
||||
range.createFromNode($editable.find('p')[4]).normalize().select();
|
||||
context.invoke('editor.setLastRange');
|
||||
dialog.show();
|
||||
|
||||
var checked = dialog.$dialog
|
||||
.find('.sn-checkbox-use-protocol input[type=checkbox]')
|
||||
.is(':checked');
|
||||
expect(checked).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
31
public/vendor/editor/test/base/module/Placeholder.spec.js
vendored
Executable file
31
public/vendor/editor/test/base/module/Placeholder.spec.js
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Placeholder.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import chai from 'chai';
|
||||
import $ from 'jquery';
|
||||
import Context from 'src/js/base/Context';
|
||||
import 'src/js/bs4/settings';
|
||||
|
||||
describe('Placeholder', () => {
|
||||
var assert = chai.assert;
|
||||
|
||||
it('should not be initialized by placeholder attribute without inheritPlaceHolder', () => {
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
var context = new Context($('<textarea placeholder="custom_placeholder"><p>hello</p></textarea>'), options);
|
||||
var $editor = context.layoutInfo.editor;
|
||||
|
||||
assert.isTrue($editor.find('.note-placeholder').length === 0);
|
||||
});
|
||||
|
||||
it('should be initialized by placeholder attribute with inheritPlaceHolder', () => {
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.inheritPlaceholder = true;
|
||||
var context = new Context($('<textarea placeholder="custom_placeholder"><p>hello</p></textarea>'), options);
|
||||
var $editor = context.layoutInfo.editor;
|
||||
|
||||
assert.isTrue($editor.find('.note-placeholder').length === 1);
|
||||
assert.isTrue($editor.find('.note-placeholder').html() === 'custom_placeholder');
|
||||
});
|
||||
});
|
||||
64
public/vendor/editor/test/base/module/VideoDialog.spec.js
vendored
Executable file
64
public/vendor/editor/test/base/module/VideoDialog.spec.js
vendored
Executable file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* VideoDialog.spec.js
|
||||
* (c) 2015~ Summernote Team
|
||||
* summernote may be freely distributed under the MIT license./
|
||||
*/
|
||||
import chai from 'chai';
|
||||
import $ from 'jquery';
|
||||
import Context from 'src/js/base/Context';
|
||||
import VideoDialog from 'src/js/base/module/VideoDialog';
|
||||
import 'src/js/bs4/settings';
|
||||
|
||||
describe('VideoDialog', () => {
|
||||
var expect = chai.expect;
|
||||
var context, $video;
|
||||
|
||||
function expectUrl(source, target) {
|
||||
var iframe = $video.createVideoNode(source);
|
||||
expect(iframe).to.not.equal(false);
|
||||
expect(iframe.tagName).to.equal('IFRAME');
|
||||
expect(iframe.src).to.be.have.string(target);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
var $note = $('<div></div>').appendTo('body');
|
||||
var options = $.extend({}, $.summernote.options);
|
||||
options.toolbar = [
|
||||
['video', ['video']],
|
||||
];
|
||||
context = new Context($note, options);
|
||||
context.initialize();
|
||||
|
||||
$video = new VideoDialog(context);
|
||||
});
|
||||
|
||||
describe('#createVideoNode', () => {
|
||||
it('should get false when insert invalid urls', () => {
|
||||
expect($video.createVideoNode('http://www.google.com')).to.equal(false);
|
||||
expect($video.createVideoNode('http://www.youtube.com')).to.equal(false);
|
||||
expect($video.createVideoNode('http://www.facebook.com')).to.equal(false);
|
||||
});
|
||||
|
||||
it('should get proper iframe src when insert valid video urls', () => {
|
||||
// YouTube
|
||||
expectUrl('https://www.youtube.com/watch?v=jNQXAC9IVRw',
|
||||
'//www.youtube.com/embed/jNQXAC9IVRw');
|
||||
// Instagram
|
||||
expectUrl('https://www.instagram.com/p/Bi9cbsxjn-F',
|
||||
'//instagram.com/p/Bi9cbsxjn-F/embed/');
|
||||
// v.qq.com
|
||||
expectUrl('http://v.qq.com/cover/6/640ewqy2v071ppd.html?vid=f0196y2b2cx',
|
||||
'//v.qq.com/iframe/player.html?vid=f0196y2b2cx&auto=0');
|
||||
expectUrl('http://v.qq.com/x/page/p0330y279lm.html',
|
||||
'//v.qq.com/iframe/player.html?vid=p0330y279lm&auto=0');
|
||||
// Facebook
|
||||
expectUrl('https://www.facebook.com/Engineering/videos/631826881803/',
|
||||
'//www.facebook.com/plugins/video.php?href=www.facebook.com%2FEngineering%2Fvideos%2F631826881803');
|
||||
});
|
||||
|
||||
it('should be embedded start parameter when insert YouTube video with t', () => {
|
||||
expectUrl('https://youtu.be/wZZ7oFKsKzY?t=4h2m42s',
|
||||
'//www.youtube.com/embed/wZZ7oFKsKzY?start=14562');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user