mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2025-10-16 12:05:38 +00:00
TinyMCE: update the tests for version 4.5.6. Remove default plugins tests, it is quite pointless to keep repeating them at this point.
See #40305. git-svn-id: https://develop.svn.wordpress.org/trunk@40399 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
860363337f
commit
d37198f240
@ -40,6 +40,9 @@
|
||||
<script src="tinymce/caret/LineUtils.js"></script>
|
||||
<script src="tinymce/caret/LineWalker.js"></script>
|
||||
|
||||
<!-- tinymce.content.* -->
|
||||
<script src="tinymce/content/LinkTargets.js"></script>
|
||||
|
||||
<!-- tinymce.geom.* -->
|
||||
<script src="tinymce/geom/Rect.js"></script>
|
||||
<script src="tinymce/geom/ClientRect.js"></script>
|
||||
@ -51,6 +54,8 @@
|
||||
|
||||
<!-- tinymce.fmt.* -->
|
||||
<script src="tinymce/fmt/Hooks.js"></script>
|
||||
<script src="tinymce/fmt/Preview.js"></script>
|
||||
<script src="tinymce/fmt/FontInfo.js"></script>
|
||||
|
||||
<!-- tinymce.text.* -->
|
||||
<script src="tinymce/text/ExtendingChar.js"></script>
|
||||
@ -86,6 +91,7 @@
|
||||
<script src="tinymce/ui/Collection.js"></script>
|
||||
<script src="tinymce/ui/ColorButton.js"></script>
|
||||
<script src="tinymce/ui/Control.js"></script>
|
||||
<!--<script src="tinymce/ui/FilePicker.js"></script>-->
|
||||
<script src="tinymce/ui/FitLayout.js"></script>
|
||||
<script src="tinymce/ui/FlexLayout.js"></script>
|
||||
<script src="tinymce/ui/GridLayout.js"></script>
|
||||
@ -97,6 +103,12 @@
|
||||
<script src="tinymce/ui/TextBox.js"></script>
|
||||
<script src="tinymce/ui/Window.js"></script>
|
||||
|
||||
<!-- tinymce.undo.* -->
|
||||
<script src="tinymce/undo/Diff.js"></script>
|
||||
<script src="tinymce/undo/Fragments.js"></script>
|
||||
<script src="tinymce/undo/Levels.js"></script>
|
||||
<script src="tinymce/undo/ForcedRootBlock.js"></script>
|
||||
|
||||
<!-- tinymce.util.* -->
|
||||
<script src="tinymce/util/Color.js"></script>
|
||||
<script src="tinymce/util/EventDispatcher.js"></script>
|
||||
@ -115,12 +127,15 @@
|
||||
|
||||
<!-- tinymce.* -->
|
||||
<script src="tinymce/AddOnManager.js"></script>
|
||||
<script src="tinymce/options.js"></script>
|
||||
<script src="tinymce/Editor.js"></script>
|
||||
<script src="tinymce/Editor_rtl.js"></script>
|
||||
<script src="tinymce/EditorCustomTheme.js"></script>
|
||||
<script src="tinymce/EditorUpload.js"></script>
|
||||
<script src="tinymce/EditorCommands.js"></script>
|
||||
<script src="tinymce/EditorManager.js"></script>
|
||||
<script src="tinymce/EnterKey.js"></script>
|
||||
<script src="tinymce/FocusManager.js"></script>
|
||||
<script src="tinymce/ForceBlocks.js"></script>
|
||||
<script src="tinymce/Formatter_apply.js"></script>
|
||||
<script src="tinymce/Formatter_check.js"></script>
|
||||
@ -130,29 +145,11 @@
|
||||
<script src="tinymce/SelectionOverrides.js"></script>
|
||||
<script src="tinymce/WindowManager.js"></script>
|
||||
<script src="tinymce/InsertContent.js"></script>
|
||||
<script src="tinymce/InsertContentForcedRootFalse.js"></script>
|
||||
<script src="tinymce/InsertList.js"></script>
|
||||
<script src="tinymce/NotificationManager.js"></script>
|
||||
|
||||
<!-- tinymce.plugins.* -->
|
||||
<!--<script src="plugins/autolink.js"></script>-->
|
||||
<script src="plugins/charmap.js"></script>
|
||||
<!--<script src="plugins/autosave.js"></script>-->
|
||||
<!--<script src="plugins/fullpage.js"></script>-->
|
||||
<script src="plugins/image.js"></script>
|
||||
<!--<script src="plugins/importcss.js"></script>-->
|
||||
<!--<script src="plugins/jquery_plugin.js"></script>-->
|
||||
<!--<script src="plugins/jquery_initialization.js"></script>-->
|
||||
<!--<script src="plugins/legacyoutput.js"></script>-->
|
||||
<!--<script src="plugins/link.js"></script>-->
|
||||
<script src="plugins/lists.js"></script>
|
||||
<script src="plugins/media.js"></script>
|
||||
<!--<script src="plugins/noneditable.js"></script> -->
|
||||
<script src="plugins/paste.js"></script>
|
||||
<script src="plugins/paste_images.js"></script>
|
||||
<script src="plugins/paste_smart.js"></script>
|
||||
<!--<script src="plugins/searchreplace.js"></script>-->
|
||||
<!--<script src="plugins/spellchecker.js"></script>-->
|
||||
<!--<script src="plugins/table.js"></script>-->
|
||||
<!--<script src="plugins/textpattern.js"></script>-->
|
||||
<!--<script src="plugins/wordcount.js"></script>-->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.hidepassed = true;
|
||||
|
||||
window.editor = window.inlineEditor = null;
|
||||
window.editor = window.inlineEditor = null;
|
||||
|
||||
var oldModule = module;
|
||||
|
||||
@ -23,12 +23,12 @@
|
||||
|
||||
// Sauce labs
|
||||
QUnit.testStart(function(testDetails) {
|
||||
QUnit.log = function(details) {
|
||||
QUnit.log(function(details) {
|
||||
if (!details.result) {
|
||||
details.name = currentModule + ':' + testDetails.name;
|
||||
log.push(details);
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.done(function(results) {
|
||||
|
||||
@ -571,6 +571,11 @@ if ( !defined.document || document.readyState === "complete" ) {
|
||||
config.autorun = true;
|
||||
}
|
||||
|
||||
if (document.location.search.indexOf('bedrock') !== -1) {
|
||||
config.autorun = false;
|
||||
config.autostart = false;
|
||||
}
|
||||
|
||||
QUnit.load = function() {
|
||||
runLoggingCallbacks( "begin", QUnit, {} );
|
||||
|
||||
|
||||
@ -4,4 +4,6 @@ document.write('<script src="../../../src/wp-includes/js/tinymce/tinymce.js"></s
|
||||
var wpPlugins = 'charmap colorpicker hr lists media paste tabfocus textcolor ' +
|
||||
'fullscreen wordpress wpautoresize wpeditimage wpgallery wplink wpdialogs wpview';
|
||||
|
||||
var $ = window.jQuery;
|
||||
|
||||
getUserSetting = setUserSetting = function() {}
|
||||
|
||||
@ -1,80 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.plugins.Autolink", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
plugins: 'autolink',
|
||||
autosave_ask_before_unload: false,
|
||||
indent: false,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function typeUrl(url) {
|
||||
editor.setContent('<p>' + url + '</p>');
|
||||
Utils.setSelection('p', url.length);
|
||||
Utils.type(' ');
|
||||
return editor.getContent();
|
||||
}
|
||||
|
||||
function typeAnEclipsedURL(url) {
|
||||
url = "(" + url;
|
||||
editor.setContent('<p>' + url + '</p>');
|
||||
Utils.setSelection('p', url.length);
|
||||
Utils.type(')');
|
||||
return editor.getContent();
|
||||
}
|
||||
|
||||
function typeNewlineURL(url) {
|
||||
editor.setContent('<p>' + url + '</p>');
|
||||
Utils.setSelection('p', url.length);
|
||||
Utils.type('\n');
|
||||
return editor.getContent();
|
||||
}
|
||||
|
||||
if (tinymce.Env.ie) {
|
||||
test("Skipped on IE since it has built in logic for autolink", function() {
|
||||
ok(true);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
test("Urls ended with space", function() {
|
||||
equal(typeUrl('http://www.domain.com'), '<p><a href="http://www.domain.com">http://www.domain.com</a></p>');
|
||||
equal(typeUrl('https://www.domain.com'), '<p><a href="https://www.domain.com">https://www.domain.com</a></p>');
|
||||
equal(typeUrl('ssh://www.domain.com'), '<p><a href="ssh://www.domain.com">ssh://www.domain.com</a></p>');
|
||||
equal(typeUrl('ftp://www.domain.com'), '<p><a href="ftp://www.domain.com">ftp://www.domain.com</a></p>');
|
||||
equal(typeUrl('www.domain.com'), '<p><a href="http://www.domain.com">www.domain.com</a></p>');
|
||||
equal(typeUrl('www.domain.com.'), '<p><a href="http://www.domain.com">www.domain.com</a>.</p>');
|
||||
equal(typeUrl('user@domain.com'), '<p><a href="mailto:user@domain.com">user@domain.com</a></p>');
|
||||
equal(typeUrl('mailto:user@domain.com'), '<p><a href="mailto:user@domain.com">mailto:user@domain.com</a></p>');
|
||||
equal(typeUrl('first-last@domain.com'), '<p><a href="mailto:first-last@domain.com">first-last@domain.com</a></p>');
|
||||
});
|
||||
|
||||
test("Urls ended with )", function() {
|
||||
equal(typeAnEclipsedURL('http://www.domain.com'), '<p>(<a href="http://www.domain.com">http://www.domain.com</a>)</p>');
|
||||
equal(typeAnEclipsedURL('https://www.domain.com'), '<p>(<a href="https://www.domain.com">https://www.domain.com</a>)</p>');
|
||||
equal(typeAnEclipsedURL('ssh://www.domain.com'), '<p>(<a href="ssh://www.domain.com">ssh://www.domain.com</a>)</p>');
|
||||
equal(typeAnEclipsedURL('ftp://www.domain.com'), '<p>(<a href="ftp://www.domain.com">ftp://www.domain.com</a>)</p>');
|
||||
equal(typeAnEclipsedURL('www.domain.com'), '<p>(<a href="http://www.domain.com">www.domain.com</a>)</p>');
|
||||
equal(typeAnEclipsedURL('www.domain.com.'), '<p>(<a href="http://www.domain.com">www.domain.com</a>.)</p>');
|
||||
});
|
||||
|
||||
test("Urls ended with new line", function() {
|
||||
equal(typeNewlineURL('http://www.domain.com'), '<p><a href="http://www.domain.com">http://www.domain.com</a></p><p> </p>');
|
||||
equal(typeNewlineURL('https://www.domain.com'), '<p><a href="https://www.domain.com">https://www.domain.com</a></p><p> </p>');
|
||||
equal(typeNewlineURL('ssh://www.domain.com'), '<p><a href="ssh://www.domain.com">ssh://www.domain.com</a></p><p> </p>');
|
||||
equal(typeNewlineURL('ftp://www.domain.com'), '<p><a href="ftp://www.domain.com">ftp://www.domain.com</a></p><p> </p>');
|
||||
equal(typeNewlineURL('www.domain.com'), '<p><a href="http://www.domain.com">www.domain.com</a></p><p> </p>');
|
||||
equal(typeNewlineURL('www.domain.com.'), '<p><a href="http://www.domain.com">www.domain.com</a>.</p><p> </p>');
|
||||
});
|
||||
})();
|
||||
@ -1,74 +0,0 @@
|
||||
module("tinymce.plugins.Autosave", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
plugins: 'autosave',
|
||||
autosave_ask_before_unload: false,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
editor.plugins.autosave.removeDraft();
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test("isEmpty true", function() {
|
||||
ok(editor.plugins.autosave.isEmpty(''));
|
||||
ok(editor.plugins.autosave.isEmpty(' '));
|
||||
ok(editor.plugins.autosave.isEmpty('\t\t\t'));
|
||||
|
||||
ok(editor.plugins.autosave.isEmpty('<p id="x"></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p> </p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p>\t</p>'));
|
||||
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br /></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br data-mce-bogus="true" /></p>'));
|
||||
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br><br></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br /><br /></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br data-mce-bogus="true" /><br data-mce-bogus="true" /></p>'));
|
||||
});
|
||||
|
||||
test("isEmpty false", function() {
|
||||
ok(!editor.plugins.autosave.isEmpty('X'));
|
||||
ok(!editor.plugins.autosave.isEmpty(' X'));
|
||||
ok(!editor.plugins.autosave.isEmpty('\t\t\tX'));
|
||||
|
||||
ok(!editor.plugins.autosave.isEmpty('<p>X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p> X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p>\tX</p>'));
|
||||
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br>X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br />X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br data-mce-bogus="true" />X</p>'));
|
||||
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br><br>X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br /><br />X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br data-mce-bogus="true" /><br data-mce-bogus="true" />X</p>'));
|
||||
|
||||
ok(!editor.plugins.autosave.isEmpty('<h1></h1>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<img src="x" />'));
|
||||
});
|
||||
|
||||
test("hasDraft/storeDraft/restoreDraft", function() {
|
||||
ok(!editor.plugins.autosave.hasDraft());
|
||||
|
||||
editor.setContent('X');
|
||||
editor.undoManager.add();
|
||||
editor.plugins.autosave.storeDraft();
|
||||
|
||||
ok(editor.plugins.autosave.hasDraft());
|
||||
|
||||
editor.setContent('Y');
|
||||
editor.undoManager.add();
|
||||
|
||||
editor.plugins.autosave.restoreDraft();
|
||||
equal(editor.getContent(), '<p>X</p>');
|
||||
});
|
||||
@ -1,91 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
], function() {
|
||||
module("tinymce.plugins.CharMap", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
plugins: "charmap",
|
||||
add_unload_trigger: false,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('Replace characters by array', function() {
|
||||
editor.settings.charmap = [
|
||||
[65, 'Latin A'],
|
||||
[66, 'Latin B']
|
||||
];
|
||||
|
||||
deepEqual(editor.plugins.charmap.getCharMap(), [
|
||||
[65, 'Latin A'],
|
||||
[66, 'Latin B']
|
||||
]);
|
||||
});
|
||||
|
||||
test('Replace characters by function', function() {
|
||||
editor.settings.charmap = function() {
|
||||
return [
|
||||
[65, 'Latin A fun'],
|
||||
[66, 'Latin B fun']
|
||||
];
|
||||
};
|
||||
|
||||
deepEqual(editor.plugins.charmap.getCharMap(), [
|
||||
[65, 'Latin A fun'],
|
||||
[66, 'Latin B fun']
|
||||
]);
|
||||
});
|
||||
|
||||
test('Append characters by array', function() {
|
||||
editor.settings.charmap = [
|
||||
[67, 'Latin C']
|
||||
];
|
||||
|
||||
editor.settings.charmap_append = [
|
||||
[65, 'Latin A'],
|
||||
[66, 'Latin B']
|
||||
];
|
||||
|
||||
deepEqual(editor.plugins.charmap.getCharMap(), [
|
||||
[67, 'Latin C'],
|
||||
[65, 'Latin A'],
|
||||
[66, 'Latin B']
|
||||
]);
|
||||
});
|
||||
|
||||
test('Append characters by function', function() {
|
||||
editor.settings.charmap = [
|
||||
[67, 'Latin C']
|
||||
];
|
||||
|
||||
editor.settings.charmap_append = function() {
|
||||
return [
|
||||
[65, 'Latin A fun'],
|
||||
[66, 'Latin B fun']
|
||||
];
|
||||
};
|
||||
|
||||
deepEqual(editor.plugins.charmap.getCharMap(), [
|
||||
[67, 'Latin C'],
|
||||
[65, 'Latin A fun'],
|
||||
[66, 'Latin B fun']
|
||||
]);
|
||||
});
|
||||
|
||||
test('Insert character', function() {
|
||||
var lastEvt;
|
||||
|
||||
editor.on('insertCustomChar', function(e) {
|
||||
lastEvt = e;
|
||||
});
|
||||
|
||||
editor.plugins.charmap.insertChar('A');
|
||||
equal(lastEvt.chr, 'A');
|
||||
});
|
||||
});
|
||||
@ -1,125 +0,0 @@
|
||||
module("tinymce.plugins.Fullpage", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
plugins: "fullpage",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
valid_styles: {
|
||||
'*': 'text-align,padding-left,color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display'
|
||||
},
|
||||
indent: 0,
|
||||
setup: function(ed) {
|
||||
ed.on('NodeChange', false);
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
editor.getBody().dir = 'ltr';
|
||||
}
|
||||
});
|
||||
|
||||
test('Keep header/footer intact', function() {
|
||||
expect(2);
|
||||
|
||||
function normalizeHTML(html) {
|
||||
return html.replace(/\s/g, '');
|
||||
}
|
||||
|
||||
editor.setContent('<html><body><p>Test</p>');
|
||||
equal(normalizeHTML(editor.getContent()), '<html><body><p>Test</p>', 'Invalid HTML content is still editable.');
|
||||
|
||||
editor.setContent('<html><body><p>Test</p></body></html>');
|
||||
equal(normalizeHTML(editor.getContent()), '<html><body><p>Test</p></body></html>', 'Header/footer is intact.');
|
||||
});
|
||||
|
||||
test('Default header/footer', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>Test</p>');
|
||||
equal(editor.getContent(), '<!DOCTYPE html>\n<html>\n<head>\n</head>\n<body>\n<p>Test</p>\n</body>\n</html>', 'Invalid HTML content is still editable.');
|
||||
});
|
||||
|
||||
test('Parse body attributes', function() {
|
||||
expect(9);
|
||||
|
||||
editor.setContent('<html><body><p>Test</p></body></html>');
|
||||
equal(editor.getBody().style.color, '', 'No color on body.');
|
||||
equal(editor.getBody().dir, '', 'No dir on body.');
|
||||
equal(editor.dom.getStyle(editor.getBody().firstChild, 'display', true), 'block', 'No styles added to iframe document');
|
||||
|
||||
editor.setContent('<html><body style="color:#FF0000"><p>Test</p></body></html>');
|
||||
ok(editor.getBody().style.color.length > 0, 'Color added to body');
|
||||
|
||||
editor.setContent('<html><body dir="rtl"><p>Test</p></body></html>');
|
||||
equal(editor.getBody().dir, 'rtl', 'Dir added to body');
|
||||
|
||||
editor.setContent('<html><head><style>p {text-align:right}</style></head><body dir="rtl"><p>Test</p></body></html>');
|
||||
equal(editor.dom.getStyle(editor.getBody().firstChild, 'text-align', true), 'right', 'Styles added to iframe document');
|
||||
|
||||
editor.setContent('<html><body><p>Test</p></body></html>');
|
||||
equal(editor.getBody().style.color, '', 'No color on body.');
|
||||
equal(editor.getBody().dir, '', 'No dir on body.');
|
||||
equal(editor.dom.getStyle(editor.getBody().firstChild, 'display', true), 'block', 'No styles added to iframe document');
|
||||
});
|
||||
|
||||
test('fullpage_hide_in_source_view: false', function() {
|
||||
editor.settings.fullpage_hide_in_source_view = false;
|
||||
editor.setContent('<html><body><p>1</p></body></html>');
|
||||
equal(editor.getContent({source_view: true}), '<html><body>\n<p>1</p>\n</body></html>');
|
||||
});
|
||||
|
||||
test('fullpage_hide_in_source_view: false', function() {
|
||||
editor.settings.fullpage_hide_in_source_view = true;
|
||||
editor.setContent('<html><body><p>1</p></body></html>');
|
||||
equal(editor.getContent({source_view: true}), '<p>1</p>');
|
||||
});
|
||||
|
||||
test('link elements', function() {
|
||||
editor.setContent('<html><head><link rel="stylesheet" href="a.css"><link rel="something"></head><body><p>c</p></body></html>');
|
||||
equal(editor.getContent(), '<html><head><link rel="stylesheet" href="a.css"><link rel="something"></head><body>\n<p>c</p>\n</body></html>');
|
||||
});
|
||||
|
||||
test('add/remove stylesheets', function() {
|
||||
function hasLink(href) {
|
||||
var links = editor.getDoc().getElementsByTagName('link');
|
||||
|
||||
for (var i = 0; i < links.length; i++) {
|
||||
if (links[i].href.indexOf('/' + href) != -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.setContent('<html><head><link rel="stylesheet" href="a.css"></head><body><p>c</p></body></html>');
|
||||
ok(hasLink("a.css"));
|
||||
ok(!hasLink("b.css"));
|
||||
ok(!hasLink("c.css"));
|
||||
|
||||
editor.setContent('<html><head><link rel="stylesheet" href="a.css"><link rel="stylesheet" href="b.css"></head><body><p>c</p></body></html>');
|
||||
ok(hasLink("a.css"));
|
||||
ok(hasLink("b.css"));
|
||||
ok(!hasLink("c.css"));
|
||||
|
||||
editor.setContent('<html><head><link rel="stylesheet" href="a.css"><link rel="stylesheet" href="b.css"><link rel="stylesheet" href="c.css"></head><body><p>c</p></body></html>');
|
||||
ok(hasLink("a.css"));
|
||||
ok(hasLink("b.css"));
|
||||
ok(hasLink("c.css"));
|
||||
|
||||
editor.setContent('<html><head><link rel="stylesheet" href="a.css"></head><body><p>c</p></body></html>');
|
||||
ok(hasLink("a.css"));
|
||||
ok(!hasLink("b.css"));
|
||||
ok(!hasLink("c.css"));
|
||||
|
||||
editor.setContent('<html><head></head><body><p>c</p></body></html>');
|
||||
ok(!hasLink("a.css"));
|
||||
ok(!hasLink("b.css"));
|
||||
ok(!hasLink("c.css"));
|
||||
});
|
||||
@ -1,641 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.plugins.Image", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: 'textarea',
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
plugins: "image",
|
||||
disable_nodechange: true,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
delete editor.settings.image_dimensions;
|
||||
delete editor.settings.file_browser_callback;
|
||||
delete editor.settings.image_list;
|
||||
delete editor.settings.image_class_list;
|
||||
delete editor.settings.document_base_url;
|
||||
delete editor.settings.image_advtab;
|
||||
delete editor.settings.image_caption;
|
||||
|
||||
var win = Utils.getFrontmostWindow();
|
||||
|
||||
if (win) {
|
||||
win.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function cleanHtml(html) {
|
||||
return Utils.cleanHtml(html).replace(/<p>( |<br[^>]+>)<\/p>$/, '');
|
||||
}
|
||||
|
||||
function fillAndSubmitWindowForm(data) {
|
||||
var win = Utils.getFrontmostWindow();
|
||||
|
||||
win.fromJSON(data);
|
||||
win.find('form')[0].submit();
|
||||
win.close();
|
||||
}
|
||||
|
||||
test('Default image dialog on empty editor', function() {
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"constrain": true,
|
||||
"height": "",
|
||||
"src": "",
|
||||
"width": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"alt": "alt",
|
||||
"height": "100",
|
||||
"src": "src",
|
||||
"width": "200"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img src="src" alt="alt" width="200" height="100" /></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Image dialog image_dimensions: false', function() {
|
||||
editor.settings.image_dimensions = false;
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"src": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"alt": "alt",
|
||||
"src": "src"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img src="src" alt="alt" /></p>'
|
||||
);
|
||||
});
|
||||
|
||||
if (tinymce.Env.ceFalse) {
|
||||
test('All image dialog ui options on empty editor', function() {
|
||||
editor.settings.image_caption = true;
|
||||
editor.settings.image_list = [
|
||||
{title: 'link1', value: 'link1'},
|
||||
{title: 'link2', value: 'link2'}
|
||||
];
|
||||
|
||||
editor.settings.image_class_list = [
|
||||
{title: 'class1', value: 'class1'},
|
||||
{title: 'class2', value: 'class2'}
|
||||
];
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"class": "class1",
|
||||
"constrain": true,
|
||||
"caption": false,
|
||||
"height": "",
|
||||
"src": "",
|
||||
"width": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"alt": "alt",
|
||||
"class": "class1",
|
||||
"constrain": true,
|
||||
"caption": true,
|
||||
"height": "200",
|
||||
"src": "src",
|
||||
"width": "100"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<figure class="image"><img class="class1" src="src" alt="alt" width="100" height="200" /><figcaption>caption</figcaption></figure>'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
test('All image dialog ui options on empty editor (old IE)', function() {
|
||||
editor.settings.image_caption = true;
|
||||
editor.settings.image_list = [
|
||||
{title: 'link1', value: 'link1'},
|
||||
{title: 'link2', value: 'link2'}
|
||||
];
|
||||
|
||||
editor.settings.image_class_list = [
|
||||
{title: 'class1', value: 'class1'},
|
||||
{title: 'class2', value: 'class2'}
|
||||
];
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"class": "class1",
|
||||
"constrain": true,
|
||||
"height": "",
|
||||
"src": "",
|
||||
"width": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"alt": "alt",
|
||||
"class": "class1",
|
||||
"constrain": true,
|
||||
"caption": true,
|
||||
"height": "200",
|
||||
"src": "src",
|
||||
"width": "100"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img class="class1" src="src" alt="alt" width="100" height="200" /></p>'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test("Image recognizes relative src url and prepends relative image_prepend_url setting.", function() {
|
||||
var win, elementId, element;
|
||||
|
||||
editor.settings.image_prepend_url = 'testing/images/';
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
var data = {
|
||||
"src": "src",
|
||||
"alt": "alt"
|
||||
};
|
||||
|
||||
win = Utils.getFrontmostWindow();
|
||||
elementId = win.find('#src')[0]._id;
|
||||
element = document.getElementById(elementId).childNodes[0];
|
||||
|
||||
win.fromJSON(data);
|
||||
Utils.triggerElementChange(element);
|
||||
|
||||
win.find('form')[0].submit();
|
||||
win.close();
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img src="' + editor.settings.image_prepend_url + 'src" alt="alt" /></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Image recognizes relative src url and prepends absolute image_prepend_url setting.", function() {
|
||||
var win, elementId, element;
|
||||
|
||||
editor.settings.image_prepend_url = 'http://localhost/images/';
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
var data = {
|
||||
"src": "src",
|
||||
"alt": "alt"
|
||||
};
|
||||
|
||||
win = Utils.getFrontmostWindow();
|
||||
elementId = win.find('#src')[0]._id;
|
||||
element = document.getElementById(elementId).childNodes[0];
|
||||
|
||||
win.fromJSON(data);
|
||||
Utils.triggerElementChange(element);
|
||||
|
||||
win.find('form')[0].submit();
|
||||
win.close();
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img src="' + editor.settings.image_prepend_url + 'src" alt="alt" /></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Advanced image dialog border option on empty editor', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"alt": "alt",
|
||||
"border": "10px",
|
||||
"src": "src"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img style="border-width: 10px;" src="src" alt="alt" /></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Advanced image dialog margin space options on empty editor', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"alt": "alt",
|
||||
"hspace": "10",
|
||||
"src": "src",
|
||||
"vspace": "10"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img style="margin: 10px;" src="src" alt="alt" /></p>'
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog border style only options on empty editor', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"alt": "alt",
|
||||
"src": "src",
|
||||
"style": "border-width: 10px;"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img style="border-width: 10px;" src="src" alt="alt" /></p>'
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog margin style only options on empty editor', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"alt": "alt",
|
||||
"src": "src",
|
||||
"style": "margin: 10px;"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img style="margin: 10px;" src="src" alt="alt" /></p>'
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog overriden border style options on empty editor', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"alt": "alt",
|
||||
"border": "10",
|
||||
"src": "src",
|
||||
"style": "border-width: 15px;"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img style="border-width: 10px;" src="src" alt="alt" /></p>'
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog overriden margin style options on empty editor', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"alt": "alt",
|
||||
"hspace": "10",
|
||||
"src": "src",
|
||||
"style": "margin-left: 15px; margin-top: 20px;",
|
||||
"vspace": "10"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><img style="margin: 10px;" src="src" alt="alt" /></p>'
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog non-shorthand horizontal margin style change test', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
Utils.getFrontmostWindow().find('#style').value('margin-left: 15px; margin-right: 15px;').fire('change');
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "15",
|
||||
"src": "",
|
||||
"style": "margin-left: 15px; margin-right: 15px;",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog non-shorthand vertical margin style change test', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
Utils.getFrontmostWindow().find('#style').value('margin-top: 15px; margin-bottom: 15px;').fire('change');
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "margin-top: 15px; margin-bottom: 15px;",
|
||||
"vspace": "15"
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog shorthand margin 1 value style change test', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
Utils.getFrontmostWindow().find('#style').value('margin: 5px;').fire('change');
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "5",
|
||||
"src": "",
|
||||
"style": "margin: 5px;",
|
||||
"vspace": "5"
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog shorthand margin 2 value style change test', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
Utils.getFrontmostWindow().find('#style').value('margin: 5px 10px;').fire('change');
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "10",
|
||||
"src": "",
|
||||
"style": "margin: 5px 10px 5px 10px;",
|
||||
"vspace": "5"
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog shorthand margin 2 value style change test', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
Utils.getFrontmostWindow().find('#style').value('margin: 5px 10px;').fire('change');
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "10",
|
||||
"src": "",
|
||||
"style": "margin: 5px 10px 5px 10px;",
|
||||
"vspace": "5"
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog shorthand margin 3 value style change test', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
Utils.getFrontmostWindow().find('#style').value('margin: 5px 10px 15px;').fire('change');
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "10",
|
||||
"src": "",
|
||||
"style": "margin: 5px 10px 15px 10px;",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog shorthand margin 4 value style change test', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
Utils.getFrontmostWindow().find('#style').value('margin: 5px 10px 15px 20px;').fire('change');
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "margin: 5px 10px 15px 20px;",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('Advanced image dialog shorthand margin 4 value style change test', function(){
|
||||
editor.settings.image_advtab = true;
|
||||
editor.settings.image_dimensions = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceImage', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "",
|
||||
"vspace": ""
|
||||
});
|
||||
|
||||
Utils.getFrontmostWindow().find('#style').value('margin: 5px 10px 15px 20px; margin-top: 15px;').fire('change');
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"alt": "",
|
||||
"border": "",
|
||||
"hspace": "",
|
||||
"src": "",
|
||||
"style": "margin: 15px 10px 15px 20px;",
|
||||
"vspace": "15"
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
@ -1,350 +0,0 @@
|
||||
(function() {
|
||||
var menuCtrl;
|
||||
|
||||
module("tinymce.plugins.ImportCSS", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
plugins: 'importcss',
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
if (menuCtrl) {
|
||||
menuCtrl.remove();
|
||||
menuCtrl = null;
|
||||
}
|
||||
|
||||
editor.contentCSS = [];
|
||||
delete editor.settings.importcss_file_filter;
|
||||
delete editor.settings.importcss_merge_classes;
|
||||
delete editor.settings.importcss_append;
|
||||
delete editor.settings.importcss_selector_filter;
|
||||
delete editor.settings.importcss_groups;
|
||||
delete editor.settings.importcss_exclusive;
|
||||
delete editor.settings.importcss_selector_converter;
|
||||
}
|
||||
});
|
||||
|
||||
function fireFormatsMenuEvent(styleSheets, items) {
|
||||
menuCtrl = tinymce.ui.Factory.create('menu', {
|
||||
items: items
|
||||
}).renderTo(document.getElementById('view'));
|
||||
|
||||
return editor.fire('renderFormatsMenu', {
|
||||
control: menuCtrl,
|
||||
doc: {
|
||||
styleSheets: styleSheets
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getMenuItemFormat(item) {
|
||||
return editor.formatter.get(item.settings.format)[0];
|
||||
}
|
||||
|
||||
test("Import content_css files", function() {
|
||||
editor.contentCSS.push("test1.css");
|
||||
editor.contentCSS.push("test2.css");
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{
|
||||
href: 'test1.css',
|
||||
cssRules: [
|
||||
{selectorText: '.a'},
|
||||
{selectorText: 'p.b'},
|
||||
{selectorText: 'img.c'}
|
||||
]
|
||||
},
|
||||
|
||||
{href: 'test2.css', cssRules: [{selectorText: '.d'}]},
|
||||
{href: 'test3.css', cssRules: [{selectorText: '.e'}]}
|
||||
]);
|
||||
|
||||
equal(evt.control.items().length, 4);
|
||||
|
||||
equal(evt.control.items()[0].text(), 'a');
|
||||
equal(getMenuItemFormat(evt.control.items()[0]).classes, 'a');
|
||||
|
||||
equal(evt.control.items()[1].text(), 'p.b');
|
||||
equal(getMenuItemFormat(evt.control.items()[1]).block, 'p');
|
||||
equal(getMenuItemFormat(evt.control.items()[1]).classes, 'b');
|
||||
|
||||
equal(evt.control.items()[2].text(), 'img.c');
|
||||
equal(getMenuItemFormat(evt.control.items()[2]).selector, 'img');
|
||||
equal(getMenuItemFormat(evt.control.items()[2]).classes, 'c');
|
||||
|
||||
equal(evt.control.items()[3].text(), 'd');
|
||||
});
|
||||
|
||||
test("Import custom importcss_merge_classes: false", function() {
|
||||
editor.contentCSS.push("test.css");
|
||||
editor.settings.importcss_merge_classes = false;
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test.css', cssRules: [{selectorText: '.a'}]}
|
||||
]);
|
||||
|
||||
equal(evt.control.items().length, 1);
|
||||
deepEqual(getMenuItemFormat(evt.control.items()[0]).attributes, {"class": "a"});
|
||||
});
|
||||
|
||||
test("Import custom importcss_append: true", function() {
|
||||
editor.contentCSS.push("test.css");
|
||||
editor.settings.importcss_append = true;
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test.css', cssRules: [{selectorText: '.b'}]}
|
||||
], {text: 'a'});
|
||||
|
||||
equal(evt.control.items().length, 2);
|
||||
equal(evt.control.items()[0].text(), 'a');
|
||||
equal(evt.control.items()[1].text(), 'b');
|
||||
});
|
||||
|
||||
test("Import custom importcss_selector_filter (string)", function() {
|
||||
editor.contentCSS.push("test1.css");
|
||||
editor.settings.importcss_selector_filter = ".a";
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [
|
||||
{selectorText: '.a'},
|
||||
{selectorText: '.b'}
|
||||
]}
|
||||
]);
|
||||
|
||||
equal(evt.control.items().length, 1);
|
||||
equal(evt.control.items()[0].text(), 'a');
|
||||
});
|
||||
|
||||
test("Import custom importcss_selector_filter (function)", function() {
|
||||
editor.contentCSS.push("test1.css");
|
||||
editor.settings.importcss_selector_filter = function(selector) {
|
||||
return selector === ".a";
|
||||
};
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [
|
||||
{selectorText: '.a'},
|
||||
{selectorText: '.b'}
|
||||
]}
|
||||
]);
|
||||
|
||||
equal(evt.control.items().length, 1);
|
||||
equal(evt.control.items()[0].text(), 'a');
|
||||
});
|
||||
|
||||
test("Import custom importcss_selector_filter (regexp)", function() {
|
||||
editor.contentCSS.push("test1.css");
|
||||
editor.settings.importcss_selector_filter = /a/;
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [
|
||||
{selectorText: '.a'},
|
||||
{selectorText: '.b'}
|
||||
]}
|
||||
]);
|
||||
|
||||
equal(evt.control.items().length, 1);
|
||||
equal(evt.control.items()[0].text(), 'a');
|
||||
});
|
||||
|
||||
test("Import custom importcss_groups", function() {
|
||||
editor.contentCSS.push("test1.css");
|
||||
editor.settings.importcss_groups = [
|
||||
{title: 'g1', filter: /a/},
|
||||
{title: 'g2', filter: /b/},
|
||||
{title: 'g3'}
|
||||
];
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [
|
||||
{selectorText: '.a'},
|
||||
{selectorText: '.b'},
|
||||
{selectorText: '.c'}
|
||||
]}
|
||||
]);
|
||||
|
||||
equal(evt.control.items().length, 3);
|
||||
equal(evt.control.items()[0].text(), 'g1');
|
||||
equal(evt.control.items()[0].settings.menu[0].text, 'a');
|
||||
equal(evt.control.items()[1].text(), 'g2');
|
||||
equal(evt.control.items()[1].settings.menu[0].text, 'b');
|
||||
equal(evt.control.items()[2].text(), 'g3');
|
||||
equal(evt.control.items()[2].settings.menu[0].text, 'c');
|
||||
});
|
||||
|
||||
test("Import custom importcss_file_filter (string)", function() {
|
||||
editor.contentCSS.push("test1.css");
|
||||
editor.settings.importcss_file_filter = "test2.css";
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [{selectorText: '.a'}]},
|
||||
{href: 'test2.css', cssRules: [{selectorText: '.b'}]}
|
||||
]);
|
||||
|
||||
equal(evt.control.items().length, 1);
|
||||
equal(evt.control.items()[0].text(), 'b');
|
||||
});
|
||||
|
||||
test("Import custom importcss_file_filter (function)", function() {
|
||||
editor.contentCSS.push("test1.css");
|
||||
editor.settings.importcss_file_filter = function(href) {
|
||||
return href === "test2.css";
|
||||
};
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [{selectorText: '.a'}]},
|
||||
{href: 'test2.css', cssRules: [{selectorText: '.b'}]}
|
||||
]);
|
||||
|
||||
equal(evt.control.items().length, 1);
|
||||
equal(evt.control.items()[0].text(), 'b');
|
||||
});
|
||||
|
||||
test("Import custom importcss_file_filter (regexp)", function() {
|
||||
editor.contentCSS.push("test1.css");
|
||||
editor.settings.importcss_file_filter = /test2\.css/;
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [{selectorText: '.a'}]},
|
||||
{href: 'test2.css', cssRules: [{selectorText: '.b'}]}
|
||||
]);
|
||||
|
||||
equal(evt.control.items().length, 1);
|
||||
equal(evt.control.items()[0].text(), 'b');
|
||||
});
|
||||
|
||||
test("Import custom importcss_selector_converter", function() {
|
||||
editor.settings.importcss_groups = [
|
||||
{title: 'g1', filter: /\.a/, custom: 'A'},
|
||||
{title: 'g2', filter: /\.b/, custom: 'B'},
|
||||
{title: 'g3', custom: 'C'}
|
||||
];
|
||||
|
||||
editor.contentCSS.push("test1.css");
|
||||
editor.settings.importcss_selector_converter = function (selector, group) {
|
||||
return {
|
||||
title: selector + group.custom,
|
||||
inline: 'span'
|
||||
};
|
||||
};
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [
|
||||
{selectorText: '.a'},
|
||||
{selectorText: '.b'},
|
||||
{selectorText: '.c'}
|
||||
]}
|
||||
]);
|
||||
|
||||
var items = evt.control.items();
|
||||
equal(items.length, 3);
|
||||
equal(items[0].text(), 'g1');
|
||||
equal(items[0].settings.menu[0].text, '.aA');
|
||||
equal(items[1].text(), 'g2');
|
||||
equal(items[1].settings.menu[0].text, '.bB');
|
||||
equal(items[2].text(), 'g3');
|
||||
equal(items[2].settings.menu[0].text, '.cC');
|
||||
});
|
||||
|
||||
test("Import custom group selector_converter", function() {
|
||||
var constant = function (format) {
|
||||
return function () {
|
||||
return format;
|
||||
};
|
||||
};
|
||||
|
||||
var formatA = {
|
||||
title: 'my format a',
|
||||
selector: 'p'
|
||||
};
|
||||
|
||||
var formatB = {
|
||||
title: 'my format b',
|
||||
selector: 'h1'
|
||||
};
|
||||
|
||||
editor.settings.importcss_groups = [
|
||||
{title: 'g1', filter: /\.a/, selector_converter: constant(formatA)},
|
||||
{title: 'g2', filter: /\.b/, selector_converter: constant(formatB)},
|
||||
{title: 'g3', custom: 'C'}
|
||||
];
|
||||
|
||||
editor.contentCSS.push("test1.css");
|
||||
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [
|
||||
{selectorText: '.a'},
|
||||
{selectorText: '.b'},
|
||||
{selectorText: '.c'}
|
||||
]}
|
||||
]);
|
||||
|
||||
var items = evt.control.items();
|
||||
equal(items.length, 3);
|
||||
equal(items[0].text(), 'g1');
|
||||
equal(items[0].settings.menu[0].text, 'my format a');
|
||||
equal(items[1].text(), 'g2');
|
||||
equal(items[1].settings.menu[0].text, 'my format b');
|
||||
equal(items[2].text(), 'g3');
|
||||
equal(items[2].settings.menu[0].text, 'c');
|
||||
});
|
||||
|
||||
test("Import custom importcss_exclusive: true", function() {
|
||||
editor.settings.importcss_exclusive = true;
|
||||
editor.settings.importcss_groups = [
|
||||
{title: 'g1'},
|
||||
{title: 'g2'}
|
||||
];
|
||||
|
||||
editor.contentCSS.push("test1.css");
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [
|
||||
{selectorText: '.a'},
|
||||
{selectorText: '.b'},
|
||||
{selectorText: '.c'}
|
||||
]}
|
||||
]);
|
||||
|
||||
var items = evt.control.items();
|
||||
equal(items.length, 1);
|
||||
equal(items[0].text(), 'g1');
|
||||
equal(items[0].settings.menu[0].text, 'a');
|
||||
equal(items[0].settings.menu[1].text, 'b');
|
||||
});
|
||||
|
||||
test("Import custom importcss_exclusive: false", function() {
|
||||
editor.settings.importcss_exclusive = false;
|
||||
editor.settings.importcss_groups = [
|
||||
{title: 'g1'},
|
||||
{title: 'g2'}
|
||||
];
|
||||
|
||||
editor.contentCSS.push("test1.css");
|
||||
var evt = fireFormatsMenuEvent([
|
||||
{href: 'test1.css', cssRules: [
|
||||
{selectorText: '.a'},
|
||||
{selectorText: '.b'},
|
||||
{selectorText: '.c'}
|
||||
]}
|
||||
]);
|
||||
|
||||
var items = evt.control.items();
|
||||
equal(items.length, 2);
|
||||
equal(items[0].text(), 'g1');
|
||||
equal(items[0].settings.menu[0].text, 'a');
|
||||
equal(items[0].settings.menu[1].text, 'b');
|
||||
equal(items[1].text(), 'g2');
|
||||
equal(items[1].settings.menu[0].text, 'a');
|
||||
equal(items[1].settings.menu[1].text, 'b');
|
||||
});
|
||||
})();
|
||||
@ -1,40 +0,0 @@
|
||||
module("tinymce.plugins.jQueryInitialization", {
|
||||
setupModule: function() {
|
||||
document.getElementById('view').innerHTML = (
|
||||
'<textarea id="elm1"></textarea>' +
|
||||
'<textarea id="elm2"></textarea>'
|
||||
);
|
||||
|
||||
this.val = $.fn.val;
|
||||
|
||||
QUnit.stop();
|
||||
|
||||
$(function() {
|
||||
QUnit.start();
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
$.fn.val = this.val;
|
||||
}
|
||||
});
|
||||
|
||||
test("applyPatch is only called once", function() {
|
||||
expect(1);
|
||||
|
||||
var options = {plugins: [
|
||||
"pagebreak,layer,table,save,emoticons,insertdatetime,preview,media,searchreplace",
|
||||
"print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,template"
|
||||
]},
|
||||
oldValFn;
|
||||
|
||||
$('#elm1').tinymce(options);
|
||||
|
||||
oldValFn = $.fn.val = function() {
|
||||
// no-op
|
||||
};
|
||||
|
||||
$('#elm2').tinymce(options);
|
||||
|
||||
equal($.fn.val, oldValFn);
|
||||
});
|
||||
96
tests/qunit/editor/plugins/jquery_plugin.js
vendored
96
tests/qunit/editor/plugins/jquery_plugin.js
vendored
@ -1,96 +0,0 @@
|
||||
module("tinymce.plugins.jQuery", {
|
||||
setupModule: function() {
|
||||
document.getElementById('view').innerHTML = (
|
||||
'<textarea id="elm1"></textarea>' +
|
||||
'<textarea id="elm2"></textarea>' +
|
||||
'<textarea id="elm3">Textarea</textarea>'
|
||||
);
|
||||
|
||||
QUnit.stop();
|
||||
|
||||
$(function() {
|
||||
$('#elm1,#elm2').tinymce({
|
||||
plugins: [
|
||||
"pagebreak,layer,table,save,emoticons,insertdatetime,preview,media,searchreplace",
|
||||
"print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,template"
|
||||
],
|
||||
|
||||
init_instance_callback: function() {
|
||||
var ed1 = tinymce.get('elm1'), ed2 = tinymce.get('elm2');
|
||||
|
||||
// When both editors are initialized
|
||||
if (ed1 && ed1.initialized && ed2 && ed2.initialized) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test("Get editor instance", function() {
|
||||
equal($('#elm1').tinymce().id, 'elm1');
|
||||
equal($('#elm2').tinymce().id, 'elm2');
|
||||
equal($('#elm3').tinymce(), null);
|
||||
});
|
||||
|
||||
test("Get contents using jQuery", function() {
|
||||
expect(4);
|
||||
|
||||
tinymce.get('elm1').setContent('<p>Editor 1</p>');
|
||||
|
||||
equal($('#elm1').html(), '<p>Editor 1</p>');
|
||||
equal($('#elm1').val(), '<p>Editor 1</p>');
|
||||
equal($('#elm1').attr('value'), '<p>Editor 1</p>');
|
||||
equal($('#elm1').text(), 'Editor 1');
|
||||
});
|
||||
|
||||
test("Set contents using jQuery", function() {
|
||||
expect(4);
|
||||
|
||||
$('#elm1').html('Test 1');
|
||||
equal($('#elm1').html(), '<p>Test 1</p>');
|
||||
|
||||
$('#elm1').val('Test 2');
|
||||
equal($('#elm1').html(), '<p>Test 2</p>');
|
||||
|
||||
$('#elm1').text('Test 3');
|
||||
equal($('#elm1').html(), '<p>Test 3</p>');
|
||||
|
||||
$('#elm1').attr('value', 'Test 4');
|
||||
equal($('#elm1').html(), '<p>Test 4</p>');
|
||||
});
|
||||
|
||||
test("append/prepend contents using jQuery", function() {
|
||||
expect(2);
|
||||
|
||||
tinymce.get('elm1').setContent('<p>Editor 1</p>');
|
||||
|
||||
$('#elm1').append('<p>Test 1</p>');
|
||||
equal($('#elm1').html(), '<p>Editor 1</p>\n<p>Test 1</p>');
|
||||
|
||||
$('#elm1').prepend('<p>Test 2</p>');
|
||||
equal($('#elm1').html(), '<p>Test 2</p>\n<p>Editor 1</p>\n<p>Test 1</p>');
|
||||
});
|
||||
|
||||
test("Find using :tinymce selector", function() {
|
||||
expect(1);
|
||||
|
||||
equal($('textarea:tinymce').length, 2);
|
||||
});
|
||||
|
||||
test("Set contents using :tinymce selector", function() {
|
||||
expect(3);
|
||||
|
||||
$('textarea:tinymce').val('Test 1');
|
||||
equal($('#elm1').val(), '<p>Test 1</p>');
|
||||
equal($('#elm2').val(), '<p>Test 1</p>');
|
||||
equal($('#elm3').val(), 'Textarea');
|
||||
});
|
||||
|
||||
test("Get contents using :tinymce selector", function() {
|
||||
expect(1);
|
||||
|
||||
$('textarea:tinymce').val('Test get');
|
||||
equal($('textarea:tinymce').val(), '<p>Test get</p>');
|
||||
});
|
||||
@ -1,93 +0,0 @@
|
||||
module("tinymce.plugins.Legacyoutput", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
plugins: 'legacyoutput',
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test("Font color", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('forecolor', false, '#FF0000');
|
||||
equal(editor.getContent().toLowerCase(), '<p><font color="#ff0000">text</font></p>');
|
||||
});
|
||||
|
||||
test("Font size", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('fontsize', false, 7);
|
||||
equal(editor.getContent(), '<p><font size="7">text</font></p>');
|
||||
});
|
||||
|
||||
test("Font face", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('fontname', false, "times");
|
||||
equal(editor.getContent(), '<p><font face="times">text</font></p>');
|
||||
});
|
||||
|
||||
test("Bold", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('bold');
|
||||
equal(editor.getContent(), '<p><b>text</b></p>');
|
||||
});
|
||||
|
||||
test("Italic", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('italic');
|
||||
equal(editor.getContent(), '<p><i>text</i></p>');
|
||||
});
|
||||
|
||||
test("Underline", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('underline');
|
||||
equal(editor.getContent(), '<p><u>text</u></p>');
|
||||
});
|
||||
|
||||
test("Strikethrough", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('strikethrough');
|
||||
equal(editor.getContent(), '<p><strike>text</strike></p>');
|
||||
});
|
||||
|
||||
test("Justifyleft", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('justifyleft');
|
||||
equal(editor.getContent(), '<p align="left">text</p>');
|
||||
});
|
||||
|
||||
test("Justifycenter", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('justifycenter');
|
||||
equal(editor.getContent(), '<p align="center">text</p>');
|
||||
});
|
||||
|
||||
test("Justifyright", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('justifyright');
|
||||
equal(editor.getContent(), '<p align="right">text</p>');
|
||||
});
|
||||
|
||||
test("Justifyfull", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('justifyfull');
|
||||
equal(editor.getContent(), '<p align="justify">text</p>');
|
||||
});
|
||||
@ -1,182 +0,0 @@
|
||||
(function() {
|
||||
|
||||
var nonRelativeRegex = /^\w+:/i;
|
||||
|
||||
module("tinymce.plugins.Link", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: 'textarea',
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
indent: false,
|
||||
plugins: "link",
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
delete editor.settings.file_browser_callback;
|
||||
delete editor.settings.link_list;
|
||||
delete editor.settings.link_class_list;
|
||||
delete editor.settings.link_target_list;
|
||||
delete editor.settings.rel_list;
|
||||
|
||||
var win = Utils.getFrontmostWindow();
|
||||
|
||||
if (win) {
|
||||
win.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function cleanHtml(html) {
|
||||
return Utils.cleanHtml(html).replace(/<p>( |<br[^>]+>)<\/p>$/, '');
|
||||
}
|
||||
|
||||
function fillAndSubmitWindowForm(data) {
|
||||
var win = Utils.getFrontmostWindow();
|
||||
|
||||
win.fromJSON(data);
|
||||
win.find('form')[0].submit();
|
||||
win.close();
|
||||
}
|
||||
|
||||
test('Default link dialog on empty editor', function() {
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceLink', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"href": "",
|
||||
"target": "",
|
||||
"text": "",
|
||||
"title": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"href": "href",
|
||||
"target": "_blank",
|
||||
"text": "text",
|
||||
"title": "title"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><a title="title" href="href" target="_blank">text</a></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Default link dialog on text selection', function() {
|
||||
editor.setContent('<p>abc</p>');
|
||||
Utils.setSelection('p', 1, 'p', 2);
|
||||
editor.execCommand('mceLink', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"href": "",
|
||||
"target": "",
|
||||
"text": "b",
|
||||
"title": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"href": "href",
|
||||
"target": "_blank",
|
||||
"title": "title"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p>a<a title="title" href="href" target="_blank">b</a>c</p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Default link dialog on non pure text selection', function() {
|
||||
editor.setContent('<p>a</p><p>bc</p>');
|
||||
Utils.setSelection('p:nth-child(1)', 0, 'p:nth-child(2)', 2);
|
||||
editor.execCommand('mceLink', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"href": "",
|
||||
"target": "",
|
||||
"title": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"href": "href",
|
||||
"target": "_blank",
|
||||
"title": "title"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><a title="title" href="href" target="_blank">a</a></p>' +
|
||||
'<p><a title="title" href="href" target="_blank">bc</a></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('All lists link dialog on empty editor', function() {
|
||||
editor.settings.link_list = [
|
||||
{title: 'link1', value: 'link1'},
|
||||
{title: 'link2', value: 'link2'}
|
||||
];
|
||||
|
||||
editor.settings.link_class_list = [
|
||||
{title: 'class1', value: 'class1'},
|
||||
{title: 'class2', value: 'class2'}
|
||||
];
|
||||
|
||||
editor.settings.target_list = [
|
||||
{title: 'target1', value: 'target1'},
|
||||
{title: 'target2', value: 'target2'}
|
||||
];
|
||||
|
||||
editor.settings.rel_list = [
|
||||
{title: 'rel1', value: 'rel1'},
|
||||
{title: 'rel2', value: 'rel2'}
|
||||
];
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceLink', true);
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
"class": "class1",
|
||||
"href": "",
|
||||
"rel": "rel1",
|
||||
"target": "target1",
|
||||
"text": "",
|
||||
"title": ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"href": "href",
|
||||
"text": "text",
|
||||
"title": "title"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanHtml(editor.getContent()),
|
||||
'<p><a class="class1" title="title" href="href" target="target1" rel="rel1">text</a></p>'
|
||||
);
|
||||
});
|
||||
|
||||
//Since there's no capability to use the confirm dialog with unit tests, simply test the regex we're using
|
||||
test('Test new regex for non relative link setting ftp', function() {
|
||||
equal(nonRelativeRegex.test('ftp://testftp.com'), true);
|
||||
});
|
||||
|
||||
test('Test new regex for non relative link setting http', function() {
|
||||
equal(nonRelativeRegex.test('http://testhttp.com'), true);
|
||||
});
|
||||
|
||||
test('Test new regex for non relative link setting relative', function() {
|
||||
equal(nonRelativeRegex.test('testhttp.com'), false);
|
||||
});
|
||||
|
||||
test('Test new regex for non relative link setting relative base', function() {
|
||||
equal(nonRelativeRegex.test('/testjpg.jpg'), false);
|
||||
});
|
||||
})();
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,205 +0,0 @@
|
||||
module("tinymce.plugins.Media", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
plugins: 'media',
|
||||
live_embeds: false,
|
||||
document_base_url: '/tinymce/tinymce/trunk/tests/',
|
||||
extended_valid_elements: 'script[src|type]',
|
||||
media_scripts: [
|
||||
{filter: 'http://media1.tinymce.com'},
|
||||
{filter: 'http://media2.tinymce.com', width: 100, height: 200}
|
||||
],
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
delete editor.settings.media_filter_html;
|
||||
delete editor.settings.media_live_embeds;
|
||||
}
|
||||
});
|
||||
|
||||
function fillAndSubmitWindowForm(data) {
|
||||
var win = Utils.getFrontmostWindow();
|
||||
|
||||
win.fromJSON(data);
|
||||
win.find('form')[0].submit();
|
||||
win.close();
|
||||
}
|
||||
|
||||
test('Default media dialog on empty editor', function() {
|
||||
editor.settings.media_live_embeds = false;
|
||||
|
||||
editor.setContent('');
|
||||
editor.plugins.media.showDialog();
|
||||
|
||||
deepEqual(Utils.getFrontmostWindow().toJSON(), {
|
||||
constrain: true,
|
||||
embed: "",
|
||||
height: "",
|
||||
poster: "",
|
||||
source1: "",
|
||||
source2: "",
|
||||
width: ""
|
||||
});
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"source1": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
||||
});
|
||||
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<p><iframe src=\"//www.youtube.com/embed/dQw4w9WgXcQ\" width=\"560\" height=\"314\" allowfullscreen=\"allowfullscreen\"></iframe></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Object retain as is", function() {
|
||||
editor.setContent(
|
||||
'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355">' +
|
||||
'<param name="movie" value="someurl">' +
|
||||
'<param name="wmode" value="transparent">' +
|
||||
'<embed src="someurl" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355" />' +
|
||||
'</object>'
|
||||
);
|
||||
|
||||
equal(editor.getContent(),
|
||||
'<p><object width="425" height="355" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000">' +
|
||||
'<param name="movie" value="someurl" />' +
|
||||
'<param name="wmode" value="transparent" />' +
|
||||
'<embed src="someurl" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355" />' +
|
||||
'</object></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Embed retain as is", function() {
|
||||
editor.setContent(
|
||||
'<embed src="320x240.ogg" width="100" height="200">text<a href="#">link</a></embed>'
|
||||
);
|
||||
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<p><embed src="320x240.ogg" width="100" height="200"></embed>text<a href="#">link</a></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Video retain as is", function() {
|
||||
editor.setContent(
|
||||
'<video src="320x240.ogg" autoplay loop controls>text<a href="#">link</a></video>'
|
||||
);
|
||||
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<p><video src="320x240.ogg" autoplay="autoplay" loop="loop" controls="controls" width="300" height="150">text<a href="#">link</a></video></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Iframe retain as is", function() {
|
||||
editor.setContent(
|
||||
'<iframe src="320x240.ogg" allowfullscreen>text<a href="#">link</a></iframe>'
|
||||
);
|
||||
|
||||
equal(editor.getContent(),
|
||||
'<p><iframe src="320x240.ogg" width="300" height="150" allowfullscreen="allowfullscreen">text<a href="#">link</a></iframe></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Audio retain as is", function() {
|
||||
editor.setContent(
|
||||
'<audio src="sound.mp3">' +
|
||||
'<track kind="captions" src="foo.en.vtt" srclang="en" label="English">' +
|
||||
'<track kind="captions" src="foo.sv.vtt" srclang="sv" label="Svenska">' +
|
||||
'text<a href="#">link</a>' +
|
||||
'</audio>'
|
||||
);
|
||||
|
||||
equal(editor.getContent(),
|
||||
'<p>' +
|
||||
'<audio src="sound.mp3">' +
|
||||
'<track kind="captions" src="foo.en.vtt" srclang="en" label="English" />' +
|
||||
'<track kind="captions" src="foo.sv.vtt" srclang="sv" label="Svenska" />' +
|
||||
'text<a href="#">link</a>' +
|
||||
'</audio>' +
|
||||
'</p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Resize complex object", function() {
|
||||
editor.setContent(
|
||||
'<video width="300" height="150" controls="controls">' +
|
||||
'<source src="s" />' +
|
||||
'<object type="application/x-shockwave-flash" data="../../js/tinymce/plugins/media/moxieplayer.swf" width="300" height="150">' +
|
||||
'<param name="allowfullscreen" value="true" />' +
|
||||
'<param name="allowscriptaccess" value="always" />' +
|
||||
'<param name="flashvars" value="video_src=s" />' +
|
||||
'<!--[if IE]><param name="movie" value="../../js/tinymce/plugins/media/moxieplayer.swf" /><![endif]-->' +
|
||||
'</object>' +
|
||||
'</video>'
|
||||
);
|
||||
|
||||
var placeholderElm = editor.getBody().firstChild.firstChild;
|
||||
placeholderElm.width = 100;
|
||||
placeholderElm.height = 200;
|
||||
editor.fire('objectResized', {target: placeholderElm, width: placeholderElm.width, height: placeholderElm.height});
|
||||
editor.settings.media_filter_html = false;
|
||||
|
||||
equal(editor.getContent(),
|
||||
'<p>' +
|
||||
'<video controls="controls" width="100" height="200">' +
|
||||
'<source src="s" />' +
|
||||
'<object type="application/x-shockwave-flash" data="../../js/tinymce/plugins/media/moxieplayer.swf" width="100" height="200">' +
|
||||
'<param name="allowfullscreen" value="true" />' +
|
||||
'<param name="allowscriptaccess" value="always" />' +
|
||||
'<param name="flashvars" value="video_src=s" />' +
|
||||
'<!--[if IE]>' +
|
||||
'<param name="movie" value="../../js/tinymce/plugins/media/moxieplayer.swf" />' +
|
||||
'<![endif]-->' +
|
||||
'</object>' +
|
||||
'</video>' +
|
||||
'</p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Media script elements", function() {
|
||||
editor.setContent(
|
||||
'<script src="http://media1.tinymce.com/123456"></sc' + 'ript>' +
|
||||
'<script src="http://media2.tinymce.com/123456"></sc' + 'ript>'
|
||||
);
|
||||
|
||||
equal(editor.getBody().getElementsByTagName('img')[0].className, 'mce-object mce-object-script');
|
||||
equal(editor.getBody().getElementsByTagName('img')[0].width, 300);
|
||||
equal(editor.getBody().getElementsByTagName('img')[0].height, 150);
|
||||
equal(editor.getBody().getElementsByTagName('img')[1].className, 'mce-object mce-object-script');
|
||||
equal(editor.getBody().getElementsByTagName('img')[1].width, 100);
|
||||
equal(editor.getBody().getElementsByTagName('img')[1].height, 200);
|
||||
|
||||
equal(editor.getContent(),
|
||||
'<p>\n' +
|
||||
'<script src="http://media1.tinymce.com/123456" type="text/javascript"></sc' + 'ript>\n' +
|
||||
'<script src="http://media2.tinymce.com/123456" type="text/javascript"></sc' + 'ript>\n' +
|
||||
'</p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("XSS content", function() {
|
||||
function testXss(input, expectedOutput) {
|
||||
editor.setContent(input);
|
||||
equal(editor.getContent(), expectedOutput);
|
||||
}
|
||||
|
||||
testXss('<video><a href="javascript:alert(1);">a</a></video>', '<p><video width="300" height="150"><a>a</a></video></p>');
|
||||
testXss('<video><img src="x" onload="alert(1)"></video>', '<p><video width="300" height=\"150\"></video></p>');
|
||||
testXss('<video><img src="x"></video>', '<p><video width="300" height="150"><img src="x" /></video></p>');
|
||||
testXss('<video><!--[if IE]><img src="x"><![endif]--></video>', '<p><video width="300" height="150"><!-- [if IE]><img src="x"><![endif]--></video></p>');
|
||||
testXss('<p><p><audio><audio src=x onerror=alert(1)>', '<p><audio></audio></p>');
|
||||
testXss('<p><html><audio><br /><audio src=x onerror=alert(1)></p>', '');
|
||||
testXss('<p><audio><img src="javascript:alert(1)"></audio>', '<p><audio><img /></audio></p>');
|
||||
testXss('<p><audio><img src="x" style="behavior:url(x); width: 1px"></audio>', '<p><audio><img src="x" style="width: 1px;" /></audio></p>');
|
||||
});
|
||||
@ -1,45 +0,0 @@
|
||||
module("tinymce.plugins.Noneditable", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
indent: false,
|
||||
noneditable_regexp: [/\{[^\}]+\}/g],
|
||||
plugins: 'noneditable',
|
||||
convert_fonts_to_spans: false,
|
||||
entities: 'raw',
|
||||
valid_styles: {
|
||||
'*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display'
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Ignore on IE 7, 8 this is a known bug not worth fixing
|
||||
if (tinymce.Env.ceFalse) {
|
||||
test('noneditable class', function() {
|
||||
editor.setContent('<p><span class="mceNonEditable">abc</span></p>');
|
||||
equal(editor.dom.select('span')[0].contentEditable, "false");
|
||||
});
|
||||
|
||||
test('editable class', function() {
|
||||
editor.setContent('<p><span class="mceEditable">abc</span></p>');
|
||||
equal(editor.dom.select('span')[0].contentEditable, "true");
|
||||
});
|
||||
|
||||
test('noneditable regexp', function() {
|
||||
editor.setContent('<p>{test1}{test2}</p>');
|
||||
|
||||
equal(editor.dom.select('span').length, 2);
|
||||
equal(editor.dom.select('span')[0].contentEditable, "false");
|
||||
equal(editor.dom.select('span')[1].contentEditable, "false");
|
||||
equal(editor.getContent(), '<p>{test1}{test2}</p>');
|
||||
});
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -1,188 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/pasteplugin/Clipboard",
|
||||
"tinymce/Env",
|
||||
"tinymce/util/Delay",
|
||||
"tinymce/util/Promise"
|
||||
], function(Clipboard, Env, Delay, Promise) {
|
||||
var base64ImgSrc = [
|
||||
'R0lGODdhZABkAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQECgAAACwAAAAAZABkAIEAAAD78jY/',
|
||||
'P3SsMjIC/4SPqcvtD6OctNqLs968+w+G4kiW5ommR8C27gvHrxrK9g3TIM7f+tcL5n4doZFFLB6F',
|
||||
'Sc6SCRFIp9SqVTp6BiPXbjer5XG95Ck47IuWy2e0bLz2tt3DR5w8p7vgd2tej6TW5ycCGMM3aFZo',
|
||||
'OCOYqFjDuOf4KPAHiPh4qZeZuEnXOfjpFto3ilZ6dxqWGreq1br2+hTLtigZaFcJuYOb67DLC+Qb',
|
||||
'UIt3i2sshyzZtEFc7JwBLT1NXI2drb3N3e39DR4uPk5ebn6Onq6+zu488A4fLz9P335Aj58fb2+g',
|
||||
'71/P759AePwADBxY8KDAhAr9MWyY7yFEgPYmRgxokWK7jEYa2XGcJ/HjgJAfSXI0mRGlRZUTWUJ0',
|
||||
'2RCmQpkHaSLEKPKdzYU4c+78VzCo0KFEixo9ijSp0qVMmzp9CjWq1KlUq1q9eqEAADs='
|
||||
].join('');
|
||||
|
||||
if (!Env.fileApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
module("tinymce.plugins.Paste - Images", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
automatic_uploads: false,
|
||||
plugins: "paste",
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
delete editor.settings.paste_data_images;
|
||||
delete editor.settings.images_dataimg_filter;
|
||||
editor.editorUpload.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
var base64ToBlob = function (base64, type) {
|
||||
var buff = atob(base64);
|
||||
var bytes = new Uint8Array(buff.length);
|
||||
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
bytes[i] = buff.charCodeAt(i);
|
||||
}
|
||||
|
||||
return new Blob([bytes], {type: type});
|
||||
};
|
||||
|
||||
var noop = function () {
|
||||
};
|
||||
|
||||
var mockEvent = function (type) {
|
||||
var event, transferName;
|
||||
|
||||
event = {
|
||||
type: type,
|
||||
preventDefault: noop
|
||||
};
|
||||
|
||||
transferName = type === 'drop' ? 'dataTransfer' : 'clipboardData';
|
||||
event[transferName] = {
|
||||
files: [
|
||||
base64ToBlob(base64ImgSrc, 'image/gif')
|
||||
]
|
||||
};
|
||||
|
||||
return event;
|
||||
};
|
||||
|
||||
var setupContent = function () {
|
||||
editor.setContent('<p>a</p>');
|
||||
Utils.setSelection('p', 0);
|
||||
return editor.selection.getRng();
|
||||
};
|
||||
|
||||
var waitForSelector = function (selector) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var check = function (time, count) {
|
||||
var result = editor.dom.select(selector);
|
||||
|
||||
if (result.length > 0) {
|
||||
resolve(result);
|
||||
} else {
|
||||
if (count === 0) {
|
||||
reject();
|
||||
} else {
|
||||
Delay.setTimeout(function () {
|
||||
check(time, count--);
|
||||
}, time);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
check(10, 100);
|
||||
});
|
||||
};
|
||||
|
||||
var fail = function () {
|
||||
ok(false, 'Failed to get image due to timeout.');
|
||||
QUnit.start();
|
||||
};
|
||||
|
||||
asyncTest('dropImages', function() {
|
||||
var rng, event, clipboard = new Clipboard(editor);
|
||||
|
||||
editor.settings.paste_data_images = true;
|
||||
rng = setupContent();
|
||||
|
||||
event = mockEvent('drop');
|
||||
clipboard.pasteImageData(event, rng);
|
||||
|
||||
waitForSelector('img').then(function () {
|
||||
equal(editor.getContent(), '<p><img src=\"data:image/gif;base64,' + base64ImgSrc + '" />a</p>');
|
||||
strictEqual(editor.dom.select('img')[0].src.indexOf('blob:'), 0);
|
||||
|
||||
QUnit.start();
|
||||
}, fail);
|
||||
});
|
||||
|
||||
asyncTest('pasteImages', function() {
|
||||
var rng, event, clipboard = new Clipboard(editor);
|
||||
|
||||
editor.settings.paste_data_images = true;
|
||||
rng = setupContent();
|
||||
|
||||
event = mockEvent('paste');
|
||||
clipboard.pasteImageData(event, rng);
|
||||
|
||||
waitForSelector('img').then(function () {
|
||||
equal(editor.getContent(), '<p><img src=\"data:image/gif;base64,' + base64ImgSrc + '" />a</p>');
|
||||
strictEqual(editor.dom.select('img')[0].src.indexOf('blob:'), 0);
|
||||
|
||||
QUnit.start();
|
||||
}, fail);
|
||||
});
|
||||
|
||||
asyncTest('dropImages - images_dataimg_filter', function() {
|
||||
var rng, event, clipboard = new Clipboard(editor);
|
||||
|
||||
editor.settings.paste_data_images = true;
|
||||
editor.settings.images_dataimg_filter = function (img) {
|
||||
strictEqual(img.src, 'data:image/gif;base64,' + base64ImgSrc);
|
||||
return false;
|
||||
};
|
||||
rng = setupContent();
|
||||
|
||||
event = mockEvent('drop');
|
||||
clipboard.pasteImageData(event, rng);
|
||||
|
||||
waitForSelector('img').then(function () {
|
||||
equal(editor.getContent(), '<p><img src=\"data:image/gif;base64,' + base64ImgSrc + '" />a</p>');
|
||||
strictEqual(editor.dom.select('img')[0].src.indexOf('data:'), 0);
|
||||
|
||||
QUnit.start();
|
||||
}, fail);
|
||||
});
|
||||
|
||||
asyncTest('pasteImages - images_dataimg_filter', function() {
|
||||
var rng, event, clipboard = new Clipboard(editor);
|
||||
|
||||
editor.settings.paste_data_images = true;
|
||||
editor.settings.images_dataimg_filter = function (img) {
|
||||
strictEqual(img.src, 'data:image/gif;base64,' + base64ImgSrc);
|
||||
return false;
|
||||
};
|
||||
rng = setupContent();
|
||||
|
||||
event = mockEvent('paste');
|
||||
clipboard.pasteImageData(event, rng);
|
||||
|
||||
waitForSelector('img').then(function () {
|
||||
equal(editor.getContent(), '<p><img src=\"data:image/gif;base64,' + base64ImgSrc + '" />a</p>');
|
||||
strictEqual(editor.dom.select('img')[0].src.indexOf('data:'), 0);
|
||||
|
||||
QUnit.start();
|
||||
}, fail);
|
||||
});
|
||||
});
|
||||
@ -1,88 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/pasteplugin/SmartPaste"
|
||||
], function (SmartPaste) {
|
||||
module("tinymce.plugins.Paste_smart", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
indent: false,
|
||||
plugins: 'paste',
|
||||
setup: function(ed) {
|
||||
ed.on('NodeChange', false);
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
delete ed.settings.smart_paste;
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('isAbsoluteUrl', function() {
|
||||
equal(SmartPaste.isAbsoluteUrl('http://www.site.com'), true);
|
||||
equal(SmartPaste.isAbsoluteUrl('https://www.site.com'), true);
|
||||
equal(SmartPaste.isAbsoluteUrl('http://www.site.com/dir-name/file.gif?query=%42'), true);
|
||||
equal(SmartPaste.isAbsoluteUrl('https://www.site.com/dir-name/file.gif?query=%42'), true);
|
||||
equal(SmartPaste.isAbsoluteUrl('https://www.site.com/dir-name/file.gif?query=%42#a'), true);
|
||||
equal(SmartPaste.isAbsoluteUrl('https://www.site.com/~abc'), true);
|
||||
equal(SmartPaste.isAbsoluteUrl('file.gif'), false);
|
||||
equal(SmartPaste.isAbsoluteUrl(''), false);
|
||||
});
|
||||
|
||||
test('isImageUrl', function() {
|
||||
equal(SmartPaste.isImageUrl('http://www.site.com'), false);
|
||||
equal(SmartPaste.isImageUrl('https://www.site.com'), false);
|
||||
equal(SmartPaste.isImageUrl('http://www.site.com/dir-name/file.jpeg'), true);
|
||||
equal(SmartPaste.isImageUrl('http://www.site.com/dir-name/file.jpg'), true);
|
||||
equal(SmartPaste.isImageUrl('http://www.site.com/dir-name/file.png'), true);
|
||||
equal(SmartPaste.isImageUrl('http://www.site.com/dir-name/file.gif'), true);
|
||||
equal(SmartPaste.isImageUrl('https://www.site.com/dir-name/file.gif'), true);
|
||||
equal(SmartPaste.isImageUrl('https://www.site.com/~dir-name/file.gif'), true);
|
||||
equal(SmartPaste.isImageUrl('https://www.site.com/dir-name/file.gif?query=%42'), false);
|
||||
equal(SmartPaste.isImageUrl('https://www.site.com/dir-name/file.html?query=%42'), false);
|
||||
equal(SmartPaste.isImageUrl('file.gif'), false);
|
||||
equal(SmartPaste.isImageUrl(''), false);
|
||||
});
|
||||
|
||||
test('smart paste url on selection', function() {
|
||||
editor.focus();
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('<p>abc</p>');
|
||||
Utils.setSelection('p', 0, 'p', 3);
|
||||
editor.undoManager.add();
|
||||
|
||||
editor.execCommand('mceInsertClipboardContent', false, {content: 'http://www.site.com'});
|
||||
equal(editor.getContent(), '<p><a href="http://www.site.com">abc</a></p>');
|
||||
equal(editor.undoManager.data.length, 3);
|
||||
});
|
||||
|
||||
test('smart paste image url', function() {
|
||||
editor.focus();
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('<p>abc</p>');
|
||||
Utils.setSelection('p', 1);
|
||||
editor.undoManager.add();
|
||||
|
||||
editor.execCommand('mceInsertClipboardContent', false, {content: 'http://www.site.com/my.jpg'});
|
||||
equal(editor.getContent(), '<p>a<img src="http://www.site.com/my.jpg" />bc</p>');
|
||||
equal(editor.undoManager.data.length, 3);
|
||||
});
|
||||
|
||||
test('smart paste option disabled', function() {
|
||||
editor.focus();
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('<p>abc</p>');
|
||||
Utils.setSelection('p', 1);
|
||||
editor.undoManager.add();
|
||||
editor.settings.smart_paste = false;
|
||||
|
||||
editor.execCommand('mceInsertClipboardContent', false, {content: 'http://www.site.com/my.jpg'});
|
||||
equal(editor.getContent(), '<p>ahttp://www.site.com/my.jpgbc</p>');
|
||||
equal(editor.undoManager.data.length, 2);
|
||||
});
|
||||
});
|
||||
@ -1,122 +0,0 @@
|
||||
module("tinymce.plugins.SearchReplace", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
plugins: "searchreplace",
|
||||
elements: "elm1",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
indent: false,
|
||||
disable_nodechange: true,
|
||||
valid_elements: 'b,i',
|
||||
init_instance_callback : function(ed) {
|
||||
window.editor = ed;
|
||||
tinymce.util.Delay.setTimeout(function() {
|
||||
QUnit.start();
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('Find no match', function() {
|
||||
editor.getBody().innerHTML = 'a';
|
||||
equal(0, editor.plugins.searchreplace.find('x'));
|
||||
});
|
||||
|
||||
test('Find single match', function() {
|
||||
editor.getBody().innerHTML = 'a';
|
||||
equal(1, editor.plugins.searchreplace.find('a'));
|
||||
});
|
||||
|
||||
test('Find single match in multiple elements', function() {
|
||||
editor.getBody().innerHTML = 't<b>e</b><i>xt</i>';
|
||||
equal(1, editor.plugins.searchreplace.find('text'));
|
||||
});
|
||||
|
||||
test('Find single match, match case: true', function() {
|
||||
editor.getBody().innerHTML = 'a A';
|
||||
equal(1, editor.plugins.searchreplace.find('A', true));
|
||||
});
|
||||
|
||||
test('Find single match, whole words: true', function() {
|
||||
editor.getBody().innerHTML = 'a Ax';
|
||||
equal(1, editor.plugins.searchreplace.find('a', false, true));
|
||||
});
|
||||
|
||||
test('Find multiple matches', function() {
|
||||
editor.getBody().innerHTML = 'a b A';
|
||||
equal(2, editor.plugins.searchreplace.find('a'));
|
||||
});
|
||||
|
||||
test('Find and replace single match', function() {
|
||||
editor.getBody().innerHTML = 'a';
|
||||
editor.plugins.searchreplace.find('a');
|
||||
ok(!editor.plugins.searchreplace.replace('x'));
|
||||
equal("<p>x</p>", editor.getContent());
|
||||
});
|
||||
|
||||
test('Find and replace first in multiple matches', function() {
|
||||
editor.getBody().innerHTML = 'a b a';
|
||||
editor.plugins.searchreplace.find('a');
|
||||
ok(editor.plugins.searchreplace.replace('x'));
|
||||
equal("<p>x b a</p>", editor.getContent());
|
||||
});
|
||||
|
||||
test('Find and replace all in multiple matches', function() {
|
||||
editor.getBody().innerHTML = 'a b a';
|
||||
editor.plugins.searchreplace.find('a');
|
||||
ok(!editor.plugins.searchreplace.replace('x', true, true));
|
||||
equal("<p>x b x</p>", editor.getContent());
|
||||
});
|
||||
|
||||
test('Find multiple matches, move to next and replace', function() {
|
||||
editor.getBody().innerHTML = 'a a';
|
||||
equal(2, editor.plugins.searchreplace.find('a'));
|
||||
editor.plugins.searchreplace.next();
|
||||
ok(!editor.plugins.searchreplace.replace('x'));
|
||||
equal("<p>a x</p>", editor.getContent());
|
||||
});
|
||||
|
||||
test('Find and replace fragmented match', function() {
|
||||
editor.getBody().innerHTML = '<b>te<i>s</i>t</b><b>te<i>s</i>t</b>';
|
||||
editor.plugins.searchreplace.find('test');
|
||||
ok(editor.plugins.searchreplace.replace('abc'));
|
||||
equal(editor.getContent(), "<p><b>abc</b><b>te<i>s</i>t</b></p>");
|
||||
});
|
||||
|
||||
test('Find and replace all fragmented matches', function() {
|
||||
editor.getBody().innerHTML = '<b>te<i>s</i>t</b><b>te<i>s</i>t</b>';
|
||||
editor.plugins.searchreplace.find('test');
|
||||
ok(!editor.plugins.searchreplace.replace('abc', true, true));
|
||||
equal(editor.getContent(), "<p><b>abc</b><b>abc</b></p>");
|
||||
});
|
||||
|
||||
test('Find multiple matches, move to next and replace backwards', function() {
|
||||
editor.getBody().innerHTML = 'a a';
|
||||
equal(2, editor.plugins.searchreplace.find('a'));
|
||||
editor.plugins.searchreplace.next();
|
||||
ok(editor.plugins.searchreplace.replace('x', false));
|
||||
ok(!editor.plugins.searchreplace.replace('y', false));
|
||||
equal("<p>y x</p>", editor.getContent());
|
||||
});
|
||||
|
||||
test('Find multiple matches and unmark them', function() {
|
||||
editor.getBody().innerHTML = 'a b a';
|
||||
equal(2, editor.plugins.searchreplace.find('a'));
|
||||
editor.plugins.searchreplace.done();
|
||||
equal('a', editor.selection.getContent());
|
||||
equal(0, editor.getBody().getElementsByTagName('span').length);
|
||||
});
|
||||
|
||||
test('Find multiple matches with pre blocks', function() {
|
||||
editor.getBody().innerHTML = 'abc<pre> abc </pre>abc';
|
||||
equal(3, editor.plugins.searchreplace.find('b'));
|
||||
equal(Utils.normalizeHtml(editor.getBody().innerHTML), (
|
||||
'a<span class="mce-match-marker mce-match-marker-selected" data-mce-bogus="1" data-mce-index="0">b</span>c' +
|
||||
'<pre> a<span class="mce-match-marker" data-mce-bogus="1" data-mce-index="1">b</span>c </pre>' +
|
||||
'a<span class="mce-match-marker" data-mce-bogus="1" data-mce-index="2">b</span>c'
|
||||
));
|
||||
});
|
||||
@ -1,95 +0,0 @@
|
||||
(function() {
|
||||
var count = 0;
|
||||
|
||||
module("tinymce.plugins.Spellchecker", {
|
||||
setupModule: function() {
|
||||
document.getElementById('view').innerHTML = (
|
||||
'<textarea id="no_lang"></textarea>' +
|
||||
'<textarea id="one_lang"></textarea>' +
|
||||
'<textarea id="many_lang"></textarea>'
|
||||
);
|
||||
|
||||
QUnit.stop();
|
||||
|
||||
function wait() {
|
||||
if (++count == 3) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
|
||||
tinymce.init({
|
||||
selector: '#no_lang',
|
||||
plugins: "spellchecker",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
disable_nodechange: true,
|
||||
toolbar: 'spellchecker',
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
wait();
|
||||
}
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
selector: '#one_lang',
|
||||
plugins: "spellchecker",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
spellchecker_languages: 'English=en',
|
||||
disable_nodechange: true,
|
||||
toolbar: 'spellchecker',
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
wait();
|
||||
}
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
selector: '#many_lang',
|
||||
plugins: "spellchecker",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
spellchecker_languages: 'English=en,French=fr,German=de',
|
||||
disable_nodechange: true,
|
||||
toolbar: 'spellchecker',
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
wait();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
editor.settings.forced_root_block = 'p';
|
||||
}
|
||||
});
|
||||
|
||||
// Default spellchecker language should match editor language
|
||||
test('Check default language', function() {
|
||||
var mainLanguage = tinymce.get('no_lang').settings.language || 'en';
|
||||
equal(tinymce.get('no_lang').settings.spellchecker_language, mainLanguage);
|
||||
});
|
||||
|
||||
// Spellchecker button may include a language menu
|
||||
|
||||
// When no languages are specified, the default list of languages should be
|
||||
// used, matching the list in the old TinyMCE 3 spellchecker plugin.
|
||||
test('Check spellcheck button is a splitbutton (no languages)', function() {
|
||||
var spellcheckButton = tinymce.get('no_lang').buttons.spellchecker;
|
||||
equal(spellcheckButton.type, 'splitbutton');
|
||||
});
|
||||
|
||||
// When exactly one spellchecker language is specified, there's no need to
|
||||
// display a selection menu.
|
||||
test('Check spellcheck button is a normal button (one language)', function() {
|
||||
var spellcheckButton = tinymce.get('one_lang').buttons.spellchecker;
|
||||
equal(spellcheckButton.type, 'button');
|
||||
});
|
||||
|
||||
// When more than one spellchecker language is specified, a selection menu
|
||||
// should be provided to choose between them.
|
||||
test('Check spellcheck button is a splitbutton (many languages)', function() {
|
||||
var spellcheckButton = tinymce.get('many_lang').buttons.spellchecker;
|
||||
equal(spellcheckButton.type, 'splitbutton');
|
||||
});
|
||||
})();
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,126 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.plugins.TextPattern", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: 'textarea',
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
indent: false,
|
||||
plugins: "textpattern",
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
delete editor.settings.textpattern_patterns;
|
||||
}
|
||||
});
|
||||
|
||||
test('Italic format on single word using space', function() {
|
||||
editor.setContent('<p>*abc*\u00a0</p>');
|
||||
Utils.setSelection('p', 6);
|
||||
editor.fire('keyup', {keyCode: 32});
|
||||
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<p><em>abc</em> </p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Bold format on single word using space', function() {
|
||||
editor.setContent('<p>**abc**\u00a0</p>');
|
||||
Utils.setSelection('p', 8);
|
||||
editor.fire('keyup', {keyCode: 32});
|
||||
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<p><strong>abc</strong> </p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Bold format on multiple words using space', function() {
|
||||
editor.setContent('<p>**abc 123**\u00a0</p>');
|
||||
Utils.setSelection('p', 12);
|
||||
editor.fire('keyup', {keyCode: 32});
|
||||
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<p><strong>abc 123</strong> </p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Bold format on single word using enter', function() {
|
||||
editor.setContent('<p>**abc**</p>');
|
||||
Utils.setSelection('p', 7);
|
||||
editor.fire('keydown', {keyCode: 13});
|
||||
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<p><strong>abc</strong></p><p> </p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('H1 format on single word node using enter', function() {
|
||||
editor.setContent('<p>#abc</p>');
|
||||
Utils.setSelection('p', 4);
|
||||
editor.fire('keydown', {keyCode: 13});
|
||||
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<h1>abc</h1><p> </p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('OL format on single word node using enter', function() {
|
||||
editor.setContent('<p>1. abc</p>');
|
||||
Utils.setSelection('p', 6);
|
||||
editor.fire('keydown', {keyCode: 13});
|
||||
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<ol><li>abc</li><li></li></ol>'
|
||||
);
|
||||
});
|
||||
|
||||
test('UL format on single word node using enter', function() {
|
||||
editor.setContent('<p>* abc</p>');
|
||||
Utils.setSelection('p', 5);
|
||||
editor.fire('keydown', {keyCode: 13});
|
||||
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<ul><li>abc</li><li></li></ul>'
|
||||
);
|
||||
});
|
||||
|
||||
test('getPatterns/setPatterns', function() {
|
||||
editor.plugins.textpattern.setPatterns([
|
||||
{start: '#', format: 'h1'},
|
||||
{start: '##', format: 'h2'},
|
||||
{start: '###', format: 'h3'}
|
||||
]);
|
||||
|
||||
deepEqual(
|
||||
editor.plugins.textpattern.getPatterns(),
|
||||
[
|
||||
{
|
||||
"format": "h3",
|
||||
"start": "###"
|
||||
},
|
||||
{
|
||||
"format": "h2",
|
||||
"start": "##"
|
||||
},
|
||||
{
|
||||
"format": "h1",
|
||||
"start": "#"
|
||||
}
|
||||
]
|
||||
);
|
||||
});
|
||||
})();
|
||||
@ -1,81 +0,0 @@
|
||||
module("tinymce.plugins.Wordcount", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
wordcount_target_id: 'current-count',
|
||||
plugins: 'wordcount',
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test("Blank document has 0 words", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 0);
|
||||
});
|
||||
|
||||
test("Simple word count", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>My sentence is this.</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 4);
|
||||
});
|
||||
|
||||
test("Does not count dashes", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>Something -- ok</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 2);
|
||||
});
|
||||
|
||||
test("Does not count asterisks, non-word characters", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>* something\n\u00b7 something else</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 3);
|
||||
});
|
||||
|
||||
test("Does not count numbers", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>Something 123 ok</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 2);
|
||||
});
|
||||
|
||||
test("Does not count htmlentities", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>It’s my life – – – don\'t you forget.</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 6);
|
||||
});
|
||||
|
||||
test("Counts hyphenated words as one word", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>Hello some-word here.</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 3);
|
||||
});
|
||||
|
||||
test("Counts words between blocks as two words", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>Hello</p><p>world</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 2);
|
||||
});
|
||||
@ -492,7 +492,36 @@ test('translate', function() {
|
||||
equal(editor.translate('input i18n'), 'output i18n');
|
||||
});
|
||||
|
||||
test('Treat some paragraphs as empty contents', function() {
|
||||
editor.setContent('<p><br /></p>');
|
||||
equal(editor.getContent(), '');
|
||||
|
||||
editor.setContent('<p>\u00a0</p>');
|
||||
equal(editor.getContent(), '');
|
||||
});
|
||||
|
||||
test('kamer word bounderies', function() {
|
||||
editor.setContent('<p>!\u200b!\u200b!</p>');
|
||||
equal(editor.getContent(), '<p>!\u200b!\u200b!</p>');
|
||||
});
|
||||
});
|
||||
|
||||
test('Padd empty elements with br', function() {
|
||||
editor.settings.padd_empty_with_br = true;
|
||||
editor.setContent('<p>a</p><p></p>');
|
||||
equal(editor.getContent(), '<p>a</p><p><br /></p>');
|
||||
delete editor.settings.padd_empty_with_br;
|
||||
});
|
||||
|
||||
test('Padd empty elements with br on insert at caret', function() {
|
||||
editor.settings.padd_empty_with_br = true;
|
||||
editor.setContent('<p>a</p>');
|
||||
Utils.setSelection('p', 1);
|
||||
editor.insertContent('<p>b</p><p></p>');
|
||||
equal(editor.getContent(), '<p>a</p><p>b</p><p><br /></p>');
|
||||
delete editor.settings.padd_empty_with_br;
|
||||
});
|
||||
|
||||
test('Preserve whitespace pre elements', function() {
|
||||
editor.setContent('<pre> </pre>');
|
||||
equal(editor.getContent(), '<pre> </pre>');
|
||||
});
|
||||
|
||||
@ -750,6 +750,13 @@ test('unlink', function() {
|
||||
equal(editor.getContent(), '<p>test 123</p>');
|
||||
});
|
||||
|
||||
test('unlink - unselected a[href] with childNodes', function() {
|
||||
editor.setContent('<p><a href="test"><strong><em>test</em></strong></a></p>');
|
||||
Utils.setSelection('em', 0);
|
||||
editor.execCommand('unlink');
|
||||
equal(editor.getContent(), '<p><strong><em>test</em></strong></p>');
|
||||
});
|
||||
|
||||
test('subscript/superscript', function() {
|
||||
expect(4);
|
||||
|
||||
@ -803,6 +810,33 @@ test('indent/outdent', function() {
|
||||
equal(editor.getContent(), '<p>test 123</p>');
|
||||
});
|
||||
|
||||
test('indent/outdent table always uses margin', function () {
|
||||
expect(4);
|
||||
|
||||
editor.setContent('<table><tbody><tr><td>test</td></tr></tbody></table>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Indent');
|
||||
equal(editor.getContent(), '<table style="margin-left: 30px;"><tbody><tr><td>test</td></tr></tbody></table>');
|
||||
|
||||
editor.setContent('<table><tbody><tr><td>test</td></tr></tbody></table>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Indent');
|
||||
editor.execCommand('Indent');
|
||||
equal(editor.getContent(), '<table style="margin-left: 60px;"><tbody><tr><td>test</td></tr></tbody></table>');
|
||||
|
||||
editor.setContent('<table><tbody><tr><td>test</td></tr></tbody></table>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Indent');
|
||||
editor.execCommand('Indent');
|
||||
editor.execCommand('Outdent');
|
||||
equal(editor.getContent(), '<table style="margin-left: 30px;"><tbody><tr><td>test</td></tr></tbody></table>');
|
||||
|
||||
editor.setContent('<table><tbody><tr><td>test</td></tr></tbody></table>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Outdent');
|
||||
equal(editor.getContent(), '<table><tbody><tr><td>test</td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test('RemoveFormat', function() {
|
||||
expect(4);
|
||||
|
||||
@ -827,6 +861,17 @@ test('RemoveFormat', function() {
|
||||
equal(editor.getContent(), '<p>dfn tag code tag samp tag kbd tag var tag cite tag mark tag q tag</p>');
|
||||
});
|
||||
|
||||
if (tinymce.Env.ceFalse) {
|
||||
test('SelectAll', function() {
|
||||
editor.setContent('<p>a</p><div contenteditable="false"><div contenteditable="true">b</div><p>c</p>');
|
||||
Utils.setSelection('div div', 0);
|
||||
editor.execCommand('SelectAll');
|
||||
equal(editor.selection.getStart().nodeName, 'DIV');
|
||||
equal(editor.selection.getEnd().nodeName, 'DIV');
|
||||
equal(editor.selection.isCollapsed(), false);
|
||||
});
|
||||
}
|
||||
|
||||
test('InsertLineBreak', function() {
|
||||
editor.setContent('<p>123</p>');
|
||||
Utils.setSelection('p', 2);
|
||||
|
||||
43
tests/qunit/editor/tinymce/EditorCustomTheme.js
Normal file
43
tests/qunit/editor/tinymce/EditorCustomTheme.js
Normal file
@ -0,0 +1,43 @@
|
||||
ModuleLoader.require([
|
||||
], function() {
|
||||
module("tinymce.EditorCustomTheme", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
theme: function (editor, targetnode) {
|
||||
var editorContainer = document.createElement('div');
|
||||
editorContainer.id = 'editorContainer';
|
||||
|
||||
var iframeContainer = document.createElement('div');
|
||||
iframeContainer.id = 'iframeContainer';
|
||||
|
||||
editorContainer.appendChild(iframeContainer);
|
||||
targetnode.parentNode.insertBefore(editorContainer, targetnode);
|
||||
|
||||
return {
|
||||
iframeContainer: iframeContainer,
|
||||
editorContainer: editorContainer
|
||||
};
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('getContainer/getContentAreaContainer', function() {
|
||||
QUnit.equal(editor.getContainer().id, 'editorContainer', 'Should be the new editorContainer element');
|
||||
QUnit.equal(editor.getContainer().nodeType, 1, 'Should be an element');
|
||||
QUnit.equal(editor.getContentAreaContainer().id, 'iframeContainer', 'Should be the new iframeContainer element');
|
||||
QUnit.equal(editor.getContentAreaContainer().nodeType, 1, 'Should be an element');
|
||||
});
|
||||
});
|
||||
@ -98,12 +98,16 @@ asyncTest('Init/remove on same id', function() {
|
||||
});
|
||||
|
||||
asyncTest('Init editor async with proper editors state', function() {
|
||||
var unloadTheme = function(name) {
|
||||
var url = tinymce.baseURI.toAbsolute('themes/' + name + '/theme.js');
|
||||
var unloadUrl = function (url) {
|
||||
tinymce.dom.ScriptLoader.ScriptLoader.remove(url);
|
||||
tinymce.ThemeManager.remove(name);
|
||||
};
|
||||
|
||||
var unloadTheme = function(name) {
|
||||
unloadUrl(tinymce.baseURI.toAbsolute('themes/' + name + '/theme.min.js'));
|
||||
unloadUrl(tinymce.baseURI.toAbsolute('themes/' + name + '/theme.js'));
|
||||
};
|
||||
|
||||
tinymce.remove();
|
||||
|
||||
var init = function() {
|
||||
@ -141,6 +145,9 @@ test('overrideDefaults', function() {
|
||||
external_plugins: {
|
||||
"plugina": "//domain/plugina.js",
|
||||
"pluginb": "//domain/pluginb.js"
|
||||
},
|
||||
plugin_base_urls: {
|
||||
testplugin: 'http://custom.ephox.com/dir/testplugin'
|
||||
}
|
||||
});
|
||||
|
||||
@ -148,11 +155,15 @@ test('overrideDefaults', function() {
|
||||
strictEqual(tinymce.baseURL, "http://www.tinymce.com/base");
|
||||
strictEqual(tinymce.suffix, "x");
|
||||
strictEqual(new tinymce.Editor('ed1', {}, tinymce).settings.test, 42);
|
||||
strictEqual(tinymce.PluginManager.urls.testplugin, 'http://custom.ephox.com/dir/testplugin');
|
||||
|
||||
deepEqual(new tinymce.Editor('ed2', {
|
||||
external_plugins: {
|
||||
"plugina": "//domain/plugina2.js",
|
||||
"pluginc": "//domain/pluginc.js"
|
||||
},
|
||||
plugin_base_urls: {
|
||||
testplugin: 'http://custom.ephox.com/dir/testplugin'
|
||||
}
|
||||
}, tinymce).settings.external_plugins, {
|
||||
"plugina": "//domain/plugina2.js",
|
||||
|
||||
@ -235,7 +235,8 @@ ModuleLoader.require([
|
||||
|
||||
if (callCount == 2) {
|
||||
QUnit.start();
|
||||
equal(uploadCount, 1, 'Should only be one upload.');
|
||||
// This is in exact since the status of the image can be pending or failed meaing it should try again
|
||||
ok(uploadCount >= 1, 'Should at least be one.');
|
||||
}
|
||||
|
||||
equal(result[0].element, editor.$('img')[0]);
|
||||
|
||||
@ -1098,3 +1098,24 @@ if (window.getSelection) {
|
||||
notEqual(rng.startContainer.data, ' ');
|
||||
});
|
||||
}
|
||||
|
||||
if (tinymce.Env.ceFalse) {
|
||||
test('Enter before cE=false div', function() {
|
||||
editor.getBody().innerHTML = '<div contenteditable="false">x</div>';
|
||||
editor.selection.select(editor.dom.select('div')[0]);
|
||||
editor.selection.collapse(true);
|
||||
Utils.pressEnter();
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p><br data-mce-bogus="1"></p><div contenteditable="false">x</div>');
|
||||
equal(editor.selection.getNode().nodeName, 'P');
|
||||
});
|
||||
|
||||
test('Enter after cE=false div', function() {
|
||||
editor.getBody().innerHTML = '<div contenteditable="false">x</div>';
|
||||
editor.selection.select(editor.dom.select('div')[0]);
|
||||
editor.selection.collapse(false);
|
||||
Utils.pressEnter();
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<div contenteditable="false">x</div><p><br data-mce-bogus="1"></p>');
|
||||
equal(editor.selection.getNode().nodeName, 'P');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
46
tests/qunit/editor/tinymce/FocusManager.js
Normal file
46
tests/qunit/editor/tinymce/FocusManager.js
Normal file
@ -0,0 +1,46 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/FocusManager",
|
||||
"tinymce/dom/DOMUtils"
|
||||
], function (FocusManager, DOMUtils) {
|
||||
var DOM = DOMUtils.DOM;
|
||||
|
||||
module("tinymce.FocusManager", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('isEditorUIElement on valid element', function () {
|
||||
var uiElm = DOM.create('div', {'class': 'mce-abc'}, null);
|
||||
equal(FocusManager.isEditorUIElement(uiElm), true, 'Should be true since mce- is a ui prefix');
|
||||
});
|
||||
|
||||
test('isEditorUIElement on invalid element', function () {
|
||||
var noUiElm = DOM.create('div', {'class': 'mcex-abc'}, null);
|
||||
equal(FocusManager.isEditorUIElement(noUiElm), false, 'Should be true since mcex- is not a ui prefix');
|
||||
});
|
||||
|
||||
test('_isUIElement on valid element', function () {
|
||||
var uiElm1 = DOM.create('div', {'class': 'mce-abc'}, null);
|
||||
var uiElm2 = DOM.create('div', {'class': 'mcex-abc'}, null);
|
||||
var noUiElm = DOM.create('div', {'class': 'mcey-abc'}, null);
|
||||
editor.settings.custom_ui_selector = '.mcex-abc';
|
||||
equal(FocusManager._isUIElement(editor, uiElm1), true, 'Should be true since mce- is a ui prefix');
|
||||
equal(FocusManager._isUIElement(editor, uiElm2), true, 'Should be true since mcex- is a ui prefix');
|
||||
equal(FocusManager._isUIElement(editor, noUiElm), false, 'Should be true since mcey- is not a ui prefix');
|
||||
delete editor.settings.custom_ui_selector;
|
||||
});
|
||||
});
|
||||
@ -1,6 +1,6 @@
|
||||
module("tinymce.Formatter - Apply", {
|
||||
setupModule: function() {
|
||||
document.getElementById('view').innerHTML = '<textarea id="elm1"></textarea><div id="elm2"></div>';
|
||||
document.getElementById('view').innerHTML = '<textarea id="elm1"></textarea><div id="elm2"></div><textarea id="elm3"></textarea>';
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
@ -18,32 +18,8 @@ module("tinymce.Formatter - Apply", {
|
||||
'*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display,text-align'
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
QUnit.start();
|
||||
window.editor = ed;
|
||||
|
||||
if (inlineEditor) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
selector: "#elm2",
|
||||
inline: true,
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
indent: false,
|
||||
convert_fonts_to_spans: false,
|
||||
disable_nodechange: true,
|
||||
entities: 'raw',
|
||||
valid_styles: {
|
||||
'*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display,text-align'
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
window.inlineEditor = ed;
|
||||
|
||||
if (editor) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1291,6 +1267,16 @@ test('Caret format inside single block word', function() {
|
||||
equal(editor.getContent(), '<p><b>abc</b></p>');
|
||||
});
|
||||
|
||||
test('Caret format inside non-ascii single block word', function() {
|
||||
editor.setContent('<p>noël</p>');
|
||||
editor.formatter.register('format', {
|
||||
inline: 'b'
|
||||
});
|
||||
Utils.setSelection('p', 2, 'p', 2);
|
||||
editor.formatter.apply('format');
|
||||
equal(editor.getContent(), '<p><b>noël</b></p>');
|
||||
});
|
||||
|
||||
test('Caret format inside first block word', function() {
|
||||
editor.setContent('<p>abc 123</p>');
|
||||
editor.formatter.register('format', {
|
||||
@ -1679,39 +1665,51 @@ test('Bug #6471 - Merge left/right style properties', function() {
|
||||
equal(editor.getContent(), '<p><span style="font-weight: bold;">abc</span></p>');
|
||||
});
|
||||
|
||||
test('Bug #6518 - Apply div blocks to inline editor paragraph', function() {
|
||||
inlineEditor.setContent('<p>a</p><p>b</p>');
|
||||
inlineEditor.selection.select(inlineEditor.getBody().firstChild, true);
|
||||
inlineEditor.selection.collapse(true);
|
||||
inlineEditor.formatter.register('format', {
|
||||
block: 'div'
|
||||
asyncTest('Bug #6518 - Apply div blocks to inline editor paragraph', function() {
|
||||
tinymce.init({
|
||||
selector: "#elm2",
|
||||
inline: true,
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
indent: false,
|
||||
convert_fonts_to_spans: false,
|
||||
disable_nodechange: true,
|
||||
entities: 'raw',
|
||||
valid_styles: {
|
||||
'*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display,text-align'
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
QUnit.start();
|
||||
|
||||
ed.setContent('<p>a</p><p>b</p>');
|
||||
ed.selection.select(ed.getBody().firstChild, true);
|
||||
ed.selection.collapse(true);
|
||||
ed.formatter.register('format', {
|
||||
block: 'div'
|
||||
});
|
||||
ed.formatter.apply('format');
|
||||
equal(ed.getContent(), '<div>a</div><p>b</p>');
|
||||
}
|
||||
});
|
||||
inlineEditor.formatter.apply('format');
|
||||
equal(inlineEditor.getContent(), '<div>a</div><p>b</p>');
|
||||
});
|
||||
|
||||
asyncTest('Bug #7412 - valid_styles affects the Bold and Italic buttons, although it shouldn\'t', function() {
|
||||
tinymce.remove();
|
||||
|
||||
document.getElementById('view').innerHTML = '<textarea id="elm1"></textarea>';
|
||||
|
||||
tinymce.init({
|
||||
selector: "#elm1",
|
||||
selector: "#elm3",
|
||||
add_unload_trigger: false,
|
||||
valid_styles: {
|
||||
span: 'color,background-color,font-size,text-decoration,padding-left'
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
|
||||
editor.getBody().innerHTML = '<p>1 <span style="text-decoration: underline;">1234</span> 1</p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0], 0);
|
||||
rng.setEnd(editor.dom.select('span')[0], 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.toggle('bold');
|
||||
equal(getContent(), '<p>1 <strong><span style="text-decoration: underline;">1234</span></strong> 1</p>');
|
||||
ed.getBody().innerHTML = '<p>1 <span style="text-decoration: underline;">1234</span> 1</p>';
|
||||
var rng = ed.dom.createRng();
|
||||
rng.setStart(ed.dom.select('span')[0], 0);
|
||||
rng.setEnd(ed.dom.select('span')[0], 1);
|
||||
ed.selection.setRng(rng);
|
||||
ed.formatter.toggle('bold');
|
||||
equal(ed.getContent(), '<p>1 <strong><span style="text-decoration: underline;">1234</span></strong> 1</p>');
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1721,12 +1719,77 @@ test('Format selection from with end at beginning of block', function(){
|
||||
editor.focus();
|
||||
Utils.setSelection('#a', 0, '#b', 0);
|
||||
editor.execCommand('formatBlock', false, 'h1');
|
||||
equal(getContent(), '<h1 id="a">one</h1>\n<div id="b">two</div>');
|
||||
equal(getContent(), '<h1 id="a">one</h1><div id="b">two</div>');
|
||||
});
|
||||
|
||||
test('Format selection over fragments', function(){
|
||||
editor.setContent("<strong>a</strong>bc<em>d</em>");
|
||||
editor.setContent("<p><strong>a</strong>bc<em>d</em></p>");
|
||||
Utils.setSelection('strong', 1, 'em', 0);
|
||||
editor.formatter.apply('underline');
|
||||
equal(getContent(), '<p><strong>a</strong><span style="text-decoration: underline;">bc</span><em>d</em></p>');
|
||||
});
|
||||
|
||||
test("Wrapper with fontSize should retain priority within a branch of nested inline format wrappers", function() {
|
||||
editor.setContent("<p>abc</p>");
|
||||
Utils.setSelection('p', 0, 'p', 3);
|
||||
|
||||
editor.formatter.apply('fontsize', {value: '18px'});
|
||||
editor.formatter.apply('bold');
|
||||
editor.formatter.apply('underline');
|
||||
editor.formatter.apply('forecolor', {value: '#ff0000'});
|
||||
|
||||
equal(getContent(), '<p><span style="color: #ff0000; font-size: 18px; text-decoration: underline;"><strong>abc</strong></span></p>');
|
||||
});
|
||||
|
||||
test("Child wrapper having the same format as the immediate parent, shouldn't be removed if it also has other formats merged", function() {
|
||||
editor.getBody().innerHTML = '<p><span style="font-family: verdana;">a <span style="color: #ff0000;">b</span>c</span></p>';
|
||||
Utils.setSelection('span span', 0, 'span span', 1);
|
||||
editor.formatter.apply('fontname', {value: "verdana"});
|
||||
equal(getContent(), '<p><span style="font-family: verdana;">a <span style="color: #ff0000;">b</span>c</span></p>');
|
||||
});
|
||||
|
||||
test("When format with backgroundColor is applied, all the nested childNodes having fontSize should receive backgroundColor as well", function() {
|
||||
editor.getBody().innerHTML = '<p>a <span style="font-size: 36pt;">b</span> c</p>';
|
||||
editor.selection.select(editor.dom.select('p')[0]);
|
||||
|
||||
editor.formatter.apply('hilitecolor', {value: "#ff0000"});
|
||||
equal(getContent(), '<p><span style="background-color: #ff0000;">a <span style="font-size: 36pt; background-color: #ff0000;">b</span> c</span></p>');
|
||||
|
||||
editor.formatter.remove('hilitecolor', {value: "#ff0000"});
|
||||
equal(getContent(), '<p>a <span style="font-size: 36pt;">b</span> c</p>');
|
||||
});
|
||||
|
||||
test("TINY-782: Can't apply sub/sup to word on own line with large font", function() {
|
||||
editor.getBody().innerHTML = '<p><span style="font-size: 18px;">abc</p>';
|
||||
Utils.setSelection('span', 0, 'span', 3);
|
||||
editor.formatter.apply('superscript');
|
||||
equal(getContent(), '<p><span style="font-size: 18px;"><sup>abc</sup></span></p>');
|
||||
});
|
||||
|
||||
test("TINY-671: Background color on nested font size bug", function() {
|
||||
editor.getBody().innerHTML = '<p><strong><span style="font-size: 18px;">abc</span></strong></p>';
|
||||
Utils.setSelection('span', 0, 'span', 3);
|
||||
editor.formatter.apply('hilitecolor', {value: '#ff0000'});
|
||||
equal(getContent(), '<p><span style="font-size: 18px; background-color: #ff0000;"><strong>abc</strong></span></p>');
|
||||
});
|
||||
|
||||
test("TINY-865: Font size removed when changing background color", function() {
|
||||
editor.getBody().innerHTML = '<p><span style="background-color: #ffff00;"><span style="font-size: 8pt;">a</span> <span style="font-size: 36pt;">b</span> <span style="font-size: 8pt;">c</span></span></p>';
|
||||
Utils.setSelection('span span:nth-child(2)', 0, 'span span:nth-child(2)', 1);
|
||||
editor.formatter.apply('hilitecolor', {value: '#ff0000'});
|
||||
equal(getContent(), '<p><span style="background-color: #ffff00;"><span style="font-size: 8pt;">a</span> <span style="font-size: 36pt; background-color: #ff0000;">b</span> <span style="font-size: 8pt;">c</span></span></p>');
|
||||
});
|
||||
|
||||
test("TINY-935: Text color, then size, then change color wraps span doesn't change color", function() {
|
||||
editor.getBody().innerHTML = '<p><span style="color: #00ff00; font-size: 14pt;">text</span></p>';
|
||||
Utils.setSelection('span', 0, 'span', 4);
|
||||
editor.formatter.apply('forecolor', {value: '#ff0000'});
|
||||
equal(getContent(), '<p><span style="color: #ff0000; font-size: 14pt;">text</span></p>');
|
||||
});
|
||||
|
||||
test("GH-3519: Font family selection does not work after changing font size", function() {
|
||||
editor.getBody().innerHTML = '<p><span style="font-size: 14pt; font-family: \'comic sans ms\', sans-serif;">text</span></p>';
|
||||
Utils.setSelection('span', 0, 'span', 4);
|
||||
editor.formatter.apply('fontname', {value: "verdana"});
|
||||
equal(getContent(), '<p><span style="font-size: 14pt; font-family: verdana;">text</span></p>');
|
||||
});
|
||||
|
||||
@ -228,8 +228,3 @@ test('Match format on div block in inline mode', function() {
|
||||
inlineEditor.execCommand('SelectAll');
|
||||
ok(!inlineEditor.formatter.match('div'), 'Formatter.match on div says true');
|
||||
});
|
||||
|
||||
test('Get preview css text for formats', function() {
|
||||
ok(/font-weight\:(bold|700)/.test(editor.formatter.getCssText('bold')), 'Bold not found in preview style');
|
||||
ok(/font-weight\:(bold|700)/.test(editor.formatter.getCssText({inline: 'b'})), 'Bold not found in preview style');
|
||||
});
|
||||
|
||||
47
tests/qunit/editor/tinymce/InsertContentForcedRootFalse.js
Normal file
47
tests/qunit/editor/tinymce/InsertContentForcedRootFalse.js
Normal file
@ -0,0 +1,47 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/InsertContent"
|
||||
], function(InsertContent) {
|
||||
module("tinymce.InsertContentForcedRootFalse", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
},
|
||||
forced_root_block: false
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var trimBrs = function(string) {
|
||||
return string.replace(/<br>/g, '');
|
||||
};
|
||||
|
||||
test('insertAtCaret - selected image with bogus div', function() {
|
||||
editor.getBody().innerHTML = '<img src="about:blank" /><div data-mce-bogus="all">x</div>';
|
||||
editor.focus();
|
||||
// editor.selection.setCursorLocation(editor.getBody(), 0);
|
||||
editor.selection.select(editor.dom.select('img')[0]);
|
||||
InsertContent.insertAtCaret(editor, 'a');
|
||||
equal(trimBrs(editor.getBody().innerHTML), 'a<div data-mce-bogus="all">x</div>');
|
||||
});
|
||||
|
||||
test('insertAtCaret - selected text with bogus div', function() {
|
||||
editor.getBody().innerHTML = 'a<div data-mce-bogus="all">x</div>';
|
||||
editor.focus();
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 0);
|
||||
rng.setEnd(editor.getBody().firstChild, 1);
|
||||
editor.selection.setRng(rng);
|
||||
InsertContent.insertAtCaret(editor, 'b');
|
||||
equal(trimBrs(editor.getBody().innerHTML), 'b<div data-mce-bogus="all">x</div>');
|
||||
});
|
||||
});
|
||||
109
tests/qunit/editor/tinymce/NotificationManager.js
Normal file
109
tests/qunit/editor/tinymce/NotificationManager.js
Normal file
@ -0,0 +1,109 @@
|
||||
ModuleLoader.require([
|
||||
'tinymce/util/Tools'
|
||||
], function(Tools) {
|
||||
module("tinymce.NotificationManager", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
},
|
||||
teardown: function() {
|
||||
var notifications = [].concat(editor.notificationManager.notifications);
|
||||
|
||||
Tools.each(notifications, function(notification) {
|
||||
notification.close();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
test('Should not add duplicate text message', function() {
|
||||
expect(4);
|
||||
|
||||
var testMsg1 = {type: 'default', text: 'test default message'};
|
||||
var testMsg2 = {type: 'warning', text: 'test warning message'};
|
||||
var testMsg3 = {type: 'error', text: 'test error message'};
|
||||
var testMsg4 = {type: 'info', text: 'test info message'};
|
||||
var notifications = editor.notificationManager.notifications;
|
||||
|
||||
editor.notificationManager.open(testMsg1);
|
||||
|
||||
equal(notifications.length, 1, 'Should have one message after one added.');
|
||||
|
||||
editor.notificationManager.open(testMsg1);
|
||||
|
||||
equal(notifications.length, 1, 'Should not add message if duplicate.');
|
||||
|
||||
editor.notificationManager.open(testMsg2);
|
||||
editor.notificationManager.open(testMsg3);
|
||||
editor.notificationManager.open(testMsg4);
|
||||
|
||||
equal(notifications.length, 4, 'Non duplicate messages should get added.');
|
||||
|
||||
editor.notificationManager.open(testMsg2);
|
||||
editor.notificationManager.open(testMsg3);
|
||||
editor.notificationManager.open(testMsg4);
|
||||
|
||||
equal(notifications.length, 4, 'Should work for all text message types.');
|
||||
});
|
||||
|
||||
test('Should add duplicate progressBar messages', function() {
|
||||
expect(2);
|
||||
var testMsg1 = {text: 'test progressBar message', progressBar: true};
|
||||
var notifications = editor.notificationManager.notifications;
|
||||
|
||||
editor.notificationManager.open(testMsg1);
|
||||
|
||||
equal(notifications.length, 1, 'Should have one message after one added.');
|
||||
|
||||
editor.notificationManager.open(testMsg1);
|
||||
editor.notificationManager.open(testMsg1);
|
||||
editor.notificationManager.open(testMsg1);
|
||||
|
||||
equal(notifications.length, 4, 'Duplicate should be added for progressBar message.');
|
||||
});
|
||||
|
||||
asyncTest('Should add duplicate timeout messages', function() {
|
||||
expect(2);
|
||||
var checkClosed = function () {
|
||||
if (notifications.length === 0) {
|
||||
start();
|
||||
}
|
||||
};
|
||||
var testMsg1 = {text: 'test timeout message', timeout: 1};
|
||||
var notifications = editor.notificationManager.notifications;
|
||||
|
||||
editor.notificationManager.open(testMsg1).on('close', checkClosed);
|
||||
|
||||
equal(notifications.length, 1, 'Should have one message after one added.');
|
||||
|
||||
editor.notificationManager.open(testMsg1).on('close', checkClosed);
|
||||
|
||||
equal(notifications.length, 2, 'Duplicate should be added for timeout message.');
|
||||
});
|
||||
|
||||
test('Should not open notifcation if editor is removed', function() {
|
||||
var testMsg1 = {type: 'default', text: 'test progressBar message'};
|
||||
|
||||
editor.remove();
|
||||
|
||||
try {
|
||||
editor.notificationManager.open(testMsg1);
|
||||
ok(true, 'Should execute without throwing.')
|
||||
} catch (e) {
|
||||
ok(false, 'Should never throw exception.');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@ -47,7 +47,7 @@ ModuleLoader.require([
|
||||
|
||||
function assertCaretInCaretBlockContainer() {
|
||||
var beforeRng = editor.selection.getRng();
|
||||
equal(CaretContainer.isCaretContainerBlock(beforeRng.startContainer.parentNode), true, 'Not in caret block container.');
|
||||
equal(CaretContainer.isCaretContainerBlock(beforeRng.startContainer), true, 'Not in caret block container.');
|
||||
}
|
||||
|
||||
var leftArrow = pressKey(VK.LEFT);
|
||||
@ -224,7 +224,7 @@ ModuleLoader.require([
|
||||
|
||||
equal(editor.getContent(), '<p contenteditable="false">1</p><p contenteditable="false">2</p>');
|
||||
assertCaretInCaretBlockContainer();
|
||||
equal(rng.startContainer.parentNode.previousSibling, editor.dom.select('p')[0]);
|
||||
equal(rng.startContainer.previousSibling, editor.dom.select('p')[0]);
|
||||
});
|
||||
|
||||
test('delete from after cE=false block to text', function() {
|
||||
@ -263,7 +263,7 @@ ModuleLoader.require([
|
||||
|
||||
equal(editor.getContent(), '<p contenteditable="false">1</p><p contenteditable="false">2</p>');
|
||||
assertCaretInCaretBlockContainer();
|
||||
equal(rng.startContainer.parentNode.nextSibling, editor.dom.select('p')[2]);
|
||||
equal(rng.startContainer.nextSibling, editor.dom.select('p')[2]);
|
||||
});
|
||||
|
||||
test('delete from block to before cE=false inline', function() {
|
||||
@ -328,4 +328,30 @@ ModuleLoader.require([
|
||||
// Since we can't do a real click we need to check if it gets sucked in towards the cE=false block
|
||||
equal(editor.selection.getNode().nodeName !== 'P', true);
|
||||
});
|
||||
|
||||
test('offscreen copy of cE=false block remains offscreen', function() {
|
||||
if (tinymce.isIE || tinymce.isGecko || tinymce.isOpera) {
|
||||
editor.setContent(
|
||||
'<table contenteditable="false" style="width: 100%; table-layout: fixed">' +
|
||||
'<tbody><tr><td>1</td><td>2</td></tr></tbody>' +
|
||||
'</table>'
|
||||
);
|
||||
|
||||
editor.selection.select(editor.dom.select('table')[0]);
|
||||
var offscreenSelection = editor.dom.select('.mce-offscreen-selection')[0];
|
||||
|
||||
ok(offscreenSelection.offsetLeft !== undefined, 'The offscreen selection\'s left border is undefined');
|
||||
ok(offscreenSelection.offsetLeft < 0, 'The offscreen selection\'s left border is onscreen');
|
||||
ok(offscreenSelection.offsetWidth + offscreenSelection.offsetLeft < 0,
|
||||
'The cE=false offscreen selection is visible on-screen. Right edge: ' +
|
||||
offscreenSelection.offsetLeft + '+' + offscreenSelection.offsetWidth + '=' +
|
||||
(offscreenSelection.offsetLeft + offscreenSelection.offsetWidth) + 'px'
|
||||
);
|
||||
} else {
|
||||
// Chrome and Safari behave correctly, and PhantomJS also declares itself as WebKit but does not
|
||||
// put the off-screen selection off-screen, so fails the above tests. However, it has no visible UI,
|
||||
// so everything is off-screen anyway :-)
|
||||
ok(true, 'Not a tested browser - Chrome & Safari work, PhantomJS does not put the selection off screen');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -96,7 +96,7 @@ test('Typing state', function() {
|
||||
editor.dom.fire(editor.getBody(), 'keydown', {keyCode: 65});
|
||||
ok(editor.undoManager.typing);
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'keyup', {keyCode: 13});
|
||||
editor.dom.fire(editor.getBody(), 'keydown', {keyCode: 13});
|
||||
ok(!editor.undoManager.typing);
|
||||
|
||||
selectAllFlags = {keyCode: 65, ctrlKey: false, altKey: false, shiftKey: false};
|
||||
@ -451,3 +451,41 @@ test('Dirty state type AltGr+letter', function() {
|
||||
equal(editor.getContent(), "<p>aB</p>");
|
||||
ok(editor.isDirty(), "Dirty state should be true");
|
||||
});
|
||||
|
||||
test('ExecCommand while typing should produce undo level', function() {
|
||||
editor.undoManager.clear();
|
||||
editor.setDirty(false);
|
||||
editor.setContent('<p>a</p>');
|
||||
Utils.setSelection('p', 1);
|
||||
|
||||
equal(editor.undoManager.typing, false);
|
||||
Utils.type({keyCode: 66, charCode: 66});
|
||||
equal(editor.undoManager.typing, true);
|
||||
equal(editor.getContent(), '<p>aB</p>');
|
||||
editor.execCommand('mceInsertContent', false, 'C');
|
||||
equal(editor.undoManager.typing, false);
|
||||
equal(editor.undoManager.data.length, 3);
|
||||
equal(editor.undoManager.data[0].content, '<p>a</p>');
|
||||
equal(editor.undoManager.data[1].content, '<p>aB</p>');
|
||||
equal(editor.undoManager.data[2].content, '<p>aBC</p>');
|
||||
});
|
||||
|
||||
test('transact while typing should produce undo level', function() {
|
||||
editor.undoManager.clear();
|
||||
editor.setDirty(false);
|
||||
editor.setContent('<p>a</p>');
|
||||
Utils.setSelection('p', 1);
|
||||
|
||||
equal(editor.undoManager.typing, false);
|
||||
Utils.type({keyCode: 66, charCode: 66});
|
||||
equal(editor.undoManager.typing, true);
|
||||
equal(editor.getContent(), '<p>aB</p>');
|
||||
editor.undoManager.transact(function () {
|
||||
editor.getBody().firstChild.firstChild.data = 'aBC';
|
||||
});
|
||||
equal(editor.undoManager.typing, false);
|
||||
equal(editor.undoManager.data.length, 3);
|
||||
equal(editor.undoManager.data[0].content, '<p>a</p>');
|
||||
equal(editor.undoManager.data[1].content, '<p>aB</p>');
|
||||
equal(editor.undoManager.data[2].content, '<p>aBC</p>');
|
||||
});
|
||||
|
||||
@ -118,4 +118,20 @@ ModuleLoader.require([
|
||||
setViewHtml('abc' + Zwsp.ZWSP);
|
||||
equal(CaretContainer.endsWithCaretContainer(getRoot().firstChild), true);
|
||||
});
|
||||
|
||||
test('hasContent', function() {
|
||||
setViewHtml('<span contentEditable="false">1</span>');
|
||||
var caretContainerBlock = CaretContainer.insertBlock('p', getRoot().firstChild, true);
|
||||
equal(CaretContainer.hasContent(caretContainerBlock), false);
|
||||
caretContainerBlock.insertBefore(document.createTextNode('a'), caretContainerBlock.firstChild);
|
||||
equal(CaretContainer.hasContent(caretContainerBlock), true);
|
||||
});
|
||||
|
||||
test('showCaretContainerBlock', function() {
|
||||
setViewHtml('<span contentEditable="false">1</span>');
|
||||
var caretContainerBlock = CaretContainer.insertBlock('p', getRoot().firstChild, true);
|
||||
caretContainerBlock.insertBefore(document.createTextNode('a'), caretContainerBlock.firstChild);
|
||||
CaretContainer.showCaretContainerBlock(caretContainerBlock);
|
||||
equal(caretContainerBlock.outerHTML, '<p>a</p>');
|
||||
});
|
||||
});
|
||||
|
||||
@ -34,7 +34,7 @@ ModuleLoader.require([
|
||||
|
||||
equal($fakeCaretElm[0].nodeName, 'P');
|
||||
equal($fakeCaretElm.attr('data-mce-caret'), 'before');
|
||||
Utils.assertRange(rng, Utils.createRange($fakeCaretElm[0].firstChild, 0, $fakeCaretElm[0].firstChild, 1));
|
||||
Utils.assertRange(rng, Utils.createRange($fakeCaretElm[0], 0, $fakeCaretElm[0], 0));
|
||||
|
||||
fakeCaret.hide();
|
||||
equal($('#view *[data-mce-caret]').length, 0);
|
||||
@ -50,7 +50,7 @@ ModuleLoader.require([
|
||||
|
||||
equal($fakeCaretElm[1].nodeName, 'P');
|
||||
equal($fakeCaretElm.eq(1).attr('data-mce-caret'), 'after');
|
||||
Utils.assertRange(rng, Utils.createRange($fakeCaretElm[1].firstChild, 0, $fakeCaretElm[1].firstChild, 1));
|
||||
Utils.assertRange(rng, Utils.createRange($fakeCaretElm[1], 0, $fakeCaretElm[1], 0));
|
||||
|
||||
fakeCaret.hide();
|
||||
equal($('#view *[data-mce-caret]').length, 0);
|
||||
|
||||
104
tests/qunit/editor/tinymce/content/LinkTargets.js
Normal file
104
tests/qunit/editor/tinymce/content/LinkTargets.js
Normal file
@ -0,0 +1,104 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/content/LinkTargets",
|
||||
"tinymce/util/Arr"
|
||||
], function(LinkTargets, Arr) {
|
||||
module("tinymce.content.LinkTargets", {});
|
||||
|
||||
var createFromHtml = function (html) {
|
||||
var elm = document.createElement('div');
|
||||
elm.contentEditable = true;
|
||||
elm.innerHTML = html;
|
||||
return elm;
|
||||
};
|
||||
|
||||
var targetsIn = function (html) {
|
||||
return LinkTargets.find(createFromHtml(html));
|
||||
};
|
||||
|
||||
var equalTargets = function (actualTargets, expectedTargets, message) {
|
||||
var nonAttachedTargets = Arr.map(actualTargets, function (target) {
|
||||
return {
|
||||
level: target.level,
|
||||
title: target.title,
|
||||
type: target.type,
|
||||
url: target.url
|
||||
};
|
||||
});
|
||||
|
||||
deepEqual(nonAttachedTargets, expectedTargets, message);
|
||||
};
|
||||
|
||||
test('Non link targets', function() {
|
||||
equal(targetsIn('a').length, 0, 'Text has no targets');
|
||||
equal(targetsIn('<p>a</p>').length, 0, 'Paragraph has no targets');
|
||||
equal(targetsIn('<a href="#1">a</a>').length, 0, 'Link has no targets');
|
||||
});
|
||||
|
||||
test('Anchor targets', function() {
|
||||
equalTargets(targetsIn('<a id="a"></a>'), [{level: 0, title: '#a', type: 'anchor', url: '#a'}], 'Anchor with id');
|
||||
equalTargets(targetsIn('<a name="a"></a>'), [{level: 0, title: '#a', type: 'anchor', url: '#a'}], 'Anchor with name');
|
||||
equalTargets(targetsIn('<a name="a" contentEditable="false"></a>'), [], 'cE=false anchor');
|
||||
equalTargets(targetsIn('<div contentEditable="false"><a name="a"></a></div>'), [], 'Anchor in cE=false');
|
||||
equalTargets(targetsIn('<a name=""></a>'), [], 'Empty anchor name should not produce a target');
|
||||
equalTargets(targetsIn('<a id=""></a>'), [], 'Empty anchor id should not produce a target');
|
||||
});
|
||||
|
||||
test('Header targets', function() {
|
||||
equalTargets(targetsIn('<h1 id="a">a</h1>'), [{level: 1, title: 'a', type: 'header', url: '#a'}], 'Header 1 with id');
|
||||
equalTargets(targetsIn('<h2 id="a">a</h2>'), [{level: 2, title: 'a', type: 'header', url: '#a'}], 'Header 2 with id');
|
||||
equalTargets(targetsIn('<h3 id="a">a</h3>'), [{level: 3, title: 'a', type: 'header', url: '#a'}], 'Header 3 with id');
|
||||
equalTargets(targetsIn('<h4 id="a">a</h4>'), [{level: 4, title: 'a', type: 'header', url: '#a'}], 'Header 4 with id');
|
||||
equalTargets(targetsIn('<h5 id="a">a</h5>'), [{level: 5, title: 'a', type: 'header', url: '#a'}], 'Header 5 with id');
|
||||
equalTargets(targetsIn('<h6 id="a">a</h6>'), [{level: 6, title: 'a', type: 'header', url: '#a'}], 'Header 6 with id');
|
||||
equalTargets(targetsIn('<h1 id="a"></h1>'), [], 'Empty header should not produce a target');
|
||||
equalTargets(targetsIn('<div contentEditable="false"><h1 id="a">a</h1></div>'), [], 'Header in cE=false');
|
||||
equalTargets(targetsIn('<h1 id="a" contentEditable="false">a</h1>'), [], 'cE=false header');
|
||||
});
|
||||
|
||||
test('Mixed targets', function() {
|
||||
equalTargets(
|
||||
targetsIn('<h1 id="a">a</h1><a id="b"></a>'),
|
||||
[
|
||||
{level: 1, title: 'a', type: 'header', url: '#a'},
|
||||
{level: 0, title: '#b', type: 'anchor', url: '#b'}
|
||||
],
|
||||
'Header 1 with id and anchor with id'
|
||||
);
|
||||
});
|
||||
|
||||
test('Anchor attach', function() {
|
||||
var elm = createFromHtml('<a id="a"></a>');
|
||||
var targets = LinkTargets.find(elm);
|
||||
|
||||
targets[0].attach();
|
||||
equal(elm.innerHTML, '<a id="a"></a>', 'Should remain the same as before attach');
|
||||
});
|
||||
|
||||
test('Header attach on header with id', function() {
|
||||
var elm = createFromHtml('<h1 id="a">a</h1>');
|
||||
var targets = LinkTargets.find(elm);
|
||||
|
||||
targets[0].attach();
|
||||
equal(elm.innerHTML, '<h1 id="a">a</h1>', 'Should remain the same as before attach');
|
||||
});
|
||||
|
||||
test('Header attach on headers without ids', function() {
|
||||
var elm = createFromHtml('<h1>a</h1><h2>b</h2>');
|
||||
var targets = LinkTargets.find(elm);
|
||||
|
||||
targets[0].attach();
|
||||
targets[1].attach();
|
||||
|
||||
var idA = elm.firstChild.id;
|
||||
var idB = elm.lastChild.id;
|
||||
var afterAttachHtml = elm.innerHTML;
|
||||
|
||||
equal(afterAttachHtml, '<h1 id="' + idA + '">a</h1><h2 id="' + idB + '">b</h2>', 'Should have unique id:s');
|
||||
ok(idA !== idB, 'Should not be equal id:s');
|
||||
|
||||
targets[0].attach();
|
||||
targets[1].attach();
|
||||
|
||||
equal(elm.innerHTML, afterAttachHtml, 'Should be the same id:s regardless of how many times you attach');
|
||||
});
|
||||
});
|
||||
@ -35,7 +35,7 @@
|
||||
dom.serializeStyle(dom.parseStyle('border-width: 1pt 1pt 1pt 1pt; border-style: none none none none; border-color: black black black black;')),
|
||||
'border: 1pt none black;'
|
||||
);
|
||||
|
||||
|
||||
equal(
|
||||
dom.serializeStyle(dom.parseStyle('border-width: 1pt 4pt 2pt 3pt; border-style: solid dashed dotted none; border-color: black red green blue;')),
|
||||
'border-width: 1pt 4pt 2pt 3pt; border-style: solid dashed dotted none; border-color: black red green blue;'
|
||||
@ -339,15 +339,21 @@
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
var eqNodeName = function(name) {
|
||||
return function (n) {
|
||||
return n.nodeName === name;
|
||||
};
|
||||
};
|
||||
|
||||
test('getParent', 6, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.get('test').innerHTML = '<div><span>ab<a id="test2" href="">abc</a>c</span></div>';
|
||||
|
||||
equal(DOM.getParent('test2', function(n) {return n.nodeName == 'SPAN';}).nodeName, 'SPAN');
|
||||
equal(DOM.getParent('test2', function(n) {return n.nodeName == 'BODY';}).nodeName, 'BODY');
|
||||
equal(DOM.getParent('test2', function(n) {return n.nodeName == 'BODY';}, document.body), null);
|
||||
equal(DOM.getParent('test2', function() {return false;}), null);
|
||||
equal(DOM.getParent('test2', eqNodeName('SPAN')).nodeName, 'SPAN');
|
||||
equal(DOM.getParent('test2', eqNodeName('BODY')).nodeName, 'BODY');
|
||||
equal(DOM.getParent('test2', eqNodeName('BODY'), document.body), null);
|
||||
equal(DOM.getParent('test2', eqNodeName('X')), null);
|
||||
equal(DOM.getParent('test2', 'SPAN').nodeName, 'SPAN');
|
||||
equal(DOM.getParent('test2', 'body', DOM.get('test')), null);
|
||||
|
||||
@ -360,7 +366,7 @@
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
DOM.get('test').innerHTML = '<div><span class="test">ab<span><a id="test2" href="">abc</a>c</span></span></div>';
|
||||
|
||||
equal(DOM.getParents('test2', function(n) {return n.nodeName == 'SPAN';}).length, 2);
|
||||
equal(DOM.getParents('test2', eqNodeName('SPAN')).length, 2);
|
||||
equal(DOM.getParents('test2', 'span').length, 2);
|
||||
equal(DOM.getParents('test2', 'span.test').length, 1);
|
||||
equal(DOM.getParents('test2', 'body', DOM.get('test')).length, 0);
|
||||
@ -433,7 +439,7 @@
|
||||
equal(DOM.getNext(DOM.get('test').firstChild, 'em').nodeName, 'EM');
|
||||
equal(DOM.getNext(DOM.get('test').firstChild, 'div'), null);
|
||||
equal(DOM.getNext(null, 'div'), null);
|
||||
equal(DOM.getNext(DOM.get('test').firstChild, function(n) {return n.nodeName == 'EM';}).nodeName, 'EM');
|
||||
equal(DOM.getNext(DOM.get('test').firstChild, eqNodeName('EM')).nodeName, 'EM');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
@ -446,7 +452,7 @@
|
||||
equal(DOM.getPrev(DOM.get('test').lastChild, 'strong').nodeName, 'STRONG');
|
||||
equal(DOM.getPrev(DOM.get('test').lastChild, 'div'), null);
|
||||
equal(DOM.getPrev(null, 'div'), null);
|
||||
equal(DOM.getPrev(DOM.get('test').lastChild, function(n) {return n.nodeName == 'STRONG';}).nodeName, 'STRONG');
|
||||
equal(DOM.getPrev(DOM.get('test').lastChild, eqNodeName('STRONG')).nodeName, 'STRONG');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
@ -581,7 +587,7 @@
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('isEmpty', 14, function() {
|
||||
test('isEmpty', function() {
|
||||
DOM.schema = new tinymce.html.Schema(); // A schema will be added when used within a editor instance
|
||||
DOM.add(document.body, 'div', {id : 'test'}, '');
|
||||
|
||||
@ -626,6 +632,30 @@
|
||||
DOM.setHTML('test', '<div><!-- comment --></div>');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Element with comment.');
|
||||
|
||||
DOM.setHTML('test', '<span data-mce-bogus="1"></span>');
|
||||
ok(DOM.isEmpty(DOM.get('test')), 'Contains just a bogus element.');
|
||||
|
||||
DOM.setHTML('test', '<span data-mce-bogus="1">a</span>');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Contains a text node in a bogus element.');
|
||||
|
||||
DOM.setHTML('test', '<span data-mce-bogus="all">a</span>');
|
||||
ok(DOM.isEmpty(DOM.get('test')), 'Contains just a bogus all element.');
|
||||
|
||||
DOM.setHTML('test', '<span data-mce-bogus="all">a</span>b');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Contains a bogus all element but some text as well.');
|
||||
|
||||
DOM.setHTML('test', '<code> </code>');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Contains a code element should be treated as content.');
|
||||
|
||||
DOM.setHTML('test', '<pre> </pre>');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Contains a pre element should be treated as content.');
|
||||
|
||||
DOM.setHTML('test', '<code></code>');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Contains a code element should be treated as content.');
|
||||
|
||||
DOM.setHTML('test', '<pre></pre>');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Contains a pre element should be treated as content.');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
@ -634,6 +664,11 @@
|
||||
equal(false, DOM.isEmpty(elm, {img: true}));
|
||||
});
|
||||
|
||||
test('isEmpty on pre', function() {
|
||||
var elm = DOM.create('pre', null, ' ');
|
||||
equal(false, DOM.isEmpty(elm));
|
||||
});
|
||||
|
||||
test('isEmpty with list of elements considered non-empty without schema', function() {
|
||||
var domWithoutSchema = new tinymce.dom.DOMUtils(document, {keep_values: true});
|
||||
|
||||
@ -645,7 +680,7 @@
|
||||
var elm = DOM.create('p', null, '<em><br></em>');
|
||||
ok(DOM.isEmpty(elm, 'No children'));
|
||||
});
|
||||
|
||||
|
||||
test('isEmpty on P with two BR in EM', function() {
|
||||
var elm = DOM.create('p', null, '<em><br><br></em>');
|
||||
equal(false, DOM.isEmpty(elm));
|
||||
@ -654,13 +689,18 @@
|
||||
test('bind/unbind/fire', function() {
|
||||
var count = 0;
|
||||
|
||||
DOM.bind(document, 'click', function() {count++;});
|
||||
DOM.bind(document, 'click', function() {
|
||||
count++;
|
||||
});
|
||||
DOM.fire(document, 'click');
|
||||
DOM.unbind(document, 'click');
|
||||
equal(count, 1);
|
||||
|
||||
count = 0;
|
||||
DOM.bind([document, window], 'click', function(e) {e.stopPropagation(); count++;});
|
||||
DOM.bind([document, window], 'click', function(e) {
|
||||
e.stopPropagation();
|
||||
count++;
|
||||
});
|
||||
DOM.fire(document, 'click');
|
||||
DOM.fire(window, 'click');
|
||||
DOM.unbind([document, window], 'click');
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/caret/CaretContainer",
|
||||
"tinymce/text/Zwsp",
|
||||
"tinymce/Env"
|
||||
], function(CaretContainer, Env) {
|
||||
], function(CaretContainer, Zwsp, Env) {
|
||||
module("tinymce.dom.Selection", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
@ -503,8 +504,8 @@ ModuleLoader.require([
|
||||
editor.setContent('<p contentEditable="false">1</p>');
|
||||
CaretContainer.insertBlock('p', editor.$('p')[0], true);
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.$('p')[0].firstChild, 0);
|
||||
rng.setEnd(editor.$('p')[0].firstChild, 1);
|
||||
rng.setStart(editor.$('p')[0], 0);
|
||||
rng.setEnd(editor.$('p')[0], 0);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2);
|
||||
editor.setContent('<p contentEditable="false">1</p>');
|
||||
@ -846,6 +847,21 @@ ModuleLoader.require([
|
||||
equal(rng.startOffset, 0);
|
||||
});
|
||||
|
||||
test('normalize lean left from br into formatter caret container', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p><span id="_mce_caret">' + Zwsp.ZWSP + '</span><br /></p>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.getBody().firstChild.lastChild);
|
||||
rng.setEndBefore(editor.getBody().firstChild.lastChild);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeType, 3);
|
||||
equal(rng.startOffset, 1);
|
||||
});
|
||||
|
||||
test('normalize don\'t lean left into empty inline elements if there is a br element after caret', function() {
|
||||
var rng;
|
||||
|
||||
@ -1055,5 +1071,71 @@ ModuleLoader.require([
|
||||
equal(rng.endContainer.nodeName, '#text');
|
||||
equal(rng.endOffset, 1);
|
||||
});
|
||||
|
||||
test('getRng should return null if win.document is not defined or null', function() {
|
||||
var win = editor.selection.win,
|
||||
rng = editor.dom.createRng();
|
||||
|
||||
editor.setContent('<p>x</p>');
|
||||
|
||||
rng.setStart(editor.$('p')[0].firstChild, 0);
|
||||
rng.setEnd(editor.$('p')[0].firstChild, 1);
|
||||
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.setRng(null);
|
||||
|
||||
editor.selection.win = {};
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng, null);
|
||||
|
||||
editor.selection.win = {document:null};
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng, null);
|
||||
|
||||
editor.selection.win = win;
|
||||
});
|
||||
|
||||
test('image selection webkit bug', function() {
|
||||
var testImageSelection = function (inputHtml, expectedContainerName, expectedOffset) {
|
||||
editor.setContent(inputHtml);
|
||||
editor.selection.select(editor.dom.select('img')[0]);
|
||||
|
||||
var rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, expectedOffset);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, expectedOffset + 1);
|
||||
equal(editor.selection.getNode().nodeName, 'IMG');
|
||||
equal(editor.selection.getStart().nodeName, 'IMG');
|
||||
equal(editor.selection.getEnd().nodeName, 'IMG');
|
||||
|
||||
var nativeRng = editor.selection.getSel().getRangeAt(0);
|
||||
equal(nativeRng.startContainer.nodeName, 'P');
|
||||
equal(nativeRng.startOffset, expectedOffset);
|
||||
equal(nativeRng.startContainer.nodeName, 'P');
|
||||
equal(nativeRng.endOffset, expectedOffset + 1);
|
||||
};
|
||||
|
||||
testImageSelection('<p><img src="#"></p>', 'P', 0);
|
||||
testImageSelection('<p><img src="#">abc</p>', 'P', 0);
|
||||
testImageSelection('<p>abc<img src="#"></p>', 'P', 1);
|
||||
testImageSelection('<p>abc<img src="#">def</p>', 'P', 1);
|
||||
testImageSelection('<p><img style="float: right;" src="#"></p>', 'P', 0);
|
||||
testImageSelection('<p><img style="float: right;" src="#">abc</p>', 'P', 0);
|
||||
testImageSelection('<p>abc<img style="float: right;" src="#"></p>', 'P', 1);
|
||||
testImageSelection('<p>abc<img style="float: right;" src="#">def</p>', 'P', 1);
|
||||
testImageSelection('<p><img style="float: left;" src="#"></p>', 'P', 0);
|
||||
testImageSelection('<p><img style="float: left;" src="#">abc</p>', 'P', 0);
|
||||
testImageSelection('<p>abc<img style="float: left;" src="#"></p>', 'P', 1);
|
||||
testImageSelection('<p>abc<img style="float: left;" src="#">def</p>', 'P', 1);
|
||||
testImageSelection('<p dir="rtl"><img style="float: right;" src="#"></p>', 'P', 0);
|
||||
testImageSelection('<p dir="rtl"><img style="float: right;" src="#">abc</p>', 'P', 0);
|
||||
testImageSelection('<p dir="rtl">abc<img style="float: right;" src="#"></p>', 'P', 1);
|
||||
testImageSelection('<p dir="rtl">abc<img style="float: right;" src="#">def</p>', 'P', 1);
|
||||
testImageSelection('<p dir="rtl"><img style="float: left;" src="#"></p>', 'P', 0);
|
||||
testImageSelection('<p dir="rtl"><img style="float: left;" src="#">abc</p>', 'P', 0);
|
||||
testImageSelection('<p dir="rtl">abc<img style="float: left;" src="#"></p>', 'P', 1);
|
||||
testImageSelection('<p dir="rtl">abc<img style="float: left;" src="#">def</p>', 'P', 1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ test('Schema rules', function() {
|
||||
|
||||
ser.setRules('a[href|target<_blank?_top|title:forced value]');
|
||||
DOM.setHTML('test', '<a href="file.htm" data-mce-href="file.htm" target="_blank" title="title">link</a><a href="#" data-mce-href="#" target="test">test2</a>');
|
||||
equal(ser.serialize(DOM.get('test')), '<a href="file.htm" target="_blank" title="forced value">link</a><a href="#" title="forced value">test2</a>');
|
||||
equal(ser.serialize(DOM.get('test')), '<a href="file.htm" target="_blank" title="forced value" rel="noopener noreferrer">link</a><a href="#" title="forced value">test2</a>');
|
||||
|
||||
ser.setRules('img[src|border=0|alt=]');
|
||||
DOM.setHTML('test', '<img src="tinymce/ui/img/raster.gif" data-mce-src="tinymce/ui/img/raster.gif" border="0" alt="" />');
|
||||
@ -234,6 +234,17 @@ test('Padd empty elements', function() {
|
||||
equal(ser.serialize(DOM.get('test')), '<p>test</p><p> </p>');
|
||||
});
|
||||
|
||||
test('Padd empty elements with BR', function() {
|
||||
var ser = new tinymce.dom.Serializer({padd_empty_with_br: true});
|
||||
|
||||
ser.setRules('#p,table,tr,#td,br');
|
||||
|
||||
DOM.setHTML('test', '<p>a</p><p></p>');
|
||||
equal(ser.serialize(DOM.get('test')), '<p>a</p><p><br /></p>');
|
||||
DOM.setHTML('test', '<p>a</p><table><tr><td><br></td></tr></table>');
|
||||
equal(ser.serialize(DOM.get('test')), '<p>a</p><table><tr><td><br /></td></tr></table>');
|
||||
});
|
||||
|
||||
test('Remove empty elements', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
@ -346,6 +357,14 @@ test('Script whitespace in beginning/end and cdata', 1, function() {
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<s' + 'cript>// <![CDATA[\n1 < 2;\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Whitespace preserve in pre', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('pre');
|
||||
|
||||
DOM.setHTML('test', '<pre> </pre>');
|
||||
equal(ser.serialize(DOM.get('test')), '<pre> </pre>');
|
||||
});
|
||||
|
||||
test('Script with src attr', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
@ -524,3 +543,17 @@ test('addTempAttr', function() {
|
||||
equal(ser.serialize(DOM.get('test'), {getInner: 1}), '<p data-z="3">a</p>');
|
||||
equal(ser.trimHtml('<p data-x="1" data-y="2" data-z="3">a</p>'), '<p data-z="3">a</p>');
|
||||
});
|
||||
|
||||
test('addTempAttr same attr twice', function() {
|
||||
var ser1 = new tinymce.dom.Serializer({});
|
||||
var ser2 = new tinymce.dom.Serializer({});
|
||||
|
||||
ser1.addTempAttr('data-x');
|
||||
ser2.addTempAttr('data-x');
|
||||
|
||||
DOM.setHTML('test', '<p data-x="1" data-z="3">a</p>');
|
||||
equal(ser1.serialize(DOM.get('test'), {getInner: 1}), '<p data-z="3">a</p>');
|
||||
equal(ser1.trimHtml('<p data-x="1" data-z="3">a</p>'), '<p data-z="3">a</p>');
|
||||
equal(ser2.serialize(DOM.get('test'), {getInner: 1}), '<p data-z="3">a</p>');
|
||||
equal(ser2.trimHtml('<p data-x="1" data-z="3">a</p>'), '<p data-z="3">a</p>');
|
||||
});
|
||||
|
||||
@ -2,21 +2,31 @@ ModuleLoader.require([
|
||||
"tinymce/file/ImageScanner",
|
||||
"tinymce/file/UploadStatus",
|
||||
"tinymce/file/BlobCache",
|
||||
"tinymce/file/Conversions",
|
||||
"tinymce/Env"
|
||||
], function(ImageScanner, UploadStatus, BlobCache, Env) {
|
||||
], function(ImageScanner, UploadStatus, BlobCache, Conversions, Env) {
|
||||
if (!tinymce.Env.fileApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("tinymce.file.ImageScanner");
|
||||
|
||||
var base64Src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==';
|
||||
var blobUriSrc;
|
||||
|
||||
Conversions.uriToBlob(base64Src).then(function(blob) {
|
||||
blobUriSrc = URL.createObjectURL(blob);
|
||||
QUnit.start();
|
||||
});
|
||||
|
||||
QUnit.asyncTest("findAll", function() {
|
||||
var imageScanner = new ImageScanner(new UploadStatus(), new BlobCache());
|
||||
|
||||
document.getElementById('view').innerHTML = (
|
||||
'<img src="' + base64Src + '">' +
|
||||
'<img src="' + blobUriSrc + '">' +
|
||||
'<img src="' + Env.transparentSrc + '">' +
|
||||
'<img src="' + base64Src + '" data-mce-bogus="1">' +
|
||||
'<img src="' + base64Src + '" data-mce-placeholder="1">'
|
||||
@ -24,8 +34,9 @@ ModuleLoader.require([
|
||||
|
||||
imageScanner.findAll(document.getElementById('view')).then(function(result) {
|
||||
QUnit.start();
|
||||
equal(result.length, 1);
|
||||
equal('data:image/gif;base64,' + result[0].blobInfo.base64(), base64Src);
|
||||
var blobInfo = result[0].blobInfo;
|
||||
equal(result.length, 2);
|
||||
equal('data:image/gif;base64,' + blobInfo.base64(), base64Src);
|
||||
strictEqual(result[0].image, document.getElementById('view').firstChild);
|
||||
});
|
||||
});
|
||||
|
||||
75
tests/qunit/editor/tinymce/fmt/FontInfo.js
Normal file
75
tests/qunit/editor/tinymce/fmt/FontInfo.js
Normal file
@ -0,0 +1,75 @@
|
||||
ModuleLoader.require(["tinymce/fmt/FontInfo"], function(FontInfo) {
|
||||
module("tinymce.fmt.FontInfo", {});
|
||||
|
||||
var assertComputedFontProp = function (fontProp, html, expected) {
|
||||
var div = document.createElement('div');
|
||||
var fontGetProp = fontProp === 'fontSize' ? FontInfo.getFontSize : FontInfo.getFontFamily;
|
||||
|
||||
document.body.appendChild(div);
|
||||
div.style[fontProp] = expected;
|
||||
div.innerHTML = html;
|
||||
equal(fontGetProp(div, div.getElementsByTagName('mark')[0]), expected, 'Doesn\'t match the expected computed runtime style');
|
||||
div.parentNode.removeChild(div);
|
||||
};
|
||||
|
||||
var assertSpecificFontProp = function (fontProp, html, expected) {
|
||||
var div = document.createElement('div');
|
||||
var fontGetProp = fontProp === 'fontSize' ? FontInfo.getFontSize : FontInfo.getFontFamily;
|
||||
|
||||
document.body.appendChild(div);
|
||||
div.innerHTML = html;
|
||||
equal(fontGetProp(div, div.getElementsByTagName('mark')[0]), expected, 'Doesn\'t match the expected specific element style');
|
||||
div.parentNode.removeChild(div);
|
||||
};
|
||||
|
||||
test('toPt', function() {
|
||||
equal(FontInfo.toPt('10px'), '8pt');
|
||||
equal(FontInfo.toPt('11px'), '8pt');
|
||||
equal(FontInfo.toPt('12.5px'), '9pt');
|
||||
equal(FontInfo.toPt('13px'), '10pt');
|
||||
equal(FontInfo.toPt('36px'), '27pt');
|
||||
});
|
||||
|
||||
test('getFontSize', function() {
|
||||
assertComputedFontProp('fontSize', '<mark></mark>', '10px');
|
||||
assertComputedFontProp('fontSize', '<span><mark></mark></span>', '10px');
|
||||
assertSpecificFontProp('fontSize', '<mark style="font-size: 10px"></mark>', '10px');
|
||||
assertSpecificFontProp('fontSize', '<mark style="font-size: 14px"></mark>', '14px');
|
||||
assertSpecificFontProp('fontSize', '<mark style="font-size: 14pt"></mark>', '14pt');
|
||||
assertSpecificFontProp('fontSize', '<mark style="font-size: 14em"></mark>', '14em');
|
||||
assertSpecificFontProp('fontSize', '<span style="font-size: 10px"><mark></mark></span>', '10px');
|
||||
assertSpecificFontProp('fontSize', '<span style="font-size: 14px"><mark></mark></span>', '14px');
|
||||
assertSpecificFontProp('fontSize', '<span style="font-size: 10px"><span><mark></mark></span></span>', '10px');
|
||||
assertSpecificFontProp('fontSize', '<span style="font-size: 14px"><span><mark></mark></span></span>', '14px');
|
||||
});
|
||||
|
||||
test('getFontFamily', function() {
|
||||
assertComputedFontProp('fontFamily', '<mark></mark>', 'Arial,Verdana');
|
||||
assertComputedFontProp('fontFamily', '<span><mark></mark></span>', 'Arial,Helvetica,Verdana');
|
||||
assertSpecificFontProp('fontFamily', '<mark style="font-family: Arial, Verdana"></mark>', 'Arial,Verdana');
|
||||
assertSpecificFontProp('fontFamily', '<mark style="font-family: Arial, Helvetica, Verdana"></mark>', 'Arial,Helvetica,Verdana');
|
||||
assertSpecificFontProp('fontFamily', '<span style="font-family: Arial, Verdana"><mark></mark></span>', 'Arial,Verdana');
|
||||
assertSpecificFontProp('fontFamily', '<span style="font-family: Arial, Helvetica, Verdana"><mark></mark></span>', 'Arial,Helvetica,Verdana');
|
||||
assertSpecificFontProp('fontFamily', '<span style="font-family: Arial, Verdana"><span><mark></mark></span>', 'Arial,Verdana');
|
||||
assertSpecificFontProp('fontFamily', '<span style="font-family: Arial, Helvetica, Verdana"><span><mark></mark></span></span>', 'Arial,Helvetica,Verdana');
|
||||
});
|
||||
|
||||
asyncTest('getFontFamily should always return string even if display: none (firefox specific bug)', function() {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.style.display = 'none';
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
iframe.addEventListener('load', function () {
|
||||
QUnit.start();
|
||||
var fontFamily = FontInfo.getFontFamily(iframe.contentDocument.body, iframe.contentDocument.body.firstChild);
|
||||
|
||||
equal(typeof fontFamily, 'string', 'Should always be a string');
|
||||
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
}, false);
|
||||
|
||||
iframe.contentDocument.open();
|
||||
iframe.contentDocument.write('<html><body><p>a</p></body></html>');
|
||||
iframe.contentDocument.close();
|
||||
});
|
||||
});
|
||||
247
tests/qunit/editor/tinymce/fmt/Preview.js
Normal file
247
tests/qunit/editor/tinymce/fmt/Preview.js
Normal file
@ -0,0 +1,247 @@
|
||||
ModuleLoader.require(["tinymce/fmt/Preview"], function(Preview) {
|
||||
module("tinymce.fmt.Preview", {
|
||||
setupModule: function () {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
custom_elements: '~custom',
|
||||
extended_valid_elements: 'custom',
|
||||
init_instance_callback: function (ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
test('Get preview css text for formats', function () {
|
||||
|
||||
function getCssText(format) {
|
||||
return Preview.getCssText(editor, format);
|
||||
}
|
||||
|
||||
ok(/font-weight\:(bold|700)/.test(getCssText('bold')),
|
||||
'Bold not found in preview style');
|
||||
|
||||
ok(/font-weight\:(bold|700)/.test(getCssText({inline: 'b'})),
|
||||
'Bold not found in preview style');
|
||||
|
||||
ok(!/font-weight\:(bold|700)/.test(getCssText({inline: 'b', preview: 'font-size'})),
|
||||
'Bold should not be when we only preview font-size');
|
||||
|
||||
ok(/color\:rgb\(255, 0, 0\)/.test(getCssText({inline: 'custom', styles: {color: '#ff0000'}})),
|
||||
'Test preview of a custom element.');
|
||||
|
||||
editor.dom.addStyle(
|
||||
'table .preview {' +
|
||||
'color: rgb(0, 255, 0);' + // green
|
||||
'}' +
|
||||
|
||||
'ol .preview {' +
|
||||
'color: rgb(0, 0, 255);' + // blue
|
||||
'}' +
|
||||
|
||||
'.preview {' +
|
||||
'color: rgb(255, 0, 0);' + // red
|
||||
'}'
|
||||
);
|
||||
|
||||
ok(/color\:rgb\(0, 255, 0\)/.test(getCssText({selector: 'tr', classes: ['preview']})),
|
||||
'Style is properly inherited in preview for partial element (like TR).');
|
||||
|
||||
|
||||
ok(/color\:rgb\(255, 0, 0\)/.test(getCssText({selector: 'li', classes: ['preview']})),
|
||||
'For LI element default required parent is UL.');
|
||||
|
||||
ok(/color\:rgb\(0, 0, 255\)/.test(getCssText({selector: 'ol li', classes: ['preview']})),
|
||||
'Parent explicitly present in the selector will have preference.');
|
||||
|
||||
ok(/color\:rgb\(0, 0, 255\)/.test(getCssText({selector: 'ol > li', classes: ['preview']})),
|
||||
'ol > li previewed properly.');
|
||||
|
||||
ok(/color\:rgb\(0, 0, 255\)/.test(getCssText({
|
||||
selector: 'ol.someClass > li#someId[title="someTitle"]',
|
||||
classes: ['preview']
|
||||
})),
|
||||
'ol.someClass > li#someId[title="someTitle"] previewed properly.');
|
||||
|
||||
ok(/color\:rgb\(0, 0, 255\)/.test(getCssText({
|
||||
selector: 'ul + ol.someClass > li#someId',
|
||||
classes: ['preview']
|
||||
})),
|
||||
'ul + ol.someClass > li#someId previewed properly.');
|
||||
|
||||
ok(/color\:rgb\(0, 0, 255\)/.test(getCssText({selector: 'ul li ol li', classes: ['preview']})),
|
||||
'ul li ol li previewed properly.');
|
||||
});
|
||||
|
||||
|
||||
test('Preview.parseSelector()', function() {
|
||||
|
||||
deepEqual(Preview.parseSelector('li.class1.class2#id1[attr1="1"]:disabled'), [
|
||||
{
|
||||
name: 'li',
|
||||
selector: 'li.class1.class2#id1[attr1="1"]:disabled',
|
||||
classes: ['class1', 'class2'],
|
||||
attrs: {
|
||||
id: 'id1',
|
||||
attr1: '1',
|
||||
disabled: 'disabled'
|
||||
}
|
||||
}
|
||||
], 'li.class1.class2#id1 ok');
|
||||
|
||||
|
||||
deepEqual(Preview.parseSelector('ul.parent1 > li.class1.class2#id1'), [
|
||||
{
|
||||
name: 'li',
|
||||
selector: 'li.class1.class2#id1',
|
||||
classes: ['class1', 'class2'],
|
||||
attrs: {
|
||||
id: 'id1'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'ul',
|
||||
selector: 'ul.parent1',
|
||||
classes: ['parent1'],
|
||||
attrs: {}
|
||||
}
|
||||
], 'ul.parent1 > li.class1.class2#id1 ok');
|
||||
|
||||
|
||||
deepEqual(Preview.parseSelector('div.class1 > ol.class2 + ul > li:hover'), [
|
||||
{
|
||||
name: 'li',
|
||||
selector: 'li:hover',
|
||||
classes: [],
|
||||
attrs: {}
|
||||
},
|
||||
{
|
||||
name: 'ul',
|
||||
selector: 'ul',
|
||||
classes: [],
|
||||
attrs: {},
|
||||
siblings: [
|
||||
{
|
||||
name: 'ol',
|
||||
selector: 'ol.class2',
|
||||
classes: ['class2'],
|
||||
attrs: {}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'div',
|
||||
selector: 'div.class1',
|
||||
classes: ['class1'],
|
||||
attrs: {}
|
||||
}
|
||||
], 'div.class1 > ol.class2 + ul > li:hover ok');
|
||||
|
||||
deepEqual(Preview.parseSelector('.class > *'), [
|
||||
{
|
||||
name: "div",
|
||||
selector: "*",
|
||||
attrs: {},
|
||||
classes: []
|
||||
},
|
||||
{
|
||||
name: "div",
|
||||
selector: ".class",
|
||||
classes: ["class"],
|
||||
attrs: {}
|
||||
}
|
||||
], '.class > * ok');
|
||||
|
||||
deepEqual(Preview.parseSelector('p + *'), [
|
||||
{
|
||||
name: "div",
|
||||
selector: "*",
|
||||
attrs: {},
|
||||
classes: [],
|
||||
siblings: [
|
||||
{
|
||||
name: "p",
|
||||
selector: "p",
|
||||
attrs: {},
|
||||
classes: []
|
||||
}
|
||||
]
|
||||
}
|
||||
], 'p + * ok');
|
||||
|
||||
deepEqual(Preview.parseSelector('*.test'), [
|
||||
{
|
||||
name: "*",
|
||||
selector: "*.test",
|
||||
attrs: {},
|
||||
classes: ['test']
|
||||
}
|
||||
], '*.test ok');
|
||||
});
|
||||
|
||||
|
||||
test('Preview.selectorToHtml()', function() {
|
||||
function trimSpaces(str) {
|
||||
return str.replace(/>\s+</g, '><').replace(/^\s*|\s*$/g, '');
|
||||
}
|
||||
|
||||
function selectorToHtml(selector) {
|
||||
return Utils.normalizeHtml(Preview.selectorToHtml(selector).outerHTML);
|
||||
}
|
||||
|
||||
equal(selectorToHtml('ul > li.class1'), trimSpaces([
|
||||
'<div>',
|
||||
'<ul>',
|
||||
'<li class="class1"></li>',
|
||||
'</ul>',
|
||||
'</div>'
|
||||
].join('')), 'ul > li.class1 ok');
|
||||
|
||||
|
||||
equal(selectorToHtml('ol + ul#id1 > li.class1[title="Some Title"]'), trimSpaces([
|
||||
'<div>',
|
||||
'<div>',
|
||||
'<ol></ol>',
|
||||
'<ul id="id1">',
|
||||
' <li class="class1" title="Some Title"></li>',
|
||||
'</ul>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join('')), 'ol + ul#id1 > li.class1[title="Some Title"] ok');
|
||||
|
||||
|
||||
equal(selectorToHtml('tr > th + td'), trimSpaces([
|
||||
'<div>',
|
||||
'<table>',
|
||||
'<tbody>',
|
||||
'<tr>',
|
||||
'<th></th>',
|
||||
'<td></td>',
|
||||
'</tr>',
|
||||
'</tbody>',
|
||||
'</table>',
|
||||
'</div>'
|
||||
].join('')), 'tr > th + td (required parental structure properly rebuilt) ok');
|
||||
|
||||
|
||||
equal(selectorToHtml('p li[title="Some Title"][alt="Some Alt"]'), trimSpaces([
|
||||
'<div>',
|
||||
'<p>',
|
||||
'<ul>',
|
||||
'<li alt="Some Alt" title="Some Title"></li>',
|
||||
'</ul>',
|
||||
'</p>',
|
||||
'</div>'
|
||||
].join('')), 'p li[title="Some Title"][alt="Some Alt"] (test multiple spaced attributes) ok');
|
||||
|
||||
});
|
||||
});
|
||||
@ -99,6 +99,13 @@
|
||||
deepEqual(countNodes(root), {body:1, pre:1, '#text':1}, 'Whitespace around and inside PRE (count)');
|
||||
});
|
||||
|
||||
test('Whitespace preserved in PRE', function() {
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<PRE> </PRE>');
|
||||
equal(serializer.serialize(root), '<pre> </pre>', 'Whitespace around and inside PRE');
|
||||
deepEqual(countNodes(root), {body:1, pre:1, '#text':1}, 'Whitespace around and inside PRE (count)');
|
||||
});
|
||||
|
||||
test('Whitespace preserved in SPAN inside PRE', function() {
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse(' \t\r\n <PRE> \t\r\n <span> test </span> \t\r\n </PRE> \t\r\n ');
|
||||
@ -106,6 +113,20 @@
|
||||
deepEqual(countNodes(root), {body:1, pre:1, span:1, '#text':3}, 'Whitespace around and inside PRE (count)');
|
||||
});
|
||||
|
||||
test('Whitespace preserved in code', function() {
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<code> a </code>');
|
||||
equal(serializer.serialize(root), '<code> a </code>', 'Whitespace inside code');
|
||||
deepEqual(countNodes(root), {body:1, code:1, '#text':1}, 'Whitespace inside code (count)');
|
||||
});
|
||||
|
||||
test('Whitespace preserved in code', function() {
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<code> </code>');
|
||||
equal(serializer.serialize(root), '<code> </code>', 'Whitespace inside code');
|
||||
deepEqual(countNodes(root), {body:1, code:1, '#text':1}, 'Whitespace inside code (count)');
|
||||
});
|
||||
|
||||
test('Parse invalid contents', function() {
|
||||
var parser, root;
|
||||
|
||||
@ -422,6 +443,14 @@
|
||||
'Mixed text nodes, inline elements and blocks.');
|
||||
});
|
||||
|
||||
test('Parse html4 lists into html5 lists', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
parser = new tinymce.html.DomParser({fix_list_elements: true}, schema);
|
||||
root = parser.parse('<ul><ul><li>a</li></ul></ul><ul><li>a</li><ul><li>b</li></ul></ul>');
|
||||
equal(serializer.serialize(root), '<ul><li style="list-style-type: none"><ul><li>a</li></ul></li></ul><ul><li>a<ul><li>b</li></ul></li></ul>');
|
||||
});
|
||||
|
||||
test('Parse contents with html4 anchors and allow_html_in_named_anchor: false', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
@ -510,6 +539,14 @@
|
||||
equal(serializer.serialize(root), '');
|
||||
});
|
||||
|
||||
test('Padd empty with br', function() {
|
||||
var schema = new tinymce.html.Schema();
|
||||
var parser = new tinymce.html.DomParser({padd_empty_with_br: true}, schema);
|
||||
var serializer = new tinymce.html.Serializer({padd_empty_with_br: true}, schema);
|
||||
var root = parser.parse('<p>a</p><p></p>');
|
||||
equal(serializer.serialize(root), '<p>a</p><p><br /></p>');
|
||||
});
|
||||
|
||||
test('Preserve space in inline span', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
|
||||
@ -139,7 +139,7 @@ test('remove middle node', function() {
|
||||
ok(root.lastChild === node3, 'root.lastChild');
|
||||
ok(node.next === node3, 'node.next');
|
||||
equal(node.prev, undefined, 'node.prev');
|
||||
ok(node3.prev, node, 'node3.prev');
|
||||
equal(node3.prev, node, 'node3.prev');
|
||||
equal(node3.next, undefined, 'node3.next');
|
||||
});
|
||||
|
||||
|
||||
@ -604,6 +604,10 @@
|
||||
writer.reset();
|
||||
parser.parse('<!--[if !IE]>alert(1)<![endif]-->');
|
||||
equal(writer.getContent(), '<!-- [if !IE]>alert(1)<![endif]-->');
|
||||
|
||||
writer.reset();
|
||||
parser.parse('<!--[iF !IE]>alert(1)<![endif]-->');
|
||||
equal(writer.getContent(), '<!-- [iF !IE]>alert(1)<![endif]-->');
|
||||
});
|
||||
|
||||
test('Parse script urls (allowed)', function() {
|
||||
|
||||
@ -13,27 +13,27 @@ test('Whildcard element rule', function() {
|
||||
expect(17);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: '*[id|class]'});
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'b*[id|class]'});
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
|
||||
deepEqual(schema.getElementRule('body').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('body').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('body').attributesOrder, ["id", "class"]);
|
||||
equal(schema.getElementRule('img'), undefined);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'b?[id|class]'});
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
|
||||
deepEqual(schema.getElementRule('bx').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('bx').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('bx').attributesOrder, ["id", "class"]);
|
||||
equal(schema.getElementRule('body'), undefined);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'b+[id|class]'});
|
||||
deepEqual(schema.getElementRule('body').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('body').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('body').attributesOrder, ["id", "class"]);
|
||||
deepEqual(schema.getElementRule('bx').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('bx').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('bx').attributesOrder, ["id", "class"]);
|
||||
equal(schema.getElementRule('b'), undefined);
|
||||
});
|
||||
@ -44,19 +44,19 @@ test('Whildcard attribute rule', function() {
|
||||
expect(13);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'b[id|class|*]'});
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
|
||||
ok(schema.getElementRule('b').attributePatterns[0].pattern.test('x'));
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'b[id|class|x?]'});
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
|
||||
ok(schema.getElementRule('b').attributePatterns[0].pattern.test('xy'));
|
||||
ok(!schema.getElementRule('b').attributePatterns[0].pattern.test('xba'));
|
||||
ok(!schema.getElementRule('b').attributePatterns[0].pattern.test('a'));
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'b[id|class|x+]'});
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
|
||||
ok(!schema.getElementRule('b').attributePatterns[0].pattern.test('x'));
|
||||
ok(schema.getElementRule('b').attributePatterns[0].pattern.test('xb'));
|
||||
@ -119,6 +119,15 @@ test('Required attribute values', function() {
|
||||
deepEqual(schema.getElementRule('span'), {"attributes": {"dir": {"validValues": {"rtl": {}, "ltr": {}}}}, "attributesOrder": ["dir"]});
|
||||
});
|
||||
|
||||
test('Required parents', function() {
|
||||
var schema;
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getElementRule('tr').parentsRequired, ['tbody', 'thead', 'tfoot']);
|
||||
deepEqual(schema.getElementRule('li').parentsRequired, ['ul', 'ol']);
|
||||
deepEqual(schema.getElementRule('div').parentsRequired, undefined);
|
||||
});
|
||||
|
||||
test('Remove empty elements', function() {
|
||||
var schema;
|
||||
|
||||
@ -220,11 +229,11 @@ test('getNonEmptyElements', function() {
|
||||
"EMBED": {}, "PARAM": {}, "META": {}, "LINK": {}, "ISINDEX": {},
|
||||
"INPUT": {}, "IMG": {}, "HR": {}, "FRAME": {}, "COL": {}, "BR": {},
|
||||
"BASEFONT": {}, "BASE": {}, "AREA": {}, "SOURCE" : {},
|
||||
"TD": {}, "TH": {}, "IFRAME": {}, "VIDEO": {}, "AUDIO": {}, "OBJECT": {}, "WBR": {}, "TRACK" : {}, "SCRIPT" : {},
|
||||
"TD": {}, "TH": {}, "IFRAME": {}, "VIDEO": {}, "AUDIO": {}, "OBJECT": {}, "WBR": {}, "TRACK" : {}, "SCRIPT" : {}, "PRE": {}, "CODE": {},
|
||||
"embed": {}, "param": {}, "meta": {}, "link": {}, "isindex": {},
|
||||
"input": {}, "img": {}, "hr": {}, "frame": {}, "col": {}, "br": {},
|
||||
"basefont": {}, "base": {}, "area": {}, "source" : {},
|
||||
"td": {}, "th": {}, "iframe": {}, "video": {}, "audio": {}, "object": {}, "wbr" : {}, "track" : {}, "script" : {}
|
||||
"td": {}, "th": {}, "iframe": {}, "video": {}, "audio": {}, "object": {}, "wbr" : {}, "track" : {}, "script" : {}, "pre": {}, "code": {}
|
||||
});
|
||||
});
|
||||
|
||||
@ -235,9 +244,9 @@ test('getWhiteSpaceElements', function() {
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getWhiteSpaceElements(), {
|
||||
"IFRAME": {}, "NOSCRIPT": {}, "OBJECT": {}, "PRE": {},
|
||||
"IFRAME": {}, "NOSCRIPT": {}, "OBJECT": {}, "PRE": {}, "CODE": {},
|
||||
"SCRIPT": {}, "STYLE": {}, "TEXTAREA": {}, "VIDEO": {}, "AUDIO": {},
|
||||
"iframe": {}, "noscript": {}, "object": {}, "pre": {},
|
||||
"iframe": {}, "noscript": {}, "object": {}, "pre": {}, "code": {},
|
||||
"script": {}, "style": {}, "textarea": {}, "video": {}, "audio": {}
|
||||
});
|
||||
});
|
||||
|
||||
@ -3,7 +3,7 @@ module("tinymce.html.Styles");
|
||||
test('Basic parsing/serializing', function() {
|
||||
var styles = new tinymce.html.Styles();
|
||||
|
||||
expect(11);
|
||||
expect(12);
|
||||
|
||||
equal(styles.serialize(styles.parse('FONT-SIZE:10px')), "font-size: 10px;");
|
||||
equal(styles.serialize(styles.parse('FONT-SIZE:10px;COLOR:red')), "font-size: 10px; color: red;");
|
||||
@ -16,6 +16,7 @@ test('Basic parsing/serializing', function() {
|
||||
equal(styles.serialize(styles.parse('value: "&"')), "value: '&';");
|
||||
equal(styles.serialize(styles.parse('value: "&"')), "value: '&';");
|
||||
equal(styles.serialize(styles.parse('value: ')), "");
|
||||
equal(styles.serialize(styles.parse("background: url('http://www.site.com/(foo)');")), "background: url('http://www.site.com/(foo)');");
|
||||
});
|
||||
|
||||
test('Colors force hex and lowercase', function() {
|
||||
@ -61,7 +62,7 @@ test('Compress styles', function() {
|
||||
styles.serialize(styles.parse('border-width: 1pt 1pt 1pt 1pt; border-style: none none none none; border-color: black black black black;')),
|
||||
'border: 1pt none black;'
|
||||
);
|
||||
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('border-width: 1pt 4pt 2pt 3pt; border-style: solid dashed dotted none; border-color: black red green blue;')),
|
||||
'border-width: 1pt 4pt 2pt 3pt; border-style: solid dashed dotted none; border-color: black red green blue;'
|
||||
@ -137,10 +138,19 @@ test('Invalid styles', function() {
|
||||
equal(styles.serialize(styles.parse('color: #ff0000; font-size: 10px; margin-left: 10px; margin-right: 10px;'), 'a'), "margin-right: 10px;");
|
||||
});
|
||||
|
||||
test('Suspicious (XSS) property names', function() {
|
||||
var styles = new tinymce.html.Styles();
|
||||
|
||||
equal(styles.serialize(styles.parse('font-fa"on-load\\3dxss\\28\\29\\20mily:\'arial\'')), "");
|
||||
equal(styles.serialize(styles.parse('font-fa\\"on-load\\3dxss\\28\\29\\20mily:\'arial\'')), "");
|
||||
equal(styles.serialize(styles.parse('font-fa\\22on-load\\3dxss\\28\\29\\20mily:\'arial\'')), "");
|
||||
});
|
||||
|
||||
test('Script urls denied', function() {
|
||||
var styles = new tinymce.html.Styles();
|
||||
|
||||
equal(styles.serialize(styles.parse('behavior:url(test.htc)')), "");
|
||||
equal(styles.serialize(styles.parse('b\\65havior:url(test.htc)')), "");
|
||||
equal(styles.serialize(styles.parse('color:expression(alert(1))')), "");
|
||||
equal(styles.serialize(styles.parse('color:\\65xpression(alert(1))')), "");
|
||||
equal(styles.serialize(styles.parse('color:exp/**/ression(alert(1))')), "");
|
||||
@ -148,9 +158,20 @@ test('Script urls denied', function() {
|
||||
equal(styles.serialize(styles.parse('color: expression ( alert(1))')), "");
|
||||
equal(styles.serialize(styles.parse('background:url(jAvaScript:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url(javascript:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url(j\\61vascript:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url(\\6a\\61vascript:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url(\\6A\\61vascript:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url\\28\\6A\\61vascript:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('background:\\75rl(j\\61vascript:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('b\\61ckground:\\75rl(j\\61vascript:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url(vbscript:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url(j\navas\u0000cr\tipt:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url(data:image/svg+xml,%3Csvg/%3E)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url( data:image/svg+xml,%3Csvg/%3E)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url\\28 data:image/svg+xml,%3Csvg/%3E)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url("data: image/svg+xml,%3Csvg/%3E")')), "");
|
||||
equal(styles.serialize(styles.parse('background:url("data: ima ge/svg+xml,%3Csvg/%3E")')), "");
|
||||
equal(styles.serialize(styles.parse('background:url("data: image /svg+xml,%3Csvg/%3E")')), "");
|
||||
});
|
||||
|
||||
test('Script urls allowed', function() {
|
||||
|
||||
94
tests/qunit/editor/tinymce/options.js
Normal file
94
tests/qunit/editor/tinymce/options.js
Normal file
@ -0,0 +1,94 @@
|
||||
module("tinymce.options", {
|
||||
setup: function() {
|
||||
var i, htmlReset = '';
|
||||
for (i = 1; i < 9; i++) {
|
||||
htmlReset += '<textarea id="elm-' + i + '" class="' + (i&1 ? 'elm-odd' : 'elm-even') + '"></textarea>';
|
||||
}
|
||||
|
||||
document.getElementById('view').innerHTML = htmlReset;
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
var ed;
|
||||
while ((ed = tinymce.editors.pop())) {
|
||||
ed.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
test("target (initialised properly)", function() {
|
||||
var elm1 = document.getElementById('elm-1');
|
||||
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
target: elm1,
|
||||
init_instance_callback: function(ed) {
|
||||
QUnit.start();
|
||||
|
||||
equal(ed.targetElm, elm1);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test("target (initialise on element without id)", function() {
|
||||
var elm = document.createElement('textarea');
|
||||
document.getElementById('view').appendChild(elm);
|
||||
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
target: elm,
|
||||
init_instance_callback: function(ed) {
|
||||
QUnit.start();
|
||||
|
||||
ok(ed.id, "editors id set to: " + ed.id);
|
||||
equal(ed.targetElm, elm);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test("target (selector option takes precedence over target option)", function() {
|
||||
var elm1 = document.getElementById('elm-1');
|
||||
var elm2 = document.getElementById('elm-2');
|
||||
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: '#elm-2',
|
||||
target: elm1,
|
||||
init_instance_callback: function(ed) {
|
||||
QUnit.start();
|
||||
|
||||
equal(ed.targetElm, elm2);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test("target (each editor should have a different target)", function() {
|
||||
var maxCount = $('.elm-even').length;
|
||||
var elm1 = document.getElementById('elm-1');
|
||||
var count = 0;
|
||||
var targets = [];
|
||||
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: '.elm-even',
|
||||
target: elm1,
|
||||
init_instance_callback: function(ed) {
|
||||
notEqual(ed.targetElm, elm1, "target option ignored");
|
||||
ok($.inArray(ed.targetElm, targets) === -1);
|
||||
|
||||
targets.push(ed.targetElm);
|
||||
|
||||
if (++count >= maxCount) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
260
tests/qunit/editor/tinymce/ui/FilePicker.js
Normal file
260
tests/qunit/editor/tinymce/ui/FilePicker.js
Normal file
@ -0,0 +1,260 @@
|
||||
ModuleLoader.require([
|
||||
'tinymce/util/VK',
|
||||
'tinymce/util/Promise'
|
||||
], function(VK, Promise) {
|
||||
module("tinymce.ui.FilePicker", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
plugins: 'link',
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
},
|
||||
filepicker_validator_handler: function (query, success) {
|
||||
setTimeout(function () {
|
||||
var valid = query.url.indexOf('fake') === -1;
|
||||
|
||||
success({
|
||||
status: valid ? 'valid' : 'invalid',
|
||||
message: valid ? 'Valid message' : 'Invalid message'
|
||||
});
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
delete editor.settings.anchor_top;
|
||||
delete editor.settings.anchor_bottom;
|
||||
delete editor.settings.typeahead_urls;
|
||||
}
|
||||
});
|
||||
|
||||
var getFilePickerCtrl = function () {
|
||||
var win = editor.windowManager.getWindows()[0];
|
||||
return win ? win.find('filepicker')[0] : null;
|
||||
};
|
||||
|
||||
var keydownOnCtrl = function (pickerCtrl, keyCode) {
|
||||
return new Promise(function (resolve) {
|
||||
pickerCtrl.fire('keydown', {target: pickerCtrl.getEl('inp'), keyCode: keyCode});
|
||||
resolve(pickerCtrl);
|
||||
});
|
||||
};
|
||||
|
||||
var downOnMenu = function () {
|
||||
return keydownOnCtrl(getFilePickerCtrl().menu, VK.DOWN);
|
||||
};
|
||||
|
||||
var enterOnMenu = function () {
|
||||
return keydownOnCtrl(getFilePickerCtrl().menu, VK.ENTER);
|
||||
};
|
||||
|
||||
var downOnPicker = function () {
|
||||
return keydownOnCtrl(getFilePickerCtrl(), VK.DOWN);
|
||||
};
|
||||
|
||||
var enterOnPicker = function () {
|
||||
return keydownOnCtrl(getFilePickerCtrl(), VK.ENTER);
|
||||
};
|
||||
|
||||
var setContent = function (content) {
|
||||
return function () {
|
||||
return new Promise(function (resolve) {
|
||||
editor.setContent(content);
|
||||
resolve(true);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var execCommand = function (cmd) {
|
||||
return function () {
|
||||
return new Promise(function (resolve) {
|
||||
editor.execCommand(cmd);
|
||||
resolve(true);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var assertContent = function (exceptedContent) {
|
||||
return function () {
|
||||
return new Promise(function (resolve) {
|
||||
equal(editor.getContent(), exceptedContent, 'Should have the expected content');
|
||||
resolve(true);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var waitFor = function (predicate, poll, timeout) {
|
||||
return function () {
|
||||
var start = new Date().getTime();
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
var check = function () {
|
||||
if (predicate()) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
if (new Date().getTime() - start > timeout) {
|
||||
reject(new Error('Timeout while waiting for predicate'));
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(check, poll);
|
||||
};
|
||||
|
||||
check();
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var waitForMenu = waitFor(
|
||||
function () {
|
||||
var pickerCtrl = getFilePickerCtrl();
|
||||
return pickerCtrl && pickerCtrl.menu;
|
||||
},
|
||||
100,
|
||||
1000
|
||||
);
|
||||
|
||||
var setCaret = function (selector, index) {
|
||||
return function () {
|
||||
return new Promise(function (resolve) {
|
||||
Utils.setSelection(selector, index);
|
||||
resolve(true);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var assertValue = function (expectedValue) {
|
||||
return function () {
|
||||
return new Promise(function (resolve) {
|
||||
var pickerCtrl = getFilePickerCtrl();
|
||||
equal(pickerCtrl.value(), expectedValue, 'Should have the correct file picker value');
|
||||
resolve(pickerCtrl);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var setPickerValue = function (value) {
|
||||
return function () {
|
||||
return new Promise(function (resolve) {
|
||||
var pickerCtrl = getFilePickerCtrl();
|
||||
pickerCtrl.value(value);
|
||||
resolve(pickerCtrl);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var waitForStatusChange = waitFor(
|
||||
function () {
|
||||
var pickerCtrl = getFilePickerCtrl();
|
||||
var msg = pickerCtrl.statusMessage();
|
||||
return msg && msg.length > 0;
|
||||
},
|
||||
100,
|
||||
1000
|
||||
);
|
||||
|
||||
var assertStatus = function (level, message) {
|
||||
return function () {
|
||||
return new Promise(function (resolve) {
|
||||
var pickerCtrl = getFilePickerCtrl();
|
||||
equal(pickerCtrl.statusLevel(), level);
|
||||
equal(pickerCtrl.statusMessage(), message);
|
||||
resolve(pickerCtrl);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var sequence = function (fs) {
|
||||
return new Promise(function (resolve) {
|
||||
var result = [];
|
||||
|
||||
var next = function () {
|
||||
var f = fs.shift();
|
||||
|
||||
if (f) {
|
||||
f().then(function (res) {
|
||||
result.push(res);
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
};
|
||||
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
asyncTest('pick first anchor <top>', function() {
|
||||
sequence([
|
||||
setContent(''),
|
||||
execCommand('mceLink'),
|
||||
downOnPicker,
|
||||
waitForMenu,
|
||||
enterOnMenu,
|
||||
assertValue('#top'),
|
||||
enterOnPicker,
|
||||
assertContent('<p><a href="#top"><top></a></p>')
|
||||
]).then(function () {
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('pick second anchor <bottom>', function() {
|
||||
sequence([
|
||||
setContent(''),
|
||||
execCommand('mceLink'),
|
||||
downOnPicker,
|
||||
waitForMenu,
|
||||
downOnMenu,
|
||||
enterOnMenu,
|
||||
assertValue('#bottom'),
|
||||
enterOnPicker,
|
||||
assertContent('<p><a href="#bottom"><bottom></a></p>')
|
||||
]).then(function () {
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('pick first header', function() {
|
||||
sequence([
|
||||
setContent('<p>x</p><h1 id="h1">header</h1>'),
|
||||
setCaret('p', 0),
|
||||
execCommand('mceLink'),
|
||||
downOnPicker,
|
||||
waitForMenu,
|
||||
enterOnMenu,
|
||||
assertValue('#h1'),
|
||||
enterOnPicker,
|
||||
assertContent('<p><a href="#h1">header</a>x</p><h1 id="h1">header</h1>')
|
||||
]).then(function () {
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('filepicker_validator_handler', function() {
|
||||
sequence([
|
||||
setContent('<p>abc</p>'),
|
||||
setCaret('p', 0),
|
||||
execCommand('mceLink'),
|
||||
setPickerValue('http://www.site.com'),
|
||||
waitForStatusChange,
|
||||
assertStatus('ok', 'Valid message'),
|
||||
enterOnPicker
|
||||
]).then(function () {
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -36,7 +36,16 @@
|
||||
});
|
||||
|
||||
test("title, no buttonbar, autoResize, title is widest", function() {
|
||||
var win = createWindow({
|
||||
var win1 = createWindow({
|
||||
x: 100,
|
||||
y: 120,
|
||||
title: "XXXXXXXXXXXXXXXXXXX",
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1}
|
||||
]
|
||||
});
|
||||
|
||||
var win2 = createWindow({
|
||||
x: 100,
|
||||
y: 120,
|
||||
title: "XXXXXXXXXXXXXXXXXXXXXX",
|
||||
@ -45,8 +54,8 @@
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.size(win), [326, 61], 60);
|
||||
Utils.nearlyEqualRects(Utils.size(win.find("spacer")[0]), [324, 20], 60);
|
||||
equal(Utils.size(win2)[0] > Utils.size(win1)[0], true, 'Window 2 should be wider since the title spaces out the window');
|
||||
equal(Utils.size(win2.find("spacer")[0]) > Utils.size(win1.find("spacer")[0]), true, 'Window 2 spacer should be widger than window 1');
|
||||
});
|
||||
|
||||
test("buttonbar, autoResize, buttonbar is widest", function() {
|
||||
|
||||
17
tests/qunit/editor/tinymce/undo/Diff.js
Normal file
17
tests/qunit/editor/tinymce/undo/Diff.js
Normal file
@ -0,0 +1,17 @@
|
||||
ModuleLoader.require(["tinymce/undo/Diff"], function(Diff) {
|
||||
module("tinymce.undo.Diff");
|
||||
|
||||
var KEEP = Diff.KEEP, INSERT = Diff.INSERT, DELETE = Diff.DELETE;
|
||||
|
||||
test('diff', function() {
|
||||
deepEqual(Diff.diff([], []), []);
|
||||
deepEqual(Diff.diff([1], []), [[DELETE, 1]]);
|
||||
deepEqual(Diff.diff([1, 2], []), [[DELETE, 1], [DELETE, 2]]);
|
||||
deepEqual(Diff.diff([], [1]), [[INSERT, 1]]);
|
||||
deepEqual(Diff.diff([], [1, 2]), [[INSERT, 1], [INSERT, 2]]);
|
||||
deepEqual(Diff.diff([1], [1]), [[KEEP, 1]]);
|
||||
deepEqual(Diff.diff([1, 2], [1, 2]), [[KEEP, 1], [KEEP, 2]]);
|
||||
deepEqual(Diff.diff([1], [2]), [[INSERT, 2], [DELETE, 1]]);
|
||||
deepEqual(Diff.diff([1], [2, 3]), [[INSERT, 2], [INSERT, 3], [DELETE, 1]]);
|
||||
});
|
||||
});
|
||||
54
tests/qunit/editor/tinymce/undo/ForcedRootBlock.js
Normal file
54
tests/qunit/editor/tinymce/undo/ForcedRootBlock.js
Normal file
@ -0,0 +1,54 @@
|
||||
ModuleLoader.require([
|
||||
'tinymce/undo/Levels'
|
||||
], function(Levels) {
|
||||
module('tinymce.undo.ForcedRootBlock', {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: 'textarea',
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
forced_root_block: false,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('createFromEditor forced_root_block: false', function() {
|
||||
editor.getBody().innerHTML = '<strong>a</strong> <span>b</span>';
|
||||
|
||||
deepEqual(Levels.createFromEditor(editor), {
|
||||
'beforeBookmark': null,
|
||||
'bookmark': null,
|
||||
'content': '<strong>a</strong> <span>b</span>',
|
||||
'fragments': null,
|
||||
'type': 'complete'
|
||||
});
|
||||
});
|
||||
|
||||
test('createFromEditor forced_root_block: false', function() {
|
||||
editor.getBody().innerHTML = '<iframe src="about:blank"></iframe> <strong>a</strong> <span>b</span>';
|
||||
|
||||
deepEqual(Levels.createFromEditor(editor), {
|
||||
'beforeBookmark': null,
|
||||
'bookmark': null,
|
||||
'content': '',
|
||||
'fragments': [
|
||||
"<iframe src=\"about:blank\"></iframe>",
|
||||
" ",
|
||||
"<strong>a</strong>",
|
||||
" ",
|
||||
"<span>b</span>"
|
||||
],
|
||||
'type': 'fragmented'
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
32
tests/qunit/editor/tinymce/undo/Fragments.js
Normal file
32
tests/qunit/editor/tinymce/undo/Fragments.js
Normal file
@ -0,0 +1,32 @@
|
||||
ModuleLoader.require(['tinymce/undo/Fragments'], function(Fragments) {
|
||||
module('tinymce.undo.Fragments');
|
||||
|
||||
var div = function (html) {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = html;
|
||||
return div;
|
||||
};
|
||||
|
||||
var html = function (elm) {
|
||||
return elm.innerHTML;
|
||||
};
|
||||
|
||||
test('read', function() {
|
||||
deepEqual(Fragments.read(div('')), []);
|
||||
deepEqual(Fragments.read(div('a')), ['a']);
|
||||
deepEqual(Fragments.read(div('<!--a-->')), ['<!--a-->']);
|
||||
deepEqual(Fragments.read(div('<b>a</b>')), ['<b>a</b>']);
|
||||
deepEqual(Fragments.read(div('a<!--b--><b>c</b>')), ['a', '<!--b-->', '<b>c</b>']);
|
||||
});
|
||||
|
||||
test('write', function() {
|
||||
deepEqual(html(Fragments.write([], div(''))), '');
|
||||
deepEqual(html(Fragments.write([], div('a'))), '');
|
||||
deepEqual(html(Fragments.write(['a'], div(''))), 'a');
|
||||
deepEqual(html(Fragments.write(['a'], div('a'))), 'a');
|
||||
deepEqual(html(Fragments.write(['a'], div('b'))), 'a');
|
||||
deepEqual(html(Fragments.write(['a', '<b>c</b>'], div('a<b>b</b>'))), 'a<b>c</b>');
|
||||
deepEqual(html(Fragments.write(['<b>c</b>', '<b>d</b>'], div('a<b>b</b>'))), '<b>c</b><b>d</b>');
|
||||
deepEqual(html(Fragments.write(['<b>c</b>', '<b>d</b>', '<!--e-->'], div('a<b>b</b>'))), '<b>c</b><b>d</b><!--e-->');
|
||||
});
|
||||
});
|
||||
142
tests/qunit/editor/tinymce/undo/Levels.js
Normal file
142
tests/qunit/editor/tinymce/undo/Levels.js
Normal file
@ -0,0 +1,142 @@
|
||||
ModuleLoader.require([
|
||||
'tinymce/undo/Levels',
|
||||
'tinymce/Env'
|
||||
], function(Levels, Env) {
|
||||
module('tinymce.undo.Levels', {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: 'textarea',
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var getBookmark = function (editor) {
|
||||
return editor.selection.getBookmark(2, true);
|
||||
};
|
||||
|
||||
test('createFragmentedLevel', function() {
|
||||
deepEqual(Levels.createFragmentedLevel(['a', 'b']), {
|
||||
'beforeBookmark': null,
|
||||
'bookmark': null,
|
||||
'content': '',
|
||||
'fragments': ['a', 'b'],
|
||||
'type': 'fragmented'
|
||||
});
|
||||
});
|
||||
|
||||
test('createCompleteLevel', function() {
|
||||
deepEqual(Levels.createCompleteLevel('a'), {
|
||||
'beforeBookmark': null,
|
||||
'bookmark': null,
|
||||
'content': 'a',
|
||||
'fragments': null,
|
||||
'type': 'complete'
|
||||
});
|
||||
});
|
||||
|
||||
test('createFromEditor', function() {
|
||||
deepEqual(Levels.createFromEditor(editor), {
|
||||
'beforeBookmark': null,
|
||||
'bookmark': null,
|
||||
'content': Env.ie && Env.ie < 11 ? '<p></p>' : '<p><br data-mce-bogus="1"></p>',
|
||||
'fragments': null,
|
||||
'type': 'complete'
|
||||
});
|
||||
|
||||
editor.getBody().innerHTML = '<iframe src="about:blank"></iframe>a<!--b-->c';
|
||||
|
||||
deepEqual(Levels.createFromEditor(editor), {
|
||||
'beforeBookmark': null,
|
||||
'bookmark': null,
|
||||
'content': '',
|
||||
'fragments': ['<iframe src="about:blank"></iframe>', 'a', '<!--b-->', 'c'],
|
||||
'type': 'fragmented'
|
||||
});
|
||||
});
|
||||
|
||||
test('createFromEditor removes bogus=al', function() {
|
||||
editor.getBody().innerHTML = '<p data-mce-bogus="all">a</p> <span>b</span>';
|
||||
|
||||
deepEqual(Levels.createFromEditor(editor), {
|
||||
'beforeBookmark': null,
|
||||
'bookmark': null,
|
||||
'content': ' <span>b</span>',
|
||||
'fragments': null,
|
||||
'type': 'complete'
|
||||
});
|
||||
});
|
||||
|
||||
test('createFromEditor removes bogus=all', function() {
|
||||
editor.getBody().innerHTML = '<iframe src="about:blank"></iframe> <p data-mce-bogus="all">a</p> <span>b</span>';
|
||||
|
||||
deepEqual(Levels.createFromEditor(editor), {
|
||||
'beforeBookmark': null,
|
||||
'bookmark': null,
|
||||
'content': '',
|
||||
'fragments':[
|
||||
"<iframe src=\"about:blank\"></iframe>",
|
||||
" ",
|
||||
"",
|
||||
" ",
|
||||
"<span>b</span>"
|
||||
],
|
||||
'type': 'fragmented'
|
||||
});
|
||||
});
|
||||
|
||||
test('applyToEditor to equal content with complete level', function() {
|
||||
var level = Levels.createCompleteLevel('<p>a</p>');
|
||||
level.bookmark = {start: [1, 0, 0]};
|
||||
|
||||
editor.getBody().innerHTML = '<p>a</p>';
|
||||
Utils.setSelection('p', 0);
|
||||
Levels.applyToEditor(editor, level, false);
|
||||
|
||||
strictEqual(editor.getBody().innerHTML, '<p>a</p>');
|
||||
deepEqual(getBookmark(editor), {start: [1, 0, 0]});
|
||||
});
|
||||
|
||||
test('applyToEditor to different content with complete level', function() {
|
||||
var level = Levels.createCompleteLevel('<p>b</p>');
|
||||
level.bookmark = {start: [1, 0, 0]};
|
||||
|
||||
editor.getBody().innerHTML = '<p>a</p>';
|
||||
Utils.setSelection('p', 0);
|
||||
Levels.applyToEditor(editor, level, false);
|
||||
|
||||
strictEqual(editor.getBody().innerHTML, '<p>b</p>');
|
||||
deepEqual(getBookmark(editor), {start: [1, 0, 0]});
|
||||
});
|
||||
|
||||
test('applyToEditor to different content with fragmented level', function() {
|
||||
var level = Levels.createFragmentedLevel(['<p>a</p>', '<p>b</p>']);
|
||||
level.bookmark = {start: [1, 0, 0]};
|
||||
|
||||
editor.getBody().innerHTML = '<p>c</p>';
|
||||
Utils.setSelection('p', 0);
|
||||
Levels.applyToEditor(editor, level, false);
|
||||
|
||||
strictEqual(editor.getBody().innerHTML, '<p>a</p><p>b</p>');
|
||||
deepEqual(getBookmark(editor), {start: [1, 0, 0]});
|
||||
});
|
||||
|
||||
test('isEq', function() {
|
||||
strictEqual(Levels.isEq(Levels.createFragmentedLevel(['a', 'b']), Levels.createFragmentedLevel(['a', 'b'])), true);
|
||||
strictEqual(Levels.isEq(Levels.createFragmentedLevel(['a', 'b']), Levels.createFragmentedLevel(['a', 'c'])), false);
|
||||
strictEqual(Levels.isEq(Levels.createCompleteLevel('a'), Levels.createCompleteLevel('a')), true);
|
||||
strictEqual(Levels.isEq(Levels.createCompleteLevel('a'), Levels.createCompleteLevel('b')), false);
|
||||
strictEqual(Levels.isEq(Levels.createFragmentedLevel(['a']), Levels.createCompleteLevel('a')), true);
|
||||
strictEqual(Levels.isEq(Levels.createCompleteLevel('a'), Levels.createFragmentedLevel(['a'])), true);
|
||||
});
|
||||
});
|
||||
@ -5,20 +5,51 @@ module("tinymce.util.I18n", {
|
||||
});
|
||||
|
||||
test("Translate strings", function() {
|
||||
var undef;
|
||||
var translate = tinymce.util.I18n.translate;
|
||||
|
||||
tinymce.util.I18n.add("code", {
|
||||
"text": "text translation",
|
||||
"value:{0}{1}": "value translation:{0}{1}",
|
||||
"text{context:something}": "text translation with context",
|
||||
"value:{0}{1}{context:something}": "value translation:{0}{1} with context"
|
||||
"value:{0}{1}{context:something}": "value translation:{0}{1} with context",
|
||||
"empty string": ""
|
||||
});
|
||||
|
||||
equal(tinymce.util.I18n.translate("text"), "text translation");
|
||||
equal(tinymce.util.I18n.translate("untranslated text"), "untranslated text");
|
||||
equal(tinymce.util.I18n.translate(["untranslated value:{0}{1}", "a", "b"]), "untranslated value:ab");
|
||||
equal(tinymce.util.I18n.translate(["value:{0}{1}", "a", "b"]), "value translation:ab");
|
||||
equal(tinymce.util.I18n.translate("untranslated text{context:context}"), "untranslated text");
|
||||
equal(tinymce.util.I18n.translate(["untranslated value:{0}{1}{context:something}", "a", "b"]), "untranslated value:ab");
|
||||
equal(tinymce.util.I18n.translate(["value:{0}{1}{context:something}", "a", "b"]), "value translation:ab with context");
|
||||
equal(translate("text"), "text translation");
|
||||
equal(translate("untranslated text"), "untranslated text");
|
||||
equal(translate(["untranslated value:{0}{1}", "a", "b"]), "untranslated value:ab");
|
||||
equal(translate(["value:{0}{1}", "a", "b"]), "value translation:ab");
|
||||
equal(translate("untranslated text{context:context}"), "untranslated text");
|
||||
equal(translate(["untranslated value:{0}{1}{context:something}", "a", "b"]), "untranslated value:ab");
|
||||
equal(translate(["value:{0}{1}{context:something}", "a", "b"]), "value translation:ab with context");
|
||||
|
||||
// check if translate survives some awkward cases
|
||||
deepEqual(translate("empty string"), "");
|
||||
equal(translate(["untranslated value:{0}{1}", "a"]), "untranslated value:a{1}",
|
||||
"Do not strip tokens that weren't replaced.");
|
||||
|
||||
equal(translate([{}]), "[object Object]");
|
||||
equal(translate(function(){}), "[object Function]");
|
||||
|
||||
equal(translate(null), "");
|
||||
equal(translate(0), 0, "0");
|
||||
equal(translate(true), "true", "true");
|
||||
equal(translate(false), "false", "false");
|
||||
|
||||
equal(translate({}), "[object Object]", "[object Object]");
|
||||
equal(translate({raw:""}), "", "empty string");
|
||||
equal(translate({raw:false}), "false", "false");
|
||||
equal(translate({raw:undef}), "");
|
||||
equal(translate({raw:null}), "");
|
||||
|
||||
// https://github.com/tinymce/tinymce/issues/3029
|
||||
equal(translate("hasOwnProperty"), "hasOwnProperty");
|
||||
tinymce.util.I18n.add("code", {
|
||||
"hasOwnProperty": "good"
|
||||
});
|
||||
equal(translate("hasOwnProperty"), "good");
|
||||
|
||||
});
|
||||
|
||||
test("Switch language", function() {
|
||||
|
||||
@ -125,6 +125,17 @@ if (tinymce.isWebKit) {
|
||||
equal(editor.selection.getStart().nodeName, 'H1');
|
||||
});
|
||||
|
||||
test('Delete from after image to paragraph', function() {
|
||||
editor.getBody().innerHTML = '<p>a</p><p><img src="about:blank"></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStartAfter(editor.dom.select('img')[0]);
|
||||
rng.setEndAfter(editor.dom.select('img')[0]);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('Delete');
|
||||
equal(Utils.normalizeHtml(Utils.cleanHtml(editor.getBody().innerHTML)), '<p>a</p>');
|
||||
equal(editor.selection.getStart().nodeName, 'P');
|
||||
});
|
||||
|
||||
test('ForwardDelete from end of H1 to P with style span', function() {
|
||||
editor.getBody().innerHTML = '<h1>a</h1><p><span style="color:red">b</span></p>';
|
||||
Utils.setSelection('h1', 1);
|
||||
@ -334,6 +345,14 @@ if (tinymce.isWebKit) {
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p><br data-mce-bogus="1"></p>');
|
||||
equal(editor.selection.getStart(true).nodeName, 'P');
|
||||
});
|
||||
|
||||
test('Delete with similar sibling nodes', function() {
|
||||
editor.getBody().innerHTML = '<p>Test test</p><p>a</p><p>a</p><p id="t1">a</p><p>test1</p><p id="t2">test2</p>';
|
||||
Utils.setSelection('p#t1', 1, 'p#t2', 5);
|
||||
editor.fire('keydown', {keyCode: 8});
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p>test test</p><p>a</p><p>a</p><p id="t1">a</p>');
|
||||
equal(editor.selection.getStart(true).nodeName, 'P');
|
||||
});
|
||||
} else {
|
||||
test("Skipped since the browser isn't WebKit", function() {
|
||||
ok(true, "Skipped");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user