mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2025-10-16 12:05:38 +00:00
TinyMCE: remove the pre-4.6.0 tests. Move regression testing for obsolete tags and attributes to the default QUnit tests.
See #40690. git-svn-id: https://develop.svn.wordpress.org/trunk@40584 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
f4d3513802
commit
1727d6fbef
@ -1,101 +0,0 @@
|
||||
/**
|
||||
* plugin.js
|
||||
*
|
||||
* Released under LGPL License.
|
||||
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
||||
*
|
||||
* License: http://www.tinymce.com/license
|
||||
* Contributing: http://www.tinymce.com/contributing
|
||||
*/
|
||||
|
||||
/*global tinymce:true */
|
||||
|
||||
tinymce.PluginManager.add('noneditable', function(editor) {
|
||||
var editClass, nonEditClass, nonEditableRegExps, contentEditableAttrName = 'contenteditable';
|
||||
|
||||
function hasClass(checkClassName) {
|
||||
return function(node) {
|
||||
return (" " + node.attr("class") + " ").indexOf(checkClassName) !== -1;
|
||||
};
|
||||
}
|
||||
|
||||
function convertRegExpsToNonEditable(e) {
|
||||
var i = nonEditableRegExps.length, content = e.content, cls = tinymce.trim(nonEditClass);
|
||||
|
||||
function replaceMatchWithSpan(match) {
|
||||
var args = arguments, index = args[args.length - 2];
|
||||
|
||||
// Is value inside an attribute then don't replace
|
||||
if (index > 0 && content.charAt(index - 1) == '"') {
|
||||
return match;
|
||||
}
|
||||
|
||||
return (
|
||||
'<span class="' + cls + '" data-mce-content="' + editor.dom.encode(args[0]) + '">' +
|
||||
editor.dom.encode(typeof args[1] === "string" ? args[1] : args[0]) + '</span>'
|
||||
);
|
||||
}
|
||||
|
||||
// Don't replace the variables when raw is used for example on undo/redo
|
||||
if (e.format == "raw") {
|
||||
return;
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
content = content.replace(nonEditableRegExps[i], replaceMatchWithSpan);
|
||||
}
|
||||
|
||||
e.content = content;
|
||||
}
|
||||
|
||||
editClass = " " + tinymce.trim(editor.getParam("noneditable_editable_class", "mceEditable")) + " ";
|
||||
nonEditClass = " " + tinymce.trim(editor.getParam("noneditable_noneditable_class", "mceNonEditable")) + " ";
|
||||
|
||||
var hasEditClass = hasClass(editClass);
|
||||
var hasNonEditClass = hasClass(nonEditClass);
|
||||
|
||||
nonEditableRegExps = editor.getParam("noneditable_regexp");
|
||||
if (nonEditableRegExps && !nonEditableRegExps.length) {
|
||||
nonEditableRegExps = [nonEditableRegExps];
|
||||
}
|
||||
|
||||
editor.on('PreInit', function() {
|
||||
if (nonEditableRegExps) {
|
||||
editor.on('BeforeSetContent', convertRegExpsToNonEditable);
|
||||
}
|
||||
|
||||
editor.parser.addAttributeFilter('class', function(nodes) {
|
||||
var i = nodes.length, node;
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
|
||||
if (hasEditClass(node)) {
|
||||
node.attr(contentEditableAttrName, "true");
|
||||
} else if (hasNonEditClass(node)) {
|
||||
node.attr(contentEditableAttrName, "false");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
editor.serializer.addAttributeFilter(contentEditableAttrName, function(nodes) {
|
||||
var i = nodes.length, node;
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
if (!hasEditClass(node) && !hasNonEditClass(node)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nonEditableRegExps && node.attr('data-mce-content')) {
|
||||
node.name = "#text";
|
||||
node.type = 3;
|
||||
node.raw = true;
|
||||
node.value = node.attr('data-mce-content');
|
||||
} else {
|
||||
node.attr(contentEditableAttrName, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1 +0,0 @@
|
||||
tinymce.PluginManager.add("noneditable",function(a){function b(a){return function(b){return-1!==(" "+b.attr("class")+" ").indexOf(a)}}function c(b){function c(b){var c=arguments,d=c[c.length-2];return d>0&&'"'==g.charAt(d-1)?b:'<span class="'+h+'" data-mce-content="'+a.dom.encode(c[0])+'">'+a.dom.encode("string"==typeof c[1]?c[1]:c[0])+"</span>"}var d=f.length,g=b.content,h=tinymce.trim(e);if("raw"!=b.format){for(;d--;)g=g.replace(f[d],c);b.content=g}}var d,e,f,g="contenteditable";d=" "+tinymce.trim(a.getParam("noneditable_editable_class","mceEditable"))+" ",e=" "+tinymce.trim(a.getParam("noneditable_noneditable_class","mceNonEditable"))+" ";var h=b(d),i=b(e);f=a.getParam("noneditable_regexp"),f&&!f.length&&(f=[f]),a.on("PreInit",function(){f&&a.on("BeforeSetContent",c),a.parser.addAttributeFilter("class",function(a){for(var b,c=a.length;c--;)b=a[c],h(b)?b.attr(g,"true"):i(b)&&b.attr(g,"false")}),a.serializer.addAttributeFilter(g,function(a){for(var b,c=a.length;c--;)b=a[c],(h(b)||i(b))&&(f&&b.attr("data-mce-content")?(b.name="#text",b.type=3,b.raw=!0,b.value=b.attr("data-mce-content")):b.attr(g,null))})})});
|
||||
@ -1,155 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<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" />
|
||||
<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" />
|
||||
<style>
|
||||
#qunit-modulefilter-container { float: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture"></div>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
|
||||
<script src="../../../src/wp-includes/js/jquery/jquery.js"></script>
|
||||
<script src="js/module_loader.js"></script>
|
||||
<script src="js/qunit/qunit.js"></script>
|
||||
<script src="js/tinymce_loader.js"></script>
|
||||
<!--<script src="../js/tinymce/classes/jquery.tinymce.js"></script> -->
|
||||
<script src="../../../src/wp-includes/js/tinymce/plugins/paste/plugin.js"></script>
|
||||
<script src="js/utils.js"></script>
|
||||
<script src="js/init.js"></script>
|
||||
|
||||
<!-- tinymce.data.* -->
|
||||
<script src="tinymce/data/ObservableObject.js"></script>
|
||||
|
||||
<!-- tinymce.caret.* -->
|
||||
<script src="tinymce/caret/CaretBookmark.js"></script>
|
||||
<script src="tinymce/caret/CaretCandidate.js"></script>
|
||||
<script src="tinymce/caret/CaretContainer.js"></script>
|
||||
<script src="tinymce/caret/CaretPosition.js"></script>
|
||||
<script src="tinymce/caret/CaretUtils.js"></script>
|
||||
<script src="tinymce/caret/CaretWalker.js"></script>
|
||||
<script src="tinymce/caret/FakeCaret.js"></script>
|
||||
<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>
|
||||
|
||||
<!-- tinymce.file.* -->
|
||||
<script src="tinymce/file/Conversions.js"></script>
|
||||
<script src="tinymce/file/ImageScanner.js"></script>
|
||||
<script src="tinymce/file/UploadStatus.js"></script>
|
||||
|
||||
<!-- 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>
|
||||
<script src="tinymce/text/Zwsp.js"></script>
|
||||
|
||||
<!-- tinymce.dom.* -->
|
||||
<script src="tinymce/dom/NodeType.js"></script>
|
||||
<script src="tinymce/dom/DomQuery.js"></script>
|
||||
<script src="tinymce/dom/DOMUtils.js"></script>
|
||||
<script src="tinymce/dom/Dimensions.js"></script>
|
||||
<script src="tinymce/dom/EventUtils.js"></script>
|
||||
<script src="tinymce/dom/Range.js"></script>
|
||||
<script src="tinymce/dom/Selection.js"></script>
|
||||
<script src="tinymce/dom/Serializer.js"></script>
|
||||
<script src="tinymce/dom/TridentSelection.js"></script>
|
||||
<script src="tinymce/dom/NodePath.js"></script>
|
||||
<script src="tinymce/dom/TreeWalker.js"></script>
|
||||
|
||||
<!-- tinymce.html.* -->
|
||||
<script src="tinymce/html/DomParser.js"></script>
|
||||
<script src="tinymce/html/Entities.js"></script>
|
||||
<script src="tinymce/html/Node.js"></script>
|
||||
<script src="tinymce/html/SaxParser.js"></script>
|
||||
<script src="tinymce/html/Schema.js"></script>
|
||||
<script src="tinymce/html/Obsolete.js"></script>
|
||||
<script src="tinymce/html/Styles.js"></script>
|
||||
<script src="tinymce/html/Writer.js"></script>
|
||||
<script src="tinymce/html/Serializer.js"></script>
|
||||
|
||||
<!-- tnymce.ui.* -->
|
||||
<script src="tinymce/ui/AbsoluteLayout.js"></script>
|
||||
<script src="tinymce/ui/Button.js"></script>
|
||||
<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>
|
||||
<script src="tinymce/ui/MenuButton.js"></script>
|
||||
<script src="tinymce/ui/Panel.js"></script>
|
||||
<script src="tinymce/ui/Selector.js"></script>
|
||||
<script src="tinymce/ui/SplitButton.js"></script>
|
||||
<script src="tinymce/ui/TabPanel.js"></script>
|
||||
<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>
|
||||
<script src="tinymce/util/JSON.js"></script>
|
||||
<script src="tinymce/util/JSONRequest.js"></script>
|
||||
<script src="tinymce/util/LocalStorage.js"></script>
|
||||
<script src="tinymce/util/Observable.js"></script>
|
||||
<script src="tinymce/util/Quirks_webkit.js"></script>
|
||||
<script src="tinymce/util/URI.js"></script>
|
||||
<script src="tinymce/util/XHR.js"></script>
|
||||
<script src="tinymce/util/I18n.js"></script>
|
||||
<script src="tinymce/util/Fun.js"></script>
|
||||
<script src="tinymce/util/Delay.js"></script>
|
||||
<script src="tinymce/util/Promise.js"></script>
|
||||
<script src="tinymce/util/Tools.js"></script>
|
||||
|
||||
<!-- 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>
|
||||
<script src="tinymce/Formatter_remove.js"></script>
|
||||
<script src="tinymce/Shortcuts.js"></script>
|
||||
<script src="tinymce/UndoManager.js"></script>
|
||||
<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.* -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,122 +0,0 @@
|
||||
(function() {
|
||||
var coverObjects = [], modulesExecuted = {}, log = [], currentModule;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.hidepassed = true;
|
||||
|
||||
window.editor = window.inlineEditor = null;
|
||||
|
||||
var oldModule = module;
|
||||
|
||||
QUnit.moduleStart(function(details) {
|
||||
currentModule = details.name;
|
||||
modulesExecuted[details.name] = true;
|
||||
|
||||
tinymce.remove();
|
||||
document.getElementById('view').innerHTML = '<textarea></textarea>';
|
||||
});
|
||||
|
||||
QUnit.moduleDone(function() {
|
||||
tinymce.remove();
|
||||
window.editor = window.inlineEditor = null;
|
||||
});
|
||||
|
||||
// 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) {
|
||||
coverObjects.push(window.__$coverObject);
|
||||
|
||||
$('<button>Coverage report</button>').on('click', function() {
|
||||
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) {
|
||||
settings = settings || {};
|
||||
|
||||
if (settings.setupModule) {
|
||||
QUnit.moduleStart(function(details) {
|
||||
if (details.name == name) {
|
||||
settings.setupModule();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (settings.teardownModule) {
|
||||
QUnit.moduleDone(function(details) {
|
||||
if (details.name == name) {
|
||||
settings.teardownModule();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
oldModule(name, settings);
|
||||
};
|
||||
|
||||
window.getCoverObject = function() {
|
||||
var coverObject = {}, fileName, gaps, gap, count, targetModuleName;
|
||||
var isScoped = document.location.search.indexOf('module=') != -1;
|
||||
|
||||
for (var i = 0, length = coverObjects.length; i < length; i++) {
|
||||
for (fileName in coverObjects[i]) {
|
||||
gaps = coverObjects[i][fileName];
|
||||
|
||||
if (isScoped && fileName.indexOf('js/tinymce/classes') === 0) {
|
||||
targetModuleName = "tinymce." + fileName.substr('js/tinymce/classes'.length + 1).replace(/\//g, '.');
|
||||
targetModuleName = targetModuleName.replace(/\.js$/, '');
|
||||
|
||||
if (!modulesExecuted[targetModuleName]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!coverObject.hasOwnProperty(fileName)) {
|
||||
coverObject[fileName] = gaps;
|
||||
} else {
|
||||
for (gap in gaps) {
|
||||
if (gap === '__code') {
|
||||
continue;
|
||||
}
|
||||
|
||||
count = gaps[gap];
|
||||
|
||||
if (!coverObject[fileName].hasOwnProperty(gap)) {
|
||||
coverObject[fileName][gap] = count;
|
||||
} else {
|
||||
coverObject[fileName][gap] += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return coverObject;
|
||||
};
|
||||
})();
|
||||
@ -1,37 +0,0 @@
|
||||
(function(exports) {
|
||||
exports.AMDLC_TESTS = true;
|
||||
|
||||
function resolve(id) {
|
||||
var i, target = exports, fragments = id.split(/[.\/]/);
|
||||
|
||||
for (i = 0; i < fragments.length; i++) {
|
||||
if (!target[fragments[i]]) {
|
||||
return;
|
||||
}
|
||||
|
||||
target = target[fragments[i]];
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
function require(ids, callback) {
|
||||
var i, module, defs = [], privateModules = exports.privateModules || {};
|
||||
|
||||
for (i = 0; i < ids.length; i++) {
|
||||
module = privateModules[ids[i]] || resolve(ids[i]);
|
||||
|
||||
if (!module) {
|
||||
throw 'module definition dependency not found: ' + ids[i];
|
||||
}
|
||||
|
||||
defs.push(module);
|
||||
}
|
||||
|
||||
callback.apply(null, defs);
|
||||
}
|
||||
|
||||
exports.ModuleLoader = {
|
||||
require: require
|
||||
};
|
||||
})(this);
|
||||
@ -1,20 +0,0 @@
|
||||
Copyright (c) 2010 John Resig, http://jquery.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@ -1,237 +0,0 @@
|
||||
/*!
|
||||
* QUnit 1.14.0
|
||||
* http://qunitjs.com/
|
||||
*
|
||||
* Copyright 2013 jQuery Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* Date: 2014-01-31T16:40Z
|
||||
*/
|
||||
|
||||
/** Font Family and Sizes */
|
||||
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
||||
#qunit-tests { font-size: smaller; }
|
||||
|
||||
|
||||
/** Resets */
|
||||
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/** Header */
|
||||
|
||||
#qunit-header {
|
||||
padding: 0.5em 0 0.5em 1em;
|
||||
|
||||
color: #8699A4;
|
||||
background-color: #0D3349;
|
||||
|
||||
font-size: 1.5em;
|
||||
line-height: 1em;
|
||||
font-weight: 400;
|
||||
|
||||
border-radius: 5px 5px 0 0;
|
||||
}
|
||||
|
||||
#qunit-header a {
|
||||
text-decoration: none;
|
||||
color: #C2CCD1;
|
||||
}
|
||||
|
||||
#qunit-header a:hover,
|
||||
#qunit-header a:focus {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar label {
|
||||
display: inline-block;
|
||||
padding: 0 0.5em 0 0.1em;
|
||||
}
|
||||
|
||||
#qunit-banner {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar {
|
||||
padding: 0.5em 0 0.5em 2em;
|
||||
color: #5E740B;
|
||||
background-color: #EEE;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#qunit-userAgent {
|
||||
padding: 0.5em 0 0.5em 2.5em;
|
||||
background-color: #2B81AF;
|
||||
color: #FFF;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||
}
|
||||
|
||||
#qunit-modulefilter-container {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/** Tests: Pass/Fail */
|
||||
|
||||
#qunit-tests {
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests li {
|
||||
padding: 0.4em 0.5em 0.4em 2.5em;
|
||||
border-bottom: 1px solid #FFF;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests li strong {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#qunit-tests li a {
|
||||
padding: 0.5em;
|
||||
color: #C2CCD1;
|
||||
text-decoration: none;
|
||||
}
|
||||
#qunit-tests li a:hover,
|
||||
#qunit-tests li a:focus {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#qunit-tests li .runtime {
|
||||
float: right;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.qunit-assert-list {
|
||||
margin-top: 0.5em;
|
||||
padding: 0.5em;
|
||||
|
||||
background-color: #FFF;
|
||||
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.qunit-collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests table {
|
||||
border-collapse: collapse;
|
||||
margin-top: 0.2em;
|
||||
}
|
||||
|
||||
#qunit-tests th {
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
padding: 0 0.5em 0 0;
|
||||
}
|
||||
|
||||
#qunit-tests td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#qunit-tests pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
#qunit-tests del {
|
||||
background-color: #E0F2BE;
|
||||
color: #374E0C;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#qunit-tests ins {
|
||||
background-color: #FFCACA;
|
||||
color: #500;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*** Test Counts */
|
||||
|
||||
#qunit-tests b.counts { color: #000; }
|
||||
#qunit-tests b.passed { color: #5E740B; }
|
||||
#qunit-tests b.failed { color: #710909; }
|
||||
|
||||
#qunit-tests li li {
|
||||
padding: 5px;
|
||||
background-color: #FFF;
|
||||
border-bottom: none;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
/*** Passing Styles */
|
||||
|
||||
#qunit-tests li li.pass {
|
||||
color: #3C510C;
|
||||
background-color: #FFF;
|
||||
border-left: 10px solid #C6E746;
|
||||
}
|
||||
|
||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
||||
#qunit-tests .pass .test-name { color: #366097; }
|
||||
|
||||
#qunit-tests .pass .test-actual,
|
||||
#qunit-tests .pass .test-expected { color: #999; }
|
||||
|
||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
||||
|
||||
/*** Failing Styles */
|
||||
|
||||
#qunit-tests li li.fail {
|
||||
color: #710909;
|
||||
background-color: #FFF;
|
||||
border-left: 10px solid #EE5757;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#qunit-tests > li:last-child {
|
||||
border-radius: 0 0 5px 5px;
|
||||
}
|
||||
|
||||
#qunit-tests .fail { color: #000; background-color: #EE5757; }
|
||||
#qunit-tests .fail .test-name,
|
||||
#qunit-tests .fail .module-name { color: #000; }
|
||||
|
||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
||||
#qunit-tests .fail .test-expected { color: #008000; }
|
||||
|
||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
||||
|
||||
|
||||
/** Result */
|
||||
|
||||
#qunit-testresult {
|
||||
padding: 0.5em 0.5em 0.5em 2.5em;
|
||||
|
||||
color: #2B81AF;
|
||||
background-color: #D2E0E6;
|
||||
|
||||
border-bottom: 1px solid #FFF;
|
||||
}
|
||||
#qunit-testresult .module-name {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/** Fixture */
|
||||
|
||||
#qunit-fixture {
|
||||
position: absolute;
|
||||
top: -10000px;
|
||||
left: -10000px;
|
||||
width: 1000px;
|
||||
height: 1000px;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,148 +0,0 @@
|
||||
/*
|
||||
* PhantomJS Runner QUnit Plugin 1.2.0
|
||||
*
|
||||
* PhantomJS binaries: http://phantomjs.org/download.html
|
||||
* Requires PhantomJS 1.6+ (1.7+ recommended)
|
||||
*
|
||||
* Run with:
|
||||
* phantomjs runner.js [url-of-your-qunit-testsuite]
|
||||
*
|
||||
* e.g.
|
||||
* phantomjs runner.js http://localhost/qunit/test/index.html
|
||||
*/
|
||||
|
||||
/*global phantom:false, require:false, console:false, window:false, QUnit:false */
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var url, page, timeout,
|
||||
args = require('system').args;
|
||||
|
||||
// arg[0]: scriptName, args[1...]: arguments
|
||||
if (args.length < 2 || args.length > 3) {
|
||||
console.error('Usage:\n phantomjs runner.js [url-of-your-qunit-testsuite] [timeout-in-seconds]');
|
||||
phantom.exit(1);
|
||||
}
|
||||
|
||||
url = args[1];
|
||||
page = require('webpage').create();
|
||||
if (args[2] !== undefined) {
|
||||
timeout = parseInt(args[2], 10);
|
||||
}
|
||||
|
||||
// Route `console.log()` calls from within the Page context to the main Phantom context (i.e. current `this`)
|
||||
page.onConsoleMessage = function(msg) {
|
||||
console.log(msg);
|
||||
};
|
||||
|
||||
page.onInitialized = function() {
|
||||
page.evaluate(addLogging);
|
||||
};
|
||||
|
||||
page.onCallback = function(message) {
|
||||
var result,
|
||||
failed;
|
||||
|
||||
if (message) {
|
||||
if (message.name === 'QUnit.done') {
|
||||
result = message.data;
|
||||
failed = !result || !result.total || result.failed;
|
||||
|
||||
if (!result.total) {
|
||||
console.error('No tests were executed. Are you loading tests asynchronously?');
|
||||
}
|
||||
|
||||
phantom.exit(failed ? 1 : 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
page.open(url, function(status) {
|
||||
if (status !== 'success') {
|
||||
console.error('Unable to access network: ' + status);
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
// Cannot do this verification with the 'DOMContentLoaded' handler because it
|
||||
// will be too late to attach it if a page does not have any script tags.
|
||||
var qunitMissing = page.evaluate(function() { return (typeof QUnit === 'undefined' || !QUnit); });
|
||||
if (qunitMissing) {
|
||||
console.error('The `QUnit` object is not present on this page.');
|
||||
phantom.exit(1);
|
||||
}
|
||||
|
||||
// Set a timeout on the test running, otherwise tests with async problems will hang forever
|
||||
if (typeof timeout === 'number') {
|
||||
setTimeout(function() {
|
||||
console.error('The specified timeout of ' + timeout + ' seconds has expired. Aborting...');
|
||||
phantom.exit(1);
|
||||
}, timeout * 1000);
|
||||
}
|
||||
|
||||
// Do nothing... the callback mechanism will handle everything!
|
||||
}
|
||||
});
|
||||
|
||||
function addLogging() {
|
||||
window.document.addEventListener('DOMContentLoaded', function() {
|
||||
var currentTestAssertions = [];
|
||||
|
||||
QUnit.log(function(details) {
|
||||
var response;
|
||||
|
||||
// Ignore passing assertions
|
||||
if (details.result) {
|
||||
return;
|
||||
}
|
||||
|
||||
response = details.message || '';
|
||||
|
||||
if (typeof details.expected !== 'undefined') {
|
||||
if (response) {
|
||||
response += ', ';
|
||||
}
|
||||
|
||||
response += 'expected: ' + details.expected + ', but was: ' + details.actual;
|
||||
}
|
||||
|
||||
if (details.source) {
|
||||
response += "\n" + details.source;
|
||||
}
|
||||
|
||||
currentTestAssertions.push('Failed assertion: ' + response);
|
||||
});
|
||||
|
||||
QUnit.testDone(function(result) {
|
||||
var i,
|
||||
len,
|
||||
name = '';
|
||||
|
||||
if (result.module) {
|
||||
name += result.module + ': ';
|
||||
}
|
||||
name += result.name;
|
||||
|
||||
if (result.failed) {
|
||||
console.log('\n' + 'Test failed: ' + name);
|
||||
|
||||
for (i = 0, len = currentTestAssertions.length; i < len; i++) {
|
||||
console.log(' ' + currentTestAssertions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
currentTestAssertions.length = 0;
|
||||
});
|
||||
|
||||
QUnit.done(function(result) {
|
||||
console.log('\n' + 'Took ' + result.runtime + 'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.');
|
||||
|
||||
if (typeof window.callPhantom === 'function') {
|
||||
window.callPhantom({
|
||||
'name': 'QUnit.done',
|
||||
'data': result
|
||||
});
|
||||
}
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
})();
|
||||
@ -1,9 +0,0 @@
|
||||
// Edited for WordPres
|
||||
document.write('<script src="../../../src/wp-includes/js/tinymce/tinymce.js"></script>');
|
||||
|
||||
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,493 +0,0 @@
|
||||
(function() {
|
||||
function fontFace(face) {
|
||||
if (tinymce.isOpera) {
|
||||
return "'" + face + "'";
|
||||
}
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
function findContainer(selector) {
|
||||
var container;
|
||||
if (tinymce.is(selector, 'string')) {
|
||||
container = editor.dom.select(selector)[0];
|
||||
} else {
|
||||
container = selector;
|
||||
}
|
||||
if (container.firstChild) {
|
||||
container = container.firstChild;
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
function setSelection(startSelector, startOffset, endSelector, endOffset) {
|
||||
if (!endSelector) {
|
||||
endSelector = startSelector;
|
||||
endOffset = startOffset;
|
||||
}
|
||||
var startContainer = findContainer(startSelector);
|
||||
var endContainer = findContainer(endSelector);
|
||||
var rng = editor.dom.createRng();
|
||||
|
||||
function setRange(container, offset, start) {
|
||||
offset = offset || 0;
|
||||
|
||||
if (offset === 'after') {
|
||||
if (start) {
|
||||
rng.setStartAfter(container);
|
||||
} else {
|
||||
rng.setEndAfter(container);
|
||||
}
|
||||
return;
|
||||
} else if (offset === 'afterNextCharacter') {
|
||||
container = container.nextSibling;
|
||||
offset = 1;
|
||||
}
|
||||
if (start) {
|
||||
rng.setStart(container, offset);
|
||||
} else {
|
||||
rng.setEnd(container, offset);
|
||||
}
|
||||
}
|
||||
|
||||
setRange(startContainer, startOffset, true);
|
||||
setRange(endContainer, endOffset, false);
|
||||
editor.selection.setRng(rng);
|
||||
}
|
||||
|
||||
function assertRange(actual, expected) {
|
||||
deepEqual({
|
||||
startContainer: actual.startContainer,
|
||||
startOffset: actual.startOffset,
|
||||
endContainer: actual.endContainer,
|
||||
endOffset: actual.endOffset
|
||||
}, {
|
||||
startContainer: expected.startContainer,
|
||||
startOffset: expected.startOffset,
|
||||
endContainer: expected.endContainer,
|
||||
endOffset: expected.endOffset
|
||||
});
|
||||
}
|
||||
|
||||
function createRange(startContainer, startOffset, endContainer, endOffset) {
|
||||
var rng = tinymce.DOM.createRng();
|
||||
|
||||
rng.setStart(startContainer, startOffset);
|
||||
|
||||
if (endContainer) {
|
||||
rng.setEnd(endContainer, endOffset);
|
||||
}
|
||||
|
||||
return rng;
|
||||
}
|
||||
|
||||
function assertCaretPosition(actual, expected, message) {
|
||||
if (expected === null) {
|
||||
strictEqual(actual, expected, message || 'Expected null.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (actual === null) {
|
||||
strictEqual(actual, expected, message || 'Didn\'t expect null.');
|
||||
return;
|
||||
}
|
||||
|
||||
deepEqual({
|
||||
container: actual.container(),
|
||||
offset: actual.offset()
|
||||
}, {
|
||||
container: expected.container(),
|
||||
offset: expected.offset()
|
||||
}, message);
|
||||
}
|
||||
|
||||
function trimContent(content) {
|
||||
return content.replace(/^<p> <\/p>\n?/, '').replace(/\n?<p> <\/p>$/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fakes a key event.
|
||||
*
|
||||
* @param {Element/String} e DOM element object or element id to send fake event to.
|
||||
* @param {String} na Event name to fake like "keydown".
|
||||
* @param {Object} o Optional object with data to send with the event like keyCode and charCode.
|
||||
*/
|
||||
function fakeKeyEvent(e, na, o) {
|
||||
var ev;
|
||||
|
||||
o = tinymce.extend({
|
||||
keyCode : 13,
|
||||
charCode : 0
|
||||
}, o);
|
||||
|
||||
e = tinymce.DOM.get(e);
|
||||
|
||||
if (e.fireEvent) {
|
||||
ev = document.createEventObject();
|
||||
tinymce.extend(ev, o);
|
||||
e.fireEvent('on' + na, ev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.createEvent) {
|
||||
try {
|
||||
// Fails in Safari
|
||||
ev = document.createEvent('KeyEvents');
|
||||
ev.initKeyEvent(na, true, true, window, false, false, false, false, o.keyCode, o.charCode);
|
||||
} catch (ex) {
|
||||
ev = document.createEvent('Events');
|
||||
ev.initEvent(na, true, true);
|
||||
|
||||
ev.keyCode = o.keyCode;
|
||||
ev.charCode = o.charCode;
|
||||
}
|
||||
} else {
|
||||
ev = document.createEvent('UIEvents');
|
||||
|
||||
if (ev.initUIEvent) {
|
||||
ev.initUIEvent(na, true, true, window, 1);
|
||||
}
|
||||
|
||||
ev.keyCode = o.keyCode;
|
||||
ev.charCode = o.charCode;
|
||||
}
|
||||
|
||||
e.dispatchEvent(ev);
|
||||
}
|
||||
|
||||
function normalizeRng(rng) {
|
||||
if (rng.startContainer.nodeType == 3) {
|
||||
if (rng.startOffset === 0) {
|
||||
rng.setStartBefore(rng.startContainer);
|
||||
} else if (rng.startOffset >= rng.startContainer.nodeValue.length - 1) {
|
||||
rng.setStartAfter(rng.startContainer);
|
||||
}
|
||||
}
|
||||
|
||||
if (rng.endContainer.nodeType == 3) {
|
||||
if (rng.endOffset === 0) {
|
||||
rng.setEndBefore(rng.endContainer);
|
||||
} else if (rng.endOffset >= rng.endContainer.nodeValue.length - 1) {
|
||||
rng.setEndAfter(rng.endContainer);
|
||||
}
|
||||
}
|
||||
|
||||
return rng;
|
||||
}
|
||||
|
||||
// TODO: Replace this with the new event logic in 3.5
|
||||
function type(chr) {
|
||||
var editor = tinymce.activeEditor, keyCode, charCode, evt, startElm, rng, offset;
|
||||
|
||||
function charCodeToKeyCode(charCode) {
|
||||
var lookup = {
|
||||
'0': 48, '1': 49, '2': 50, '3': 51, '4': 52, '5': 53, '6': 54, '7': 55, '8': 56, '9': 57, 'a': 65, 'b': 66, 'c': 67,
|
||||
'd': 68, 'e': 69, 'f': 70, 'g': 71, 'h': 72, 'i': 73, 'j': 74, 'k': 75, 'l': 76, 'm': 77, 'n': 78, 'o': 79, 'p': 80, 'q': 81,
|
||||
'r': 82, 's': 83, 't': 84, 'u': 85, 'v': 86, 'w': 87, 'x': 88, 'y': 89, ' ': 32, ',': 188, '-': 189, '.': 190, '/': 191, '\\': 220,
|
||||
'[': 219, ']': 221, '\'': 222, ';': 186, '=': 187, ')': 41
|
||||
};
|
||||
|
||||
return lookup[String.fromCharCode(charCode)];
|
||||
}
|
||||
|
||||
function fakeEvent(target, type, evt) {
|
||||
editor.dom.fire(target, type, evt);
|
||||
}
|
||||
|
||||
// Numeric keyCode
|
||||
if (typeof chr == "number") {
|
||||
charCode = chr;
|
||||
keyCode = charCodeToKeyCode(charCode);
|
||||
} else if (typeof chr == "string") {
|
||||
// String value
|
||||
if (chr == '\b') {
|
||||
keyCode = 8;
|
||||
charCode = chr.charCodeAt(0);
|
||||
} else if (chr == '\n') {
|
||||
keyCode = 13;
|
||||
charCode = chr.charCodeAt(0);
|
||||
} else {
|
||||
charCode = chr.charCodeAt(0);
|
||||
keyCode = charCodeToKeyCode(charCode);
|
||||
}
|
||||
} else {
|
||||
evt = chr;
|
||||
|
||||
if (evt.charCode) {
|
||||
chr = String.fromCharCode(evt.charCode);
|
||||
}
|
||||
|
||||
if (evt.keyCode) {
|
||||
keyCode = evt.keyCode;
|
||||
}
|
||||
}
|
||||
|
||||
evt = evt || {keyCode: keyCode, charCode: charCode};
|
||||
|
||||
startElm = editor.selection.getStart();
|
||||
fakeEvent(startElm, 'keydown', evt);
|
||||
fakeEvent(startElm, 'keypress', evt);
|
||||
|
||||
if (!evt.isDefaultPrevented()) {
|
||||
if (keyCode == 8) {
|
||||
if (editor.getDoc().selection) {
|
||||
rng = editor.getDoc().selection.createRange();
|
||||
|
||||
if (rng.text.length === 0) {
|
||||
rng.moveStart('character', -1);
|
||||
rng.select();
|
||||
}
|
||||
|
||||
rng.execCommand('Delete', false, null);
|
||||
} else {
|
||||
rng = editor.selection.getRng();
|
||||
|
||||
if (rng.collapsed) {
|
||||
if (rng.startContainer.nodeType == 1) {
|
||||
var nodes = rng.startContainer.childNodes, lastNode = nodes[nodes.length - 1];
|
||||
|
||||
// If caret is at <p>abc|</p> and after the abc text node then move it to the end of the text node
|
||||
// Expand the range to include the last char <p>ab[c]</p> since IE 11 doesn't delete otherwise
|
||||
if (rng.startOffset >= nodes.length - 1 && lastNode && lastNode.nodeType == 3 && lastNode.data.length > 0) {
|
||||
rng.setStart(lastNode, lastNode.data.length - 1);
|
||||
rng.setEnd(lastNode, lastNode.data.length);
|
||||
editor.selection.setRng(rng);
|
||||
}
|
||||
} else if (rng.startContainer.nodeType == 3) {
|
||||
// If caret is at <p>abc|</p> and after the abc text node then move it to the end of the text node
|
||||
// Expand the range to include the last char <p>ab[c]</p> since IE 11 doesn't delete otherwise
|
||||
offset = rng.startOffset;
|
||||
if (offset > 0) {
|
||||
rng.setStart(rng.startContainer, offset - 1);
|
||||
rng.setEnd(rng.startContainer, offset);
|
||||
editor.selection.setRng(rng);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.getDoc().execCommand('Delete', false, null);
|
||||
}
|
||||
} else if (typeof chr == 'string') {
|
||||
rng = editor.selection.getRng(true);
|
||||
|
||||
if (rng.startContainer.nodeType == 3 && rng.collapsed) {
|
||||
rng.startContainer.insertData(rng.startOffset, chr);
|
||||
rng.setStart(rng.startContainer, rng.startOffset + 1);
|
||||
rng.collapse(true);
|
||||
editor.selection.setRng(rng);
|
||||
} else {
|
||||
rng.deleteContents();
|
||||
rng.insertNode(editor.getDoc().createTextNode(chr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fakeEvent(startElm, 'keyup', evt);
|
||||
}
|
||||
|
||||
function cleanHtml(html) {
|
||||
html = html.toLowerCase().replace(/[\r\n]+/gi, '');
|
||||
html = html.replace(/ (sizcache[0-9]+|sizcache|nodeindex|sizset[0-9]+|sizset|data\-mce\-expando|data\-mce\-selected)="[^"]*"/gi, '');
|
||||
html = html.replace(/<span[^>]+data-mce-bogus[^>]+>[\u200B\uFEFF]+<\/span>|<div[^>]+data-mce-bogus[^>]+><\/div>/gi, '');
|
||||
html = html.replace(/ style="([^"]+)"/gi, function(val1, val2) {
|
||||
val2 = val2.replace(/;$/, '');
|
||||
return ' style="' + val2.replace(/\:([^ ])/g, ': $1') + ';"';
|
||||
});
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function normalizeHtml(html) {
|
||||
var writer = new tinymce.html.Writer();
|
||||
|
||||
new tinymce.html.SaxParser({
|
||||
validate: false,
|
||||
comment: writer.comment,
|
||||
cdata: writer.cdata,
|
||||
text: writer.text,
|
||||
end: writer.end,
|
||||
pi: writer.pi,
|
||||
doctype: writer.doctype,
|
||||
|
||||
start: function(name, attrs, empty) {
|
||||
attrs.sort(function(a, b) {
|
||||
if (a.name === b.name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return a.name > b.name ? 1 : -1;
|
||||
});
|
||||
|
||||
writer.start(name, attrs, empty);
|
||||
}
|
||||
}).parse(html);
|
||||
|
||||
return writer.getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Measures the x, y, w, h of the specified element/control relative to the view element.
|
||||
*/
|
||||
function rect(ctrl) {
|
||||
var outerRect, innerRect;
|
||||
|
||||
if (ctrl.nodeType) {
|
||||
innerRect = ctrl.getBoundingClientRect();
|
||||
} else {
|
||||
innerRect = ctrl.getEl().getBoundingClientRect();
|
||||
}
|
||||
|
||||
outerRect = document.getElementById('view').getBoundingClientRect();
|
||||
|
||||
return [
|
||||
Math.round(innerRect.left - outerRect.left),
|
||||
Math.round(innerRect.top - outerRect.top),
|
||||
Math.round(innerRect.right - innerRect.left),
|
||||
Math.round(innerRect.bottom - innerRect.top)
|
||||
];
|
||||
}
|
||||
|
||||
function size(ctrl) {
|
||||
return rect(ctrl).slice(2);
|
||||
}
|
||||
|
||||
function resetScroll(elm) {
|
||||
elm.scrollTop = 0;
|
||||
elm.scrollLeft = 0;
|
||||
}
|
||||
|
||||
// Needed since fonts render differently on different platforms
|
||||
function nearlyEqualRects(rect1, rect2, diff) {
|
||||
diff = diff || 1;
|
||||
|
||||
for (var i = 0; i < 4; i++) {
|
||||
if (Math.abs(rect1[i] - rect2[i]) > diff) {
|
||||
deepEqual(rect1, rect2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ok(true);
|
||||
}
|
||||
|
||||
function getFrontmostWindow() {
|
||||
return editor.windowManager.windows[editor.windowManager.windows.length - 1];
|
||||
}
|
||||
|
||||
function pressKey(evt) {
|
||||
var dom = editor.dom, target = editor.selection.getNode();
|
||||
|
||||
if (typeof evt == "number") {
|
||||
evt = {keyCode: evt};
|
||||
}
|
||||
|
||||
evt = tinymce.extend({keyCode: 37}, evt);
|
||||
|
||||
dom.fire(target, 'keydown', evt);
|
||||
dom.fire(target, 'keypress', evt);
|
||||
dom.fire(target, 'keyup', evt);
|
||||
}
|
||||
|
||||
function pressArrowKey(evt) {
|
||||
var dom = editor.dom, target = editor.selection.getNode();
|
||||
|
||||
evt = tinymce.extend({keyCode: 37}, evt);
|
||||
|
||||
dom.fire(target, 'keydown', evt);
|
||||
dom.fire(target, 'keypress', evt);
|
||||
dom.fire(target, 'keyup', evt);
|
||||
}
|
||||
|
||||
function pressEnter(evt) {
|
||||
var dom = editor.dom, target = editor.selection.getNode();
|
||||
|
||||
evt = tinymce.extend({keyCode: 13}, evt);
|
||||
|
||||
dom.fire(target, 'keydown', evt);
|
||||
dom.fire(target, 'keypress', evt);
|
||||
dom.fire(target, 'keyup', evt);
|
||||
}
|
||||
|
||||
function trimBrsOnIE(html) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
function triggerElementChange(element){
|
||||
var evt;
|
||||
|
||||
if ("createEvent" in document) {
|
||||
evt = document.createEvent("HTMLEvents");
|
||||
evt.initEvent("change", false, true);
|
||||
element.dispatchEvent(evt);
|
||||
} else {
|
||||
element.fireEvent("onchange");
|
||||
}
|
||||
}
|
||||
|
||||
window.Utils = {
|
||||
fontFace: fontFace,
|
||||
findContainer: findContainer,
|
||||
setSelection: setSelection,
|
||||
trimContent: trimContent,
|
||||
fakeKeyEvent: fakeKeyEvent,
|
||||
normalizeRng: normalizeRng,
|
||||
type: type,
|
||||
cleanHtml: cleanHtml,
|
||||
normalizeHtml: normalizeHtml,
|
||||
rect: rect,
|
||||
size: size,
|
||||
resetScroll: resetScroll,
|
||||
nearlyEqualRects: nearlyEqualRects,
|
||||
getFrontmostWindow: getFrontmostWindow,
|
||||
pressKey: pressKey,
|
||||
pressArrowKey: pressArrowKey,
|
||||
pressEnter: pressEnter,
|
||||
trimBrsOnIE: trimBrsOnIE,
|
||||
patch: patch,
|
||||
unpatch: unpatch,
|
||||
triggerElementChange: triggerElementChange,
|
||||
createRange: createRange,
|
||||
assertRange: assertRange,
|
||||
assertCaretPosition: assertCaretPosition
|
||||
};
|
||||
})();
|
||||
@ -1,39 +0,0 @@
|
||||
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);
|
||||
});
|
||||
@ -1,527 +0,0 @@
|
||||
module("tinymce.Editor", {
|
||||
setupModule: function() {
|
||||
document.getElementById('view').innerHTML = '<textarea id="elm1"></textarea><div id="elm2"></div>';
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "#elm1",
|
||||
add_unload_trigger: false,
|
||||
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'
|
||||
},
|
||||
custom_elements: 'custom1,~custom2',
|
||||
extended_valid_elements: 'custom1,custom2,script[*]',
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
|
||||
if (window.inlineEditor) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
selector: "#elm2",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
inline: true,
|
||||
init_instance_callback: function(ed) {
|
||||
window.inlineEditor = ed;
|
||||
|
||||
if (window.editor) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
Utils.unpatch(editor.getDoc());
|
||||
inlineEditor.show();
|
||||
editor.show();
|
||||
}
|
||||
});
|
||||
|
||||
test('Event: change', function() {
|
||||
var level, lastLevel;
|
||||
|
||||
editor.on('change', function(e) {
|
||||
level = e.level;
|
||||
lastLevel = e.lastLevel;
|
||||
});
|
||||
|
||||
editor.setContent('');
|
||||
editor.insertContent('a');
|
||||
equal(level.content.toLowerCase(), '<p>a</p>');
|
||||
equal(lastLevel.content, editor.undoManager.data[0].content);
|
||||
|
||||
editor.off('change');
|
||||
});
|
||||
|
||||
test('Event: beforeExecCommand', function() {
|
||||
var cmd, ui, value;
|
||||
|
||||
editor.on('BeforeExecCommand', function(e) {
|
||||
cmd = e.command;
|
||||
ui = e.ui;
|
||||
value = e.value;
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
editor.setContent('');
|
||||
editor.insertContent('a');
|
||||
equal(editor.getContent(), '');
|
||||
equal(cmd, 'mceInsertContent');
|
||||
equal(ui, false);
|
||||
equal(value, 'a');
|
||||
|
||||
editor.off('BeforeExecCommand');
|
||||
editor.setContent('');
|
||||
editor.insertContent('a');
|
||||
equal(editor.getContent(), '<p>a</p>');
|
||||
});
|
||||
|
||||
test('urls - relativeURLs', function() {
|
||||
editor.settings.relative_urls = true;
|
||||
editor.documentBaseURI = new tinymce.util.URI('http://www.site.com/dirA/dirB/dirC/');
|
||||
|
||||
editor.setContent('<a href="test.html">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="test.html">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="../test.html">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="../test.html">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="test/test.html">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="test/test.html">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="/test.html">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="../../../test.html">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="http://www.somesite.com/test/file.htm">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="http://www.somesite.com/test/file.htm">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="//www.site.com/test/file.htm">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="../../../test/file.htm">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="//www.somesite.com/test/file.htm">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="//www.somesite.com/test/file.htm">test</a></p>');
|
||||
});
|
||||
|
||||
test('urls - absoluteURLs', function() {
|
||||
editor.settings.relative_urls = false;
|
||||
editor.settings.remove_script_host = true;
|
||||
editor.documentBaseURI = new tinymce.util.URI('http://www.site.com/dirA/dirB/dirC/');
|
||||
|
||||
editor.setContent('<a href="test.html">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="/dirA/dirB/dirC/test.html">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="../test.html">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="/dirA/dirB/test.html">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="test/test.html">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="/dirA/dirB/dirC/test/test.html">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="http://www.somesite.com/test/file.htm">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="http://www.somesite.com/test/file.htm">test</a></p>');
|
||||
|
||||
editor.settings.relative_urls = false;
|
||||
editor.settings.remove_script_host = false;
|
||||
|
||||
editor.setContent('<a href="test.html">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="http://www.site.com/dirA/dirB/dirC/test.html">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="../test.html">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="http://www.site.com/dirA/dirB/test.html">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="test/test.html">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="http://www.site.com/dirA/dirB/dirC/test/test.html">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="http://www.somesite.com/test/file.htm">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="http://www.somesite.com/test/file.htm">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="//www.site.com/test/file.htm">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="//www.site.com/test/file.htm">test</a></p>');
|
||||
|
||||
editor.setContent('<a href="//www.somesite.com/test/file.htm">test</a>');
|
||||
equal(editor.getContent(), '<p><a href="//www.somesite.com/test/file.htm">test</a></p>');
|
||||
});
|
||||
|
||||
test('WebKit Serialization range bug', function() {
|
||||
expect(1);
|
||||
|
||||
if (tinymce.isIE) {
|
||||
ok(true, "Skip IE");
|
||||
} else {
|
||||
// Note that if we create the P with this invalid content directly, Chrome cleans it up differently to other browsers so we don't
|
||||
// wind up testing the serialization functionality we were aiming for and the test fails.
|
||||
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><table><tbody><tr><td>X</td></tr></tbody></table><p>456</p>');
|
||||
}
|
||||
});
|
||||
|
||||
test('editor_methods - getParam', function() {
|
||||
expect(5);
|
||||
|
||||
editor.settings.test = 'a,b,c';
|
||||
equal(editor.getParam('test', '', 'hash').c, 'c');
|
||||
|
||||
editor.settings.test = 'a';
|
||||
equal(editor.getParam('test', '', 'hash').a, 'a');
|
||||
|
||||
editor.settings.test = 'a=b';
|
||||
equal(editor.getParam('test', '', 'hash').a, 'b');
|
||||
|
||||
editor.settings.test = 'a=b;c=d,e';
|
||||
equal(editor.getParam('test', '', 'hash').c, 'd,e');
|
||||
|
||||
editor.settings.test = 'a=b,c=d';
|
||||
equal(editor.getParam('test', '', 'hash').c, 'd');
|
||||
});
|
||||
|
||||
test('setContent', function() {
|
||||
var count;
|
||||
|
||||
expect(4);
|
||||
|
||||
function callback(e) {
|
||||
e.content = e.content.replace(/test/, 'X');
|
||||
count++;
|
||||
}
|
||||
|
||||
editor.on('SetContent', callback);
|
||||
editor.on('BeforeSetContent', callback);
|
||||
count = 0;
|
||||
editor.setContent('<p>test</p>');
|
||||
equal(editor.getContent(), "<p>X</p>");
|
||||
equal(count, 2);
|
||||
editor.off('SetContent', callback);
|
||||
editor.off('BeforeSetContent', callback);
|
||||
|
||||
count = 0;
|
||||
editor.setContent('<p>test</p>');
|
||||
equal(editor.getContent(), "<p>test</p>");
|
||||
equal(count, 0);
|
||||
});
|
||||
|
||||
test('setContent with comment bug #4409', function() {
|
||||
editor.setContent('<!-- x --><br>');
|
||||
editor.settings.disable_nodechange = false;
|
||||
editor.nodeChanged();
|
||||
editor.settings.disable_nodechange = true;
|
||||
equal(editor.getContent(), "<!-- x --><p>\u00a0</p>");
|
||||
});
|
||||
|
||||
test('custom elements', function() {
|
||||
editor.setContent('<custom1>c1</custom1><custom2>c1</custom2>');
|
||||
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>');
|
||||
});
|
||||
|
||||
test('show/hide/isHidden and events', function() {
|
||||
var lastEvent;
|
||||
|
||||
editor.on('show hide', function(e) {
|
||||
lastEvent = e;
|
||||
});
|
||||
|
||||
equal(editor.isHidden(), false, 'Initial isHidden state');
|
||||
|
||||
editor.hide();
|
||||
equal(editor.isHidden(), true, 'After hide isHidden state');
|
||||
equal(lastEvent.type, "hide");
|
||||
|
||||
lastEvent = null;
|
||||
editor.hide();
|
||||
strictEqual(lastEvent, null);
|
||||
|
||||
editor.show();
|
||||
equal(editor.isHidden(), false, 'After show isHidden state');
|
||||
equal(lastEvent.type, "show");
|
||||
|
||||
lastEvent = null;
|
||||
editor.show();
|
||||
strictEqual(lastEvent, null);
|
||||
});
|
||||
|
||||
test('show/hide/isHidden and events (inline)', function() {
|
||||
var lastEvent;
|
||||
|
||||
inlineEditor.on('show hide', function(e) {
|
||||
lastEvent = e;
|
||||
});
|
||||
|
||||
equal(inlineEditor.isHidden(), false, 'Initial isHidden state');
|
||||
|
||||
inlineEditor.hide();
|
||||
equal(inlineEditor.isHidden(), true, 'After hide isHidden state');
|
||||
equal(lastEvent.type, "hide");
|
||||
strictEqual(inlineEditor.getBody().contentEditable, "false", "ContentEditable after hide");
|
||||
|
||||
lastEvent = null;
|
||||
inlineEditor.hide();
|
||||
strictEqual(lastEvent, null);
|
||||
|
||||
inlineEditor.show();
|
||||
equal(inlineEditor.isHidden(), false, 'After show isHidden state');
|
||||
equal(lastEvent.type, "show");
|
||||
strictEqual(inlineEditor.getBody().contentEditable, "true", "ContentEditable after show");
|
||||
|
||||
lastEvent = null;
|
||||
inlineEditor.show();
|
||||
strictEqual(lastEvent, null);
|
||||
});
|
||||
|
||||
test('hide save content and hidden state while saving', function() {
|
||||
var lastEvent, hiddenStateWhileSaving;
|
||||
|
||||
editor.on('SaveContent', function(e) {
|
||||
lastEvent = e;
|
||||
hiddenStateWhileSaving = editor.isHidden();
|
||||
});
|
||||
|
||||
editor.setContent('xyz');
|
||||
editor.hide();
|
||||
|
||||
strictEqual(hiddenStateWhileSaving, false, 'False isHidden state while saving');
|
||||
strictEqual(lastEvent.content, '<p>xyz</p>');
|
||||
strictEqual(document.getElementById('elm1').value, '<p>xyz</p>');
|
||||
});
|
||||
|
||||
asyncTest('remove editor', function() {
|
||||
document.getElementById('view').appendChild(tinymce.DOM.create('textarea', {id: 'elmx'}));
|
||||
|
||||
tinymce.init({
|
||||
selector: "#elmx",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
init_instance_callback: function(editor) {
|
||||
window.setTimeout(function() {
|
||||
var lastEvent;
|
||||
|
||||
editor.on('SaveContent', function(e) {
|
||||
lastEvent = e;
|
||||
});
|
||||
|
||||
editor.setContent('xyz');
|
||||
editor.remove();
|
||||
|
||||
QUnit.start();
|
||||
|
||||
strictEqual(lastEvent.content, '<p>xyz</p>');
|
||||
strictEqual(document.getElementById('elmx').value, '<p>xyz</p>');
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('insertContent', function() {
|
||||
editor.setContent('<p>ab</p>');
|
||||
Utils.setSelection('p', 1);
|
||||
editor.insertContent('c');
|
||||
equal(editor.getContent(), '<p>acb</p>');
|
||||
});
|
||||
|
||||
test('insertContent merge', function() {
|
||||
editor.setContent('<p><strong>a</strong></p>');
|
||||
Utils.setSelection('p', 1);
|
||||
editor.insertContent('<em><strong>b</strong></em>', {merge: true});
|
||||
equal(editor.getContent(), '<p><strong>a<em>b</em></strong></p>');
|
||||
});
|
||||
|
||||
test('execCommand return values for native commands', function() {
|
||||
var lastCmd;
|
||||
|
||||
strictEqual(editor.execCommand("NonExistingCommand"), false, "Return value for a completely unhandled command");
|
||||
|
||||
Utils.patch(editor.getDoc(), 'execCommand', function(orgFunc, cmd) {
|
||||
lastCmd = cmd;
|
||||
return true;
|
||||
});
|
||||
|
||||
strictEqual(editor.execCommand("ExistingCommand"), true, "Return value for an editor handled command");
|
||||
strictEqual(lastCmd, "ExistingCommand");
|
||||
});
|
||||
|
||||
test('addCommand', function() {
|
||||
var scope = {}, lastScope, lastArgs;
|
||||
|
||||
function callback() {
|
||||
lastScope = this;
|
||||
lastArgs = arguments;
|
||||
}
|
||||
|
||||
editor.addCommand("CustomCommand1", callback, scope);
|
||||
editor.addCommand("CustomCommand2", callback);
|
||||
|
||||
editor.execCommand("CustomCommand1", false, "value", {extra: true});
|
||||
strictEqual(lastArgs[0], false);
|
||||
strictEqual(lastArgs[1], "value");
|
||||
ok(lastScope === scope);
|
||||
|
||||
editor.execCommand("CustomCommand2");
|
||||
equal(typeof lastArgs[0], "undefined");
|
||||
equal(typeof lastArgs[1], "undefined");
|
||||
ok(lastScope === editor);
|
||||
});
|
||||
|
||||
test('addQueryStateHandler', function() {
|
||||
var scope = {}, lastScope, currentState;
|
||||
|
||||
function callback() {
|
||||
lastScope = this;
|
||||
return currentState;
|
||||
}
|
||||
|
||||
editor.addQueryStateHandler("CustomCommand1", callback, scope);
|
||||
editor.addQueryStateHandler("CustomCommand2", callback);
|
||||
|
||||
currentState = false;
|
||||
ok(!editor.queryCommandState("CustomCommand1"));
|
||||
ok(lastScope === scope, "Scope is not custom scope");
|
||||
|
||||
currentState = true;
|
||||
ok(editor.queryCommandState("CustomCommand2"));
|
||||
ok(lastScope === editor, "Scope is not editor");
|
||||
});
|
||||
|
||||
test('Block script execution', function() {
|
||||
editor.setContent('<script></script><script type="x"></script><script type="mce-x"></script><p>x</p>');
|
||||
equal(
|
||||
Utils.cleanHtml(editor.getBody().innerHTML),
|
||||
'<script type="mce-no/type"></script>' +
|
||||
'<script type="mce-x"></script>' +
|
||||
'<script type="mce-x"></script>' +
|
||||
'<p>x</p>'
|
||||
);
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<script></script>' +
|
||||
'<script type="x"></script>' +
|
||||
'<script type="x"></script>' +
|
||||
'<p>x</p>'
|
||||
);
|
||||
});
|
||||
|
||||
test('addQueryValueHandler', function() {
|
||||
var scope = {}, lastScope, currentValue;
|
||||
|
||||
function callback() {
|
||||
lastScope = this;
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
editor.addQueryValueHandler("CustomCommand1", callback, scope);
|
||||
editor.addQueryValueHandler("CustomCommand2", callback);
|
||||
|
||||
currentValue = "a";
|
||||
equal(editor.queryCommandValue("CustomCommand1"), "a");
|
||||
ok(lastScope === scope, "Scope is not custom scope");
|
||||
|
||||
currentValue = "b";
|
||||
ok(editor.queryCommandValue("CustomCommand2"), "b");
|
||||
ok(lastScope === editor, "Scope is not editor");
|
||||
});
|
||||
|
||||
test('setDirty/isDirty', function() {
|
||||
var lastArgs = null;
|
||||
|
||||
editor.on('dirty', function(e) {
|
||||
lastArgs = e;
|
||||
});
|
||||
|
||||
editor.setDirty(false);
|
||||
strictEqual(lastArgs, null);
|
||||
strictEqual(editor.isDirty(), false);
|
||||
|
||||
editor.setDirty(true);
|
||||
strictEqual(lastArgs.type, 'dirty');
|
||||
strictEqual(editor.isDirty(), true);
|
||||
|
||||
lastArgs = null;
|
||||
editor.setDirty(true);
|
||||
strictEqual(lastArgs, null);
|
||||
strictEqual(editor.isDirty(), true);
|
||||
|
||||
editor.setDirty(false);
|
||||
strictEqual(lastArgs, null);
|
||||
strictEqual(editor.isDirty(), false);
|
||||
});
|
||||
|
||||
test('setMode', function() {
|
||||
var clickCount = 0;
|
||||
|
||||
editor.on('click', function() {
|
||||
clickCount++;
|
||||
});
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'click');
|
||||
equal(clickCount, 1);
|
||||
|
||||
editor.setMode('readonly');
|
||||
equal(editor.theme.panel.find('button:last')[2].disabled(), true);
|
||||
editor.dom.fire(editor.getBody(), 'click');
|
||||
equal(clickCount, 1);
|
||||
|
||||
editor.setMode('design');
|
||||
editor.dom.fire(editor.getBody(), 'click');
|
||||
equal(editor.theme.panel.find('button:last')[2].disabled(), false);
|
||||
equal(clickCount, 2);
|
||||
});
|
||||
|
||||
test('translate', function() {
|
||||
tinymce.addI18n('en_US', {
|
||||
'input i18n': 'output i18n'
|
||||
});
|
||||
|
||||
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>');
|
||||
});
|
||||
@ -1,890 +0,0 @@
|
||||
module("tinymce.EditorCommands", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
indent: false,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
convert_urls: 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,padding-left,text-align,display'
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function getContent() {
|
||||
return editor.getContent({format:'raw'}).toLowerCase().replace(/[\r\n]+/g, '');
|
||||
}
|
||||
|
||||
test('mceInsertContent - p inside text of p', function() {
|
||||
var rng;
|
||||
|
||||
expect(7);
|
||||
|
||||
editor.setContent('<p>1234</p>');
|
||||
editor.focus();
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 1);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, '<p>abc</p>');
|
||||
equal(getContent(), '<p>1</p><p>abc</p><p>4</p>');
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(rng.startContainer.innerHTML, 'abc');
|
||||
});
|
||||
|
||||
test('mceInsertContent before HR', function() {
|
||||
var rng;
|
||||
|
||||
editor.setContent('<hr>');
|
||||
editor.focus();
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 0);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, 'x');
|
||||
equal(getContent(), '<p>x</p><hr />');
|
||||
});
|
||||
|
||||
test('mceInsertContent HR at end of H1', function() {
|
||||
editor.setContent('<h1>abc</h1>');
|
||||
Utils.setSelection('h1', 3);
|
||||
editor.execCommand('mceInsertContent', false, '<hr>');
|
||||
equal(editor.selection.getNode(), editor.getBody().lastChild);
|
||||
equal(editor.selection.getNode().nodeName, 'H1');
|
||||
equal(getContent(), '<h1>abc</h1><hr /><h1>\u00a0</h1>');
|
||||
});
|
||||
|
||||
test('mceInsertContent HR at end of H1 with P sibling', function() {
|
||||
editor.setContent('<h1>abc</h1><p>def</p>');
|
||||
Utils.setSelection('h1', 3);
|
||||
editor.execCommand('mceInsertContent', false, '<hr>');
|
||||
equal(editor.selection.getNode(), editor.getBody().lastChild);
|
||||
equal(editor.selection.getNode().nodeName, 'P');
|
||||
equal(getContent(), '<h1>abc</h1><hr /><p>def</p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent HR at end of H1 with inline elements with P sibling', function() {
|
||||
editor.setContent('<h1><strong>abc</strong></h1><p>def</p>');
|
||||
Utils.setSelection('strong', 3);
|
||||
editor.execCommand('mceInsertContent', false, '<hr>');
|
||||
equal(editor.selection.getNode(), editor.getBody().lastChild);
|
||||
equal(editor.selection.getNode().nodeName, 'P');
|
||||
equal(getContent(), '<h1><strong>abc</strong></h1><hr /><p>def</p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent empty block', function() {
|
||||
editor.setContent('<h1>abc</h1>');
|
||||
Utils.setSelection('h1', 1);
|
||||
editor.execCommand('mceInsertContent', false, '<p></p>');
|
||||
equal(editor.selection.getNode(), editor.getBody().childNodes[1]);
|
||||
equal(editor.selection.getNode().nodeName, 'P');
|
||||
equal(getContent(), '<h1>a</h1><p>\u00a0</p><h1>bc</h1>');
|
||||
});
|
||||
|
||||
test('mceInsertContent table at end of H1 with P sibling', function() {
|
||||
editor.setContent('<h1>abc</h1><p>def</p>');
|
||||
Utils.setSelection('h1', 3);
|
||||
editor.execCommand('mceInsertContent', false, '<table><tr><td></td></tr></table>');
|
||||
equal(editor.selection.getNode().nodeName, 'TD');
|
||||
equal(getContent(), '<h1>abc</h1><table><tbody><tr><td>\u00a0</td></tr></tbody></table><p>def</p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - p inside whole p', function() {
|
||||
var rng;
|
||||
|
||||
expect(7);
|
||||
|
||||
editor.setContent('<p>1234</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, '<p>abc</p>');
|
||||
equal(getContent(), '<p>abc</p>');
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(rng.startContainer.innerHTML, 'abc');
|
||||
});
|
||||
|
||||
test('mceInsertContent - pre in text of pre', function() {
|
||||
var rng;
|
||||
|
||||
expect(7);
|
||||
|
||||
editor.setContent('<pre>1234</pre>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('pre')[0].firstChild, 1);
|
||||
rng.setEnd(editor.dom.select('pre')[0].firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, '<pre>abc</pre>');
|
||||
equal(getContent(), '<pre>1</pre><pre>abc</pre><pre>4</pre>');
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer.nodeName, 'PRE');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'PRE');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(rng.startContainer.innerHTML, 'abc');
|
||||
});
|
||||
|
||||
test('mceInsertContent - h1 in text of h1', function() {
|
||||
var rng;
|
||||
|
||||
expect(7);
|
||||
|
||||
editor.setContent('<h1>1234</h1>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('h1')[0].firstChild, 1);
|
||||
rng.setEnd(editor.dom.select('h1')[0].firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, '<h1>abc</h1>');
|
||||
equal(getContent(), '<h1>1</h1><h1>abc</h1><h1>4</h1>');
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer.nodeName, 'H1');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'H1');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(rng.startContainer.innerHTML, 'abc');
|
||||
});
|
||||
|
||||
test('mceInsertContent - li inside li', function() {
|
||||
var rng;
|
||||
|
||||
expect(7);
|
||||
|
||||
editor.setContent('<ul><li>1234</li></ul>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('li')[0].firstChild, 1);
|
||||
rng.setEnd(editor.dom.select('li')[0].firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, '<li>abc</li>');
|
||||
equal(getContent(), '<ul><li>1</li><li>abc</li><li>4</li></ul>');
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer.nodeName, 'LI');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'LI');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(rng.startContainer.innerHTML, 'abc');
|
||||
});
|
||||
|
||||
test('mceInsertContent - p inside empty editor', function() {
|
||||
var rng;
|
||||
|
||||
expect(7);
|
||||
|
||||
editor.setContent('');
|
||||
editor.execCommand('mceInsertContent', false, '<p>abc</p>');
|
||||
equal(getContent(), '<p>abc</p>');
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(rng.startContainer.innerHTML, 'abc');
|
||||
});
|
||||
|
||||
test('mceInsertContent - text inside empty p', function() {
|
||||
var rng;
|
||||
|
||||
expect(7);
|
||||
|
||||
editor.getBody().innerHTML = '<p></p>';
|
||||
Utils.setSelection('p', 0);
|
||||
editor.execCommand('mceInsertContent', false, 'abc');
|
||||
equal(editor.getBody().innerHTML.toLowerCase().replace(/^<br>/, ''), '<p>abc</p>'); // Opera inserts a BR at the beginning of contents if the P is empty
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(rng.startContainer.innerHTML, 'abc');
|
||||
});
|
||||
|
||||
test('mceInsertContent - text inside empty p with br caret node', function() {
|
||||
var rng;
|
||||
|
||||
expect(7);
|
||||
|
||||
editor.getBody().innerHTML = '<p><br></p>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 0);
|
||||
rng.setEnd(editor.getBody().firstChild, 0);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, 'abc');
|
||||
equal(editor.getBody().innerHTML.toLowerCase(), '<p>abc</p>');
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(rng.startContainer.innerHTML, 'abc');
|
||||
});
|
||||
|
||||
test('mceInsertContent - image inside p', function() {
|
||||
var rng;
|
||||
|
||||
expect(6);
|
||||
|
||||
editor.setContent('<p>1</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, '<img src="about:blank" />');
|
||||
equal(editor.getContent(), '<p><img src="about:blank" /></p>');
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 1);
|
||||
});
|
||||
|
||||
test('mceInsertContent - legacy content', function() {
|
||||
var rng;
|
||||
|
||||
expect(1);
|
||||
|
||||
// Convert legacy content
|
||||
editor.setContent('<p>1</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, '<strike>strike</strike><font size="7">font</font>');
|
||||
equal(editor.getContent(), '<p><span style="text-decoration: line-through;">strike</span><span style="font-size: 300%;">font</span></p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - hr', function() {
|
||||
var rng;
|
||||
|
||||
expect(7);
|
||||
|
||||
editor.setContent('<p>123</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 1);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 2);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, '<hr />');
|
||||
equal(editor.getContent(), '<p>1</p><hr /><p>3</p>');
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer, editor.getBody().lastChild);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 0);
|
||||
});
|
||||
|
||||
test('mceInsertContent - forced root block', function() {
|
||||
expect(1);
|
||||
|
||||
// Forced root block
|
||||
editor.getBody().innerHTML = '';
|
||||
editor.execCommand('mceInsertContent', false, 'test<b>123</b><!-- a -->');
|
||||
// Opera adds an extra paragraph since it adds a BR at the end of the contents pass though this for now since it's an minority browser
|
||||
equal(editor.getContent().replace(/<p>\u00a0<\/p>/g, ''), '<p>test<strong>123</strong></p><!-- a -->');
|
||||
});
|
||||
|
||||
test('mceInsertContent - mixed inline content inside td', function() {
|
||||
expect(1);
|
||||
|
||||
// Forced root block
|
||||
editor.getBody().innerHTML = '<table><tr><td>X</td></tr></table>';
|
||||
Utils.setSelection('td', 0, 'td', 0);
|
||||
editor.execCommand('mceInsertContent', false, 'test<b>123</b><!-- a -->');
|
||||
equal(editor.getContent(), '<table><tbody><tr><td>test<strong>123</strong><!-- a -->X</td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - invalid insertion with spans on page', function(){
|
||||
var startingContent = '<p>123 testing <em>span later in document</em></p>',
|
||||
insertedContent = '<ul><li>u</li><li>l</li></ul>';
|
||||
editor.setContent(startingContent);
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 0);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertContent', false, insertedContent);
|
||||
|
||||
equal(editor.getContent(), insertedContent + startingContent);
|
||||
});
|
||||
|
||||
test('mceInsertContent - text with space before at start of block', function() {
|
||||
editor.getBody().innerHTML = '<p>a</p>';
|
||||
Utils.setSelection('p', 0);
|
||||
editor.execCommand('mceInsertContent', false, ' b');
|
||||
equal(editor.getContent(), '<p>\u00a0ba</p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - text with space after at end of block', function() {
|
||||
editor.getBody().innerHTML = '<p>a</p>';
|
||||
Utils.setSelection('p', 1);
|
||||
editor.execCommand('mceInsertContent', false, 'b ');
|
||||
equal(editor.getContent(), '<p>ab\u00a0</p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - text with space before/after at middle of block', function() {
|
||||
editor.getBody().innerHTML = '<p>ac</p>';
|
||||
Utils.setSelection('p', 1);
|
||||
editor.execCommand('mceInsertContent', false, ' b ');
|
||||
equal(editor.getContent(), '<p>a b c</p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - inline element with space before/after at middle of block', function() {
|
||||
editor.getBody().innerHTML = '<p>ac</p>';
|
||||
Utils.setSelection('p', 1);
|
||||
editor.execCommand('mceInsertContent', false, ' <em>b</em> ');
|
||||
equal(editor.getContent(), '<p>a <em>b</em> c</p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - block element with space before/after at middle of block', function() {
|
||||
editor.getBody().innerHTML = '<p>ac</p>';
|
||||
Utils.setSelection('p', 1);
|
||||
editor.execCommand('mceInsertContent', false, ' <p>b</p> ');
|
||||
equal(editor.getContent(), '<p>a</p><p>b</p><p>c</p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - strong in strong', function() {
|
||||
editor.getBody().innerHTML = '<strong>ac</strong>';
|
||||
Utils.setSelection('strong', 1);
|
||||
editor.execCommand('mceInsertContent', false, {content: '<strong>b</strong>', merge: true});
|
||||
equal(editor.getContent(), '<p><strong>abc</strong></p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - span in span same style color', function() {
|
||||
editor.getBody().innerHTML = '<span style="color:#ff0000">ac</strong>';
|
||||
Utils.setSelection('span', 1);
|
||||
editor.execCommand('mceInsertContent', false, {content: '<span style="color:#ff0000">b</span>', merge: true});
|
||||
equal(editor.getContent(), '<p><span style="color: #ff0000;">abc</span></p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - span in span different style color', function() {
|
||||
editor.getBody().innerHTML = '<span style="color:#ff0000">ac</strong>';
|
||||
Utils.setSelection('span', 1);
|
||||
editor.execCommand('mceInsertContent', false, {content: '<span style="color:#00ff00">b</span>', merge: true});
|
||||
equal(editor.getContent(), '<p><span style="color: #ff0000;">a<span style="color: #00ff00;">b</span>c</span></p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - select with option element', function() {
|
||||
editor.getBody().innerHTML = '<p>1</p>';
|
||||
Utils.setSelection('p', 1);
|
||||
editor.execCommand('mceInsertContent', false, '2<select><option selected="selected">3</option></select>');
|
||||
equal(editor.getContent(), '<p>12<select><option selected="selected">3</option></select></p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - insert P in span style element #7090', function() {
|
||||
editor.setContent('<p><span style="color: red">1</span></p><p>3</p>');
|
||||
Utils.setSelection('span', 1);
|
||||
editor.execCommand('mceInsertContent', false, '<p>2</p>');
|
||||
equal(editor.getContent(), '<p><span style="color: red;">1</span></p><p>2</p><p>3</p>');
|
||||
});
|
||||
|
||||
test('mceInsertContent - insert char at char surrounded by spaces', function() {
|
||||
editor.setContent('<p>a b c</p>');
|
||||
Utils.setSelection('p', 2, 'p', 3);
|
||||
editor.execCommand('mceInsertContent', false, 'X');
|
||||
equal(tinymce.util.JSON.serialize(editor.getContent()), '"<p>a X c</p>"');
|
||||
});
|
||||
|
||||
test('InsertHorizontalRule', function() {
|
||||
var rng;
|
||||
|
||||
expect(7);
|
||||
|
||||
editor.setContent('<p>123</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 1);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 2);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('InsertHorizontalRule');
|
||||
equal(editor.getContent(), '<p>1</p><hr /><p>3</p>');
|
||||
rng = Utils.normalizeRng(editor.selection.getRng(true));
|
||||
ok(rng.collapsed);
|
||||
equal(rng.startContainer, editor.getBody().lastChild);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 0);
|
||||
});
|
||||
|
||||
test('Justify - multiple block elements selected - queryCommandState', function() {
|
||||
editor.setContent('<div style="text-align: left;"><div id="a" style="text-align: right;">one</div><div id="b" style="text-align: right;">two</div></div>');
|
||||
Utils.setSelection('#a', 0, '#b', 3);
|
||||
equal(editor.queryCommandState('JustifyLeft'), false);
|
||||
ok(editor.queryCommandState('JustifyRight'));
|
||||
});
|
||||
|
||||
test('Formatting commands (xhtmlTextStyles)', function() {
|
||||
editor.focus();
|
||||
editor.setContent('test 123');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Bold');
|
||||
equal(editor.getContent(), "<p><strong>test 123</strong></p>");
|
||||
|
||||
editor.setContent('test 123');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Italic');
|
||||
equal(editor.getContent(), "<p><em>test 123</em></p>");
|
||||
|
||||
editor.setContent('test 123');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Underline');
|
||||
equal(editor.getContent(), '<p><span style="text-decoration: underline;">test 123</span></p>');
|
||||
|
||||
editor.setContent('test 123');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Strikethrough');
|
||||
equal(editor.getContent(), '<p><span style="text-decoration: line-through;">test 123</span></p>');
|
||||
|
||||
editor.setContent('test 123');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FontName', false, 'Arial');
|
||||
equal(editor.getContent(), '<p><span style="font-family: ' + Utils.fontFace('Arial') + ';">test 123</span></p>');
|
||||
|
||||
editor.setContent('test 123');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FontSize', false, '7');
|
||||
equal(editor.getContent(), '<p><span style="font-size: xx-large;">test 123</span></p>');
|
||||
|
||||
editor.setContent('test 123');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('ForeColor', false, '#FF0000');
|
||||
equal(editor.getContent(), '<p><span style="color: #ff0000;">test 123</span></p>');
|
||||
|
||||
editor.setContent('test 123');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('HiliteColor', false, '#FF0000');
|
||||
equal(editor.getContent(), '<p><span style="background-color: #ff0000;">test 123</span></p>');
|
||||
|
||||
editor.setContent('<p><span style="text-decoration: underline;">test 123</span></p>');
|
||||
equal(editor.getContent(), '<p><span style="text-decoration: underline;">test 123</span></p>');
|
||||
|
||||
editor.setContent('<p><span style="text-decoration: line-through;">test 123</span></p>');
|
||||
equal(editor.getContent(), '<p><span style="text-decoration: line-through;">test 123</span></p>');
|
||||
|
||||
editor.setContent('<p><span style="font-family: Arial;">test 123</span></p>');
|
||||
equal(editor.getContent(), '<p><span style="font-family: Arial;">test 123</span></p>');
|
||||
|
||||
editor.setContent('<p><span style="font-size: xx-large;">test 123</span></p>');
|
||||
equal(editor.getContent(), '<p><span style="font-size: xx-large;">test 123</span></p>');
|
||||
|
||||
editor.setContent('<p><strike>test 123</strike></p>');
|
||||
equal(editor.getContent(), '<p><span style="text-decoration: line-through;">test 123</span></p>');
|
||||
|
||||
editor.setContent('<p><font face="Arial">test 123</font></p>');
|
||||
equal(editor.getContent(), '<p><span style="font-family: ' + Utils.fontFace('Arial') + ';">test 123</span></p>');
|
||||
|
||||
editor.setContent('<p><font size="7">test 123</font></p>');
|
||||
equal(editor.getContent(), '<p><span style="font-size: 300%;">test 123</span></p>');
|
||||
|
||||
editor.setContent('<p><font face="Arial" size="7">test 123</font></p>');
|
||||
equal(editor.getContent(), '<p><span style="font-size: 300%; font-family: ' + Utils.fontFace('Arial') + ';">test 123</span></p>');
|
||||
|
||||
editor.setContent('<font style="background-color: #ff0000" color="#ff0000">test</font><font face="Arial">test</font>');
|
||||
equal(editor.getContent(), '<p><span style="color: #ff0000; background-color: #ff0000;">test</span><span style="font-family: ' + Utils.fontFace('Arial') + ';">test</span></p>');
|
||||
|
||||
editor.setContent('<p><font face="Arial" style="color: #ff0000">test 123</font></p>');
|
||||
equal(editor.getContent(), '<p><span style="color: #ff0000; font-family: ' + Utils.fontFace('Arial') + ';">test 123</span></p>');
|
||||
});
|
||||
|
||||
test('Formatting commands (alignInline)', function() {
|
||||
expect(7);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('JustifyLeft');
|
||||
equal(editor.getContent(), '<p style="text-align: left;">test 123</p>');
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('JustifyCenter');
|
||||
equal(editor.getContent(), '<p style="text-align: center;">test 123</p>');
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('JustifyRight');
|
||||
equal(editor.getContent(), '<p style="text-align: right;">test 123</p>');
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('JustifyFull');
|
||||
equal(editor.getContent(), '<p style="text-align: justify;">test 123</p>');
|
||||
|
||||
editor.setContent('<img src="tinymce/ui/img/raster.gif" />');
|
||||
editor.selection.select(editor.dom.select('img')[0]);
|
||||
editor.execCommand('JustifyLeft');
|
||||
equal(editor.getContent(), '<p><img style="float: left;" src="tinymce/ui/img/raster.gif" /></p>');
|
||||
|
||||
editor.setContent('<img src="tinymce/ui/img/raster.gif" />');
|
||||
editor.selection.select(editor.dom.select('img')[0]);
|
||||
editor.execCommand('JustifyCenter');
|
||||
equal(editor.getContent(), '<p><img style="margin-right: auto; margin-left: auto; display: block;" src="tinymce/ui/img/raster.gif" /></p>');
|
||||
|
||||
editor.setContent('<img src="tinymce/ui/img/raster.gif" />');
|
||||
editor.selection.select(editor.dom.select('img')[0]);
|
||||
editor.execCommand('JustifyRight');
|
||||
equal(editor.getContent(), '<p><img style="float: right;" src="tinymce/ui/img/raster.gif" /></p>');
|
||||
});
|
||||
|
||||
test('mceBlockQuote', function() {
|
||||
expect(2);
|
||||
|
||||
editor.focus();
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceBlockQuote');
|
||||
equal(editor.getContent().replace(/\s+/g, ''), '<blockquote><p>test123</p></blockquote>');
|
||||
|
||||
editor.setContent('<p>test 123</p><p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceBlockQuote');
|
||||
equal(editor.getContent().replace(/\s+/g, ''), '<blockquote><p>test123</p><p>test123</p></blockquote>');
|
||||
});
|
||||
|
||||
test('FormatBlock', function() {
|
||||
expect(9);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h1');
|
||||
equal(editor.getContent(), '<h1>test 123</h1>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h2');
|
||||
equal(editor.getContent(), '<h2>test 123</h2>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h3');
|
||||
equal(editor.getContent(), '<h3>test 123</h3>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h4');
|
||||
equal(editor.getContent(), '<h4>test 123</h4>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h5');
|
||||
equal(editor.getContent(), '<h5>test 123</h5>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h6');
|
||||
equal(editor.getContent(), '<h6>test 123</h6>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
|
||||
try {
|
||||
editor.execCommand('FormatBlock', false, 'div');
|
||||
} catch (ex) {
|
||||
//t.log('Failed: ' + ex.message);
|
||||
}
|
||||
|
||||
equal(editor.getContent(), '<div>test 123</div>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'address');
|
||||
equal(editor.getContent(), '<address>test 123</address>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'pre');
|
||||
equal(editor.getContent(), '<pre>test 123</pre>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (relative)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('test 123');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, 'test');
|
||||
equal(editor.getContent(), '<p><a href="test">test 123</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link absolute)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, 'http://www.site.com');
|
||||
equal(editor.getContent(), '<p><a href="http://www.site.com">test 123</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link encoded)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, '"&<>');
|
||||
equal(editor.getContent(), '<p><a href=""&<>">test 123</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link encoded and with class)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, {href : '"&<>', 'class' : 'test'});
|
||||
equal(editor.getContent(), '<p><a class="test" href=""&<>">test 123</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link with space)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, {href : 'foo bar'});
|
||||
equal(editor.getContent(), '<p><a href="foo%20bar">test 123</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link floated img)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p><img style="float: right;" src="about:blank" /></p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, 'link');
|
||||
equal(editor.getContent(), '<p><a href="link"><img style="float: right;" src="about:blank" /></a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link adjacent text)', function() {
|
||||
var rng;
|
||||
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p><a href="#">a</a>b</p>');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.lastChild, 0);
|
||||
rng.setEnd(editor.getBody().firstChild.lastChild, 1);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
editor.execCommand('mceInsertLink', false, 'link');
|
||||
equal(editor.getContent(), '<p><a href="#">a</a><a href="link">b</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link text inside text)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p><a href="#"><em>abc</em></a></p>');
|
||||
Utils.setSelection('em', 1, 'em', 2);
|
||||
|
||||
editor.execCommand('mceInsertLink', false, 'link');
|
||||
equal(editor.getContent(), '<p><a href="link"><em>abc</em></a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link around existing links)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p><a href="#1">1</a><a href="#2">2</a></p>');
|
||||
editor.execCommand('SelectAll');
|
||||
|
||||
editor.execCommand('mceInsertLink', false, 'link');
|
||||
equal(editor.getContent(), '<p><a href="link">12</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link around existing links with different attrs)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p><a id="a" href="#1">1</a><a id="b" href="#2">2</a></p>');
|
||||
editor.execCommand('SelectAll');
|
||||
|
||||
editor.execCommand('mceInsertLink', false, 'link');
|
||||
equal(editor.getContent(), '<p><a href="link">12</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link around existing complex contents with links)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p><span id="s1"><strong><a id="a" href="#1"><em>1</em></a></strong></span><span id="s2"><em><a id="b" href="#2"><strong>2</strong></a></em></span></p>');
|
||||
editor.execCommand('SelectAll');
|
||||
|
||||
editor.execCommand('mceInsertLink', false, 'link');
|
||||
equal(editor.getContent(), '<p><a href="link"><span id="s1"><strong><em>1</em></strong></span><span id="s2"><em><strong>2</strong></em></span></a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link text inside link)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p><a href="#">test</a></p>');
|
||||
Utils.setSelection('p', 0, 'p', 1);
|
||||
editor.execCommand('SelectAll');
|
||||
|
||||
editor.execCommand('mceInsertLink', false, 'link');
|
||||
equal(editor.getContent(), '<p><a href="link">test</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink bug #7331', function() {
|
||||
editor.setContent('<table><tbody><tr><td>A</td></tr><tr><td>B</td></tr></tbody></table>');
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.$('td')[1].firstChild, 0);
|
||||
rng.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.execCommand('mceInsertLink', false, {href: 'x'});
|
||||
equal(editor.getContent(), '<table><tbody><tr><td>A</td></tr><tr><td><a href=\"x\">B</a></td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test('unlink', function() {
|
||||
editor.setContent('<p><a href="test">test</a> <a href="test">123</a></p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('unlink');
|
||||
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);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('subscript');
|
||||
equal(editor.getContent(), '<p><sub>test 123</sub></p>');
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('superscript');
|
||||
equal(editor.getContent(), '<p><sup>test 123</sup></p>');
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('subscript');
|
||||
editor.execCommand('subscript');
|
||||
equal(editor.getContent(), '<p>test 123</p>');
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('superscript');
|
||||
editor.execCommand('superscript');
|
||||
equal(editor.getContent(), '<p>test 123</p>');
|
||||
});
|
||||
|
||||
test('indent/outdent', function() {
|
||||
expect(4);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Indent');
|
||||
equal(editor.getContent(), '<p style="padding-left: 30px;">test 123</p>');
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Indent');
|
||||
editor.execCommand('Indent');
|
||||
equal(editor.getContent(), '<p style="padding-left: 60px;">test 123</p>');
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Indent');
|
||||
editor.execCommand('Indent');
|
||||
editor.execCommand('Outdent');
|
||||
equal(editor.getContent(), '<p style="padding-left: 30px;">test 123</p>');
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Outdent');
|
||||
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);
|
||||
|
||||
editor.setContent('<p><em>test</em> <strong>123</strong> <a href="123">123</a> 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('RemoveFormat');
|
||||
equal(editor.getContent(), '<p>test 123 <a href="123">123</a> 123</p>');
|
||||
|
||||
editor.setContent('<p><em><em>test</em> <strong>123</strong> <a href="123">123</a> 123</em></p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('RemoveFormat');
|
||||
equal(editor.getContent(), '<p>test 123 <a href="123">123</a> 123</p>');
|
||||
|
||||
editor.setContent('<p><em>test<span id="x">test <strong>123</strong></span><a href="123">123</a> 123</em></p>');
|
||||
editor.selection.select(editor.dom.get('x'));
|
||||
editor.execCommand('RemoveFormat');
|
||||
equal(editor.getContent(), '<p><em>test</em><span id="x">test 123</span><em><a href="123">123</a> 123</em></p>');
|
||||
|
||||
editor.setContent('<p><dfn>dfn tag </dfn> <code>code tag </code> <samp>samp tag</samp> <kbd> kbd tag</kbd> <var> var tag</var> <cite> cite tag</cite> <mark> mark tag</mark> <q> q tag</q></p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('RemoveFormat');
|
||||
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);
|
||||
editor.execCommand('InsertLineBreak');
|
||||
equal(editor.getContent(), '<p>12<br />3</p>');
|
||||
|
||||
editor.setContent('<p>123</p>');
|
||||
Utils.setSelection('p', 0);
|
||||
editor.execCommand('InsertLineBreak');
|
||||
equal(editor.getContent(), '<p><br />123</p>');
|
||||
|
||||
editor.setContent('<p>123</p>');
|
||||
Utils.setSelection('p', 3);
|
||||
editor.execCommand('InsertLineBreak');
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), (tinymce.isIE && tinymce.Env.ie < 11) ? '<p>123<br></p>' : '<p>123<br><br></p>');
|
||||
});
|
||||
@ -1,43 +0,0 @@
|
||||
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');
|
||||
});
|
||||
});
|
||||
@ -1,207 +0,0 @@
|
||||
module("tinymce.EditorManager", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false
|
||||
}).then(function(editors) {
|
||||
window.editor = editors[0];
|
||||
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('Externally destroyed editor', function() {
|
||||
tinymce.remove();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
init_instance_callback: function(editor1) {
|
||||
tinymce.util.Delay.setTimeout(function() {
|
||||
// Destroy the editor by setting innerHTML common ajax pattern
|
||||
document.getElementById('view').innerHTML = '<textarea id="' + editor1.id + '"></textarea>';
|
||||
|
||||
// Re-init the editor will have the same id
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
init_instance_callback: function(editor2) {
|
||||
QUnit.start();
|
||||
|
||||
strictEqual(tinymce.get().length, 1);
|
||||
strictEqual(editor1.id, editor2.id);
|
||||
ok(editor1.destroyed, "First editor instance should be destroyed");
|
||||
}
|
||||
});
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
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() {
|
||||
tinymce.util.Delay.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);
|
||||
textArea.parentNode.removeChild(textArea);
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
|
||||
strictEqual(tinymce.get().length, 2);
|
||||
});
|
||||
|
||||
asyncTest('Init editor async with proper editors state', function() {
|
||||
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() {
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
init_instance_callback: function() {
|
||||
tinymce.util.Delay.setTimeout(function() {
|
||||
QUnit.start();
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
unloadTheme("modern");
|
||||
strictEqual(tinymce.get().length, 0);
|
||||
|
||||
init();
|
||||
strictEqual(tinymce.get().length, 1);
|
||||
|
||||
init();
|
||||
strictEqual(tinymce.get().length, 1);
|
||||
});
|
||||
|
||||
test('overrideDefaults', function() {
|
||||
var oldBaseURI, oldBaseUrl, oldSuffix;
|
||||
|
||||
oldBaseURI = tinymce.baseURI;
|
||||
oldBaseUrl = tinymce.baseURL;
|
||||
oldSuffix = tinymce.suffix;
|
||||
|
||||
tinymce.overrideDefaults({
|
||||
test: 42,
|
||||
base_url: "http://www.tinymce.com/base/",
|
||||
suffix: "x",
|
||||
external_plugins: {
|
||||
"plugina": "//domain/plugina.js",
|
||||
"pluginb": "//domain/pluginb.js"
|
||||
},
|
||||
plugin_base_urls: {
|
||||
testplugin: 'http://custom.ephox.com/dir/testplugin'
|
||||
}
|
||||
});
|
||||
|
||||
strictEqual(tinymce.baseURI.path, "/base");
|
||||
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",
|
||||
"pluginb": "//domain/pluginb.js",
|
||||
"pluginc": "//domain/pluginc.js"
|
||||
});
|
||||
|
||||
deepEqual(new tinymce.Editor('ed3', {}, tinymce).settings.external_plugins, {
|
||||
"plugina": "//domain/plugina.js",
|
||||
"pluginb": "//domain/pluginb.js"
|
||||
});
|
||||
|
||||
tinymce.baseURI = oldBaseURI;
|
||||
tinymce.baseURL = oldBaseUrl;
|
||||
tinymce.suffix = oldSuffix;
|
||||
|
||||
tinymce.overrideDefaults({});
|
||||
});
|
||||
|
||||
test('Init inline editor on invalid targets', function() {
|
||||
var invalidNames;
|
||||
|
||||
invalidNames = (
|
||||
'area base basefont br col frame hr img input isindex link meta param embed source wbr track ' +
|
||||
'colgroup option tbody tfoot thead tr script noscript style textarea video audio iframe object menu'
|
||||
);
|
||||
|
||||
tinymce.remove();
|
||||
|
||||
tinymce.each(invalidNames.split(' '), function (invalidName) {
|
||||
var elm = tinymce.DOM.add(document.body, invalidName, {'class': 'targetEditor'}, null);
|
||||
|
||||
tinymce.init({
|
||||
selector: invalidName + '.targetEditor',
|
||||
inline: true
|
||||
});
|
||||
|
||||
strictEqual(tinymce.get().length, 0, 'Should not have created an editor');
|
||||
tinymce.DOM.remove(elm);
|
||||
});
|
||||
});
|
||||
@ -1,324 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/file/Conversions",
|
||||
"tinymce/Env"
|
||||
], function(Conversions, Env) {
|
||||
var testBlobDataUri;
|
||||
|
||||
if (!tinymce.Env.fileApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
module("tinymce.EditorUpload", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
indent: false,
|
||||
automatic_uploads: false,
|
||||
init_instance_callback: function(ed) {
|
||||
var canvas, context;
|
||||
|
||||
window.editor = ed;
|
||||
|
||||
canvas = document.createElement("canvas");
|
||||
canvas.width = 320;
|
||||
canvas.height = 200;
|
||||
|
||||
context = canvas.getContext("2d");
|
||||
context.fillStyle = "#ff0000";
|
||||
context.fillRect(0, 0, 160, 100);
|
||||
context.fillStyle = "#00ff00";
|
||||
context.fillRect(160, 0, 160, 100);
|
||||
context.fillStyle = "#0000ff";
|
||||
context.fillRect(0, 100, 160, 100);
|
||||
context.fillStyle = "#ff00ff";
|
||||
context.fillRect(160, 100, 160, 100);
|
||||
|
||||
testBlobDataUri = canvas.toDataURL();
|
||||
|
||||
Conversions.uriToBlob(testBlobDataUri).then(function() {
|
||||
QUnit.start();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
editor.editorUpload.destroy();
|
||||
editor.settings.automatic_uploads = false;
|
||||
delete editor.settings.images_replace_blob_uris;
|
||||
delete editor.settings.images_dataimg_filter;
|
||||
}
|
||||
});
|
||||
|
||||
function imageHtml(uri) {
|
||||
return tinymce.DOM.createHTML('img', {src: uri});
|
||||
}
|
||||
|
||||
function assertResult(uploadedBlobInfo, result) {
|
||||
QUnit.strictEqual(result.length, 1);
|
||||
QUnit.strictEqual(result[0].status, true);
|
||||
QUnit.ok(result[0].element.src.indexOf(uploadedBlobInfo.id() + '.png') !== -1);
|
||||
QUnit.equal('<p><img src="' + uploadedBlobInfo.filename() + '" /></p>', editor.getContent());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function hasBlobAsSource(elm) {
|
||||
return elm.src.indexOf('blob:') === 0;
|
||||
}
|
||||
|
||||
asyncTest('_scanForImages', function() {
|
||||
editor.setContent(imageHtml(testBlobDataUri));
|
||||
|
||||
editor._scanForImages().then(function(result) {
|
||||
var blobInfo = result[0].blobInfo;
|
||||
|
||||
QUnit.equal("data:" + blobInfo.blob().type + ";base64," + blobInfo.base64(), testBlobDataUri);
|
||||
QUnit.equal(Utils.normalizeHtml(editor.getBody().innerHTML), '<p><img src="' + blobInfo.blobUri() + '" /></p>');
|
||||
QUnit.equal('<p><img src="data:' + blobInfo.blob().type + ';base64,' + blobInfo.base64() + '" /></p>', editor.getContent());
|
||||
QUnit.strictEqual(editor.editorUpload.blobCache.get(blobInfo.id()), blobInfo);
|
||||
}).then(QUnit.start);
|
||||
});
|
||||
|
||||
asyncTest('replace uploaded blob uri with result uri (copy/paste of an uploaded blob uri)', function() {
|
||||
editor.setContent(imageHtml(testBlobDataUri));
|
||||
|
||||
editor.settings.images_upload_handler = function(data, success) {
|
||||
success('file.png');
|
||||
};
|
||||
|
||||
editor._scanForImages().then(function(result) {
|
||||
var blobUri = result[0].blobInfo.blobUri();
|
||||
|
||||
editor.uploadImages(function() {
|
||||
editor.setContent(imageHtml(blobUri));
|
||||
QUnit.strictEqual(hasBlobAsSource(editor.$('img')[0]), false);
|
||||
QUnit.strictEqual(editor.getContent(), '<p><img src="file.png" /></p>');
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('don\'t replace uploaded blob uri with result uri (copy/paste of an uploaded blob uri) since blob uris are retained', function() {
|
||||
editor.settings.images_replace_blob_uris = false;
|
||||
editor.setContent(imageHtml(testBlobDataUri));
|
||||
|
||||
editor.settings.images_upload_handler = function(data, success) {
|
||||
success('file.png');
|
||||
};
|
||||
|
||||
editor._scanForImages().then(function(result) {
|
||||
var blobUri = result[0].blobInfo.blobUri();
|
||||
|
||||
editor.uploadImages(function() {
|
||||
editor.setContent(imageHtml(blobUri));
|
||||
QUnit.strictEqual(hasBlobAsSource(editor.$('img')[0]), true);
|
||||
QUnit.strictEqual(editor.getContent(), '<p><img src="file.png" /></p>');
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('uploadImages (callback)', function() {
|
||||
var uploadedBlobInfo;
|
||||
|
||||
editor.setContent(imageHtml(testBlobDataUri));
|
||||
|
||||
editor.settings.images_upload_handler = function(data, success) {
|
||||
uploadedBlobInfo = data;
|
||||
success(data.id() + '.png');
|
||||
};
|
||||
|
||||
editor.uploadImages(function(result) {
|
||||
assertResult(uploadedBlobInfo, result);
|
||||
|
||||
editor.uploadImages(function(result) {
|
||||
QUnit.strictEqual(result.length, 0);
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('uploadImages (promise)', function() {
|
||||
var uploadedBlobInfo;
|
||||
|
||||
editor.setContent(imageHtml(testBlobDataUri));
|
||||
|
||||
editor.settings.images_upload_handler = function(data, success) {
|
||||
uploadedBlobInfo = data;
|
||||
success(data.id() + '.png');
|
||||
};
|
||||
|
||||
editor.uploadImages().then(function(result) {
|
||||
assertResult(uploadedBlobInfo, result);
|
||||
}).then(function() {
|
||||
uploadedBlobInfo = null;
|
||||
|
||||
return editor.uploadImages().then(function(result) {
|
||||
QUnit.strictEqual(result.length, 0);
|
||||
QUnit.strictEqual(uploadedBlobInfo, null);
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('uploadImages retain blob urls after upload', function() {
|
||||
var uploadedBlobInfo;
|
||||
|
||||
function assertResult(result) {
|
||||
QUnit.strictEqual(result[0].status, true);
|
||||
QUnit.ok(hasBlobAsSource(result[0].element), 'Not a blob url');
|
||||
QUnit.equal('<p><img src="' + uploadedBlobInfo.filename() + '" /></p>', editor.getContent());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
editor.setContent(imageHtml(testBlobDataUri));
|
||||
|
||||
editor.settings.images_replace_blob_uris = false;
|
||||
editor.settings.images_upload_handler = function(data, success) {
|
||||
uploadedBlobInfo = data;
|
||||
success(data.id() + '.png');
|
||||
};
|
||||
|
||||
editor.uploadImages(assertResult).then(assertResult).then(function() {
|
||||
uploadedBlobInfo = null;
|
||||
|
||||
return editor.uploadImages(function() {}).then(function(result) {
|
||||
QUnit.strictEqual(result.length, 0);
|
||||
QUnit.strictEqual(uploadedBlobInfo, null);
|
||||
});
|
||||
}).then(QUnit.start);
|
||||
});
|
||||
|
||||
asyncTest('uploadConcurrentImages', function() {
|
||||
var uploadCount = 0, callCount = 0;
|
||||
|
||||
function done(result) {
|
||||
callCount++;
|
||||
|
||||
if (callCount == 2) {
|
||||
QUnit.start();
|
||||
equal(uploadCount, 1, 'Should only be one upload.');
|
||||
}
|
||||
|
||||
equal(editor.getContent(), '<p><img src="myimage.png" /></p>');
|
||||
equal(result[0].element, editor.$('img')[0]);
|
||||
equal(result[0].status, true);
|
||||
}
|
||||
|
||||
editor.setContent(imageHtml(testBlobDataUri));
|
||||
|
||||
editor.settings.images_upload_handler = function(data, success) {
|
||||
uploadCount++;
|
||||
|
||||
setTimeout(function() {
|
||||
success('myimage.png');
|
||||
}, 0);
|
||||
};
|
||||
|
||||
editor.uploadImages(done);
|
||||
editor.uploadImages(done);
|
||||
});
|
||||
|
||||
asyncTest('uploadConcurrentImages (fail)', function() {
|
||||
var uploadCount = 0, callCount = 0;
|
||||
|
||||
function done(result) {
|
||||
callCount++;
|
||||
|
||||
if (callCount == 2) {
|
||||
QUnit.start();
|
||||
// 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]);
|
||||
equal(result[0].status, false);
|
||||
}
|
||||
|
||||
editor.setContent(imageHtml(testBlobDataUri));
|
||||
|
||||
editor.settings.images_upload_handler = function(data, success, failure) {
|
||||
uploadCount++;
|
||||
|
||||
setTimeout(function() {
|
||||
failure('Error');
|
||||
}, 0);
|
||||
};
|
||||
|
||||
editor.uploadImages(done);
|
||||
editor.uploadImages(done);
|
||||
});
|
||||
|
||||
asyncTest('Don\'t upload transparent image', function() {
|
||||
var uploadCount = 0;
|
||||
|
||||
function done() {
|
||||
QUnit.start();
|
||||
equal(uploadCount, 0, 'Should not upload.');
|
||||
}
|
||||
|
||||
editor.setContent(imageHtml(Env.transparentSrc));
|
||||
|
||||
editor.settings.images_upload_handler = function(data, success) {
|
||||
uploadCount++;
|
||||
success('url');
|
||||
};
|
||||
|
||||
editor.uploadImages(done);
|
||||
});
|
||||
|
||||
asyncTest('Don\'t upload bogus image', function() {
|
||||
var uploadCount = 0;
|
||||
|
||||
function done() {
|
||||
QUnit.start();
|
||||
equal(uploadCount, 0, 'Should not upload.');
|
||||
}
|
||||
|
||||
editor.getBody().innerHTML = '<img src="' + testBlobDataUri + '" data-mce-bogus="1">';
|
||||
|
||||
editor.settings.images_upload_handler = function(data, success) {
|
||||
uploadCount++;
|
||||
success('url');
|
||||
};
|
||||
|
||||
editor.uploadImages(done);
|
||||
});
|
||||
|
||||
asyncTest('Don\'t upload filtered image', function() {
|
||||
var uploadCount = 0;
|
||||
|
||||
function done() {
|
||||
QUnit.start();
|
||||
equal(uploadCount, 0, 'Should not upload.');
|
||||
}
|
||||
|
||||
editor.getBody().innerHTML = (
|
||||
'<img src="' + testBlobDataUri + '" data-skip="1">'
|
||||
);
|
||||
|
||||
editor.settings.images_dataimg_filter = function(img) {
|
||||
return !img.hasAttribute('data-skip');
|
||||
};
|
||||
|
||||
editor.settings.images_upload_handler = function(data, success) {
|
||||
uploadCount++;
|
||||
success('url');
|
||||
};
|
||||
|
||||
editor.uploadImages(done);
|
||||
});
|
||||
|
||||
test('Retain blobs not in blob cache', function() {
|
||||
editor.getBody().innerHTML = '<img src="blob:http%3A//host/f8d1e462-8646-485f-87c5-f9bcee5873c6">';
|
||||
QUnit.equal('<p><img src="blob:http%3A//host/f8d1e462-8646-485f-87c5-f9bcee5873c6" /></p>', editor.getContent());
|
||||
});
|
||||
});
|
||||
@ -1,55 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/util/I18n",
|
||||
"tinymce/ui/Control"
|
||||
], function(I18n, Control) {
|
||||
var scriptLoadedRtlState = {};
|
||||
|
||||
module("tinymce.Editor_rtl", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.addI18n('ar', {
|
||||
"Bold": "Bold test",
|
||||
"_dir": "rtl"
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
toolbar: 'bold italic underline',
|
||||
setup: function (editor) {
|
||||
var beforeEventRtl = editor.rtl;
|
||||
|
||||
editor.on('ScriptsLoaded', function () {
|
||||
// We will know the rtl mode and code after all scripts have been loaded
|
||||
scriptLoadedRtlState = {
|
||||
beforeRtl: beforeEventRtl,
|
||||
afterRtl: editor.rtl,
|
||||
code: I18n.getCode()
|
||||
};
|
||||
});
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
I18n.rtl = false;
|
||||
I18n.setCode('en');
|
||||
Control.rtl = false;
|
||||
}
|
||||
});
|
||||
|
||||
test('UI rendered in RTL mode', function() {
|
||||
QUnit.equal(tinymce.activeEditor.getContainer().className.indexOf('mce-rtl') !== -1, true, 'Should have a mce-rtl class');
|
||||
QUnit.equal(tinymce.activeEditor.rtl, true, 'Should have the rtl property set');
|
||||
});
|
||||
|
||||
test('Rtl mode property set on editor instance and I18n global', function() {
|
||||
QUnit.equal(scriptLoadedRtlState.beforeRtl, undefined, 'Should be undefined since we dont know the rtl mode yet');
|
||||
QUnit.equal(scriptLoadedRtlState.afterRtl, true, 'Should be true since we now know the rtl mode');
|
||||
QUnit.equal(scriptLoadedRtlState.code, 'ar', 'Should be "ar" since the code hass been changed during loading');
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,46 +0,0 @@
|
||||
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,87 +0,0 @@
|
||||
module("tinymce.ForceBlocks", {
|
||||
autostart: false,
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
indent: false,
|
||||
skin: 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();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
editor.settings.forced_root_block = 'p';
|
||||
editor.settings.forced_root_block_attrs = null;
|
||||
}
|
||||
});
|
||||
|
||||
test('Wrap single root text node in P', function() {
|
||||
editor.getBody().innerHTML = 'abcd';
|
||||
Utils.setSelection('body', 2);
|
||||
Utils.pressArrowKey();
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p>abcd</p>');
|
||||
equal(editor.selection.getNode().nodeName, 'P');
|
||||
});
|
||||
|
||||
test('Wrap single root text node in P with attrs', function() {
|
||||
editor.settings.forced_root_block_attrs = {"class": "class1"};
|
||||
editor.getBody().innerHTML = 'abcd';
|
||||
Utils.setSelection('body', 2);
|
||||
Utils.pressArrowKey();
|
||||
equal(editor.getContent(), '<p class="class1">abcd</p>');
|
||||
equal(editor.selection.getNode().nodeName, 'P');
|
||||
});
|
||||
|
||||
test('Wrap single root text node in P but not table sibling', function() {
|
||||
editor.getBody().innerHTML = 'abcd<table><tr><td>x</td></tr></table>';
|
||||
Utils.setSelection('body', 2);
|
||||
Utils.pressArrowKey();
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p>abcd</p><table><tbody><tr><td>x</td></tr></tbody></table>');
|
||||
equal(editor.selection.getNode().nodeName, 'P');
|
||||
});
|
||||
|
||||
test('Wrap root em in P but not table sibling', function() {
|
||||
editor.getBody().innerHTML = '<em>abcd</em><table><tr><td>x</td></tr></table>';
|
||||
Utils.setSelection('em', 2);
|
||||
Utils.pressArrowKey();
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p><em>abcd</em></p><table><tbody><tr><td>x</td></tr></tbody></table>');
|
||||
equal(editor.selection.getNode().nodeName, 'EM');
|
||||
});
|
||||
|
||||
test('Wrap single root text node in DIV', function() {
|
||||
editor.settings.forced_root_block = 'div';
|
||||
editor.getBody().innerHTML = 'abcd';
|
||||
Utils.setSelection('body', 2);
|
||||
Utils.pressArrowKey();
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<div>abcd</div>');
|
||||
equal(editor.selection.getNode().nodeName, 'DIV');
|
||||
});
|
||||
|
||||
test('Remove empty root text nodes', function() {
|
||||
var body = editor.getBody();
|
||||
|
||||
editor.settings.forced_root_block = 'div';
|
||||
editor.getBody().innerHTML = 'abcd<div>abcd</div>';
|
||||
body.insertBefore(editor.getDoc().createTextNode(''), body.firstChild);
|
||||
body.appendChild(editor.getDoc().createTextNode(''));
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().childNodes[1], 1);
|
||||
rng.setEnd(editor.getBody().childNodes[1], 1);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
Utils.pressArrowKey();
|
||||
equal(Utils.cleanHtml(body.innerHTML), '<div>abcd</div><div>abcd</div>');
|
||||
equal(editor.selection.getNode().nodeName, 'DIV');
|
||||
equal(body.childNodes.length, 2);
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,230 +0,0 @@
|
||||
module("tinymce.Formatter - Check", {
|
||||
setupModule: function() {
|
||||
document.getElementById('view').innerHTML = '<textarea id="elm1"></textarea><div id="elm2"></div>';
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "#elm1",
|
||||
add_unload_trigger: false,
|
||||
extended_valid_elements: 'b,i,span[style|contenteditable]',
|
||||
skin: 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;
|
||||
|
||||
if (window.inlineEditor) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
selector: "#elm2",
|
||||
inline: true,
|
||||
add_unload_trigger: false,
|
||||
indent: false,
|
||||
skin: 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'
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
window.inlineEditor = ed;
|
||||
|
||||
if (window.editor) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('Selected style element text', function() {
|
||||
editor.formatter.register('bold', {inline: 'b'});
|
||||
editor.getBody().innerHTML = '<p><b>1234</b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('b')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('b')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(editor.formatter.match('bold'), 'Selected style element text');
|
||||
});
|
||||
|
||||
test('Selected style element with css styles', function() {
|
||||
editor.formatter.register('color', {inline: 'span', styles: {color: '#ff0000'}});
|
||||
editor.getBody().innerHTML = '<p><span style="color:#ff0000">1234</span></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(editor.formatter.match('color'), 'Selected style element with css styles');
|
||||
});
|
||||
|
||||
test('Selected style element with attributes', function() {
|
||||
editor.formatter.register('fontsize', {inline: 'font', attributes: {size: '7'}});
|
||||
editor.getBody().innerHTML = '<p><font size="7">1234</font></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('font')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('font')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(editor.formatter.match('fontsize'), 'Selected style element with attributes');
|
||||
});
|
||||
|
||||
test('Selected style element text multiple formats', function() {
|
||||
editor.formatter.register('multiple', [
|
||||
{inline: 'b'},
|
||||
{inline: 'strong'}
|
||||
]);
|
||||
editor.getBody().innerHTML = '<p><strong>1234</strong></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('strong')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('strong')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(editor.formatter.match('multiple'), 'Selected style element text multiple formats');
|
||||
});
|
||||
|
||||
test('Selected complex style element', function() {
|
||||
editor.formatter.register('complex', {inline: 'span', styles: {fontWeight: 'bold'}});
|
||||
editor.getBody().innerHTML = '<p><span style="color:#ff0000; font-weight:bold">1234</span></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(editor.formatter.match('complex'), 'Selected complex style element');
|
||||
});
|
||||
|
||||
test('Selected non style element text', function() {
|
||||
editor.formatter.register('bold', {inline: 'b'});
|
||||
editor.getBody().innerHTML = '<p>1234</p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(!editor.formatter.match('bold'), 'Selected non style element text');
|
||||
});
|
||||
|
||||
test('Selected partial style element (start)', function() {
|
||||
editor.formatter.register('bold', {inline: 'b'});
|
||||
editor.getBody().innerHTML = '<p><b>1234</b>5678</p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('b')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('p')[0].lastChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(editor.formatter.match('bold'), 'Selected partial style element (start)');
|
||||
});
|
||||
|
||||
test('Selected partial style element (end)', function() {
|
||||
editor.formatter.register('bold', {inline: 'b'});
|
||||
editor.getBody().innerHTML = '<p>1234<b>5678</b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('b')[0].lastChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(!editor.formatter.match('bold'), 'Selected partial style element (end)');
|
||||
});
|
||||
|
||||
test('Selected element text with parent inline element', function() {
|
||||
editor.formatter.register('bold', {inline: 'b'});
|
||||
editor.getBody().innerHTML = '<p><b><em><span>1234</span></em></b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(editor.formatter.match('bold'), 'Selected element text with parent inline element');
|
||||
});
|
||||
|
||||
test('Selected element match with variable', function() {
|
||||
editor.formatter.register('complex', {inline: 'span', styles: {color: '%color'}});
|
||||
editor.getBody().innerHTML = '<p><span style="color:#ff0000">1234</span></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(editor.formatter.match('complex', {color: '#ff0000'}), 'Selected element match with variable');
|
||||
});
|
||||
|
||||
test('Selected element match with variable and function', function() {
|
||||
editor.formatter.register('complex', {
|
||||
inline: 'span',
|
||||
styles: {
|
||||
color: function(vars) {
|
||||
return vars.color + '00';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
editor.getBody().innerHTML = '<p><span style="color:#ff0000">1234</span></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
ok(editor.formatter.match('complex', {color: '#ff00'}), 'Selected element match with variable and function');
|
||||
});
|
||||
|
||||
test('formatChanged simple format', function() {
|
||||
var newState, newArgs;
|
||||
|
||||
editor.formatter.formatChanged('bold', function(state, args) {
|
||||
newState = state;
|
||||
newArgs = args;
|
||||
});
|
||||
|
||||
editor.getBody().innerHTML = '<p>text</p>';
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
|
||||
// Check apply
|
||||
editor.formatter.apply('bold');
|
||||
editor.nodeChanged();
|
||||
ok(newState);
|
||||
equal(newArgs.format, 'bold');
|
||||
equal(newArgs.node, editor.getBody().firstChild.firstChild);
|
||||
equal(newArgs.parents.length, 2);
|
||||
|
||||
// Check remove
|
||||
editor.formatter.remove('bold');
|
||||
editor.nodeChanged();
|
||||
ok(!newState);
|
||||
equal(newArgs.format, 'bold');
|
||||
equal(newArgs.node, editor.getBody().firstChild);
|
||||
equal(newArgs.parents.length, 1);
|
||||
});
|
||||
|
||||
test('formatChanged complex format', function() {
|
||||
var newState, newArgs;
|
||||
|
||||
editor.formatter.register('complex', {inline: 'span', styles: {color: '%color'}});
|
||||
|
||||
editor.formatter.formatChanged('complex', function(state, args) {
|
||||
newState = state;
|
||||
newArgs = args;
|
||||
}, true);
|
||||
|
||||
editor.getBody().innerHTML = '<p>text</p>';
|
||||
Utils.setSelection('p', 0, 'p', 4);
|
||||
|
||||
// Check apply
|
||||
editor.formatter.apply('complex', {color: '#FF0000'});
|
||||
editor.nodeChanged();
|
||||
ok(newState);
|
||||
equal(newArgs.format, 'complex');
|
||||
equal(newArgs.node, editor.getBody().firstChild.firstChild);
|
||||
equal(newArgs.parents.length, 2);
|
||||
|
||||
// Check remove
|
||||
editor.formatter.remove('complex', {color: '#FF0000'});
|
||||
editor.nodeChanged();
|
||||
ok(!newState);
|
||||
equal(newArgs.format, 'complex');
|
||||
equal(newArgs.node, editor.getBody().firstChild);
|
||||
equal(newArgs.parents.length, 1);
|
||||
});
|
||||
|
||||
test('Match format on div block in inline mode', function() {
|
||||
inlineEditor.setContent('<p>a</p><p>b</p>');
|
||||
inlineEditor.execCommand('SelectAll');
|
||||
ok(!inlineEditor.formatter.match('div'), 'Formatter.match on div says true');
|
||||
});
|
||||
@ -1,415 +0,0 @@
|
||||
module("tinymce.Formatter - Remove", {
|
||||
setupModule: function() {
|
||||
document.getElementById('view').innerHTML = '<textarea id="elm1"></textarea><div id="elm2"></div>';
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
external_plugins: { noneditable: '../../../../tests/qunit/editor/external-plugins/noneditable/plugin.min.js' }, // WP
|
||||
indent: false,
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
extended_valid_elements: 'b,i,span[style|contenteditable]',
|
||||
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'
|
||||
},
|
||||
disable_nodechange: true,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function getContent() {
|
||||
return editor.getContent().toLowerCase().replace(/[\r]+/g, '');
|
||||
}
|
||||
|
||||
test('Inline element on selected text', function() {
|
||||
editor.formatter.register('format', {inline : 'b'});
|
||||
editor.getBody().innerHTML = '<p><b>1234</b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('b')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('b')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p>1234</p>', 'Inline element on selected text');
|
||||
});
|
||||
|
||||
test('Inline element on selected text with remove=all', function() {
|
||||
editor.formatter.register('format', {selector : 'b', remove : 'all'});
|
||||
editor.getBody().innerHTML = '<p><b title="text">1234</b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('b')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('b')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p>1234</p>', 'Inline element on selected text with remove=all');
|
||||
});
|
||||
|
||||
test('Inline element on selected text with remove=none', function() {
|
||||
editor.formatter.register('format', {selector : 'span', styles : {fontWeight : 'bold'}, remove : 'none'});
|
||||
editor.getBody().innerHTML = '<p><span style="font-weight:bold">1234</span></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0], 0);
|
||||
rng.setEnd(editor.dom.select('p')[0], 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p><span>1234</span></p>', 'Inline element on selected text with remove=none');
|
||||
});
|
||||
|
||||
test('Inline element style where element is format root', function() {
|
||||
editor.formatter.register('format', {inline : 'span', styles : {fontWeight : 'bold'}});
|
||||
editor.getBody().innerHTML = '<p><span style="font-weight:bold; color:#FF0000"><em>1234</em></span></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('em')[0].firstChild, 1);
|
||||
rng.setEnd(editor.dom.select('em')[0].firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(),
|
||||
'<p><span style="color: #ff0000; font-weight: bold;">' +
|
||||
'<em>1</em></span><span style="color: #ff0000;"><em>23</em></span>' +
|
||||
'<span style=\"color: #ff0000; font-weight: bold;\"><em>4' +
|
||||
'</em></span></p>',
|
||||
'Inline element style where element is format root');
|
||||
});
|
||||
|
||||
test('Partially selected inline element text', function() {
|
||||
editor.formatter.register('format', {inline : 'b'});
|
||||
editor.getBody().innerHTML = '<p><b>1234</b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('b')[0].firstChild, 2);
|
||||
rng.setEnd(editor.dom.select('b')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p><b>12</b>34</p>', 'Partially selected inline element text');
|
||||
});
|
||||
|
||||
test('Partially selected inline element text with children', function() {
|
||||
editor.formatter.register('format', {inline : 'b'});
|
||||
editor.getBody().innerHTML = '<p><b><em><span>1234</span></em></b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 2);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p><b><em><span>12</span></em></b><em><span>34</span></em></p>', 'Partially selected inline element text with children');
|
||||
});
|
||||
|
||||
test('Partially selected inline element text with complex children', function() {
|
||||
editor.formatter.register('format', {inline : 'span', styles : {fontWeight : 'bold'}});
|
||||
editor.getBody().innerHTML = '<p><span style="font-weight:bold"><em><span style="color:#ff0000;font-weight:bold">1234</span></em></span></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[1].firstChild, 2);
|
||||
rng.setEnd(editor.dom.select('span')[1].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p><span style="font-weight: bold;"><em><span style="color: #ff0000; font-weight: bold;">12</span></em></span><em><span style="color: #ff0000;">34</span></em></p>', 'Partially selected inline element text with complex children');
|
||||
});
|
||||
|
||||
test('Inline elements with exact flag', function() {
|
||||
editor.formatter.register('format', {inline : 'span', styles : {color : '#ff0000'}, exact : true});
|
||||
editor.getBody().innerHTML = '<p><span style="font-size:10px;color:#ff0000">1234</span><span style="font-size:10px;color:#00ff00">1234</span></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0], 0);
|
||||
rng.setEnd(editor.dom.select('p')[0], 2);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p><span style="font-size: 10px;">1234</span><span style="color: #00ff00; font-size: 10px;">1234</span></p>', 'Inline elements with exact flag');
|
||||
});
|
||||
|
||||
test('Inline elements with variables', function() {
|
||||
editor.formatter.register('format', {inline : 'span', styles : {color : '%color'}, exact : true});
|
||||
editor.getBody().innerHTML = '<p><span style="font-size:10px;color:#ff0000">1234</span><span style="font-size:10px;color:#00ff00">1234</span></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0], 0);
|
||||
rng.setEnd(editor.dom.select('p')[0], 2);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format', {color : '#ff0000'});
|
||||
equal(getContent(), '<p><span style="font-size: 10px;">1234</span><span style="color: #00ff00; font-size: 10px;">1234</span></p>', 'Inline elements on selected text with variables');
|
||||
});
|
||||
|
||||
test('Inline elements with functions and variables', function() {
|
||||
editor.formatter.register('format', {
|
||||
inline : 'span',
|
||||
styles : {
|
||||
color : function(vars) {
|
||||
return vars.color + "00";
|
||||
}
|
||||
},
|
||||
exact : true
|
||||
});
|
||||
|
||||
editor.getBody().innerHTML = '<p><span style="font-size:10px;color:#ff0000">1234</span><span style="font-size:10px;color:#00ff00">1234</span></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0], 0);
|
||||
rng.setEnd(editor.dom.select('p')[0], 2);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format', {
|
||||
color : '#ff00'
|
||||
});
|
||||
equal(getContent(), '<p><span style="font-size: 10px;">1234</span><span style="color: #00ff00; font-size: 10px;">1234</span></p>', 'Inline elements with functions and variables');
|
||||
});
|
||||
|
||||
test('End within start element', function() {
|
||||
editor.formatter.register('format', {inline : 'b'});
|
||||
editor.getBody().innerHTML = '<p><b>1234<b>5678</b></b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0], 0);
|
||||
rng.setEnd(editor.dom.select('b')[0], 2);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p>12345678</p>', 'End within start element');
|
||||
});
|
||||
|
||||
test('Start and end within similar format 1', function() {
|
||||
editor.formatter.register('format', {inline : 'b'});
|
||||
editor.getBody().innerHTML = '<p><b><em><b>1234<b>5678</b></b></em></b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('em')[0], 0);
|
||||
rng.setEnd(editor.dom.select('b')[1], 2);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p><em>12345678</em></p>', 'Start and end within similar format 1');
|
||||
});
|
||||
|
||||
test('Start and end within similar format 2', function() {
|
||||
editor.formatter.register('format', {inline : 'b'});
|
||||
editor.getBody().innerHTML = '<p><b><em><b>1234</b><b>5678</b></em></b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('em')[0], 0);
|
||||
rng.setEnd(editor.dom.select('em')[0], 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p><em>1234</em><b><em><b>5678</b></em></b></p>', 'Start and end within similar format 2');
|
||||
});
|
||||
|
||||
test('Start and end within similar format 3', function() {
|
||||
editor.formatter.register('format', {inline : 'b'});
|
||||
editor.getBody().innerHTML = '<p><b><em><b>1234</b></em></b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('em')[0], 0);
|
||||
rng.setEnd(editor.dom.select('em')[0], 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p><em>1234</em></p>', 'Start and end within similar format 3');
|
||||
});
|
||||
|
||||
test('End within start', function() {
|
||||
editor.formatter.register('format', {inline : 'b'});
|
||||
editor.getBody().innerHTML = '<p><b><em>x<b>abc</b>y</em></b></p>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0], 0);
|
||||
rng.setEnd(editor.dom.select('b')[1].firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p><em>x</em><em>abc</em><b><em>y</em></b></p>', 'End within start');
|
||||
});
|
||||
|
||||
test('Remove block format', function() {
|
||||
editor.formatter.register('format', {block : 'h1'});
|
||||
editor.getBody().innerHTML = '<h1>text</h1>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('h1')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('h1')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p>text</p>', 'Remove block format');
|
||||
});
|
||||
|
||||
test('Remove wrapper block format', function() {
|
||||
editor.formatter.register('format', {block : 'blockquote', wrapper : true});
|
||||
editor.getBody().innerHTML = '<blockquote><p>text</p></blockquote>';
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p>text</p>', 'Remove wrapper block format');
|
||||
});
|
||||
|
||||
test('Remove span format within block with style', function() {
|
||||
editor.formatter.register('format', {selector : 'span', attributes : ['style', 'class'], remove : 'empty', split : true, expand : false, deep : true});
|
||||
var rng = editor.dom.createRng();
|
||||
editor.getBody().innerHTML = '<p style="color:#ff0000"><span style="color:#00ff00">text</span></p>';
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 1);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p style="color: #ff0000;"><span style="color: #00ff00;">t</span>ex<span style="color: #00ff00;">t</span></p>', 'Remove span format within block with style');
|
||||
});
|
||||
|
||||
test('Remove and verify start element', function() {
|
||||
editor.formatter.register('format', {inline : 'b'});
|
||||
var rng = editor.dom.createRng();
|
||||
editor.getBody().innerHTML = '<p><b>text</b></p>';
|
||||
rng.setStart(editor.dom.select('b')[0].firstChild, 1);
|
||||
rng.setEnd(editor.dom.select('b')[0].firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), '<p><b>t</b>ex<b>t</b></p>');
|
||||
equal(editor.selection.getStart().nodeName, 'P');
|
||||
});
|
||||
|
||||
test('Remove with selection collapsed ensure correct caret position', function() {
|
||||
var content = '<p>test</p><p>testing</p>';
|
||||
|
||||
editor.formatter.register('format', {block : 'p'});
|
||||
var rng = editor.dom.createRng();
|
||||
editor.getBody().innerHTML = content;
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 4);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(getContent(), content);
|
||||
equal(editor.selection.getStart(), editor.dom.select('p')[0]);
|
||||
});
|
||||
|
||||
test('Caret format at middle of text', function() {
|
||||
editor.setContent('<p><b>abc</b></p>');
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
Utils.setSelection('b', 1, 'b', 1);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p>abc</p>');
|
||||
});
|
||||
|
||||
test('Caret format at end of text', function() {
|
||||
editor.setContent('<p><b>abc</b></p>');
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
Utils.setSelection('b', 3, 'b', 3);
|
||||
editor.formatter.remove('format');
|
||||
Utils.type('d');
|
||||
equal(editor.getContent(), '<p><b>abc</b>d</p>');
|
||||
});
|
||||
|
||||
test('Caret format at end of text inside other format', function() {
|
||||
editor.setContent('<p><em><b>abc</b></em></p>');
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
Utils.setSelection('b', 3, 'b', 3);
|
||||
editor.formatter.remove('format');
|
||||
Utils.type('d');
|
||||
equal(editor.getContent(), '<p><em><b>abc</b>d</em></p>');
|
||||
});
|
||||
|
||||
test('Caret format at end of text inside other format with text after 1', function() {
|
||||
editor.setContent('<p><em><b>abc</b></em>e</p>');
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
Utils.setSelection('b', 3, 'b', 3);
|
||||
editor.formatter.remove('format');
|
||||
Utils.type('d');
|
||||
equal(editor.getContent(), '<p><em><b>abc</b>d</em>e</p>');
|
||||
});
|
||||
|
||||
test('Caret format at end of text inside other format with text after 2', function() {
|
||||
editor.setContent('<p><em><b>abc</b></em>e</p>');
|
||||
editor.formatter.register('format', {inline: 'em'});
|
||||
Utils.setSelection('b', 3, 'b', 3);
|
||||
editor.formatter.remove('format');
|
||||
Utils.type('d');
|
||||
equal(editor.getContent(), '<p><em><b>abc</b></em><b>d</b>e</p>');
|
||||
});
|
||||
|
||||
test('Toggle styles at the end of the content don\' removes the format where it is not needed.', function() {
|
||||
editor.setContent('<p><em><b>abce</b></em></p>');
|
||||
editor.formatter.register('b', {inline: 'b'});
|
||||
editor.formatter.register('em', {inline: 'em'});
|
||||
Utils.setSelection('b', 4, 'b', 4);
|
||||
editor.formatter.remove('b');
|
||||
editor.formatter.remove('em');
|
||||
equal(editor.getContent(), '<p><em><b>abce</b></em></p>');
|
||||
});
|
||||
|
||||
test('Caret format on second word in table cell', function() {
|
||||
editor.setContent('<table><tbody><tr><td>one <b>two</b></td></tr></tbody></table>');
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
Utils.setSelection('b', 2, 'b', 2);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<table><tbody><tr><td>one two</td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test('contentEditable: false on start and contentEditable: true on end', function() {
|
||||
if (tinymce.Env.ie) {
|
||||
ok("Skipped since IE doesn't support selection of parts of a cE=false element", true);
|
||||
return;
|
||||
}
|
||||
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
editor.setContent('<p>abc</p><p contenteditable="false"><b>def</b></p><p><b>ghj</b></p>');
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('b')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('b')[1].firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p>abc</p><p contenteditable="false"><b>def</b></p><p>ghj</p>', 'Text in last paragraph is not bold');
|
||||
});
|
||||
|
||||
test('contentEditable: true on start and contentEditable: false on end', function() {
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
editor.setContent('<p>abc</p><p><b>def</b></p><p contenteditable="false"><b>ghj</b></p>');
|
||||
Utils.setSelection('p:nth-child(2) b', 0, 'p:last b', 3);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p>abc</p><p>def</p><p contenteditable="false"><b>ghj</b></p>', 'Text in first paragraph is not bold');
|
||||
});
|
||||
|
||||
test('contentEditable: true inside contentEditable: false', function() {
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
editor.setContent('<p>abc</p><p contenteditable="false"><span contenteditable="true"><b>def</b></span></p>');
|
||||
Utils.setSelection('b', 0, 'b', 3);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p>abc</p><p contenteditable="false"><span contenteditable="true">def</span></p>', 'Text is not bold');
|
||||
});
|
||||
|
||||
test('remove format block on contentEditable: false block', function() {
|
||||
editor.formatter.register('format', {block: 'h1'});
|
||||
editor.setContent('<p>abc</p><h1 contenteditable="false">def</h1>');
|
||||
Utils.setSelection('h1:nth-child(2)', 0, 'h1:nth-child(2)', 3);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p>abc</p><h1 contenteditable="false">def</h1>', 'H1 is still not h1');
|
||||
});
|
||||
|
||||
test('remove format on del using removeformat format', function() {
|
||||
editor.getBody().innerHTML = '<p><del>abc</del></p>';
|
||||
Utils.setSelection('del', 0, 'del', 3);
|
||||
editor.formatter.remove('removeformat');
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p>abc</p>');
|
||||
});
|
||||
|
||||
test('remove format on span with class using removeformat format', function() {
|
||||
editor.getBody().innerHTML = '<p><span class="x">abc</span></p>';
|
||||
Utils.setSelection('span', 0, 'span', 3);
|
||||
editor.formatter.remove('removeformat');
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p>abc</p>');
|
||||
});
|
||||
|
||||
test('remove format on span with internal class using removeformat format', function() {
|
||||
editor.getBody().innerHTML = '<p><span class="mce-item-internal">abc</span></p>';
|
||||
Utils.setSelection('span', 0, 'span', 3);
|
||||
editor.formatter.remove('removeformat');
|
||||
equal(Utils.normalizeHtml(Utils.cleanHtml(editor.getBody().innerHTML)), '<p><span class="mce-item-internal">abc</span></p>');
|
||||
});
|
||||
|
||||
test('Remove format bug 1', function() {
|
||||
editor.setContent('<p><b><i>ab</i>c</b></p>');
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
Utils.setSelection('i', 1, 'i', 2);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p><b><i>a</i></b><i>b</i><b>c</b></p>');
|
||||
});
|
||||
|
||||
test('Remove format bug 2', function() {
|
||||
editor.setContent('<p>ab<b>c</b></p>');
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
Utils.setSelection('b', 0, 'b', 1);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p>abc</p>');
|
||||
});
|
||||
|
||||
test('Remove format bug 3', function() {
|
||||
editor.setContent('<p><b><i>ab</i></b></p>');
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
Utils.setSelection('i', 1, 'i', 2);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p><b><i>a</i></b><i>b</i></p>');
|
||||
});
|
||||
@ -1,110 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/InsertContent"
|
||||
], function(InsertContent) {
|
||||
module("tinymce.InsertContent", {
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function assertSelection(selector, offset) {
|
||||
var node = editor.$(selector)[0];
|
||||
var rng = editor.selection.getRng();
|
||||
|
||||
equal(rng.startContainer, node.firstChild);
|
||||
equal(rng.startOffset, offset);
|
||||
equal(rng.collapsed, true);
|
||||
}
|
||||
|
||||
test('insertAtCaret - i inside text, converts to em', function() {
|
||||
editor.setContent('<p>1234</p>');
|
||||
editor.focus();
|
||||
Utils.setSelection('p', 2);
|
||||
InsertContent.insertAtCaret(editor, '<i>a</i>');
|
||||
equal(editor.getContent(), '<p>12<em>a</em>34</p>');
|
||||
});
|
||||
|
||||
test('insertAtCaret - ul at beginning of li', function() {
|
||||
editor.setContent('<ul><li>12</li></ul>');
|
||||
editor.focus();
|
||||
Utils.setSelection('li', 0);
|
||||
InsertContent.insertAtCaret(editor, {content: '<ul><li>a</li></ul>', paste: true});
|
||||
equal(editor.getContent(), '<ul><li>a</li><li>12</li></ul>');
|
||||
assertSelection('li:nth-child(2)', 0);
|
||||
});
|
||||
|
||||
test('insertAtCaret - ul with multiple items at beginning of li', function() {
|
||||
editor.setContent('<ul><li>12</li></ul>');
|
||||
editor.focus();
|
||||
Utils.setSelection('li', 0);
|
||||
InsertContent.insertAtCaret(editor, {content: '<ul><li>a</li><li>b</li></ul>', paste: true});
|
||||
equal(editor.getContent(), '<ul><li>a</li><li>b</li><li>12</li></ul>');
|
||||
assertSelection('li:nth-child(3)', 0);
|
||||
});
|
||||
|
||||
test('insertAtCaret - ul at end of li', function() {
|
||||
editor.setContent('<ul><li>12</li></ul>');
|
||||
editor.focus();
|
||||
Utils.setSelection('li', 2);
|
||||
InsertContent.insertAtCaret(editor, {content: '<ul><li>a</li></ul>', paste: true});
|
||||
equal(editor.getContent(), '<ul><li>12</li><li>a</li></ul>');
|
||||
assertSelection('li:nth-child(2)', 1);
|
||||
});
|
||||
|
||||
test('insertAtCaret - ul with multiple items at end of li', function() {
|
||||
editor.setContent('<ul><li>12</li></ul>');
|
||||
editor.focus();
|
||||
Utils.setSelection('li', 2);
|
||||
InsertContent.insertAtCaret(editor, {content: '<ul><li>a</li><li>b</li><li>c</li></ul>', paste: true});
|
||||
equal(editor.getContent(), '<ul><li>12</li><li>a</li><li>b</li><li>c</li></ul>');
|
||||
assertSelection('li:nth-child(4)', 1);
|
||||
});
|
||||
|
||||
test('insertAtCaret - ul with multiple items in middle of li', function() {
|
||||
editor.setContent('<ul><li>12</li></ul>');
|
||||
editor.focus();
|
||||
Utils.setSelection('li', 1);
|
||||
InsertContent.insertAtCaret(editor, {content: '<ul><li>a</li><li>b</li></ul>', paste: true});
|
||||
equal(editor.getContent(), '<ul><li>1</li><li>a</li><li>b</li><li>2</li></ul>');
|
||||
assertSelection('li:nth-child(4)', 1);
|
||||
});
|
||||
|
||||
test('insertAtCaret - ul in middle of li with formatting', function() {
|
||||
editor.setContent('<ul><li><em><strong>12</strong></em></li></ul>');
|
||||
editor.focus();
|
||||
Utils.setSelection('strong', 1);
|
||||
InsertContent.insertAtCaret(editor, {content: '<ul><li>a</li></ul>', paste: true});
|
||||
equal(editor.getContent(), '<ul><li><em><strong>1</strong></em></li><li>a</li><li><em><strong>2</strong></em></li></ul>');
|
||||
assertSelection('li:nth-child(3) strong', 1);
|
||||
});
|
||||
|
||||
test('insertAtCaret - ul at beginning of li with empty end li', function() {
|
||||
editor.setContent('<ul><li>12</li></ul>');
|
||||
editor.focus();
|
||||
Utils.setSelection('li', 0);
|
||||
InsertContent.insertAtCaret(editor, {content: '<ul><li>a</li><li></li></ul>', paste: true});
|
||||
equal(editor.getContent(), '<ul><li>a</li><li>12</li></ul>');
|
||||
assertSelection('li:nth-child(2)', 0);
|
||||
});
|
||||
|
||||
test('insertAtCaret - merge inline elements', function() {
|
||||
editor.setContent('<strong><em>abc</em></strong>');
|
||||
editor.focus();
|
||||
Utils.setSelection('em', 1);
|
||||
InsertContent.insertAtCaret(editor, {content: '<em><strong>123</strong></em>', merge: true});
|
||||
equal(editor.getContent(), '<p><strong><em>a123bc</em></strong></p>');
|
||||
});
|
||||
});
|
||||
@ -1,47 +0,0 @@
|
||||
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>');
|
||||
});
|
||||
});
|
||||
@ -1,41 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/InsertList",
|
||||
"tinymce/html/Node",
|
||||
"tinymce/html/DomParser",
|
||||
"tinymce/dom/DOMUtils"
|
||||
], function(InsertList, Node, DomParser, DOMUtils) {
|
||||
module("tinymce.InsertList", {});
|
||||
|
||||
var createFragment = function(html) {
|
||||
var parser = new DomParser({validate: false});
|
||||
var fragment = parser.parse(html);
|
||||
|
||||
return fragment;
|
||||
};
|
||||
|
||||
var createDomFragment = function(html) {
|
||||
return DOMUtils.DOM.createFragment(html);
|
||||
};
|
||||
|
||||
test('isListFragment', function() {
|
||||
equal(InsertList.isListFragment(createFragment('<ul><li>x</li></ul>')), true);
|
||||
equal(InsertList.isListFragment(createFragment('<ol><li>x</li></ol>')), true);
|
||||
equal(InsertList.isListFragment(createFragment('<meta><ul><li>x</li></ul>')), true);
|
||||
equal(InsertList.isListFragment(createFragment('<ul><li>x</li></ul><span id="mce_marker"></span>')), true);
|
||||
equal(InsertList.isListFragment(createFragment('<div></div>')), false);
|
||||
});
|
||||
|
||||
test('listItems', function() {
|
||||
var list = createDomFragment('<ul><li>a</li><li>b</li><li>c</li></ul>').firstChild;
|
||||
|
||||
equal(InsertList.listItems(list).length, 3);
|
||||
equal(InsertList.listItems(list)[0].nodeName, 'LI');
|
||||
});
|
||||
|
||||
test('trimListItems', function() {
|
||||
var list = createDomFragment('<ul><li>a</li><li>b</li><li></li></ul>').firstChild;
|
||||
|
||||
equal(InsertList.listItems(list).length, 3);
|
||||
equal(InsertList.trimListItems(InsertList.listItems(list)).length, 2);
|
||||
});
|
||||
});
|
||||
@ -1,109 +0,0 @@
|
||||
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.');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@ -1,357 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/caret/CaretPosition",
|
||||
"tinymce/caret/CaretContainer",
|
||||
"tinymce/util/VK",
|
||||
"tinymce/text/Zwsp"
|
||||
], function(CaretPosition, CaretContainer, VK, Zwsp) {
|
||||
module("tinymce.SelectionOverrides", {
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function pressKey(key) {
|
||||
return function() {
|
||||
Utils.pressKey({keyCode: key});
|
||||
};
|
||||
}
|
||||
|
||||
function exitPreTest(arrow, offset, expectedContent) {
|
||||
return function() {
|
||||
editor.setContent('<pre>abc</pre>');
|
||||
|
||||
Utils.setSelection('pre', 1);
|
||||
arrow();
|
||||
equal(editor.getContent(), '<pre>abc</pre>');
|
||||
equal(editor.selection.getNode().nodeName, 'PRE');
|
||||
|
||||
Utils.setSelection('pre', offset);
|
||||
arrow();
|
||||
equal(editor.getContent(), expectedContent);
|
||||
equal(editor.selection.getNode().nodeName, 'P');
|
||||
};
|
||||
}
|
||||
|
||||
function assertCaretInCaretBlockContainer() {
|
||||
var beforeRng = editor.selection.getRng();
|
||||
equal(CaretContainer.isCaretContainerBlock(beforeRng.startContainer), true, 'Not in caret block container.');
|
||||
}
|
||||
|
||||
var leftArrow = pressKey(VK.LEFT);
|
||||
var rightArrow = pressKey(VK.RIGHT);
|
||||
var backspace = pressKey(VK.BACKSPACE);
|
||||
var forwardDelete = pressKey(VK.DELETE);
|
||||
var upArrow = pressKey(VK.UP);
|
||||
var downArrow = pressKey(VK.DOWN);
|
||||
|
||||
test('left/right over cE=false inline', function() {
|
||||
editor.setContent('<span contenteditable="false">1</span>');
|
||||
editor.selection.select(editor.$('span')[0]);
|
||||
|
||||
leftArrow();
|
||||
equal(editor.getContent(), '<p><span contenteditable="false">1</span></p>');
|
||||
equal(CaretContainer.isCaretContainerInline(editor.selection.getRng().startContainer), true);
|
||||
equal(editor.selection.getRng().startContainer, editor.$('p')[0].firstChild);
|
||||
|
||||
rightArrow();
|
||||
equal(editor.getContent(), '<p><span contenteditable="false">1</span></p>');
|
||||
equal(editor.selection.getNode(), editor.$('span')[0]);
|
||||
|
||||
rightArrow();
|
||||
equal(editor.getContent(), '<p><span contenteditable="false">1</span></p>');
|
||||
equal(CaretContainer.isCaretContainerInline(editor.selection.getRng().startContainer), true);
|
||||
equal(editor.selection.getRng().startContainer, editor.$('p')[0].lastChild);
|
||||
});
|
||||
|
||||
test('left/right over cE=false block', function() {
|
||||
editor.setContent('<p contenteditable="false">1</p>');
|
||||
editor.selection.select(editor.$('p')[0]);
|
||||
|
||||
leftArrow();
|
||||
equal(editor.getContent(), '<p contenteditable="false">1</p>');
|
||||
equal(CaretContainer.isCaretContainerBlock(editor.selection.getRng().startContainer), true);
|
||||
|
||||
rightArrow();
|
||||
equal(editor.getContent(), '<p contenteditable="false">1</p>');
|
||||
equal(editor.selection.getNode(), editor.$('p')[0]);
|
||||
|
||||
rightArrow();
|
||||
equal(editor.getContent(), '<p contenteditable="false">1</p>');
|
||||
equal(CaretContainer.isCaretContainerBlock(editor.selection.getRng().startContainer), true);
|
||||
});
|
||||
|
||||
test('left before cE=false block and type', function() {
|
||||
editor.setContent('<p contenteditable="false">1</p>');
|
||||
editor.selection.select(editor.$('p')[0]);
|
||||
|
||||
leftArrow();
|
||||
Utils.type('a');
|
||||
equal(editor.getContent(), '<p>a</p><p contenteditable="false">1</p>');
|
||||
equal(CaretContainer.isCaretContainerBlock(editor.selection.getRng().startContainer.parentNode), false);
|
||||
});
|
||||
|
||||
test('right after cE=false block and type', function() {
|
||||
editor.setContent('<p contenteditable="false">1</p>');
|
||||
editor.selection.select(editor.$('p')[0]);
|
||||
|
||||
rightArrow();
|
||||
Utils.type('a');
|
||||
equal(editor.getContent(), '<p contenteditable="false">1</p><p>a</p>');
|
||||
equal(CaretContainer.isCaretContainerBlock(editor.selection.getRng().startContainer.parentNode), false);
|
||||
});
|
||||
|
||||
test('up from P to inline cE=false', function() {
|
||||
editor.setContent('<p>a<span contentEditable="false">1</span></p><p>abc</p>');
|
||||
Utils.setSelection('p:last', 3);
|
||||
|
||||
upArrow();
|
||||
equal(CaretContainer.isCaretContainerInline(editor.$('p:first')[0].lastChild), true);
|
||||
});
|
||||
|
||||
test('down from P to inline cE=false', function() {
|
||||
editor.setContent('<p>abc</p><p>a<span contentEditable="false">1</span></p>');
|
||||
Utils.setSelection('p:first', 3);
|
||||
|
||||
downArrow();
|
||||
equal(CaretContainer.isCaretContainerInline(editor.$('p:last')[0].lastChild), true);
|
||||
});
|
||||
|
||||
test('backspace on selected cE=false block', function() {
|
||||
editor.setContent('<p contenteditable="false">1</p>');
|
||||
editor.selection.select(editor.$('p')[0]);
|
||||
|
||||
backspace();
|
||||
equal(editor.getContent(), '');
|
||||
equal(editor.selection.getRng().startContainer, editor.$('p')[0]);
|
||||
});
|
||||
|
||||
test('backspace after cE=false block', function() {
|
||||
editor.setContent('<p contenteditable="false">1</p>');
|
||||
editor.selection.select(editor.$('p')[0]);
|
||||
|
||||
rightArrow();
|
||||
backspace();
|
||||
equal(editor.getContent(), '');
|
||||
equal(editor.selection.getRng().startContainer, editor.$('p')[0]);
|
||||
});
|
||||
|
||||
test('delete on selected cE=false block', function() {
|
||||
editor.setContent('<p contenteditable="false">1</p>');
|
||||
editor.selection.select(editor.$('p')[0]);
|
||||
|
||||
forwardDelete();
|
||||
equal(editor.getContent(), '');
|
||||
equal(editor.selection.getRng().startContainer, editor.$('p')[0]);
|
||||
});
|
||||
|
||||
test('delete inside nested cE=true block element', function() {
|
||||
editor.setContent('<div contenteditable="false">1<div contenteditable="true">2</div>3</div>');
|
||||
Utils.setSelection('div div', 1);
|
||||
|
||||
Utils.type('\b');
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<div contenteditable="false">1<div contenteditable="true"><br data-mce-bogus="1"></div>3</div>');
|
||||
equal(editor.selection.getRng().startContainer, editor.$('div div')[0]);
|
||||
});
|
||||
|
||||
test('backspace from block to after cE=false inline', function() {
|
||||
editor.setContent('<p>1<span contenteditable="false">2</span></p><p>3</p>');
|
||||
Utils.setSelection('p:nth-child(2)', 0);
|
||||
|
||||
Utils.type('\b');
|
||||
equal(editor.getContent(), '<p>1<span contenteditable="false">2</span>3</p>');
|
||||
ok(Zwsp.isZwsp(editor.selection.getRng().startContainer.data));
|
||||
equal(editor.selection.getRng().startContainer.previousSibling.nodeName, 'SPAN');
|
||||
});
|
||||
|
||||
test('delete from block to before cE=false inline', function() {
|
||||
editor.setContent('<p>1</p><p><span contenteditable="false">2</span>3</p>');
|
||||
Utils.setSelection('p:nth-child(1)', 1);
|
||||
|
||||
forwardDelete();
|
||||
equal(editor.getContent(), '<p>1<span contenteditable="false">2</span>3</p>');
|
||||
ok(Zwsp.isZwsp(editor.selection.getRng().startContainer.data));
|
||||
equal(editor.selection.getRng().startContainer.nextSibling.nodeName, 'SPAN');
|
||||
});
|
||||
|
||||
test('backspace from before cE=false block to text', function() {
|
||||
editor.setContent('<p>1</p><p contenteditable="false">2</p><p>3</p>');
|
||||
editor.selection.select(editor.dom.select('p')[1]);
|
||||
editor.selection.collapse(true);
|
||||
assertCaretInCaretBlockContainer();
|
||||
|
||||
Utils.type('\b');
|
||||
var rng = editor.selection.getRng();
|
||||
|
||||
equal(editor.getContent(), '<p>1</p><p contenteditable="false">2</p><p>3</p>');
|
||||
equal(rng.startContainer, editor.dom.select('p')[0].firstChild);
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.collapsed, true);
|
||||
});
|
||||
|
||||
test('backspace from before first cE=false block', function() {
|
||||
editor.setContent('<p contenteditable="false">1</p><p>2</p>');
|
||||
editor.selection.select(editor.dom.select('p')[0]);
|
||||
editor.selection.collapse(true);
|
||||
assertCaretInCaretBlockContainer();
|
||||
|
||||
Utils.type('\b');
|
||||
|
||||
equal(editor.getContent(), '<p contenteditable="false">1</p><p>2</p>');
|
||||
assertCaretInCaretBlockContainer();
|
||||
});
|
||||
|
||||
test('backspace from before cE=false block to after cE=false block', function() {
|
||||
editor.setContent('<p contenteditable="false">1</p><p contenteditable="false">2</p>');
|
||||
editor.selection.select(editor.dom.select('p')[1]);
|
||||
editor.selection.collapse(true);
|
||||
assertCaretInCaretBlockContainer();
|
||||
|
||||
Utils.type('\b');
|
||||
var rng = editor.selection.getRng();
|
||||
|
||||
equal(editor.getContent(), '<p contenteditable="false">1</p><p contenteditable="false">2</p>');
|
||||
assertCaretInCaretBlockContainer();
|
||||
equal(rng.startContainer.previousSibling, editor.dom.select('p')[0]);
|
||||
});
|
||||
|
||||
test('delete from after cE=false block to text', function() {
|
||||
editor.setContent('<p>1</p><p contenteditable="false">2</p><p>3</p>');
|
||||
editor.selection.select(editor.dom.select('p')[1]);
|
||||
editor.selection.collapse(false);
|
||||
assertCaretInCaretBlockContainer();
|
||||
|
||||
forwardDelete();
|
||||
var rng = editor.selection.getRng();
|
||||
|
||||
equal(editor.getContent(), '<p>1</p><p contenteditable="false">2</p><p>3</p>');
|
||||
equal(rng.startContainer, editor.dom.select('p')[2].firstChild);
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.collapsed, true);
|
||||
});
|
||||
|
||||
test('delete from after last cE=false block', function() {
|
||||
editor.setContent('<p>1</p><p contenteditable="false">2</p>');
|
||||
editor.selection.select(editor.dom.select('p')[1]);
|
||||
editor.selection.collapse(false);
|
||||
assertCaretInCaretBlockContainer();
|
||||
forwardDelete();
|
||||
equal(editor.getContent(), '<p>1</p><p contenteditable="false">2</p>');
|
||||
assertCaretInCaretBlockContainer();
|
||||
});
|
||||
|
||||
test('delete from after cE=false block to before cE=false block', function() {
|
||||
editor.setContent('<p contenteditable="false">1</p><p contenteditable="false">2</p>');
|
||||
editor.selection.select(editor.dom.select('p')[0]);
|
||||
rightArrow();
|
||||
assertCaretInCaretBlockContainer();
|
||||
|
||||
forwardDelete();
|
||||
var rng = editor.selection.getRng();
|
||||
|
||||
equal(editor.getContent(), '<p contenteditable="false">1</p><p contenteditable="false">2</p>');
|
||||
assertCaretInCaretBlockContainer();
|
||||
equal(rng.startContainer.nextSibling, editor.dom.select('p')[2]);
|
||||
});
|
||||
|
||||
test('delete from block to before cE=false inline', function() {
|
||||
editor.setContent('<p>1</p><p><span contenteditable="false">2</span>3</p>');
|
||||
Utils.setSelection('p:nth-child(1)', 1);
|
||||
|
||||
forwardDelete();
|
||||
equal(editor.getContent(), '<p>1<span contenteditable="false">2</span>3</p>');
|
||||
ok(Zwsp.isZwsp(editor.selection.getRng().startContainer.data));
|
||||
equal(editor.selection.getRng().startContainer.nextSibling.nodeName, 'SPAN');
|
||||
});
|
||||
|
||||
test('backspace from empty block to after cE=false', function() {
|
||||
editor.getBody().innerHTML = '<p contenteditable="false">1</p><p><br></p>';
|
||||
Utils.setSelection('p:nth-child(2)', 0);
|
||||
|
||||
backspace();
|
||||
equal(editor.getContent(), '<p contenteditable="false">1</p>');
|
||||
assertCaretInCaretBlockContainer();
|
||||
});
|
||||
|
||||
test('delete from empty block to before cE=false', function() {
|
||||
editor.getBody().innerHTML = '<p><br></p><p contenteditable="false">2</p>';
|
||||
Utils.setSelection('p:nth-child(1)', 0);
|
||||
|
||||
forwardDelete();
|
||||
equal(editor.getContent(), '<p contenteditable="false">2</p>');
|
||||
assertCaretInCaretBlockContainer();
|
||||
});
|
||||
|
||||
test('exit pre block (up)', exitPreTest(upArrow, 0, '<p>\u00a0</p><pre>abc</pre>'));
|
||||
test('exit pre block (left)', exitPreTest(leftArrow, 0, '<p>\u00a0</p><pre>abc</pre>'));
|
||||
test('exit pre block (down)', exitPreTest(downArrow, 3, '<pre>abc</pre><p>\u00a0</p>'));
|
||||
test('exit pre block (right)', exitPreTest(rightArrow, 3, '<pre>abc</pre><p>\u00a0</p>'));
|
||||
|
||||
test('click on link in cE=false', function() {
|
||||
editor.setContent('<p contentEditable="false"><a href="#"><strong>link</strong></a></p>');
|
||||
var evt = editor.fire('click', {target: editor.$('strong')[0]});
|
||||
|
||||
equal(evt.isDefaultPrevented(), true);
|
||||
});
|
||||
|
||||
test('click next to cE=false block', function() {
|
||||
editor.setContent(
|
||||
'<table style="width: 100%">' +
|
||||
'<tr>' +
|
||||
'<td style="vertical-align: top">1</td>' +
|
||||
'<td><div contentEditable="false" style="width: 100px; height: 100px">2</div></td>' +
|
||||
'</tr>' +
|
||||
'</table>'
|
||||
);
|
||||
|
||||
var firstTd = editor.dom.select('td')[0];
|
||||
var rect = editor.dom.getRect(firstTd);
|
||||
|
||||
editor.fire('mousedown', {
|
||||
target: firstTd,
|
||||
clientX: rect.x + rect.w,
|
||||
clientY: rect.y + 10
|
||||
});
|
||||
|
||||
// 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');
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1,87 +0,0 @@
|
||||
module("tinymce.Shortcuts", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
indent: false,
|
||||
skin: false,
|
||||
entities: 'raw',
|
||||
schema: 'html5',
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('Shortcuts formats', function() {
|
||||
function assertShortcut(shortcut, args, assertState) {
|
||||
var called = false;
|
||||
|
||||
editor.shortcuts.add(shortcut, '', function() {
|
||||
called = true;
|
||||
});
|
||||
|
||||
args = tinymce.extend({
|
||||
ctrlKey: false,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false
|
||||
}, args);
|
||||
|
||||
editor.fire('keydown', args);
|
||||
|
||||
if (assertState) {
|
||||
ok(called, 'Shortcut wasn\'t called: ' + shortcut);
|
||||
} else {
|
||||
ok(!called, 'Shortcut was called when it shouldn\'t have been: ' + shortcut);
|
||||
}
|
||||
}
|
||||
|
||||
assertShortcut('ctrl+d', {ctrlKey: true, keyCode: 68}, true);
|
||||
assertShortcut('ctrl+d', {altKey: true, keyCode: 68}, false);
|
||||
|
||||
if (tinymce.Env.mac) {
|
||||
assertShortcut('meta+d', {metaKey: true, keyCode: 68}, true);
|
||||
assertShortcut('access+d', {ctrlKey: true, altKey: true, keyCode: 68}, true);
|
||||
assertShortcut('meta+d', {ctrlKey: true, keyCode: 68}, false);
|
||||
assertShortcut('access+d', {shiftKey: true, altKey: true, keyCode: 68}, false);
|
||||
} else {
|
||||
assertShortcut('meta+d', {ctrlKey: true, keyCode: 68}, true);
|
||||
assertShortcut('access+d', {shiftKey: true, altKey: true, keyCode: 68}, true);
|
||||
assertShortcut('meta+d', {metaKey: true, keyCode: 68}, false);
|
||||
assertShortcut('access+d', {ctrlKey: true, altKey: true, keyCode: 68}, false);
|
||||
}
|
||||
|
||||
assertShortcut('ctrl+shift+d', {ctrlKey: true, shiftKey: true, keyCode: 68}, true);
|
||||
assertShortcut('ctrl+shift+alt+d', {ctrlKey: true, shiftKey: true, altKey: true, keyCode: 68}, true);
|
||||
assertShortcut('ctrl+221', {ctrlKey: true, keyCode: 221}, true);
|
||||
});
|
||||
|
||||
test('Remove', function() {
|
||||
var called = false, eventArgs;
|
||||
|
||||
eventArgs = {
|
||||
ctrlKey: true,
|
||||
keyCode: 68,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false
|
||||
};
|
||||
|
||||
editor.shortcuts.add('ctrl+d', '', function() {
|
||||
called = true;
|
||||
});
|
||||
|
||||
editor.fire('keydown', eventArgs);
|
||||
ok(called, 'Shortcut wasn\'t called when it should have been.');
|
||||
|
||||
called = false;
|
||||
editor.shortcuts.remove('ctrl+d');
|
||||
editor.fire('keydown', eventArgs);
|
||||
ok(!called, 'Shortcut was called when it shouldn\'t.');
|
||||
});
|
||||
@ -1,491 +0,0 @@
|
||||
module("tinymce.UndoManager", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
skin: false,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('Initial states', function() {
|
||||
expect(3);
|
||||
|
||||
ok(!editor.undoManager.hasUndo());
|
||||
ok(!editor.undoManager.hasRedo());
|
||||
ok(!editor.undoManager.typing);
|
||||
});
|
||||
|
||||
test('One undo level', function() {
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('test');
|
||||
|
||||
expect(3);
|
||||
|
||||
editor.focus();
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Bold');
|
||||
|
||||
ok(editor.undoManager.hasUndo());
|
||||
ok(!editor.undoManager.hasRedo());
|
||||
ok(!editor.undoManager.typing);
|
||||
});
|
||||
|
||||
test('Two undo levels', function() {
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('test');
|
||||
|
||||
expect(3);
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Bold');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Italic');
|
||||
|
||||
ok(editor.undoManager.hasUndo());
|
||||
ok(!editor.undoManager.hasRedo());
|
||||
ok(!editor.undoManager.typing);
|
||||
});
|
||||
|
||||
test('No undo levels and one redo', function() {
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('test');
|
||||
|
||||
expect(3);
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Bold');
|
||||
editor.undoManager.undo();
|
||||
|
||||
ok(!editor.undoManager.hasUndo());
|
||||
ok(editor.undoManager.hasRedo());
|
||||
ok(!editor.undoManager.typing);
|
||||
});
|
||||
|
||||
test('One undo levels and one redo', function() {
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('test');
|
||||
|
||||
expect(3);
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Bold');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Italic');
|
||||
editor.undoManager.undo();
|
||||
|
||||
ok(editor.undoManager.hasUndo());
|
||||
ok(editor.undoManager.hasRedo());
|
||||
ok(!editor.undoManager.typing);
|
||||
});
|
||||
|
||||
test('Typing state', function() {
|
||||
var selectAllFlags;
|
||||
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('test');
|
||||
|
||||
ok(!editor.undoManager.typing);
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'keydown', {keyCode: 65});
|
||||
ok(editor.undoManager.typing);
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'keydown', {keyCode: 13});
|
||||
ok(!editor.undoManager.typing);
|
||||
|
||||
selectAllFlags = {keyCode: 65, ctrlKey: false, altKey: false, shiftKey: false};
|
||||
|
||||
if (tinymce.Env.mac) {
|
||||
selectAllFlags.metaKey = true;
|
||||
} else {
|
||||
selectAllFlags.ctrlKey = true;
|
||||
}
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'keydown', selectAllFlags);
|
||||
ok(!editor.undoManager.typing);
|
||||
});
|
||||
|
||||
test('Undo and add new level', function() {
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('test');
|
||||
|
||||
expect(3);
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Bold');
|
||||
editor.undoManager.undo();
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Italic');
|
||||
|
||||
ok(editor.undoManager.hasUndo());
|
||||
ok(!editor.undoManager.hasRedo());
|
||||
ok(!editor.undoManager.typing);
|
||||
});
|
||||
|
||||
test('Events', function() {
|
||||
var add, undo, redo;
|
||||
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('test');
|
||||
|
||||
expect(6);
|
||||
|
||||
editor.on('AddUndo', function(e) {
|
||||
add = e.level;
|
||||
});
|
||||
|
||||
editor.on('Undo', function(e) {
|
||||
undo = e.level;
|
||||
});
|
||||
|
||||
editor.on('Redo', function(e) {
|
||||
redo = e.level;
|
||||
});
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('Bold');
|
||||
ok(add.content);
|
||||
ok(add.bookmark);
|
||||
|
||||
editor.undoManager.undo();
|
||||
ok(undo.content);
|
||||
ok(undo.bookmark);
|
||||
|
||||
editor.undoManager.redo();
|
||||
ok(redo.content);
|
||||
ok(redo.bookmark);
|
||||
});
|
||||
|
||||
test('No undo/redo cmds on Undo/Redo shortcut', function() {
|
||||
var evt, commands = [], added = false;
|
||||
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('test');
|
||||
|
||||
editor.on('BeforeExecCommand', function(e) {
|
||||
commands.push(e.command);
|
||||
});
|
||||
|
||||
editor.on('BeforeAddUndo', function() {
|
||||
added = true;
|
||||
});
|
||||
|
||||
evt = {
|
||||
keyCode: 90,
|
||||
metaKey: tinymce.Env.mac,
|
||||
ctrlKey: !tinymce.Env.mac,
|
||||
shiftKey: false,
|
||||
altKey: false
|
||||
};
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'keydown', evt);
|
||||
editor.dom.fire(editor.getBody(), 'keypress', evt);
|
||||
editor.dom.fire(editor.getBody(), 'keyup', evt);
|
||||
|
||||
strictEqual(added, false);
|
||||
deepEqual(commands, ["Undo"]);
|
||||
});
|
||||
|
||||
test('Transact', function() {
|
||||
var count = 0, level;
|
||||
|
||||
editor.undoManager.clear();
|
||||
|
||||
editor.on('BeforeAddUndo', function() {
|
||||
count++;
|
||||
});
|
||||
|
||||
level = editor.undoManager.transact(function() {
|
||||
editor.undoManager.add();
|
||||
editor.undoManager.add();
|
||||
});
|
||||
|
||||
equal(count, 1);
|
||||
equal(level !== null, true);
|
||||
});
|
||||
|
||||
test('Transact no change', function() {
|
||||
editor.undoManager.add();
|
||||
|
||||
var level = editor.undoManager.transact(function() {
|
||||
});
|
||||
|
||||
equal(level, null);
|
||||
});
|
||||
|
||||
test('Transact with change', function() {
|
||||
editor.undoManager.add();
|
||||
|
||||
var level = editor.undoManager.transact(function() {
|
||||
editor.setContent('x');
|
||||
});
|
||||
|
||||
equal(level !== null, true);
|
||||
});
|
||||
|
||||
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('Extra with changes', function() {
|
||||
var data;
|
||||
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('<p>abc</p>');
|
||||
Utils.setSelection('p', 0);
|
||||
editor.undoManager.add();
|
||||
|
||||
editor.undoManager.extra(function() {
|
||||
Utils.setSelection('p', 1, 'p', 2);
|
||||
editor.insertContent('1');
|
||||
}, function () {
|
||||
Utils.setSelection('p', 1, 'p', 2);
|
||||
editor.insertContent('2');
|
||||
});
|
||||
|
||||
data = editor.undoManager.data;
|
||||
equal(data.length, 3);
|
||||
equal(data[0].content, '<p>abc</p>');
|
||||
deepEqual(data[0].bookmark, {start: [0, 0, 0]});
|
||||
deepEqual(data[0].beforeBookmark, {start: [0, 0, 0]});
|
||||
equal(data[1].content, '<p>a1c</p>');
|
||||
deepEqual(data[1].bookmark, {start: [2, 0, 0]});
|
||||
deepEqual(data[1].beforeBookmark, {start: [2, 0, 0]});
|
||||
equal(data[2].content, '<p>a2c</p>');
|
||||
deepEqual(data[2].bookmark, {start: [2, 0, 0]});
|
||||
deepEqual(data[1].beforeBookmark, data[2].bookmark);
|
||||
});
|
||||
|
||||
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="all"></div>' +
|
||||
'<div data-mce-bogus="all"><div><b>x</b></div></div>' +
|
||||
'<img src="about:blank" data-mce-bogus="all">' +
|
||||
'<br data-mce-bogus="1">' +
|
||||
'test' +
|
||||
'\u200B' +
|
||||
'<img src="about:blank" />' +
|
||||
'<table><tr><td>x</td></tr></table>'
|
||||
);
|
||||
|
||||
editor.undoManager.add();
|
||||
equal(count, 2);
|
||||
equal(Utils.cleanHtml(lastLevel.content),
|
||||
'<br data-mce-bogus="1">' +
|
||||
'test' +
|
||||
'\u200B' +
|
||||
'<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;
|
||||
|
||||
function blockEvent(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
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', blockEvent);
|
||||
|
||||
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");
|
||||
|
||||
editor.off('BeforeAddUndo', blockEvent);
|
||||
});
|
||||
|
||||
test('Dirty state type letter', function() {
|
||||
editor.undoManager.clear();
|
||||
editor.setDirty(false);
|
||||
editor.setContent("<p>a</p>");
|
||||
Utils.setSelection('p', 1);
|
||||
|
||||
ok(!editor.isDirty(), "Dirty state should be false");
|
||||
Utils.type('b');
|
||||
equal(editor.getContent(), "<p>ab</p>");
|
||||
ok(editor.isDirty(), "Dirty state should be true");
|
||||
});
|
||||
|
||||
test('Dirty state type shift+letter', function() {
|
||||
editor.undoManager.clear();
|
||||
editor.setDirty(false);
|
||||
editor.setContent("<p>a</p>");
|
||||
Utils.setSelection('p', 1);
|
||||
|
||||
ok(!editor.isDirty(), "Dirty state should be false");
|
||||
Utils.type({keyCode: 65, charCode: 66, shiftKey: true});
|
||||
equal(editor.getContent(), "<p>aB</p>");
|
||||
ok(editor.isDirty(), "Dirty state should be true");
|
||||
});
|
||||
|
||||
test('Dirty state type AltGr+letter', function() {
|
||||
editor.undoManager.clear();
|
||||
editor.setDirty(false);
|
||||
editor.setContent("<p>a</p>");
|
||||
Utils.setSelection('p', 1);
|
||||
|
||||
ok(!editor.isDirty(), "Dirty state should be false");
|
||||
Utils.type({keyCode: 65, charCode: 66, ctrlKey: true, altKey: true});
|
||||
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>');
|
||||
});
|
||||
@ -1,41 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
], function() {
|
||||
module("tinymce.WindowManager", {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
editor.off('CloseWindow OpenWindow');
|
||||
}
|
||||
});
|
||||
|
||||
test('OpenWindow/CloseWindow events', function() {
|
||||
var openWindowArgs, closeWindowArgs;
|
||||
|
||||
editor.on('CloseWindow', function(e) {
|
||||
closeWindowArgs = e;
|
||||
});
|
||||
|
||||
editor.on('OpenWindow', function(e) {
|
||||
openWindowArgs = e;
|
||||
e.win.close();
|
||||
});
|
||||
|
||||
editor.windowManager.alert('test');
|
||||
|
||||
equal(openWindowArgs.type, 'openwindow');
|
||||
equal(closeWindowArgs.type, 'closewindow');
|
||||
equal(editor.windowManager.getWindows().length, 0);
|
||||
});
|
||||
});
|
||||
@ -1,137 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
'tinymce/caret/CaretBookmark',
|
||||
'tinymce/caret/CaretPosition'
|
||||
], function(CaretBookmark, CaretPosition) {
|
||||
var assertCaretPosition = Utils.assertCaretPosition;
|
||||
|
||||
module('tinymce.caret.CaretBookmark');
|
||||
|
||||
function getRoot() {
|
||||
return document.getElementById('view');
|
||||
}
|
||||
|
||||
function setupHtml(html) {
|
||||
getRoot().innerHTML = html;
|
||||
}
|
||||
|
||||
function createTextPos(textNode, offset) {
|
||||
return new CaretPosition(textNode, offset);
|
||||
}
|
||||
|
||||
test('create element index', function() {
|
||||
setupHtml('<b></b><i></i><b></b>');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().childNodes[0])), 'b[0],before');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().childNodes[1])), 'i[0],before');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().childNodes[2])), 'b[1],before');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.after(getRoot().childNodes[2])), 'b[1],after');
|
||||
});
|
||||
|
||||
test('create text index', function() {
|
||||
setupHtml('a<b></b>b<b></b>ccc');
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[0], 0)), 'text()[0],0');
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[2], 1)), 'text()[1],1');
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[4], 3)), 'text()[2],3');
|
||||
});
|
||||
|
||||
test('create text index on fragmented text nodes', function() {
|
||||
setupHtml('a');
|
||||
getRoot().appendChild(document.createTextNode('b'));
|
||||
getRoot().appendChild(document.createTextNode('c'));
|
||||
getRoot().appendChild(document.createElement('b'));
|
||||
getRoot().appendChild(document.createTextNode('d'));
|
||||
getRoot().appendChild(document.createTextNode('e'));
|
||||
|
||||
equal(getRoot().childNodes.length, 6);
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[0], 0)), 'text()[0],0');
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[1], 0)), 'text()[0],1');
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[2], 0)), 'text()[0],2');
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[4], 0)), 'text()[1],0');
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(getRoot().childNodes[5], 0)), 'text()[1],1');
|
||||
});
|
||||
|
||||
test('create br element index', function() {
|
||||
setupHtml('<p><br data-mce-bogus="1"></p><p><br></p>');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().firstChild.firstChild)), 'p[0]/br[0],before');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().lastChild.firstChild)), 'p[1]/br[0],before');
|
||||
});
|
||||
|
||||
test('create deep element index', function() {
|
||||
setupHtml('<p><span>a</span><span><b id="a"></b><b id="b"></b><b id="c"></b></span></p>');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.before(document.getElementById('a'))), 'p[0]/span[1]/b[0],before');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.before(document.getElementById('b'))), 'p[0]/span[1]/b[1],before');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.before(document.getElementById('c'))), 'p[0]/span[1]/b[2],before');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.after(document.getElementById('c'))), 'p[0]/span[1]/b[2],after');
|
||||
});
|
||||
|
||||
test('create deep text index', function() {
|
||||
setupHtml('<p><span>a</span><span id="x">a<b></b>b<b></b>ccc</span></p>');
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(document.getElementById('x').childNodes[0], 0)), 'p[0]/span[1]/text()[0],0');
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(document.getElementById('x').childNodes[2], 1)), 'p[0]/span[1]/text()[1],1');
|
||||
equal(CaretBookmark.create(getRoot(), createTextPos(document.getElementById('x').childNodes[4], 3)), 'p[0]/span[1]/text()[2],3');
|
||||
});
|
||||
|
||||
test('create element index from bogus', function() {
|
||||
setupHtml('<b></b><span data-mce-bogus="1"><b></b><span data-mce-bogus="1"><b></b><b></b></span></span>');
|
||||
equal(CaretBookmark.create(getRoot(), CaretPosition.before(getRoot().lastChild.lastChild.childNodes[1])), 'b[3],before');
|
||||
});
|
||||
|
||||
test('resolve element index', function() {
|
||||
setupHtml('<b></b><i></i><b></b>');
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'b[0],before'), CaretPosition.before(getRoot().childNodes[0]));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'b[1],before'), CaretPosition.before(getRoot().childNodes[2]));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'b[1],after'), CaretPosition.after(getRoot().childNodes[2]));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'i[0],before'), CaretPosition.before(getRoot().childNodes[1]));
|
||||
});
|
||||
|
||||
test('resolve odd element names', function() {
|
||||
setupHtml('<h-2X>abc</h-2X>');
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'h-2X[0]/text()[0],2'), createTextPos(getRoot().childNodes[0].firstChild, 2));
|
||||
});
|
||||
|
||||
test('resolve deep element index', function() {
|
||||
setupHtml('<p><span>a</span><span><b id="a"></b><b id="b"></b><b id="c"></b></span></p>');
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[0],before'), CaretPosition.before(document.getElementById('a')));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[1],before'), CaretPosition.before(document.getElementById('b')));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[2],before'), CaretPosition.before(document.getElementById('c')));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'p[0]/span[1]/b[2],after'), CaretPosition.after(document.getElementById('c')));
|
||||
});
|
||||
|
||||
test('resolve text index', function() {
|
||||
setupHtml('a<b></b>b<b></b>ccc');
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],0'), createTextPos(getRoot().childNodes[0], 0));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],1'), createTextPos(getRoot().childNodes[2], 1));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[2],3'), createTextPos(getRoot().childNodes[4], 3));
|
||||
});
|
||||
|
||||
test('resolve text index on fragmented text nodes', function() {
|
||||
setupHtml('a');
|
||||
getRoot().appendChild(document.createTextNode('b'));
|
||||
getRoot().appendChild(document.createTextNode('c'));
|
||||
getRoot().appendChild(document.createElement('b'));
|
||||
getRoot().appendChild(document.createTextNode('d'));
|
||||
getRoot().appendChild(document.createTextNode('e'));
|
||||
|
||||
equal(getRoot().childNodes.length, 6);
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],0'), createTextPos(getRoot().childNodes[0], 0));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],1'), createTextPos(getRoot().childNodes[0], 1));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],2'), createTextPos(getRoot().childNodes[1], 1));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],3'), createTextPos(getRoot().childNodes[2], 1));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],4'), createTextPos(getRoot().childNodes[2], 1));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],0'), createTextPos(getRoot().childNodes[4], 0));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],1'), createTextPos(getRoot().childNodes[4], 1));
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[1],2'), createTextPos(getRoot().childNodes[5], 1));
|
||||
});
|
||||
|
||||
test('resolve text index with to high offset', function() {
|
||||
setupHtml('abc');
|
||||
assertCaretPosition(CaretBookmark.resolve(getRoot(), 'text()[0],10'), createTextPos(getRoot().childNodes[0], 3));
|
||||
});
|
||||
|
||||
test('resolve invalid paths', function() {
|
||||
setupHtml('<b><i></i></b>');
|
||||
equal(CaretBookmark.resolve(getRoot(), 'x[0]/y[1]/z[2]'), null);
|
||||
equal(CaretBookmark.resolve(getRoot(), 'b[0]/i[2]'), null);
|
||||
equal(CaretBookmark.resolve(getRoot(), 'x'), null);
|
||||
equal(CaretBookmark.resolve(getRoot(), null), null);
|
||||
});
|
||||
});
|
||||
@ -1,63 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/Env",
|
||||
"tinymce/caret/CaretCandidate",
|
||||
"tinymce/dom/DomQuery",
|
||||
"tinymce/text/Zwsp"
|
||||
], function(Env, CaretCandidate, $, Zwsp) {
|
||||
module("tinymce.caret.CaretCandidate");
|
||||
|
||||
if (!Env.ceFalse) {
|
||||
return;
|
||||
}
|
||||
|
||||
function getRoot() {
|
||||
return document.getElementById('view');
|
||||
}
|
||||
|
||||
function setupHtml(html) {
|
||||
getRoot().innerHTML = html;
|
||||
}
|
||||
|
||||
test('isCaretCandidate', function() {
|
||||
$.each("img input textarea hr table iframe video audio object".split(' '), function(index, name) {
|
||||
equal(CaretCandidate.isCaretCandidate(document.createElement(name)), true);
|
||||
});
|
||||
|
||||
equal(CaretCandidate.isCaretCandidate(document.createTextNode('text')), true);
|
||||
equal(CaretCandidate.isCaretCandidate($('<span contentEditable="false"></span>')[0]), true);
|
||||
equal(CaretCandidate.isCaretCandidate($('<div contentEditable="false"></div>')[0]), true);
|
||||
equal(CaretCandidate.isCaretCandidate($('<table><tr><td>X</td></tr></table>')[0]), true);
|
||||
equal(CaretCandidate.isCaretCandidate($('<span contentEditable="true"></span>')[0]), false);
|
||||
equal(CaretCandidate.isCaretCandidate($('<span></span>')[0]), false);
|
||||
equal(CaretCandidate.isCaretCandidate(document.createComment('text')), false);
|
||||
equal(CaretCandidate.isCaretCandidate($('<span data-mce-caret="1"></span>')[0]), false);
|
||||
equal(CaretCandidate.isCaretCandidate(document.createTextNode(Zwsp.ZWSP)), false);
|
||||
});
|
||||
|
||||
test('isInEditable', function() {
|
||||
setupHtml('abc<span contentEditable="true"><b><span contentEditable="false">X</span></b></span>');
|
||||
equal(CaretCandidate.isInEditable($('span span', getRoot())[0].firstChild, getRoot()), false);
|
||||
equal(CaretCandidate.isInEditable($('span span', getRoot())[0], getRoot()), true);
|
||||
equal(CaretCandidate.isInEditable($('span', getRoot())[0], getRoot()), true);
|
||||
equal(CaretCandidate.isInEditable(getRoot().firstChild, getRoot()), true);
|
||||
});
|
||||
|
||||
test('isAtomic', function() {
|
||||
$.each(["img", "input", "textarea", "hr"], function(index, name) {
|
||||
equal(CaretCandidate.isAtomic(document.createElement(name)), true);
|
||||
});
|
||||
|
||||
equal(CaretCandidate.isAtomic(document.createTextNode('text')), false);
|
||||
equal(CaretCandidate.isAtomic($('<table><tr><td>X</td></tr></table>')[0]), false);
|
||||
equal(CaretCandidate.isAtomic($('<span contentEditable="false">X</span>')[0]), true);
|
||||
equal(CaretCandidate.isAtomic($('<span contentEditable="false">X<span contentEditable="true">Y</span>Z</span>')[0]), false);
|
||||
});
|
||||
|
||||
test('isEditableCaretCandidate', function() {
|
||||
setupHtml('abc<b>xx</b><span contentEditable="false"><span contentEditable="false">X</span></span>');
|
||||
equal(CaretCandidate.isEditableCaretCandidate(getRoot().firstChild, getRoot()), true);
|
||||
equal(CaretCandidate.isEditableCaretCandidate($('b', getRoot())[0]), false);
|
||||
equal(CaretCandidate.isEditableCaretCandidate($('span', getRoot())[0]), true);
|
||||
equal(CaretCandidate.isEditableCaretCandidate($('span span', getRoot())[0]), false);
|
||||
});
|
||||
});
|
||||
@ -1,137 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/Env",
|
||||
"tinymce/caret/CaretContainer",
|
||||
"tinymce/dom/DomQuery",
|
||||
"tinymce/text/Zwsp"
|
||||
], function(Env, CaretContainer, $, Zwsp) {
|
||||
module("tinymce.caret.CaretContainer");
|
||||
|
||||
if (!Env.ceFalse) {
|
||||
return;
|
||||
}
|
||||
|
||||
function setViewHtml(html) {
|
||||
var child, rootElm = getRoot();
|
||||
|
||||
// IE leaves zwsp in the dom on innerHTML
|
||||
while ((child = rootElm.firstChild)) {
|
||||
rootElm.removeChild(child);
|
||||
}
|
||||
|
||||
rootElm.innerHTML = html;
|
||||
}
|
||||
|
||||
function getRoot() {
|
||||
return document.getElementById('view');
|
||||
}
|
||||
|
||||
test('isCaretContainer', function() {
|
||||
equal(CaretContainer.isCaretContainer(document.createTextNode('text')), false);
|
||||
equal(CaretContainer.isCaretContainer($('<span></span>')[0]), false);
|
||||
equal(CaretContainer.isCaretContainer($('<span data-mce-caret="1"></span>')[0]), true);
|
||||
equal(CaretContainer.isCaretContainer($('<span data-mce-caret="1">x</span>')[0].firstChild), true);
|
||||
equal(CaretContainer.isCaretContainer(document.createTextNode(Zwsp.ZWSP)), true);
|
||||
});
|
||||
|
||||
test('isCaretContainerBlock', function() {
|
||||
equal(CaretContainer.isCaretContainerBlock(document.createTextNode('text')), false);
|
||||
equal(CaretContainer.isCaretContainerBlock($('<span></span>')[0]), false);
|
||||
equal(CaretContainer.isCaretContainerBlock($('<span data-mce-caret="1"></span>')[0]), true);
|
||||
equal(CaretContainer.isCaretContainerBlock($('<span data-mce-caret="1">a</span>')[0].firstChild), true);
|
||||
equal(CaretContainer.isCaretContainerBlock(document.createTextNode(Zwsp.ZWSP)), false);
|
||||
});
|
||||
|
||||
test('isCaretContainerInline', function() {
|
||||
equal(CaretContainer.isCaretContainerInline(document.createTextNode('text')), false);
|
||||
equal(CaretContainer.isCaretContainerInline($('<span></span>')[0]), false);
|
||||
equal(CaretContainer.isCaretContainerInline($('<span data-mce-caret="1"></span>')[0]), false);
|
||||
equal(CaretContainer.isCaretContainerInline($('<span data-mce-caret="1">a</span>')[0].firstChild), false);
|
||||
equal(CaretContainer.isCaretContainerInline(document.createTextNode(Zwsp.ZWSP)), true);
|
||||
});
|
||||
|
||||
test('insertInline before element', function() {
|
||||
setViewHtml('<span contentEditable="false">1</span>');
|
||||
equal(CaretContainer.insertInline(getRoot().firstChild, true), getRoot().firstChild);
|
||||
equal(CaretContainer.isCaretContainerInline(getRoot().firstChild), true);
|
||||
});
|
||||
|
||||
test('insertInline after element', function() {
|
||||
setViewHtml('<span contentEditable="false">1</span>');
|
||||
equal(CaretContainer.insertInline(getRoot().firstChild, false), getRoot().lastChild);
|
||||
equal(CaretContainer.isCaretContainerInline(getRoot().lastChild), true);
|
||||
});
|
||||
|
||||
test('insertInline between elements', function() {
|
||||
setViewHtml('<span contentEditable="false">1</span><span contentEditable="false">1</span>');
|
||||
equal(CaretContainer.insertBlock('p', getRoot().lastChild, true), getRoot().childNodes[1]);
|
||||
equal(CaretContainer.isCaretContainerBlock(getRoot().childNodes[1]), true);
|
||||
});
|
||||
|
||||
test('insertInline before element with ZWSP', function() {
|
||||
setViewHtml('abc' + Zwsp.ZWSP + '<span contentEditable="false">1</span>');
|
||||
equal(CaretContainer.insertInline(getRoot().lastChild, true), getRoot().childNodes[1]);
|
||||
equal(CaretContainer.isCaretContainerInline(getRoot().firstChild), false);
|
||||
equal(CaretContainer.isCaretContainerInline(getRoot().childNodes[1]), true);
|
||||
});
|
||||
|
||||
test('insertInline after element with ZWSP', function() {
|
||||
setViewHtml('<span contentEditable="false">1</span>' + Zwsp.ZWSP + 'abc');
|
||||
equal(CaretContainer.insertInline(getRoot().firstChild, false), getRoot().childNodes[1]);
|
||||
equal(CaretContainer.isCaretContainerInline(getRoot().lastChild), false);
|
||||
equal(CaretContainer.isCaretContainerInline(getRoot().childNodes[1]), true);
|
||||
});
|
||||
|
||||
test('insertBlock before element', function() {
|
||||
setViewHtml('<span contentEditable="false">1</span>');
|
||||
equal(CaretContainer.insertBlock('p', getRoot().firstChild, true), getRoot().firstChild);
|
||||
equal(CaretContainer.isCaretContainerBlock(getRoot().firstChild), true);
|
||||
});
|
||||
|
||||
test('insertBlock after element', function() {
|
||||
setViewHtml('<span contentEditable="false">1</span>');
|
||||
equal(CaretContainer.insertBlock('p', getRoot().firstChild, false), getRoot().lastChild);
|
||||
equal(CaretContainer.isCaretContainerBlock(getRoot().lastChild), true);
|
||||
});
|
||||
|
||||
test('insertBlock between elements', function() {
|
||||
setViewHtml('<span contentEditable="false">1</span><span contentEditable="false">1</span>');
|
||||
equal(CaretContainer.insertInline(getRoot().lastChild, true), getRoot().childNodes[1]);
|
||||
equal(CaretContainer.isCaretContainerInline(getRoot().childNodes[1]), true);
|
||||
});
|
||||
|
||||
test('remove', function() {
|
||||
setViewHtml('<span contentEditable="false">1</span>');
|
||||
|
||||
CaretContainer.insertInline(getRoot().firstChild, true);
|
||||
equal(CaretContainer.isCaretContainerInline(getRoot().firstChild), true);
|
||||
|
||||
CaretContainer.remove(getRoot().firstChild);
|
||||
equal(CaretContainer.isCaretContainerInline(getRoot().firstChild), false);
|
||||
});
|
||||
|
||||
test('startsWithCaretContainer', function() {
|
||||
setViewHtml(Zwsp.ZWSP + 'abc');
|
||||
equal(CaretContainer.startsWithCaretContainer(getRoot().firstChild), true);
|
||||
});
|
||||
|
||||
test('endsWithCaretContainer', function() {
|
||||
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>');
|
||||
});
|
||||
});
|
||||
@ -1,173 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/Env",
|
||||
"tinymce/caret/CaretPosition"
|
||||
], function(Env, CaretPosition) {
|
||||
module("tinymce.caret.CaretPosition");
|
||||
|
||||
if (!Env.ceFalse) {
|
||||
return;
|
||||
}
|
||||
|
||||
var createRange = Utils.createRange,
|
||||
assertCaretPosition = Utils.assertCaretPosition,
|
||||
assertRange = Utils.assertRange;
|
||||
|
||||
function getRoot() {
|
||||
return document.getElementById('view');
|
||||
}
|
||||
|
||||
function setupHtml(html) {
|
||||
tinymce.$(getRoot()).empty();
|
||||
getRoot().innerHTML = html;
|
||||
}
|
||||
|
||||
test('Constructor', function() {
|
||||
setupHtml('abc');
|
||||
strictEqual(new CaretPosition(getRoot(), 0).container(), getRoot());
|
||||
strictEqual(new CaretPosition(getRoot(), 1).offset(), 1);
|
||||
strictEqual(new CaretPosition(getRoot().firstChild, 0).container(), getRoot().firstChild);
|
||||
strictEqual(new CaretPosition(getRoot().firstChild, 1).offset(), 1);
|
||||
});
|
||||
|
||||
test('fromRangeStart', function() {
|
||||
setupHtml('abc');
|
||||
assertCaretPosition(CaretPosition.fromRangeStart(createRange(getRoot(), 0)), new CaretPosition(getRoot(), 0));
|
||||
assertCaretPosition(CaretPosition.fromRangeStart(createRange(getRoot(), 1)), new CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(CaretPosition.fromRangeStart(createRange(getRoot().firstChild, 1)), new CaretPosition(getRoot().firstChild, 1));
|
||||
});
|
||||
|
||||
test('fromRangeEnd', function() {
|
||||
setupHtml('abc');
|
||||
assertCaretPosition(CaretPosition.fromRangeEnd(createRange(getRoot(), 0, getRoot(), 1)), new CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(CaretPosition.fromRangeEnd(createRange(getRoot().firstChild, 0, getRoot().firstChild, 1)), new CaretPosition(getRoot().firstChild, 1));
|
||||
});
|
||||
|
||||
test('after', function() {
|
||||
setupHtml('abc<b>123</b>');
|
||||
assertCaretPosition(CaretPosition.after(getRoot().firstChild), new CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(CaretPosition.after(getRoot().lastChild), new CaretPosition(getRoot(), 2));
|
||||
});
|
||||
|
||||
test('before', function() {
|
||||
setupHtml('abc<b>123</b>');
|
||||
assertCaretPosition(CaretPosition.before(getRoot().firstChild), new CaretPosition(getRoot(), 0));
|
||||
assertCaretPosition(CaretPosition.before(getRoot().lastChild), new CaretPosition(getRoot(), 1));
|
||||
});
|
||||
|
||||
test('isAtStart', function() {
|
||||
setupHtml('abc<b>123</b>123');
|
||||
ok(new CaretPosition(getRoot(), 0).isAtStart());
|
||||
ok(!new CaretPosition(getRoot(), 1).isAtStart());
|
||||
ok(!new CaretPosition(getRoot(), 3).isAtStart());
|
||||
ok(new CaretPosition(getRoot().firstChild, 0).isAtStart());
|
||||
ok(!new CaretPosition(getRoot().firstChild, 1).isAtStart());
|
||||
ok(!new CaretPosition(getRoot().firstChild, 3).isAtStart());
|
||||
});
|
||||
|
||||
test('isAtEnd', function() {
|
||||
setupHtml('abc<b>123</b>123');
|
||||
ok(new CaretPosition(getRoot(), 3).isAtEnd());
|
||||
ok(!new CaretPosition(getRoot(), 2).isAtEnd());
|
||||
ok(!new CaretPosition(getRoot(), 0).isAtEnd());
|
||||
ok(new CaretPosition(getRoot().firstChild, 3).isAtEnd());
|
||||
ok(!new CaretPosition(getRoot().firstChild, 0).isAtEnd());
|
||||
ok(!new CaretPosition(getRoot().firstChild, 1).isAtEnd());
|
||||
});
|
||||
|
||||
test('toRange', function() {
|
||||
setupHtml('abc');
|
||||
assertRange(new CaretPosition(getRoot(), 0).toRange(), createRange(getRoot(), 0));
|
||||
assertRange(new CaretPosition(getRoot(), 1).toRange(), createRange(getRoot(), 1));
|
||||
assertRange(new CaretPosition(getRoot().firstChild, 1).toRange(), createRange(getRoot().firstChild, 1));
|
||||
});
|
||||
|
||||
test('isEqual', function() {
|
||||
setupHtml('abc');
|
||||
equal(new CaretPosition(getRoot(), 0).isEqual(new CaretPosition(getRoot(), 0)), true);
|
||||
equal(new CaretPosition(getRoot(), 1).isEqual(new CaretPosition(getRoot(), 0)), false);
|
||||
equal(new CaretPosition(getRoot(), 0).isEqual(new CaretPosition(getRoot().firstChild, 0)), false);
|
||||
});
|
||||
|
||||
test('isVisible', function() {
|
||||
setupHtml('<b> abc</b>');
|
||||
equal(new CaretPosition(getRoot().firstChild.firstChild, 0).isVisible(), false);
|
||||
equal(new CaretPosition(getRoot().firstChild.firstChild, 3).isVisible(), true);
|
||||
});
|
||||
|
||||
test('getClientRects', function() {
|
||||
setupHtml(
|
||||
'<b>abc</b>' +
|
||||
'<div contentEditable="false">1</div>' +
|
||||
'<div contentEditable="false">2</div>' +
|
||||
'<div contentEditable="false">2</div>' +
|
||||
'<input style="margin: 10px">' +
|
||||
'<input style="margin: 10px">' +
|
||||
'<input style="margin: 10px">' +
|
||||
'<p>123</p>' +
|
||||
'<br>'
|
||||
);
|
||||
|
||||
equal(new CaretPosition(getRoot().firstChild.firstChild, 0).getClientRects().length, 1);
|
||||
equal(new CaretPosition(getRoot(), 1).getClientRects().length, 1);
|
||||
equal(new CaretPosition(getRoot(), 2).getClientRects().length, 2);
|
||||
equal(new CaretPosition(getRoot(), 3).getClientRects().length, 2);
|
||||
equal(new CaretPosition(getRoot(), 4).getClientRects().length, 2);
|
||||
equal(new CaretPosition(getRoot(), 5).getClientRects().length, 1);
|
||||
equal(new CaretPosition(getRoot(), 6).getClientRects().length, 1);
|
||||
equal(new CaretPosition(getRoot(), 7).getClientRects().length, 1);
|
||||
equal(new CaretPosition(getRoot(), 8).getClientRects().length, 1);
|
||||
equal(new CaretPosition(getRoot(), 9).getClientRects().length, 0);
|
||||
});
|
||||
|
||||
test('getClientRects between inline node and cE=false', function() {
|
||||
setupHtml(
|
||||
'<span contentEditable="false">def</span>' +
|
||||
'<b>ghi</b>'
|
||||
);
|
||||
|
||||
equal(new CaretPosition(getRoot(), 1).getClientRects().length, 1);
|
||||
});
|
||||
|
||||
test('getClientRects at last visible character', function() {
|
||||
setupHtml('<b>a </b>');
|
||||
|
||||
equal(new CaretPosition(getRoot().firstChild.firstChild, 1).getClientRects().length, 1);
|
||||
});
|
||||
|
||||
test('getClientRects at extending character', function() {
|
||||
setupHtml('a\u0301b');
|
||||
|
||||
equal(new CaretPosition(getRoot().firstChild, 0).getClientRects().length, 1);
|
||||
equal(new CaretPosition(getRoot().firstChild, 1).getClientRects().length, 0);
|
||||
equal(new CaretPosition(getRoot().firstChild, 2).getClientRects().length, 1);
|
||||
});
|
||||
|
||||
test('getClientRects at whitespace character', function() {
|
||||
setupHtml(' a ');
|
||||
|
||||
equal(new CaretPosition(getRoot().firstChild, 0).getClientRects().length, 0);
|
||||
equal(new CaretPosition(getRoot().firstChild, 1).getClientRects().length, 0);
|
||||
equal(new CaretPosition(getRoot().firstChild, 2).getClientRects().length, 1);
|
||||
equal(new CaretPosition(getRoot().firstChild, 3).getClientRects().length, 1);
|
||||
equal(new CaretPosition(getRoot().firstChild, 4).getClientRects().length, 0);
|
||||
equal(new CaretPosition(getRoot().firstChild, 5).getClientRects().length, 0);
|
||||
});
|
||||
|
||||
test('getNode', function() {
|
||||
setupHtml('<b>abc</b><input><input>');
|
||||
|
||||
equal(new CaretPosition(getRoot().firstChild.firstChild, 0).getNode(), getRoot().firstChild.firstChild);
|
||||
equal(new CaretPosition(getRoot(), 1).getNode(), getRoot().childNodes[1]);
|
||||
equal(new CaretPosition(getRoot(), 2).getNode(), getRoot().childNodes[2]);
|
||||
equal(new CaretPosition(getRoot(), 3).getNode(), getRoot().childNodes[2]);
|
||||
});
|
||||
|
||||
test('getNode (before)', function() {
|
||||
setupHtml('<b>abc</b><input><input>');
|
||||
|
||||
equal(new CaretPosition(getRoot().firstChild.firstChild, 0).getNode(true), getRoot().firstChild.firstChild);
|
||||
equal(new CaretPosition(getRoot(), 1).getNode(true), getRoot().childNodes[0]);
|
||||
equal(new CaretPosition(getRoot(), 2).getNode(true), getRoot().childNodes[1]);
|
||||
equal(new CaretPosition(getRoot(), 3).getNode(true), getRoot().childNodes[2]);
|
||||
});
|
||||
});
|
||||
@ -1,264 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/Env",
|
||||
"tinymce/caret/CaretUtils",
|
||||
"tinymce/caret/CaretPosition",
|
||||
"tinymce/text/Zwsp"
|
||||
], function(Env, CaretUtils, CaretPosition, Zwsp) {
|
||||
module("tinymce.caret.CaretUtils");
|
||||
|
||||
if (!Env.ceFalse) {
|
||||
return;
|
||||
}
|
||||
|
||||
var assertRange = Utils.assertRange,
|
||||
createRange = Utils.createRange,
|
||||
ZWSP = Zwsp.ZWSP;
|
||||
|
||||
function getRoot() {
|
||||
return document.getElementById('view');
|
||||
}
|
||||
|
||||
function replaceWithZwsp(node) {
|
||||
for (var i = 0; i < node.childNodes.length; i++) {
|
||||
var childNode = node.childNodes[i];
|
||||
|
||||
if (childNode.nodeType === 3) {
|
||||
childNode.nodeValue = childNode.nodeValue.replace(/__ZWSP__/, ZWSP);
|
||||
} else {
|
||||
replaceWithZwsp(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setupHtml(html) {
|
||||
var child, rootElm = getRoot();
|
||||
|
||||
// IE leaves zwsp in the dom on innerHTML
|
||||
while ((child = rootElm.firstChild)) {
|
||||
rootElm.removeChild(child);
|
||||
}
|
||||
|
||||
// IE messes zwsp up on innerHTML so we need to first set markers then replace then using dom operations
|
||||
rootElm.innerHTML = html.replace(new RegExp(ZWSP, 'g'), '__ZWSP__');
|
||||
replaceWithZwsp(rootElm);
|
||||
}
|
||||
|
||||
function findElm(selector) {
|
||||
return tinymce.$(selector, getRoot())[0];
|
||||
}
|
||||
|
||||
test('isForwards', function() {
|
||||
equal(CaretUtils.isForwards(1), true);
|
||||
equal(CaretUtils.isForwards(10), true);
|
||||
equal(CaretUtils.isForwards(0), false);
|
||||
equal(CaretUtils.isForwards(-1), false);
|
||||
equal(CaretUtils.isForwards(-10), false);
|
||||
});
|
||||
|
||||
test('isBackwards', function() {
|
||||
equal(CaretUtils.isBackwards(1), false);
|
||||
equal(CaretUtils.isBackwards(10), false);
|
||||
equal(CaretUtils.isBackwards(0), false);
|
||||
equal(CaretUtils.isBackwards(-1), true);
|
||||
equal(CaretUtils.isBackwards(-10), true);
|
||||
});
|
||||
|
||||
test('findNode', function() {
|
||||
setupHtml('<b>abc</b><b><i>123</i></b>def');
|
||||
|
||||
function isBold(node) {
|
||||
return node.nodeName == 'B';
|
||||
}
|
||||
|
||||
function isText(node) {
|
||||
return node.nodeType == 3;
|
||||
}
|
||||
|
||||
equal(CaretUtils.findNode(getRoot(), 1, isBold, getRoot()), getRoot().firstChild);
|
||||
equal(CaretUtils.findNode(getRoot(), 1, isText, getRoot()), getRoot().firstChild.firstChild);
|
||||
equal(CaretUtils.findNode(getRoot().childNodes[1], 1, isBold, getRoot().childNodes[1]), null);
|
||||
equal(CaretUtils.findNode(getRoot().childNodes[1], 1, isText, getRoot().childNodes[1]).nodeName, '#text');
|
||||
equal(CaretUtils.findNode(getRoot(), -1, isBold, getRoot()), getRoot().childNodes[1]);
|
||||
equal(CaretUtils.findNode(getRoot(), -1, isText, getRoot()), getRoot().lastChild);
|
||||
});
|
||||
|
||||
test('getEditingHost', function() {
|
||||
setupHtml('<span contentEditable="true"><span contentEditable="false"></span></span>');
|
||||
|
||||
equal(CaretUtils.getEditingHost(getRoot(), getRoot()), getRoot());
|
||||
equal(CaretUtils.getEditingHost(getRoot().firstChild, getRoot()), getRoot());
|
||||
equal(CaretUtils.getEditingHost(getRoot().firstChild.firstChild, getRoot()), getRoot().firstChild);
|
||||
});
|
||||
|
||||
test('getParentBlock', function() {
|
||||
setupHtml('<p>abc</p><div><p><table><tr><td>X</td></tr></p></div>');
|
||||
|
||||
strictEqual(CaretUtils.getParentBlock(findElm('p:first')), findElm('p:first'));
|
||||
strictEqual(CaretUtils.getParentBlock(findElm('td:first').firstChild), findElm('td:first'));
|
||||
strictEqual(CaretUtils.getParentBlock(findElm('td:first')), findElm('td:first'));
|
||||
strictEqual(CaretUtils.getParentBlock(findElm('table')), findElm('table'));
|
||||
});
|
||||
|
||||
test('isInSameBlock', function() {
|
||||
setupHtml('<p>abc</p><p>def<b>ghj</b></p>');
|
||||
|
||||
strictEqual(CaretUtils.isInSameBlock(
|
||||
CaretPosition(findElm('p:first').firstChild, 0),
|
||||
CaretPosition(findElm('p:last').firstChild, 0)
|
||||
), false);
|
||||
|
||||
strictEqual(CaretUtils.isInSameBlock(
|
||||
CaretPosition(findElm('p:first').firstChild, 0),
|
||||
CaretPosition(findElm('p:first').firstChild, 0)
|
||||
), true);
|
||||
|
||||
strictEqual(CaretUtils.isInSameBlock(
|
||||
CaretPosition(findElm('p:last').firstChild, 0),
|
||||
CaretPosition(findElm('b').firstChild, 0)
|
||||
), true);
|
||||
});
|
||||
|
||||
test('isInSameEditingHost', function() {
|
||||
setupHtml(
|
||||
'<p>abc</p>' +
|
||||
'def' +
|
||||
'<span contentEditable="false">' +
|
||||
'<span contentEditable="true">ghi</span>' +
|
||||
'<span contentEditable="true">jkl</span>' +
|
||||
'</span>'
|
||||
);
|
||||
|
||||
strictEqual(CaretUtils.isInSameEditingHost(
|
||||
CaretPosition(findElm('p:first').firstChild, 0),
|
||||
CaretPosition(findElm('p:first').firstChild, 1)
|
||||
), true);
|
||||
|
||||
strictEqual(CaretUtils.isInSameEditingHost(
|
||||
CaretPosition(findElm('p:first').firstChild, 0),
|
||||
CaretPosition(getRoot().childNodes[1], 1)
|
||||
), true);
|
||||
|
||||
strictEqual(CaretUtils.isInSameEditingHost(
|
||||
CaretPosition(findElm('span span:first').firstChild, 0),
|
||||
CaretPosition(findElm('span span:first').firstChild, 1)
|
||||
), true);
|
||||
|
||||
strictEqual(CaretUtils.isInSameEditingHost(
|
||||
CaretPosition(findElm('p:first').firstChild, 0),
|
||||
CaretPosition(findElm('span span:first').firstChild, 1)
|
||||
), false);
|
||||
|
||||
strictEqual(CaretUtils.isInSameEditingHost(
|
||||
CaretPosition(findElm('span span:first').firstChild, 0),
|
||||
CaretPosition(findElm('span span:last').firstChild, 1)
|
||||
), false);
|
||||
});
|
||||
|
||||
test('isBeforeContentEditableFalse', function() {
|
||||
setupHtml(
|
||||
'<span contentEditable="false"></span>' +
|
||||
'<span contentEditable="false"></span>a'
|
||||
);
|
||||
|
||||
strictEqual(CaretUtils.isBeforeContentEditableFalse(CaretPosition(getRoot(), 0)), true);
|
||||
strictEqual(CaretUtils.isBeforeContentEditableFalse(CaretPosition(getRoot(), 1)), true);
|
||||
strictEqual(CaretUtils.isBeforeContentEditableFalse(CaretPosition(getRoot(), 2)), false);
|
||||
strictEqual(CaretUtils.isBeforeContentEditableFalse(CaretPosition(getRoot(), 3)), false);
|
||||
});
|
||||
|
||||
test('isAfterContentEditableFalse', function() {
|
||||
setupHtml(
|
||||
'<span contentEditable="false"></span>' +
|
||||
'<span contentEditable="false"></span>a'
|
||||
);
|
||||
|
||||
strictEqual(CaretUtils.isAfterContentEditableFalse(CaretPosition(getRoot(), 0)), false);
|
||||
strictEqual(CaretUtils.isAfterContentEditableFalse(CaretPosition(getRoot(), 1)), true);
|
||||
strictEqual(CaretUtils.isAfterContentEditableFalse(CaretPosition(getRoot(), 2)), true);
|
||||
strictEqual(CaretUtils.isAfterContentEditableFalse(CaretPosition(getRoot(), 3)), false);
|
||||
});
|
||||
|
||||
test('normalizeRange', function() {
|
||||
setupHtml(
|
||||
'abc<span contentEditable="false">1</span>def'
|
||||
);
|
||||
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().firstChild, 2)), createRange(getRoot().firstChild, 2));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().firstChild, 3)), createRange(getRoot(), 1));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().lastChild, 2)), createRange(getRoot().lastChild, 2));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().lastChild, 0)), createRange(getRoot(), 2));
|
||||
});
|
||||
|
||||
test('normalizeRange deep', function() {
|
||||
setupHtml(
|
||||
'<i><b>abc</b></i><span contentEditable="false">1</span><i><b>def</b></i>'
|
||||
);
|
||||
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(findElm('b').firstChild, 2)), createRange(findElm('b').firstChild, 2));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(findElm('b').firstChild, 3)), createRange(getRoot(), 1));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(findElm('b:last').firstChild, 1)), createRange(findElm('b:last').firstChild, 1));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(findElm('b:last').firstChild, 0)), createRange(getRoot(), 2));
|
||||
});
|
||||
|
||||
test('normalizeRange break at candidate', function() {
|
||||
setupHtml(
|
||||
'<p><b>abc</b><input></p><p contentEditable="false">1</p><p><input><b>abc</b></p>'
|
||||
);
|
||||
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(findElm('b').firstChild, 3)), createRange(findElm('b').firstChild, 3));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(findElm('b:last').lastChild, 0)), createRange(findElm('b:last').lastChild, 0));
|
||||
});
|
||||
|
||||
test('normalizeRange at block caret container', function() {
|
||||
setupHtml(
|
||||
'<p data-mce-caret="before">\u00a0</p><p contentEditable="false">1</p><p data-mce-caret="after">\u00a0</p>'
|
||||
);
|
||||
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(findElm('p:first').firstChild, 0)), createRange(getRoot(), 1));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(findElm('p:first').firstChild, 1)), createRange(getRoot(), 1));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(findElm('p:last').firstChild, 0)), createRange(getRoot(), 2));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(findElm('p:last').firstChild, 1)), createRange(getRoot(), 2));
|
||||
});
|
||||
|
||||
test('normalizeRange at inline caret container', function() {
|
||||
setupHtml(
|
||||
'abc<span contentEditable="false">1</span>def'
|
||||
);
|
||||
|
||||
getRoot().insertBefore(document.createTextNode(ZWSP), getRoot().childNodes[1]);
|
||||
getRoot().insertBefore(document.createTextNode(ZWSP), getRoot().childNodes[3]);
|
||||
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().firstChild, 3)), createRange(getRoot(), 2));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().childNodes[1], 0)), createRange(getRoot(), 2));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().childNodes[1], 1)), createRange(getRoot(), 2));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().lastChild, 0)), createRange(getRoot(), 3));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().childNodes[3], 0)), createRange(getRoot(), 3));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().childNodes[3], 1)), createRange(getRoot(), 3));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(getRoot().firstChild, 3)), createRange(getRoot(), 2));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(getRoot().childNodes[1], 0)), createRange(getRoot(), 2));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(getRoot().childNodes[1], 1)), createRange(getRoot(), 2));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(getRoot().lastChild, 0)), createRange(getRoot(), 3));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(getRoot().childNodes[3], 0)), createRange(getRoot(), 3));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(getRoot().childNodes[3], 1)), createRange(getRoot(), 3));
|
||||
});
|
||||
|
||||
test('normalizeRange at inline caret container (combined)', function() {
|
||||
setupHtml(
|
||||
'abc' + ZWSP + '<span contentEditable="false">1</span>' + ZWSP + 'def'
|
||||
);
|
||||
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().firstChild, 3)), createRange(getRoot(), 1));
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().firstChild, 4)), createRange(getRoot(), 1));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(getRoot().lastChild, 0)), createRange(getRoot(), 2));
|
||||
assertRange(CaretUtils.normalizeRange(-1, getRoot(), createRange(getRoot().lastChild, 1)), createRange(getRoot(), 2));
|
||||
});
|
||||
|
||||
test('normalizeRange at inline caret container after block', function() {
|
||||
setupHtml(
|
||||
'<p><span contentEditable="false">1</span></p>' + ZWSP + 'abc'
|
||||
);
|
||||
|
||||
assertRange(CaretUtils.normalizeRange(1, getRoot(), createRange(getRoot().lastChild, 0)), createRange(getRoot().lastChild, 0));
|
||||
|
||||
});
|
||||
});
|
||||
@ -1,277 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/Env",
|
||||
"tinymce/caret/CaretWalker",
|
||||
"tinymce/caret/CaretPosition"
|
||||
], function(Env, CaretWalker, CaretPosition) {
|
||||
module("tinymce.caret.CaretWalker");
|
||||
|
||||
if (!Env.ceFalse) {
|
||||
return;
|
||||
}
|
||||
|
||||
function getRoot() {
|
||||
return document.getElementById('view');
|
||||
}
|
||||
|
||||
function setupHtml(html) {
|
||||
tinymce.$(getRoot()).empty();
|
||||
getRoot().innerHTML = html;
|
||||
}
|
||||
|
||||
function findElm(selector) {
|
||||
return tinymce.$(selector, getRoot())[0];
|
||||
}
|
||||
|
||||
function findElmPos(selector, offset) {
|
||||
return CaretPosition(tinymce.$(selector, getRoot())[0], offset);
|
||||
}
|
||||
|
||||
function findTextPos(selector, offset) {
|
||||
return CaretPosition(tinymce.$(selector, getRoot())[0].firstChild, offset);
|
||||
}
|
||||
|
||||
var assertCaretPosition = Utils.assertCaretPosition,
|
||||
logicalCaret = new CaretWalker(getRoot());
|
||||
|
||||
test('inside empty root', function() {
|
||||
setupHtml('');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), null);
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 0)), null);
|
||||
});
|
||||
|
||||
test('on null', function() {
|
||||
setupHtml('');
|
||||
assertCaretPosition(logicalCaret.next(null), null);
|
||||
assertCaretPosition(logicalCaret.prev(null), null);
|
||||
});
|
||||
|
||||
test('within text node in root', function() {
|
||||
setupHtml('abc');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 0)), CaretPosition(getRoot().firstChild, 1));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 1)), CaretPosition(getRoot().firstChild, 2));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 2)), CaretPosition(getRoot().firstChild, 3));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 3)), null);
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().firstChild, 3)), CaretPosition(getRoot().firstChild, 2));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().firstChild, 2)), CaretPosition(getRoot().firstChild, 1));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().firstChild, 1)), CaretPosition(getRoot().firstChild, 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().firstChild, 0)), null);
|
||||
});
|
||||
|
||||
test('within text node in element', function() {
|
||||
setupHtml('<p>abc</p>');
|
||||
assertCaretPosition(logicalCaret.next(findTextPos('p', 0)), findTextPos('p', 1));
|
||||
assertCaretPosition(logicalCaret.next(findTextPos('p', 1)), findTextPos('p', 2));
|
||||
assertCaretPosition(logicalCaret.next(findTextPos('p', 2)), findTextPos('p', 3));
|
||||
assertCaretPosition(logicalCaret.next(findTextPos('p', 3)), null);
|
||||
assertCaretPosition(logicalCaret.prev(findTextPos('p', 3)), findTextPos('p', 2));
|
||||
assertCaretPosition(logicalCaret.prev(findTextPos('p', 2)), findTextPos('p', 1));
|
||||
assertCaretPosition(logicalCaret.prev(findTextPos('p', 1)), findTextPos('p', 0));
|
||||
assertCaretPosition(logicalCaret.prev(findTextPos('p', 0)), null);
|
||||
});
|
||||
|
||||
test('from index text node over comment', function() {
|
||||
setupHtml('abcd<!-- x -->abcd');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), CaretPosition(getRoot().firstChild, 0));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(getRoot().lastChild, 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot().firstChild, 4));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 3)), CaretPosition(getRoot().lastChild, 4));
|
||||
});
|
||||
|
||||
test('from text to text across elements', function() {
|
||||
setupHtml('<p>abc</p><p>abc</p>');
|
||||
assertCaretPosition(logicalCaret.next(findTextPos('p:first', 3)), findTextPos('p:last', 0));
|
||||
assertCaretPosition(logicalCaret.prev(findTextPos('p:last', 0)), findTextPos('p:first', 3));
|
||||
});
|
||||
|
||||
test('from text to text across elements with siblings', function() {
|
||||
setupHtml('<p>abc<b><!-- x --></b></p><p><b><!-- x --></b></p><p><b><!-- x --></b>abc</p>');
|
||||
assertCaretPosition(logicalCaret.next(findTextPos('p:first', 3)), CaretPosition(findElm('p:last').lastChild, 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('p:last').lastChild)), findTextPos('p:first', 3));
|
||||
});
|
||||
|
||||
test('from input to text', function() {
|
||||
setupHtml('123<input>456');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), CaretPosition(getRoot().lastChild, 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot().firstChild, 3));
|
||||
});
|
||||
|
||||
test('from input to input across elements', function() {
|
||||
setupHtml('<p><input></p><p><input></p>');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('p:first'), 1)), CaretPosition(findElm('p:last'), 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('p:last'), 0)), CaretPosition(findElm('p:first'), 1));
|
||||
});
|
||||
|
||||
test('next br to br across elements', function() {
|
||||
setupHtml('<p><br></p><p><br></p>');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('p:first'), 0)), CaretPosition(findElm('p:last'), 0));
|
||||
});
|
||||
|
||||
test('prev br to br across elements', function() {
|
||||
setupHtml('<p><br></p><p><br></p>');
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('p:last'), 0)), CaretPosition(findElm('p:first'), 0));
|
||||
});
|
||||
|
||||
test('from before/after br to text', function() {
|
||||
setupHtml('<br>123<br>456<br>789');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 3));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 4)), CaretPosition(getRoot(), 5));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 5)), CaretPosition(getRoot().lastChild, 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 5)), CaretPosition(getRoot(), 4));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 4)), CaretPosition(getRoot().childNodes[3], 3));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 0));
|
||||
});
|
||||
|
||||
test('over br', function() {
|
||||
setupHtml('<br><br><br>');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 3));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 3)), null);
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 3)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 0)), null);
|
||||
});
|
||||
|
||||
test('over input', function() {
|
||||
setupHtml('<input><input><input>');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 3));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 3)), null);
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 3)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 0)), null);
|
||||
});
|
||||
|
||||
test('over img', function() {
|
||||
setupHtml('<img src="about:blank"><img src="about:blank"><img src="about:blank">');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 3));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 3)), null);
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 3)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 0)), null);
|
||||
});
|
||||
|
||||
test('over script/style/textarea', function() {
|
||||
setupHtml('a<script>//x</script>b<style>x{}</style>c<textarea>x</textarea>d');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 1)), CaretPosition(getRoot().childNodes[2], 0));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().childNodes[2], 1)), CaretPosition(getRoot().childNodes[4], 0));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 5)), CaretPosition(getRoot(), 6));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 6)), CaretPosition(getRoot(), 5));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().childNodes[4], 0)), CaretPosition(getRoot().childNodes[2], 1));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot().childNodes[0], 1));
|
||||
});
|
||||
|
||||
test('around tables', function() {
|
||||
setupHtml('a<table><tr><td>A</td></tr></table><table><tr><td>B</td></tr></table>b');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 1)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), findTextPos('td:first', 0));
|
||||
assertCaretPosition(logicalCaret.next(findTextPos('td:first', 1)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), findTextPos('td:last', 0));
|
||||
assertCaretPosition(logicalCaret.next(findTextPos('table:last td', 1)), CaretPosition(getRoot(), 3));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 3)), CaretPosition(getRoot().lastChild, 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().lastChild, 0)), CaretPosition(getRoot(), 3));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 3)), findTextPos('td:last', 1));
|
||||
assertCaretPosition(logicalCaret.prev(findTextPos('td:last', 0)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), findTextPos('td:first', 1));
|
||||
assertCaretPosition(logicalCaret.prev(findTextPos('td:first', 0)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot().firstChild, 1));
|
||||
});
|
||||
|
||||
test('over cE=false', function() {
|
||||
setupHtml('123<span contentEditable="false">a</span>456');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 3)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().lastChild, 0)), CaretPosition(getRoot(), 2));
|
||||
});
|
||||
/*
|
||||
test('from outside cE=false to nested cE=true', function() {
|
||||
setupHtml('abc<span contentEditable="false">b<span contentEditable="true">c</span></span>def');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 3)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), findTextPos('span span', 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().lastChild, 0)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), findTextPos('span span', 1));
|
||||
});
|
||||
|
||||
test('from outside cE=false to nested cE=true before/after cE=false', function() {
|
||||
setupHtml('a<span contentEditable="false">b<span contentEditable="true"><span contentEditable="false"></span></span></span>d');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(findElm('span span'), 0));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('span span'), 1)), CaretPosition(getRoot(), 2));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(findElm('span span'), 1));
|
||||
});
|
||||
*/
|
||||
test('from inside cE=true in cE=false to after cE=false', function() {
|
||||
setupHtml(
|
||||
'<p>' +
|
||||
'<span contentEditable="false">' +
|
||||
'<span contentEditable="true">' +
|
||||
'abc' +
|
||||
'</span>' +
|
||||
'def' +
|
||||
'</span>' +
|
||||
'</p>' +
|
||||
'<p>abc</p>'
|
||||
);
|
||||
|
||||
assertCaretPosition(logicalCaret.next(findTextPos('span span', 3)), CaretPosition(findElm('p'), 1));
|
||||
});
|
||||
|
||||
test('around cE=false inside nested cE=true', function() {
|
||||
setupHtml(
|
||||
'<span contentEditable="false">' +
|
||||
'<span contentEditable="true">' +
|
||||
'<span contentEditable="false">1</span>' +
|
||||
'<span contentEditable="false">2</span>' +
|
||||
'<span contentEditable="false">3</span>' +
|
||||
'</span>' +
|
||||
'</span>'
|
||||
);
|
||||
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('span span'), 0)), CaretPosition(findElm('span span'), 1));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('span span'), 1)), CaretPosition(findElm('span span'), 2));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('span span'), 2)), CaretPosition(findElm('span span'), 3));
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('span span'), 3)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('span span'), 0)), CaretPosition(getRoot(), 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('span span'), 1)), CaretPosition(findElm('span span'), 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('span span'), 2)), CaretPosition(findElm('span span'), 1));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('span span'), 3)), CaretPosition(findElm('span span'), 2));
|
||||
});
|
||||
|
||||
test('next from last node', function() {
|
||||
setupHtml(
|
||||
'<p><b><input></b></p>' +
|
||||
'<input>' +
|
||||
'<p><b><input></b></p>'
|
||||
);
|
||||
|
||||
assertCaretPosition(logicalCaret.next(findElmPos('p:first', 1)), CaretPosition(getRoot(), 1));
|
||||
assertCaretPosition(logicalCaret.next(findElmPos('p:last', 1)), null);
|
||||
});
|
||||
|
||||
test('left/right between cE=false inlines in different blocks', function() {
|
||||
setupHtml(
|
||||
'<p>' +
|
||||
'<span contentEditable="false">abc</span>' +
|
||||
'</p>' +
|
||||
'<p>' +
|
||||
'<span contentEditable="false">def</span>' +
|
||||
'</p>'
|
||||
);
|
||||
|
||||
assertCaretPosition(logicalCaret.next(findElmPos('p:first', 1)), findElmPos('p:last', 0));
|
||||
assertCaretPosition(logicalCaret.prev(findElmPos('p:last', 0)), findElmPos('p:first', 1));
|
||||
});
|
||||
|
||||
test('never into caret containers', function() {
|
||||
setupHtml('abc<b data-mce-caret="1">def</b>ghi');
|
||||
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 3)), CaretPosition(getRoot().lastChild, 0));
|
||||
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().lastChild, 0)), CaretPosition(getRoot().firstChild, 3));
|
||||
});
|
||||
});
|
||||
@ -1,94 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/Env",
|
||||
"tinymce/caret/FakeCaret",
|
||||
"tinymce/dom/DomQuery",
|
||||
"tinymce/text/Zwsp"
|
||||
], function(Env, FakeCaret, $, Zwsp) {
|
||||
var fakeCaret;
|
||||
|
||||
if (!Env.ceFalse) {
|
||||
return;
|
||||
}
|
||||
|
||||
module("tinymce.caret.FakeCaret", {
|
||||
setupModule: function() {
|
||||
fakeCaret = new FakeCaret($('#view')[0], isBlock);
|
||||
},
|
||||
|
||||
teardownModule: function() {
|
||||
fakeCaret.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
function isBlock(node) {
|
||||
return node.nodeName == 'DIV';
|
||||
}
|
||||
|
||||
test('show/hide (before, block)', function() {
|
||||
var rng, $fakeCaretElm;
|
||||
|
||||
$('#view').html('<div>a</div>');
|
||||
|
||||
rng = fakeCaret.show(true, $('#view div')[0]);
|
||||
$fakeCaretElm = $('#view').children();
|
||||
|
||||
equal($fakeCaretElm[0].nodeName, 'P');
|
||||
equal($fakeCaretElm.attr('data-mce-caret'), 'before');
|
||||
Utils.assertRange(rng, Utils.createRange($fakeCaretElm[0], 0, $fakeCaretElm[0], 0));
|
||||
|
||||
fakeCaret.hide();
|
||||
equal($('#view *[data-mce-caret]').length, 0);
|
||||
});
|
||||
|
||||
test('show/hide (before, block)', function() {
|
||||
var rng, $fakeCaretElm;
|
||||
|
||||
$('#view').html('<div>a</div>');
|
||||
|
||||
rng = fakeCaret.show(false, $('#view div')[0]);
|
||||
$fakeCaretElm = $('#view').children();
|
||||
|
||||
equal($fakeCaretElm[1].nodeName, 'P');
|
||||
equal($fakeCaretElm.eq(1).attr('data-mce-caret'), 'after');
|
||||
Utils.assertRange(rng, Utils.createRange($fakeCaretElm[1], 0, $fakeCaretElm[1], 0));
|
||||
|
||||
fakeCaret.hide();
|
||||
equal($('#view *[data-mce-caret]').length, 0);
|
||||
});
|
||||
|
||||
test('show/hide (before, inline)', function() {
|
||||
var rng, $fakeCaretText;
|
||||
|
||||
$('#view').html('<span>a</span>');
|
||||
|
||||
rng = fakeCaret.show(true, $('#view span')[0]);
|
||||
$fakeCaretText = $('#view').contents();
|
||||
|
||||
equal($fakeCaretText[0].nodeName, '#text');
|
||||
equal($fakeCaretText[0].data, Zwsp.ZWSP);
|
||||
Utils.assertRange(rng, Utils.createRange($fakeCaretText[0], 1));
|
||||
|
||||
fakeCaret.hide();
|
||||
equal($('#view').contents()[0].nodeName, 'SPAN');
|
||||
});
|
||||
|
||||
test('show/hide (after, inline)', function() {
|
||||
var rng, $fakeCaretText;
|
||||
|
||||
$('#view').html('<span>a</span>');
|
||||
|
||||
rng = fakeCaret.show(false, $('#view span')[0]);
|
||||
$fakeCaretText = $('#view').contents();
|
||||
|
||||
equal($fakeCaretText[1].nodeName, '#text');
|
||||
equal($fakeCaretText[1].data, Zwsp.ZWSP);
|
||||
Utils.assertRange(rng, Utils.createRange($fakeCaretText[1], 1));
|
||||
|
||||
fakeCaret.hide();
|
||||
equal($('#view').contents()[0].nodeName, 'SPAN');
|
||||
});
|
||||
|
||||
test('getCss', function() {
|
||||
equal(fakeCaret.getCss().length > 10, true);
|
||||
});
|
||||
});
|
||||
@ -1,28 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/Env",
|
||||
"tinymce/caret/LineUtils"
|
||||
], function(Env, LineUtils) {
|
||||
module("tinymce.caret.LineUtils");
|
||||
|
||||
if (!Env.ceFalse) {
|
||||
return;
|
||||
}
|
||||
|
||||
function rect(x, y, w, h) {
|
||||
return {
|
||||
left: x,
|
||||
top: y,
|
||||
bottom: y + h,
|
||||
right: x + w,
|
||||
width: w,
|
||||
height: h
|
||||
};
|
||||
}
|
||||
|
||||
test('findClosestClientRect', function() {
|
||||
deepEqual(LineUtils.findClosestClientRect([rect(10, 10, 10, 10), rect(30, 10, 10, 10)], 15), rect(10, 10, 10, 10));
|
||||
deepEqual(LineUtils.findClosestClientRect([rect(10, 10, 10, 10), rect(30, 10, 10, 10)], 27), rect(30, 10, 10, 10));
|
||||
deepEqual(LineUtils.findClosestClientRect([rect(10, 10, 10, 10), rect(30, 10, 10, 10)], 23), rect(10, 10, 10, 10));
|
||||
deepEqual(LineUtils.findClosestClientRect([rect(10, 10, 10, 10), rect(20, 10, 10, 10)], 13), rect(10, 10, 10, 10));
|
||||
});
|
||||
});
|
||||
@ -1,88 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/Env",
|
||||
"tinymce/caret/LineWalker",
|
||||
"tinymce/caret/CaretPosition",
|
||||
"tinymce/dom/DomQuery"
|
||||
], function(Env, LineWalker, CaretPosition, $) {
|
||||
module("tinymce.caret.LineWalker");
|
||||
|
||||
if (!Env.ceFalse) {
|
||||
return;
|
||||
}
|
||||
|
||||
test('positionsUntil', function() {
|
||||
var result, predicateCallCount = 0;
|
||||
|
||||
function predicate() {
|
||||
predicateCallCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#view').html('<span contentEditable="false">a</span><span>b</span>');
|
||||
result = LineWalker.positionsUntil(1, $('#view')[0], predicate, $('#view')[0].firstChild);
|
||||
equal(result.length, 3);
|
||||
equal(result[0].position.getNode(), $('#view')[0].lastChild);
|
||||
equal(result[1].position.getNode(), $('#view')[0].lastChild.firstChild);
|
||||
equal(result[2].position.getNode(), $('#view')[0].lastChild.firstChild);
|
||||
equal(predicateCallCount, 3);
|
||||
|
||||
predicateCallCount = 0;
|
||||
$('#view').html('<span>a</span><span contentEditable="false">b</span>');
|
||||
result = LineWalker.positionsUntil(-1, $('#view')[0], predicate, $('#view')[0].lastChild);
|
||||
equal(result.length, 3);
|
||||
equal(result[0].position.getNode(), $('#view')[0].lastChild);
|
||||
equal(result[1].position.getNode(), $('#view')[0].firstChild.firstChild);
|
||||
equal(result[2].position.getNode(), $('#view')[0].firstChild.firstChild);
|
||||
equal(predicateCallCount, 3);
|
||||
});
|
||||
|
||||
test('upUntil', function() {
|
||||
var caretPosition, result, predicateCallCount = 0;
|
||||
|
||||
function predicate() {
|
||||
predicateCallCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#view').html('<p>a</p><p>b</p><p>c</p>');
|
||||
|
||||
caretPosition = new CaretPosition($('#view')[0].lastChild.lastChild, 1);
|
||||
result = LineWalker.upUntil($('#view')[0], predicate, caretPosition);
|
||||
|
||||
equal(result.length, 3);
|
||||
equal(result[0].line, 0);
|
||||
equal(result[1].line, 1);
|
||||
equal(result[2].line, 2);
|
||||
equal(predicateCallCount, 3);
|
||||
});
|
||||
|
||||
test('downUntil', function() {
|
||||
var caretPosition, result, predicateCallCount = 0;
|
||||
|
||||
function predicate() {
|
||||
predicateCallCount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#view').html('<p>a</p><p>b</p><p>c</p>');
|
||||
|
||||
caretPosition = new CaretPosition($('#view')[0].firstChild.firstChild, 0);
|
||||
result = LineWalker.downUntil($('#view')[0], predicate, caretPosition);
|
||||
|
||||
equal(result.length, 3);
|
||||
equal(result[0].line, 0);
|
||||
equal(result[1].line, 1);
|
||||
equal(result[2].line, 2);
|
||||
equal(predicateCallCount, 3);
|
||||
});
|
||||
|
||||
test('isAboveLine', function() {
|
||||
equal(LineWalker.isAboveLine(5)({line: 10}), true);
|
||||
equal(LineWalker.isAboveLine(5)({line: 2}), false);
|
||||
});
|
||||
|
||||
test('isLine', function() {
|
||||
equal(LineWalker.isLine(3)({line: 3}), true);
|
||||
equal(LineWalker.isLine(3)({line: 4}), false);
|
||||
});
|
||||
});
|
||||
@ -1,104 +0,0 @@
|
||||
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');
|
||||
});
|
||||
});
|
||||
@ -1,51 +0,0 @@
|
||||
ModuleLoader.require(["tinymce/data/ObservableObject"], function(ObservableObject) {
|
||||
module("tinymce.data.ObservableObject");
|
||||
|
||||
test("Constructor", function(assert) {
|
||||
var obj;
|
||||
|
||||
obj = new ObservableObject();
|
||||
assert.ok(!obj.has('a'));
|
||||
|
||||
obj = new ObservableObject({a: 1, b: 2});
|
||||
assert.strictEqual(obj.get('a'), 1);
|
||||
assert.strictEqual(obj.get('b'), 2);
|
||||
});
|
||||
|
||||
test("set/get and observe all", function(assert) {
|
||||
var obj = new ObservableObject(), events = [];
|
||||
|
||||
obj.on('change', function(e) {
|
||||
events.push(e);
|
||||
});
|
||||
|
||||
obj.set('a', 'a');
|
||||
obj.set('a', 'a2');
|
||||
obj.set('a', 'a3');
|
||||
obj.set('b', 'b');
|
||||
assert.strictEqual(obj.get('a'), 'a3');
|
||||
|
||||
equal(events[0].type, 'change');
|
||||
equal(events[0].value, 'a');
|
||||
equal(events[1].type, 'change');
|
||||
equal(events[1].value, 'a2');
|
||||
equal(events[2].type, 'change');
|
||||
equal(events[2].value, 'a3');
|
||||
equal(events[3].type, 'change');
|
||||
equal(events[3].value, 'b');
|
||||
});
|
||||
|
||||
test("set/get and observe specific", function(assert) {
|
||||
var obj = new ObservableObject(), events = [];
|
||||
|
||||
obj.on('change:a', function(e) {
|
||||
events.push(e);
|
||||
});
|
||||
|
||||
obj.set('a', 'a');
|
||||
obj.set('b', 'b');
|
||||
equal(events[0].type, 'change');
|
||||
equal(events[0].value, 'a');
|
||||
equal(events.length, 1);
|
||||
});
|
||||
});
|
||||
@ -1,716 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.dom.DOMUtils", {
|
||||
teardownModule: function() {
|
||||
DOM = null;
|
||||
}
|
||||
});
|
||||
|
||||
var DOM = new tinymce.dom.DOMUtils(document, {keep_values : true, schema : new tinymce.html.Schema()});
|
||||
|
||||
test('parseStyle', 11, function() {
|
||||
var dom;
|
||||
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
dom = new tinymce.dom.DOMUtils(document, {hex_colors : true, keep_values : true, url_converter : function(u) {
|
||||
return 'X' + u + 'Y';
|
||||
}});
|
||||
|
||||
equal(
|
||||
dom.serializeStyle(dom.parseStyle('border: 1px solid red; color: green')),
|
||||
'border: 1px solid red; color: green;'
|
||||
);
|
||||
|
||||
equal(
|
||||
dom.serializeStyle(dom.parseStyle('border: 1px solid rgb(0, 255, 255); color: green')),
|
||||
'border: 1px solid #00ffff; color: green;'
|
||||
);
|
||||
|
||||
equal(
|
||||
dom.serializeStyle(dom.parseStyle('border-top: 1px solid red; border-left: 1px solid red; border-bottom: 1px solid red; border-right: 1px solid red;')),
|
||||
'border: 1px solid red;'
|
||||
);
|
||||
|
||||
equal(
|
||||
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;'
|
||||
);
|
||||
|
||||
equal(
|
||||
dom.serializeStyle(dom.parseStyle('background: transparent url(test.gif);')),
|
||||
'background: transparent url(\'Xtest.gifY\');'
|
||||
);
|
||||
|
||||
equal(
|
||||
dom.serializeStyle(dom.parseStyle('background: transparent url(http://www.site.com/test.gif?a=1&b=2);')),
|
||||
'background: transparent url(\'Xhttp://www.site.com/test.gif?a=1&b=2Y\');'
|
||||
);
|
||||
|
||||
dom.setHTML('test', '<span id="test2" style=" margin-left: 1px; margin-top: 1px; margin-right: 1px; margin-bottom: 1px "></span>');
|
||||
equal(dom.getAttrib('test2', 'style'), 'margin: 1px;');
|
||||
|
||||
dom.setHTML('test', '<span id="test2" style="background-image: url(test.gif);"></span>');
|
||||
equal(dom.getAttrib('test2', 'style'), 'background-image: url(\'Xtest.gifY\');');
|
||||
|
||||
dom.get('test').innerHTML = '<span id="test2" style="border: 1px solid #00ff00"></span>';
|
||||
equal(dom.getAttrib('test2', 'style'), tinymce.isIE && !window.getSelection ? 'border: #00ff00 1px solid;' : 'border: 1px solid #00ff00;'); // IE has a separate output
|
||||
|
||||
dom.get('test').innerHTML = '<span id="test2" style="background-image: url(http://www.site.com/test.gif);"></span>';
|
||||
equal(dom.getAttrib('test2', 'style'), 'background-image: url(\'Xhttp://www.site.com/test.gifY\');');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('addClass', function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.get('test').className = '';
|
||||
DOM.addClass('test', 'abc');
|
||||
equal(DOM.get('test').className, 'abc');
|
||||
|
||||
DOM.addClass('test', '123');
|
||||
equal(DOM.get('test').className, 'abc 123');
|
||||
|
||||
DOM.get('test').innerHTML = '<span id="test2"></span><span id="test3"></span><span id="test4"></span>';
|
||||
DOM.addClass(DOM.select('span', 'test'), 'abc');
|
||||
equal(DOM.get('test2').className, 'abc');
|
||||
equal(DOM.get('test3').className, 'abc');
|
||||
equal(DOM.get('test4').className, 'abc');
|
||||
DOM.get('test').innerHTML = '';
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('removeClass', 5, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.get('test').className = 'abc 123 xyz';
|
||||
DOM.removeClass('test', '123');
|
||||
equal(DOM.get('test').className, 'abc xyz');
|
||||
|
||||
DOM.get('test').innerHTML = '<span id="test2" class="test1"></span><span id="test3" class="test test1 test"></span><span id="test4" class="test1 test"></span>';
|
||||
DOM.removeClass(DOM.select('span', 'test'), 'test1');
|
||||
equal(DOM.get('test2').className, '');
|
||||
equal(DOM.get('test3').className, 'test test');
|
||||
equal(DOM.get('test4').className, 'test');
|
||||
|
||||
DOM.get('test').innerHTML = '<span id="test2" class="test"></span>';
|
||||
DOM.removeClass('test2', 'test');
|
||||
equal(Utils.normalizeHtml(DOM.get('test').innerHTML), '<span id="test2"></span>');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('hasClass', 7, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.get('test').className = 'abc 123 xyz';
|
||||
ok(DOM.hasClass('test', 'abc'));
|
||||
ok(DOM.hasClass('test', '123'));
|
||||
ok(DOM.hasClass('test', 'xyz'));
|
||||
ok(!DOM.hasClass('test', 'aaa'));
|
||||
|
||||
DOM.get('test').className = 'abc';
|
||||
ok(DOM.hasClass('test', 'abc'));
|
||||
|
||||
DOM.get('test').className = 'aaa abc';
|
||||
ok(DOM.hasClass('test', 'abc'));
|
||||
|
||||
DOM.get('test').className = 'abc aaa';
|
||||
ok(DOM.hasClass('test', 'abc'));
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('add', 5, function() {
|
||||
var e;
|
||||
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.add('test', 'span', {'class' : 'abc 123'}, 'content <b>abc</b>');
|
||||
e = DOM.get('test').getElementsByTagName('span')[0];
|
||||
equal(e.className, 'abc 123');
|
||||
equal(e.innerHTML.toLowerCase(), 'content <b>abc</b>');
|
||||
DOM.remove(e);
|
||||
|
||||
DOM.add('test', 'span', {'class' : 'abc 123'});
|
||||
e = DOM.get('test').getElementsByTagName('span')[0];
|
||||
equal(e.className, 'abc 123');
|
||||
DOM.remove(e);
|
||||
|
||||
DOM.add('test', 'span');
|
||||
e = DOM.get('test').getElementsByTagName('span')[0];
|
||||
equal(e.nodeName, 'SPAN');
|
||||
DOM.remove(e);
|
||||
|
||||
DOM.get('test').innerHTML = '<span id="test2"></span><span id="test3"></span><span id="test4"></span>';
|
||||
DOM.add(['test2', 'test3', 'test4'], 'span', {'class' : 'abc 123'});
|
||||
equal(DOM.select('span', 'test').length, 6);
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('create', 3, function() {
|
||||
var e;
|
||||
|
||||
e = DOM.create('span', {'class' : 'abc 123'}, 'content <b>abc</b>');
|
||||
|
||||
equal(e.nodeName, 'SPAN');
|
||||
equal(e.className, 'abc 123');
|
||||
equal(e.innerHTML.toLowerCase(), 'content <b>abc</b>');
|
||||
});
|
||||
|
||||
test('createHTML', 5, function() {
|
||||
equal(DOM.createHTML('span', {'id': 'id1', 'class': 'abc 123'}, 'content <b>abc</b>'), '<span id="id1" class="abc 123">content <b>abc</b></span>');
|
||||
equal(DOM.createHTML('span', {'id': 'id1', 'class': 'abc 123'}), '<span id="id1" class="abc 123" />');
|
||||
equal(DOM.createHTML('span', {'id': null, 'class': undefined}), '<span />');
|
||||
equal(DOM.createHTML('span'), '<span />');
|
||||
equal(DOM.createHTML('span', null, 'content <b>abc</b>'), '<span>content <b>abc</b></span>');
|
||||
});
|
||||
|
||||
test('uniqueId', 3, function() {
|
||||
DOM.counter = 0;
|
||||
|
||||
equal(DOM.uniqueId(), 'mce_0');
|
||||
equal(DOM.uniqueId(), 'mce_1');
|
||||
equal(DOM.uniqueId(), 'mce_2');
|
||||
});
|
||||
|
||||
test('showHide', function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.show('test');
|
||||
equal(DOM.get('test').style.display, '');
|
||||
ok(!DOM.isHidden('test'));
|
||||
|
||||
DOM.hide('test');
|
||||
equal(DOM.get('test').style.display, 'none');
|
||||
ok(DOM.isHidden('test'));
|
||||
|
||||
// Cleanup
|
||||
DOM.setAttrib('test', 'style', '');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('select', 4, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setHTML('test', '<div>test 1</div><div>test 2 <div>test 3</div></div><div>test 4</div>');
|
||||
equal(DOM.select('div', 'test').length, 4);
|
||||
ok(DOM.select('div', 'test').reverse);
|
||||
|
||||
DOM.setHTML('test', '<div class="test1 test2 test3">test 1</div><div class="test2">test 2 <div>test 3</div></div><div>test 4</div>');
|
||||
equal(DOM.select('div.test2', 'test').length, 2);
|
||||
|
||||
DOM.setHTML('test', '<div class="test1 test2 test3">test 1</div><div class="test2">test 2 <div>test 3</div></div><div>test 4</div>');
|
||||
equal(DOM.select('div div', 'test').length, 1, null, tinymce.isWebKit); // Issue: http://bugs.webkit.org/show_bug.cgi?id=17461
|
||||
//alert(DOM.select('div div', 'test').length +","+DOM.get('test').querySelectorAll('div div').length);
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('is', 3, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
DOM.setHTML('test', '<div id="textX" class="test">test 1</div>');
|
||||
|
||||
ok(DOM.is(DOM.get('textX'), 'div'));
|
||||
ok(DOM.is(DOM.get('textX'), 'div#textX.test'));
|
||||
ok(!DOM.is(DOM.get('textX'), 'div#textX2'));
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('encode', 1, function() {
|
||||
equal(DOM.encode('abc<>"&\'\u00e5\u00e4\u00f6'), 'abc<>"&'\u00e5\u00e4\u00f6');
|
||||
});
|
||||
|
||||
test('setGetAttrib', function() {
|
||||
var dom;
|
||||
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setAttrib('test', 'class', 'test 123');
|
||||
equal(DOM.getAttrib('test', 'class'), 'test 123');
|
||||
|
||||
DOM.setAttrib('test', 'src', 'url');
|
||||
equal(DOM.getAttrib('test', 'src'), 'url');
|
||||
equal(DOM.getAttrib('test', 'data-mce-src'), 'url');
|
||||
equal(DOM.getAttrib('test', 'abc'), '');
|
||||
|
||||
DOM.setAttribs('test', {'class' : '123', title : 'abc'});
|
||||
equal(DOM.getAttrib('test', 'class'), '123');
|
||||
equal(DOM.getAttrib('test', 'title'), 'abc');
|
||||
|
||||
DOM.setAttribs('test');
|
||||
equal(DOM.getAttrib('test', 'class'), '123');
|
||||
equal(DOM.getAttrib('test', 'title'), 'abc');
|
||||
|
||||
dom = new tinymce.dom.DOMUtils(document, {keep_values : true, url_converter : function(u, n) {
|
||||
return '&<>"' + u + '&<>"' + n;
|
||||
}});
|
||||
|
||||
dom.setAttribs('test', {src : '123', href : 'abc'});
|
||||
equal(DOM.getAttrib('test', 'src'), '&<>"123&<>"src');
|
||||
equal(DOM.getAttrib('test', 'href'), '&<>"abc&<>"href');
|
||||
|
||||
equal(DOM.getAttrib(document, 'test'), false);
|
||||
equal(DOM.getAttrib(document, 'test', ''), '');
|
||||
equal(DOM.getAttrib(document, 'test', 'x'), 'x');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('setGetAttrib on null', function() {
|
||||
strictEqual(DOM.getAttrib(null, 'test'), '');
|
||||
DOM.setAttrib(null, 'test');
|
||||
});
|
||||
|
||||
test('getAttribs', 2, function() {
|
||||
function check(obj, val) {
|
||||
var count = 0;
|
||||
|
||||
val = val.split(',');
|
||||
|
||||
tinymce.each(obj, function(o) {
|
||||
if (tinymce.inArray(val, o.nodeName.toLowerCase()) != -1 && o.specified) {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
return count == obj.length;
|
||||
}
|
||||
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.get('test').innerHTML = '<span id="test2" class="test"></span>';
|
||||
ok(check(DOM.getAttribs('test2'), 'id,class'));
|
||||
|
||||
DOM.get('test').innerHTML = '<input id="test2" type="checkbox" name="test" value="1" disabled readonly checked></span>';
|
||||
ok(check(DOM.getAttribs('test2'), 'id,type,name,value,disabled,readonly,checked'), 'Expected attributed: type,name,disabled,readonly,checked');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('setGetStyles', function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setStyle('test', 'font-size', '20px');
|
||||
equal(DOM.getStyle('test', 'font-size'), '20px');
|
||||
|
||||
DOM.setStyle('test', 'fontSize', '21px');
|
||||
equal(DOM.getStyle('test', 'fontSize'), '21px');
|
||||
|
||||
DOM.setStyles('test', {fontSize : '22px', display : 'inline'});
|
||||
equal(DOM.getStyle('test', 'fontSize'), '22px');
|
||||
equal(DOM.getStyle('test', 'display'), 'inline');
|
||||
|
||||
DOM.setStyle('test', 'fontSize', 23);
|
||||
equal(DOM.getStyle('test', 'fontSize'), '23px');
|
||||
|
||||
DOM.setStyle('test', 'fontSize', 23);
|
||||
DOM.setStyle('test', 'fontSize', '');
|
||||
equal(DOM.getStyle('test', 'fontSize'), '');
|
||||
|
||||
DOM.setStyle('test', 'fontSize', 23);
|
||||
DOM.setStyle('test', 'fontSize', null);
|
||||
equal(DOM.getStyle('test', 'fontSize'), '');
|
||||
|
||||
DOM.setAttrib('test', 'style', '');
|
||||
equal(typeof DOM.getStyle(null, 'fontSize'), 'undefined');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('getPos', 2, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setStyles('test', {position : 'absolute', left : 100, top : 110});
|
||||
equal(DOM.getPos('test').x, 100);
|
||||
equal(DOM.getPos('test').y, 110);
|
||||
|
||||
DOM.setAttrib('test', 'style', '');
|
||||
|
||||
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', 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);
|
||||
|
||||
DOM.get('test').innerHTML = '';
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('getParents', 4, function() {
|
||||
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', 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);
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('is', 2, function() {
|
||||
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>';
|
||||
|
||||
ok(DOM.is(DOM.select('span', 'test'), 'span'));
|
||||
ok(DOM.is(DOM.select('#test2', 'test'), '#test2'));
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('getViewPort', 4, function() {
|
||||
var wp;
|
||||
|
||||
wp = DOM.getViewPort();
|
||||
equal(wp.x, 0);
|
||||
equal(wp.y, 0);
|
||||
ok(wp.w > 0);
|
||||
ok(wp.h > 0);
|
||||
});
|
||||
|
||||
test('getRect', 5, function() {
|
||||
var r;
|
||||
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setStyles('test', {position : 'absolute', left : 100, top : 110, width : 320, height : 240});
|
||||
r = DOM.getRect('test');
|
||||
equal(r.x, 100);
|
||||
equal(r.y, 110);
|
||||
equal(r.w, 320);
|
||||
equal(r.h, 240);
|
||||
|
||||
DOM.setAttrib('test', 'style', '');
|
||||
|
||||
DOM.get('test').innerHTML = '<div style="width:320px;height:240px"><div id="test2" style="width:50%;height:240px"></div></div>';
|
||||
r = DOM.getRect('test2');
|
||||
equal(r.w, 160);
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('getSize', 2, function() {
|
||||
var r;
|
||||
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.get('test').innerHTML = '<div style="width:320px;height:240px"><div id="test2" style="width:50%;height:240px"></div></div>';
|
||||
r = DOM.getSize('test2');
|
||||
equal(r.w, 160);
|
||||
|
||||
DOM.get('test').innerHTML = '<div style="width:320px;height:240px"><div id="test2" style="width:100px;height:240px"></div></div>';
|
||||
r = DOM.getSize('test2');
|
||||
equal(r.w, 100);
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('getNext', 5, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.get('test').innerHTML = '<strong>A</strong><span>B</span><em>C</em>';
|
||||
equal(DOM.getNext(DOM.get('test').firstChild, '*').nodeName, 'SPAN');
|
||||
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, eqNodeName('EM')).nodeName, 'EM');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('getPrev', 5, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.get('test').innerHTML = '<strong>A</strong><span>B</span><em>C</em>';
|
||||
equal(DOM.getPrev(DOM.get('test').lastChild, '*').nodeName, 'SPAN');
|
||||
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, eqNodeName('STRONG')).nodeName, 'STRONG');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('loadCSS', 1, function() {
|
||||
var c = 0;
|
||||
|
||||
DOM.loadCSS('tinymce/dom/test.css?a=1,tinymce/dom/test.css?a=2,tinymce/dom/test.css?a=3');
|
||||
|
||||
tinymce.each(document.getElementsByTagName('link'), function(n) {
|
||||
if (n.href.indexOf('test.css?a=') != -1) {
|
||||
c++;
|
||||
}
|
||||
});
|
||||
|
||||
equal(c, 3, null, tinymce.isOpera);
|
||||
});
|
||||
|
||||
test('insertAfter', 2, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"></span>');
|
||||
DOM.insertAfter(DOM.create('br'), 'test2');
|
||||
equal(DOM.get('test2').nextSibling.nodeName, 'BR');
|
||||
|
||||
DOM.setHTML('test', '<span>test</span><span id="test2"></span><span>test</span>');
|
||||
DOM.insertAfter(DOM.create('br'), 'test2');
|
||||
equal(DOM.get('test2').nextSibling.nodeName, 'BR');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('isBlock', 4, function() {
|
||||
ok(DOM.isBlock(DOM.create('div')));
|
||||
ok(DOM.isBlock('DIV'));
|
||||
ok(!DOM.isBlock('SPAN'));
|
||||
ok(DOM.isBlock('div'));
|
||||
});
|
||||
|
||||
test('remove', 2, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
DOM.remove('test2', 1);
|
||||
equal(DOM.get('test').innerHTML.toLowerCase(), '<span>test</span><span>test2</span>');
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
equal(DOM.remove('test2').nodeName, 'SPAN');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('replace', 2, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
DOM.replace(DOM.create('div', {id : 'test2'}), 'test2', 1);
|
||||
equal(DOM.get('test2').innerHTML.toLowerCase(), '<span>test</span><span>test2</span>');
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
DOM.replace(DOM.create('div', {id : 'test2'}), 'test2');
|
||||
equal(DOM.get('test2').innerHTML, '');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('toHex', 5, function() {
|
||||
equal(DOM.toHex('rgb(0, 255, 255)'), '#00ffff');
|
||||
equal(DOM.toHex('rgb(255, 0, 0)'), '#ff0000');
|
||||
equal(DOM.toHex('rgb(0, 0, 255)'), '#0000ff');
|
||||
equal(DOM.toHex('rgb ( 0 , 0 , 255 ) '), '#0000ff');
|
||||
equal(DOM.toHex(' RGB ( 0 , 0 , 255 ) '), '#0000ff');
|
||||
});
|
||||
|
||||
test('getOuterHTML', 4, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
equal(DOM.getOuterHTML('test2').toLowerCase().replace(/\"/g, ''), '<span id=test2><span>test</span><span>test2</span></span>');
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
DOM.setOuterHTML('test2', '<div id="test2">123</div>');
|
||||
equal(tinymce.trim(DOM.getOuterHTML('test2') || '').toLowerCase().replace(/\"/g, ''), '<div id=test2>123</div>');
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
DOM.setOuterHTML('test2', '<div id="test2">123</div><div id="test3">abc</div>');
|
||||
equal(tinymce.trim(DOM.get('test').innerHTML).toLowerCase().replace(/>\s+</g, '><').replace(/\"/g, ''), '<div id=test2>123</div><div id=test3>abc</div>');
|
||||
|
||||
DOM.setHTML('test', 'test');
|
||||
equal(tinymce.trim(DOM.getOuterHTML(DOM.get('test').firstChild)), 'test');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('encodeDecode', 2, function() {
|
||||
equal(DOM.encode('\u00e5\u00e4\u00f6&<>"'), '\u00e5\u00e4\u00f6&<>"');
|
||||
equal(DOM.decode('åäö&<>"'), '\u00e5\u00e4\u00f6&<>"');
|
||||
});
|
||||
|
||||
test('split', 2, function() {
|
||||
var point, parent;
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setHTML('test', '<p><b>text1<span>inner</span>text2</b></p>');
|
||||
parent = DOM.select('p', DOM.get('test'))[0];
|
||||
point = DOM.select('span', DOM.get('test'))[0];
|
||||
DOM.split(parent, point);
|
||||
equal(DOM.get('test').innerHTML.toLowerCase().replace(/\s+/g, ''), '<p><b>text1</b></p><span>inner</span><p><b>text2</b></p>');
|
||||
|
||||
DOM.setHTML('test', '<ul><li>first line<br><ul><li><span>second</span> <span>line</span></li><li>third line<br></li></ul></li></ul>');
|
||||
parent = DOM.select('li:nth-child(1)', DOM.get('test'))[0];
|
||||
point = DOM.select('ul li:nth-child(2)', DOM.get('test'))[0];
|
||||
DOM.split(parent, point);
|
||||
equal(Utils.cleanHtml(DOM.get('test').innerHTML), '<ul><li>first line<br><ul><li><span>second</span> <span>line</span></li></ul></li><li>third line<br></li></ul>');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('nodeIndex', 5, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'}, 'abc<b>abc</b>abc');
|
||||
|
||||
equal(DOM.nodeIndex(DOM.get('test').childNodes[0]), 0, 'Index of first child.');
|
||||
equal(DOM.nodeIndex(DOM.get('test').childNodes[1]), 1, 'Index of second child.');
|
||||
equal(DOM.nodeIndex(DOM.get('test').childNodes[2]), 2, 'Index of third child.');
|
||||
|
||||
DOM.get('test').insertBefore(DOM.doc.createTextNode('a'), DOM.get('test').firstChild);
|
||||
DOM.get('test').insertBefore(DOM.doc.createTextNode('b'), DOM.get('test').firstChild);
|
||||
|
||||
equal(DOM.nodeIndex(DOM.get('test').lastChild), 4, 'Index of last child with fragmented DOM.');
|
||||
equal(DOM.nodeIndex(DOM.get('test').lastChild, true), 2, 'Normalized index of last child with fragmented DOM.');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
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'}, '');
|
||||
|
||||
ok(DOM.isEmpty(DOM.get('test')), 'No children');
|
||||
|
||||
DOM.setHTML('test', '<br />');
|
||||
ok(DOM.isEmpty(DOM.get('test')), 'Br child');
|
||||
|
||||
DOM.setHTML('test', '<br /><br />');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Br children');
|
||||
|
||||
DOM.setHTML('test', 'text');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Text child');
|
||||
|
||||
DOM.setHTML('test', '<span>text</span>');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Text child in span');
|
||||
|
||||
DOM.setHTML('test', '<span></span>');
|
||||
ok(DOM.isEmpty(DOM.get('test')), 'Empty span child');
|
||||
|
||||
DOM.setHTML('test', '<div><span><b></b></span><b></b><em></em></div>');
|
||||
ok(DOM.isEmpty(DOM.get('test')), 'Empty complex HTML');
|
||||
|
||||
DOM.setHTML('test', '<div><span><b></b></span><b></b><em>X</em></div>');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Non empty complex HTML');
|
||||
|
||||
DOM.setHTML('test', '<div><span><b></b></span><b></b><em> </em></div>');
|
||||
ok(DOM.isEmpty(DOM.get('test')), 'Non empty complex HTML with space');
|
||||
|
||||
DOM.setHTML('test', '<div><span><b></b></span><b></b><em><a name="x"></a></em></div>');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Non empty complex HTML with achor name');
|
||||
|
||||
DOM.setHTML('test', '<img src="tinymce/ui/img/raster.gif">');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Non empty html with img element');
|
||||
|
||||
DOM.setHTML('test', '<span data-mce-bookmark="1"></span>');
|
||||
ok(!DOM.isEmpty(DOM.get('test')), 'Span with bookmark attribute.');
|
||||
|
||||
DOM.setHTML('test', '<span data-mce-style="color:Red"></span>');
|
||||
ok(DOM.isEmpty(DOM.get('test')), 'Span with data-mce attribute.');
|
||||
|
||||
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');
|
||||
});
|
||||
|
||||
test('isEmpty with list of elements considered non-empty', function() {
|
||||
var elm = DOM.create('p', null, '<img>');
|
||||
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});
|
||||
|
||||
var elm = domWithoutSchema.create('p', null, '<img>');
|
||||
equal(false, domWithoutSchema.isEmpty(elm, {img: true}));
|
||||
});
|
||||
|
||||
test('isEmpty on P with BR in EM', function() {
|
||||
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));
|
||||
});
|
||||
|
||||
test('bind/unbind/fire', function() {
|
||||
var count = 0;
|
||||
|
||||
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.fire(document, 'click');
|
||||
DOM.fire(window, 'click');
|
||||
DOM.unbind([document, window], 'click');
|
||||
equal(count, 2);
|
||||
|
||||
count = 0;
|
||||
DOM.fire(document, 'click');
|
||||
DOM.fire(window, 'click');
|
||||
equal(count, 0);
|
||||
});
|
||||
|
||||
DOM.remove('test');
|
||||
})();
|
||||
@ -1,34 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/util/Arr",
|
||||
"tinymce/dom/Dimensions"
|
||||
], function(Arr, Dimensions) {
|
||||
module("tinymce.dom.Dimensions");
|
||||
|
||||
function setupHtml(html) {
|
||||
var viewElm;
|
||||
|
||||
viewElm = document.getElementById('view');
|
||||
viewElm.innerHTML = html;
|
||||
|
||||
return viewElm;
|
||||
}
|
||||
|
||||
test('getClientRects', function() {
|
||||
var viewElm = setupHtml('abc<span>123</span>');
|
||||
|
||||
strictEqual(Dimensions.getClientRects(viewElm.firstChild).length, 1);
|
||||
strictEqual(Dimensions.getClientRects(viewElm.lastChild).length, 1);
|
||||
strictEqual(Dimensions.getClientRects(viewElm.firstChild)[0].node, viewElm.firstChild);
|
||||
strictEqual(Dimensions.getClientRects(viewElm.firstChild)[0].left > 3, true);
|
||||
strictEqual(Dimensions.getClientRects(viewElm.lastChild)[0].left > 3, true);
|
||||
});
|
||||
|
||||
test('getClientRects from array', function() {
|
||||
var viewElm = setupHtml('<b>a</b><b>b</b>'),
|
||||
clientRects = Dimensions.getClientRects(Arr.toArray(viewElm.childNodes));
|
||||
|
||||
strictEqual(clientRects.length, 2);
|
||||
strictEqual(clientRects[0].node, viewElm.childNodes[0]);
|
||||
strictEqual(clientRects[1].node, viewElm.childNodes[1]);
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,443 +0,0 @@
|
||||
var eventUtils = tinymce.dom.Event;
|
||||
|
||||
module("tinymce.dom.Event", {
|
||||
setupModule: function() {
|
||||
document.getElementById('view').innerHTML = (
|
||||
'<div id="content" tabindex="0">' +
|
||||
'<div id="inner" tabindex="0"></div>' +
|
||||
'</div>'
|
||||
);
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
eventUtils.clean(window);
|
||||
}
|
||||
});
|
||||
|
||||
test("unbind all", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'click', function() {
|
||||
result.click = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'keydown', function() {
|
||||
result.keydown1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'keydown', function() {
|
||||
result.keydown2 = true;
|
||||
});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(window, 'click');
|
||||
eventUtils.fire(window, 'keydown');
|
||||
deepEqual(result, {click: true, keydown1: true, keydown2: true});
|
||||
|
||||
eventUtils.unbind(window);
|
||||
result = {};
|
||||
eventUtils.fire(window, 'click');
|
||||
eventUtils.fire(window, 'keydown');
|
||||
deepEqual(result, {});
|
||||
});
|
||||
|
||||
test("unbind event", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'click', function() {
|
||||
result.click = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'keydown', function() {
|
||||
result.keydown1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'keydown', function() {
|
||||
result.keydown2 = true;
|
||||
});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(window, 'click');
|
||||
eventUtils.fire(window, 'keydown');
|
||||
deepEqual(result, {click: true, keydown1: true, keydown2: true});
|
||||
|
||||
eventUtils.unbind(window, 'click');
|
||||
result = {};
|
||||
eventUtils.fire(window, 'click');
|
||||
eventUtils.fire(window, 'keydown');
|
||||
deepEqual(result, {keydown1: true, keydown2: true});
|
||||
});
|
||||
|
||||
test("unbind event non existing", function() {
|
||||
eventUtils.unbind(window, 'noevent');
|
||||
ok(true, "No exception");
|
||||
});
|
||||
|
||||
test("unbind callback", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'click', function() {
|
||||
result.click = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'keydown', function() {
|
||||
result.keydown1 = true;
|
||||
});
|
||||
|
||||
function callback2() {
|
||||
result.keydown2 = true;
|
||||
}
|
||||
|
||||
eventUtils.bind(window, 'keydown', callback2);
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(window, 'click');
|
||||
eventUtils.fire(window, 'keydown');
|
||||
deepEqual(result, {click: true, keydown1: true, keydown2: true});
|
||||
|
||||
eventUtils.unbind(window, 'keydown', callback2);
|
||||
result = {};
|
||||
eventUtils.fire(window, 'click');
|
||||
eventUtils.fire(window, 'keydown');
|
||||
deepEqual(result, {click: true, keydown1: true});
|
||||
});
|
||||
|
||||
test("unbind multiple", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'mouseup mousedown click', function(e) {
|
||||
result[e.type] = true;
|
||||
});
|
||||
|
||||
eventUtils.unbind(window, 'mouseup mousedown');
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(window, 'mouseup');
|
||||
eventUtils.fire(window, 'mousedown');
|
||||
eventUtils.fire(window, 'click');
|
||||
deepEqual(result, {click: true});
|
||||
});
|
||||
|
||||
test("bind multiple", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'mouseup mousedown', function(e) {
|
||||
result[e.type] = true;
|
||||
});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(window, 'mouseup');
|
||||
eventUtils.fire(window, 'mousedown');
|
||||
eventUtils.fire(window, 'click');
|
||||
deepEqual(result, {mouseup: true, mousedown: true});
|
||||
});
|
||||
|
||||
test("bind/fire bubbling", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'click', function() {
|
||||
result.window = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document, 'click', function() {
|
||||
result.document = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.body, 'click', function() {
|
||||
result.body = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('content'), 'click', function() {
|
||||
result.content = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('inner'), 'click', function() {
|
||||
result.inner = true;
|
||||
});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(window, 'click');
|
||||
deepEqual(result, {window: true});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(document, 'click');
|
||||
deepEqual(result, {document: true, window: true});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(document.body, 'click');
|
||||
deepEqual(result, {body: true, document: true, window: true});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(document.getElementById('content'), 'click');
|
||||
deepEqual(result, {content: true, body: true, document: true, window: true});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(document.getElementById('inner'), 'click');
|
||||
deepEqual(result, {inner: true, content: true, body: true, document: true, window: true});
|
||||
});
|
||||
|
||||
test("bind/fire stopImmediatePropagation", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'click', function() {
|
||||
result.click1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'click', function(e) {
|
||||
result.click2 = true;
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'click', function() {
|
||||
result.click3 = true;
|
||||
});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(window, 'click');
|
||||
deepEqual(result, {click1: true, click2: true});
|
||||
});
|
||||
|
||||
test("bind/fire stopPropagation", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'click', function() {
|
||||
result.click1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.body, 'click', function() {
|
||||
result.click2 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('inner'), 'click', function(e) {
|
||||
result.click3 = true;
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(document.getElementById('inner'), 'click');
|
||||
deepEqual(result, {click3: true});
|
||||
});
|
||||
|
||||
test("clean window", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'click', function() {
|
||||
result.click1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.body, 'click', function() {
|
||||
result.click2 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('content'), 'click', function() {
|
||||
result.click3 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('inner'), 'click', function() {
|
||||
result.click4 = true;
|
||||
});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(document.getElementById('inner'), 'click');
|
||||
deepEqual(result, {click1: true, click2: true, click3: true, click4: true});
|
||||
|
||||
eventUtils.clean(window);
|
||||
result = {};
|
||||
eventUtils.fire(document.getElementById('inner'), 'click');
|
||||
deepEqual(result, {});
|
||||
});
|
||||
|
||||
test("clean document", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'click', function() {
|
||||
result.click1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document, 'click', function() {
|
||||
result.click2 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.body, 'click', function() {
|
||||
result.click3 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('content'), 'click', function() {
|
||||
result.click4 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('inner'), 'click', function() {
|
||||
result.click5 = true;
|
||||
});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(document.getElementById('inner'), 'click');
|
||||
deepEqual(result, {click1: true, click2: true, click3: true, click4: true, click5: true});
|
||||
|
||||
eventUtils.clean(document);
|
||||
result = {};
|
||||
eventUtils.fire(document.getElementById('inner'), 'click');
|
||||
deepEqual(result, {click1: true});
|
||||
});
|
||||
|
||||
test("clean element", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'click', function() {
|
||||
result.click1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.body, 'click', function() {
|
||||
result.click2 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('content'), 'click', function() {
|
||||
result.click3 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('inner'), 'click', function() {
|
||||
result.click4 = true;
|
||||
});
|
||||
|
||||
result = {};
|
||||
eventUtils.fire(document.getElementById('inner'), 'click');
|
||||
deepEqual(result, {click1: true, click2: true, click3: true, click4: true});
|
||||
|
||||
eventUtils.clean(document.getElementById('content'));
|
||||
result = {};
|
||||
eventUtils.fire(document.getElementById('inner'), 'click');
|
||||
deepEqual(result, {click1: true, click2: true});
|
||||
});
|
||||
|
||||
test("mouseenter/mouseleave bind/unbind", function() {
|
||||
var result = {};
|
||||
|
||||
eventUtils.bind(document.body, 'mouseenter mouseleave', function(e) {
|
||||
result[e.type] = true;
|
||||
});
|
||||
|
||||
eventUtils.fire(document.body, 'mouseenter');
|
||||
eventUtils.fire(document.body, 'mouseleave');
|
||||
|
||||
deepEqual(result, {mouseenter: true, mouseleave: true});
|
||||
|
||||
result = {};
|
||||
eventUtils.clean(document.body);
|
||||
eventUtils.fire(document.body, 'mouseenter');
|
||||
eventUtils.fire(document.body, 'mouseleave');
|
||||
deepEqual(result, {});
|
||||
});
|
||||
|
||||
/*
|
||||
asyncTest("focusin/focusout bind/unbind", function() {
|
||||
var result = {};
|
||||
|
||||
window.setTimeout(function() {
|
||||
eventUtils.bind(document.body, 'focusin focusout', function(e) {
|
||||
// IE will fire a focusout on the parent element if you focus an element within not a big deal so lets detect it in the test
|
||||
if (e.type == "focusout" && e.target.contains(document.activeElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
result[e.type] = result[e.type] ? ++result[e.type] : 1;
|
||||
});
|
||||
|
||||
start();
|
||||
document.getElementById('content').focus();
|
||||
document.getElementById('inner').focus();
|
||||
|
||||
deepEqual(result, {focusin: 2, focusout: 1});
|
||||
}, 0);
|
||||
});
|
||||
*/
|
||||
|
||||
test("bind unbind fire clean on null", function() {
|
||||
eventUtils.bind(null, 'click', function() {});
|
||||
eventUtils.unbind(null, 'click', function() {});
|
||||
eventUtils.fire(null, {});
|
||||
eventUtils.clean(null);
|
||||
ok(true, "No exception");
|
||||
});
|
||||
|
||||
test("bind ready when page is loaded", function() {
|
||||
var ready;
|
||||
|
||||
eventUtils.bind(window, 'ready', function() {
|
||||
ready = true;
|
||||
});
|
||||
|
||||
ok(eventUtils.domLoaded, "DomLoaded state true");
|
||||
ok(ready, "Window is ready.");
|
||||
});
|
||||
|
||||
test("event states when event object is fired twice", function() {
|
||||
var result = {};
|
||||
|
||||
eventUtils.bind(window, 'keydown', function(e) {result[e.type] = true;e.preventDefault();e.stopPropagation();});
|
||||
eventUtils.bind(window, 'keyup', function(e) {result[e.type] = true;e.stopImmediatePropagation();});
|
||||
|
||||
var event = {};
|
||||
eventUtils.fire(window, 'keydown', event);
|
||||
eventUtils.fire(window, 'keyup', event);
|
||||
|
||||
ok(event.isDefaultPrevented(), "Default is prevented.");
|
||||
ok(event.isPropagationStopped(), "Propagation is stopped.");
|
||||
ok(event.isImmediatePropagationStopped(), "Immediate propagation is stopped.");
|
||||
|
||||
deepEqual(result, {keydown: true, keyup: true});
|
||||
});
|
||||
|
||||
test("unbind inside callback", function() {
|
||||
var data;
|
||||
|
||||
function append(value) {
|
||||
return function() {
|
||||
data += value;
|
||||
};
|
||||
}
|
||||
|
||||
function callback() {
|
||||
eventUtils.unbind(window, 'click', callback);
|
||||
data += 'b';
|
||||
}
|
||||
|
||||
data = '';
|
||||
eventUtils.bind(window, 'click', append("a"));
|
||||
eventUtils.bind(window, 'click', callback);
|
||||
eventUtils.bind(window, 'click', append("c"));
|
||||
|
||||
eventUtils.fire(window, 'click', {});
|
||||
equal(data, 'abc');
|
||||
|
||||
data = '';
|
||||
eventUtils.fire(window, 'click', {});
|
||||
equal(data, 'ac');
|
||||
});
|
||||
|
||||
test("ready/DOMContentLoaded (domLoaded = true)", function() {
|
||||
var evt;
|
||||
|
||||
eventUtils.bind(window, "ready", function(e) {evt = e;});
|
||||
equal(evt.type, "ready");
|
||||
});
|
||||
|
||||
test("ready/DOMContentLoaded (document.readyState check)", function() {
|
||||
var evt;
|
||||
|
||||
try {
|
||||
document.readyState = "loading";
|
||||
} catch (e) {
|
||||
ok(true, "IE doesn't allow us to set document.readyState");
|
||||
return;
|
||||
}
|
||||
|
||||
eventUtils.domLoaded = false;
|
||||
document.readyState = "loading";
|
||||
eventUtils.bind(window, "ready", function(e) {evt = e;});
|
||||
ok(typeof(evt) !== "undefined");
|
||||
|
||||
eventUtils.domLoaded = false;
|
||||
document.readyState = "complete";
|
||||
eventUtils.bind(window, "ready", function(e) {evt = e;});
|
||||
equal(evt.type, "ready");
|
||||
});
|
||||
@ -1,29 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/dom/NodePath"
|
||||
], function(NodePath) {
|
||||
module("tinymce.dom.NodePath", {});
|
||||
|
||||
function getRoot() {
|
||||
return document.getElementById('view');
|
||||
}
|
||||
|
||||
function setupHtml(html) {
|
||||
getRoot().innerHTML = html;
|
||||
}
|
||||
|
||||
test("create", function() {
|
||||
setupHtml('<p>a<b>12<input></b></p>');
|
||||
|
||||
deepEqual(NodePath.create(getRoot(), getRoot().firstChild), [0]);
|
||||
deepEqual(NodePath.create(getRoot(), getRoot().firstChild.firstChild), [0, 0]);
|
||||
deepEqual(NodePath.create(getRoot(), getRoot().firstChild.lastChild.lastChild), [1, 1, 0]);
|
||||
});
|
||||
|
||||
test("resolve", function() {
|
||||
setupHtml('<p>a<b>12<input></b></p>');
|
||||
|
||||
deepEqual(NodePath.resolve(getRoot(), NodePath.create(getRoot(), getRoot().firstChild)), getRoot().firstChild);
|
||||
deepEqual(NodePath.resolve(getRoot(), NodePath.create(getRoot(), getRoot().firstChild.firstChild)), getRoot().firstChild.firstChild);
|
||||
deepEqual(NodePath.resolve(getRoot(), NodePath.create(getRoot(), getRoot().firstChild.lastChild.lastChild)), getRoot().firstChild.lastChild.lastChild);
|
||||
});
|
||||
});
|
||||
@ -1,81 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/dom/NodeType",
|
||||
"tinymce/dom/DomQuery"
|
||||
], function(NodeType, $) {
|
||||
module("tinymce.dom.NodeType");
|
||||
|
||||
test('isText/isElement/isComment', function() {
|
||||
strictEqual(NodeType.isText(document.createTextNode("x")), true);
|
||||
strictEqual(NodeType.isText(null), false);
|
||||
strictEqual(NodeType.isText(document.createElement("div")), false);
|
||||
strictEqual(NodeType.isText(document.createComment("x")), false);
|
||||
|
||||
strictEqual(NodeType.isElement(document.createElement("div")), true);
|
||||
strictEqual(NodeType.isElement(null), false);
|
||||
strictEqual(NodeType.isElement(document.createTextNode("x")), false);
|
||||
strictEqual(NodeType.isElement(document.createComment("x")), false);
|
||||
|
||||
strictEqual(NodeType.isComment(document.createComment("x")), true);
|
||||
strictEqual(NodeType.isComment(null), false);
|
||||
strictEqual(NodeType.isComment(document.createTextNode("x")), false);
|
||||
strictEqual(NodeType.isComment(document.createElement("div")), false);
|
||||
});
|
||||
|
||||
test('isBr', function() {
|
||||
strictEqual(NodeType.isBr(null), false);
|
||||
strictEqual(NodeType.isBr(document.createTextNode("x")), false);
|
||||
strictEqual(NodeType.isBr(document.createElement('br')), true);
|
||||
strictEqual(NodeType.isBr(document.createComment("x")), false);
|
||||
});
|
||||
|
||||
test('isContentEditableTrue', function() {
|
||||
strictEqual(NodeType.isContentEditableTrue(null), false);
|
||||
strictEqual(NodeType.isContentEditableTrue(document.createComment("x")), false);
|
||||
strictEqual(NodeType.isContentEditableTrue(document.createTextNode("x")), false);
|
||||
strictEqual(NodeType.isContentEditableTrue(document.createElement('div')), false);
|
||||
strictEqual(NodeType.isContentEditableTrue($('<div contentEditable="true"></div>')[0]), true);
|
||||
strictEqual(NodeType.isContentEditableTrue($('<div contentEditable="trUe"></div>')[0]), true);
|
||||
strictEqual(NodeType.isContentEditableTrue($('<div contentEditable="false"></div>')[0]), false);
|
||||
strictEqual(NodeType.isContentEditableTrue($('<div contentEditable="fAlse"></div>')[0]), false);
|
||||
strictEqual(NodeType.isContentEditableTrue($('<div contentEditable="inherit"></div>')[0]), false);
|
||||
});
|
||||
|
||||
test('isContentEditableFalse', function() {
|
||||
strictEqual(NodeType.isContentEditableFalse(null), false);
|
||||
strictEqual(NodeType.isContentEditableFalse(document.createComment("x")), false);
|
||||
strictEqual(NodeType.isContentEditableFalse(document.createTextNode("x")), false);
|
||||
strictEqual(NodeType.isContentEditableFalse(document.createElement('div')), false);
|
||||
strictEqual(NodeType.isContentEditableFalse($('<div contentEditable="true"></div>')[0]), false);
|
||||
strictEqual(NodeType.isContentEditableFalse($('<div contentEditable="trUe"></div>')[0]), false);
|
||||
strictEqual(NodeType.isContentEditableFalse($('<div contentEditable="false"></div>')[0]), true);
|
||||
strictEqual(NodeType.isContentEditableFalse($('<div contentEditable="fAlse"></div>')[0]), true);
|
||||
strictEqual(NodeType.isContentEditableFalse($('<div contentEditable="inherit"></div>')[0]), false);
|
||||
});
|
||||
|
||||
test('matchNodeNames', function() {
|
||||
var matchNodeNames = NodeType.matchNodeNames('a div #text');
|
||||
|
||||
strictEqual(matchNodeNames(null), false);
|
||||
strictEqual(matchNodeNames(document.createTextNode('x')), true);
|
||||
strictEqual(matchNodeNames(document.createElement('a')), true);
|
||||
strictEqual(matchNodeNames(document.createElement('div')), true);
|
||||
strictEqual(matchNodeNames(document.createElement('b')), false);
|
||||
});
|
||||
|
||||
test('hasPropValue', function() {
|
||||
var hasTabIndex3 = NodeType.hasPropValue('tabIndex', 3);
|
||||
|
||||
strictEqual(hasTabIndex3(null), false);
|
||||
strictEqual(hasTabIndex3($('<div tabIndex="3"></div>')[0]), true);
|
||||
strictEqual(hasTabIndex3(document.createElement('div')), false);
|
||||
strictEqual(hasTabIndex3(document.createElement('b')), false);
|
||||
});
|
||||
|
||||
test('isBogus', function() {
|
||||
strictEqual(NodeType.isBogus($('<div data-mce-bogus="1"></div>')[0]), true);
|
||||
strictEqual(NodeType.isBogus($('<div data-mce-bogus="all"></div>')[0]), true);
|
||||
strictEqual(NodeType.isBogus($('<div></div>')[0]), false);
|
||||
strictEqual(NodeType.isBogus(document.createTextNode('test')), false);
|
||||
strictEqual(NodeType.isBogus(null), false);
|
||||
});
|
||||
});
|
||||
@ -1,550 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/dom/Range"
|
||||
], function(Range) {
|
||||
module("tinymce.dom.Range", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = (
|
||||
'<div id="sample">' +
|
||||
'<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p>' +
|
||||
'<p id="second">bar</p>' +
|
||||
'<p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p>' +
|
||||
'<table id="table">' +
|
||||
'<tr>' +
|
||||
'<td>1</td>' +
|
||||
'<td id="two">abc</td>' +
|
||||
'</tr>' +
|
||||
'<tr>' +
|
||||
'<td>3</td>' +
|
||||
'<td>4</td>' +
|
||||
'</tr>' +
|
||||
'</table>' +
|
||||
'<p id="last">textabc<span>span</span></p>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
function createRng() {
|
||||
return document.createRange ? document.createRange() : new Range(tinymce.DOM);
|
||||
}
|
||||
|
||||
function getHTML(co) {
|
||||
var div = document.createElement('div'), h;
|
||||
|
||||
if (!co) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
div.appendChild(co.cloneNode(true));
|
||||
h = div.innerHTML.toLowerCase();
|
||||
|
||||
h = h.replace(/[\r\n\t]/g, ''); // Remove line feeds and tabs
|
||||
h = h.replace(/ (\w+)=([^\"][^\s>]*)/gi, ' $1="$2"'); // Restore attribs on IE
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
test("Initial state", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(5);
|
||||
|
||||
equal(r.startContainer, document);
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer, document);
|
||||
equal(r.endOffset, 0);
|
||||
equal(r.commonAncestorContainer, document);
|
||||
});
|
||||
|
||||
test("setStartSetEnd", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(12);
|
||||
|
||||
r.setStart(document.getElementById('first').firstChild, 1);
|
||||
r.setEnd(document.getElementById('strong').firstChild, 3);
|
||||
|
||||
equal(r.startContainer.nodeValue, 'first');
|
||||
equal(r.startContainer.nodeType, 3);
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endContainer.nodeValue, 'strong');
|
||||
equal(r.endContainer.nodeType, 3);
|
||||
equal(r.endOffset, 3);
|
||||
equal(r.commonAncestorContainer.nodeName, 'P');
|
||||
|
||||
r.setStart(document.getElementById('first'), 0);
|
||||
r.setEnd(document.getElementById('strong'), 0);
|
||||
|
||||
equal(r.startContainer.nodeName, 'P');
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeName, 'STRONG');
|
||||
equal(r.endOffset, 0);
|
||||
equal(r.commonAncestorContainer.nodeName, 'P');
|
||||
});
|
||||
|
||||
test("setStartBeforeSetEndAfter", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(5);
|
||||
|
||||
r.setStartBefore(document.getElementById('first'));
|
||||
r.setEndAfter(document.getElementById('strong'));
|
||||
|
||||
equal(r.startContainer.nodeName, 'DIV');
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeName, 'P');
|
||||
equal(r.endOffset, 5);
|
||||
equal(r.commonAncestorContainer.nodeName, 'DIV');
|
||||
});
|
||||
|
||||
test("test_setStartAfterSetEndBefore", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(5);
|
||||
|
||||
r.setStartAfter(document.getElementById('strong'));
|
||||
r.setEndBefore(document.getElementById('em1'));
|
||||
|
||||
equal(r.startContainer.nodeName, 'P');
|
||||
equal(r.startOffset, 5);
|
||||
equal(r.endContainer.nodeName, 'P');
|
||||
equal(r.endOffset, 6);
|
||||
equal(r.commonAncestorContainer.nodeName, 'P');
|
||||
});
|
||||
|
||||
test("test_collapse", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(10);
|
||||
|
||||
r.setStart(document.getElementById('strong').firstChild, 0);
|
||||
r.setEnd(document.getElementById('strong').firstChild, 6);
|
||||
|
||||
r.collapse(true);
|
||||
|
||||
equal(r.startContainer.nodeType, 3);
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 3);
|
||||
equal(r.endOffset, 0);
|
||||
equal(r.commonAncestorContainer.nodeType, 3);
|
||||
|
||||
r.setStart(document.getElementById('strong').firstChild, 0);
|
||||
r.setEnd(document.getElementById('strong').firstChild, 6);
|
||||
|
||||
r.collapse(false);
|
||||
|
||||
equal(r.startContainer.nodeType, 3);
|
||||
equal(r.startOffset, 6);
|
||||
equal(r.endContainer.nodeType, 3);
|
||||
equal(r.endOffset, 6);
|
||||
equal(r.commonAncestorContainer.nodeType, 3);
|
||||
});
|
||||
|
||||
test("test_selectNode", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(4);
|
||||
|
||||
r.selectNode(document.getElementById('strong').firstChild);
|
||||
|
||||
equal(r.startContainer.nodeType, 1);
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 1);
|
||||
});
|
||||
|
||||
test("test_selectNodeContents", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(8);
|
||||
|
||||
r.selectNodeContents(document.getElementById('strong').firstChild);
|
||||
|
||||
equal(r.startContainer.nodeType, 3);
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 3);
|
||||
equal(r.endOffset, 6);
|
||||
|
||||
r.selectNodeContents(document.getElementById('first'));
|
||||
|
||||
equal(r.startContainer.nodeType, 1);
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 8);
|
||||
});
|
||||
|
||||
test("test_insertNode", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(4);
|
||||
|
||||
r.setStart(document.getElementById('first').firstChild, 1);
|
||||
r.setEnd(document.getElementById('first').firstChild, 2);
|
||||
r.insertNode(document.createTextNode('ABC'));
|
||||
|
||||
equal(document.getElementById('first').childNodes[0].nodeValue, 'f');
|
||||
equal(document.getElementById('first').childNodes[1].nodeValue, 'ABC');
|
||||
equal(document.getElementById('first').childNodes[2].nodeValue, 'irst');
|
||||
|
||||
r.selectNode(document.getElementById('strong'));
|
||||
r.insertNode(document.createElement('span'));
|
||||
|
||||
equal(document.getElementById('strong').previousSibling.nodeName, 'SPAN');
|
||||
});
|
||||
|
||||
test("test_cloneRange", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(6);
|
||||
|
||||
r.setStart(document.getElementById('first').firstChild, 1);
|
||||
r.setEnd(document.getElementById('strong').firstChild, 2);
|
||||
|
||||
var r2 = r.cloneRange();
|
||||
|
||||
equal(r2.startContainer.nodeType, 3);
|
||||
equal(r2.startOffset, 1);
|
||||
equal(r2.endContainer.nodeType, 3);
|
||||
equal(r2.endOffset, 2);
|
||||
equal(r2.collapsed, false);
|
||||
equal(r2.commonAncestorContainer.nodeName, 'P');
|
||||
});
|
||||
|
||||
if (tinymce.isGecko) {
|
||||
test('test_cloneContents (SKIPPED)', function() {
|
||||
ok(true, 'Before Firefox 3.6 this test fails because of a corner case bug but since the point is to test the IE Range implementation we skip it.');
|
||||
});
|
||||
} else {
|
||||
test("test_cloneContents", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(77);
|
||||
|
||||
r.setStart(document.getElementById('first').firstChild, 1);
|
||||
r.setEnd(document.getElementById('two').firstChild, 2);
|
||||
|
||||
equal(getHTML(r.cloneContents()), '<p id="first">irst<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">ab</td></tr></tbody></table>');
|
||||
equal(r.startContainer.nodeType, 3);
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endContainer.nodeType, 3);
|
||||
equal(r.endOffset, 2);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeName, 'DIV');
|
||||
|
||||
r.setStart(document.getElementById('two').firstChild, 1);
|
||||
r.setEnd(document.getElementById('last').firstChild, 2);
|
||||
|
||||
equal(getHTML(r.cloneContents()), '<table id="table"><tbody><tr><td id="two">bc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">te</p>');
|
||||
equal(r.startContainer.nodeType, 3);
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endContainer.nodeType, 3);
|
||||
equal(r.endOffset, 2);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeName, 'DIV');
|
||||
|
||||
r.setStart(document.getElementById('first').firstChild, 1);
|
||||
r.setEnd(document.getElementById('first').lastChild, 4);
|
||||
|
||||
equal(getHTML(r.cloneContents()), 'irst<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> str');
|
||||
equal(r.startContainer.nodeType, 3);
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endContainer.nodeType, 3);
|
||||
equal(r.endOffset, 4);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeName, 'P');
|
||||
|
||||
r.setStart(document.getElementById('first').firstChild, 1);
|
||||
r.setEnd(document.getElementById('first').firstChild, 4);
|
||||
|
||||
equal(getHTML(r.cloneContents()), 'irs');
|
||||
equal(r.startContainer.nodeType, 3);
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endContainer.nodeType, 3);
|
||||
equal(r.endOffset, 4);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeType, 3);
|
||||
|
||||
r.setStart(document.getElementById('first'), 0);
|
||||
r.setEnd(document.getElementById('last'), 0);
|
||||
|
||||
equal(getHTML(r.cloneContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\"></p>');
|
||||
equal(r.startContainer.nodeType, 1);
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 0);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeType, 1);
|
||||
|
||||
r.setStart(document.getElementById('first'), 1);
|
||||
r.setEnd(document.getElementById('last'), 1);
|
||||
|
||||
equal(getHTML(r.cloneContents()), '<p id="first"><!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc</p>');
|
||||
equal(r.startContainer.nodeType, 1);
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 1);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeType, 1);
|
||||
|
||||
r.setStart(document.getElementById('sample'), 0);
|
||||
r.setEnd(document.getElementById('sample'), document.getElementById('sample').childNodes.length - 1);
|
||||
|
||||
equal(getHTML(r.cloneContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table>');
|
||||
equal(r.startContainer.nodeType, 1);
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, document.getElementById('sample').childNodes.length - 1);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeType, 1);
|
||||
|
||||
r.setStart(document.getElementById('first'), 0);
|
||||
r.setEnd(document.getElementById('last').firstChild, 1);
|
||||
|
||||
equal(getHTML(r.cloneContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">t</p>');
|
||||
equal(r.startContainer.nodeType, 1);
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 3);
|
||||
equal(r.endOffset, 1);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeType, 1);
|
||||
|
||||
r.setStart(document.getElementById('first').firstChild, 1);
|
||||
r.setEnd(document.getElementById('last'), 0);
|
||||
|
||||
equal(getHTML(r.cloneContents()), '<p id="first">irst<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id=\"last\"></p>');
|
||||
equal(r.startContainer.nodeType, 3);
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 0);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeType, 1);
|
||||
|
||||
r.setStart(document.getElementById('sample'), 0);
|
||||
r.setEnd(document.getElementById('traverse'), 2);
|
||||
|
||||
equal(getHTML(r.cloneContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em></p>');
|
||||
equal(r.startContainer.nodeType, 1);
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 2);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeType, 1);
|
||||
|
||||
r.setStart(document.getElementById('sample'), 0);
|
||||
r.setEnd(document.getElementById('traverse'), 1);
|
||||
|
||||
equal(getHTML(r.cloneContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b></p>');
|
||||
equal(r.startContainer.nodeType, 1);
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 1);
|
||||
equal(r.collapsed, false);
|
||||
equal(r.commonAncestorContainer.nodeType, 1);
|
||||
});
|
||||
}
|
||||
|
||||
test("test_extractContents1", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(10);
|
||||
|
||||
r.setStart(document.getElementById('first').firstChild, 1);
|
||||
r.setEnd(document.getElementById('first').firstChild, 4);
|
||||
|
||||
equal(getHTML(r.extractContents()), 'irs');
|
||||
equal(r.startContainer.nodeType, 3);
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endContainer.nodeType, 3);
|
||||
equal(r.endOffset, 1);
|
||||
equal(r.collapsed, true);
|
||||
equal(r.startContainer == r.endContainer, true);
|
||||
equal(r.startOffset == r.endOffset, true);
|
||||
equal(r.commonAncestorContainer.nodeType, 3);
|
||||
equal(getHTML(document.getElementById('first')), '<p id="first">ft<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p>');
|
||||
});
|
||||
|
||||
test("test_extractContents2", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(9);
|
||||
|
||||
r.setStart(document.getElementById('two').firstChild, 1);
|
||||
r.setEnd(document.getElementById('last').firstChild, 2);
|
||||
|
||||
equal(getHTML(r.extractContents()), '<table id="table"><tbody><tr><td id="two">bc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">te</p>');
|
||||
equal(r.startContainer.nodeType, 1);
|
||||
equal(getHTML(r.startContainer), '<div id="sample"><p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">a</td></tr></tbody></table><p id="last">xtabc<span>span</span></p></div>');
|
||||
equal(r.startOffset, 4);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 4);
|
||||
equal(getHTML(r.endContainer), '<div id="sample"><p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">a</td></tr></tbody></table><p id="last">xtabc<span>span</span></p></div>');
|
||||
equal(r.collapsed, true);
|
||||
equal(r.commonAncestorContainer.nodeName, 'DIV');
|
||||
});
|
||||
|
||||
test("test_extractContents3", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(9);
|
||||
|
||||
r.setStart(document.getElementById('sample'), 0);
|
||||
r.setEnd(document.getElementById('traverse'), 2);
|
||||
|
||||
equal(getHTML(r.extractContents()), '<p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em></p>');
|
||||
equal(getHTML(r.startContainer), '<div id="sample"><p id="traverse">more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 0);
|
||||
equal(getHTML(r.endContainer), '<div id="sample"><p id="traverse">more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
|
||||
equal(getHTML(document.getElementById('sample')), '<div id="sample"><p id="traverse">more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
|
||||
equal(r.collapsed, true);
|
||||
equal(r.commonAncestorContainer.nodeName, 'DIV');
|
||||
});
|
||||
|
||||
test("test_deleteContents1", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(8);
|
||||
|
||||
r.setStart(document.getElementById('two').firstChild, 1);
|
||||
r.setEnd(document.getElementById('last').firstChild, 2);
|
||||
r.deleteContents();
|
||||
|
||||
equal(getHTML(r.startContainer), '<div id="sample"><p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">a</td></tr></tbody></table><p id="last">xtabc<span>span</span></p></div>');
|
||||
equal(r.startOffset, 4);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 4);
|
||||
equal(getHTML(r.endContainer), '<div id="sample"><p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">a</td></tr></tbody></table><p id="last">xtabc<span>span</span></p></div>');
|
||||
equal(getHTML(document.getElementById('sample')), '<div id="sample"><p id="first">first<!--not--> strong <!-- --><strong id="strong">strong</strong> second <em id="em1">em</em> strong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">a</td></tr></tbody></table><p id="last">xtabc<span>span</span></p></div>');
|
||||
equal(r.collapsed, true);
|
||||
equal(r.commonAncestorContainer.nodeName, 'DIV');
|
||||
});
|
||||
|
||||
test("test_deleteContents2", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(8);
|
||||
|
||||
r.setStart(document.getElementById('first').firstChild, 1);
|
||||
r.setEnd(document.getElementById('first').lastChild, 4);
|
||||
r.deleteContents();
|
||||
|
||||
equal(getHTML(r.startContainer), '<p id="first">fong.</p>');
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 1);
|
||||
equal(getHTML(r.endContainer), '<p id="first">fong.</p>');
|
||||
equal(getHTML(document.getElementById('sample')), '<div id="sample"><p id="first">fong.</p><p id="second">bar</p><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
|
||||
equal(r.collapsed, true);
|
||||
equal(r.commonAncestorContainer.nodeName, 'P');
|
||||
});
|
||||
|
||||
test("test_deleteContents3", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(8);
|
||||
|
||||
r.setStart(document.getElementById('sample'), 0);
|
||||
r.setEnd(document.getElementById('sample'), 2);
|
||||
r.deleteContents();
|
||||
|
||||
equal(getHTML(r.startContainer), '<div id="sample"><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 0);
|
||||
equal(getHTML(r.endContainer), '<div id="sample"><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
|
||||
equal(getHTML(document.getElementById('sample')), '<div id="sample"><p id="traverse"><b><em id="em2">some text</em></b><em>em text</em>more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
|
||||
equal(r.collapsed, true);
|
||||
equal(r.commonAncestorContainer.nodeName, 'DIV');
|
||||
});
|
||||
|
||||
test("test_deleteContents4", function() {
|
||||
var r = createRng();
|
||||
|
||||
expect(8);
|
||||
|
||||
r.setStart(document.getElementById('sample'), 0);
|
||||
r.setEnd(document.getElementById('traverse'), 2);
|
||||
r.deleteContents();
|
||||
|
||||
equal(getHTML(r.startContainer), '<div id="sample"><p id="traverse">more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endContainer.nodeType, 1);
|
||||
equal(r.endOffset, 0);
|
||||
equal(getHTML(r.endContainer), '<div id="sample"><p id="traverse">more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
|
||||
equal(getHTML(document.getElementById('sample')), '<div id="sample"><p id="traverse">more text</p><table id="table"><tbody><tr><td>1</td><td id="two">abc</td></tr><tr><td>3</td><td>4</td></tr></tbody></table><p id="last">textabc<span>span</span></p></div>');
|
||||
equal(r.collapsed, true);
|
||||
equal(r.commonAncestorContainer.nodeName, 'DIV');
|
||||
});
|
||||
|
||||
test("test_compareBoundaryPoints", function() {
|
||||
var r1 = createRng(), r2 = createRng(), START_TO_START = 0, START_TO_END = 1, END_TO_END = 2, END_TO_START = 3;
|
||||
|
||||
r1.setStartBefore(document.getElementById('strong'));
|
||||
r1.setEndAfter(document.getElementById('strong'));
|
||||
r2.setStartBefore(document.getElementById('strong'));
|
||||
r2.setEndAfter(document.getElementById('strong'));
|
||||
equal(r1.compareBoundaryPoints(START_TO_START, r2), 0, 'Start to start for same ranges');
|
||||
equal(r1.compareBoundaryPoints(END_TO_END, r2), 0, 'End to end for same ranges');
|
||||
equal(r1.compareBoundaryPoints(START_TO_END, r1), 1, 'Start to end for same ranges');
|
||||
equal(r1.compareBoundaryPoints(END_TO_START, r2), -1, 'End to start for same ranges');
|
||||
|
||||
r1.setStartBefore(document.getElementById('strong'));
|
||||
r1.setEndAfter(document.getElementById('strong'));
|
||||
r2.setStartBefore(document.getElementById('em1'));
|
||||
r2.setEndAfter(document.getElementById('em1'));
|
||||
equal(r1.compareBoundaryPoints(START_TO_START, r2), -1, 'Start to start for range before');
|
||||
equal(r1.compareBoundaryPoints(END_TO_END, r2), -1, 'End to end for range before');
|
||||
equal(r1.compareBoundaryPoints(START_TO_END, r2), -1, 'Start to end for range before');
|
||||
equal(r1.compareBoundaryPoints(END_TO_START, r2), -1, 'End to start for range before');
|
||||
|
||||
equal(r2.compareBoundaryPoints(START_TO_START, r1), 1, 'Start to start for range after');
|
||||
equal(r2.compareBoundaryPoints(END_TO_END, r1), 1, 'End to end for range after');
|
||||
equal(r2.compareBoundaryPoints(START_TO_END, r1), 1, 'Start to end for range after');
|
||||
equal(r2.compareBoundaryPoints(END_TO_START, r1), 1, 'End to start for range after');
|
||||
|
||||
r1.setStartBefore(document.getElementById('strong'));
|
||||
r1.setEndAfter(document.getElementById('strong'));
|
||||
r2.setStart(document.getElementById('strong').firstChild, 2);
|
||||
r2.setEnd(document.getElementById('strong').firstChild, 3);
|
||||
equal(r1.compareBoundaryPoints(START_TO_START, r2), -1, 'Start to start for range inside');
|
||||
equal(r1.compareBoundaryPoints(END_TO_END, r2), 1, 'End to end for range inside');
|
||||
equal(r1.compareBoundaryPoints(START_TO_END, r2), 1, 'Start to end for range inside');
|
||||
equal(r1.compareBoundaryPoints(END_TO_START, r2), -1, 'End to start for range inside');
|
||||
});
|
||||
|
||||
test("toString in part of same text node", function() {
|
||||
var rng = createRng();
|
||||
|
||||
rng.setStart(document.getElementById('strong').firstChild, 1);
|
||||
rng.setEnd(document.getElementById('strong').firstChild, 3);
|
||||
equal(rng.toString(), "tr");
|
||||
});
|
||||
|
||||
test("toString in start/end of same text node", function() {
|
||||
var rng = createRng();
|
||||
|
||||
rng.setStart(document.getElementById('strong').firstChild, 0);
|
||||
rng.setEnd(document.getElementById('strong').firstChild, 6);
|
||||
equal(rng.toString(), "strong");
|
||||
});
|
||||
|
||||
test("toString in start in one text node end in another", function() {
|
||||
var rng = createRng();
|
||||
|
||||
rng.setStart(document.getElementById('strong').firstChild, 1);
|
||||
rng.setEnd(document.getElementById('em1').firstChild, 1);
|
||||
equal(rng.toString(), "trong second e");
|
||||
});
|
||||
|
||||
// Run on IE only
|
||||
if (tinymce.isIE) {
|
||||
test("toString in start in one text node end in another", function() {
|
||||
var rng = createRng();
|
||||
|
||||
rng.setStartBefore(document.getElementById('strong'));
|
||||
rng.setEndAfter(document.getElementById('em2'));
|
||||
equal(rng.toString().replace(/\r\n/g, ''), "strong second em strong.barsome text");
|
||||
});
|
||||
}
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,559 +0,0 @@
|
||||
var DOM = tinymce.DOM;
|
||||
|
||||
module("tinymce.dom.Serializer", {
|
||||
setupModule: function() {
|
||||
document.getElementById('view').innerHTML = '<div id="content"><div id="test"></div></div>';
|
||||
}
|
||||
});
|
||||
|
||||
test('Schema rules', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(8);
|
||||
|
||||
ser.setRules('@[id|title|class|style],div,img[src|alt|-style|border],span,hr');
|
||||
DOM.setHTML('test', '<img title="test" src="tinymce/ui/img/raster.gif" data-mce-src="tinymce/ui/img/raster.gif" alt="test" border="0" style="border: 1px solid red" class="test" /><span id="test2">test</span><hr />');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><img title="test" class="test" src="tinymce/ui/img/raster.gif" alt="test" border="0" /><span id="test2">test</span><hr /></div>', 'Global rule');
|
||||
|
||||
ser.setRules('*a[*],em/i[*],strong/b[*i*]');
|
||||
DOM.setHTML('test', '<a href="test" data-mce-href="test">test</a><strong title="test" class="test">test2</strong><em title="test">test3</em>');
|
||||
equal(ser.serialize(DOM.get('test')), '<a href="test">test</a><strong title="test">test2</strong><em title="test">test3</em>', 'Wildcard rules');
|
||||
|
||||
ser.setRules('br,hr,input[type|name|value],div[id],span[id],strong/b,a,em/i,a[!href|!name],img[src|border=0|title={$uid}]');
|
||||
DOM.setHTML('test', '<br /><hr /><input type="text" name="test" value="val" class="no" /><span id="test2" class="no"><b class="no">abc</b><em class="no">123</em></span>123<a href="file.html" data-mce-href="file.html">link</a><a name="anchor"></a><a>no</a><img src="tinymce/ui/img/raster.gif" data-mce-src="tinymce/ui/img/raster.gif" />');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><br /><hr /><input type="text" name="test" value="val" /><span id="test2"><strong>abc</strong><em>123</em></span>123<a href="file.html">link</a><a name="anchor"></a>no<img src="tinymce/ui/img/raster.gif" border="0" title="mce_0" /></div>', 'Output name and attribute rules');
|
||||
|
||||
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" 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="" />');
|
||||
equal(ser.serialize(DOM.get('test')), '<img src="tinymce/ui/img/raster.gif" border="0" alt="" />', 'Default attribute with empty value');
|
||||
|
||||
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" /><hr />');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><img src="tinymce/ui/img/raster.gif" border="0" alt="" /><hr /></div>');
|
||||
|
||||
ser = new tinymce.dom.Serializer({
|
||||
valid_elements : 'img[src|border=0|alt=]',
|
||||
extended_valid_elements : 'div[id],img[src|alt=]'
|
||||
});
|
||||
DOM.setHTML('test', '<img src="tinymce/ui/img/raster.gif" data-mce-src="tinymce/ui/img/raster.gif" alt="" />');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><img src="tinymce/ui/img/raster.gif" alt="" /></div>');
|
||||
|
||||
ser = new tinymce.dom.Serializer({invalid_elements : 'hr,br'});
|
||||
DOM.setHTML('test', '<img src="tinymce/ui/img/raster.gif" data-mce-src="tinymce/ui/img/raster.gif" /><hr /><br />');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><img src="tinymce/ui/img/raster.gif" /></div>');
|
||||
});
|
||||
|
||||
test('Entity encoding', function() {
|
||||
var ser;
|
||||
|
||||
expect(4);
|
||||
|
||||
ser = new tinymce.dom.Serializer({entity_encoding : 'numeric'});
|
||||
DOM.setHTML('test', '<>&" åäö');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><>&" åäö</div>');
|
||||
|
||||
ser = new tinymce.dom.Serializer({entity_encoding : 'named'});
|
||||
DOM.setHTML('test', '<>&" åäö');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><>&" åäö</div>');
|
||||
|
||||
ser = new tinymce.dom.Serializer({entity_encoding : 'named+numeric', entities : '160,nbsp,34,quot,38,amp,60,lt,62,gt'});
|
||||
DOM.setHTML('test', '<>&" åäö');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><>&" åäö</div>');
|
||||
|
||||
ser = new tinymce.dom.Serializer({entity_encoding : 'raw'});
|
||||
DOM.setHTML('test', '<>&" åäö');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><>&"\u00a0\u00e5\u00e4\u00f6</div>');
|
||||
});
|
||||
|
||||
test('Form elements (general)', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(5);
|
||||
|
||||
ser.setRules('form[method],label[for],input[type|name|value|checked|disabled|readonly|length|maxlength],select[multiple],option[value|selected],textarea[name|disabled|readonly]');
|
||||
|
||||
DOM.setHTML('test', '<input type="text" />');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="text" />');
|
||||
|
||||
DOM.setHTML('test', '<input type="text" value="text" length="128" maxlength="129" />');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="text" value="text" length="128" maxlength="129" />');
|
||||
|
||||
DOM.setHTML('test', '<form method="post"><input type="hidden" name="method" value="get" /></form>');
|
||||
equal(ser.serialize(DOM.get('test')), '<form method="post"><input type="hidden" name="method" value="get" /></form>');
|
||||
|
||||
DOM.setHTML('test', '<label for="test">label</label>');
|
||||
equal(ser.serialize(DOM.get('test')), '<label for="test">label</label>');
|
||||
|
||||
DOM.setHTML('test', '<input type="checkbox" value="test" /><input type="button" /><textarea></textarea>');
|
||||
|
||||
// Edge will add an empty input value so remove that to normalize test since it doesn't break anything
|
||||
equal(ser.serialize(DOM.get('test')).replace(/ value=""/g, ''), '<input type="checkbox" value="test" /><input type="button" /><textarea></textarea>');
|
||||
});
|
||||
|
||||
test('Form elements (checkbox)', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(4);
|
||||
|
||||
ser.setRules('form[method],label[for],input[type|name|value|checked|disabled|readonly|length|maxlength],select[multiple],option[value|selected]');
|
||||
|
||||
DOM.setHTML('test', '<input type="checkbox" value="1">');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="checkbox" value="1" />');
|
||||
|
||||
DOM.setHTML('test', '<input type="checkbox" value="1" checked disabled readonly>');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="checkbox" value="1" checked="checked" disabled="disabled" readonly="readonly" />');
|
||||
|
||||
DOM.setHTML('test', '<input type="checkbox" value="1" checked="1" disabled="1" readonly="1">');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="checkbox" value="1" checked="checked" disabled="disabled" readonly="readonly" />');
|
||||
|
||||
DOM.setHTML('test', '<input type="checkbox" value="1" checked="true" disabled="true" readonly="true">');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="checkbox" value="1" checked="checked" disabled="disabled" readonly="readonly" />');
|
||||
});
|
||||
|
||||
test('Form elements (select)', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(7);
|
||||
|
||||
ser.setRules('form[method],label[for],input[type|name|value|checked|disabled|readonly|length|maxlength],select[multiple],option[value|selected]');
|
||||
|
||||
DOM.setHTML('test', '<select><option value="1">test1</option><option value="2" selected>test2</option></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select><option value="1">test1</option><option value="2" selected="selected">test2</option></select>');
|
||||
|
||||
DOM.setHTML('test', '<select><option value="1">test1</option><option selected="1" value="2">test2</option></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select><option value="1">test1</option><option value="2" selected="selected">test2</option></select>');
|
||||
|
||||
DOM.setHTML('test', '<select><option value="1">test1</option><option value="2" selected="true">test2</option></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select><option value="1">test1</option><option value="2" selected="selected">test2</option></select>');
|
||||
|
||||
DOM.setHTML('test', '<select multiple></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select multiple="multiple"></select>');
|
||||
|
||||
DOM.setHTML('test', '<select multiple="multiple"></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select multiple="multiple"></select>');
|
||||
|
||||
DOM.setHTML('test', '<select multiple="1"></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select multiple="multiple"></select>');
|
||||
|
||||
DOM.setHTML('test', '<select></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select></select>');
|
||||
});
|
||||
|
||||
test('List elements', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(5);
|
||||
|
||||
ser.setRules('ul[compact],ol,li');
|
||||
|
||||
DOM.setHTML('test', '<ul compact></ul>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ul compact="compact"></ul>');
|
||||
|
||||
DOM.setHTML('test', '<ul compact="compact"></ul>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ul compact="compact"></ul>');
|
||||
|
||||
DOM.setHTML('test', '<ul compact="1"></ul>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ul compact="compact"></ul>');
|
||||
|
||||
DOM.setHTML('test', '<ul></ul>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ul></ul>');
|
||||
|
||||
DOM.setHTML('test', '<ol><li>a</li><ol><li>b</li><li>c</li></ol><li>e</li></ol>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ol><li>a<ol><li>b</li><li>c</li></ol></li><li>e</li></ol>');
|
||||
});
|
||||
|
||||
test('Tables', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(4);
|
||||
|
||||
ser.setRules('table,tr,td[nowrap]');
|
||||
|
||||
DOM.setHTML('test', '<table><tr><td></td></tr></table>');
|
||||
equal(ser.serialize(DOM.get('test')), '<table><tr><td></td></tr></table>');
|
||||
|
||||
DOM.setHTML('test', '<table><tr><td nowrap></td></tr></table>');
|
||||
equal(ser.serialize(DOM.get('test')), '<table><tr><td nowrap="nowrap"></td></tr></table>');
|
||||
|
||||
DOM.setHTML('test', '<table><tr><td nowrap="nowrap"></td></tr></table>');
|
||||
equal(ser.serialize(DOM.get('test')), '<table><tr><td nowrap="nowrap"></td></tr></table>');
|
||||
|
||||
DOM.setHTML('test', '<table><tr><td nowrap="1"></td></tr></table>');
|
||||
equal(ser.serialize(DOM.get('test')), '<table><tr><td nowrap="nowrap"></td></tr></table>');
|
||||
});
|
||||
|
||||
test('Styles', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(1);
|
||||
|
||||
ser.setRules('*[*]');
|
||||
|
||||
DOM.setHTML('test', '<span style="border: 1px solid red" data-mce-style="border: 1px solid red;">test</span>');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><span style="border: 1px solid red;">test</span></div>');
|
||||
});
|
||||
|
||||
test('Comments', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(1);
|
||||
|
||||
ser.setRules('*[*]');
|
||||
|
||||
DOM.setHTML('test', '<!-- abc -->');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><!-- abc --></div>');
|
||||
});
|
||||
|
||||
test('Non HTML elements and attributes', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(2);
|
||||
|
||||
ser.setRules('*[*]');
|
||||
ser.schema.addValidChildren('+div[prefix:test]');
|
||||
|
||||
DOM.setHTML('test', '<div test:attr="test">test</div>');
|
||||
equal(ser.serialize(DOM.get('test'), {getInner : 1}), '<div test:attr="test">test</div>');
|
||||
|
||||
DOM.setHTML('test', 'test1<prefix:test>Test</prefix:test>test2');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test">test1<prefix:test>Test</prefix:test>test2</div>');
|
||||
});
|
||||
|
||||
test('Padd empty elements', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(1);
|
||||
|
||||
ser.setRules('#p');
|
||||
|
||||
DOM.setHTML('test', '<p>test</p><p></p>');
|
||||
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});
|
||||
|
||||
expect(1);
|
||||
|
||||
ser.setRules('-p');
|
||||
|
||||
DOM.setHTML('test', '<p>test</p><p></p>');
|
||||
equal(ser.serialize(DOM.get('test')), '<p>test</p>');
|
||||
});
|
||||
|
||||
test('Pre/post process events', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(3);
|
||||
|
||||
ser.setRules('div[id],span[id|class],a[href],b[class]');
|
||||
|
||||
ser.onPreProcess = function(o) {
|
||||
equal(o.test, 'abc');
|
||||
DOM.setAttrib(o.node.getElementsByTagName('span')[0], 'class', 'abc');
|
||||
};
|
||||
|
||||
ser.onPostProcess = function(o) {
|
||||
equal(o.test, 'abc');
|
||||
o.content = o.content.replace(/<b>/g, '<b class="123">');
|
||||
};
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><b>abc</b></span>123<a href="file.html" data-mce-href="file.html">link</a>');
|
||||
equal(ser.serialize(DOM.get('test'), {test : 'abc'}), '<div id="test"><span id="test2" class="abc"><b class="123">abc</b></span>123<a href="file.html">link</a></div>');
|
||||
});
|
||||
|
||||
test('Script with non JS type attribute', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<s' + 'cript type="mylanguage"></s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<s' + 'cript type="mylanguage"></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with tags inside a comment', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<s' + 'cript>// <img src="test"><a href="#"></a></s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<s' + 'cript>// <![CDATA[\n// <img src="test"><a href="#"></a>\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with less than', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<s' + 'cript>1 < 2;</s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<s' + 'cript>// <![CDATA[\n1 < 2;\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with type attrib and less than', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<s' + 'cript type="text/javascript">1 < 2;</s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<script type="text/javascript">// <![CDATA[\n1 < 2;\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with whitespace in beginning/end', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script>\n\t1 < 2;\n\t if (2 < 1)\n\t\talert(1);\n</s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<s' + 'cript>// <![CDATA[\n\t1 < 2;\n\t if (2 < 1)\n\t\talert(1);\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with a HTML comment and less than', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script><!-- 1 < 2; // --></s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<s' + 'cript>// <![CDATA[\n1 < 2;\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with white space in beginning, comment and less than', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script>\n\n<!-- 1 < 2;\n\n--></s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<s' + 'cript>// <![CDATA[\n1 < 2;\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with comments and cdata', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script>// <![CDATA[1 < 2; // ]]></s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<s' + 'cript>// <![CDATA[\n1 < 2;\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with cdata', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script><![CDATA[1 < 2; ]]></s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<s' + 'cript>// <![CDATA[\n1 < 2;\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script whitespace in beginning/end and cdata', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script>\n\n<![CDATA[\n\n1 < 2;\n\n]]>\n\n</s' + 'cript>');
|
||||
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]');
|
||||
|
||||
DOM.setHTML('test', '<script src="test.js" data-mce-src="test.js"></s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')), '<s' + 'cript src="test.js"></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with HTML comment, comment and CDATA', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script><!--// <![CDATA[var hi = "hello";// ]]>--></s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')), '<script>// <![CDATA[\nvar hi = \"hello\";\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with block comment around cdata', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script>/* <![CDATA[ */\nvar hi = "hello";\n/* ]]> */</s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')), '<script>// <![CDATA[\nvar hi = \"hello\";\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with html comment and block comment around cdata', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script><!-- /* <![CDATA[ */\nvar hi = "hello";\n/* ]]>*/--></s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')), '<script>// <![CDATA[\nvar hi = \"hello\";\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with line comment and html comment', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script>// <!--\nvar hi = "hello";\n// --></s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')), '<script>// <![CDATA[\nvar hi = \"hello\";\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Script with block comment around html comment', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
ser.setRules('script[type|language|src]');
|
||||
|
||||
DOM.setHTML('test', '<script>/* <!-- */\nvar hi = "hello";\n/*-->*/</s' + 'cript>');
|
||||
equal(ser.serialize(DOM.get('test')), '<script>// <![CDATA[\nvar hi = \"hello\";\n// ]]></s' + 'cript>');
|
||||
});
|
||||
|
||||
test('Protected blocks', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(3);
|
||||
|
||||
ser.setRules('noscript[test]');
|
||||
|
||||
DOM.setHTML('test', '<!--mce:protected ' + escape('<noscript test="test"><br></noscript>') + '-->');
|
||||
equal(ser.serialize(DOM.get('test')), '<noscript test="test"><br></noscript>');
|
||||
|
||||
DOM.setHTML('test', '<!--mce:protected ' + escape('<noscript><br></noscript>') + '-->');
|
||||
equal(ser.serialize(DOM.get('test')), '<noscript><br></noscript>');
|
||||
|
||||
DOM.setHTML('test', '<!--mce:protected ' + escape('<noscript><!-- text --><br></noscript>') + '-->');
|
||||
equal(ser.serialize(DOM.get('test')), '<noscript><!-- text --><br></noscript>');
|
||||
});
|
||||
|
||||
test('Style with whitespace at beginning', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true, valid_children: '+body[style]'});
|
||||
ser.setRules('style');
|
||||
|
||||
DOM.setHTML('test', '<style> body { background:#fff }</style>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<style><!--\n body { background:#fff }\n--></style>');
|
||||
});
|
||||
|
||||
test('Style with cdata', 1, function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true, valid_children: '+body[style]'});
|
||||
ser.setRules('style');
|
||||
|
||||
DOM.setHTML('test', '<style>\r\n<![CDATA[\r\n body { background:#fff }]]></style>');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '<style><!--\nbody { background:#fff }\n--></style>');
|
||||
});
|
||||
|
||||
test('CDATA', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(2);
|
||||
|
||||
ser.setRules('span');
|
||||
|
||||
DOM.setHTML('test', '123<!--[CDATA[<test>]]-->abc');
|
||||
equal(ser.serialize(DOM.get('test')), '123<![CDATA[<test>]]>abc');
|
||||
|
||||
DOM.setHTML('test', '123<!--[CDATA[<te\n\nst>]]-->abc');
|
||||
equal(ser.serialize(DOM.get('test')).replace(/\r/g, ''), '123<![CDATA[<te\n\nst>]]>abc');
|
||||
});
|
||||
|
||||
test('BR at end of blocks', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
ser.setRules('ul,li,br');
|
||||
|
||||
DOM.setHTML('test', '<ul><li>test<br /></li><li>test<br /></li><li>test<br /></li></ul>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ul><li>test</li><li>test</li><li>test</li></ul>');
|
||||
});
|
||||
|
||||
test('Map elements', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
ser.setRules('map[id|name],area[shape|coords|href|target|alt]');
|
||||
|
||||
DOM.setHTML('test', '<map id="planetmap" name="planetmap"><area shape="rect" coords="0,0,82,126" href="sun.htm" data-mce-href="sun.htm" target="_blank" alt="sun" /></map>');
|
||||
equal(ser.serialize(DOM.get('test')).toLowerCase(), '<map id="planetmap" name="planetmap"><area shape="rect" coords="0,0,82,126" href="sun.htm" target="_blank" alt="sun" /></map>');
|
||||
});
|
||||
|
||||
test('Custom elements', function() {
|
||||
var ser = new tinymce.dom.Serializer({
|
||||
custom_elements: 'custom1,~custom2',
|
||||
valid_elements: 'custom1,custom2'
|
||||
});
|
||||
|
||||
document.createElement('custom1');
|
||||
document.createElement('custom2');
|
||||
|
||||
DOM.setHTML('test', '<p><custom1>c1</custom1><custom2>c2</custom2></p>');
|
||||
equal(ser.serialize(DOM.get('test')), '<custom1>c1</custom1><custom2>c2</custom2>');
|
||||
});
|
||||
|
||||
test('Remove internal classes', function() {
|
||||
var ser = new tinymce.dom.Serializer({
|
||||
valid_elements: 'span[class]'
|
||||
});
|
||||
|
||||
DOM.setHTML('test', '<span class="a mce-item-X mce-item-selected b"></span>');
|
||||
equal(ser.serialize(DOM.get('test')), '<span class="a b"></span>');
|
||||
|
||||
DOM.setHTML('test', '<span class="a mce-item-X"></span>');
|
||||
equal(ser.serialize(DOM.get('test')), '<span class="a"></span>');
|
||||
|
||||
DOM.setHTML('test', '<span class="mce-item-X"></span>');
|
||||
equal(ser.serialize(DOM.get('test')), '<span></span>');
|
||||
|
||||
DOM.setHTML('test', '<span class="mce-item-X b"></span>');
|
||||
equal(ser.serialize(DOM.get('test')), '<span class=" b"></span>');
|
||||
|
||||
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>');
|
||||
});
|
||||
|
||||
test('Trailing BR (IE11)', function() {
|
||||
var ser = new tinymce.dom.Serializer({
|
||||
valid_elements: 'p,br'
|
||||
});
|
||||
|
||||
DOM.setHTML('test', '<p>a</p><br><br>');
|
||||
equal(ser.serialize(DOM.get('test')), '<p>a</p>');
|
||||
|
||||
DOM.setHTML('test', 'a<br><br>');
|
||||
equal(ser.serialize(DOM.get('test')), 'a');
|
||||
});
|
||||
|
||||
test('addTempAttr', function() {
|
||||
var ser = new tinymce.dom.Serializer({});
|
||||
|
||||
ser.addTempAttr('data-x');
|
||||
ser.addTempAttr('data-y');
|
||||
|
||||
DOM.setHTML('test', '<p data-x="1" data-y="2" data-z="3">a</p>');
|
||||
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>');
|
||||
});
|
||||
@ -1,109 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/dom/TreeWalker"
|
||||
], function(TreeWalker) {
|
||||
var viewElm, nodes;
|
||||
|
||||
module("tinymce.dom.TreeWalker", {
|
||||
setupModule: function() {
|
||||
function setupHtml(html) {
|
||||
var viewElm;
|
||||
|
||||
viewElm = document.getElementById('view');
|
||||
viewElm.innerHTML = html;
|
||||
|
||||
return viewElm;
|
||||
}
|
||||
|
||||
function all(node) {
|
||||
var list = [node];
|
||||
|
||||
if (node.hasChildNodes()) {
|
||||
for (var i = 0; i < node.childNodes.length; i++) {
|
||||
list = list.concat(all(node.childNodes[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
viewElm = setupHtml(
|
||||
'1' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'2' +
|
||||
'<ul>' +
|
||||
'<li>3</li>' +
|
||||
'<li>4</li>' +
|
||||
'</ul>' +
|
||||
'</li>' +
|
||||
'<li>' +
|
||||
'5' +
|
||||
'<ul>' +
|
||||
'<li>6</li>' +
|
||||
'<li>7</li>' +
|
||||
'</ul>' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'8'
|
||||
);
|
||||
|
||||
nodes = all(viewElm).slice(1);
|
||||
},
|
||||
|
||||
teardownModule: function() {
|
||||
viewElm = nodes = null;
|
||||
}
|
||||
});
|
||||
|
||||
function compareNodeLists(expectedNodes, actutalNodes) {
|
||||
if (expectedNodes.length !== actutalNodes.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < expectedNodes.length; i++) {
|
||||
if (expectedNodes[i] !== actutalNodes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
test('next', function() {
|
||||
var walker = new TreeWalker(nodes[0], viewElm);
|
||||
var actualNodes;
|
||||
|
||||
actualNodes = [walker.current()];
|
||||
while ((walker.next())) {
|
||||
actualNodes.push(walker.current());
|
||||
}
|
||||
|
||||
ok(compareNodeLists(nodes, actualNodes), 'Should be the same');
|
||||
});
|
||||
|
||||
test('prev2', function() {
|
||||
var walker = new TreeWalker(nodes[nodes.length - 1], viewElm);
|
||||
var actualNodes;
|
||||
|
||||
actualNodes = [walker.current()];
|
||||
while ((walker.prev2())) {
|
||||
actualNodes.push(walker.current());
|
||||
}
|
||||
|
||||
actualNodes = actualNodes.reverse();
|
||||
ok(compareNodeLists(nodes, actualNodes), 'Should be the same');
|
||||
});
|
||||
|
||||
test('prev2(shallow:true)', function() {
|
||||
var walker = new TreeWalker(nodes[nodes.length - 1], viewElm);
|
||||
var actualNodes;
|
||||
|
||||
actualNodes = [walker.current()];
|
||||
while ((walker.prev2(true))) {
|
||||
actualNodes.push(walker.current());
|
||||
}
|
||||
|
||||
actualNodes = actualNodes.reverse();
|
||||
ok(compareNodeLists(viewElm.childNodes, actualNodes), 'Should be the same');
|
||||
});
|
||||
});
|
||||
@ -1,543 +0,0 @@
|
||||
module("tinymce.dom.TridentSelection", {
|
||||
setupModule: function() {
|
||||
if (window.getSelection) {
|
||||
return;
|
||||
}
|
||||
|
||||
QUnit.stop();
|
||||
document.getElementById('view').innerHTML = '<textarea></textarea>';
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
elements: "elm1",
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
skin: false,
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (!window.getSelection) {
|
||||
test("Selection of element containing text", function(){
|
||||
expect(5);
|
||||
|
||||
editor.setContent('<p>123</p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, '#text', 'Start container is text node');
|
||||
equal(rng.endContainer.nodeName, '#text', 'End container is text node');
|
||||
equal(rng.startOffset, 0, 'Start of text node');
|
||||
equal(rng.endOffset, 3, 'End of text node');
|
||||
equal(editor.dom.getOuterHTML(rng.cloneContents()), '123', 'Contents matches');
|
||||
});
|
||||
|
||||
test("Single image selection", function(){
|
||||
expect(6);
|
||||
|
||||
editor.setContent('<p><img src="about:blank" /></p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.dom.select('img')[0]);
|
||||
rng.setEndAfter(editor.dom.select('img')[0]);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, 'P', 'Check startContainer');
|
||||
equal(rng.endContainer.nodeName, 'P', 'Check endContainer');
|
||||
equal(rng.startOffset, 0, 'Check startOffset');
|
||||
equal(rng.endOffset, 1, 'Check endOffset');
|
||||
equal(Utils.cleanHtml(editor.dom.getOuterHTML(rng.cloneContents()).toLowerCase()), '<img src="about:blank">', 'Check contents');
|
||||
ok(editor.selection.getRng().item, 'Check if it\'s a control selection');
|
||||
});
|
||||
|
||||
test("Multiple image selection", function(){
|
||||
expect(6);
|
||||
|
||||
editor.setContent('<p><img src="about:blank" /><img src="about:blank" /></p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.dom.select('img')[0]);
|
||||
rng.setEndAfter(editor.dom.select('img')[1]);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endOffset, 2);
|
||||
equal(editor.dom.getOuterHTML(rng.cloneContents()).toLowerCase(), '<img src="about:blank"><img src="about:blank">');
|
||||
ok(editor.selection.getRng().parentElement, 'Is text selection');
|
||||
});
|
||||
|
||||
test("Text node selection", function(){
|
||||
expect(5);
|
||||
|
||||
editor.setContent('<p>1234</p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild, 1);
|
||||
rng.setEnd(editor.getBody().firstChild.firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, '#text');
|
||||
equal(rng.endContainer.nodeName, '#text');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endOffset, 3);
|
||||
equal(editor.dom.getOuterHTML(rng.cloneContents()), '23');
|
||||
});
|
||||
|
||||
test("Text node selection between two elements", function(){
|
||||
expect(5);
|
||||
|
||||
editor.setContent('<p>1234</p><p>abcd</p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild, 1);
|
||||
rng.setEnd(editor.getBody().childNodes[1].firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, '#text');
|
||||
equal(rng.endContainer.nodeName, '#text');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endOffset, 3);
|
||||
equal(editor.dom.getOuterHTML(rng.cloneContents()).replace(/[\r\n]/g, '').toLowerCase(), '<p>234</p><p>abc</p>');
|
||||
|
||||
editor.setContent('<p>1</p><p>1234</p><p>abcd</p><p>2</p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
});
|
||||
|
||||
test("Mixed selection start at element end at text", function(){
|
||||
expect(5);
|
||||
|
||||
editor.setContent('<p><img src="about:blank" />text</p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.dom.select('img')[0]);
|
||||
rng.setEnd(editor.getBody().firstChild.lastChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.endContainer.nodeName, '#text');
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endOffset, 3);
|
||||
equal(editor.dom.getOuterHTML(rng.cloneContents()).toLowerCase(), '<img src="about:blank">tex');
|
||||
});
|
||||
|
||||
test("Mixed selection start at text end at element", function(){
|
||||
expect(5);
|
||||
|
||||
editor.setContent('<p>text<img src="about:blank" /></p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild, 1);
|
||||
rng.setEndAfter(editor.getBody().firstChild.lastChild);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
|
||||
equal(rng.startContainer.nodeName, '#text');
|
||||
equal(rng.startOffset, 1);
|
||||
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 2);
|
||||
|
||||
equal(editor.dom.getOuterHTML(rng.cloneContents()).toLowerCase(), 'ext<img src="about:blank">');
|
||||
});
|
||||
|
||||
test("Caret position before image", function(){
|
||||
expect(4);
|
||||
|
||||
editor.setContent('<p><img src="about:blank" /><img src="about:blank" /></p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.dom.select('img')[0]);
|
||||
rng.setEndBefore(editor.dom.select('img')[0]);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endOffset, 0);
|
||||
});
|
||||
|
||||
test("Caret position between images", function(){
|
||||
expect(4);
|
||||
|
||||
editor.setContent('<p><img src="about:blank" /><img src="about:blank" /></p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStartAfter(editor.dom.select('img')[0]);
|
||||
rng.setEndAfter(editor.dom.select('img')[0]);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endOffset, 1);
|
||||
});
|
||||
|
||||
test("Caret position after image", function(){
|
||||
expect(4);
|
||||
|
||||
editor.setContent('<p><img src="about:blank" /><img src="about:blank" /></p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStartAfter(editor.dom.select('img')[1]);
|
||||
rng.setEndAfter(editor.dom.select('img')[1]);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 2);
|
||||
equal(rng.endOffset, 2);
|
||||
});
|
||||
|
||||
test("Selection of empty text element", function(){
|
||||
expect(6);
|
||||
|
||||
editor.setContent('<div></div>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'BODY');
|
||||
equal(rng.endContainer.nodeName, 'BODY');
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endOffset, 1);
|
||||
equal(rng.startContainer.childNodes[0].innerHTML, '');
|
||||
equal(editor.dom.getOuterHTML(rng.cloneContents()).toLowerCase(), '<div></div>');
|
||||
});
|
||||
|
||||
test("Selection of empty text element with caret inside", function(){
|
||||
expect(6);
|
||||
|
||||
editor.setContent('<div></div>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
var rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 0);
|
||||
rng.setEnd(editor.getBody().firstChild, 0);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'DIV');
|
||||
equal(rng.endContainer.nodeName, 'DIV');
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endOffset, 0);
|
||||
equal(rng.startContainer.innerHTML, '');
|
||||
equal(editor.dom.getOuterHTML(rng.cloneContents()).toLowerCase(), '');
|
||||
});
|
||||
|
||||
/*test("Caret position before table", function() {
|
||||
var table, rng;
|
||||
|
||||
editor.focus();
|
||||
editor.setContent('<p>Before</p><table id="table" border="1"><tr><td>Cell 1</td><td>Cell 2</td></tr><tr><td>Cell 3</td><td>Cell 4</td></tr></table><p>After</p>');
|
||||
|
||||
table = editor.dom.get('table');
|
||||
rng = editor.selection.getRng();
|
||||
rng.moveToElementText(table);
|
||||
rng.move('character', -1);
|
||||
rng.select();
|
||||
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, 'BODY');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'BODY');
|
||||
equal(rng.endOffset, 1);
|
||||
});*/
|
||||
|
||||
test("Selection end within empty element", function() {
|
||||
var rng;
|
||||
|
||||
editor.focus();
|
||||
editor.getBody().innerHTML = '<p>123</p><p></p>';
|
||||
|
||||
rng = editor.execCommand('SelectAll');
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, '#text');
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endContainer.nodeName, 'BODY');
|
||||
equal(rng.endOffset, 2);
|
||||
});
|
||||
|
||||
test("Selection after paragraph", function() {
|
||||
var rng;
|
||||
|
||||
editor.focus();
|
||||
editor.getBody().innerHTML = '<p>123</p><p>abcd</p>';
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 1);
|
||||
rng.setEnd(editor.getBody().firstChild, 1);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
ok(rng.startContainer == rng.endContainer);
|
||||
equal(rng.startContainer.nodeName, '#text');
|
||||
equal(rng.startOffset, 3);
|
||||
equal(rng.endContainer.nodeName, '#text');
|
||||
equal(rng.endOffset, 3);
|
||||
});
|
||||
|
||||
test("Selection of text outside of a block element", function() {
|
||||
var r;
|
||||
|
||||
editor.settings.forced_root_block = '';
|
||||
editor.focus();
|
||||
editor.getBody().innerHTML = '<ul><li>Item</li></ul>Text';
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody().lastChild, 2);
|
||||
r.setEnd(editor.getBody().lastChild, 2);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody().lastChild, "Start container is text node.");
|
||||
equal(r.endContainer, editor.getBody().lastChild, "End container is text node.");
|
||||
equal(r.startOffset, 2);
|
||||
equal(r.endOffset, 2);
|
||||
|
||||
equal(editor.selection.getStart(), editor.getBody(), "Selection start is body.");
|
||||
deepEqual(editor.selection.getSelectedBlocks(), [], "No blocks selected.");
|
||||
});
|
||||
|
||||
test("Resizable element text selection", function() {
|
||||
var r;
|
||||
|
||||
editor.getBody().innerHTML = '<div style="width: 100px; height:100px;"><table><tr><td>.</td></tr></table>abc</div>';
|
||||
editor.focus();
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody().firstChild.lastChild, 1);
|
||||
r.setEnd(editor.getBody().firstChild.lastChild, 2);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody().firstChild.lastChild, "Start container is text node.");
|
||||
equal(r.endContainer, editor.getBody().firstChild.lastChild, "End container is text node.");
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endOffset, 2);
|
||||
});
|
||||
|
||||
test("Resizable element before table selection", function() {
|
||||
var r;
|
||||
|
||||
editor.getBody().innerHTML = '<div style="width: 100px; height:100px;"><table><tr><td>.</td></tr></table></div>';
|
||||
editor.focus();
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody().firstChild, 0);
|
||||
r.setEnd(editor.getBody().firstChild, 0);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody().firstChild, "Start container is div node.");
|
||||
equal(r.endContainer, editor.getBody().firstChild, "End container is div node.");
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endOffset, 0);
|
||||
});
|
||||
|
||||
test("Fragmented text nodes after element", function() {
|
||||
var r;
|
||||
|
||||
editor.getBody().innerHTML = '<b>x</b>';
|
||||
editor.getBody().appendChild(editor.getDoc().createTextNode('1'));
|
||||
editor.getBody().appendChild(editor.getDoc().createTextNode('23'));
|
||||
editor.getBody().appendChild(editor.getDoc().createTextNode('456'));
|
||||
editor.getBody().appendChild(editor.getDoc().createTextNode('7890'));
|
||||
editor.focus();
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody().lastChild, 1);
|
||||
r.setEnd(editor.getBody().lastChild, 1);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody().lastChild, "Start container is last text node.");
|
||||
equal(r.endContainer, editor.getBody().lastChild, "End container is last text node.");
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endOffset, 1);
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody().childNodes[2], 2);
|
||||
r.setEnd(editor.getBody().childNodes[2], 2);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody().childNodes[2], "Start container is second text node.");
|
||||
equal(r.endContainer, editor.getBody().childNodes[2], "End container is second text node.");
|
||||
equal(r.startOffset, 2);
|
||||
equal(r.endOffset, 2);
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody().childNodes[3], 0);
|
||||
r.setEnd(editor.getBody().childNodes[3], 1);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody().childNodes[2], "Start container is second text node (lean left).");
|
||||
equal(r.endContainer, editor.getBody().childNodes[3], "End container is third text node.");
|
||||
equal(r.startOffset, 2);
|
||||
equal(r.endOffset, 1);
|
||||
});
|
||||
|
||||
test("Fragmented text nodes before element", function() {
|
||||
var r;
|
||||
|
||||
editor.getBody().innerHTML = '';
|
||||
editor.getBody().appendChild(editor.getDoc().createTextNode('1'));
|
||||
editor.getBody().appendChild(editor.getDoc().createTextNode('23'));
|
||||
editor.getBody().appendChild(editor.getDoc().createTextNode('456'));
|
||||
editor.getBody().appendChild(editor.getDoc().createTextNode('7890'));
|
||||
editor.getBody().appendChild(editor.dom.create('b', null, 'x'));
|
||||
editor.focus();
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody().childNodes[3], 1);
|
||||
r.setEnd(editor.getBody().childNodes[3], 1);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody().childNodes[3], "Start container is last text node.");
|
||||
equal(r.endContainer, editor.getBody().childNodes[3], "End container is last text node.");
|
||||
equal(r.startContainer.nodeValue, '7890');
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endOffset, 1);
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody().childNodes[1], 2);
|
||||
r.setEnd(editor.getBody().childNodes[1], 2);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody().childNodes[2], "Start container is second text node. (lean right)");
|
||||
equal(r.endContainer, editor.getBody().childNodes[2], "End container is second text node.");
|
||||
equal(r.startContainer.nodeValue, '456');
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endOffset, 0);
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody().childNodes[1], 0);
|
||||
r.setEnd(editor.getBody().childNodes[1], 1);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody().childNodes[1], "Start container is second text node.");
|
||||
equal(r.endContainer, editor.getBody().childNodes[1], "End container is third text node.");
|
||||
equal(r.startContainer.nodeValue, '23');
|
||||
equal(r.endContainer.nodeValue, '23');
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endOffset, 1);
|
||||
});
|
||||
|
||||
test("Non contentEditable elements", function() {
|
||||
var r;
|
||||
|
||||
editor.getBody().innerHTML = '<span contentEditable="false">a</span><span contentEditable="false">a</span><span contentEditable="false">a</span>';
|
||||
editor.focus();
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody(), 0);
|
||||
r.setEnd(editor.getBody(), 0);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody(), "Start container is before first nonEditable.");
|
||||
equal(r.endContainer, editor.getBody(), "End container is before first nonEditable.");
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endOffset, 0);
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody(), 0);
|
||||
r.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody(), "Start container before first nonEditable.");
|
||||
equal(r.endContainer, editor.getBody(), "End container is after first nonEditable.");
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endOffset, 1);
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody(), 0);
|
||||
r.setEnd(editor.getBody(), 2);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody(), "Start container before first nonEditable.");
|
||||
equal(r.endContainer, editor.getBody(), "End container is after second nonEditable.");
|
||||
equal(r.startOffset, 0);
|
||||
equal(r.endOffset, 2);
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody(), 1);
|
||||
r.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody(), "Start container is before second nonEditable.");
|
||||
equal(r.endContainer, editor.getBody(), "End container is div before second nonEditable.");
|
||||
equal(r.startOffset, 1);
|
||||
equal(r.endOffset, 1);
|
||||
|
||||
r = editor.dom.createRng();
|
||||
r.setStart(editor.getBody(), 2);
|
||||
r.setEnd(editor.getBody(), 2);
|
||||
editor.selection.setRng(r);
|
||||
|
||||
r = editor.selection.getRng(true);
|
||||
equal(r.startContainer, editor.getBody(), "Start container is after last nonEditable.");
|
||||
equal(r.endContainer, editor.getBody(), "End container is after last nonEditable.");
|
||||
equal(r.startOffset, 2);
|
||||
equal(r.endOffset, 2);
|
||||
});
|
||||
} else {
|
||||
test("Skipped ie_selection tests as not running in IE.", function() {
|
||||
ok(true, "Dummy assert");
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,120 +0,0 @@
|
||||
body, div, h1 { font-family: 'trebuchet ms', verdana, arial; margin: 0; padding: 0 }
|
||||
body {font-size: 10pt; }
|
||||
h1 { padding: 15px; font-size: large; background-color: #06b; color: white; }
|
||||
h1 a { color: white; }
|
||||
h2 { padding: 10px; background-color: #eee; color: black; margin: 0; font-size: small; font-weight: normal }
|
||||
|
||||
.pass { color: green; }
|
||||
.fail { color: red; }
|
||||
p.result { margin-left: 1em; }
|
||||
|
||||
#banner { height: 2em; border-bottom: 1px solid white; }
|
||||
h2.pass { background-color: green; }
|
||||
h2.fail { background-color: red; }
|
||||
|
||||
div.testrunner-toolbar { background: #eee; border-top: 1px solid black; padding: 10px; }
|
||||
|
||||
ol#tests > li > strong { cursor:pointer; }
|
||||
|
||||
div#fx-tests h4 {
|
||||
background: red;
|
||||
}
|
||||
|
||||
div#fx-tests h4.pass {
|
||||
background: green;
|
||||
}
|
||||
|
||||
div#fx-tests div.box {
|
||||
background: red url(data/cow.jpg) no-repeat;
|
||||
overflow: hidden;
|
||||
border: 2px solid #000;
|
||||
}
|
||||
|
||||
div#fx-tests div.overflow {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
div.inline {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.autoheight {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
div.autowidth {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
div.autoopacity {
|
||||
opacity: auto;
|
||||
}
|
||||
|
||||
div.largewidth {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
div.largeheight {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
div.largeopacity {
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=100);
|
||||
}
|
||||
|
||||
div.medwidth {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
div.medheight {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
div.medopacity {
|
||||
opacity: 0.5;
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50);
|
||||
}
|
||||
|
||||
div.nowidth {
|
||||
width: 0px;
|
||||
}
|
||||
|
||||
div.noheight {
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
div.noopacity {
|
||||
opacity: 0;
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0);
|
||||
}
|
||||
|
||||
div.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div#fx-tests div.widewidth {
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
div#fx-tests div.wideheight {
|
||||
background-repeat: repeat-y;
|
||||
}
|
||||
|
||||
div#fx-tests div.widewidth.wideheight {
|
||||
background-repeat: repeat;
|
||||
}
|
||||
|
||||
div#fx-tests div.noback {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
div.chain, div.chain div { width: 100px; height: 20px; position: relative; float: left; }
|
||||
div.chain div { position: absolute; top: 0px; left: 0px; }
|
||||
|
||||
div.chain.test { background: red; }
|
||||
div.chain.test div { background: green; }
|
||||
|
||||
div.chain.out { background: green; }
|
||||
div.chain.out div { background: red; display: none; }
|
||||
|
||||
div#show-tests * { display: none; }
|
||||
@ -1,17 +0,0 @@
|
||||
ModuleLoader.require(["tinymce/file/Conversions"], function(Conversions) {
|
||||
module("tinymce.file.Conversions");
|
||||
|
||||
if (!tinymce.Env.fileApi) {
|
||||
test("File API not supported by browser.", function() {
|
||||
QUnit.ok(true);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QUnit.asyncTest("uriToBlob", function() {
|
||||
Conversions.uriToBlob("data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D").then(Conversions.blobToDataUri).then(function(dataUri) {
|
||||
QUnit.equal(dataUri, "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==");
|
||||
}).then(QUnit.start);
|
||||
});
|
||||
});
|
||||
@ -1,63 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/file/ImageScanner",
|
||||
"tinymce/file/UploadStatus",
|
||||
"tinymce/file/BlobCache",
|
||||
"tinymce/file/Conversions",
|
||||
"tinymce/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">'
|
||||
);
|
||||
|
||||
imageScanner.findAll(document.getElementById('view')).then(function(result) {
|
||||
QUnit.start();
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.asyncTest("findAll (filtered)", function() {
|
||||
var imageScanner = new ImageScanner(new UploadStatus(), new BlobCache());
|
||||
|
||||
function predicate(img) {
|
||||
return !img.hasAttribute('data-skip');
|
||||
}
|
||||
|
||||
document.getElementById('view').innerHTML = (
|
||||
'<img src="' + base64Src + '">' +
|
||||
'<img src="' + base64Src + '" data-skip="1">'
|
||||
);
|
||||
|
||||
imageScanner.findAll(document.getElementById('view'), predicate).then(function(result) {
|
||||
QUnit.start();
|
||||
equal(result.length, 1);
|
||||
equal('data:image/gif;base64,' + result[0].blobInfo.base64(), base64Src);
|
||||
strictEqual(result[0].image, document.getElementById('view').firstChild);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,32 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/file/UploadStatus"
|
||||
], function(UploadStatus) {
|
||||
module("tinymce.file.UploadStatus");
|
||||
|
||||
QUnit.test("hasBlobUri/markPending", function() {
|
||||
var status = new UploadStatus();
|
||||
|
||||
strictEqual(status.hasBlobUri("nonexisting_uri"), false);
|
||||
status.markPending("existing_uri");
|
||||
strictEqual(status.isPending("existing_uri"), true);
|
||||
strictEqual(status.isUploaded("existing_uri"), false);
|
||||
strictEqual(status.hasBlobUri("existing_uri"), true);
|
||||
|
||||
status.markUploaded("existing_uri", "uri");
|
||||
strictEqual(status.isPending("existing_uri"), false);
|
||||
strictEqual(status.isUploaded("existing_uri"), true);
|
||||
strictEqual(status.hasBlobUri("existing_uri"), true);
|
||||
strictEqual(status.getResultUri("existing_uri"), "uri");
|
||||
|
||||
status.markUploaded("existing_uri2", "uri2");
|
||||
strictEqual(status.isPending("existing_uri"), false);
|
||||
strictEqual(status.isUploaded("existing_uri"), true);
|
||||
strictEqual(status.hasBlobUri("existing_uri2"), true);
|
||||
strictEqual(status.getResultUri("existing_uri2"), "uri2");
|
||||
|
||||
status.markPending("existing_uri");
|
||||
strictEqual(status.hasBlobUri("existing_uri"), true);
|
||||
status.removeFailed("existing_uri");
|
||||
strictEqual(status.hasBlobUri("existing_uri"), false);
|
||||
});
|
||||
});
|
||||
@ -1,75 +0,0 @@
|
||||
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();
|
||||
});
|
||||
});
|
||||
@ -1,71 +0,0 @@
|
||||
ModuleLoader.require(["tinymce/fmt/Hooks"], function(Hooks) {
|
||||
module("tinymce.fmt.Hooks", {
|
||||
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) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('pre - postProcessHook', function() {
|
||||
function assertPreHook(setupHtml, setupSelection, expected) {
|
||||
editor.getBody().innerHTML = setupHtml;
|
||||
Utils.setSelection.apply(Utils, setupSelection);
|
||||
Hooks.postProcess('pre', editor);
|
||||
equal(editor.getContent(), expected);
|
||||
}
|
||||
|
||||
assertPreHook(
|
||||
'<pre>a</pre><pre>b</pre>',
|
||||
['pre:nth-child(1)', 0, 'pre:nth-child(2)', 1],
|
||||
'<pre>a<br /><br />b</pre>'
|
||||
);
|
||||
|
||||
assertPreHook(
|
||||
'<pre>a</pre><pre>b</pre>',
|
||||
['pre:nth-child(2)', 0, 'pre:nth-child(2)', 1],
|
||||
'<pre>a</pre><pre>b</pre>'
|
||||
);
|
||||
|
||||
assertPreHook(
|
||||
'<pre>a</pre><pre>b</pre>',
|
||||
['pre:nth-child(2)', 1, 'pre:nth-child(2)', 1],
|
||||
'<pre>a</pre><pre>b</pre>'
|
||||
);
|
||||
|
||||
assertPreHook(
|
||||
'<pre>a</pre><pre>b</pre><pre>c</pre>',
|
||||
['pre:nth-child(1)', 0, 'pre:nth-child(3)', 1],
|
||||
'<pre>a<br /><br />b<br /><br />c</pre>'
|
||||
);
|
||||
|
||||
assertPreHook(
|
||||
'<pre>a</pre><pre>b</pre>',
|
||||
['pre:nth-child(1)', 0, 'pre:nth-child(1)', 1],
|
||||
'<pre>a</pre><pre>b</pre>'
|
||||
);
|
||||
|
||||
assertPreHook(
|
||||
'<pre>a</pre><p>b</p><pre>c</pre>',
|
||||
['pre:nth-child(1)', 0, 'pre:nth-child(3)', 1],
|
||||
'<pre>a</pre><p>b</p><pre>c</pre>'
|
||||
);
|
||||
|
||||
assertPreHook(
|
||||
'<pre>a</pre><pre>b</pre><p>c</p><pre>d</pre><pre>e</pre>',
|
||||
['pre:nth-child(1)', 0, 'pre:nth-child(5)', 1],
|
||||
'<pre>a<br /><br />b</pre><p>c</p><pre>d<br /><br />e</pre>'
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,247 +0,0 @@
|
||||
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');
|
||||
|
||||
});
|
||||
});
|
||||
@ -1,79 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/geom/ClientRect"
|
||||
], function(ClientRect) {
|
||||
module("tinymce.geom.ClientRect");
|
||||
|
||||
function rect(x, y, w, h) {
|
||||
return {
|
||||
left: x,
|
||||
top: y,
|
||||
bottom: y + h,
|
||||
right: x + w,
|
||||
width: w,
|
||||
height: h
|
||||
};
|
||||
}
|
||||
|
||||
test('clone', function() {
|
||||
deepEqual(ClientRect.clone(rect(10, 20, 30, 40)), rect(10, 20, 30, 40));
|
||||
deepEqual(ClientRect.clone(rect(10.1, 20.1, 30.1, 40.1)), rect(10, 20, 30, 40));
|
||||
});
|
||||
|
||||
test('collapse', function() {
|
||||
deepEqual(ClientRect.collapse(rect(10, 20, 30, 40), true), rect(10, 20, 0, 40));
|
||||
deepEqual(ClientRect.collapse(rect(10, 20, 30, 40), false), rect(40, 20, 0, 40));
|
||||
});
|
||||
|
||||
test('isAbove', function() {
|
||||
equal(ClientRect.isAbove(rect(10, 70, 10, 40), rect(20, 40, 10, 20)), false);
|
||||
equal(ClientRect.isAbove(rect(10, 40, 10, 20), rect(20, 70, 10, 40)), true);
|
||||
});
|
||||
|
||||
test('isAbove intersects', function() {
|
||||
equal(ClientRect.isAbove(rect(10, 20, 10, 10), rect(20, 20, 10, 10)), false);
|
||||
equal(ClientRect.isAbove(rect(10, 20, 10, 40), rect(20, 20, 10, 10)), false);
|
||||
equal(ClientRect.isAbove(rect(10, 20, 10, 10), rect(20, 20, 10, 40)), false);
|
||||
equal(ClientRect.isAbove(rect(10, 10, 10, 10), rect(20, 20, 10, 10)), true);
|
||||
equal(ClientRect.isAbove(rect(10, 15, 10, 10), rect(20, 20, 10, 10)), false);
|
||||
});
|
||||
|
||||
test('isBelow', function() {
|
||||
equal(ClientRect.isBelow(rect(10, 70, 10, 40), rect(20, 40, 10, 20)), true);
|
||||
equal(ClientRect.isBelow(rect(10, 40, 10, 20), rect(20, 70, 10, 40)), false);
|
||||
});
|
||||
|
||||
test('isBelow intersects', function() {
|
||||
equal(ClientRect.isBelow(rect(10, 30, 10, 20), rect(20, 10, 10, 20)), true);
|
||||
equal(ClientRect.isBelow(rect(10, 30, 10, 20), rect(20, 10, 10, 25)), true);
|
||||
equal(ClientRect.isBelow(rect(10, 15, 10, 20), rect(20, 30, 10, 20)), false);
|
||||
equal(ClientRect.isBelow(rect(10, 29, 10, 20), rect(20, 10, 10, 30)), false);
|
||||
equal(ClientRect.isBelow(rect(10, 30, 10, 20), rect(20, 10, 10, 30)), true);
|
||||
equal(ClientRect.isBelow(rect(10, 20, 10, 20), rect(20, 10, 10, 30)), false);
|
||||
});
|
||||
|
||||
test('isLeft', function() {
|
||||
equal(ClientRect.isLeft(rect(10, 20, 30, 40), rect(20, 20, 30, 40)), true);
|
||||
equal(ClientRect.isLeft(rect(20, 20, 30, 40), rect(10, 20, 30, 40)), false);
|
||||
});
|
||||
|
||||
test('isRight', function() {
|
||||
equal(ClientRect.isRight(rect(10, 20, 30, 40), rect(20, 20, 30, 40)), false);
|
||||
equal(ClientRect.isRight(rect(20, 20, 30, 40), rect(10, 20, 30, 40)), true);
|
||||
});
|
||||
|
||||
test('compare', function() {
|
||||
equal(ClientRect.compare(rect(10, 70, 10, 40), rect(10, 40, 10, 20)), 1);
|
||||
equal(ClientRect.compare(rect(10, 40, 10, 20), rect(10, 70, 10, 40)), -1);
|
||||
equal(ClientRect.compare(rect(5, 10, 10, 10), rect(10, 10, 10, 10)), -1);
|
||||
equal(ClientRect.compare(rect(15, 10, 10, 10), rect(10, 10, 10, 10)), 1);
|
||||
});
|
||||
|
||||
test('containsXY', function() {
|
||||
equal(ClientRect.containsXY(rect(10, 70, 10, 40), 1, 2), false);
|
||||
equal(ClientRect.containsXY(rect(10, 70, 10, 40), 15, 2), false);
|
||||
equal(ClientRect.containsXY(rect(10, 70, 10, 40), 25, 2), false);
|
||||
equal(ClientRect.containsXY(rect(10, 70, 10, 40), 10, 70), true);
|
||||
equal(ClientRect.containsXY(rect(10, 70, 10, 40), 20, 110), true);
|
||||
equal(ClientRect.containsXY(rect(10, 70, 10, 40), 15, 75), true);
|
||||
});
|
||||
});
|
||||
@ -1,92 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/geom/Rect",
|
||||
"tinymce/util/Tools"
|
||||
], function(Rect, Tools) {
|
||||
module("tinymce.geom.Rect");
|
||||
|
||||
test('relativePosition', function() {
|
||||
var sourceRect = Rect.create(0, 0, 20, 30),
|
||||
targetRect = Rect.create(10, 20, 40, 50),
|
||||
tests = [
|
||||
// Only test a few of them all would be 81
|
||||
['tl-tl', 10, 20, 20, 30],
|
||||
['tc-tc', 20, 20, 20, 30],
|
||||
['tr-tr', 30, 20, 20, 30],
|
||||
['cl-cl', 10, 30, 20, 30],
|
||||
['cc-cc', 20, 30, 20, 30],
|
||||
['cr-cr', 30, 30, 20, 30],
|
||||
['bl-bl', 10, 40, 20, 30],
|
||||
['bc-bc', 20, 40, 20, 30],
|
||||
['br-br', 30, 40, 20, 30],
|
||||
['tr-tl', 50, 20, 20, 30],
|
||||
['br-bl', 50, 40, 20, 30]
|
||||
];
|
||||
|
||||
Tools.each(tests, function(item) {
|
||||
deepEqual(
|
||||
Rect.relativePosition(sourceRect, targetRect, item[0]),
|
||||
Rect.create(item[1], item[2], item[3], item[4]),
|
||||
item[0]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('findBestRelativePosition', function() {
|
||||
var sourceRect = Rect.create(0, 0, 20, 30),
|
||||
targetRect = Rect.create(10, 20, 40, 50),
|
||||
tests = [
|
||||
[['tl-tl'], 5, 15, 100, 100, 'tl-tl'],
|
||||
[['tl-tl'], 20, 30, 100, 100, null],
|
||||
[['tl-tl', 'tr-tl'], 20, 20, 100, 100, 'tr-tl'],
|
||||
[['tl-bl', 'tr-tl', 'bl-tl'], 10, 20, 40, 100, 'bl-tl']
|
||||
];
|
||||
|
||||
Tools.each(tests, function(item) {
|
||||
equal(
|
||||
Rect.findBestRelativePosition(sourceRect, targetRect, Rect.create(item[1], item[2], item[3], item[4]), item[0]),
|
||||
item[5],
|
||||
item[5]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('inflate', function() {
|
||||
deepEqual(Rect.inflate(Rect.create(10, 20, 30, 40), 5, 10), Rect.create(5, 10, 40, 60));
|
||||
});
|
||||
|
||||
test('intersect', function() {
|
||||
ok(Rect.intersect(Rect.create(10, 20, 30, 40), Rect.create(10, 20, 30, 40)));
|
||||
ok(Rect.intersect(Rect.create(10, 20, 30, 40), Rect.create(15, 25, 30, 40)));
|
||||
ok(Rect.intersect(Rect.create(10, 20, 30, 40), Rect.create(15, 25, 5, 5)));
|
||||
ok(!Rect.intersect(Rect.create(10, 20, 30, 40), Rect.create(0, 10, 5, 5)));
|
||||
ok(!Rect.intersect(Rect.create(10, 20, 30, 40), Rect.create(45, 20, 5, 5)));
|
||||
ok(!Rect.intersect(Rect.create(10, 20, 30, 40), Rect.create(10, 65, 5, 5)));
|
||||
ok(Rect.intersect(Rect.create(10, 20, 30, 40), Rect.create(40, 20, 30, 40)));
|
||||
ok(Rect.intersect(Rect.create(10, 20, 30, 40), Rect.create(10, 60, 30, 40)));
|
||||
});
|
||||
|
||||
test('clamp', function() {
|
||||
deepEqual(
|
||||
Rect.clamp(Rect.create(10, 20, 30, 40), Rect.create(10, 20, 30, 40)),
|
||||
Rect.create(10, 20, 30, 40)
|
||||
);
|
||||
|
||||
deepEqual(
|
||||
Rect.clamp(Rect.create(5, 20, 30, 40), Rect.create(10, 20, 30, 40)),
|
||||
Rect.create(10, 20, 25, 40)
|
||||
);
|
||||
|
||||
deepEqual(
|
||||
Rect.clamp(Rect.create(5, 20, 30, 40), Rect.create(10, 20, 30, 40), true),
|
||||
Rect.create(10, 20, 30, 40)
|
||||
);
|
||||
});
|
||||
|
||||
test('create', function() {
|
||||
deepEqual(Rect.create(10, 20, 30, 40), {x: 10, y: 20, w: 30, h: 40});
|
||||
});
|
||||
|
||||
test('fromClientRect', function() {
|
||||
deepEqual(Rect.fromClientRect({left: 10, top: 20, width: 30, height: 40}), {x: 10, y: 20, w: 30, h: 40});
|
||||
});
|
||||
});
|
||||
@ -1,579 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.html.DomParser");
|
||||
|
||||
var schema = new tinymce.html.Schema({valid_elements: '*[class|title]'});
|
||||
var serializer = new tinymce.html.Serializer({}, schema);
|
||||
var parser, root;
|
||||
|
||||
function countNodes(node, counter) {
|
||||
var sibling;
|
||||
|
||||
if (!counter) {
|
||||
counter = {};
|
||||
}
|
||||
|
||||
if (node.name in counter) {
|
||||
counter[node.name]++;
|
||||
} else {
|
||||
counter[node.name] = 1;
|
||||
}
|
||||
|
||||
for (sibling = node.firstChild; sibling; sibling = sibling.next) {
|
||||
countNodes(sibling, counter);
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
schema.addValidChildren('+body[style]');
|
||||
|
||||
test('Parse element', function() {
|
||||
var parser, root;
|
||||
|
||||
expect(7);
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<B title="title" class="class">test</B>');
|
||||
equal(serializer.serialize(root), '<b class="class" title="title">test</b>', 'Inline element');
|
||||
equal(root.firstChild.type, 1, 'Element type');
|
||||
equal(root.firstChild.name, 'b', 'Element name');
|
||||
deepEqual(root.firstChild.attributes, [{name: 'title', value: 'title'}, {name: 'class', value: 'class'}], 'Element attributes');
|
||||
deepEqual(countNodes(root), {body:1, b:1, '#text':1}, 'Element attributes (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse(' \t\r\n <SCRIPT> \t\r\n a < b > \t\r\n </S' + 'CRIPT> \t\r\n ');
|
||||
equal(serializer.serialize(root), '<script> \t\r\n a < b > \t\r\n </s' + 'cript>', 'Retain code inside SCRIPT');
|
||||
deepEqual(countNodes(root), {body:1, script:1, '#text':1}, 'Retain code inside SCRIPT (count)');
|
||||
});
|
||||
|
||||
test('Whitespace', function() {
|
||||
expect(12);
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse(' \t\r\n <B> \t\r\n test \t\r\n </B> \t\r\n ');
|
||||
equal(serializer.serialize(root), ' <b> test </b> ', 'Redundant whitespace (inline element)');
|
||||
deepEqual(countNodes(root), {body:1, b:1, '#text':3}, 'Redundant whitespace (inline element) (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse(' \t\r\n <P> \t\r\n test \t\r\n </P> \t\r\n ');
|
||||
equal(serializer.serialize(root), '<p>test</p>', 'Redundant whitespace (block element)');
|
||||
deepEqual(countNodes(root), {body:1, p:1, '#text':1}, 'Redundant whitespace (block element) (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse(' \t\r\n <SCRIPT> \t\r\n test \t\r\n </S' + 'CRIPT> \t\r\n ');
|
||||
equal(serializer.serialize(root), '<script> \t\r\n test \t\r\n </s' + 'cript>', 'Whitespace around and inside SCRIPT');
|
||||
deepEqual(countNodes(root), {body:1, script:1, '#text':1}, 'Whitespace around and inside SCRIPT (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse(' \t\r\n <STYLE> \t\r\n test \t\r\n </STYLE> \t\r\n ');
|
||||
equal(serializer.serialize(root), '<style> \t\r\n test \t\r\n </style>', 'Whitespace around and inside STYLE');
|
||||
deepEqual(countNodes(root), {body:1, style:1, '#text':1}, 'Whitespace around and inside STYLE (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<ul>\n<li>Item 1\n<ul>\n<li>\n \t Indented \t \n</li>\n</ul>\n</li>\n</ul>\n');
|
||||
equal(serializer.serialize(root), '<ul><li>Item 1<ul><li>Indented</li></ul></li></ul>', 'Whitespace around and inside blocks (ul/li)');
|
||||
deepEqual(countNodes(root), {body:1, li:2, ul:2, '#text':2}, 'Whitespace around and inside blocks (ul/li) (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, new tinymce.html.Schema({invalid_elements : 'hr,br'}));
|
||||
root = parser.parse('\n<hr />\n<br />\n<div>\n<hr />\n<br />\n<img src="file.gif" data-mce-src="file.gif" />\n<hr />\n<br />\n</div>\n<hr />\n<br />\n');
|
||||
equal(serializer.serialize(root), '<div><img src="file.gif" data-mce-src="file.gif" /></div>', 'Whitespace where SaxParser will produce multiple whitespace nodes');
|
||||
deepEqual(countNodes(root), {body:1, div:1, img:1}, 'Whitespace where SaxParser will produce multiple whitespace nodes (count)');
|
||||
});
|
||||
|
||||
test('Whitespace before/after invalid element with text in block', function() {
|
||||
parser = new tinymce.html.DomParser({}, new tinymce.html.Schema({invalid_elements : 'em'}));
|
||||
root = parser.parse('<p>a <em>b</em> c</p>');
|
||||
equal(serializer.serialize(root), '<p>a b c</p>');
|
||||
});
|
||||
|
||||
test('Whitespace before/after invalid element whitespace element in block', function() {
|
||||
parser = new tinymce.html.DomParser({}, new tinymce.html.Schema({invalid_elements : 'span'}));
|
||||
root = parser.parse('<p> <span></span> </p>');
|
||||
equal(serializer.serialize(root), '<p>\u00a0</p>');
|
||||
});
|
||||
|
||||
test('Whitespace preserved in PRE', function() {
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse(' \t\r\n <PRE> \t\r\n test \t\r\n </PRE> \t\r\n ');
|
||||
equal(serializer.serialize(root), '<pre> \t\r\n test \t\r\n </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 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 ');
|
||||
equal(serializer.serialize(root), '<pre> \t\r\n <span> test </span> \t\r\n </pre>', 'Whitespace around and inside PRE');
|
||||
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;
|
||||
|
||||
expect(20);
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p class="a"><p class="b">123</p></p>');
|
||||
equal(serializer.serialize(root), '<p class="b">123</p>', 'P in P, no nodes before/after');
|
||||
deepEqual(countNodes(root), {body:1, p:1, '#text':1}, 'P in P, no nodes before/after (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p class="a">a<p class="b">b</p><p class="c">c</p>d</p>');
|
||||
equal(serializer.serialize(root), '<p class="a">a</p><p class="b">b</p><p class="c">c</p><p class="a">d</p>', 'Two P in P, no nodes before/after');
|
||||
deepEqual(countNodes(root), {body: 1, p:4, '#text': 4}, 'Two P in P, no nodes before/after (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p class="a">abc<p class="b">def</p></p>');
|
||||
equal(serializer.serialize(root), '<p class="a">abc</p><p class="b">def</p>', 'P in P with nodes before');
|
||||
deepEqual(countNodes(root), {body: 1, p:2, '#text': 2}, 'P in P with nodes before (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p class="a"><p class="b">abc</p>def</p>');
|
||||
equal(serializer.serialize(root), '<p class="b">abc</p><p class="a">def</p>', 'P in P with nodes after');
|
||||
deepEqual(countNodes(root), {body: 1, p:2, '#text': 2}, 'P in P with nodes after (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p class="a"><p class="b">abc</p><br></p>');
|
||||
equal(serializer.serialize(root), '<p class="b">abc</p>', 'P in P with BR after');
|
||||
deepEqual(countNodes(root), {body: 1, p:1, '#text': 1}, 'P in P with BR after (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p class="a">a<strong>b<span>c<em>d<p class="b">e</p>f</em>g</span>h</strong>i</p>');
|
||||
equal(serializer.serialize(root), '<p class="a">a<strong>b<span>c<em>d</em></span></strong></p><p class="b">e</p><p class="a"><strong><span><em>f</em>g</span>h</strong>i</p>', 'P in P wrapped in inline elements');
|
||||
deepEqual(countNodes(root), {"body":1, "p":3, "#text":9, "strong":2, "span":2, "em": 2}, 'P in P wrapped in inline elements (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p class="a">a<p class="b">b<p class="c">c</p>d</p>e</p>');
|
||||
equal(serializer.serialize(root), '<p class="a">a</p><p class="b">b</p><p class="c">c</p><p class="b">d</p><p class="a">e</p>', 'P in P in P with text before/after');
|
||||
deepEqual(countNodes(root), {body: 1, p:5, '#text': 5}, 'P in P in P with text before/after (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p>a<ul><li>b</li><li>c</li></ul>d</p>');
|
||||
equal(serializer.serialize(root), '<p>a</p><ul><li>b</li><li>c</li></ul><p>d</p>', 'UL inside P');
|
||||
deepEqual(countNodes(root), {body: 1, p:2, ul:1, li:2, '#text': 4}, 'UL inside P (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<table><tr><td><tr>a</tr></td></tr></table>');
|
||||
equal(serializer.serialize(root), '<table><tr><td>a</td></tr></table>', 'TR inside TD');
|
||||
deepEqual(countNodes(root), {body: 1, table:1, tr:1, td:1, '#text': 1}, 'TR inside TD (count)');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, new tinymce.html.Schema({valid_elements: 'p,section,div'}));
|
||||
root = parser.parse('<div><section><p>a</p></section></div>');
|
||||
equal(serializer.serialize(root), '<div><section><p>a</p></section></div>', 'P inside SECTION');
|
||||
deepEqual(countNodes(root), {"body":1, "div":1, "section":1, "p":1, "#text":1}, 'P inside SECTION (count)');
|
||||
});
|
||||
|
||||
test('Remove empty nodes', function() {
|
||||
parser = new tinymce.html.DomParser({}, new tinymce.html.Schema({valid_elements: '-p,-span[id]'}));
|
||||
root = parser.parse('<p>a<span></span><span> </span><span id="x">b</span><span id="y"></span></p><p></p><p><span></span></p><p> </p>');
|
||||
equal(serializer.serialize(root), '<p>a <span id="x">b</span><span id="y"></span></p>');
|
||||
});
|
||||
|
||||
test('addNodeFilter', function() {
|
||||
var parser, result;
|
||||
|
||||
expect(7);
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
parser.addNodeFilter('#comment', function(nodes, name, args) {
|
||||
result = {nodes : nodes, name : name, args : args};
|
||||
});
|
||||
parser.parse('text<!--text1-->text<!--text2-->');
|
||||
|
||||
deepEqual(result.args, {}, 'Parser args');
|
||||
equal(result.name, '#comment', 'Parser filter result name');
|
||||
equal(result.nodes.length, 2, 'Parser filter result node');
|
||||
equal(result.nodes[0].name, '#comment', 'Parser filter result node(0) name');
|
||||
equal(result.nodes[0].value, 'text1', 'Parser filter result node(0) value');
|
||||
equal(result.nodes[1].name, '#comment', 'Parser filter result node(1) name');
|
||||
equal(result.nodes[1].value, 'text2', 'Parser filter result node(1) value');
|
||||
});
|
||||
|
||||
test('addNodeFilter multiple names', function() {
|
||||
var parser, results = {};
|
||||
|
||||
expect(14);
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
parser.addNodeFilter('#comment,#text', function(nodes, name, args) {
|
||||
results[name] = {nodes : nodes, name : name, args : args};
|
||||
});
|
||||
parser.parse('text1<!--text1-->text2<!--text2-->');
|
||||
|
||||
deepEqual(results['#comment'].args, {}, 'Parser args');
|
||||
equal(results['#comment'].name, '#comment', 'Parser filter result name');
|
||||
equal(results['#comment'].nodes.length, 2, 'Parser filter result node');
|
||||
equal(results['#comment'].nodes[0].name, '#comment', 'Parser filter result node(0) name');
|
||||
equal(results['#comment'].nodes[0].value, 'text1', 'Parser filter result node(0) value');
|
||||
equal(results['#comment'].nodes[1].name, '#comment', 'Parser filter result node(1) name');
|
||||
equal(results['#comment'].nodes[1].value, 'text2', 'Parser filter result node(1) value');
|
||||
deepEqual(results['#text'].args, {}, 'Parser args');
|
||||
equal(results['#text'].name, '#text', 'Parser filter result name');
|
||||
equal(results['#text'].nodes.length, 2, 'Parser filter result node');
|
||||
equal(results['#text'].nodes[0].name, '#text', 'Parser filter result node(0) name');
|
||||
equal(results['#text'].nodes[0].value, 'text1', 'Parser filter result node(0) value');
|
||||
equal(results['#text'].nodes[1].name, '#text', 'Parser filter result node(1) name');
|
||||
equal(results['#text'].nodes[1].value, 'text2', 'Parser filter result node(1) value');
|
||||
});
|
||||
|
||||
test('addNodeFilter with parser args', function() {
|
||||
var parser, result;
|
||||
|
||||
expect(1);
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
parser.addNodeFilter('#comment', function(nodes, name, args) {
|
||||
result = {nodes : nodes, name : name, args : args};
|
||||
});
|
||||
parser.parse('text<!--text1-->text<!--text2-->', {value: 1});
|
||||
|
||||
deepEqual(result.args, {value: 1}, 'Parser args');
|
||||
});
|
||||
|
||||
test('addAttributeFilter', function() {
|
||||
var parser, result;
|
||||
|
||||
expect(7);
|
||||
|
||||
parser = new tinymce.html.DomParser({});
|
||||
parser.addAttributeFilter('src', function(nodes, name, args) {
|
||||
result = {nodes : nodes, name : name, args : args};
|
||||
});
|
||||
parser.parse('<b>a<img src="1.gif" />b<img src="1.gif" />c</b>');
|
||||
|
||||
deepEqual(result.args, {}, 'Parser args');
|
||||
equal(result.name, 'src', 'Parser filter result name');
|
||||
equal(result.nodes.length, 2, 'Parser filter result node');
|
||||
equal(result.nodes[0].name, 'img', 'Parser filter result node(0) name');
|
||||
equal(result.nodes[0].attr('src'), '1.gif', 'Parser filter result node(0) attr');
|
||||
equal(result.nodes[1].name, 'img', 'Parser filter result node(1) name');
|
||||
equal(result.nodes[1].attr('src'), '1.gif', 'Parser filter result node(1) attr');
|
||||
});
|
||||
|
||||
test('addAttributeFilter multiple', function() {
|
||||
var parser, results = {};
|
||||
|
||||
expect(14);
|
||||
|
||||
parser = new tinymce.html.DomParser({});
|
||||
parser.addAttributeFilter('src,href', function(nodes, name, args) {
|
||||
results[name] = {nodes : nodes, name : name, args : args};
|
||||
});
|
||||
parser.parse('<b><a href="1.gif">a</a><img src="1.gif" />b<img src="1.gif" /><a href="2.gif">c</a></b>');
|
||||
|
||||
deepEqual(results.src.args, {}, 'Parser args');
|
||||
equal(results.src.name, 'src', 'Parser filter result name');
|
||||
equal(results.src.nodes.length, 2, 'Parser filter result node');
|
||||
equal(results.src.nodes[0].name, 'img', 'Parser filter result node(0) name');
|
||||
equal(results.src.nodes[0].attr('src'), '1.gif', 'Parser filter result node(0) attr');
|
||||
equal(results.src.nodes[1].name, 'img', 'Parser filter result node(1) name');
|
||||
equal(results.src.nodes[1].attr('src'), '1.gif', 'Parser filter result node(1) attr');
|
||||
deepEqual(results.href.args, {}, 'Parser args');
|
||||
equal(results.href.name, 'href', 'Parser filter result name');
|
||||
equal(results.href.nodes.length, 2, 'Parser filter result node');
|
||||
equal(results.href.nodes[0].name, 'a', 'Parser filter result node(0) name');
|
||||
equal(results.href.nodes[0].attr('href'), '1.gif', 'Parser filter result node(0) attr');
|
||||
equal(results.href.nodes[1].name, 'a', 'Parser filter result node(1) name');
|
||||
equal(results.href.nodes[1].attr('href'), '2.gif', 'Parser filter result node(1) attr');
|
||||
});
|
||||
|
||||
test('Fix orphan LI elements', function() {
|
||||
var parser;
|
||||
|
||||
expect(3);
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<ul><li>a</li></ul><li>b</li>');
|
||||
equal(serializer.serialize(root), '<ul><li>a</li><li>b</li></ul>', 'LI moved to previous sibling UL');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<li>a</li><ul><li>b</li></ul>');
|
||||
equal(serializer.serialize(root), '<ul><li>a</li><li>b</li></ul>', 'LI moved to next sibling UL');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<li>a</li>');
|
||||
equal(serializer.serialize(root), '<ul><li>a</li></ul>', 'LI wrapped in new UL');
|
||||
});
|
||||
|
||||
test('Remove empty elements', function() {
|
||||
var parser, schema = new tinymce.html.Schema({valid_elements: 'span,-a,img'});
|
||||
|
||||
expect(3);
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<span></span><a href="#"></a>');
|
||||
equal(serializer.serialize(root), '<span></span>', 'Remove empty a element');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, new tinymce.html.Schema({valid_elements: 'span,a[name],img'}));
|
||||
root = parser.parse('<span></span><a name="anchor"></a>');
|
||||
equal(serializer.serialize(root), '<span></span><a name="anchor"></a>', 'Leave a with name attribute');
|
||||
|
||||
parser = new tinymce.html.DomParser({}, new tinymce.html.Schema({valid_elements: 'span,a[href],img[src]'}));
|
||||
root = parser.parse('<span></span><a href="#"><img src="about:blank" /></a>');
|
||||
equal(serializer.serialize(root), '<span></span><a href="#"><img src="about:blank" /></a>', 'Leave elements with img in it');
|
||||
});
|
||||
|
||||
test('Self closing list elements', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
expect(1);
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<ul><li>1<li><b>2</b><li><em><b>3</b></em></ul>');
|
||||
equal(serializer.serialize(root), '<ul><li>1</li><li><strong>2</strong></li><li><em><strong>3</strong></em></li></ul>', 'Split out LI elements in LI elements.');
|
||||
});
|
||||
|
||||
test('Remove redundant br elements', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
expect(1);
|
||||
|
||||
parser = new tinymce.html.DomParser({remove_trailing_brs : true}, schema);
|
||||
root = parser.parse(
|
||||
'<p>a<br></p>' +
|
||||
'<p>a<br>b<br></p>' +
|
||||
'<p>a<br><br></p><p>a<br><span data-mce-type="bookmark"></span><br></p>' +
|
||||
'<p>a<span data-mce-type="bookmark"></span><br></p>'
|
||||
);
|
||||
equal(serializer.serialize(root), '<p>a</p><p>a<br />b</p><p>a<br /><br /></p><p>a<br /><br /></p><p>a</p>', 'Remove traling br elements.');
|
||||
});
|
||||
|
||||
test('Replace br with nbsp when wrapped in two inline elements and one block', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
parser = new tinymce.html.DomParser({remove_trailing_brs : true}, schema);
|
||||
root = parser.parse('<p><strong><em><br /></em></strong></p>');
|
||||
equal(serializer.serialize(root), '<p><strong><em>\u00a0</em></strong></p>');
|
||||
});
|
||||
|
||||
test('Replace br with nbsp when wrapped in an inline element and placed in the root', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
parser = new tinymce.html.DomParser({remove_trailing_brs : true}, schema);
|
||||
root = parser.parse('<strong><br /></strong>');
|
||||
equal(serializer.serialize(root), '<strong>\u00a0</strong>');
|
||||
});
|
||||
|
||||
test('Don\'t replace br inside root element when there is multiple brs', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
parser = new tinymce.html.DomParser({remove_trailing_brs : true}, schema);
|
||||
root = parser.parse('<strong><br /><br /></strong>');
|
||||
equal(serializer.serialize(root), '<strong><br /><br /></strong>');
|
||||
});
|
||||
|
||||
test('Don\'t replace br inside root element when there is siblings', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
parser = new tinymce.html.DomParser({remove_trailing_brs : true}, schema);
|
||||
root = parser.parse('<strong><br /></strong><em>x</em>');
|
||||
equal(serializer.serialize(root), '<strong><br /></strong><em>x</em>');
|
||||
});
|
||||
|
||||
test('Remove br in invalid parent bug', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema({valid_elements: 'br'});
|
||||
|
||||
expect(1);
|
||||
|
||||
parser = new tinymce.html.DomParser({remove_trailing_brs : true}, schema);
|
||||
root = parser.parse('<br>');
|
||||
equal(serializer.serialize(root), '', 'Remove traling br elements.');
|
||||
});
|
||||
|
||||
test('Forced root blocks', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
expect(1);
|
||||
|
||||
parser = new tinymce.html.DomParser({forced_root_block : 'p'}, schema);
|
||||
root = parser.parse(
|
||||
'<!-- a -->' +
|
||||
'b' +
|
||||
'<b>c</b>' +
|
||||
'<p>d</p>' +
|
||||
'<p>e</p>' +
|
||||
'f' +
|
||||
'<b>g</b>' +
|
||||
'h'
|
||||
);
|
||||
equal(serializer.serialize(root), '<!-- a --><p>b<strong>c</strong></p><p>d</p><p>e</p><p>f<strong>g</strong>h</p>', 'Mixed text nodes, inline elements and blocks.');
|
||||
});
|
||||
|
||||
test('Forced root blocks attrs', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
expect(1);
|
||||
|
||||
parser = new tinymce.html.DomParser({forced_root_block: 'p', forced_root_block_attrs: {"class": "class1"}}, schema);
|
||||
root = parser.parse(
|
||||
'<!-- a -->' +
|
||||
'b' +
|
||||
'<b>c</b>' +
|
||||
'<p>d</p>' +
|
||||
'<p>e</p>' +
|
||||
'f' +
|
||||
'<b>g</b>' +
|
||||
'h'
|
||||
);
|
||||
equal(serializer.serialize(root), '<!-- a -->' +
|
||||
'<p class="class1">b<strong>c</strong></p>' +
|
||||
'<p>d</p>' +
|
||||
'<p>e</p>' +
|
||||
'<p class="class1">f<strong>g</strong>h</p>',
|
||||
'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();
|
||||
|
||||
parser = new tinymce.html.DomParser({allow_html_in_named_anchor : false}, schema);
|
||||
root = parser.parse('<a name="x">a</a><a href="x">x</a>');
|
||||
equal(serializer.serialize(root), '<a name="x"></a>a<a href="x">x</a>');
|
||||
});
|
||||
|
||||
test('Parse contents with html5 anchors and allow_html_in_named_anchor: false', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema({schema: "html5"});
|
||||
|
||||
parser = new tinymce.html.DomParser({allow_html_in_named_anchor : false}, schema);
|
||||
root = parser.parse('<a id="x">a</a><a href="x">x</a>');
|
||||
equal(serializer.serialize(root), '<a id="x"></a>a<a href="x">x</a>');
|
||||
});
|
||||
|
||||
test('Parse contents with html4 anchors and allow_html_in_named_anchor: true', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
parser = new tinymce.html.DomParser({allow_html_in_named_anchor : true}, schema);
|
||||
root = parser.parse('<a name="x">a</a><a href="x">x</a>');
|
||||
equal(serializer.serialize(root), '<a name="x">a</a><a href="x">x</a>');
|
||||
});
|
||||
|
||||
test('Parse contents with html5 anchors and allow_html_in_named_anchor: true', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema({schema: "html5"});
|
||||
|
||||
parser = new tinymce.html.DomParser({allow_html_in_named_anchor : true}, schema);
|
||||
root = parser.parse('<a id="x">a</a><a href="x">x</a>');
|
||||
equal(serializer.serialize(root), '<a id="x">a</a><a href="x">x</a>');
|
||||
});
|
||||
|
||||
test('Parse contents with html5 self closing datalist options', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema({schema: "html5"});
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<datalist><option label="a1" value="b1"><option label="a2" value="b2"><option label="a3" value="b3"></datalist>');
|
||||
equal(serializer.serialize(root), '<datalist><option label="a1" value="b1"></option><option label="a2" value="b2"></option><option label="a3" value="b3"></option></datalist>');
|
||||
});
|
||||
|
||||
test('Parse inline contents before block bug #5424', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema({schema: "html5"});
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<b>1</b> 2<p>3</p>');
|
||||
equal(serializer.serialize(root), '<b>1</b> 2<p>3</p>');
|
||||
});
|
||||
|
||||
test('Invalid text blocks within a li', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema({schema: "html5", valid_children: '-li[p]'});
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<ul><li>1<p>2</p></li><li>a<p>b</p><p>c</p></li></ul>');
|
||||
equal(serializer.serialize(root), '<ul><li>12</li><li>ab</li><li>c</li></ul>');
|
||||
});
|
||||
|
||||
test('Invalid inline element with space before', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p><span>1</span> <strong>2</strong></p>');
|
||||
equal(serializer.serialize(root), '<p>1 <strong>2</strong></p>');
|
||||
});
|
||||
|
||||
test('Valid classes', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema({valid_classes: 'classA classB'});
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p class="classA classB classC">a</p>');
|
||||
equal(serializer.serialize(root), '<p class="classA classB">a</p>');
|
||||
});
|
||||
|
||||
test('Valid classes multiple elements', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema({valid_classes: {'*': 'classA classB', 'strong': 'classC'}});
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<p class="classA classB classC"><strong class="classA classB classC classD">a</strong></p>');
|
||||
equal(serializer.serialize(root), '<p class="classA classB"><strong class="classA classB classC">a</strong></p>');
|
||||
});
|
||||
|
||||
test('Remove empty list blocks', function() {
|
||||
var parser, root, schema = new tinymce.html.Schema();
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('<ul><li></li></ul><ul><li> </li></ul>');
|
||||
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();
|
||||
|
||||
parser = new tinymce.html.DomParser({}, schema);
|
||||
root = parser.parse('a<span> </span>b');
|
||||
equal(serializer.serialize(root), 'a b');
|
||||
});
|
||||
|
||||
test('Bug #7543 removes whitespace between bogus elements before a block', function() {
|
||||
var serializer = new tinymce.html.Serializer();
|
||||
|
||||
equal(
|
||||
serializer.serialize(new tinymce.html.DomParser().parse(
|
||||
'<div><b data-mce-bogus="1">a</b> <b data-mce-bogus="1">b</b><p>c</p></div>')
|
||||
),
|
||||
'<div>a b<p>c</p></div>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Bug #7582 removes whitespace between bogus elements before a block', function() {
|
||||
var serializer = new tinymce.html.Serializer();
|
||||
|
||||
equal(
|
||||
serializer.serialize(new tinymce.html.DomParser().parse(
|
||||
'<div>1 <span data-mce-bogus="1">2</span><div>3</div></div>')
|
||||
),
|
||||
'<div>1 2<div>3</div></div>'
|
||||
);
|
||||
});
|
||||
})();
|
||||
@ -1,75 +0,0 @@
|
||||
module("tinymce.html.Entities");
|
||||
|
||||
test('encodeRaw', function() {
|
||||
expect(2);
|
||||
|
||||
equal(tinymce.html.Entities.encodeRaw('<>"\'&\u00e5\u00e4\u00f6\u0060'), '<>"\'&\u00e5\u00e4\u00f6\u0060', 'Raw encoding text');
|
||||
equal(tinymce.html.Entities.encodeRaw('<>"\'&\u00e5\u00e4\u00f6\u0060', true), '<>"\'&\u00e5\u00e4\u00f6`', 'Raw encoding attribute');
|
||||
});
|
||||
|
||||
test('encodeAllRaw', function() {
|
||||
expect(1);
|
||||
|
||||
equal(tinymce.html.Entities.encodeAllRaw('<>"\'&\u00e5\u00e4\u00f6'), '<>"'&\u00e5\u00e4\u00f6', 'Raw encoding all');
|
||||
});
|
||||
|
||||
test('encodeNumeric', function() {
|
||||
expect(2);
|
||||
|
||||
equal(tinymce.html.Entities.encodeNumeric('<>"\'&\u00e5\u00e4\u00f6\u03b8\u2170\ufa11'), '<>"\'&åäöθⅰ﨑', 'Numeric encoding text');
|
||||
equal(tinymce.html.Entities.encodeNumeric('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Numeric encoding attribute');
|
||||
});
|
||||
|
||||
test('encodeNamed', function() {
|
||||
expect(4);
|
||||
|
||||
equal(tinymce.html.Entities.encodeNamed('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&åäö', 'Named encoding text');
|
||||
equal(tinymce.html.Entities.encodeNamed('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Named encoding attribute');
|
||||
equal(tinymce.html.Entities.encodeNamed('<>"\'\u00e5\u00e4\u00f6', false, {'\u00e5' : 'å'}), '<>"\'å\u00e4\u00f6', 'Named encoding text');
|
||||
equal(tinymce.html.Entities.encodeNamed('<>"\'\u00e5\u00e4\u00f6', true, {'\u00e5' : 'å'}), '<>"\'å\u00e4\u00f6', 'Named encoding attribute');
|
||||
});
|
||||
|
||||
test('getEncodeFunc', function() {
|
||||
var encodeFunc;
|
||||
|
||||
expect(10);
|
||||
|
||||
encodeFunc = tinymce.html.Entities.getEncodeFunc('raw');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&\u00e5\u00e4\u00f6', 'Raw encoding text');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&\u00e5\u00e4\u00f6', 'Raw encoding attribute');
|
||||
|
||||
encodeFunc = tinymce.html.Entities.getEncodeFunc('named');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&åäö', 'Named encoding text');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Named encoding attribute');
|
||||
|
||||
encodeFunc = tinymce.html.Entities.getEncodeFunc('numeric');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&åäö', 'Named encoding text');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Named encoding attribute');
|
||||
|
||||
encodeFunc = tinymce.html.Entities.getEncodeFunc('named+numeric', '229,aring');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&åäö', 'Named+numeric encoding text');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Named+numeric encoding attribute');
|
||||
|
||||
encodeFunc = tinymce.html.Entities.getEncodeFunc('named,numeric', '229,aring');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&åäö', 'Named+numeric encoding text');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Named+numeric encoding attribute');
|
||||
});
|
||||
|
||||
test('decode', function() {
|
||||
equal(tinymce.html.Entities.decode('<>"'&åäö&unknown;'), '<>"\'&\u00e5\u00e4\u00f6&unknown;', 'Decode text with various entities');
|
||||
equal(tinymce.html.Entities.decode('AB''), 'AB\'', 'Decode numeric entities');
|
||||
equal(tinymce.html.Entities.decode('OO''), 'OO\'', 'Decode hexanumeric entities');
|
||||
equal(tinymce.html.Entities.decode('ABC'), 'ABC', 'Decode numeric entities with no semicolon');
|
||||
equal(tinymce.html.Entities.decode('&test'), '&test', 'Dont decode invalid entity name without semicolon');
|
||||
|
||||
equal(tinymce.html.Entities.encodeNumeric(tinymce.html.Entities.decode(
|
||||
'‚ƒ„…†‡ˆ‰Š' +
|
||||
'‹ŒŽ‘’“”•–—˜' +
|
||||
'™š›œžŸ')
|
||||
), '‚ƒ„…†‡ˆ‰Š‹ŒŽ' +
|
||||
'‘’“”•–—˜™š' +
|
||||
'›œžŸ',
|
||||
'Entity decode ascii');
|
||||
|
||||
equal(tinymce.html.Entities.encodeNumeric(tinymce.html.Entities.decode('你')), '你', "High byte non western character.");
|
||||
});
|
||||
@ -1,442 +0,0 @@
|
||||
module("tinymce.html.Node");
|
||||
|
||||
test('construction', function() {
|
||||
var node;
|
||||
|
||||
expect(15);
|
||||
|
||||
node = new tinymce.html.Node('#text', 3);
|
||||
equal(node.name, '#text');
|
||||
equal(node.type, 3);
|
||||
|
||||
node = new tinymce.html.Node('#comment', 8);
|
||||
equal(node.name, '#comment');
|
||||
equal(node.type, 8);
|
||||
|
||||
node = new tinymce.html.Node('b', 1);
|
||||
equal(node.name, 'b');
|
||||
equal(node.type, 1);
|
||||
deepEqual(node.attributes, []);
|
||||
|
||||
node = new tinymce.html.Node('#pi', 7);
|
||||
equal(node.name, '#pi');
|
||||
equal(node.type, 7);
|
||||
|
||||
node = new tinymce.html.Node('#doctype', 10);
|
||||
equal(node.name, '#doctype');
|
||||
equal(node.type, 10);
|
||||
|
||||
node = new tinymce.html.Node('#cdata', 4);
|
||||
equal(node.name, '#cdata');
|
||||
equal(node.type, 4);
|
||||
|
||||
node = new tinymce.html.Node('#frag', 11);
|
||||
equal(node.name, '#frag');
|
||||
equal(node.type, 11);
|
||||
});
|
||||
|
||||
test('append inside empty node', function() {
|
||||
var root, node;
|
||||
|
||||
expect(10);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node = root.append(new tinymce.html.Node('b', 1));
|
||||
ok(root.firstChild.parent === root);
|
||||
equal(root.firstChild.next, undefined);
|
||||
equal(root.firstChild.prev, undefined);
|
||||
equal(root.firstChild.firstChild, undefined);
|
||||
equal(root.firstChild.lastChild, undefined);
|
||||
ok(node.parent === root);
|
||||
equal(node.next, undefined);
|
||||
equal(node.prev, undefined);
|
||||
equal(node.firstChild, undefined);
|
||||
equal(node.lastChild, undefined);
|
||||
});
|
||||
|
||||
test('append node after node', function() {
|
||||
var root, node, node2;
|
||||
|
||||
expect(17);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node2 = root.append(new tinymce.html.Node('a', 1));
|
||||
node = root.append(new tinymce.html.Node('b', 1));
|
||||
ok(root.firstChild.parent === root, 'root.firstChild.parent === root');
|
||||
ok(root.firstChild === node2, 'root.firstChild');
|
||||
ok(root.lastChild === node, 'root.firstChild');
|
||||
ok(root.firstChild.next === node, 'root.firstChild.next');
|
||||
equal(root.firstChild.prev, undefined, 'root.firstChild.prev');
|
||||
equal(root.firstChild.firstChild, undefined, 'root.firstChild.firstChild');
|
||||
equal(root.firstChild.lastChild, undefined, 'root.firstChild.lastChild');
|
||||
ok(node2.parent === root, 'node2.parent === root');
|
||||
ok(node2.next === node, 'node2.next');
|
||||
equal(node2.prev, undefined, 'node2.prev');
|
||||
equal(node2.firstChild, undefined, 'node2.firstChild');
|
||||
equal(node2.lastChild, undefined, 'node2.lastChild');
|
||||
ok(node.parent === root, 'node.parent === root');
|
||||
equal(node.next, undefined, 'node.next');
|
||||
ok(node.prev === node2, 'node.prev');
|
||||
equal(node.firstChild, undefined, 'node.firstChild');
|
||||
equal(node.lastChild, undefined, 'node.lastChild');
|
||||
});
|
||||
|
||||
test('append existing node before other existing node', function() {
|
||||
var root, node, node2;
|
||||
|
||||
expect(8);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node = root.append(new tinymce.html.Node('a', 1));
|
||||
node2 = root.append(new tinymce.html.Node('b', 1));
|
||||
root.append(node);
|
||||
ok(root.firstChild === node2, 'root.firstChild');
|
||||
ok(root.lastChild === node, 'root.lastChild');
|
||||
equal(node.next, undefined, 'node.next');
|
||||
ok(node.prev === node2, 'node.prev');
|
||||
ok(node.parent === root, 'node.parent');
|
||||
ok(node2.parent === root, 'node2.parent');
|
||||
equal(node2.prev, undefined, 'node2.prev');
|
||||
ok(node2.next === node, 'node2.next');
|
||||
});
|
||||
|
||||
test('remove unattached node', function() {
|
||||
expect(1);
|
||||
|
||||
ok(!new tinymce.html.Node('#text', 3).remove().parent);
|
||||
});
|
||||
|
||||
test('remove single child', function() {
|
||||
var root, node;
|
||||
|
||||
expect(6);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node = root.append(new tinymce.html.Node('p', 1));
|
||||
node = root.firstChild.remove();
|
||||
equal(root.firstChild, undefined);
|
||||
equal(root.lastChild, undefined);
|
||||
equal(node.parent, undefined);
|
||||
equal(node.next, undefined);
|
||||
equal(node.prev, undefined);
|
||||
equal(node.name, 'p');
|
||||
});
|
||||
|
||||
test('remove middle node', function() {
|
||||
var root, node, node2, node3;
|
||||
|
||||
expect(9);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node = root.append(new tinymce.html.Node('a', 1));
|
||||
node2 = root.append(new tinymce.html.Node('b', 1));
|
||||
node3 = root.append(new tinymce.html.Node('c', 1));
|
||||
node2.remove();
|
||||
equal(node2.parent, undefined);
|
||||
equal(node2.next, undefined);
|
||||
equal(node2.prev, undefined);
|
||||
ok(root.firstChild === node, 'root.firstChild');
|
||||
ok(root.lastChild === node3, 'root.lastChild');
|
||||
ok(node.next === node3, 'node.next');
|
||||
equal(node.prev, undefined, 'node.prev');
|
||||
equal(node3.prev, node, 'node3.prev');
|
||||
equal(node3.next, undefined, 'node3.next');
|
||||
});
|
||||
|
||||
test('insert after last', function() {
|
||||
var fragment, root, node, node2;
|
||||
|
||||
expect(5);
|
||||
|
||||
fragment = new tinymce.html.Node('#frag', 11);
|
||||
root = fragment.append(new tinymce.html.Node('body', 1));
|
||||
node = root.append(new tinymce.html.Node('a', 1));
|
||||
node2 = root.insert(new tinymce.html.Node('x', 1), node);
|
||||
ok(root.firstChild === node, 'root.firstChild');
|
||||
ok(root.lastChild === node2, 'root.lastChild');
|
||||
ok(node.next === node2, 'node.next');
|
||||
ok(node2.prev === node, 'node2.prev');
|
||||
ok(node2.parent === root, 'node3.next');
|
||||
});
|
||||
|
||||
test('insert before first', function() {
|
||||
var fragment, root, node, node2;
|
||||
|
||||
expect(8);
|
||||
|
||||
fragment = new tinymce.html.Node('#frag', 11);
|
||||
root = fragment.append(new tinymce.html.Node('body', 1));
|
||||
node = root.append(new tinymce.html.Node('a', 1));
|
||||
node2 = root.insert(new tinymce.html.Node('x', 1), node, true);
|
||||
ok(root.firstChild === node2, 'root.firstChild');
|
||||
ok(root.lastChild === node, 'root.lastChild');
|
||||
ok(node2.parent === root, 'node2.lastChild');
|
||||
ok(node2.next === node, 'node2.next');
|
||||
ok(node2.prev === undefined, 'node2.prev');
|
||||
ok(node.parent === root, 'node.lastChild');
|
||||
ok(node.next === undefined, 'node.next');
|
||||
ok(node.prev === node2, 'node.prev');
|
||||
});
|
||||
|
||||
test('insert before second', function() {
|
||||
var fragment, root, node, node2, node3;
|
||||
|
||||
expect(5);
|
||||
|
||||
fragment = new tinymce.html.Node('#frag', 11);
|
||||
root = fragment.append(new tinymce.html.Node('body', 1));
|
||||
node = root.append(new tinymce.html.Node('a', 1));
|
||||
node2 = root.append(new tinymce.html.Node('b', 1));
|
||||
node3 = root.insert(new tinymce.html.Node('x', 1), node2, true);
|
||||
ok(root.firstChild === node, 'root.firstChild');
|
||||
ok(root.lastChild === node2, 'root.lastChild');
|
||||
ok(node3.parent === root, 'node3.parent');
|
||||
ok(node3.next === node2, 'node3.next');
|
||||
ok(node3.prev === node, 'node3.prev');
|
||||
});
|
||||
|
||||
test('insert after and between two nodes', function() {
|
||||
var root, node, node2, node3, fragment;
|
||||
|
||||
expect(7);
|
||||
|
||||
fragment = new tinymce.html.Node('#frag', 11);
|
||||
root = fragment.append(new tinymce.html.Node('body', 1));
|
||||
node = root.append(new tinymce.html.Node('a', 1));
|
||||
node2 = root.append(new tinymce.html.Node('b', 1));
|
||||
node3 = root.insert(new tinymce.html.Node('x', 1), node);
|
||||
ok(root.firstChild === node, 'root.firstChild');
|
||||
ok(root.lastChild === node2, 'root.lastChild');
|
||||
ok(node.next === node3, 'node.next');
|
||||
ok(node2.prev === node3, 'node2.prev');
|
||||
ok(node3.parent === root, 'node3.next');
|
||||
ok(node3.next === node2, 'node3.next');
|
||||
ok(node3.prev === node, 'node3.prev');
|
||||
});
|
||||
|
||||
test('replace single child', function() {
|
||||
var root, node1, node2;
|
||||
|
||||
expect(5);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('b', 1));
|
||||
node2 = root.append(new tinymce.html.Node('em', 1));
|
||||
node1.replace(node2);
|
||||
ok(root.firstChild === node2, 'root.firstChild');
|
||||
ok(root.lastChild === node2, 'root.lastChild');
|
||||
ok(node2.parent === root, 'node2.parent');
|
||||
ok(!node2.next, 'node2.next');
|
||||
ok(!node2.prev, 'node2.prev');
|
||||
});
|
||||
|
||||
test('replace first child', function() {
|
||||
var root, node1, node2, node3;
|
||||
|
||||
expect(5);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('b', 1));
|
||||
node2 = root.append(new tinymce.html.Node('em', 1));
|
||||
node3 = root.append(new tinymce.html.Node('b', 1));
|
||||
node1.replace(node2);
|
||||
ok(root.firstChild === node2, 'root.firstChild');
|
||||
ok(root.lastChild === node3, 'root.lastChild');
|
||||
ok(node2.parent === root, 'node2.parent');
|
||||
ok(node2.next === node3, 'node2.next');
|
||||
ok(!node2.prev, 'node2.prev');
|
||||
});
|
||||
|
||||
test('replace last child', function() {
|
||||
var root, node1, node2, node3;
|
||||
|
||||
expect(5);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('b', 1));
|
||||
node3 = root.append(new tinymce.html.Node('b', 1));
|
||||
node2 = root.append(new tinymce.html.Node('em', 1));
|
||||
node3.replace(node2);
|
||||
ok(root.firstChild === node1, 'root.firstChild');
|
||||
ok(root.lastChild === node2, 'root.lastChild');
|
||||
ok(node2.parent === root, 'node2.parent');
|
||||
ok(!node2.next, 'node2.next');
|
||||
ok(node2.prev === node1, 'node2.prev');
|
||||
});
|
||||
|
||||
test('replace middle child', function() {
|
||||
var root, node1, node2, node3, node4;
|
||||
|
||||
expect(5);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('b', 1));
|
||||
node2 = root.append(new tinymce.html.Node('b', 1));
|
||||
node3 = root.append(new tinymce.html.Node('b', 1));
|
||||
node4 = root.append(new tinymce.html.Node('em', 1));
|
||||
node2.replace(node4);
|
||||
ok(root.firstChild === node1, 'root.firstChild');
|
||||
ok(root.lastChild === node3, 'root.lastChild');
|
||||
ok(node4.parent === root, 'node4.parent');
|
||||
ok(node4.next === node3, 'node4.next');
|
||||
ok(node4.prev === node1, 'node4.prev');
|
||||
});
|
||||
|
||||
test('attr', 22, function() {
|
||||
var node;
|
||||
|
||||
node = new tinymce.html.Node('b', 1);
|
||||
deepEqual(node.attributes, []);
|
||||
node.attr('attr1', 'value1');
|
||||
equal(node.attr('attr1'), 'value1');
|
||||
equal(node.attr('attr2'), undefined);
|
||||
deepEqual(node.attributes, [{name: 'attr1', value: 'value1'}]);
|
||||
deepEqual(node.attributes.map, {'attr1': 'value1'});
|
||||
|
||||
node = new tinymce.html.Node('b', 1);
|
||||
deepEqual(node.attributes, []);
|
||||
node.attr('attr1', 'value1');
|
||||
node.attr('attr1', 'valueX');
|
||||
equal(node.attr('attr1'), 'valueX');
|
||||
deepEqual(node.attributes, [{name: 'attr1', value: 'valueX'}]);
|
||||
deepEqual(node.attributes.map, {'attr1': 'valueX'});
|
||||
|
||||
node = new tinymce.html.Node('b', 1);
|
||||
deepEqual(node.attributes, []);
|
||||
node.attr('attr1', 'value1');
|
||||
node.attr('attr2', 'value2');
|
||||
equal(node.attr('attr1'), 'value1');
|
||||
equal(node.attr('attr2'), 'value2');
|
||||
deepEqual(node.attributes, [{name: 'attr1', value: 'value1'}, {name: 'attr2', value: 'value2'}]);
|
||||
deepEqual(node.attributes.map, {'attr1': 'value1', 'attr2': 'value2'});
|
||||
|
||||
node = new tinymce.html.Node('b', 1);
|
||||
deepEqual(node.attributes, []);
|
||||
node.attr('attr1', 'value1');
|
||||
node.attr('attr1', null);
|
||||
equal(node.attr('attr1'), undefined);
|
||||
deepEqual(node.attributes, []);
|
||||
deepEqual(node.attributes.map, {});
|
||||
|
||||
node = new tinymce.html.Node('b', 1);
|
||||
node.attr({a:'1', b:'2'});
|
||||
deepEqual(node.attributes, [{name: 'a', value: '1'}, {name: 'b', value: '2'}]);
|
||||
deepEqual(node.attributes.map, {a:'1', b:'2'});
|
||||
|
||||
node = new tinymce.html.Node('b', 1);
|
||||
node.attr(null);
|
||||
deepEqual(node.attributes, []);
|
||||
deepEqual(node.attributes.map, {});
|
||||
});
|
||||
|
||||
test('clone', function() {
|
||||
var root, node, clone;
|
||||
|
||||
expect(16);
|
||||
|
||||
node = new tinymce.html.Node('#text', 3);
|
||||
node.value = 'value';
|
||||
clone = node.clone();
|
||||
equal(clone.name, '#text');
|
||||
equal(clone.type, 3);
|
||||
equal(clone.value, 'value');
|
||||
equal(clone.parent, undefined);
|
||||
equal(clone.next, undefined);
|
||||
equal(clone.prev, undefined);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node = new tinymce.html.Node('#text', 3);
|
||||
node.value = 'value';
|
||||
root.append(node);
|
||||
equal(clone.name, '#text');
|
||||
equal(clone.type, 3);
|
||||
equal(clone.value, 'value');
|
||||
equal(clone.parent, undefined);
|
||||
equal(clone.next, undefined);
|
||||
equal(clone.prev, undefined);
|
||||
|
||||
node = new tinymce.html.Node('b', 1);
|
||||
node.attr('id', 'id');
|
||||
node.attr('class', 'class');
|
||||
node.attr('title', 'title');
|
||||
clone = node.clone();
|
||||
equal(clone.name, 'b');
|
||||
equal(clone.type, 1);
|
||||
deepEqual(clone.attributes, [{name: 'class', value: 'class'}, {name: 'title', value: 'title'}]);
|
||||
deepEqual(clone.attributes.map, {'class': 'class', 'title': 'title'});
|
||||
});
|
||||
|
||||
test('unwrap', function() {
|
||||
var root, node1, node2, node3;
|
||||
|
||||
expect(7);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('b', 1));
|
||||
node2 = node1.append(new tinymce.html.Node('em', 1));
|
||||
node1.unwrap();
|
||||
ok(root.firstChild === node2, 'root.firstChild');
|
||||
ok(root.lastChild === node2, 'root.lastChild');
|
||||
ok(node2.parent === root, 'node2.parent');
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('b', 1));
|
||||
node2 = node1.append(new tinymce.html.Node('em', 1));
|
||||
node3 = node1.append(new tinymce.html.Node('span', 1));
|
||||
node1.unwrap();
|
||||
ok(root.firstChild === node2, 'root.firstChild');
|
||||
ok(root.lastChild === node3, 'root.lastChild');
|
||||
ok(node2.parent === root, 'node2.parent');
|
||||
ok(node3.parent === root, 'node3.parent');
|
||||
});
|
||||
|
||||
test('empty', function() {
|
||||
var root, node1, node2;
|
||||
|
||||
expect(4);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('b', 1));
|
||||
node2 = node1.append(new tinymce.html.Node('em', 1));
|
||||
node1.empty();
|
||||
ok(root.firstChild === node1, 'root.firstChild');
|
||||
ok(root.lastChild === node1, 'root.firstChild');
|
||||
ok(!node1.firstChild, 'node1.firstChild');
|
||||
ok(!node1.lastChild, 'node1.firstChild');
|
||||
});
|
||||
|
||||
test('isEmpty', function() {
|
||||
var root, node1, node2;
|
||||
|
||||
expect(9);
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('p', 1));
|
||||
node2 = node1.append(new tinymce.html.Node('b', 1));
|
||||
ok(root.isEmpty({img: 1}), 'Is empty 1');
|
||||
ok(node1.isEmpty({img: 1}), 'Is empty 2');
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('p', 1));
|
||||
node2 = node1.append(new tinymce.html.Node('img', 1));
|
||||
ok(!root.isEmpty({img: 1}), 'Is not empty 1');
|
||||
ok(!node1.isEmpty({img: 1}), 'Is not empty 2');
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('p', 1));
|
||||
node2 = node1.append(new tinymce.html.Node('#text', 3));
|
||||
node2.value = 'X';
|
||||
ok(!root.isEmpty({img: 1}), 'Is not empty 3');
|
||||
ok(!node1.isEmpty({img: 1}), 'Is not empty 4');
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('p', 1));
|
||||
node2 = node1.append(new tinymce.html.Node('#text', 3));
|
||||
node2.value = '';
|
||||
ok(root.isEmpty({img: 1}), 'Is empty 4');
|
||||
ok(node1.isEmpty({img: 1}), 'Is empty 5');
|
||||
|
||||
root = new tinymce.html.Node('#frag', 11);
|
||||
node1 = root.append(new tinymce.html.Node('a', 1)).attr('name', 'x');
|
||||
ok(!root.isEmpty({img: 1}), 'Contains anchor with name attribute.');
|
||||
});
|
||||
@ -1,262 +0,0 @@
|
||||
module( 'tinymce.html.Obsolete', {
|
||||
setupModule: function() {
|
||||
QUnit.stop();
|
||||
|
||||
tinymce.init({
|
||||
selector: 'textarea',
|
||||
add_unload_trigger : false,
|
||||
skin: false,
|
||||
indent : false,
|
||||
entities : 'raw',
|
||||
plugins: 'media',
|
||||
convert_urls : false,
|
||||
init_instance_callback : function(ed) {
|
||||
window.editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Test whether attribute exists in a HTML string
|
||||
*
|
||||
* @param html The HTML string
|
||||
* @param attr string|object When string, test for the first instance of attr.
|
||||
* When object, break up the HTML string into individual tags and test for attr in the specified tag.
|
||||
* Format: { tagName: 'attr1 attr2', ... }
|
||||
* @return bool
|
||||
*/
|
||||
function hasAttr( html, attr ) {
|
||||
var tagName, tags, tag, array, regex, i;
|
||||
|
||||
if ( typeof attr === 'string' ) {
|
||||
return new RegExp( ' \\b' + attr + '\\b' ).test( html );
|
||||
}
|
||||
|
||||
for ( tagName in attr ) {
|
||||
if ( tags = html.match( new RegExp( '<' + tagName + ' [^>]+>', 'g' ) ) ) {
|
||||
for ( tag in tags ) {
|
||||
array = attr[tagName].split(' ');
|
||||
|
||||
for ( i in array ) {
|
||||
regex = new RegExp( '\\b' + array[i] + '\\b' );
|
||||
|
||||
if ( regex.test( tags[tag] ) ) {
|
||||
attr[tagName] = attr[tagName].replace( regex, '' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( attr[tagName].replace( / +/g, '' ).length ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ref: http://www.w3.org/TR/html5/obsolete.html, http://developers.whatwg.org/obsolete.html
|
||||
|
||||
test('HTML elements non-conforming to HTML 5.0', function() {
|
||||
var testString;
|
||||
|
||||
/*
|
||||
Not supported, deprecated in HTML 4.0 or earlier, and/or proprietary:
|
||||
applet
|
||||
bgsound
|
||||
dir
|
||||
frame
|
||||
frameset
|
||||
noframes
|
||||
isindex
|
||||
listing
|
||||
nextid
|
||||
noembed
|
||||
plaintext
|
||||
rb
|
||||
xmp
|
||||
basefont
|
||||
blink
|
||||
marquee
|
||||
multicol
|
||||
nobr
|
||||
spacer
|
||||
|
||||
The rest are still supported in TinyMCE but "...must not be used by authors".
|
||||
*/
|
||||
|
||||
expect(6);
|
||||
|
||||
text = 'acronym';
|
||||
testString = '<p><acronym title="www">WWW</acronym></p>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'strike, converted to span';
|
||||
editor.setContent( '<strike>test</strike>' );
|
||||
equal( editor.getContent(), '<p><span style="text-decoration: line-through;">test</span></p>', text );
|
||||
|
||||
text = 'big';
|
||||
testString = '<p><big>test</big></p>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'center';
|
||||
testString = '<center>test</center>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'font, converted to span';
|
||||
editor.setContent( '<p><font size="4">test</font></p>' );
|
||||
equal( editor.getContent(), '<p><span style="font-size: large;">test</span></p>', text );
|
||||
|
||||
text = 'tt';
|
||||
testString = '<p><tt>test</tt></p>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
});
|
||||
|
||||
test('Obsolete (but still conforming) HTML attributes', function() {
|
||||
var testString;
|
||||
|
||||
expect(3);
|
||||
|
||||
text = 'border on <img>';
|
||||
testString = '<p><img src="../../test.gif" alt="" border="5" /></p>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'Old style anchors';
|
||||
testString = '<p><a name="test"></a></p>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'maxlength, size on input type="number"';
|
||||
testString = '<p><input maxlength="5" size="10" type="number" value="" /></p>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { input: 'maxlength size' } ), text );
|
||||
});
|
||||
|
||||
test('Obsolete attributes in HTML 5.0', function() {
|
||||
var testString, text;
|
||||
|
||||
expect(22);
|
||||
|
||||
text = 'charset, rev, shape, coords on <a> elements';
|
||||
testString = '<p><a href="javascript;:" charset="en" rev="made" shape="rect" coords="5,5">test</a></p>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { a: 'charset rev shape coords' } ), text );
|
||||
|
||||
text = 'name, align, hspace, vspace on img elements';
|
||||
testString = '<p><img src="../../test.gif" alt="" name="test" align="left" hspace="5" vspace="5" /></p>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { img: 'name align hspace vspace' } ), text );
|
||||
|
||||
text = 'name, align, hspace, vspace, on embed elements';
|
||||
testString = '<p><embed width="100" height="100" src="test.swf" vspace="5" hspace="5" align="left" name="test"></embed></p>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { embed: 'name align hspace vspace' } ), text );
|
||||
|
||||
text = 'archive, classid, code, codebase, codetype, declare, standby on object elements';
|
||||
testString = '<p><object width="100" height="100" classid="clsid" codebase="clsid" standby="standby" codetype="1" code="1" archive="1" declare="declare"></object></p>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { object: 'archive classid code codebase codetype declare standby' } ), text );
|
||||
|
||||
text = 'type, valuetype on param elements';
|
||||
testString = '<p><object width="100" height="100"><param type="" valuetype="" /></object></p>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { param: 'type valuetype' } ), text );
|
||||
|
||||
text = 'align, bgcolor, border, cellpadding, cellspacing, frame, rules, summary, width on table elements';
|
||||
testString = '<table border="1" summary="" width="100" frame="" rules="" cellspacing="5" cellpadding="5" align="left" bgcolor="blue"><tbody><tr><td>test</td></tr></tbody></table>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { table: 'align bgcolor border cellpadding cellspacing frame rules summary width' } ), text );
|
||||
|
||||
text = 'align, char, charoff, valign on tbody, thead, and tfoot elements';
|
||||
testString = '<table><thead align="left" char="" charoff="" valign="top"></thead><tfoot align="left" char="" charoff="" valign="top"></tfoot><tbody align="left" char="" charoff="" valign="top"><tr><th>test</th><td>test</td></tr></tbody></table>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), {
|
||||
thead: 'align char charoff valign',
|
||||
tfoot: 'align char charoff valign',
|
||||
tbody: 'align char charoff valign'
|
||||
} ), text );
|
||||
|
||||
text = 'axis, align, bgcolor, char, charoff, height, nowrap, valign, width on td and th elements, scope on td elements';
|
||||
testString = '<table><tbody><tr><th axis="" align="left" char="" charoff="" valign="top" nowrap="nowrap" bgcolor="blue" width="100" height="10">test</th><td axis="" align="left" char="" charoff="" valign="top" nowrap="nowrap" bgcolor="blue" width="100" height="10" scope="">test</td></tr></tbody></table>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), {
|
||||
th: 'axis align bgcolor char charoff height nowrap valign width',
|
||||
td: 'axis align bgcolor char charoff height nowrap valign width scope'
|
||||
} ), text );
|
||||
|
||||
text = 'align, bgcolor, char, charoff, valign on tr elements';
|
||||
testString = '<table><tbody><tr align="left" char="" charoff="" valign="top" bgcolor="blue"><td>test</td></tr></tbody></table>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { tr: 'align bgcolor char charoff valign' } ), text );
|
||||
|
||||
text = 'clear on br elements';
|
||||
testString = '<p>test<br clear="all" />test</p>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'align on caption elements';
|
||||
testString = '<table><caption align="left">test</caption><tbody><tr><td>test</td></tr></tbody></table>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'align, char, charoff, valign, width on col elements';
|
||||
testString = '<table><colgroup><col width="100" align="left" char="a" charoff="1" valign="top" /><col /></colgroup><tbody><tr><td>test</td><td>test</td></tr></tbody></table>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { col: 'align char charoff valign width' } ), text );
|
||||
|
||||
text = 'align on div, h1—h6, input, legend, p elements';
|
||||
testString = '<div align="left">1</div><h3 align="left">1</h3><p align="left">1</p><form><fieldset><legend align="left">test</legend><input type="text" align="left" /></fieldset></form>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'compact on dl elements';
|
||||
testString = '<dl compact="compact"><dd>1</dd></dl>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'align, hspace, vspace on embed elements';
|
||||
testString = '<p><embed width="100" height="100" vspace="5" hspace="5" align="left"></embed></p>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { embed: 'align hspace vspace' } ), text );
|
||||
|
||||
text = 'align, noshade, size, width on hr elements';
|
||||
testString = '<hr align="left" noshade="noshade" size="1" width="100" />';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { hr: 'align noshade size width' } ), text );
|
||||
|
||||
text = 'align, frameborder, marginheight, marginwidth, scrolling on iframe elements';
|
||||
testString = '<p><iframe width="100" height="100" frameborder="1" marginwidth="5" marginheight="5" scrolling="" align="left"></iframe></p>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { iframe: 'align frameborder marginheight marginwidth scrolling' } ), text );
|
||||
|
||||
text = 'type on li elements';
|
||||
testString = '<ul><li type="disc">test</li></ul>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'align, border, hspace, vspace on object elements';
|
||||
testString = '<p><object width="100" height="100" border="1" vspace="5" hspace="5" align="left"></object></p>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { object: 'align border hspace vspace' } ), text );
|
||||
|
||||
text = 'compact on ol elements';
|
||||
testString = '<ol compact="compact"><li>test</li></ol>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
|
||||
text = 'compact, type on ul elements';
|
||||
testString = '<ul type="disc" compact="compact"><li>test</li></ul>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( editor.getContent(), { ul: 'compact type' } ), text );
|
||||
|
||||
text = 'width on pre elements';
|
||||
testString = '<pre width="100">1</pre>';
|
||||
editor.setContent( testString );
|
||||
equal( editor.getContent(), testString, text );
|
||||
});
|
||||
@ -1,742 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.html.SaxParser");
|
||||
|
||||
var writer = new tinymce.html.Writer(), schema = new tinymce.html.Schema();
|
||||
|
||||
function createCounter(writer) {
|
||||
var counts = {};
|
||||
|
||||
return {
|
||||
counts : counts,
|
||||
|
||||
comment: function(text) {
|
||||
if ("comment" in counts) {
|
||||
counts.comment++;
|
||||
} else {
|
||||
counts.comment = 1;
|
||||
}
|
||||
|
||||
writer.comment(text);
|
||||
},
|
||||
|
||||
cdata: function(text) {
|
||||
if ("cdata" in counts) {
|
||||
counts.cdata++;
|
||||
} else {
|
||||
counts.cdata = 1;
|
||||
}
|
||||
|
||||
writer.cdata(text);
|
||||
},
|
||||
|
||||
text: function(text, raw) {
|
||||
if ("text" in counts) {
|
||||
counts.text++;
|
||||
} else {
|
||||
counts.text = 1;
|
||||
}
|
||||
|
||||
writer.text(text, raw);
|
||||
},
|
||||
|
||||
start: function(name, attrs, empty) {
|
||||
if ("start" in counts) {
|
||||
counts.start++;
|
||||
} else {
|
||||
counts.start = 1;
|
||||
}
|
||||
|
||||
writer.start(name, attrs, empty);
|
||||
},
|
||||
|
||||
end: function(name) {
|
||||
if ("end" in counts) {
|
||||
counts.end++;
|
||||
} else {
|
||||
counts.end = 1;
|
||||
}
|
||||
|
||||
writer.end(name);
|
||||
},
|
||||
|
||||
pi: function(name, text) {
|
||||
if ("pi" in counts) {
|
||||
counts.pi++;
|
||||
} else {
|
||||
counts.pi = 1;
|
||||
}
|
||||
|
||||
writer.pi(name, text);
|
||||
},
|
||||
|
||||
doctype: function(text) {
|
||||
if ("doctype:" in counts) {
|
||||
counts.doctype++;
|
||||
} else {
|
||||
counts.doctype = 1;
|
||||
}
|
||||
|
||||
writer.doctype(text);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test('Parse elements', function() {
|
||||
var counter, parser;
|
||||
|
||||
expect(48);
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<span id=id1 title="title value" class=\'class1 class2\' data-value="value1" MYATTR="val1" myns:myattr="val2" disabled empty=""></span>');
|
||||
equal(writer.getContent(), '<span id="id1" title="title value" class="class1 class2" data-value="value1" myattr="val1" myns:myattr="val2" disabled="disabled" empty=""></span>', 'Parse attribute formats.');
|
||||
deepEqual(counter.counts, {start:1, end:1}, 'Parse attribute formats counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<b href=\'"&<>\'></b>');
|
||||
equal(writer.getContent(), '<b href=""&<>"></b>', 'Parse attributes with <> in them.');
|
||||
deepEqual(counter.counts, {start:1, end:1}, 'Parse attributes with <> in them (count).');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<span title=" "class=" "></span>');
|
||||
equal(writer.getContent(), '<span title=" " class=" "></span>', 'Parse compressed attributes.');
|
||||
deepEqual(counter.counts, {start:1, end:1}, 'Parse compressed attributes (count).');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<span title></span>');
|
||||
equal(writer.getContent(), '<span title=""></span>', 'Single empty attribute.');
|
||||
deepEqual(counter.counts, {start:1, end:1}, 'Single empty attributes (count).');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<span class="class" title></span>');
|
||||
equal(writer.getContent(), '<span class="class" title=""></span>', 'Empty attribute at end.');
|
||||
deepEqual(counter.counts, {start:1, end:1}, 'Empty attribute at end (count).');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<span title class="class"></span>');
|
||||
equal(writer.getContent(), '<span title="" class="class"></span>', 'Empty attribute at start.');
|
||||
deepEqual(counter.counts, {start:1, end:1}, 'Empty attribute at start (count).');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<img src="test">');
|
||||
equal(writer.getContent(), '<img src="test" />', 'Parse empty element.');
|
||||
deepEqual(counter.counts, {start:1}, 'Parse empty element counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<img\nsrc="test"\ntitle="row1\nrow2">');
|
||||
equal(writer.getContent(), '<img src="test" title="row1\nrow2" />', 'Parse attributes with linebreak.');
|
||||
deepEqual(counter.counts, {start: 1}, 'Parse attributes with linebreak counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<img \t \t src="test" \t \t title="\t row1\t row2">');
|
||||
equal(writer.getContent(), '<img src="test" title="\t row1\t row2" />', 'Parse attributes with whitespace.');
|
||||
deepEqual(counter.counts, {start: 1}, 'Parse attributes with whitespace counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<myns:mytag>text</myns:mytag>');
|
||||
equal(writer.getContent(), '<myns:mytag>text</myns:mytag>', 'Parse element with namespace.');
|
||||
deepEqual(counter.counts, {start:1, text:1, end: 1}, 'Parse element with namespace counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<myns-mytag>text</myns-mytag>');
|
||||
equal(writer.getContent(), '<myns-mytag>text</myns-mytag>', 'Parse element with dash name.');
|
||||
deepEqual(counter.counts, {start:1, text:1, end:1}, 'Parse element with dash name counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<myns_mytag>text</myns_mytag>');
|
||||
equal(writer.getContent(), '<myns_mytag>text</myns_mytag>', 'Parse element with underscore name.');
|
||||
deepEqual(counter.counts, {start:1, text:1, end:1}, 'Parse element with underscore name counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<p>text2<b>text3</p>text4</b>text5');
|
||||
equal(writer.getContent(), 'text1<p>text2<b>text3</b></p>text4text5', 'Parse tag soup 1.');
|
||||
deepEqual(counter.counts, {text:5, start: 2, end: 2}, 'Parse tag soup 1 counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<P>text2<B>text3</p>text4</b>text5');
|
||||
equal(writer.getContent(), 'text1<p>text2<b>text3</b></p>text4text5', 'Parse tag soup 2.');
|
||||
deepEqual(counter.counts, {text: 5, start: 2, end: 2}, 'Parse tag soup 2 counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<P>text2<B>tex<t3</p>te>xt4</b>text5');
|
||||
equal(writer.getContent(), 'text1<p>text2<b>tex<t3</b></p>te>xt4text5', 'Parse tag soup 3.');
|
||||
deepEqual(counter.counts, {text: 5, start: 2, end: 2}, 'Parse tag soup 3 counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<p>text2<b>text3');
|
||||
equal(writer.getContent(), 'text1<p>text2<b>text3</b></p>', 'Parse tag soup 4.');
|
||||
deepEqual(counter.counts, {text: 3, start: 2, end: 2}, 'Parse tag soup 4 counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<script>text2');
|
||||
equal(writer.getContent(), 'text1<script>text2</s' + 'cript>', 'Parse tag soup 5.');
|
||||
deepEqual(counter.counts, {text: 2, start: 1, end: 1}, 'Parse tag soup 5 counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<style>text2');
|
||||
equal(writer.getContent(), 'text1<style>text2</st' + 'yle>', 'Parse tag soup 6.');
|
||||
deepEqual(counter.counts, {text: 2, start: 1, end: 1}, 'Parse tag soup 6 counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<span title="<test" data-test="test>"></span>');
|
||||
equal(writer.getContent(), 'text1<span title="<test" data-test="test>"></span>', 'Parse element with </> in attributes.');
|
||||
deepEqual(counter.counts, {text: 1, start: 1, end: 1}, 'Parse element with </> in attributes counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse("text\n<SC"+"RIPT type=mce-text/javascript>// <![CDATA[\nalert('HELLO WORLD!');\n// ]]></SC"+"RIPT>");
|
||||
equal(writer.getContent(), "text\n<sc"+"ript type=\"mce-text/javascript\">// <![CDATA[\nalert('HELLO WORLD!');\n// ]]></sc"+"ript>", 'Parse cdata script.');
|
||||
deepEqual(counter.counts, {text: 2, start: 1, end: 1}, 'Parse cdata script counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<noscript>te<br>xt2</noscript>text3');
|
||||
equal(writer.getContent(), 'text1<noscript>te<br>xt2</noscript>text3', 'Parse noscript elements.');
|
||||
deepEqual(counter.counts, {text: 3, start: 1, end: 1}, 'Parse noscript elements counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<p>a</p><p /><p>b</p>');
|
||||
equal(writer.getContent(), '<p>a</p><p></p><p>b</p>', 'Parse invalid closed element.');
|
||||
deepEqual(counter.counts, {text: 2, start: 3, end: 3}, 'Parse invalid closed element counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<br><br /><br/>');
|
||||
equal(writer.getContent(), '<br /><br /><br />', 'Parse short ended elements.');
|
||||
deepEqual(counter.counts, {start: 3}, 'Parse short ended elements counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<p ></p>');
|
||||
equal(writer.getContent(), '<p></p>', 'Parse start elements with whitespace only attribs part.');
|
||||
deepEqual(counter.counts, {start: 1, end: 1}, 'Parse start elements with whitespace only attribs part (counts).');
|
||||
});
|
||||
|
||||
test('Parse style elements', function() {
|
||||
var counter, parser;
|
||||
|
||||
expect(8);
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<em><style>// <b>tag</b></st' + 'yle>text2</em>');
|
||||
equal(writer.getContent(), 'text1<em><style>// <b>tag</b></st' + 'yle>text2</em>', 'Parse style element.');
|
||||
deepEqual(counter.counts, {start: 2, end: 2, text: 3}, 'Parse style element counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<em><style id="id">// <b>tag</b></st' + 'yle>text2</em>');
|
||||
equal(writer.getContent(), 'text1<em><style id="id">// <b>tag</b></st' + 'yle>text2</em>', 'Parse style element with attributes.');
|
||||
deepEqual(counter.counts, {text:3, start:2, end:2}, 'Parse style element with attributes counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<em><style></st' + 'yle>text2</span>');
|
||||
equal(writer.getContent(), 'text1<em><style></st' + 'yle>text2</em>', 'Parse empty style element.');
|
||||
deepEqual(counter.counts, {text:2, start:2, end:2}, 'Parse empty style element counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(tinymce.extend({validate : true}, counter), new tinymce.html.Schema({invalid_elements: 'style'}));
|
||||
writer.reset();
|
||||
parser.parse('text1<em><style>text2</st' + 'yle>text3</em>');
|
||||
equal(writer.getContent(), 'text1<em>text3</em>', 'Parse invalid style element.');
|
||||
deepEqual(counter.counts, {text:2, start:1, end:1}, 'Parse invalid style element (count).');
|
||||
});
|
||||
|
||||
test('Parse script elements', function() {
|
||||
var counter, parser;
|
||||
|
||||
expect(8);
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<em><script>// <b>tag</b></s' + 'cript>text2</em>');
|
||||
equal(writer.getContent(), 'text1<em><script>// <b>tag</b></s' + 'cript>text2</em>', 'Parse script element.');
|
||||
deepEqual(counter.counts, {start:2, end:2, text:3}, 'Parse script element counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<em><script id="id">// <b>tag</b></s' + 'cript>text2</em>');
|
||||
equal(writer.getContent(), 'text1<em><script id="id">// <b>tag</b></s' + 'cript>text2</em>', 'Parse script element with attributes.');
|
||||
deepEqual(counter.counts, {start:2, end:2, text:3}, 'Parse script element with attributes counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<em><script></s' + 'cript>text2</em>');
|
||||
equal(writer.getContent(), 'text1<em><script></s' + 'cript>text2</em>', 'Parse empty script element.');
|
||||
deepEqual(counter.counts, {text: 2, start:2, end: 2}, 'Parse empty script element counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(tinymce.extend({validate : true}, counter), new tinymce.html.Schema({invalid_elements: 'script'}));
|
||||
writer.reset();
|
||||
parser.parse('text1<em><s' + 'cript>text2</s' + 'cript>text3</em>');
|
||||
equal(writer.getContent(), 'text1<em>text3</em>', 'Parse invalid script element.');
|
||||
deepEqual(counter.counts, {text:2, start:1, end:1}, 'Parse invalid script element (count).');
|
||||
});
|
||||
|
||||
test('Parse text', function() {
|
||||
var counter, parser;
|
||||
|
||||
expect(10);
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('');
|
||||
equal(writer.getContent(), '', 'Parse empty.');
|
||||
deepEqual(counter.counts, {}, 'Parse empty counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text');
|
||||
equal(writer.getContent(), 'text', 'Parse single text node.');
|
||||
deepEqual(counter.counts, {text: 1}, 'Parse single text node counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<b>text</b>');
|
||||
equal(writer.getContent(), '<b>text</b>', 'Parse wrapped text.');
|
||||
deepEqual(counter.counts, {start:1, text:1, end:1}, 'Parse wrapped text counts');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<b>text2</b>');
|
||||
equal(writer.getContent(), 'text1<b>text2</b>', 'Parse text at start.');
|
||||
deepEqual(counter.counts, {start:1, text:2, end:1}, 'Parse text at start counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<b>text1</b>text2');
|
||||
equal(writer.getContent(), '<b>text1</b>text2', 'Parse text at end.');
|
||||
deepEqual(counter.counts, {start:1, end:1, text:2}, 'Parse text at end counts.');
|
||||
});
|
||||
|
||||
test('Parsing comments', function() {
|
||||
var counter, parser;
|
||||
|
||||
expect(8);
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<!-- comment value -->');
|
||||
equal(writer.getContent(), '<!-- comment value -->', 'Parse comment with value.');
|
||||
deepEqual(counter.counts, {comment:1}, 'Parse comment with value count.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<!---->');
|
||||
equal(writer.getContent(), '', 'Parse comment without value.');
|
||||
deepEqual(counter.counts, {}, 'Parse comment without value count.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<!--<b></b>-->');
|
||||
equal(writer.getContent(), '<!--<b></b>-->', 'Parse comment with tag inside.');
|
||||
deepEqual(counter.counts, {comment:1}, 'Parse comment with tag inside counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<b>a<!-- value -->b</b>');
|
||||
equal(writer.getContent(), '<b>a<!-- value -->b</b>', 'Parse comment with tags around it.');
|
||||
deepEqual(counter.counts, {comment:1, text:2, start:1, end:1}, 'Parse comment with tags around it counts.');
|
||||
});
|
||||
|
||||
test('Parsing cdata', function() {
|
||||
var counter, parser;
|
||||
|
||||
expect(8);
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<![CDATA[test text]]>');
|
||||
equal(writer.getContent(), '<![CDATA[test text]]>', 'Parse cdata with value.');
|
||||
deepEqual(counter.counts, {cdata:1}, 'Parse cdata with value counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<![CDATA[]]>');
|
||||
equal(writer.getContent(), '', 'Parse cdata without value.');
|
||||
deepEqual(counter.counts, {}, 'Parse cdata without value counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<![CDATA[<b>a</b>]]>');
|
||||
equal(writer.getContent(), '<![CDATA[<b>a</b>]]>', 'Parse cdata with tag inside.');
|
||||
deepEqual(counter.counts, {cdata:1}, 'Parse cdata with tag inside counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<b>a<![CDATA[value]]>b</b>');
|
||||
equal(writer.getContent(), '<b>a<![CDATA[value]]>b</b>', 'Parse cdata with tags around it.');
|
||||
deepEqual(counter.counts, {cdata:1, start:1, end:1, text:2}, 'Parse cdata with tags around it counts.');
|
||||
});
|
||||
|
||||
test('Parse PI', function() {
|
||||
var counter, parser;
|
||||
|
||||
expect(6);
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<?xml version="1.0" encoding="UTF-8" ?>text1');
|
||||
equal(writer.getContent(), '<?xml version="1.0" encoding="UTF-8" ?>text1', 'Parse PI with attributes.');
|
||||
deepEqual(counter.counts, {pi:1, text:1}, 'Parse PI with attributes counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<?xml?>text1');
|
||||
equal(writer.getContent(), '<?xml?>text1', 'Parse PI with no data.');
|
||||
deepEqual(counter.counts, {pi:1, text:1}, 'Parse PI with data counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<?xml somevalue/>text1');
|
||||
equal(writer.getContent(), '<?xml somevalue?>text1', 'Parse PI with IE style ending.');
|
||||
deepEqual(counter.counts, {pi:1, text:1}, 'Parse PI with IE style ending counts.');
|
||||
});
|
||||
|
||||
test('Parse doctype', function() {
|
||||
var counter, parser;
|
||||
|
||||
expect(4);
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">text1');
|
||||
equal(writer.getContent(), '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">text1', 'Parse DOCTYPE.');
|
||||
deepEqual(counter.counts, {doctype:1, text:1}, 'Parse HTML5 DOCTYPE counts.');
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<!DOCTYPE html>text1');
|
||||
equal(writer.getContent(), '<!DOCTYPE html>text1', 'Parse HTML5 DOCTYPE.');
|
||||
deepEqual(counter.counts, {doctype:1, text:1}, 'Parse HTML5 DOCTYPE counts.');
|
||||
});
|
||||
|
||||
test('Parse (validate)', function() {
|
||||
var counter, parser;
|
||||
|
||||
expect(2);
|
||||
|
||||
counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<invalid1>123<invalid2 />456<span title="title" invalid3="value">789</span>012</invalid1>');
|
||||
equal(writer.getContent(), '123456<span title="title">789</span>012', 'Parse invalid elements and attributes.');
|
||||
deepEqual(counter.counts, {start:1, end:1, text:4}, 'Parse invalid elements and attributes counts.');
|
||||
});
|
||||
|
||||
test('Self closing', function() {
|
||||
var counter, parser;
|
||||
|
||||
expect(1);
|
||||
|
||||
counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<ul><li>1<li><b>2</b><li><em><b>3</b></em></ul>');
|
||||
equal(writer.getContent(), '<ul><li>1</li><li><b>2</b></li><li><em><b>3</b></em></li></ul>', 'Parse list with self closing items.');
|
||||
});
|
||||
|
||||
test('Preserve internal elements', function() {
|
||||
var counter, parser, schema;
|
||||
|
||||
expect(2);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements : 'b'});
|
||||
counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<span id="id"><b>text</b></span><span id="id" data-mce-type="something"></span>');
|
||||
equal(writer.getContent(), '<b>text</b><span id="id" data-mce-type="something"></span>', 'Preserve internal span element without any span schema rule.');
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements : 'b,span[class]'});
|
||||
counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<span id="id" class="class"><b>text</b></span><span id="id" data-mce-type="something"></span>');
|
||||
equal(writer.getContent(), '<span class="class"><b>text</b></span><span id="id" data-mce-type="something"></span>', 'Preserve internal span element with a span schema rule.');
|
||||
});
|
||||
|
||||
test('Remove internal elements', function() {
|
||||
var counter, parser, schema;
|
||||
|
||||
expect(2);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements : 'b'});
|
||||
counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
counter.remove_internals = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<span id="id"><b>text</b></span><span id="id" data-mce-type="something"></span>');
|
||||
equal(writer.getContent(), '<b>text</b>', 'Remove internal span element without any span schema rule.');
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements : 'b,span[class]'});
|
||||
counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
counter.remove_internals = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<span id="id" class="class"><b>text</b></span><span id="id" data-mce-type="something"></span>');
|
||||
equal(writer.getContent(), '<span class="class"><b>text</b></span>', 'Remove internal span element with a span schema rule.');
|
||||
|
||||
// Reset
|
||||
counter.remove_internals = false;
|
||||
});
|
||||
|
||||
test('Parse attr with backslash #5436', function() {
|
||||
var counter, parser;
|
||||
|
||||
counter = createCounter(writer);
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<a title="\\" href="h">x</a>');
|
||||
equal(writer.getContent(), '<a title="\\" href="h">x</a>');
|
||||
});
|
||||
|
||||
test('Parse no attributes span before strong', function() {
|
||||
var counter, parser;
|
||||
|
||||
counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<p><span>A</span> <strong>B</strong></p>');
|
||||
equal(writer.getContent(), '<p>A <strong>B</strong></p>');
|
||||
});
|
||||
|
||||
test('Conditional comments (allowed)', function() {
|
||||
var counter, parser;
|
||||
|
||||
counter = createCounter(writer);
|
||||
counter.validate = false;
|
||||
counter.allow_conditional_comments = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
|
||||
writer.reset();
|
||||
parser.parse('<!--[if gte IE 4]>alert(1)<![endif]-->');
|
||||
equal(writer.getContent(), '<!--[if gte IE 4]>alert(1)<![endif]-->');
|
||||
});
|
||||
|
||||
test('Conditional comments (denied)', function() {
|
||||
var counter, parser;
|
||||
|
||||
counter = createCounter(writer);
|
||||
counter.validate = false;
|
||||
counter.allow_conditional_comments = false;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
|
||||
writer.reset();
|
||||
parser.parse('<!--[if gte IE 4]>alert(1)<![endif]-->');
|
||||
equal(writer.getContent(), '<!-- [if gte IE 4]>alert(1)<![endif]-->');
|
||||
|
||||
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() {
|
||||
var counter, parser;
|
||||
|
||||
counter = createCounter(writer);
|
||||
counter.validate = false;
|
||||
counter.allow_script_urls = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse(
|
||||
'<a href="javascript:alert(1)">1</a>' +
|
||||
'<a href=" 2 ">2</a>' +
|
||||
'<a href="data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+">3</a>'
|
||||
);
|
||||
equal(
|
||||
writer.getContent(),
|
||||
'<a href="javascript:alert(1)">1</a><a href=" 2 ">2</a>' +
|
||||
'<a href="data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+">3</a>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Parse script urls (allowed html data uris)', function() {
|
||||
var counter, parser;
|
||||
|
||||
counter = createCounter(writer);
|
||||
counter.validate = false;
|
||||
counter.allow_html_data_urls = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse(
|
||||
'<a href="javascript:alert(1)">1</a>' +
|
||||
'<a href="data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+">2</a>'
|
||||
);
|
||||
equal(
|
||||
writer.getContent(),
|
||||
'<a>1</a>' +
|
||||
'<a href="data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+">2</a>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Parse script urls (denied)', function() {
|
||||
var counter, parser;
|
||||
|
||||
counter = createCounter(writer);
|
||||
counter.validate = false;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
|
||||
writer.reset();
|
||||
parser.parse(
|
||||
'<a href="jAvaScript:alert(1)">1</a>' +
|
||||
'<a href="vbscript:alert(2)">2</a>' +
|
||||
'<a href="java\u0000script:alert(3)">3</a>' +
|
||||
'<a href="\njavascript:alert(4)">4</a>' +
|
||||
'<a href="java\nscript:alert(5)">5</a>' +
|
||||
'<a href="java\tscript:alert(6)">6</a>' +
|
||||
'<a href="%6aavascript:alert(7)">7</a>' +
|
||||
'<a href="data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+">8</a>' +
|
||||
'<a href=" dAt%61: tExt/html ; bAse64 , PHN2Zy9vbmxvYWQ9YWxlcnQoMik+">9</a>' +
|
||||
'<object data="data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+">10</object>' +
|
||||
'<button formaction="javascript:alert(11)">11</button>' +
|
||||
'<table background="javascript:alert(12)"><tr><tr>12</tr></tr></table>' +
|
||||
'<a href="mhtml:13">13</a>' +
|
||||
'<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">' +
|
||||
'<a href="%E3%82%AA%E3%83%BC%E3%83">Invalid url</a>'
|
||||
);
|
||||
|
||||
equal(
|
||||
writer.getContent(),
|
||||
'<a>1</a><a>2</a><a>3</a><a>4</a><a>5</a><a>6</a><a>7</a><a>8</a><a>9</a>' +
|
||||
'<object>10</object><button>11</button><table><tr></tr><tr>12</tr></table><a>13</a>' +
|
||||
'<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" />' +
|
||||
'<a href="%E3%82%AA%E3%83%BC%E3%83">Invalid url</a>'
|
||||
);
|
||||
});
|
||||
|
||||
test('Parse away bogus elements', function() {
|
||||
function testBogusSaxParse(inputHtml, outputHtml, counters) {
|
||||
var counter, parser;
|
||||
|
||||
counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse(inputHtml);
|
||||
equal(writer.getContent(), outputHtml);
|
||||
deepEqual(counter.counts, counters);
|
||||
}
|
||||
|
||||
testBogusSaxParse('a<b data-mce-bogus="1">b</b>c', 'abc', {text: 3});
|
||||
testBogusSaxParse('a<b data-mce-bogus="true">b</b>c', 'abc', {text: 3});
|
||||
testBogusSaxParse('a<b data-mce-bogus="1"></b>c', 'ac', {text: 2});
|
||||
testBogusSaxParse('a<b data-mce-bogus="all">b</b>c', 'ac', {text: 2});
|
||||
testBogusSaxParse('a<b data-mce-bogus="all"><!-- x --><?xml?></b>c', 'ac', {text: 2});
|
||||
testBogusSaxParse('a<b data-mce-bogus="all"><b>b</b></b>c', 'ac', {text: 2});
|
||||
testBogusSaxParse('a<b data-mce-bogus="all"><br>b</b><b>c</b>', 'a<b>c</b>', {start: 1, end: 1, text: 2});
|
||||
testBogusSaxParse('a<b data-mce-bogus="all"><img>b</b><b>c</b>', 'a<b>c</b>', {start: 1, end: 1, text: 2});
|
||||
testBogusSaxParse('a<b data-mce-bogus="all"><b attr="x">b</b></b>c', 'ac', {text: 2});
|
||||
testBogusSaxParse('a<b data-mce-bogus="all"></b>c', 'ac', {text: 2});
|
||||
testBogusSaxParse('a<b data-mce-bogus="all"></b><b>c</b>', 'a<b>c</b>', {start: 1, end: 1, text:2});
|
||||
});
|
||||
|
||||
test('findEndTag', function() {
|
||||
function testFindEndTag(html, startIndex, expectedIndex) {
|
||||
equal(tinymce.html.SaxParser.findEndTag(schema, html, startIndex), expectedIndex);
|
||||
}
|
||||
|
||||
testFindEndTag('<b>', 3, 3);
|
||||
testFindEndTag('<img>', 3, 3);
|
||||
testFindEndTag('<b></b>', 3, 7);
|
||||
testFindEndTag('<b><img></b>', 3, 12);
|
||||
testFindEndTag('<b><!-- </b> --></b>', 3, 20);
|
||||
testFindEndTag('<span><b><i>a<img>b</i><b>c</b></b></span>', 9, 35);
|
||||
});
|
||||
|
||||
test('parse XSS PI', function() {
|
||||
var counter, parser;
|
||||
|
||||
counter = createCounter(writer);
|
||||
counter.validate = false;
|
||||
parser = new tinymce.html.SaxParser(counter, schema);
|
||||
|
||||
writer.reset();
|
||||
parser.parse('<?xml><iframe SRC=javascript:alert('XSS')>?>');
|
||||
|
||||
equal(
|
||||
writer.getContent(),
|
||||
'<?xml ><iframe SRC=&#106&#97&#118&#97&#115&#99&#114&#105&#112&' +
|
||||
'#116&#58&#97&#108&#101&#114&#116&#40&#39&#88&#83&#83&#39&#41>?>'
|
||||
);
|
||||
});
|
||||
})();
|
||||
@ -1,560 +0,0 @@
|
||||
module("tinymce.html.Schema");
|
||||
|
||||
test('Valid elements global rule', function() {
|
||||
expect(1);
|
||||
|
||||
var schema = new tinymce.html.Schema({valid_elements: '@[id|style],img[src|-style]'});
|
||||
deepEqual(schema.getElementRule('img'), {"attributes": {"id": {}, "src": {}}, "attributesOrder": ["id", "src"]});
|
||||
});
|
||||
|
||||
test('Whildcard element rule', function() {
|
||||
var schema;
|
||||
|
||||
expect(17);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: '*[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').attributesOrder, ["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').attributesOrder, ["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').attributesOrder, ["id", "class"]);
|
||||
deepEqual(schema.getElementRule('bx').attributes, {"id": {}, "class": {}});
|
||||
deepEqual(schema.getElementRule('bx').attributesOrder, ["id", "class"]);
|
||||
equal(schema.getElementRule('b'), undefined);
|
||||
});
|
||||
|
||||
test('Whildcard attribute rule', function() {
|
||||
var schema;
|
||||
|
||||
expect(13);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'b[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').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').attributesOrder, ["id", "class"]);
|
||||
ok(!schema.getElementRule('b').attributePatterns[0].pattern.test('x'));
|
||||
ok(schema.getElementRule('b').attributePatterns[0].pattern.test('xb'));
|
||||
ok(schema.getElementRule('b').attributePatterns[0].pattern.test('xba'));
|
||||
});
|
||||
|
||||
test('Valid attributes and attribute order', function() {
|
||||
var schema;
|
||||
|
||||
expect(3);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'div,a[href|title],b[title]'});
|
||||
deepEqual(schema.getElementRule('div'), {"attributes": {}, "attributesOrder": []});
|
||||
deepEqual(schema.getElementRule('a'), {"attributes": {"href": {}, "title": {}}, "attributesOrder": ["href", "title"]});
|
||||
deepEqual(schema.getElementRule('b'), {"attributes": {"title": {}}, "attributesOrder": ["title"]});
|
||||
});
|
||||
|
||||
test('Required any attributes', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'a![id|style|href]'});
|
||||
deepEqual(schema.getElementRule('a'), {"attributes": {"href": {}, "id": {}, "style": {}}, "attributesOrder": ["id", "style", "href"], "removeEmptyAttrs": true});
|
||||
});
|
||||
|
||||
test('Required attributes', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'a[!href|!name]'});
|
||||
deepEqual(schema.getElementRule('a'), {"attributes": {"href": {"required": true}, "name": {"required": true}}, "attributesOrder": ["href", "name"], "attributesRequired": ["href", "name"]});
|
||||
});
|
||||
|
||||
test('Default attribute values', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'img[border=0]'});
|
||||
deepEqual(schema.getElementRule('img'), {"attributes": {"border": {"defaultValue": "0"}}, "attributesOrder": ["border"], "attributesDefault": [{"name": "border", "value": "0"}]});
|
||||
});
|
||||
|
||||
test('Forced attribute values', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'img[border:0]'});
|
||||
deepEqual(schema.getElementRule('img'), {"attributes": {"border": {"forcedValue": "0"}}, "attributesOrder": ["border"], "attributesForced": [{"name": "border", "value": "0"}]});
|
||||
});
|
||||
|
||||
test('Required attribute values', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'span[dir<ltr?rtl]'});
|
||||
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;
|
||||
|
||||
expect(2);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: '-span'});
|
||||
deepEqual(schema.getElementRule('span'), {"attributes": {}, "attributesOrder": [], "removeEmpty": true});
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: '#span'});
|
||||
deepEqual(schema.getElementRule('span'), {"attributes": {}, "attributesOrder": [], "paddEmpty": true});
|
||||
});
|
||||
|
||||
test('addValidElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: '@[id|style],img[src|-style]'});
|
||||
schema.addValidElements('b[class]');
|
||||
deepEqual(schema.getElementRule('b'), {"attributes": {"id": {}, "style": {}, "class": {}}, "attributesOrder": ["id", "style", "class"]});
|
||||
});
|
||||
|
||||
test('setValidElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(3);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: '@[id|style],img[src|-style]'});
|
||||
schema.setValidElements('b[class]');
|
||||
equal(schema.getElementRule('img'), undefined);
|
||||
deepEqual(schema.getElementRule('b'), {"attributes": {"class": {}}, "attributesOrder": ["class"]});
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements: 'img[src]'});
|
||||
schema.setValidElements('@[id|style],img[src]');
|
||||
deepEqual(schema.getElementRule('img'), {"attributes": {"id": {}, "style": {}, "src": {}}, "attributesOrder": ["id", "style", "src"]});
|
||||
});
|
||||
|
||||
test('getBoolAttrs', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getBoolAttrs(), {
|
||||
"CONTROLS": {}, "LOOP": {}, "AUTOPLAY": {}, "SELECTED": {}, "READONLY": {}, "NOWRAP": {},
|
||||
"NOSHADE": {}, "NORESIZE": {}, "NOHREF": {}, "MULTIPLE": {}, "ISMAP": {}, "DISABLED": {}, "DEFER": {},
|
||||
"DECLARE": {}, "COMPACT": {}, "CHECKED": {},
|
||||
"controls": {}, "loop": {}, "autoplay": {}, "selected": {}, "readonly": {}, "nowrap": {},
|
||||
"noshade": {}, "noresize": {}, "nohref": {}, "multiple": {}, "ismap": {}, "disabled": {}, "defer": {},
|
||||
"declare": {}, "compact": {}, "checked": {}
|
||||
});
|
||||
});
|
||||
|
||||
test('getBlockElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getBlockElements(), {
|
||||
ASIDE: {}, HGROUP: {}, SECTION: {}, ARTICLE: {}, FOOTER: {}, HEADER: {},
|
||||
ISINDEX: {}, MENU: {}, NOSCRIPT: {}, FIELDSET: {}, FIGCAPTION: {}, DIR: {}, DD: {}, DT: {},
|
||||
DL: {}, CENTER: {}, BLOCKQUOTE: {}, CAPTION: {}, UL: {}, OL: {}, LI: {},
|
||||
TD: {}, TR: {}, TH: {}, TFOOT: {}, THEAD: {}, TBODY: {}, TABLE: {}, FORM: {},
|
||||
PRE: {}, ADDRESS: {}, DIV: {}, P: {}, HR: {}, H6: {}, H5: {}, H4: {}, H3: {},
|
||||
H2: {}, H1: {}, NAV: {}, FIGURE: {}, DATALIST: {}, OPTGROUP: {}, OPTION: {}, SELECT: {},
|
||||
aside: {}, hgroup: {}, section: {}, article: {}, footer: {}, header: {},
|
||||
isindex: {}, menu: {}, noscript: {}, fieldset: {}, dir: {}, dd: {}, dt: {}, dl: {}, center: {},
|
||||
blockquote: {}, caption: {}, ul: {}, ol: {}, li: {}, td: {}, tr: {}, th: {}, tfoot: {}, thead: {},
|
||||
tbody: {}, table: {}, form: {}, pre: {}, address: {}, div: {}, p: {}, hr: {}, h6: {},
|
||||
h5: {}, h4: {}, h3: {}, h2: {}, h1: {}, nav: {}, figure: {}, figcaption: {}, datalist: {}, optgroup: {},
|
||||
option: {}, select: {}
|
||||
});
|
||||
});
|
||||
|
||||
test('getShortEndedElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getShortEndedElements(), {
|
||||
"EMBED": {}, "PARAM": {}, "META": {}, "LINK": {}, "ISINDEX": {},
|
||||
"INPUT": {}, "IMG": {}, "HR": {}, "FRAME": {}, "COL": {}, "BR": {},
|
||||
"BASEFONT": {}, "BASE": {}, "AREA": {}, "SOURCE" : {}, "WBR" : {}, "TRACK" : {},
|
||||
"embed": {}, "param": {}, "meta": {}, "link": {}, "isindex": {},
|
||||
"input": {}, "img": {}, "hr": {}, "frame": {}, "col": {}, "br": {},
|
||||
"basefont": {}, "base": {}, "area": {}, "source" : {}, "wbr" : {}, "track" : {}
|
||||
});
|
||||
});
|
||||
|
||||
test('getNonEmptyElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getNonEmptyElements(), {
|
||||
"EMBED": {}, "PARAM": {}, "META": {}, "LINK": {}, "ISINDEX": {},
|
||||
"INPUT": {}, "IMG": {}, "HR": {}, "FRAME": {}, "COL": {}, "BR": {},
|
||||
"BASEFONT": {}, "BASE": {}, "AREA": {}, "SOURCE" : {},
|
||||
"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" : {}, "pre": {}, "code": {}
|
||||
});
|
||||
});
|
||||
|
||||
test('getWhiteSpaceElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getWhiteSpaceElements(), {
|
||||
"IFRAME": {}, "NOSCRIPT": {}, "OBJECT": {}, "PRE": {}, "CODE": {},
|
||||
"SCRIPT": {}, "STYLE": {}, "TEXTAREA": {}, "VIDEO": {}, "AUDIO": {},
|
||||
"iframe": {}, "noscript": {}, "object": {}, "pre": {}, "code": {},
|
||||
"script": {}, "style": {}, "textarea": {}, "video": {}, "audio": {}
|
||||
});
|
||||
});
|
||||
|
||||
test('getTextBlockElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getTextBlockElements(), {
|
||||
"ADDRESS": {}, "ARTICLE": {}, "ASIDE": {}, "BLOCKQUOTE": {}, "CENTER": {}, "DIR": {}, "DIV": {}, "FIELDSET": {}, "FIGURE": {}, "FOOTER": {}, "FORM": {},
|
||||
"H1": {}, "H2": {}, "H3": {}, "H4": {}, "H5": {}, "H6": {}, "HEADER": {}, "HGROUP": {}, "NAV": {}, "P": {}, "PRE": {}, "SECTION": {},
|
||||
"address": {}, "article": {}, "aside": {}, "blockquote": {}, "center": {}, "dir": {}, "div": {}, "fieldset": {}, "figure": {}, "footer": {}, "form": {},
|
||||
"h1": {}, "h2": {}, "h3": {}, "h4": {}, "h5": {}, "h6": {}, "header": {}, "hgroup": {}, "nav": {}, "p": {}, "pre": {}, "section": {}
|
||||
});
|
||||
});
|
||||
|
||||
test('getTextInlineElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(1);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getTextInlineElements(), {
|
||||
"B": {}, "CITE": {}, "CODE": {}, "DFN": {}, "EM": {}, "FONT": {}, "I": {}, "MARK": {}, "Q": {},
|
||||
"SAMP": {}, "SPAN": {}, "STRIKE": {}, "STRONG": {}, "SUB": {}, "SUP": {}, "U": {}, "VAR": {},
|
||||
"b": {}, "cite": {}, "code": {}, "dfn": {}, "em": {}, "font": {}, "i": {}, "mark": {}, "q": {},
|
||||
"samp": {}, "span": {}, "strike": {}, "strong": {}, "sub": {}, "sup": {}, "u": {}, "var": {}
|
||||
});
|
||||
});
|
||||
|
||||
test('isValidChild', function() {
|
||||
var schema;
|
||||
|
||||
expect(4);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
ok(schema.isValidChild('body', 'p'));
|
||||
ok(schema.isValidChild('p', 'img'));
|
||||
ok(!schema.isValidChild('body', 'body'));
|
||||
ok(!schema.isValidChild('p', 'body'));
|
||||
});
|
||||
|
||||
test('getElementRule', function() {
|
||||
var schema;
|
||||
|
||||
expect(3);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
ok(schema.getElementRule('b'));
|
||||
ok(!schema.getElementRule('bx'));
|
||||
ok(!schema.getElementRule(null));
|
||||
});
|
||||
|
||||
test('addCustomElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(5);
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements:'inline,block'});
|
||||
schema.addCustomElements('~inline,block');
|
||||
ok(schema.getElementRule('inline'));
|
||||
ok(schema.getElementRule('block'));
|
||||
ok(schema.isValidChild('body', 'block'));
|
||||
ok(schema.isValidChild('block', 'inline'));
|
||||
ok(schema.isValidChild('p', 'inline'));
|
||||
});
|
||||
|
||||
test('addValidChildren', function() {
|
||||
var schema;
|
||||
|
||||
expect(7);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
ok(schema.isValidChild('body', 'p'));
|
||||
ok(!schema.isValidChild('body', 'body'));
|
||||
ok(!schema.isValidChild('body', 'html'));
|
||||
schema.addValidChildren('+body[body|html]');
|
||||
ok(schema.isValidChild('body', 'body'));
|
||||
ok(schema.isValidChild('body', 'html'));
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
ok(schema.isValidChild('body', 'p'));
|
||||
schema.addValidChildren('-body[p]');
|
||||
ok(!schema.isValidChild('body', 'p'));
|
||||
});
|
||||
|
||||
test('addCustomElements/getCustomElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(4);
|
||||
|
||||
schema = new tinymce.html.Schema();
|
||||
schema.addCustomElements('~inline,block');
|
||||
ok(schema.getBlockElements().block);
|
||||
ok(!schema.getBlockElements().inline);
|
||||
ok(schema.getCustomElements().inline);
|
||||
ok(schema.getCustomElements().block);
|
||||
});
|
||||
|
||||
test('whitespaceElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(3);
|
||||
|
||||
schema = new tinymce.html.Schema({whitespace_elements : 'pre,p'});
|
||||
ok(schema.getWhiteSpaceElements().pre);
|
||||
ok(!schema.getWhiteSpaceElements().span);
|
||||
|
||||
schema = new tinymce.html.Schema({whitespace_elements : 'code'});
|
||||
ok(schema.getWhiteSpaceElements().code);
|
||||
});
|
||||
|
||||
test('selfClosingElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(3);
|
||||
|
||||
schema = new tinymce.html.Schema({self_closing_elements : 'pre,p'});
|
||||
ok(schema.getSelfClosingElements().pre);
|
||||
ok(schema.getSelfClosingElements().p);
|
||||
ok(!schema.getSelfClosingElements().li);
|
||||
});
|
||||
|
||||
test('shortEndedElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(3);
|
||||
|
||||
schema = new tinymce.html.Schema({short_ended_elements : 'pre,p'});
|
||||
ok(schema.getShortEndedElements().pre);
|
||||
ok(schema.getShortEndedElements().p);
|
||||
ok(!schema.getShortEndedElements().img);
|
||||
});
|
||||
|
||||
test('booleanAttributes', function() {
|
||||
var schema;
|
||||
|
||||
expect(3);
|
||||
|
||||
schema = new tinymce.html.Schema({boolean_attributes : 'href,alt'});
|
||||
ok(schema.getBoolAttrs().href);
|
||||
ok(schema.getBoolAttrs().alt);
|
||||
ok(!schema.getBoolAttrs().checked);
|
||||
});
|
||||
|
||||
test('nonEmptyElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(3);
|
||||
|
||||
schema = new tinymce.html.Schema({non_empty_elements : 'pre,p'});
|
||||
ok(schema.getNonEmptyElements().pre);
|
||||
ok(schema.getNonEmptyElements().p);
|
||||
ok(!schema.getNonEmptyElements().img);
|
||||
});
|
||||
|
||||
test('blockElements', function() {
|
||||
var schema;
|
||||
|
||||
expect(3);
|
||||
|
||||
schema = new tinymce.html.Schema({block_elements : 'pre,p'});
|
||||
ok(schema.getBlockElements().pre);
|
||||
ok(schema.getBlockElements().p);
|
||||
ok(!schema.getBlockElements().h1);
|
||||
});
|
||||
|
||||
test('isValid', function() {
|
||||
var schema;
|
||||
|
||||
schema = new tinymce.html.Schema({valid_elements : 'a[href],i[*]'});
|
||||
|
||||
ok(schema.isValid('a'));
|
||||
ok(schema.isValid('a', 'href'));
|
||||
ok(!schema.isValid('b'));
|
||||
ok(!schema.isValid('b', 'href'));
|
||||
ok(!schema.isValid('a', 'id'));
|
||||
ok(schema.isValid('i'));
|
||||
ok(schema.isValid('i', 'id'));
|
||||
});
|
||||
|
||||
test('validStyles', function() {
|
||||
var schema;
|
||||
|
||||
schema = new tinymce.html.Schema({valid_styles: 'color,font-size'});
|
||||
deepEqual(schema.getValidStyles(), {
|
||||
"*": [
|
||||
"color",
|
||||
"font-size"
|
||||
]
|
||||
});
|
||||
|
||||
schema = new tinymce.html.Schema({valid_styles: 'color font-size'});
|
||||
deepEqual(schema.getValidStyles(), {
|
||||
"*": [
|
||||
"color",
|
||||
"font-size"
|
||||
]
|
||||
});
|
||||
|
||||
schema = new tinymce.html.Schema({
|
||||
valid_styles: {
|
||||
'*': 'color font-size',
|
||||
'a': 'background font-family'
|
||||
}
|
||||
});
|
||||
deepEqual(schema.getValidStyles(), {
|
||||
"*": [
|
||||
"color",
|
||||
"font-size"
|
||||
],
|
||||
|
||||
"a": [
|
||||
"background",
|
||||
"font-family"
|
||||
],
|
||||
|
||||
"A": [
|
||||
"background",
|
||||
"font-family"
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
test('invalidStyles', function() {
|
||||
var schema;
|
||||
|
||||
schema = new tinymce.html.Schema({invalid_styles: 'color,font-size'});
|
||||
deepEqual(schema.getInvalidStyles(), {
|
||||
'*': {
|
||||
'color': {},
|
||||
'font-size': {}
|
||||
}
|
||||
});
|
||||
|
||||
schema = new tinymce.html.Schema({invalid_styles: 'color font-size'});
|
||||
deepEqual(schema.getInvalidStyles(), {
|
||||
'*': {
|
||||
'color': {},
|
||||
'font-size': {}
|
||||
}
|
||||
});
|
||||
|
||||
schema = new tinymce.html.Schema({
|
||||
invalid_styles: {
|
||||
'*': 'color font-size',
|
||||
'a': 'background font-family'
|
||||
}
|
||||
});
|
||||
deepEqual(schema.getInvalidStyles(), {
|
||||
'*': {
|
||||
'color': {},
|
||||
'font-size': {}
|
||||
},
|
||||
|
||||
'a': {
|
||||
'background': {},
|
||||
'font-family': {}
|
||||
},
|
||||
|
||||
'A': {
|
||||
'background': {},
|
||||
'font-family': {}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('validClasses', function() {
|
||||
var schema;
|
||||
|
||||
schema = new tinymce.html.Schema({valid_classes: 'classA,classB'});
|
||||
deepEqual(schema.getValidClasses(), {
|
||||
'*': {
|
||||
'classA': {},
|
||||
'classB': {}
|
||||
}
|
||||
});
|
||||
|
||||
schema = new tinymce.html.Schema({valid_classes: 'classA classB'});
|
||||
deepEqual(schema.getValidClasses(), {
|
||||
'*': {
|
||||
'classA': {},
|
||||
'classB': {}
|
||||
}
|
||||
});
|
||||
|
||||
schema = new tinymce.html.Schema({
|
||||
valid_classes: {
|
||||
'*': 'classA classB',
|
||||
'a': 'classC classD'
|
||||
}
|
||||
});
|
||||
deepEqual(schema.getValidClasses(), {
|
||||
'*': {
|
||||
'classA': {},
|
||||
'classB': {}
|
||||
},
|
||||
|
||||
'a': {
|
||||
'classC': {},
|
||||
'classD': {}
|
||||
},
|
||||
|
||||
'A': {
|
||||
'classC': {},
|
||||
'classD': {}
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1,32 +0,0 @@
|
||||
module("tinymce.html.Serializer");
|
||||
|
||||
test('Basic serialization', function() {
|
||||
var serializer = new tinymce.html.Serializer();
|
||||
|
||||
expect(6);
|
||||
|
||||
equal(serializer.serialize(new tinymce.html.DomParser().parse('text<text&')), 'text<text&');
|
||||
equal(serializer.serialize(new tinymce.html.DomParser().parse('<B>text</B><IMG src="1.gif">')), '<strong>text</strong><img src="1.gif" />');
|
||||
equal(serializer.serialize(new tinymce.html.DomParser().parse('<!-- comment -->')), '<!-- comment -->');
|
||||
equal(serializer.serialize(new tinymce.html.DomParser().parse('<![CDATA[cdata]]>')), '<![CDATA[cdata]]>');
|
||||
equal(serializer.serialize(new tinymce.html.DomParser().parse('<?xml attr="value" ?>')), '<?xml attr="value" ?>');
|
||||
equal(serializer.serialize(new tinymce.html.DomParser().parse('<!DOCTYPE html>')), '<!DOCTYPE html>');
|
||||
});
|
||||
|
||||
test('Sorting of attributes', function() {
|
||||
var serializer = new tinymce.html.Serializer();
|
||||
|
||||
expect(1);
|
||||
|
||||
equal(serializer.serialize(new tinymce.html.DomParser().parse('<b class="class" id="id">x</b>')), '<strong id="id" class="class">x</strong>');
|
||||
});
|
||||
|
||||
test('Serialize with validate: true, when parsing with validate:false bug', function() {
|
||||
var schema = new tinymce.html.Schema({valid_elements: 'b'});
|
||||
var serializer = new tinymce.html.Serializer({}, schema);
|
||||
|
||||
equal(
|
||||
serializer.serialize(new tinymce.html.DomParser({validate: false}, schema).parse('<b a="1" b="2">a</b><i a="1" b="2">b</i>')),
|
||||
'<b a="1" b="2">a</b><i a="1" b="2">b</i>'
|
||||
);
|
||||
});
|
||||
@ -1,184 +0,0 @@
|
||||
module("tinymce.html.Styles");
|
||||
|
||||
test('Basic parsing/serializing', function() {
|
||||
var styles = new tinymce.html.Styles();
|
||||
|
||||
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;");
|
||||
equal(styles.serialize(styles.parse(' FONT-SIZE : 10px ; COLOR : red ')), "font-size: 10px; color: red;");
|
||||
equal(styles.serialize(styles.parse('key:"value"')), "key: 'value';");
|
||||
equal(styles.serialize(styles.parse('key:"value1" \'value2\'')), "key: 'value1' 'value2';");
|
||||
equal(styles.serialize(styles.parse('key:"val\\"ue1" \'val\\\'ue2\'')), "key: 'val\"ue1' 'val\\'ue2';");
|
||||
equal(styles.serialize(styles.parse('width:100%')), 'width: 100%;');
|
||||
equal(styles.serialize(styles.parse('value:_; value2:"_"')), 'value: _; value2: \'_\';');
|
||||
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() {
|
||||
var styles = new tinymce.html.Styles();
|
||||
|
||||
expect(6);
|
||||
|
||||
equal(styles.serialize(styles.parse('color: rgb(1,2,3)')), "color: #010203;");
|
||||
equal(styles.serialize(styles.parse('color: RGB(1,2,3)')), "color: #010203;");
|
||||
equal(styles.serialize(styles.parse('color: #FF0000')), "color: #ff0000;");
|
||||
equal(styles.serialize(styles.parse(' color: RGB ( 1 , 2 , 3 ) ')), "color: #010203;");
|
||||
equal(styles.serialize(styles.parse(' FONT-SIZE : 10px ; COLOR : RGB ( 1 , 2 , 3 ) ')), "font-size: 10px; color: #010203;");
|
||||
equal(styles.serialize(styles.parse(' FONT-SIZE : 10px ; COLOR : RED ')), "font-size: 10px; color: red;");
|
||||
});
|
||||
|
||||
test('Urls convert urls and force format', function() {
|
||||
var styles = new tinymce.html.Styles({url_converter : function(url) {
|
||||
return '|' + url + '|';
|
||||
}});
|
||||
|
||||
expect(9);
|
||||
|
||||
equal(styles.serialize(styles.parse('background: url(a)')), "background: url('|a|');");
|
||||
equal(styles.serialize(styles.parse('background: url("a")')), "background: url('|a|');");
|
||||
equal(styles.serialize(styles.parse("background: url('a')")), "background: url('|a|');");
|
||||
equal(styles.serialize(styles.parse('background: url( a )')), "background: url('|a|');");
|
||||
equal(styles.serialize(styles.parse('background: url( "a" )')), "background: url('|a|');");
|
||||
equal(styles.serialize(styles.parse("background: url( 'a' )")), "background: url('|a|');");
|
||||
equal(styles.serialize(styles.parse('background1: url(a); background2: url("a"); background3: url(\'a\')')), "background1: url('|a|'); background2: url('|a|'); background3: url('|a|');");
|
||||
equal(styles.serialize(styles.parse("background: url('http://www.site.com/a?a=b&c=d')")), "background: url('|http://www.site.com/a?a=b&c=d|');");
|
||||
equal(styles.serialize(styles.parse("background: url('http://www.site.com/a_190x144.jpg');")), "background: url('|http://www.site.com/a_190x144.jpg|');");
|
||||
});
|
||||
|
||||
test('Compress styles', function() {
|
||||
var styles = new tinymce.html.Styles();
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('border-top: 1px solid red; border-left: 1px solid red; border-bottom: 1px solid red; border-right: 1px solid red;')),
|
||||
'border: 1px solid red;'
|
||||
);
|
||||
|
||||
equal(
|
||||
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;'
|
||||
);
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('border-top: 1px solid red; border-left: 1px solid red; border-right: 1px solid red; border-bottom: 1px solid red')),
|
||||
'border: 1px solid red;'
|
||||
);
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('border-top: 1px solid red; border-right: 2px solid red; border-bottom: 3px solid red; border-left: 4px solid red')),
|
||||
'border-top: 1px solid red; border-right: 2px solid red; border-bottom: 3px solid red; border-left: 4px solid red;'
|
||||
);
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('padding-top: 1px; padding-right: 2px; padding-bottom: 3px; padding-left: 4px')),
|
||||
'padding: 1px 2px 3px 4px;'
|
||||
);
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('margin-top: 1px; margin-right: 2px; margin-bottom: 3px; margin-left: 4px')),
|
||||
'margin: 1px 2px 3px 4px;'
|
||||
);
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('margin-top: 1px; margin-right: 1px; margin-bottom: 1px; margin-left: 2px')),
|
||||
'margin: 1px 1px 1px 2px;'
|
||||
);
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('margin-top: 2px; margin-right: 1px; margin-bottom: 1px; margin-left: 1px')),
|
||||
'margin: 2px 1px 1px 1px;'
|
||||
);
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('border-top-color: red; border-right-color: green; border-bottom-color: blue; border-left-color: yellow')),
|
||||
'border-color: red green blue yellow;'
|
||||
);
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('border-width: 1px; border-style: solid; border-color: red')),
|
||||
'border: 1px solid red;'
|
||||
);
|
||||
|
||||
equal(
|
||||
styles.serialize(styles.parse('border-width: 1px; border-color: red')),
|
||||
'border-width: 1px; border-color: red;'
|
||||
);
|
||||
});
|
||||
|
||||
test('Font weight', function() {
|
||||
var styles = new tinymce.html.Styles();
|
||||
|
||||
expect(1);
|
||||
|
||||
equal(styles.serialize(styles.parse('font-weight: 700')), "font-weight: bold;");
|
||||
});
|
||||
|
||||
test('Valid styles', function() {
|
||||
var styles = new tinymce.html.Styles({}, new tinymce.html.Schema({valid_styles : {'*': 'color,font-size', 'a': 'margin-left'}}));
|
||||
|
||||
expect(2);
|
||||
|
||||
equal(styles.serialize(styles.parse('color: #ff0000; font-size: 10px; margin-left: 10px; invalid: 1;'), 'b'), "color: #ff0000; font-size: 10px;");
|
||||
equal(styles.serialize(styles.parse('color: #ff0000; font-size: 10px; margin-left: 10px; invalid: 2;'), 'a'), "color: #ff0000; font-size: 10px; margin-left: 10px;");
|
||||
});
|
||||
|
||||
test('Invalid styles', function() {
|
||||
var styles = new tinymce.html.Styles({}, new tinymce.html.Schema({invalid_styles : {'*': 'color,font-size', 'a': 'margin-left'}}));
|
||||
|
||||
equal(styles.serialize(styles.parse('color: #ff0000; font-size: 10px; margin-left: 10px'), 'b'), "margin-left: 10px;");
|
||||
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))')), "");
|
||||
equal(styles.serialize(styles.parse('color:/**/')), "");
|
||||
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() {
|
||||
var styles = new tinymce.html.Styles({allow_script_urls: true});
|
||||
|
||||
equal(styles.serialize(styles.parse('behavior:url(test.htc)')), "behavior: url('test.htc');");
|
||||
equal(styles.serialize(styles.parse('color:expression(alert(1))')), "color: expression(alert(1));");
|
||||
equal(styles.serialize(styles.parse('background:url(javascript:alert(1)')), "background: url('javascript:alert(1');");
|
||||
equal(styles.serialize(styles.parse('background:url(vbscript:alert(1)')), "background: url('vbscript:alert(1');");
|
||||
});
|
||||
@ -1,170 +0,0 @@
|
||||
module("tinymce.html.Writer");
|
||||
|
||||
test('Comment', function() {
|
||||
var writer;
|
||||
|
||||
expect(2);
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.comment('text');
|
||||
equal(writer.getContent(), '<!--text-->');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.comment('');
|
||||
equal(writer.getContent(), '<!---->');
|
||||
});
|
||||
|
||||
test('CDATA', function() {
|
||||
var writer;
|
||||
|
||||
expect(2);
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.cdata('text');
|
||||
equal(writer.getContent(), '<![CDATA[text]]>');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.cdata('');
|
||||
equal(writer.getContent(), '<![CDATA[]]>');
|
||||
});
|
||||
|
||||
test('PI', function() {
|
||||
var writer;
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.pi('xml', 'someval');
|
||||
equal(writer.getContent(), '<?xml someval?>');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.pi('xml');
|
||||
equal(writer.getContent(), '<?xml?>');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.pi('xml', 'encoding="UTF-8" < >');
|
||||
equal(writer.getContent(), '<?xml encoding="UTF-8" < >?>');
|
||||
});
|
||||
|
||||
test('Doctype', function() {
|
||||
var writer;
|
||||
|
||||
expect(2);
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.doctype(' text');
|
||||
equal(writer.getContent(), '<!DOCTYPE text>');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.doctype('');
|
||||
equal(writer.getContent(), '<!DOCTYPE>');
|
||||
});
|
||||
|
||||
test('Text', function() {
|
||||
var writer;
|
||||
|
||||
expect(2);
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.text('te<xt');
|
||||
equal(writer.getContent(), 'te<xt');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.text('');
|
||||
equal(writer.getContent(), '');
|
||||
});
|
||||
|
||||
test('Text raw', function() {
|
||||
var writer;
|
||||
|
||||
expect(2);
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.text('te<xt', true);
|
||||
equal(writer.getContent(), 'te<xt');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.text('', true);
|
||||
equal(writer.getContent(), '');
|
||||
});
|
||||
|
||||
test('Start', function() {
|
||||
var writer;
|
||||
|
||||
expect(5);
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.start('b');
|
||||
equal(writer.getContent(), '<b>');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.start('b', [{name: 'attr1', value: 'value1'}, {name: 'attr2', value: 'value2'}]);
|
||||
equal(writer.getContent(), '<b attr1="value1" attr2="value2">');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.start('b', [{name: 'attr1', value: 'val<"ue1'}]);
|
||||
equal(writer.getContent(), '<b attr1="val<"ue1">');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.start('img', [{name: 'attr1', value: 'value1'}, {name: 'attr2', value: 'value2'}], true);
|
||||
equal(writer.getContent(), '<img attr1="value1" attr2="value2" />');
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.start('br', null, true);
|
||||
equal(writer.getContent(), '<br />');
|
||||
});
|
||||
|
||||
test('End', function() {
|
||||
var writer;
|
||||
|
||||
expect(1);
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.end('b');
|
||||
equal(writer.getContent(), '</b>');
|
||||
});
|
||||
|
||||
test('Indentation', function() {
|
||||
var writer;
|
||||
|
||||
expect(2);
|
||||
|
||||
writer = new tinymce.html.Writer({indent: true, indent_before: 'p', indent_after:'p'});
|
||||
writer.start('p');
|
||||
writer.start('span');
|
||||
writer.text('a');
|
||||
writer.end('span');
|
||||
writer.end('p');
|
||||
writer.start('p');
|
||||
writer.text('a');
|
||||
writer.end('p');
|
||||
equal(writer.getContent(), '<p><span>a</span></p>\n<p>a</p>');
|
||||
|
||||
writer = new tinymce.html.Writer({indent: true, indent_before: 'p', indent_after:'p'});
|
||||
writer.start('p');
|
||||
writer.text('a');
|
||||
writer.end('p');
|
||||
equal(writer.getContent(), '<p>a</p>');
|
||||
});
|
||||
|
||||
test('Entities', function() {
|
||||
var writer;
|
||||
|
||||
expect(3);
|
||||
|
||||
writer = new tinymce.html.Writer();
|
||||
writer.start('p', [{name: "title", value: '<>"\'&\u00e5\u00e4\u00f6'}]);
|
||||
writer.text('<>"\'&\u00e5\u00e4\u00f6');
|
||||
writer.end('p');
|
||||
equal(writer.getContent(), '<p title="<>"\'&\u00e5\u00e4\u00f6"><>"\'&\u00e5\u00e4\u00f6</p>');
|
||||
|
||||
writer = new tinymce.html.Writer({entity_encoding: 'numeric'});
|
||||
writer.start('p', [{name: "title", value: '<>"\'&\u00e5\u00e4\u00f6'}]);
|
||||
writer.text('<>"\'&\u00e5\u00e4\u00f6');
|
||||
writer.end('p');
|
||||
equal(writer.getContent(), '<p title="<>"\'&åäö"><>"\'&åäö</p>');
|
||||
|
||||
writer = new tinymce.html.Writer({entity_encoding: 'named'});
|
||||
writer.start('p', [{name: "title", value: '<>"\'&\u00e5\u00e4\u00f6'}]);
|
||||
writer.text('<>"\'&\u00e5\u00e4\u00f6');
|
||||
writer.end('p');
|
||||
equal(writer.getContent(), '<p title="<>"\'&åäö"><>"\'&åäö</p>');
|
||||
});
|
||||
@ -1,94 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1,8 +0,0 @@
|
||||
ModuleLoader.require(["tinymce/text/ExtendingChar"], function(ExtendingChar) {
|
||||
module("tinymce.text.ExtendingChar");
|
||||
|
||||
test('isExtendingChar', function() {
|
||||
strictEqual(ExtendingChar.isExtendingChar('a'), false);
|
||||
strictEqual(ExtendingChar.isExtendingChar('\u0301'), true);
|
||||
});
|
||||
});
|
||||
@ -1,15 +0,0 @@
|
||||
ModuleLoader.require(["tinymce/text/Zwsp"], function(Zwsp) {
|
||||
module("tinymce.text.Zwsp");
|
||||
|
||||
test('ZWSP', function() {
|
||||
strictEqual(Zwsp.ZWSP, '\uFEFF');
|
||||
});
|
||||
|
||||
test('isZwsp', function() {
|
||||
strictEqual(Zwsp.isZwsp(Zwsp.ZWSP), true);
|
||||
});
|
||||
|
||||
test('isZwsp', function() {
|
||||
strictEqual(Zwsp.trim('a' + Zwsp.ZWSP + 'b'), 'ab');
|
||||
});
|
||||
});
|
||||
@ -1,31 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.ui.AbsoluteLayout", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function createPanel(settings) {
|
||||
return tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: 'panel',
|
||||
layout: 'absolute',
|
||||
width: 200,
|
||||
height: 200
|
||||
}, settings)).renderTo(document.getElementById('view')).reflow();
|
||||
}
|
||||
|
||||
test("spacer x:10, y:20, minWidth: 100, minHeight: 100", function() {
|
||||
var panel = createPanel({
|
||||
items: [
|
||||
{type: 'spacer', x: 10, y: 20, w: 100, h: 120, classes: 'red'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 200, 200]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [10, 20, 100, 120]);
|
||||
});
|
||||
})();
|
||||
@ -1,104 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.ui.Button", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function createButton(settings) {
|
||||
return tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: 'button'
|
||||
}, settings)).renderTo(document.getElementById('view'));
|
||||
}
|
||||
|
||||
test("button text, size default", function() {
|
||||
var button = createButton({text: 'X'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(button), [0, 0, 27, 30], 4);
|
||||
});
|
||||
|
||||
test("button text, size large", function() {
|
||||
var button = createButton({text: 'X', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(button), [0, 0, 41, 39], 4);
|
||||
});
|
||||
|
||||
test("button text, size small", function() {
|
||||
var button = createButton({text: 'X', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(button), [0, 0, 19, 23], 4);
|
||||
});
|
||||
|
||||
test("button text, width 100, height 100", function() {
|
||||
var button = createButton({text: 'X', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(button), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(button.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("button icon, size default", function() {
|
||||
var button = createButton({icon: 'test'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(button), [0, 0, 34, 30], 4);
|
||||
});
|
||||
|
||||
test("button icon, size small", function() {
|
||||
var button = createButton({icon: 'test', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(button), [0, 0, 28, 24], 4);
|
||||
});
|
||||
|
||||
test("button icon, size large", function() {
|
||||
var button = createButton({icon: 'test', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(button), [0, 0, 44, 40], 4);
|
||||
});
|
||||
|
||||
test("button icon, width 100, height 100", function() {
|
||||
var button = createButton({icon: 'test', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(button), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(button.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("button text & icon, size default", function() {
|
||||
var button = createButton({text: 'X', icon: 'test'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(button), [0, 0, 47, 30], 4);
|
||||
});
|
||||
|
||||
test("button text & icon, size large", function() {
|
||||
var button = createButton({text: 'X', icon: 'test', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(button), [0, 0, 59, 40], 4);
|
||||
});
|
||||
|
||||
test("button text & icon, size small", function() {
|
||||
var button = createButton({text: 'X', icon: 'test', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(button), [0, 0, 38, 24], 4);
|
||||
});
|
||||
|
||||
test("button text & icon, width 100, height 100", function() {
|
||||
var button = createButton({text: 'X', icon: 'test', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(button), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(button.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("button click event", function() {
|
||||
var button, clicks = {};
|
||||
|
||||
button = createButton({text: 'X', onclick: function() {clicks.a = 'a';}});
|
||||
button.on('click', function() {clicks.b = 'b';});
|
||||
button.on('click', function() {clicks.c = 'c';});
|
||||
button.fire('click');
|
||||
|
||||
deepEqual(clicks, {a: 'a', b: 'b', c: 'c'});
|
||||
});
|
||||
})();
|
||||
|
||||
@ -1,253 +0,0 @@
|
||||
(function() {
|
||||
var panel;
|
||||
|
||||
module("tinymce.ui.Collection", {
|
||||
setupModule: function() {
|
||||
panel = tinymce.ui.Factory.create({
|
||||
type: 'panel',
|
||||
items: [
|
||||
{type: 'button', name: 'button1', text: 'button1', classes: 'class1', disabled: true},
|
||||
{type: 'button', name: 'button2', classes: 'class1 class2'},
|
||||
{type: 'button', name: 'button3', classes: 'class2 class1 class3'},
|
||||
|
||||
{type: 'buttongroup', name: 'buttongroup1', items: [
|
||||
{type: 'button', name: 'button4'},
|
||||
{type: 'button', name: 'button5'},
|
||||
{type: 'button', name: 'button6'}
|
||||
]},
|
||||
|
||||
{type: 'buttongroup', name: 'buttongroup2', items: [
|
||||
{type: 'button', name: 'button7'},
|
||||
{type: 'button', name: 'button8'},
|
||||
{type: 'button', name: 'button9'}
|
||||
]},
|
||||
|
||||
{type: 'toolbar', name: 'toolbar1', items: [
|
||||
{type: 'buttongroup', name: 'buttongroup3', items: [
|
||||
{type: 'button', name: 'button10', disabled: true},
|
||||
{type: 'button', name: 'button11'},
|
||||
{type: 'button', name: 'button12', classes: 'class4'}
|
||||
]}
|
||||
]}
|
||||
]
|
||||
}).renderTo(document.getElementById('view'));
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
test("Constructor", function() {
|
||||
equal(new tinymce.ui.Collection().length, 0);
|
||||
equal(new tinymce.ui.Collection(panel.find('button').toArray()).length, 12);
|
||||
equal(new tinymce.ui.Collection(panel.find('button')).length, 12);
|
||||
equal(new tinymce.ui.Collection(panel.find('button:first')[0]).length, 1);
|
||||
equal(new tinymce.ui.Collection(panel.find('button:first')[0])[0].type, 'button');
|
||||
});
|
||||
|
||||
test("add", function() {
|
||||
var collection = new tinymce.ui.Collection([panel, panel]);
|
||||
|
||||
equal(collection.add(panel).length, 3);
|
||||
equal(collection.add([panel, panel]).length, 5);
|
||||
});
|
||||
|
||||
test("set", function() {
|
||||
var collection = new tinymce.ui.Collection([panel, panel]);
|
||||
|
||||
equal(collection.set(panel).length, 1);
|
||||
equal(collection.set([panel, panel]).length, 2);
|
||||
});
|
||||
|
||||
test("filter", function() {
|
||||
equal(panel.find('button').filter('*:first').length, 4);
|
||||
equal(panel.find('button').filter('buttongroup button').length, 9);
|
||||
equal(panel.find('button').filter('*').length, 12);
|
||||
equal(panel.find('button').filter('nomatch').length, 0);
|
||||
equal(panel.find('button').filter(function(ctrl) {return ctrl.settings.name == "button7";}).length, 1);
|
||||
});
|
||||
|
||||
test("slice", function() {
|
||||
equal(panel.find('button').slice(1).length, 11);
|
||||
equal(panel.find('button').slice(1)[0].name(), 'button2');
|
||||
|
||||
equal(panel.find('button').slice(0, 1).length, 1);
|
||||
equal(panel.find('button').slice(0, 1)[0].name(), 'button1');
|
||||
|
||||
equal(panel.find('button').slice(-1).length, 1);
|
||||
equal(panel.find('button').slice(-1)[0].name(), 'button12');
|
||||
|
||||
equal(panel.find('button').slice(-2).length, 2);
|
||||
equal(panel.find('button').slice(-2)[0].name(), 'button11');
|
||||
|
||||
equal(panel.find('button').slice(-2, -1).length, 1);
|
||||
equal(panel.find('button').slice(-2, -1)[0].name(), 'button11');
|
||||
|
||||
equal(panel.find('button').slice(1000).length, 0);
|
||||
equal(panel.find('button').slice(-1000).length, 12);
|
||||
});
|
||||
|
||||
test("eq", function() {
|
||||
equal(panel.find('button').eq(1).length, 1);
|
||||
equal(panel.find('button').eq(1)[0].name(), 'button2');
|
||||
|
||||
equal(panel.find('button').eq(-2).length, 1);
|
||||
equal(panel.find('button').eq(-2)[0].name(), 'button11');
|
||||
|
||||
equal(panel.find('button').eq(1000).length, 0);
|
||||
});
|
||||
|
||||
test("each", function() {
|
||||
var count;
|
||||
|
||||
count = 0;
|
||||
panel.find('button').each(function() {
|
||||
count++;
|
||||
});
|
||||
|
||||
equal(count, 12);
|
||||
|
||||
count = 0;
|
||||
panel.find('nomatch').each(function() {
|
||||
count++;
|
||||
});
|
||||
|
||||
equal(count, 0);
|
||||
|
||||
count = 0;
|
||||
panel.find('button').each(function(item, index) {
|
||||
count += index;
|
||||
});
|
||||
|
||||
equal(count, 66);
|
||||
|
||||
count = 0;
|
||||
panel.find('button').each(function(item) {
|
||||
if (item.type == 'button') {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
equal(count, 12);
|
||||
|
||||
count = 0;
|
||||
panel.find('button').each(function(item, index) {
|
||||
count++;
|
||||
|
||||
if (index == 3) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
equal(count, 4);
|
||||
});
|
||||
|
||||
test("toArray", function() {
|
||||
equal(panel.find('button').toArray().length, 12);
|
||||
equal(panel.find('button').toArray().concat, Array.prototype.concat);
|
||||
});
|
||||
|
||||
test("fire/on/off", function() {
|
||||
var value;
|
||||
|
||||
value = 0;
|
||||
panel.find('button').off();
|
||||
panel.find('button#button1,button#button2').on('test', function(args) {
|
||||
value += args.value;
|
||||
});
|
||||
panel.find('button#button1').fire('test', {value: 42});
|
||||
equal(value, 42);
|
||||
|
||||
value = 0;
|
||||
panel.find('button').off();
|
||||
panel.find('button#button1,button#button2').on('test', function(args) {
|
||||
value += args.value;
|
||||
});
|
||||
panel.find('button').fire('test', {value: 42});
|
||||
equal(value, 84);
|
||||
|
||||
value = 0;
|
||||
panel.find('button').off();
|
||||
panel.find('button#button1,button#button2').on('test', function(args) {
|
||||
value += args.value;
|
||||
});
|
||||
panel.find('button#button1').off('test');
|
||||
panel.find('button').fire('test', {value: 42});
|
||||
equal(value, 42);
|
||||
|
||||
panel.find('button').off();
|
||||
|
||||
value = 0;
|
||||
panel.find('button').fire('test', {value: 42});
|
||||
equal(value, 0);
|
||||
});
|
||||
|
||||
test("show/hide", function() {
|
||||
panel.find('button#button1,button#button2').hide();
|
||||
equal(panel.find('button:not(:visible)').length, 2);
|
||||
|
||||
panel.find('button#button1').show();
|
||||
equal(panel.find('button:not(:visible)').length, 1);
|
||||
|
||||
panel.find('button#button2').show();
|
||||
});
|
||||
|
||||
test("text", function() {
|
||||
equal(panel.find('button#button1,button#button2').text(), 'button1');
|
||||
equal(panel.find('button#button2').text('button2').text(), 'button2');
|
||||
|
||||
equal(panel.find('button#button2,button#button3').text('test').text(), 'test');
|
||||
equal(panel.find('button#button3').text(), 'test');
|
||||
});
|
||||
|
||||
test("disabled", function() {
|
||||
ok(panel.find('button#button1').disabled());
|
||||
ok(!panel.find('button#button2').disabled());
|
||||
ok(panel.find('button#button2').disabled(true).disabled());
|
||||
|
||||
panel.find('button#button2').disabled(false);
|
||||
});
|
||||
|
||||
test("visible", function() {
|
||||
ok(panel.find('button#button2').visible());
|
||||
ok(!panel.find('button#button2').visible(false).visible());
|
||||
|
||||
panel.find('button#button2').visible(true);
|
||||
});
|
||||
|
||||
test("active", function() {
|
||||
ok(!panel.find('button#button2').active());
|
||||
ok(panel.find('button#button2').active(true).active());
|
||||
|
||||
panel.find('button#button2').active(false);
|
||||
});
|
||||
|
||||
test("name", function() {
|
||||
equal(panel.find('button#button1').name(), 'button1');
|
||||
equal(panel.find('button#button2').name('buttonX').name(), 'buttonX');
|
||||
|
||||
panel.find('button#buttonX').name('button2');
|
||||
});
|
||||
|
||||
test("addClass/removeClass/hasClass", function() {
|
||||
panel.find('button#button1').addClass('test');
|
||||
ok(panel.find('button#button1').hasClass('test'));
|
||||
ok(!panel.find('button#button1').hasClass('nomatch'));
|
||||
panel.find('button#button1').removeClass('test');
|
||||
ok(!panel.find('button#button1').hasClass('test'));
|
||||
});
|
||||
|
||||
test("prop", function() {
|
||||
ok(panel.find('button#button1').prop('disabled'));
|
||||
equal(panel.find('button#button1').prop('name'), 'button1');
|
||||
equal(panel.find('button#button1').prop('name', 'buttonX').prop('name'), 'buttonX');
|
||||
panel.find('button#buttonX').prop('name', 'button1');
|
||||
equal(panel.find('button#button1').prop('missingProperty'), undefined);
|
||||
});
|
||||
|
||||
test("exec", function() {
|
||||
ok(!panel.find('button#button1').exec('disabled', false).disabled());
|
||||
panel.find('button#button1').disabled(true);
|
||||
});
|
||||
})();
|
||||
@ -1,102 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.ui.ColorButton", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function createColorButton(settings) {
|
||||
return tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: 'colorbutton'
|
||||
}, settings)).renderTo(document.getElementById('view'));
|
||||
}
|
||||
|
||||
test("colorbutton text, size default", function() {
|
||||
var colorButton = createColorButton({text: 'X'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(colorButton), [0, 0, 42, 30], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text, size large", function() {
|
||||
var colorButton = createColorButton({text: 'X', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(colorButton), [0, 0, 44, 39], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text, size small", function() {
|
||||
var colorButton = createColorButton({text: 'X', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(colorButton), [0, 0, 39, 23], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text, width 100, height 100", function() {
|
||||
var colorButton = createColorButton({text: 'X', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(colorButton), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(colorButton.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("colorbutton icon, size default", function() {
|
||||
var colorButton = createColorButton({icon: 'test'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(colorButton), [0, 0, 49, 30], 4);
|
||||
});
|
||||
|
||||
test("colorbutton icon, size small", function() {
|
||||
var colorButton = createColorButton({icon: 'test', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(colorButton), [0, 0, 43, 24], 4);
|
||||
});
|
||||
|
||||
test("colorbutton icon, size large", function() {
|
||||
var colorButton = createColorButton({icon: 'test', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(colorButton), [0, 0, 49, 40], 4);
|
||||
});
|
||||
|
||||
test("colorbutton icon, width 100, height 100", function() {
|
||||
var colorButton = createColorButton({icon: 'test', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(colorButton), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(colorButton.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("colorbutton text & icon, size default", function() {
|
||||
var colorButton = createColorButton({text: 'X', icon: 'test'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(colorButton), [0, 0, 62, 30], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text & icon, size large", function() {
|
||||
var colorButton = createColorButton({text: 'X', icon: 'test', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(colorButton), [0, 0, 64, 40], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text & icon, size small", function() {
|
||||
var colorButton = createColorButton({text: 'X', icon: 'test', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(colorButton), [0, 0, 58, 24], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text & icon, width 100, height 100", function() {
|
||||
var colorButton = createColorButton({text: 'X', icon: 'test', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(colorButton), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(colorButton.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("colorbutton click event", function() {
|
||||
var colorButton, clicks = {};
|
||||
|
||||
colorButton = createColorButton({text: 'X', onclick: function() {clicks.a = 'a';}});
|
||||
colorButton.renderTo(document.getElementById('view'));
|
||||
colorButton.fire('click', {target: colorButton.getEl()});
|
||||
|
||||
deepEqual(clicks, {a: 'a'});
|
||||
});
|
||||
})();
|
||||
@ -1,204 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.ui.Control");
|
||||
|
||||
test("Initial states", function() {
|
||||
var ctrl;
|
||||
|
||||
ctrl = new tinymce.ui.Control({});
|
||||
|
||||
// Check initial states
|
||||
equal(ctrl.disabled(), false);
|
||||
equal(ctrl.active(), false);
|
||||
equal(ctrl.visible(), true);
|
||||
equal(ctrl.text(), undefined);
|
||||
equal(ctrl.name(), undefined);
|
||||
equal(ctrl.title(), undefined);
|
||||
equal(ctrl.parent(), undefined);
|
||||
deepEqual(ctrl.settings, {});
|
||||
});
|
||||
|
||||
test("Settings", function() {
|
||||
var ctrl = new tinymce.ui.Control({
|
||||
disabled: true,
|
||||
active: true,
|
||||
visible: true,
|
||||
text: 'Text',
|
||||
title: 'Title',
|
||||
name: 'Name'
|
||||
});
|
||||
|
||||
// Check settings states
|
||||
equal(ctrl.disabled(), true);
|
||||
equal(ctrl.active(), true);
|
||||
equal(ctrl.visible(), true);
|
||||
equal(ctrl.text(), "Text");
|
||||
equal(ctrl.name(), "Name");
|
||||
equal(ctrl.title(), "Title");
|
||||
equal(ctrl.parent(), undefined);
|
||||
deepEqual(ctrl.settings, {
|
||||
disabled: true,
|
||||
active: true,
|
||||
visible: true,
|
||||
text: 'Text',
|
||||
title: 'Title',
|
||||
name: 'Name'
|
||||
});
|
||||
});
|
||||
|
||||
test("Properties", function() {
|
||||
var ctrl, cont;
|
||||
|
||||
cont = new tinymce.ui.Container({});
|
||||
ctrl = new tinymce.ui.Control({});
|
||||
|
||||
// Set all states
|
||||
ctrl = ctrl.
|
||||
disabled(true).
|
||||
active(true).
|
||||
visible(true).
|
||||
text("Text").
|
||||
title("Title").
|
||||
name("Name").parent(cont);
|
||||
|
||||
// Check states
|
||||
equal(ctrl.disabled(), true);
|
||||
equal(ctrl.active(), true);
|
||||
equal(ctrl.visible(), true);
|
||||
equal(ctrl.text(), "Text");
|
||||
equal(ctrl.name(), "Name");
|
||||
equal(ctrl.title(), "Title");
|
||||
equal(ctrl.parent(), cont);
|
||||
deepEqual(ctrl.settings, {});
|
||||
});
|
||||
|
||||
test("Chained methods", function() {
|
||||
var ctrl = new tinymce.ui.Control({});
|
||||
|
||||
// Set all states
|
||||
ctrl = ctrl.
|
||||
on('click', function() {}).
|
||||
off().
|
||||
renderTo(document.getElementById('view')).
|
||||
remove();
|
||||
|
||||
// Check so that the chain worked
|
||||
ok(ctrl instanceof tinymce.ui.Control);
|
||||
});
|
||||
|
||||
test("Events", function() {
|
||||
var ctrl = new tinymce.ui.Control({
|
||||
onMyEvent: function() {
|
||||
count++;
|
||||
},
|
||||
callbacks: {
|
||||
handler1: function() {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}), count;
|
||||
|
||||
ctrl.on('MyEvent', function(args) {
|
||||
equal(ctrl, args.control);
|
||||
equal(ctrl, this);
|
||||
equal(args.myKey, 'myVal');
|
||||
});
|
||||
|
||||
ctrl.fire('MyEvent', {myKey: 'myVal'});
|
||||
|
||||
function countAndBreak() {
|
||||
count++;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bind two events
|
||||
ctrl.on('MyEvent2', countAndBreak);
|
||||
ctrl.on('MyEvent2', countAndBreak);
|
||||
|
||||
// Check if only one of them was called
|
||||
count = 0;
|
||||
ctrl.fire('MyEvent2', {myKey: 'myVal'});
|
||||
equal(count, 1);
|
||||
|
||||
// Fire unbound event
|
||||
ctrl.fire('MyEvent3', {myKey: 'myVal'});
|
||||
|
||||
// Unbind all
|
||||
ctrl.off();
|
||||
count = 0;
|
||||
ctrl.fire('MyEvent2', {myKey: 'myVal'});
|
||||
equal(count, 0, 'Unbind all');
|
||||
|
||||
// Unbind by name
|
||||
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.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.off();
|
||||
ctrl.on('MyEvent', 'handler1');
|
||||
count = 0;
|
||||
ctrl.fire('MyEvent', {myKey: 'myVal'});
|
||||
equal(count, 1);
|
||||
});
|
||||
|
||||
test("hasClass,addClass,removeClass", function() {
|
||||
var ctrl = new tinymce.ui.Control({classes: 'class1 class2 class3'});
|
||||
|
||||
equal(ctrl.classes, 'mce-class1 mce-class2 mce-class3');
|
||||
ok(ctrl.classes.contains('class1'));
|
||||
ok(ctrl.classes.contains('class2'));
|
||||
ok(ctrl.classes.contains('class3'));
|
||||
ok(!ctrl.classes.contains('class4'));
|
||||
|
||||
ctrl.classes.add('class4');
|
||||
equal(ctrl.classes, 'mce-class1 mce-class2 mce-class3 mce-class4');
|
||||
ok(ctrl.classes.contains('class1'));
|
||||
ok(ctrl.classes.contains('class2'));
|
||||
ok(ctrl.classes.contains('class3'));
|
||||
ok(ctrl.classes.contains('class4'));
|
||||
|
||||
ctrl.classes.remove('class4');
|
||||
equal(ctrl.classes, 'mce-class1 mce-class2 mce-class3');
|
||||
ok(ctrl.classes.contains('class1'));
|
||||
ok(ctrl.classes.contains('class2'));
|
||||
ok(ctrl.classes.contains('class3'));
|
||||
ok(!ctrl.classes.contains('class4'));
|
||||
|
||||
ctrl.classes.remove('class3').remove('class2');
|
||||
equal(ctrl.classes, 'mce-class1');
|
||||
ok(ctrl.classes.contains('class1'));
|
||||
ok(!ctrl.classes.contains('class2'));
|
||||
ok(!ctrl.classes.contains('class3'));
|
||||
|
||||
ctrl.classes.remove('class3').remove('class1');
|
||||
equal(ctrl.classes, '');
|
||||
ok(!ctrl.classes.contains('class1'));
|
||||
ok(!ctrl.classes.contains('class2'));
|
||||
ok(!ctrl.classes.contains('class3'));
|
||||
});
|
||||
|
||||
test("encode", function() {
|
||||
tinymce.i18n.add('en', {'old': '"new"'});
|
||||
equal(new tinymce.ui.Control({}).encode('<>"&'), '<>"&');
|
||||
equal(new tinymce.ui.Control({}).encode('old'), '"new"');
|
||||
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');
|
||||
});
|
||||
})();
|
||||
@ -1,260 +0,0 @@
|
||||
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();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,57 +0,0 @@
|
||||
(function() {
|
||||
var panel;
|
||||
|
||||
module("tinymce.ui.FitLayout", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function createFitPanel(settings) {
|
||||
return tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: 'panel',
|
||||
layout: 'fit',
|
||||
width: 200,
|
||||
height: 200,
|
||||
border: 1
|
||||
}, settings)).renderTo(document.getElementById('view')).reflow();
|
||||
}
|
||||
|
||||
test("fit with spacer inside", function() {
|
||||
panel = createFitPanel({
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 200, 200]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [1, 1, 198, 198]);
|
||||
});
|
||||
|
||||
test("fit with padding and spacer inside", function() {
|
||||
panel = createFitPanel({
|
||||
padding: 3,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 200, 200]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [4, 4, 192, 192]);
|
||||
});
|
||||
|
||||
test("fit with panel inside", function() {
|
||||
panel = createFitPanel({
|
||||
items: [
|
||||
{type: 'panel', border: 1}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 200, 200]);
|
||||
deepEqual(Utils.rect(panel.find('panel')[0]), [1, 1, 198, 198]);
|
||||
});
|
||||
})();
|
||||
@ -1,884 +0,0 @@
|
||||
(function() {
|
||||
var panel;
|
||||
|
||||
module("tinymce.ui.FlexLayout", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function renderPanel(settings) {
|
||||
var panel = tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: "panel",
|
||||
layout: "flex",
|
||||
width: 200, height: 200,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red'},
|
||||
{type: 'spacer', classes: 'green'},
|
||||
{type: 'spacer', classes: 'blue'}
|
||||
]
|
||||
}, settings)).renderTo(document.getElementById('view')).reflow();
|
||||
|
||||
Utils.resetScroll(panel.getEl('body'));
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
test("pack: default, align: default, flex: default", function() {
|
||||
panel = renderPanel({});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [20, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [40, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: default, align: default, flex: default, borders", function() {
|
||||
panel = renderPanel({defaults: {border: 1}});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 22, 22]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [22, 0, 22, 22]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [44, 0, 22, 22]);
|
||||
});
|
||||
|
||||
test("pack: default, flex: 1", function() {
|
||||
panel = renderPanel({
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [67, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [133, 0, 67, 20]);
|
||||
});
|
||||
|
||||
test("pack: default, flex: 1, minWidth: various", function() {
|
||||
panel = renderPanel({
|
||||
defaults: {flex: 1},
|
||||
items: [
|
||||
{type: 'spacer', minWidth: 25, classes: 'red'},
|
||||
{type: 'spacer', minWidth: 30, classes: 'green'},
|
||||
{type: 'spacer', minWidth: 35, classes: 'blue'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 62, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [62, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [128, 0, 72, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, flex: default", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [20, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [40, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, flex: 1", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [67, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [133, 0, 67, 20]);
|
||||
});
|
||||
|
||||
test("pack: end, flex: default", function() {
|
||||
panel = renderPanel({
|
||||
pack: "end"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [140, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [160, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [180, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: end, flex: 1", function() {
|
||||
panel = renderPanel({
|
||||
pack: "end",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [67, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [133, 0, 67, 20]);
|
||||
});
|
||||
|
||||
test("pack: center, flex: default", function() {
|
||||
panel = renderPanel({
|
||||
pack: "center"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [70, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [90, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [110, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: center, flex: 1", function() {
|
||||
panel = renderPanel({
|
||||
pack: "center",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [67, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [133, 0, 67, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, spacing: 3", function() {
|
||||
panel = renderPanel({
|
||||
layout: "flex",
|
||||
pack: "start",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [23, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [46, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: end, spacing: 3", function() {
|
||||
panel = renderPanel({
|
||||
pack: "end",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [134, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [157, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [180, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: center, spacing: 3", function() {
|
||||
panel = renderPanel({
|
||||
pack: "center",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [67, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [90, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [113, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, padding: 3", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
padding: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [23, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [43, 3, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, spacing: 3, padding: 3", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
padding: 3,
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [26, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [49, 3, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, align: start", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
align: "start"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [20, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [40, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack start, align: center", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
align: "center"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 90, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [20, 90, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [40, 90, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, align: end", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
align: "end"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 180, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [20, 180, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [40, 180, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, align: stretch", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
align: "stretch"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 200]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [20, 0, 20, 200]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [40, 0, 20, 200]);
|
||||
});
|
||||
|
||||
test("pack: start, padding: 3, align: stretch", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
align: "stretch",
|
||||
padding: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 194]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [23, 3, 20, 194]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [43, 3, 20, 194]);
|
||||
});
|
||||
|
||||
test("pack: start, flex: mixed values", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 0.3},
|
||||
{type: 'spacer', classes: 'green', flex: 1},
|
||||
{type: 'spacer', classes: 'blue', flex: 0.5}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 43, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [43, 0, 98, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [141, 0, 59, 20]);
|
||||
});
|
||||
|
||||
test("pack: justify", function() {
|
||||
panel = renderPanel({
|
||||
pack: "justify"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [90, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [180, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: justify, padding: 3", function() {
|
||||
panel = renderPanel({
|
||||
pack: "justify",
|
||||
padding: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [90, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [177, 3, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: justify, minWidth: mixed values, padding: 3", function() {
|
||||
panel = renderPanel({
|
||||
pack: "justify",
|
||||
padding: 3,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red'},
|
||||
{type: 'spacer', classes: 'green', minWidth: 80},
|
||||
{type: 'spacer', classes: 'blue', minWidth: 50}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [45, 3, 80, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [147, 3, 50, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, flex: 1, maxWidth: 80 on second", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
width: 400,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1},
|
||||
{type: 'spacer', classes: 'green', maxWidth: 80, flex: 1},
|
||||
{type: 'spacer', classes: 'blue', flex: 1}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 160, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [160, 0, 80, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [240, 0, 160, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, flex: 1, minWidth: 150 on second", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
width: 400,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1},
|
||||
{type: 'spacer', classes: 'green', minWidth: 150, flex: 1},
|
||||
{type: 'spacer', classes: 'blue', flex: 1}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 90, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [90, 0, 220, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [310, 0, 90, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, flex: default, hide item and reflow", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
autoResize: true,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red'},
|
||||
{type: 'spacer', classes: 'green'},
|
||||
{type: 'spacer', classes: 'blue'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [20, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [40, 0, 20, 20]);
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 60, 20]);
|
||||
panel.items().eq(0).hide();
|
||||
panel.reflow();
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 40, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, flex: 1, reflow after resize outer width", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1},
|
||||
{type: 'spacer', classes: 'green', flex: 1},
|
||||
{type: 'spacer', classes: 'blue', flex: 1}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [67, 0, 67, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [133, 0, 67, 20]);
|
||||
|
||||
panel.layoutRect({w: 400, h: 400}).reflow();
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 400, 400]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 133, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [133, 0, 133, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [267, 0, 133, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, maxWidth/maxHeight: 100, item minWidth/maxHeight: 200 (overflow W+H)", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
autoResize: true,
|
||||
autoScroll: true,
|
||||
maxWidth: 100,
|
||||
maxHeight: 100,
|
||||
items: [
|
||||
{type: 'spacer', minWidth: 200, minHeight: 200, classes: 'red dotted'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 100, 100]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 200, 200]);
|
||||
equal(panel.layoutRect().contentW, 200);
|
||||
equal(panel.layoutRect().contentH, 200);
|
||||
});
|
||||
|
||||
test("pack: start, direction: column, maxWidth/maxHeight: 100, padding: 20, spacing: 10, item minWidth/maxHeight: 200 (overflow W+H)", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
direction: "column",
|
||||
autoResize: true,
|
||||
autoScroll: true,
|
||||
maxWidth: 100,
|
||||
maxHeight: 100,
|
||||
padding: 20,
|
||||
spacing: 10,
|
||||
items: [
|
||||
{type: 'spacer', minWidth: 100, minHeight: 100, classes: 'red dotted'},
|
||||
{type: 'spacer', minWidth: 100, minHeight: 100, classes: 'green dotted'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 100, 100]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [20, 20, 100, 100]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [20, 130, 100, 100]);
|
||||
equal(panel.layoutRect().contentW, 20 + 100 + 20);
|
||||
equal(panel.layoutRect().contentH, 20 + 100 + 10 + 100 + 20);
|
||||
});
|
||||
|
||||
test("pack: start, maxWidth/maxHeight: 100, item minWidth/maxHeight: 200 (overflow W)", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
autoResize: true,
|
||||
autoScroll: true,
|
||||
maxWidth: 100,
|
||||
items: [
|
||||
{type: 'spacer', minWidth: 200, minHeight: 200, classes: 'red dotted'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 200, 200]);
|
||||
equal(panel.layoutRect().contentW, 200);
|
||||
equal(panel.layoutRect().contentH, 200);
|
||||
});
|
||||
|
||||
test("pack: start, maxWidth/maxHeight: 100, item minWidth/maxHeight: 200 (overflow H)", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
autoResize: true,
|
||||
autoScroll: true,
|
||||
maxHeight: 100,
|
||||
items: [
|
||||
{type: 'spacer', minWidth: 200, minHeight: 200, classes: 'red dotted'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 200, 200]);
|
||||
equal(panel.layoutRect().contentW, 200);
|
||||
equal(panel.layoutRect().contentH, 200);
|
||||
});
|
||||
|
||||
test("pack: start, minWidth: 200, item minWidth: 100 (underflow)", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
autoResize: true,
|
||||
minWidth: 200,
|
||||
items: [
|
||||
{type: 'spacer', minWidth: 100, classes: 'red'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 200, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 100, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, flex: 1, border: 1, reflow after resize inner width", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
border: 1,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1}
|
||||
]
|
||||
});
|
||||
|
||||
panel.layoutRect({innerW: 400, innerH: 400}).reflow();
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 402, 402]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [1, 1, 400, 20]);
|
||||
});
|
||||
|
||||
test("row flexbox in row flexbox", function() {
|
||||
panel = tinymce.ui.Factory.create({
|
||||
type: 'panel',
|
||||
layout: 'flex',
|
||||
align: 'end',
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red'},
|
||||
{type: 'panel', layout: 'flex', padding: 10, spacing: 10, items: [
|
||||
{type: 'spacer', classes: 'yellow'},
|
||||
{type: 'spacer', classes: 'magenta'}
|
||||
]},
|
||||
{type: 'spacer', classes: 'green'}
|
||||
]
|
||||
}).renderTo(document.getElementById('view')).reflow();
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 110, 40]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find("panel")[0]), [20, 0, 70, 40]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 20, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [30, 10, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [60, 10, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[3]), [90, 20, 20, 20]);
|
||||
});
|
||||
|
||||
test("row flexbox in row flexbox hide inner item and reflow", function() {
|
||||
panel = tinymce.ui.Factory.create({
|
||||
type: 'panel',
|
||||
layout: 'flex',
|
||||
align: 'end',
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red'},
|
||||
{type: 'panel', layout: 'flex', padding: 10, spacing: 10, items: [
|
||||
{type: 'spacer', classes: 'yellow'},
|
||||
{type: 'spacer', classes: 'magenta'}
|
||||
]},
|
||||
{type: 'spacer', classes: 'green'}
|
||||
]
|
||||
}).renderTo(document.getElementById('view')).reflow();
|
||||
|
||||
panel.find('spacer')[1].hide().parent().reflow();
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 80, 40]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find("panel")[0]), [20, 0, 40, 40]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 20, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [30, 10, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[3]), [60, 20, 20, 20]);
|
||||
});
|
||||
|
||||
// Direction column tests
|
||||
|
||||
function renderColumnPanel(settings) {
|
||||
settings.direction = "column";
|
||||
return renderPanel(settings);
|
||||
}
|
||||
|
||||
test("direction: column, pack: default, align: default, flex: default", function() {
|
||||
panel = renderColumnPanel({});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 20, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 40, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: default, flex: 1", function() {
|
||||
panel = renderColumnPanel({
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 67, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 133, 20, 67]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: default, flex: 1, minWidth: various", function() {
|
||||
panel = renderColumnPanel({
|
||||
defaults: {flex: 1},
|
||||
items: [
|
||||
{type: 'spacer', minHeight: 25, classes: 'red'},
|
||||
{type: 'spacer', minHeight: 30, classes: 'green'},
|
||||
{type: 'spacer', minHeight: 35, classes: 'blue'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 62]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 62, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 128, 20, 72]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, flex: default", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 20, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 40, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, flex: 1", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 67, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 133, 20, 67]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: end, flex: default", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "end"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 140, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 160, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 180, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: end, flex: 1", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "end",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 67, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 133, 20, 67]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: center, flex: default", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "center"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 70, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 90, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 110, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: center, flex: 1", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "center",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 67, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 133, 20, 67]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, spacing: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
layout: "flex",
|
||||
pack: "start",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 23, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 46, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: end, spacing: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "end",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 134, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 157, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 180, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: center, spacing: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "center",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 67, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 90, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 113, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, padding: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
padding: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [3, 23, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [3, 43, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, spacing: 3, padding: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
padding: 3,
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [3, 26, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [3, 49, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, align: start", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
align: "start"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 20, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 40, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack start, align: center", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
align: "center"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [90, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [90, 20, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [90, 40, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, align: end", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
align: "end"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [180, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [180, 20, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [180, 40, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, align: stretch", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
align: "stretch"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 200, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 20, 200, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 40, 200, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, padding: 3, align: stretch", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
align: "stretch",
|
||||
padding: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [3, 3, 194, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [3, 23, 194, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [3, 43, 194, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, flex: mixed values", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 0.3},
|
||||
{type: 'spacer', classes: 'green', flex: 1},
|
||||
{type: 'spacer', classes: 'blue', flex: 0.5}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 43]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 43, 20, 98]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 141, 20, 59]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: justify", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "justify"
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 90, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 180, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: justify, padding: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "justify",
|
||||
padding: 3
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [3, 90, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [3, 177, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: justify, minHeight: mixed values, padding: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "justify",
|
||||
padding: 3,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red'},
|
||||
{type: 'spacer', classes: 'green', minHeight: 80},
|
||||
{type: 'spacer', classes: 'blue', minHeight: 50}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [3, 45, 20, 80]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [3, 147, 20, 50]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, flex: 1, maxHeight: 80 on second", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
height: 400,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1},
|
||||
{type: 'spacer', classes: 'green', maxHeight: 80, flex: 1},
|
||||
{type: 'spacer', classes: 'blue', flex: 1}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 160]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 160, 20, 80]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 240, 20, 160]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, flex: 1, minHeight: 150 on second", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
height: 400,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1},
|
||||
{type: 'spacer', classes: 'green', minHeight: 150, flex: 1},
|
||||
{type: 'spacer', classes: 'blue', flex: 1}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 90]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 90, 20, 220]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 310, 20, 90]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, flex: 1, reflow after resize outer height", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1},
|
||||
{type: 'spacer', classes: 'green', flex: 1},
|
||||
{type: 'spacer', classes: 'blue', flex: 1}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 67, 20, 67]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 133, 20, 67]);
|
||||
|
||||
panel.layoutRect({w: 400, h: 400}).reflow();
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 400, 400]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 133]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [0, 133, 20, 133]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [0, 267, 20, 133]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, flex: 1, border: 1, reflow after resize inner width", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
border: 1,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1}
|
||||
]
|
||||
});
|
||||
|
||||
panel.layoutRect({innerW: 400, innerH: 400}).reflow();
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 402, 402]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [1, 1, 20, 400]);
|
||||
});
|
||||
|
||||
test("direction: column, row flexbox in row flexbox and resize parent", function() {
|
||||
panel = tinymce.ui.Factory.create({
|
||||
type: 'panel',
|
||||
layout: 'flex',
|
||||
align: 'end',
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red'},
|
||||
{type: 'panel', layout: 'flex', padding: 10, spacing: 10, items: [
|
||||
{type: 'spacer', classes: 'yellow'},
|
||||
{type: 'spacer', classes: 'magenta'}
|
||||
]},
|
||||
{type: 'spacer', classes: 'green'}
|
||||
]
|
||||
}).renderTo(document.getElementById('view')).reflow();
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 110, 40]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find("panel")[0]), [20, 0, 70, 40]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[0]), [0, 20, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[1]), [30, 10, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[2]), [60, 10, 20, 20]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.find('spacer')[3]), [90, 20, 20, 20]);
|
||||
});
|
||||
})();
|
||||
@ -1,212 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.ui.GridLayout", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function renderGridPanel(settings) {
|
||||
var panel = tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: "panel",
|
||||
layout: "grid",
|
||||
defaults: {type: 'spacer'}
|
||||
}, settings)).renderTo(document.getElementById('view')).reflow();
|
||||
|
||||
Utils.resetScroll(panel.getEl('body'));
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
test("automatic grid size 2x2", function() {
|
||||
var panel = renderGridPanel({
|
||||
items: [
|
||||
{classes: 'red'}, {classes: 'green'},
|
||||
{classes: 'blue'}, {classes: 'cyan'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 40, 40]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[1]), [20, 0, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[2]), [0, 20, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[3]), [20, 20, 20, 20]);
|
||||
});
|
||||
|
||||
/*
|
||||
test("fixed pixel size, automatic grid size 2x2", function() {
|
||||
panel = renderGridPanel({
|
||||
width: 100, height: 100,
|
||||
align: "center",
|
||||
items: [
|
||||
{classes: 'red'}, {classes: 'green'},
|
||||
{classes: 'blue'}, {classes: 'cyan'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 200, 200]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [0, 0, 17, 22]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[1]), [17, 0, 17, 22]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[2]), [0, 22, 16, 22]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[3]), [17, 22, 17, 22]);
|
||||
});
|
||||
*/
|
||||
|
||||
test("spacing: 3, automatic grid size 2x2", function() {
|
||||
var panel = renderGridPanel({
|
||||
spacing: 3,
|
||||
items: [
|
||||
{classes: 'red'}, {classes: 'green'},
|
||||
{classes: 'blue'}, {classes: 'cyan'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 43, 43]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[1]), [23, 0, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[2]), [0, 23, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[3]), [23, 23, 20, 20]);
|
||||
});
|
||||
|
||||
test("padding: 3, automatic grid size 2x2", function() {
|
||||
var panel = renderGridPanel({
|
||||
padding: 3,
|
||||
items: [
|
||||
{classes: 'red'}, {classes: 'green'},
|
||||
{classes: 'blue'}, {classes: 'cyan'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 46, 46]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[1]), [23, 3, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[2]), [3, 23, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[3]), [23, 23, 20, 20]);
|
||||
});
|
||||
|
||||
test("spacing: 3, padding: 3, automatic grid size 2x2", function() {
|
||||
var panel = renderGridPanel({
|
||||
padding: 3,
|
||||
spacing: 3,
|
||||
items: [
|
||||
{classes: 'red'}, {classes: 'green'},
|
||||
{classes: 'blue'}, {classes: 'cyan'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 49, 49]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[1]), [26, 3, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[2]), [3, 26, 20, 20]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[3]), [26, 26, 20, 20]);
|
||||
});
|
||||
|
||||
test("inner elements 100x100 maxWidth/maxHeight: 118 (overflow W+H)", function() {
|
||||
var panel = renderGridPanel({
|
||||
autoResize: true,
|
||||
autoScroll: true,
|
||||
maxWidth: 118,
|
||||
maxHeight: 118,
|
||||
defaults: {
|
||||
type: 'spacer',
|
||||
minWidth: 100,
|
||||
minHeight: 100
|
||||
},
|
||||
items: [
|
||||
{classes: 'red dotted'}, {classes: 'green dotted'},
|
||||
{classes: 'blue dotted'}, {classes: 'cyan dotted'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 118, 118]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[1]), [100, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[2]), [0, 100, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[3]), [100, 100, 100, 100]);
|
||||
equal(panel.layoutRect().w, 118);
|
||||
equal(panel.layoutRect().h, 118);
|
||||
equal(panel.layoutRect().contentW, 200);
|
||||
equal(panel.layoutRect().contentH, 200);
|
||||
});
|
||||
|
||||
test("inner elements: 100x100, padding: 20, spacing: 10, maxWidth/maxHeight: 118 (overflow W+H)", function() {
|
||||
var panel = renderGridPanel({
|
||||
autoResize: true,
|
||||
autoScroll: true,
|
||||
maxWidth: 118,
|
||||
maxHeight: 118,
|
||||
padding: 20,
|
||||
spacing: 10,
|
||||
defaults: {
|
||||
type: 'spacer',
|
||||
minWidth: 100,
|
||||
minHeight: 100
|
||||
},
|
||||
items: [
|
||||
{classes: 'red dotted'}, {classes: 'green dotted'},
|
||||
{classes: 'blue dotted'}, {classes: 'cyan dotted'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 118, 118]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [20, 20, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[1]), [130, 20, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[2]), [20, 130, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[3]), [130, 130, 100, 100]);
|
||||
equal(panel.layoutRect().w, 118);
|
||||
equal(panel.layoutRect().h, 118);
|
||||
equal(panel.layoutRect().contentW, 20 + 200 + 10 + 20);
|
||||
equal(panel.layoutRect().contentH, 20 + 200 + 10 + 20);
|
||||
});
|
||||
|
||||
test("inner elements 100x100 maxWidth: 118 (overflow W)", function() {
|
||||
var panel = renderGridPanel({
|
||||
autoResize: true,
|
||||
autoScroll: true,
|
||||
maxWidth: 100,
|
||||
defaults: {
|
||||
type: 'spacer',
|
||||
minWidth: 100,
|
||||
minHeight: 100
|
||||
},
|
||||
items: [
|
||||
{classes: 'red dotted'}, {classes: 'green dotted'},
|
||||
{classes: 'blue dotted'}, {classes: 'cyan dotted'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[1]), [100, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[2]), [0, 100, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[3]), [100, 100, 100, 100]);
|
||||
equal(panel.layoutRect().contentW, 200);
|
||||
equal(panel.layoutRect().contentH, 200);
|
||||
});
|
||||
|
||||
test("inner elements 100x100 maxHeight: 118 (overflow H)", function() {
|
||||
var panel = renderGridPanel({
|
||||
autoResize: true,
|
||||
autoScroll: true,
|
||||
maxHeight: 100,
|
||||
defaults: {
|
||||
type: 'spacer',
|
||||
minWidth: 100,
|
||||
minHeight: 100
|
||||
},
|
||||
items: [
|
||||
{classes: 'red dotted'}, {classes: 'green dotted'},
|
||||
{classes: 'blue dotted'}, {classes: 'cyan dotted'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel.find('spacer')[0]), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[1]), [100, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[2]), [0, 100, 100, 100]);
|
||||
deepEqual(Utils.rect(panel.find('spacer')[3]), [100, 100, 100, 100]);
|
||||
equal(panel.layoutRect().contentW, 200);
|
||||
equal(panel.layoutRect().contentH, 200);
|
||||
});
|
||||
})();
|
||||
@ -1,108 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.ui.MenuButton", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function createMenuButton(settings) {
|
||||
return tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: 'menubutton',
|
||||
menu: [
|
||||
{text: '1'},
|
||||
{text: '2'},
|
||||
{text: '3'}
|
||||
]
|
||||
}, settings)).renderTo(document.getElementById('view'));
|
||||
}
|
||||
|
||||
test("menubutton text, size default", function() {
|
||||
var menuButton = createMenuButton({text: 'X'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(menuButton), [0, 0, 39, 30], 4);
|
||||
});
|
||||
|
||||
test("menubutton text, size large", function() {
|
||||
var menuButton = createMenuButton({text: 'X', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(menuButton), [0, 0, 53, 39], 4);
|
||||
});
|
||||
|
||||
test("menubutton text, size small", function() {
|
||||
var menuButton = createMenuButton({text: 'X', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(menuButton), [0, 0, 30, 23], 4);
|
||||
});
|
||||
|
||||
test("menubutton text, width 100, height 100", function() {
|
||||
var menuButton = createMenuButton({text: 'X', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(menuButton), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(menuButton.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("menubutton icon, size default", function() {
|
||||
var menuButton = createMenuButton({icon: 'test'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(menuButton), [0, 0, 46, 30], 4);
|
||||
});
|
||||
|
||||
test("menubutton icon, size small", function() {
|
||||
var menuButton = createMenuButton({icon: 'test', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(menuButton), [0, 0, 39, 24], 4);
|
||||
});
|
||||
|
||||
test("menubutton icon, size large", function() {
|
||||
var menuButton = createMenuButton({icon: 'test', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(menuButton), [0, 0, 56, 40], 6);
|
||||
});
|
||||
|
||||
test("menubutton icon, width 100, height 100", function() {
|
||||
var menuButton = createMenuButton({icon: 'test', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(menuButton), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(menuButton.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("menubutton text & icon, size default", function() {
|
||||
var menuButton = createMenuButton({text: 'X', icon: 'test'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(menuButton), [0, 0, 59, 30], 4);
|
||||
});
|
||||
|
||||
test("menubutton text & icon, size large", function() {
|
||||
var menuButton = createMenuButton({text: 'X', icon: 'test', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(menuButton), [0, 0, 71, 40], 4);
|
||||
});
|
||||
|
||||
test("menubutton text & icon, size small", function() {
|
||||
var menuButton = createMenuButton({text: 'X', icon: 'test', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(menuButton), [0, 0, 49, 24], 4);
|
||||
});
|
||||
|
||||
test("menubutton text & icon, width 100, height 100", function() {
|
||||
var menuButton = createMenuButton({text: 'X', icon: 'test', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(menuButton), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(menuButton.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("menubutton click event", function() {
|
||||
var menuButton, clicks = {};
|
||||
|
||||
menuButton = createMenuButton({text: 'X', onclick: function() {clicks.a = 'a';}});
|
||||
menuButton.on('click', function() {clicks.b = 'b';});
|
||||
menuButton.on('click', function() {clicks.c = 'c';});
|
||||
menuButton.fire('click');
|
||||
|
||||
deepEqual(clicks, {a: 'a', b: 'b', c: 'c'});
|
||||
});
|
||||
})();
|
||||
@ -1,38 +0,0 @@
|
||||
(function() {
|
||||
var panel;
|
||||
|
||||
module("tinymce.ui.Panel", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function createPanel(settings) {
|
||||
return tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: 'panel'
|
||||
}, settings)).renderTo(document.getElementById('view')).reflow();
|
||||
}
|
||||
|
||||
test("panel width: 100, height: 100", function() {
|
||||
panel = createPanel({
|
||||
width: 100,
|
||||
height: 100
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 100, 100], 4);
|
||||
});
|
||||
|
||||
test("panel border: 1, width: 100, height: 100", function() {
|
||||
panel = createPanel({
|
||||
width: 100,
|
||||
height: 100,
|
||||
border: 1
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 100, 100], 4);
|
||||
});
|
||||
})();
|
||||
@ -1,127 +0,0 @@
|
||||
(function() {
|
||||
var panel;
|
||||
|
||||
module("tinymce.ui.Selector", {
|
||||
setupModule: function() {
|
||||
panel = tinymce.ui.Factory.create({
|
||||
type: 'panel',
|
||||
items: [
|
||||
{type: 'button', name: 'button1', text: 'button1', classes: 'class1', disabled: true},
|
||||
{type: 'button', name: 'button2', classes: 'class1 class2'},
|
||||
{type: 'button', name: 'button3', classes: 'class2 class1 class3'},
|
||||
|
||||
{type: 'buttongroup', name: 'buttongroup1', items: [
|
||||
{type: 'button', name: 'button4'},
|
||||
{type: 'button', name: 'button5'},
|
||||
{type: 'button', name: 'button6'}
|
||||
]},
|
||||
|
||||
{type: 'buttongroup', name: 'buttongroup2', items: [
|
||||
{type: 'button', name: 'button7'},
|
||||
{type: 'button', name: 'button8'},
|
||||
{type: 'button', name: 'button9'}
|
||||
]},
|
||||
|
||||
{type: 'toolbar', name: 'toolbar1', items: [
|
||||
{type: 'buttongroup', name: 'buttongroup3', items: [
|
||||
{type: 'button', name: 'button10', disabled: true},
|
||||
{type: 'button', name: 'button11'},
|
||||
{type: 'button', name: 'button12', classes: 'class4'}
|
||||
]}
|
||||
]}
|
||||
]
|
||||
}).renderTo(document.getElementById('view'));
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
test("Basic", function() {
|
||||
var matches;
|
||||
|
||||
matches = panel.find('button');
|
||||
equal(matches.length, 12);
|
||||
equal(matches[0].type, 'button');
|
||||
|
||||
equal(panel.find('Button').length, 12);
|
||||
equal(panel.find('buttongroup').length, 3);
|
||||
equal(panel.find('buttongroup button').length, 9);
|
||||
equal(panel.find('toolbar buttongroup button').length, 3);
|
||||
equal(panel.find('button#button1').length, 1);
|
||||
equal(panel.find('buttongroup#buttongroup1 button#button4').length, 1);
|
||||
equal(panel.find('button,button,buttongroup button').length, 12, 'Check unique');
|
||||
});
|
||||
|
||||
test("Classes", function() {
|
||||
equal(panel.find('button.class1').length, 3);
|
||||
equal(panel.find('button.class1.class2').length, 2);
|
||||
equal(panel.find('button.class2.class1').length, 2);
|
||||
equal(panel.find('button.classX').length, 0);
|
||||
equal(panel.find('button.class1, button.class2').length, 3);
|
||||
});
|
||||
|
||||
test("Psuedo:not", function() {
|
||||
equal(panel.find('button:not(.class1)').length, 9);
|
||||
equal(panel.find('button:not(buttongroup button)').length, 3);
|
||||
equal(panel.find('button:not(toolbar button)').length, 9);
|
||||
equal(panel.find('button:not(toolbar buttongroup button)').length, 9);
|
||||
equal(panel.find('button:not(panel button)').length, 0);
|
||||
equal(panel.find('button:not(.class1)').length, 9);
|
||||
equal(panel.find('button:not(.class3, .class4)').length, 10);
|
||||
});
|
||||
|
||||
test("Psuedo:odd/even/first/last", function() {
|
||||
var matches;
|
||||
|
||||
matches = panel.find('button:first');
|
||||
|
||||
equal(matches.length, 4);
|
||||
ok(matches[0].name() == 'button1');
|
||||
ok(matches[3].name() == 'button10');
|
||||
|
||||
matches = panel.find('button:last');
|
||||
|
||||
equal(matches.length, 3);
|
||||
ok(matches[0].name() == 'button6');
|
||||
ok(matches[1].name() == 'button9');
|
||||
|
||||
matches = panel.find('button:odd');
|
||||
|
||||
equal(matches.length, 4);
|
||||
ok(matches[0].name() == 'button2');
|
||||
ok(matches[1].name() == 'button5');
|
||||
|
||||
matches = panel.find('button:even');
|
||||
|
||||
equal(matches.length, 8);
|
||||
ok(matches[0].name() == 'button1');
|
||||
ok(matches[1].name() == 'button3');
|
||||
});
|
||||
|
||||
test("Psuedo:disabled", function() {
|
||||
equal(panel.find('button:disabled').length, 2);
|
||||
});
|
||||
|
||||
test("Attribute value", function() {
|
||||
equal(panel.find('button[name]').length, 12);
|
||||
equal(panel.find('button[name=button1]').length, 1);
|
||||
equal(panel.find('button[name^=button1]').length, 4);
|
||||
equal(panel.find('button[name$=1]').length, 2);
|
||||
equal(panel.find('button[name*=utt]').length, 12);
|
||||
equal(panel.find('button[name!=button1]').length, 11);
|
||||
});
|
||||
|
||||
test("Direct descendant", function() {
|
||||
equal(panel.find('> button').length, 3);
|
||||
equal(panel.find('toolbar > buttongroup').length, 1);
|
||||
equal(panel.find('toolbar > button').length, 0);
|
||||
});
|
||||
|
||||
test("Parents", function() {
|
||||
equal(panel.find("#button10")[0].parents("toolbar,buttongroup").length, 2);
|
||||
equal(panel.find("#button10")[0].parents("panel").length, 1);
|
||||
});
|
||||
})();
|
||||
|
||||
@ -1,102 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.ui.SplitButton", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function createSplitButton(settings) {
|
||||
return tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: 'splitbutton'
|
||||
}, settings)).renderTo(document.getElementById('view'));
|
||||
}
|
||||
|
||||
test("splitbutton text, size default", function() {
|
||||
var splitButton = createSplitButton({text: 'X'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(splitButton), [0, 0, 42, 30], 4);
|
||||
});
|
||||
|
||||
test("splitbutton text, size large", function() {
|
||||
var splitButton = createSplitButton({text: 'X', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(splitButton), [0, 0, 44, 39], 4);
|
||||
});
|
||||
|
||||
test("splitbutton text, size small", function() {
|
||||
var splitButton = createSplitButton({text: 'X', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(splitButton), [0, 0, 36, 23], 4);
|
||||
});
|
||||
|
||||
test("splitbutton text, width 100, height 100", function() {
|
||||
var splitButton = createSplitButton({text: 'X', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(splitButton), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(splitButton.getEl().firstChild), [1, 1, 83, 98]);
|
||||
});
|
||||
|
||||
test("splitbutton icon, size default", function() {
|
||||
var splitButton = createSplitButton({icon: 'test'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(splitButton), [0, 0, 50, 30], 4);
|
||||
});
|
||||
|
||||
test("splitbutton icon, size small", function() {
|
||||
var splitButton = createSplitButton({icon: 'test', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(splitButton), [0, 0, 45, 24], 4);
|
||||
});
|
||||
|
||||
test("splitbutton icon, size large", function() {
|
||||
var splitButton = createSplitButton({icon: 'test', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(splitButton), [0, 0, 49, 40], 4);
|
||||
});
|
||||
|
||||
test("splitbutton icon, width 100, height 100", function() {
|
||||
var splitButton = createSplitButton({icon: 'test', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(splitButton), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(splitButton.getEl().firstChild), [1, 1, 83, 98]);
|
||||
});
|
||||
|
||||
test("splitbutton text & icon, size default", function() {
|
||||
var splitButton = createSplitButton({text: 'X', icon: 'test'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(splitButton), [0, 0, 62, 30], 4);
|
||||
});
|
||||
|
||||
test("splitbutton text & icon, size large", function() {
|
||||
var splitButton = createSplitButton({text: 'X', icon: 'test', size: 'large'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(splitButton), [0, 0, 64, 40], 4);
|
||||
});
|
||||
|
||||
test("splitbutton text & icon, size small", function() {
|
||||
var splitButton = createSplitButton({text: 'X', icon: 'test', size: 'small'});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(splitButton), [0, 0, 55, 24], 4);
|
||||
});
|
||||
|
||||
test("splitbutton text & icon, width 100, height 100", function() {
|
||||
var splitButton = createSplitButton({text: 'X', icon: 'test', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.rect(splitButton), [0, 0, 100, 100]);
|
||||
deepEqual(Utils.rect(splitButton.getEl().firstChild), [1, 1, 83, 98]);
|
||||
});
|
||||
|
||||
test("splitbutton click event", function() {
|
||||
var splitButton, clicks = {};
|
||||
|
||||
splitButton = createSplitButton({text: 'X', onclick: function() {clicks.a = 'a';}});
|
||||
splitButton.fire('click', {target: splitButton.getEl().firstChild});
|
||||
|
||||
deepEqual(clicks, {a: 'a'});
|
||||
});
|
||||
})();
|
||||
|
||||
@ -1,133 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.ui.TabPanel", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function createTabPanel(settings) {
|
||||
return tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: 'tabpanel',
|
||||
items: [
|
||||
{title: 'a', type: 'spacer', classes: 'red'},
|
||||
{title: 'b', type: 'spacer', classes: 'green'},
|
||||
{title: 'c', type: 'spacer', classes: 'blue'}
|
||||
]
|
||||
}, settings)).renderTo(document.getElementById('view')).reflow();
|
||||
}
|
||||
|
||||
test("panel width: 100, height: 100", function() {
|
||||
var panel = createTabPanel({
|
||||
width: 100,
|
||||
height: 100,
|
||||
layout: 'fit'
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 100, 100]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.items()[0]), [0, 31, 100, 69], 4);
|
||||
});
|
||||
|
||||
test("panel width: 100, height: 100, border: 1", function() {
|
||||
var panel = createTabPanel({
|
||||
width: 100,
|
||||
height: 100,
|
||||
border: 1,
|
||||
layout: 'fit'
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 100, 100]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.items()[0]), [0, 31, 100, 69], 4);
|
||||
});
|
||||
|
||||
test("panel width: 100, height: 100, activeTab: 1", function() {
|
||||
var panel = createTabPanel({
|
||||
width: 100,
|
||||
height: 100,
|
||||
activeTab: 1,
|
||||
layout: 'fit'
|
||||
});
|
||||
|
||||
deepEqual(Utils.rect(panel), [0, 0, 100, 100]);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.items()[1]), [0, 31, 100, 69], 4);
|
||||
});
|
||||
|
||||
test("panel width: auto, height: auto, mixed sized widgets", function() {
|
||||
var panel = createTabPanel({
|
||||
items: [
|
||||
{title: 'a', type: 'spacer', classes: 'red', style: 'width: 100px; height: 100px'},
|
||||
{title: 'b', type: 'spacer', classes: 'green', style: 'width: 70px; height: 70px'},
|
||||
{title: 'c', type: 'spacer', classes: 'blue', style: 'width: 120px; height: 120px'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 120, 151], 4);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.items()[0]), [0, 31, 120, 120], 4);
|
||||
|
||||
panel.activateTab(1);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.items()[1]), [0, 31, 120, 120], 4);
|
||||
|
||||
panel.activateTab(2);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.items()[2]), [0, 31, 120, 120], 4);
|
||||
});
|
||||
|
||||
test("panel width: auto, height: auto, mixed sized containers", function() {
|
||||
var panel = createTabPanel({
|
||||
items: [
|
||||
{
|
||||
title: 'a',
|
||||
type: 'panel',
|
||||
layout: 'flex',
|
||||
align: 'stretch',
|
||||
items: {
|
||||
type: 'spacer',
|
||||
classes: 'red',
|
||||
flex: 1,
|
||||
minWidth: 100,
|
||||
minHeight: 100
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'b',
|
||||
type: 'panel',
|
||||
layout: 'flex',
|
||||
align: 'stretch',
|
||||
items: {
|
||||
type: 'spacer',
|
||||
flex: 1,
|
||||
classes: 'green',
|
||||
minWidth: 70,
|
||||
minHeight: 70
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'c',
|
||||
type: 'panel',
|
||||
layout: 'flex',
|
||||
align: 'stretch',
|
||||
items: {
|
||||
type: 'spacer',
|
||||
classes: 'blue',
|
||||
flex: 1,
|
||||
minWidth: 120,
|
||||
minHeight: 120
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.rect(panel), [0, 0, 120, 151], 4);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.items()[0]), [0, 31, 120, 120], 4);
|
||||
|
||||
panel.activateTab(1);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.items()[1]), [0, 31, 120, 120], 4);
|
||||
|
||||
panel.activateTab(2);
|
||||
Utils.nearlyEqualRects(Utils.rect(panel.items()[2]), [0, 31, 120, 120], 4);
|
||||
});
|
||||
})();
|
||||
@ -1,30 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.ui.TextBox", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
}
|
||||
});
|
||||
|
||||
function createTextBox(settings) {
|
||||
return tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: 'textbox'
|
||||
}, settings)).renderTo(document.getElementById('view'));
|
||||
}
|
||||
|
||||
test("textbox text, size chars: 5", function() {
|
||||
var textBox1 = createTextBox({text: 'X', size: 5});
|
||||
var textBox2 = createTextBox({text: 'X', size: 6});
|
||||
|
||||
ok(Utils.size(textBox1)[0] < Utils.size(textBox2)[0]);
|
||||
});
|
||||
|
||||
test("textbox text, size 100x100", function() {
|
||||
var textBox = createTextBox({text: 'X', width: 100, height: 100});
|
||||
|
||||
deepEqual(Utils.size(textBox), [100, 100]);
|
||||
});
|
||||
})();
|
||||
@ -1,96 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.ui.Window", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
tinymce.dom.Event.clean(document.getElementById('view'));
|
||||
tinymce.DOM.remove(document.getElementById('mce-modal-block'));
|
||||
}
|
||||
});
|
||||
|
||||
function createWindow(settings) {
|
||||
return tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: 'window'
|
||||
}, settings)).renderTo(document.getElementById('view')).reflow();
|
||||
}
|
||||
|
||||
test("window x, y, w, h", function() {
|
||||
var win = createWindow({x: 100, y: 120, width: 200, height: 210});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.size(win), [200, 210]);
|
||||
});
|
||||
|
||||
test("no title, no buttonbar, autoResize", function() {
|
||||
var win = createWindow({
|
||||
x: 100,
|
||||
y: 120,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.size(win), [22, 22]);
|
||||
Utils.nearlyEqualRects(Utils.size(win.find("spacer")[0]), [20, 20]);
|
||||
});
|
||||
|
||||
test("title, no buttonbar, autoResize, title is widest", function() {
|
||||
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",
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1}
|
||||
]
|
||||
});
|
||||
|
||||
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() {
|
||||
var win = createWindow({
|
||||
x: 100,
|
||||
y: 120,
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', flex: 1}
|
||||
],
|
||||
buttons: [
|
||||
{type: 'spacer', classes: 'green', minWidth: 400}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.size(win), [422, 63]);
|
||||
Utils.nearlyEqualRects(Utils.size(win.find("spacer")[0]), [420, 20]);
|
||||
Utils.nearlyEqualRects(Utils.size(win.statusbar.find("spacer")[0]), [400, 20]);
|
||||
});
|
||||
|
||||
test("buttonbar, title, autoResize, content is widest", function() {
|
||||
var win = createWindow({
|
||||
x: 100,
|
||||
y: 120,
|
||||
title: "X",
|
||||
items: [
|
||||
{type: 'spacer', classes: 'red', minWidth: 400}
|
||||
],
|
||||
buttons: [
|
||||
{type: 'spacer', classes: 'green'}
|
||||
]
|
||||
});
|
||||
|
||||
Utils.nearlyEqualRects(Utils.size(win), [402, 102]);
|
||||
Utils.nearlyEqualRects(Utils.size(win.getEl("head")), [400, 39]);
|
||||
Utils.nearlyEqualRects(Utils.size(win.find("spacer")[0]), [400, 20]);
|
||||
Utils.nearlyEqualRects(Utils.size(win.statusbar.find("spacer")[0]), [20, 20]);
|
||||
});
|
||||
})();
|
||||
@ -1,33 +0,0 @@
|
||||
/* Hardcodes sizes since fonts vary on platforms */
|
||||
|
||||
.mce-spacer {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
visibility: visible;
|
||||
border: 0 solid black;
|
||||
}
|
||||
|
||||
.mce-head .mce-title {
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mce-btn .mce-txt {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
/* Colors used for debugging */
|
||||
|
||||
.mce-red {background-color: red;}
|
||||
.mce-green {background-color: green;}
|
||||
.mce-blue {background-color: blue;}
|
||||
.mce-yellow {background-color: yellow;}
|
||||
.mce-magenta {background-color: magenta;}
|
||||
.mce-cyan {background-color: cyan;}
|
||||
.mce-dotted {background-image: url(../img/raster.gif);}
|
||||
.mce-i-test {background: red;}
|
||||
|
||||
body .mce-window, body .mce-notification {
|
||||
transform: none;
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 56 B |
@ -1,17 +0,0 @@
|
||||
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]]);
|
||||
});
|
||||
});
|
||||
@ -1,54 +0,0 @@
|
||||
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'
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@ -1,32 +0,0 @@
|
||||
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-->');
|
||||
});
|
||||
});
|
||||
@ -1,142 +0,0 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
@ -1,36 +0,0 @@
|
||||
(function() {
|
||||
module("tinymce.util.Color");
|
||||
|
||||
var Color = tinymce.util.Color;
|
||||
|
||||
test("Constructor", function() {
|
||||
equal(new Color().toHex(), '#000000');
|
||||
equal(new Color('#faebcd').toHex(), '#faebcd');
|
||||
});
|
||||
|
||||
test("parse method", function() {
|
||||
var color = new Color();
|
||||
|
||||
equal(color.parse('#faebcd').toHex(), '#faebcd');
|
||||
equal(color.parse('#ccc').toHex(), '#cccccc');
|
||||
equal(color.parse(' #faebcd ').toHex(), '#faebcd');
|
||||
equal(color.parse('rgb(255,254,253)').toHex(), '#fffefd');
|
||||
equal(color.parse(' rgb ( 255 , 254 , 253 ) ').toHex(), '#fffefd');
|
||||
equal(color.parse({r: 255, g: 254, b: 253}).toHex(), '#fffefd');
|
||||
equal(color.parse({h: 359, s: 50, v: 50}).toHex(), '#804041');
|
||||
equal(color.parse({r: 700, g: 700, b: 700}).toHex(), '#ffffff');
|
||||
equal(color.parse({r: -1, g: -10, b: -20}).toHex(), '#000000');
|
||||
});
|
||||
|
||||
test("toRgb method", function() {
|
||||
deepEqual(new Color('#faebcd').toRgb(), {r: 250, g: 235, b: 205});
|
||||
});
|
||||
|
||||
test("toHsv method", function() {
|
||||
deepEqual(new Color('#804041').toHsv(), {h: 359, s: 50, v: 50});
|
||||
});
|
||||
|
||||
test("toHex method", function() {
|
||||
equal(new Color({r: 255, g: 254, b: 253}).toHex(), '#fffefd');
|
||||
});
|
||||
})();
|
||||
@ -1,130 +0,0 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/util/Delay"
|
||||
], function(Delay) {
|
||||
module("tinymce.util.Delay");
|
||||
|
||||
asyncTest('requestAnimationFrame', function() {
|
||||
Delay.requestAnimationFrame(function() {
|
||||
ok("requestAnimationFrame was executed.", true);
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('setTimeout', function() {
|
||||
Delay.setTimeout(function() {
|
||||
ok("setTimeout was executed.", true);
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('setInterval', function() {
|
||||
var count = 0, id;
|
||||
|
||||
id = Delay.setInterval(function() {
|
||||
if (++count == 2) {
|
||||
Delay.clearInterval(id);
|
||||
equal(count, 2);
|
||||
QUnit.start();
|
||||
} else if (count > 3) {
|
||||
throw new Error("Still executing setInterval.");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('setEditorTimeout', function() {
|
||||
var fakeEditor = {};
|
||||
|
||||
Delay.setEditorTimeout(fakeEditor, function() {
|
||||
ok("setEditorTimeout was executed.", true);
|
||||
QUnit.start();
|
||||
});
|
||||
});
|
||||
|
||||
test('setEditorTimeout (removed)', function() {
|
||||
var fakeEditor = {removed: true};
|
||||
|
||||
Delay.setEditorTimeout(fakeEditor, function() {
|
||||
throw new Error("Still executing setEditorTimeout.");
|
||||
});
|
||||
|
||||
ok(true, "setEditorTimeout on removed instance.");
|
||||
});
|
||||
|
||||
asyncTest('setEditorInterval', function() {
|
||||
var count = 0, id, fakeEditor = {};
|
||||
|
||||
id = Delay.setEditorInterval(fakeEditor, function() {
|
||||
if (++count == 2) {
|
||||
Delay.clearInterval(id);
|
||||
equal(count, 2);
|
||||
QUnit.start();
|
||||
} else if (count > 3) {
|
||||
throw new Error("Still executing setEditorInterval.");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('setEditorInterval (removed)', function() {
|
||||
var fakeEditor = {removed: true};
|
||||
|
||||
Delay.setEditorInterval(fakeEditor, function() {
|
||||
throw new Error("Still executing setEditorInterval.");
|
||||
});
|
||||
|
||||
ok(true, "setEditorTimeout on removed instance.");
|
||||
});
|
||||
|
||||
asyncTest('throttle', function() {
|
||||
var fn, args = [];
|
||||
|
||||
fn = Delay.throttle(function(a) {
|
||||
args.push(a);
|
||||
}, 0);
|
||||
|
||||
fn(1);
|
||||
fn(2);
|
||||
|
||||
Delay.setTimeout(function() {
|
||||
deepEqual(args, [2]);
|
||||
QUnit.start();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
asyncTest('throttle stop', function() {
|
||||
var fn, args = [];
|
||||
|
||||
fn = Delay.throttle(function(a) {
|
||||
args.push(a);
|
||||
}, 0);
|
||||
|
||||
fn(1);
|
||||
fn.stop();
|
||||
|
||||
Delay.setTimeout(function() {
|
||||
deepEqual(args, []);
|
||||
QUnit.start();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
test('clearTimeout', function() {
|
||||
var id;
|
||||
|
||||
id = Delay.setTimeout(function() {
|
||||
throw new Error("clearTimeout didn't work.");
|
||||
});
|
||||
|
||||
Delay.clearTimeout(id);
|
||||
ok(true, "clearTimeout works.");
|
||||
});
|
||||
|
||||
test('clearTimeout', function() {
|
||||
var id;
|
||||
|
||||
id = Delay.setInterval(function() {
|
||||
throw new Error("clearInterval didn't work.");
|
||||
});
|
||||
|
||||
Delay.clearInterval(id);
|
||||
ok(true, "clearInterval works.");
|
||||
});
|
||||
});
|
||||
@ -1,255 +0,0 @@
|
||||
module("tinymce.util.EventDispatcher");
|
||||
|
||||
test("fire (no event listeners)", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), args;
|
||||
|
||||
args = dispatcher.fire('click', {test: 1});
|
||||
equal(args.test, 1);
|
||||
equal(args.isDefaultPrevented(), false);
|
||||
equal(args.isPropagationStopped(), false);
|
||||
equal(args.isImmediatePropagationStopped(), false);
|
||||
strictEqual(args.target, dispatcher);
|
||||
|
||||
args = dispatcher.fire('click');
|
||||
equal(args.isDefaultPrevented(), false);
|
||||
equal(args.isPropagationStopped(), false);
|
||||
equal(args.isImmediatePropagationStopped(), false);
|
||||
});
|
||||
|
||||
test("fire (event listeners)", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
dispatcher.on('click', function() {data += 'a';});
|
||||
dispatcher.on('click', function() {data += 'b';});
|
||||
|
||||
args = dispatcher.fire('click', {test: 1});
|
||||
equal(data, 'ab');
|
||||
});
|
||||
|
||||
test("fire (event listeners) stopImmediatePropagation", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
dispatcher.on('click', function(e) { data += 'a'; e.stopImmediatePropagation(); });
|
||||
dispatcher.on('click', function() { data += 'b'; });
|
||||
|
||||
dispatcher.fire('click', {test: 1});
|
||||
equal(data, 'a');
|
||||
});
|
||||
|
||||
test("on", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
strictEqual(dispatcher.on('click', function() {data += 'a';}), dispatcher);
|
||||
strictEqual(dispatcher.on('click keydown', function() {data += 'b';}), dispatcher);
|
||||
|
||||
dispatcher.fire('click');
|
||||
equal(data, 'ab');
|
||||
|
||||
dispatcher.fire('keydown');
|
||||
equal(data, 'abb');
|
||||
});
|
||||
|
||||
test("on (prepend)", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
strictEqual(dispatcher.on('click', function() {data += 'a';}), dispatcher);
|
||||
strictEqual(dispatcher.on('click', function() {data += 'b';}, true), dispatcher);
|
||||
|
||||
dispatcher.fire('click');
|
||||
equal(data, 'ba');
|
||||
});
|
||||
|
||||
test("once", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
strictEqual(dispatcher.on('click', function() {data += 'a';}), dispatcher);
|
||||
strictEqual(dispatcher.once('click', function() {data += 'b';}), dispatcher);
|
||||
strictEqual(dispatcher.on('click', function() {data += 'c';}), dispatcher);
|
||||
|
||||
dispatcher.fire('click');
|
||||
equal(data, 'abc');
|
||||
|
||||
dispatcher.fire('click');
|
||||
equal(data, 'abcac');
|
||||
});
|
||||
|
||||
test("once (prepend)", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
strictEqual(dispatcher.on('click', function() {data += 'a';}), dispatcher);
|
||||
strictEqual(dispatcher.once('click', function() {data += 'b';}, true), dispatcher);
|
||||
strictEqual(dispatcher.on('click', function() {data += 'c';}), dispatcher);
|
||||
|
||||
dispatcher.fire('click');
|
||||
equal(data, 'bac');
|
||||
|
||||
dispatcher.fire('click');
|
||||
equal(data, 'bacac');
|
||||
});
|
||||
|
||||
test("once (unbind)", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
function handler() {
|
||||
data += 'b';
|
||||
}
|
||||
|
||||
dispatcher.once('click', function() {data += 'a';});
|
||||
dispatcher.once('click', handler);
|
||||
dispatcher.off('click', handler);
|
||||
|
||||
dispatcher.fire('click');
|
||||
equal(data, 'a');
|
||||
});
|
||||
|
||||
test("once (multiple events)", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
dispatcher.once('click', function() {data += 'a';});
|
||||
dispatcher.once('keydown', function() {data += 'b';});
|
||||
|
||||
dispatcher.fire('click');
|
||||
equal(data, 'a');
|
||||
|
||||
dispatcher.fire('keydown');
|
||||
equal(data, 'ab');
|
||||
|
||||
dispatcher.fire('click');
|
||||
dispatcher.fire('keydown');
|
||||
|
||||
equal(data, 'ab');
|
||||
});
|
||||
|
||||
test("off (all)", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
function listenerA() { data += 'a'; }
|
||||
function listenerB() { data += 'b'; }
|
||||
function listenerC() { data += 'c'; }
|
||||
|
||||
dispatcher.on('click', listenerA);
|
||||
dispatcher.on('click', listenerB);
|
||||
dispatcher.on('keydown', listenerC);
|
||||
|
||||
dispatcher.off();
|
||||
|
||||
data = '';
|
||||
dispatcher.fire('click');
|
||||
dispatcher.fire('keydown');
|
||||
equal(data, '');
|
||||
});
|
||||
|
||||
test("off (all named)", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
function listenerA() { data += 'a'; }
|
||||
function listenerB() { data += 'b'; }
|
||||
function listenerC() { data += 'c'; }
|
||||
|
||||
dispatcher.on('click', listenerA);
|
||||
dispatcher.on('click', listenerB);
|
||||
dispatcher.on('keydown', listenerC);
|
||||
|
||||
dispatcher.off('click');
|
||||
|
||||
data = '';
|
||||
dispatcher.fire('click');
|
||||
dispatcher.fire('keydown');
|
||||
equal(data, 'c');
|
||||
});
|
||||
|
||||
test("off (all specific observer)", function() {
|
||||
var dispatcher = new tinymce.util.EventDispatcher(), data = '';
|
||||
|
||||
function listenerA() { data += 'a'; }
|
||||
function listenerB() { data += 'b'; }
|
||||
|
||||
dispatcher.on('click', listenerA);
|
||||
dispatcher.on('click', listenerB);
|
||||
dispatcher.off('click', listenerB);
|
||||
|
||||
data = '';
|
||||
dispatcher.fire('click');
|
||||
equal(data, 'a');
|
||||
});
|
||||
|
||||
test("scope setting", function() {
|
||||
var lastScope, lastEvent, dispatcher;
|
||||
|
||||
dispatcher = new tinymce.util.EventDispatcher();
|
||||
dispatcher.on('click', function() {
|
||||
lastScope = this;
|
||||
}).fire('click');
|
||||
strictEqual(dispatcher, lastScope);
|
||||
|
||||
var scope = {test: 1};
|
||||
dispatcher = new tinymce.util.EventDispatcher({scope: scope});
|
||||
dispatcher.on('click', function(e) {
|
||||
lastScope = this;
|
||||
lastEvent = e;
|
||||
}).fire('click');
|
||||
strictEqual(scope, lastScope);
|
||||
strictEqual(lastEvent.target, lastScope);
|
||||
});
|
||||
|
||||
test("beforeFire setting", function() {
|
||||
var lastArgs, dispatcher, args;
|
||||
|
||||
dispatcher = new tinymce.util.EventDispatcher({
|
||||
beforeFire: function(args) {
|
||||
lastArgs = args;
|
||||
}
|
||||
});
|
||||
|
||||
args = dispatcher.fire('click');
|
||||
strictEqual(lastArgs, args);
|
||||
});
|
||||
|
||||
test("beforeFire setting (stopImmediatePropagation)", function() {
|
||||
var lastArgs, dispatcher, args, data = '';
|
||||
|
||||
dispatcher = new tinymce.util.EventDispatcher({
|
||||
beforeFire: function(args) {
|
||||
lastArgs = args;
|
||||
args.stopImmediatePropagation();
|
||||
}
|
||||
});
|
||||
|
||||
function listenerA() { data += 'a'; }
|
||||
|
||||
dispatcher.on('click', listenerA);
|
||||
args = dispatcher.fire('click');
|
||||
strictEqual(lastArgs, args);
|
||||
strictEqual(data, '');
|
||||
});
|
||||
|
||||
test("toggleEvent setting", function() {
|
||||
var lastName, lastState;
|
||||
|
||||
dispatcher = new tinymce.util.EventDispatcher({
|
||||
toggleEvent: function(name, state) {
|
||||
lastName = name;
|
||||
lastState = state;
|
||||
}
|
||||
});
|
||||
|
||||
function listenerA() { data += 'a'; }
|
||||
function listenerB() { data += 'b'; }
|
||||
|
||||
dispatcher.on('click', listenerA);
|
||||
strictEqual(lastName, 'click');
|
||||
strictEqual(lastState, true);
|
||||
|
||||
lastName = lastState = null;
|
||||
dispatcher.on('click', listenerB);
|
||||
strictEqual(lastName, null);
|
||||
strictEqual(lastState, null);
|
||||
|
||||
dispatcher.off('click', listenerA);
|
||||
strictEqual(lastName, null);
|
||||
strictEqual(lastState, null);
|
||||
|
||||
dispatcher.off('click', listenerB);
|
||||
strictEqual(lastName, 'click');
|
||||
strictEqual(lastState, false);
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user