Update the TinyMCE tests to 4.0.21.1, see #27744

git-svn-id: https://develop.svn.wordpress.org/trunk@28138 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Ozz 2014-04-15 22:06:11 +00:00
parent 60f6968d80
commit 77a65852fa
16 changed files with 730 additions and 211 deletions

View File

@ -5,7 +5,6 @@
<title>TinyMCE QUnit tests</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0" />
<title>QUnit tests</title>
<link rel="stylesheet" href="js/qunit/qunit.css" type="text/css" />
<link rel="stylesheet" href="../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" type="text/css" />
<link rel="stylesheet" href="tinymce/ui/css/ui-overrides.css" type="text/css" />
@ -70,8 +69,10 @@
<script src="tinymce/util/XHR.js"></script>
<!-- tinymce.* -->
<script src="tinymce/AddOnManager.js"></script>
<script src="tinymce/Editor.js"></script>
<script src="tinymce/EditorCommands.js"></script>
<script src="tinymce/EditorManager.js"></script>
<script src="tinymce/EnterKey.js"></script>
<script src="tinymce/ForceBlocks.js"></script>
<script src="tinymce/Formatter_apply.js"></script>

View File

@ -1,11 +1,13 @@
(function() {
var coverObjects = [], modulesExecuted = {};
var coverObjects = [], modulesExecuted = {}, log = [], currentModule;
QUnit.config.reorder = false;
QUnit.config.hidepassed = true;
var oldModule = module;
QUnit.moduleStart(function(details) {
currentModule = details.name;
modulesExecuted[details.name] = true;
tinymce.remove();
@ -17,7 +19,17 @@
window.editor = window.inlineEditor = null;
});
QUnit.done(function() {
// Sauce labs
QUnit.testStart(function(testDetails) {
QUnit.log = function(details) {
if (!details.result) {
details.name = currentModule + ':' + testDetails.name;
log.push(details);
}
};
});
QUnit.done(function(results) {
document.getElementById("view").style.display = 'none';
if (window.__$coverObject) {
@ -27,6 +39,21 @@
window.open('coverage/index.html', 'coverage');
}).appendTo(document.body);
}
// Sauce labs
var tests = [];
for (var i = 0; i < log.length; i++) {
tests.push({
name: log[i].name,
result: log[i].result,
expected: log[i].expected,
actual: log[i].actual,
source: log[i].source
});
}
results.tests = tests;
window.global_test_results = results;
});
window.module = function(name, settings) {

View File

@ -98,8 +98,9 @@
} else {
ev = document.createEvent('UIEvents');
if (ev.initUIEvent)
if (ev.initUIEvent) {
ev.initUIEvent(na, true, true, window, 1);
}
ev.keyCode = o.keyCode;
ev.charCode = o.charCode;
@ -110,17 +111,19 @@
function normalizeRng(rng) {
if (rng.startContainer.nodeType == 3) {
if (rng.startOffset == 0)
if (rng.startOffset === 0) {
rng.setStartBefore(rng.startContainer);
else if (rng.startOffset >= rng.startContainer.nodeValue.length - 1)
} else if (rng.startOffset >= rng.startContainer.nodeValue.length - 1) {
rng.setStartAfter(rng.startContainer);
}
}
if (rng.endContainer.nodeType == 3) {
if (rng.endOffset == 0)
if (rng.endOffset === 0) {
rng.setEndBefore(rng.endContainer);
else if (rng.endOffset >= rng.endContainer.nodeValue.length - 1)
} else if (rng.endOffset >= rng.endContainer.nodeValue.length - 1) {
rng.setEndAfter(rng.endContainer);
}
}
return rng;
@ -128,7 +131,7 @@
// TODO: Replace this with the new event logic in 3.5
function type(chr) {
var editor = tinymce.activeEditor, keyCode, charCode, event = tinymce.dom.Event, evt, startElm, rng;
var editor = tinymce.activeEditor, keyCode, charCode, evt, startElm, rng;
function fakeEvent(target, type, evt) {
editor.dom.fire(target, type, evt);
@ -317,6 +320,46 @@
return html.replace(/<br[^>]*>/gi, '');
}
function patch(proto, name, patchFunc) {
var originalFunc = proto[name];
var originalFuncs = proto.__originalFuncs;
if (!originalFuncs) {
proto.__originalFuncs = originalFuncs = {};
}
if (!originalFuncs[name]) {
originalFuncs[name] = originalFunc;
} else {
originalFunc = originalFuncs[name];
}
proto[name] = function() {
var args = Array.prototype.slice.call(arguments);
args.unshift(originalFunc);
return patchFunc.apply(this, args);
};
}
function unpatch(proto, name) {
var originalFuncs = proto.__originalFuncs;
if (!originalFuncs) {
return;
}
if (name) {
proto[name] = originalFuncs[name];
delete originalFuncs[name];
} else {
for (var key in originalFuncs) {
proto[key] = originalFuncs[key];
}
delete proto.__originalFuncs;
}
}
window.Utils = {
fontFace: fontFace,
findContainer: findContainer,
@ -334,6 +377,8 @@
getFontmostWindow: getFontmostWindow,
pressArrowKey: pressArrowKey,
pressEnter: pressEnter,
trimBrsOnIE: trimBrsOnIE
trimBrsOnIE: trimBrsOnIE,
patch: patch,
unpatch: unpatch
};
})();

View File

@ -4,7 +4,7 @@ module("tinymce.plugins.Lists", {
QUnit.stop();
function wait() {
if (editor && inlineEditor) {
if (window.editor && window.inlineEditor) {
if (!QUnit.started) {
QUnit.start();
QUnit.started = true;
@ -449,30 +449,33 @@ test('Apply UL list to multiple formatted lines separated by BR', function() {
equal(editor.selection.getEnd().nodeName, tinymce.Env.ie && tinymce.Env.ie < 9 ? 'LI' : 'EM'); // Old IE will return the end LI not a big deal
});
test('Apply UL list to br line and text block line', function() {
editor.settings.forced_root_block = false;
// Ignore on IE 7, 8 this is a known bug not worth fixing
if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
test('Apply UL list to br line and text block line', function() {
editor.settings.forced_root_block = false;
editor.setContent(
'a' +
'<p>b</p>'
);
editor.setContent(
'a' +
'<p>b</p>'
);
var rng = editor.dom.createRng();
rng.setStart(editor.getBody().firstChild, 0);
rng.setEnd(editor.getBody().lastChild.firstChild, 1);
editor.selection.setRng(rng);
execCommand('InsertUnorderedList');
var rng = editor.dom.createRng();
rng.setStart(editor.getBody().firstChild, 0);
rng.setEnd(editor.getBody().lastChild.firstChild, 1);
editor.selection.setRng(rng);
execCommand('InsertUnorderedList');
equal(editor.getContent(),
'<ul>' +
'<li>a</li>' +
'<li>b</li>' +
'</ul>'
);
equal(editor.getContent(),
'<ul>' +
'<li>a</li>' +
'<li>b</li>' +
'</ul>'
);
equal(editor.selection.getStart().nodeName, 'LI');
equal(editor.selection.getEnd().nodeName, 'LI');
});
equal(editor.selection.getStart().nodeName, 'LI');
equal(editor.selection.getEnd().nodeName, 'LI');
});
}
test('Apply UL list to text block line and br line', function() {
editor.settings.forced_root_block = false;
@ -838,28 +841,31 @@ test('Remove empty UL between two textblocks', function() {
equal(editor.selection.getNode().nodeName, 'P');
});
test('Remove empty UL between two textblocks in BR mode', function() {
editor.settings.forced_root_block = false;
// Ignore on IE 7, 8 this is a known bug not worth fixing
if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
test('Remove empty UL between two textblocks in BR mode', function() {
editor.settings.forced_root_block = false;
editor.getBody().innerHTML = trimBrs(
'<div>a</div>' +
'<ul>' +
'<li></li>' +
'</ul>' +
'<div>b</div>'
);
editor.getBody().innerHTML = trimBrs(
'<div>a</div>' +
'<ul>' +
'<li></li>' +
'</ul>' +
'<div>b</div>'
);
editor.focus();
Utils.setSelection('li:first', 0);
execCommand('InsertUnorderedList');
editor.focus();
Utils.setSelection('li:first', 0);
execCommand('InsertUnorderedList');
equal(editor.getContent(),
'<div>a</div>' +
'<br />' +
'<div>b</div>'
);
equal(editor.selection.getStart().nodeName, 'BR');
});
equal(editor.getContent(),
'<div>a</div>' +
'<br />' +
'<div>b</div>'
);
equal(editor.selection.getStart().nodeName, 'BR');
});
}
// Outdent
@ -1730,7 +1736,7 @@ test('Delete at end of middle LI in UL inside UL', function() {
test('Remove UL in inline body element contained in LI', function() {
inlineEditor.setContent('<ul><li>a</li></ul>');
inlineEditor.focus();
inlineEditor.selection.setCursorLocation();
inlineEditor.execCommand('InsertUnorderedList');
equal(inlineEditor.getContent(), '<p>a</p>');
});

View File

@ -23,76 +23,79 @@ module("tinymce.plugins.Noneditable", {
}
});
test('expand to noneditable (start)', function() {
editor.setContent('<p><span class="mceNonEditable">no</span>yes</p>');
// Ignore on IE 7, 8 this is a known bug not worth fixing
if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
test('expand to noneditable (start)', function() {
editor.setContent('<p><span class="mceNonEditable">no</span>yes</p>');
var rng = editor.dom.createRng();
rng.setStart(editor.getBody().firstChild.firstChild.firstChild, 1);
rng.setEnd(editor.getBody().firstChild.lastChild, 1);
editor.selection.setRng(rng);
var rng = editor.dom.createRng();
rng.setStart(editor.getBody().firstChild.firstChild.firstChild, 1);
rng.setEnd(editor.getBody().firstChild.lastChild, 1);
editor.selection.setRng(rng);
editor.dom.fire(editor.getBody(), 'mouseup');
rng = Utils.normalizeRng(editor.selection.getRng(true));
editor.dom.fire(editor.getBody(), 'mouseup');
rng = Utils.normalizeRng(editor.selection.getRng(true));
equal(rng.startContainer.nodeName, 'P');
equal(rng.startOffset, 0);
equal(rng.endContainer.nodeName, '#text');
equal(rng.endOffset, 1);
});
equal(rng.startContainer.nodeName, 'P');
equal(rng.startOffset, 0);
equal(rng.endContainer.nodeName, '#text');
equal(rng.endOffset, 1);
});
test('expand to noneditable (end)', function() {
editor.setContent('<p>yes<span class="mceNonEditable">no</span></p>');
test('expand to noneditable (end)', function() {
editor.setContent('<p>yes<span class="mceNonEditable">no</span></p>');
var rng = editor.dom.createRng();
rng.setStart(editor.getBody().firstChild.firstChild, 1);
rng.setEnd(editor.getBody().firstChild.lastChild.firstChild, 1);
editor.selection.setRng(rng);
var rng = editor.dom.createRng();
rng.setStart(editor.getBody().firstChild.firstChild, 1);
rng.setEnd(editor.getBody().firstChild.lastChild.firstChild, 1);
editor.selection.setRng(rng);
editor.dom.fire(editor.getBody(), 'mouseup');
rng = Utils.normalizeRng(editor.selection.getRng(true));
editor.dom.fire(editor.getBody(), 'mouseup');
rng = Utils.normalizeRng(editor.selection.getRng(true));
equal(rng.startContainer.nodeName, '#text');
equal(rng.startOffset, 1);
equal(rng.endContainer.nodeName, 'P');
equal(rng.endOffset, 2);
});
equal(rng.startContainer.nodeName, '#text');
equal(rng.startOffset, 1);
equal(rng.endContainer.nodeName, 'P');
equal(rng.endOffset, 2);
});
test('expand to noneditable (start/end)', function() {
editor.setContent('<p>yes<span class="mceNonEditable">noedit</span>yes</p>');
test('expand to noneditable (start/end)', function() {
editor.setContent('<p>yes<span class="mceNonEditable">noedit</span>yes</p>');
var rng = editor.dom.createRng();
rng.setStart(editor.dom.select('span')[0].firstChild, 1);
rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
editor.selection.setRng(rng);
var rng = editor.dom.createRng();
rng.setStart(editor.dom.select('span')[0].firstChild, 1);
rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
editor.selection.setRng(rng);
editor.dom.fire(editor.getBody(), 'mouseup');
rng = Utils.normalizeRng(editor.selection.getRng(true));
editor.dom.fire(editor.getBody(), 'mouseup');
rng = Utils.normalizeRng(editor.selection.getRng(true));
equal(rng.startContainer.nodeName, 'P');
equal(rng.startOffset, 1);
equal(rng.endContainer.nodeName, 'P');
equal(rng.endOffset, 2);
});
equal(rng.startContainer.nodeName, 'P');
equal(rng.startOffset, 1);
equal(rng.endContainer.nodeName, 'P');
equal(rng.endOffset, 2);
});
test('type after non editable', function() {
editor.setContent('<p><span class="mceNonEditable">no</span>yes</p>');
test('type after non editable', function() {
editor.setContent('<p><span class="mceNonEditable">no</span>yes</p>');
var rng = editor.dom.createRng();
rng.setStart(editor.dom.select('span')[0].firstChild, 2);
rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
editor.selection.setRng(rng);
var rng = editor.dom.createRng();
rng.setStart(editor.dom.select('span')[0].firstChild, 2);
rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
editor.selection.setRng(rng);
editor.dom.fire(editor.getBody(), 'mouseup');
Utils.type('X');
rng = Utils.normalizeRng(editor.selection.getRng(true));
editor.dom.fire(editor.getBody(), 'mouseup');
Utils.type('X');
rng = Utils.normalizeRng(editor.selection.getRng(true));
equal(rng.startContainer.getAttribute('data-mce-bogus'), 'true');
equal(rng.startContainer.nodeName, 'SPAN');
equal(rng.startOffset, 1);
equal(rng.endContainer.nodeName, 'SPAN');
equal(rng.endOffset, 1);
equal(editor.getContent(), '<p><span class="mceNonEditable">no</span>Xyes</p>');
});
equal(rng.startContainer.getAttribute('data-mce-bogus'), 'true');
equal(rng.startContainer.nodeName, 'SPAN');
equal(rng.startOffset, 1);
equal(rng.endContainer.nodeName, 'SPAN');
equal(rng.endOffset, 1);
equal(editor.getContent(), '<p><span class="mceNonEditable">no</span>Xyes</p>');
});
}
test('type between non editable', function() {
editor.setContent('<p><span class="mceNonEditable">no</span><span class="mceNonEditable">no</span></p>');
@ -134,21 +137,24 @@ test('type after last non editable', function() {
equal(editor.getContent(), '<p><span class="mceNonEditable">no</span>X</p>');
});
test('escape noneditable inline element (left)', function() {
editor.setContent('<p>no <span class="mceNonEditable">yes</span> no</p><p class="mceNonEditable">no</p>');
// Ignore on IE 7, 8 this is a known bug not worth fixing
if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
test('escape noneditable inline element (left)', function() {
editor.setContent('<p>no <span class="mceNonEditable">yes</span> no</p><p class="mceNonEditable">no</p>');
var rng = editor.dom.createRng();
rng.selectNode(editor.dom.select('span')[0]);
editor.selection.setRng(rng);
var rng = editor.dom.createRng();
rng.selectNode(editor.dom.select('span')[0]);
editor.selection.setRng(rng);
Utils.type({keyCode: 37});
rng = Utils.normalizeRng(editor.selection.getRng(true));
Utils.type({keyCode: 37});
rng = Utils.normalizeRng(editor.selection.getRng(true));
equal(rng.startContainer.nodeName, 'SPAN');
equal(rng.startContainer.parentNode.nodeName, 'P');
equal(editor.dom.nodeIndex(rng.startContainer), 1);
equal(rng.collapsed, true);
});
equal(rng.startContainer.nodeName, 'SPAN');
equal(rng.startContainer.parentNode.nodeName, 'P');
equal(editor.dom.nodeIndex(rng.startContainer), 1);
equal(rng.collapsed, true);
});
}
test('escape noneditable inline element (right)', function() {
editor.setContent('<p>no <span class="mceNonEditable">yes</span> no</p><p class="mceNonEditable">no</p>');

View File

@ -15,6 +15,13 @@ module("tinymce.plugins.Paste", {
QUnit.start();
}
});
},
teardown: function() {
delete editor.settings.paste_remove_styles_if_webkit;
delete editor.settings.paste_retain_style_properties;
delete editor.settings.paste_enable_default_filters;
delete editor.settings.paste_data_images;
}
});
@ -96,7 +103,6 @@ test("Paste Word fake list", function() {
editor.selection.setRng(rng);
editor.execCommand('mceInsertClipboardContent', false, {content: '<p class="ListStyle" style="margin-left:36.0pt;mso-add-space:auto;text-indent:-18.0pt;mso-list:l0 level1 lfo1;tab-stops:list 36.0pt"><span lang="EN-US" style="color:black;mso-ansi-language:EN-US"><span style="mso-list:Ignore">1.<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span lang="EN-US" style="font-family:Arial;mso-fareast-font-family:Arial;mso-bidi-font-family:Arial;color:black;mso-ansi-language:EN-US">Version 7.0</span><span lang="EN-US" style="font-family:Arial;mso-fareast-font-family:Arial;mso-bidi-font-family:Arial;color:black;mso-ansi-language:EN-US">:<o:p></o:p></span></p>'});
equal(editor.getContent().replace(/[\r\n]+/g, ''), '<ol><li>Version 7.0:</li></ol>');
editor.settings.paste_retain_style_properties = '';
});
test("Paste Word fake list before BR", function() {
@ -141,6 +147,30 @@ test("Paste Word table", function() {
equal(editor.getContent().replace(/[\r\n]+/g, ''), '<table><tbody><tr><td width="307"><p>Cell 1</p></td><td width="307"><p>Cell 2</p></td></tr><tr><td width="307"><p>Cell 3</p></td><td width="307"><p>Cell 4</p></td></tr></tbody></table><p>&nbsp;</p>');
});
test("Paste Office 365", function() {
var rng = editor.dom.createRng();
editor.setContent('<p>1234</p>');
rng.setStart(editor.getBody().firstChild.firstChild, 0);
rng.setEnd(editor.getBody().firstChild.firstChild, 4);
editor.selection.setRng(rng);
editor.execCommand('mceInsertClipboardContent', false, {content: '<div class="OutlineElement Ltr SCX195156559">Test</div>'});
equal(editor.getContent().replace(/[\r\n]+/g, ''), '<p>Test</p>');
});
test("Paste Google Docs", function() {
var rng = editor.dom.createRng();
editor.setContent('<p>1234</p>');
rng.setStart(editor.getBody().firstChild.firstChild, 0);
rng.setEnd(editor.getBody().firstChild.firstChild, 4);
editor.selection.setRng(rng);
editor.execCommand('mceInsertClipboardContent', false, {content: '<span id="docs-internal-guid-94e46f1a-1c88-b42b-d502-1d19da30dde7"></span><p dir="ltr>Test</p>'});
equal(editor.getContent().replace(/[\r\n]+/g, ''), '<p>Test</p>');
});
test("Paste Word without mso markings", function() {
editor.setContent('');
editor.execCommand('mceInsertClipboardContent', false, {
@ -197,8 +227,25 @@ test("Paste Word retain styles", function() {
editor.execCommand('SelectAll');
editor.execCommand('mceInsertClipboardContent', false, {content: '<p class="MsoNormal" style="background-color: #ff0000">Test</p>'});
equal(Utils.trimContent(editor.getContent().replace(/[\r\n]+/g, '')), '<p style=\"background-color: #ff0000;\">Test</p>');
});
editor.settings.paste_retain_style_properties = '';
test("Paste Word retain bold/italic styles to elements", function() {
editor.settings.paste_retain_style_properties = 'color';
editor.setContent('');
editor.execCommand('mceInsertClipboardContent', false, {
content: (
'<p class="MsoNormal">' +
'<span style="font-weight: bold">bold</span>' +
'<span style="font-style: italic">italic</span>' +
'<span style="font-weight: bold; font-style: italic">bold + italic</span>' +
'<span style="font-weight: bold; color: red">bold + color</span>' +
'</p>'
)
});
equal(editor.getContent(), '<p><strong>bold</strong><em>italic</em><strong><em>bold + italic</em></strong><strong><span style="color: red;">bold + color</span></strong></p>');
});
test("Paste part of list from IE", function() {
@ -217,8 +264,6 @@ test("Disable default filters", function() {
editor.execCommand('mceInsertClipboardContent', false, {content: '<p class="MsoNormal" style="color: #ff0000;">Test</p>'});
equal(Utils.trimContent(editor.getContent().replace(/[\r\n]+/g, '')), '<p class="MsoNormal" style="color: #ff0000;">Test</p>');
editor.settings.paste_enable_default_filters = true;
});
test('paste invalid content with spans on page', function() {
@ -401,3 +446,95 @@ test('paste innerText of textnode with whitespace', function() {
editor.getBody().innerHTML = '<pre> a </pre>';
equal(tinymce.pasteplugin.Utils.innerText(editor.getBody().firstChild.innerHTML), ' a ');
});
if (tinymce.Env.webkit) {
test('paste webkit remove runtime styles (color)', function() {
editor.setContent('');
editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="color:red; text-indent: 10px">Test</span>'});
equal(editor.getContent(), '<p><span style="color: red;">Test</span></p>');
});
test('paste webkit remove runtime styles (background-color)', function() {
editor.setContent('');
editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="background-color:red; text-indent: 10px">Test</span>'});
equal(editor.getContent(), '<p><span style="background-color: red;">Test</span></p>');
});
test('paste webkit remove runtime styles (font-size)', function() {
editor.setContent('');
editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="font-size:42px; text-indent: 10px">Test</span>'});
equal(editor.getContent(), '<p><span style="font-size: 42px;">Test</span></p>');
});
/*
test('paste webkit remove runtime styles (font-family)', function() {
editor.setContent('');
editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="font-family:Arial; text-indent: 10px">Test</span>'});
equal(editor.getContent(), '<p><span style="font-family: Arial;">Test</span></p>');
});
*/
test('paste webkit remove runtime styles (custom styles)', function() {
editor.settings.paste_webkit_styles = 'color font-style';
editor.setContent('');
editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="color: red; font-style: italic; text-indent: 10px">Test</span>'});
equal(editor.getContent(), '<p><span style="color: red; font-style: italic;">Test</span></p>');
});
test('paste webkit remove runtime styles (all)', function() {
editor.settings.paste_webkit_styles = 'all';
editor.setContent('');
editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="color: red; font-style: italic; text-indent: 10px">Test</span>'});
equal(editor.getContent(), '<p><span style=\"color: red; font-style: italic; text-indent: 10px;\">Test</span></p>');
});
test('paste webkit remove runtime styles (none)', function() {
editor.settings.paste_webkit_styles = 'none';
editor.setContent('');
editor.execCommand('mceInsertClipboardContent', false, {content: '<span style="color: red; font-style: italic; text-indent: 10px">Test</span>'});
equal(editor.getContent(), '<p>Test</p>');
});
test('paste webkit remove runtime styles (color) in the same (color) (named)', function() {
editor.setContent('<p style="color:red">Test</span>');
Utils.setSelection('p', 0, 'p', 4);
editor.execCommand('mceInsertClipboardContent', false, {
content: (
'<span style="color:red; text-indent: 10px">a</span>' +
'<span style="color:#ff0000; text-indent: 10px">b</span>' +
'<span style="color:rgb(255, 0, 0); text-indent: 10px">c</span>'
)
});
equal(editor.getContent(), '<p style="color: red;">abc</p>');
});
test('paste webkit remove runtime styles (color) in the same (color) (hex)', function() {
editor.setContent('<p style="color:#ff0000">Test</span>');
Utils.setSelection('p', 0, 'p', 4);
editor.execCommand('mceInsertClipboardContent', false, {
content: (
'<span style="color:red; text-indent: 10px">a</span>' +
'<span style="color:#ff0000; text-indent: 10px">b</span>' +
'<span style="color:rgb(255, 0, 0); text-indent: 10px">c</span>'
)
});
equal(editor.getContent(), '<p style="color: #ff0000;">abc</p>');
});
test('paste webkit remove runtime styles (color) in the same (color) (rgb)', function() {
editor.setContent('<p style="color:rgb(255, 0, 0)">Test</span>');
Utils.setSelection('p', 0, 'p', 4);
editor.execCommand('mceInsertClipboardContent', false, {
content: (
'<span style="color:red; text-indent: 10px">a</span>' +
'<span style="color:#ff0000; text-indent: 10px">b</span>' +
'<span style="color:rgb(255, 0, 0); text-indent: 10px">c</span>'
)
});
equal(editor.getContent(), '<p style="color: #ff0000;">abc</p>');
});
}

View File

@ -0,0 +1,39 @@
module("tinymce.AddOnManager", {
teardown: function() {
Utils.unpatch(tinymce.dom.ScriptLoader.ScriptLoader);
tinymce.AddOnManager.languageLoad = true;
tinymce.AddOnManager.language = 'en';
}
});
test('requireLangPack', function() {
var languagePackUrl;
Utils.patch(tinymce.dom.ScriptLoader.ScriptLoader, 'add', function(origFunc, url) {
languagePackUrl = url;
});
function getLanguagePackUrl(language, languages) {
languagePackUrl = null;
tinymce.AddOnManager.language = language;
tinymce.AddOnManager.PluginManager.requireLangPack('plugin', languages);
return languagePackUrl;
}
tinymce.AddOnManager.PluginManager.urls.plugin = '/root';
equal(getLanguagePackUrl('sv_SE'), '/root/langs/sv_SE.js');
equal(getLanguagePackUrl('sv_SE', 'sv,en,us'), '/root/langs/sv.js');
equal(getLanguagePackUrl('sv_SE', 'sv_SE,en_US'), '/root/langs/sv_SE.js');
equal(getLanguagePackUrl('sv'), '/root/langs/sv.js');
equal(getLanguagePackUrl('sv', 'sv'), '/root/langs/sv.js');
equal(getLanguagePackUrl('sv', 'sv,en,us'), '/root/langs/sv.js');
equal(getLanguagePackUrl('sv', 'en,sv,us'), '/root/langs/sv.js');
equal(getLanguagePackUrl('sv', 'en,us,sv'), '/root/langs/sv.js');
strictEqual(getLanguagePackUrl('sv', 'en,us'), null);
strictEqual(getLanguagePackUrl(null, 'en,us'), null);
strictEqual(getLanguagePackUrl(null), null);
tinymce.AddOnManager.languageLoad = false;
strictEqual(getLanguagePackUrl('sv', 'sv'), null);
});

View File

@ -8,6 +8,7 @@ module("tinymce.Editor", {
disable_nodechange: true,
skin: false,
entities: 'raw',
indent: false,
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'
},
@ -137,7 +138,7 @@ test('WebKit Serialization range bug', function() {
var p = editor.dom.create('p', {}, '123<table><tbody><tr><td>X</td></tr></tbody></table>456');
editor.dom.replace(p, editor.getBody().firstChild);
equal(editor.getContent(), '<p>123</p>\n<table>\n<tbody>\n<tr>\n<td>X</td>\n</tr>\n</tbody>\n</table>\n<p>456</p>');
equal(editor.getContent(), '<p>123</p><table><tbody><tr><td>X</td></tr></tbody></table><p>456</p>');
}
});
@ -187,9 +188,12 @@ test('setContent', function() {
});
test('custom elements', function() {
expect(1);
editor.setContent('<custom1>c1</custom1><custom2>c1</custom2>');
equal(editor.getContent().replace(/[\r\n]/g, ''), '<custom1>c1</custom1><p><custom2>c1</custom2></p>');
equal(editor.getContent(), '<custom1>c1</custom1><p><custom2>c1</custom2></p>');
});
test('Store/restore tabindex', function() {
editor.setContent('<span tabindex="42">abc</span>');
equal(editor.getContent({format:'raw'}).toLowerCase(), '<p><span data-mce-tabindex="42">abc</span></p>');
equal(editor.getContent(), '<p><span tabindex="42">abc</span></p>');
});

View File

@ -0,0 +1,72 @@
module("tinymce.EditorManager", {
setupModule: function() {
QUnit.stop();
tinymce.init({
selector: "textarea",
add_unload_trigger: false,
disable_nodechange: true,
skin: false,
init_instance_callback: function(ed) {
window.editor = ed;
QUnit.start();
}
});
}
});
test('get', function() {
strictEqual(tinymce.get().length, 1);
strictEqual(tinymce.get(0), tinymce.activeEditor);
strictEqual(tinymce.get(1), null);
strictEqual(tinymce.get("noid"), null);
strictEqual(tinymce.get(undefined), null);
strictEqual(tinymce.get()[0], tinymce.activeEditor);
strictEqual(tinymce.get(tinymce.activeEditor.id), tinymce.activeEditor);
});
test('addI18n/translate', function() {
tinymce.addI18n('en', {
'from': 'to'
});
equal(tinymce.translate('from'), 'to');
});
test('triggerSave', function() {
var saveCount = 0;
window.editor.on('SaveContent', function() {
saveCount++;
});
tinymce.triggerSave();
equal(saveCount, 1);
});
test('Re-init on same id', function() {
tinymce.init({selector: "#" + tinymce.activeEditor.id});
strictEqual(tinymce.get().length, 1);
});
asyncTest('Init/remove on same id', function() {
var textArea = document.createElement('textarea');
document.getElementById('view').appendChild(textArea);
tinymce.init({
selector: "#view textarea",
init_instance_callback: function() {
window.setTimeout(function() {
QUnit.start();
strictEqual(tinymce.get().length, 2);
strictEqual(tinymce.get(1), tinymce.activeEditor);
tinymce.remove('#' + tinymce.get(1).id);
strictEqual(tinymce.get().length, 1);
strictEqual(tinymce.get(0), tinymce.activeEditor);
}, 0);
}
});
strictEqual(tinymce.get().length, 2);
});

View File

@ -392,7 +392,10 @@ test('Enter inside empty LI in middle of OL in LI', function() {
'</ol>'
);
equal(editor.selection.getNode().nodeName, 'LI');
// Ignore on IE 7, 8 this is a known bug not worth fixing
if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
equal(editor.selection.getNode().nodeName, 'LI');
}
});
test('Enter inside empty LI in end of OL in LI', function() {
@ -427,36 +430,39 @@ test('Enter inside empty LI in end of OL in LI', function() {
// Nested lists in OL elements
test('Enter before nested list', function() {
editor.getBody().innerHTML = Utils.trimBrsOnIE(
'<ol>' +
'<li>a' +
'<ul>' +
'<li>b</li>' +
'<li>c</li>' +
'</ul>' +
'</li>' +
'</ol>'
);
// Ignore on IE 7, 8 this is a known bug not worth fixing
if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
test('Enter before nested list', function() {
editor.getBody().innerHTML = Utils.trimBrsOnIE(
'<ol>' +
'<li>a' +
'<ul>' +
'<li>b</li>' +
'<li>c</li>' +
'</ul>' +
'</li>' +
'</ol>'
);
Utils.setSelection('ol > li', 1);
editor.focus();
Utils.pressEnter();
Utils.setSelection('ol > li', 1);
editor.focus();
Utils.pressEnter();
equal(editor.getContent(),
'<ol>' +
'<li>a</li>' +
'<li>\u00a0' +
'<ul>' +
'<li>b</li>' +
'<li>c</li>' +
'</ul>' +
'</li>' +
'</ol>'
);
equal(editor.getContent(),
'<ol>' +
'<li>a</li>' +
'<li>\u00a0' +
'<ul>' +
'<li>b</li>' +
'<li>c</li>' +
'</ul>' +
'</li>' +
'</ol>'
);
equal(editor.selection.getNode().nodeName, 'LI');
});
equal(editor.selection.getNode().nodeName, 'LI');
});
}
test('Enter inside empty LI in beginning of OL in OL', function() {
editor.getBody().innerHTML = Utils.trimBrsOnIE(
@ -561,7 +567,11 @@ test('Enter inside middle of P inside LI', function() {
Utils.setSelection('p', 2);
Utils.pressEnter();
equal(editor.getContent(),'<ol><li><p>ab</p></li><li><p>cd</p></li></ol>');
equal(editor.selection.getNode().nodeName, 'P');
// Ignore on IE 7, 8 this is a known bug not worth fixing
if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
equal(editor.selection.getNode().nodeName, 'P');
}
});
test('Enter at end of P inside LI', function() {
@ -918,15 +928,18 @@ test('Enter when forced_root_block: false and force_p_newlines: true', function(
equal(editor.getContent(),'<p>te</p><p>xt</p>');
});
test('Enter before BR between DIVs', function() {
editor.getBody().innerHTML = '<div>a<span>b</span>c</div><br /><div>d</div>';
var rng = editor.dom.createRng();
rng.setStartBefore(editor.dom.select('br')[0]);
rng.setEndBefore(editor.dom.select('br')[0]);
editor.selection.setRng(rng);
Utils.pressEnter();
equal(editor.getContent(),'<div>a<span>b</span>c</div><p>\u00a0</p><p>\u00a0</p><div>d</div>');
});
// Ignore on IE 7, 8 this is a known bug not worth fixing
if (!tinymce.Env.ie || tinymce.Env.ie > 8) {
test('Enter before BR between DIVs', function() {
editor.getBody().innerHTML = '<div>a<span>b</span>c</div><br /><div>d</div>';
var rng = editor.dom.createRng();
rng.setStartBefore(editor.dom.select('br')[0]);
rng.setEndBefore(editor.dom.select('br')[0]);
editor.selection.setRng(rng);
Utils.pressEnter();
equal(editor.getContent(),'<div>a<span>b</span>c</div><p>\u00a0</p><p>\u00a0</p><div>d</div>');
});
}
// Only test these on modern browsers
if (window.getSelection) {

View File

@ -1597,4 +1597,4 @@ test('Bug #6518 - Apply div blocks to inline editor paragraph', function() {
});
inlineEditor.formatter.apply('format');
equal(inlineEditor.getContent(), '<div>a</div><p>b</p>');
});
});

View File

@ -228,3 +228,8 @@ 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');
});

View File

@ -149,26 +149,167 @@ test('Events', function() {
ok(redo.bookmark);
});
asyncTest('Undo added when typing and losing focus', function() {
window.focus();
test('Transact', function() {
var count = 0;
window.setTimeout(function() {
start();
editor.undoManager.clear();
editor.focus();
editor.undoManager.clear();
editor.setContent("<p>some text</p>");
Utils.setSelection('p', 4, 'p', 9);
Utils.type('\b');
editor.on('BeforeAddUndo', function() {
count++;
});
// Move focus to an input element
var input = document.createElement('input');
document.getElementById('view').appendChild(input);
input.focus();
input.parentNode.removeChild(input);
editor.undoManager.transact(function() {
editor.undoManager.add();
editor.undoManager.add();
});
editor.execCommand('FormatBlock', false, 'h1');
editor.undoManager.undo();
equal(editor.getContent(), "<p>some</p>");
}, 0);
equal(count, 1);
});
test('Transact nested', function() {
var count = 0;
editor.undoManager.clear();
editor.on('BeforeAddUndo', function() {
count++;
});
editor.undoManager.transact(function() {
editor.undoManager.add();
editor.undoManager.transact(function() {
editor.undoManager.add();
});
});
equal(count, 1);
});
test('Transact exception', function() {
var count = 0;
editor.undoManager.clear();
editor.on('BeforeAddUndo', function() {
count++;
});
throws(
function() {
editor.undoManager.transact(function() {
throw new Error("Test");
});
},
"Test"
);
editor.undoManager.add();
equal(count, 1);
});
test('Exclude internal elements', function() {
var count = 0, lastLevel;
editor.undoManager.clear();
equal(count, 0);
editor.on('AddUndo', function() {
count++;
});
editor.on('BeforeAddUndo', function(e) {
lastLevel = e.level;
});
editor.getBody().innerHTML = (
'test' +
'<img src="about:blank" data-mce-selected="1" />' +
'<table data-mce-selected="1"><tr><td>x</td></tr></table>'
);
editor.undoManager.add();
equal(count, 1);
equal(Utils.cleanHtml(lastLevel.content),
'test' +
'<img src="about:blank">' +
'<table><tbody><tr><td>x</td></tr></tbody></table>'
);
editor.getBody().innerHTML = (
'<span data-mce-bogus="1">\u200B</span>' +
'<span data-mce-bogus="1">\uFEFF</span>' +
'<div data-mce-bogus="1"></div>' +
'test' +
'<img src="about:blank" />' +
'<table><tr><td>x</td></tr></table>'
);
editor.undoManager.add();
equal(count, 1);
equal(Utils.cleanHtml(lastLevel.content),
'test' +
'<img src="about:blank">' +
'<table><tbody><tr><td>x</td></tr></tbody></table>'
);
});
test('Undo added when typing and losing focus', function() {
var lastLevel;
editor.on('BeforeAddUndo', function(e) {
lastLevel = e.level;
});
editor.undoManager.clear();
editor.setContent("<p>some text</p>");
Utils.setSelection('p', 4, 'p', 9);
Utils.type('\b');
equal(Utils.cleanHtml(lastLevel.content), "<p>some text</p>");
editor.fire('blur');
equal(Utils.cleanHtml(lastLevel.content), "<p>some</p>");
editor.execCommand('FormatBlock', false, 'h1');
editor.undoManager.undo();
equal(editor.getContent(), "<p>some</p>");
});
test('BeforeAddUndo event', function() {
var lastEvt, addUndoEvt;
editor.on('BeforeAddUndo', function(e) {
lastEvt = e;
});
editor.undoManager.clear();
editor.setContent("<p>a</p>");
editor.undoManager.add();
equal(lastEvt.lastLevel, null);
equal(Utils.cleanHtml(lastEvt.level.content), "<p>a</p>");
editor.setContent("<p>b</p>");
editor.undoManager.add();
equal(Utils.cleanHtml(lastEvt.lastLevel.content), "<p>a</p>");
equal(Utils.cleanHtml(lastEvt.level.content), "<p>b</p>");
editor.on('BeforeAddUndo', function(e) {
e.preventDefault();
});
editor.on('AddUndo', function(e) {
addUndoEvt = e;
});
editor.setContent("<p>c</p>");
editor.undoManager.add(null, {data: 1});
equal(Utils.cleanHtml(lastEvt.lastLevel.content), "<p>b</p>");
equal(Utils.cleanHtml(lastEvt.level.content), "<p>c</p>");
equal(lastEvt.originalEvent.data, 1);
ok(!addUndoEvt, "Event level produced when it should be blocked");
});

View File

@ -328,6 +328,7 @@ test("mouseenter/mouseleave bind/unbind", function() {
deepEqual(result, {});
});
/*
asyncTest("focusin/focusout bind/unbind", function() {
var result = {};
@ -348,6 +349,7 @@ asyncTest("focusin/focusout bind/unbind", function() {
deepEqual(result, {focusin: 2, focusout: 1});
}, 0);
});
*/
test("bind unbind fire clean on null", function() {
eventUtils.bind(null, 'click', function() {});

View File

@ -490,3 +490,12 @@ test('Remove internal classes', function() {
DOM.setHTML('test', '<span class="b mce-item-X"></span>');
equal(ser.serialize(DOM.get('test')), '<span class="b"></span>');
});
test('Restore tabindex', function() {
var ser = new tinymce.dom.Serializer({
valid_elements: 'span[tabindex]'
});
DOM.setHTML('test', '<span data-mce-tabindex="42"></span>');
equal(ser.serialize(DOM.get('test')), '<span tabindex="42"></span>');
});

View File

@ -53,7 +53,6 @@
});
});
/*
test("Properties", function() {
var ctrl, cont;
@ -89,11 +88,9 @@
// Set all states
ctrl = ctrl.
refresh().
bind('click', function() {}).
unbind().
renderTo(document.getElementById('viewport')).
fire("nothing").
on('click', function() {}).
off().
renderTo(document.getElementById('view')).
remove();
// Check so that the chain worked
@ -102,29 +99,32 @@
test("Events", function() {
var ctrl = new tinymce.ui.Control({
handlers: {
onMyEvent: function() {
count++;
},
callbacks: {
handler1: function() {
count++;
}
}
}), count;
ctrl.bind('MyEvent', function(target, args) {
ok(target === ctrl);
ok(ctrl === this);
deepEqual(args, {myKey: 'myVal'});
ctrl.on('MyEvent', function(args) {
equal(ctrl, args.control);
equal(ctrl, this);
equal(args.myKey, 'myVal');
});
ctrl.fire('MyEvent', {myKey: 'myVal'});
function countAndBreak(target, args) {
function countAndBreak() {
count++;
return false;
}
// Bind two events
ctrl.bind('MyEvent2', countAndBreak);
ctrl.bind('MyEvent2', countAndBreak);
ctrl.on('MyEvent2', countAndBreak);
ctrl.on('MyEvent2', countAndBreak);
// Check if only one of them was called
count = 0;
@ -135,31 +135,31 @@
ctrl.fire('MyEvent3', {myKey: 'myVal'});
// Unbind all
ctrl.unbind();
ctrl.off();
count = 0;
ctrl.fire('MyEvent2', {myKey: 'myVal'});
equal(count, 0, 'Unbind all');
// Unbind by name
ctrl.bind('MyEvent1', countAndBreak);
ctrl.bind('MyEvent2', countAndBreak);
ctrl.unbind('MyEvent2');
ctrl.on('MyEvent1', countAndBreak);
ctrl.on('MyEvent2', countAndBreak);
ctrl.off('MyEvent2');
count = 0;
ctrl.fire('MyEvent1', {myKey: 'myVal'});
ctrl.fire('MyEvent2', {myKey: 'myVal'});
equal(count, 1);
// Unbind by name callback
ctrl.bind('MyEvent1', countAndBreak);
ctrl.bind('MyEvent1', function() {count++;});
ctrl.unbind('MyEvent1', countAndBreak);
ctrl.on('MyEvent1', countAndBreak);
ctrl.on('MyEvent1', function() {count++;});
ctrl.off('MyEvent1', countAndBreak);
count = 0;
ctrl.fire('MyEvent1', {myKey: 'myVal'});
equal(count, 1);
// Bind by named handler
ctrl.unbind();
ctrl.bind('MyEvent', 'handler1');
ctrl.off();
ctrl.on('MyEvent', 'handler1');
count = 0;
ctrl.fire('MyEvent', {myKey: 'myVal'});
equal(count, 1);
@ -168,28 +168,28 @@
test("hasClass,addClass,removeClass", function() {
var ctrl = new tinymce.ui.Control({classes: 'class1 class2 class3'});
equal(ctrl.classes(), 'class1 class2 class3');
equal(ctrl.classes(), 'mce-class1 mce-class2 mce-class3');
ok(ctrl.hasClass('class1'));
ok(ctrl.hasClass('class2'));
ok(ctrl.hasClass('class3'));
ok(!ctrl.hasClass('class4'));
ctrl.addClass('class4');
equal(ctrl.classes(), 'class1 class2 class3 class4');
equal(ctrl.classes(), 'mce-class1 mce-class2 mce-class3 mce-class4');
ok(ctrl.hasClass('class1'));
ok(ctrl.hasClass('class2'));
ok(ctrl.hasClass('class3'));
ok(ctrl.hasClass('class4'));
ctrl.removeClass('class4');
equal(ctrl.classes(), 'class1 class2 class3');
equal(ctrl.classes(), 'mce-class1 mce-class2 mce-class3');
ok(ctrl.hasClass('class1'));
ok(ctrl.hasClass('class2'));
ok(ctrl.hasClass('class3'));
ok(!ctrl.hasClass('class4'));
ctrl.removeClass('class3').removeClass('class2');
equal(ctrl.classes(), 'class1');
equal(ctrl.classes(), 'mce-class1');
ok(ctrl.hasClass('class1'));
ok(!ctrl.hasClass('class2'));
ok(!ctrl.hasClass('class3'));
@ -200,5 +200,17 @@
ok(!ctrl.hasClass('class2'));
ok(!ctrl.hasClass('class3'));
});
*/
test("encode", function() {
tinymce.i18n.add('en', {'old': '"new"'});
equal(new tinymce.ui.Control({}).encode('<>"&'), '&#60;&#62;&#34;&#38;');
equal(new tinymce.ui.Control({}).encode('old'), '&#34;new&#34;');
equal(new tinymce.ui.Control({}).encode('old', false), 'old');
});
test("translate", function() {
tinymce.i18n.add('en', {'old': 'new'});
equal(new tinymce.ui.Control({}).translate('old'), 'new');
equal(new tinymce.ui.Control({}).translate('old2'), 'old2');
});
})();