restore composer.json, add mysqli extension
This commit is contained in:
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