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:
Andrew Ozz 2017-05-08 05:35:41 +00:00
parent f4d3513802
commit 1727d6fbef
116 changed files with 287 additions and 25674 deletions

View File

@ -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);
}
}
});
});
});

View File

@ -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))})})});

View File

@ -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>

View File

@ -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;
};
})();

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -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);
}
})();

View File

@ -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() {}

View File

@ -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>&nbsp;<\/p>\n?/, '').replace(/\n?<p>&nbsp;<\/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
};
})();

View File

@ -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);
});

View File

@ -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>');
});

View File

@ -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="&quot;&amp;&lt;&gt;">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="&quot;&amp;&lt;&gt;">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>');
});

View File

@ -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');
});
});

View File

@ -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);
});
});

View File

@ -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());
});
});

View File

@ -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

View File

@ -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;
});
});

View File

@ -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

View File

@ -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');
});

View File

@ -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>');
});

View File

@ -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>');
});
});

View File

@ -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>');
});
});

View File

@ -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);
});
});

View File

@ -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.');
}
});
});

View File

@ -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');
}
});
});

View File

@ -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.');
});

View File

@ -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>');
});

View File

@ -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);
});
});

View File

@ -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);
});
});

View File

@ -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);
});
});

View File

@ -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>');
});
});

View File

@ -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]);
});
});

View File

@ -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));
});
});

View File

@ -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));
});
});

View File

@ -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);
});
});

View File

@ -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));
});
});

View File

@ -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);
});
});

View File

@ -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');
});
});

View File

@ -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);
});
});

View File

@ -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&lt;&gt;&quot;&amp;&#39;\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&amp;&lt;&gt;&quot;');
equal(DOM.decode('&aring;&auml;&ouml;&amp;&lt;&gt;&quot;'), '\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');
})();

View File

@ -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

View File

@ -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");
});

View File

@ -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);
});
});

View File

@ -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);
});
});

View File

@ -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

View File

@ -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', '&lt;&gt;&amp;&quot;&nbsp;&aring;&auml;&ouml;');
equal(ser.serialize(DOM.get('test')), '<div id="test">&lt;&gt;&amp;"&#160;&#229;&#228;&#246;</div>');
ser = new tinymce.dom.Serializer({entity_encoding : 'named'});
DOM.setHTML('test', '&lt;&gt;&amp;&quot;&nbsp;&aring;&auml;&ouml;');
equal(ser.serialize(DOM.get('test')), '<div id="test">&lt;&gt;&amp;"&nbsp;&aring;&auml;&ouml;</div>');
ser = new tinymce.dom.Serializer({entity_encoding : 'named+numeric', entities : '160,nbsp,34,quot,38,amp,60,lt,62,gt'});
DOM.setHTML('test', '&lt;&gt;&amp;&quot;&nbsp;&aring;&auml;&ouml;');
equal(ser.serialize(DOM.get('test')), '<div id="test">&lt;&gt;&amp;"&nbsp;&#229;&#228;&#246;</div>');
ser = new tinymce.dom.Serializer({entity_encoding : 'raw'});
DOM.setHTML('test', '&lt;&gt;&amp;&quot;&nbsp;&aring;&auml;&ouml;');
equal(ser.serialize(DOM.get('test')), '<div id="test">&lt;&gt;&amp;"\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>&nbsp;</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>');
});

View File

@ -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');
});
});

View File

@ -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");
});
}

View File

@ -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; }

View File

@ -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);
});
});

View File

@ -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);
});
});
});

View File

@ -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);
});
});

View File

@ -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();
});
});

View File

@ -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>'
);
});
});

View File

@ -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');
});
});

View File

@ -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);
});
});

View File

@ -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});
});
});

View File

@ -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>'
);
});
})();

View File

@ -1,75 +0,0 @@
module("tinymce.html.Entities");
test('encodeRaw', function() {
expect(2);
equal(tinymce.html.Entities.encodeRaw('<>"\'&\u00e5\u00e4\u00f6\u0060'), '&lt;&gt;"\'&amp;\u00e5\u00e4\u00f6\u0060', 'Raw encoding text');
equal(tinymce.html.Entities.encodeRaw('<>"\'&\u00e5\u00e4\u00f6\u0060', true), '&lt;&gt;&quot;\'&amp;\u00e5\u00e4\u00f6&#96;', 'Raw encoding attribute');
});
test('encodeAllRaw', function() {
expect(1);
equal(tinymce.html.Entities.encodeAllRaw('<>"\'&\u00e5\u00e4\u00f6'), '&lt;&gt;&quot;&#39;&amp;\u00e5\u00e4\u00f6', 'Raw encoding all');
});
test('encodeNumeric', function() {
expect(2);
equal(tinymce.html.Entities.encodeNumeric('<>"\'&\u00e5\u00e4\u00f6\u03b8\u2170\ufa11'), '&lt;&gt;"\'&amp;&#229;&#228;&#246;&#952;&#8560;&#64017;', 'Numeric encoding text');
equal(tinymce.html.Entities.encodeNumeric('<>"\'&\u00e5\u00e4\u00f6', true), '&lt;&gt;&quot;\'&amp;&#229;&#228;&#246;', 'Numeric encoding attribute');
});
test('encodeNamed', function() {
expect(4);
equal(tinymce.html.Entities.encodeNamed('<>"\'&\u00e5\u00e4\u00f6'), '&lt;&gt;"\'&amp;&aring;&auml;&ouml;', 'Named encoding text');
equal(tinymce.html.Entities.encodeNamed('<>"\'&\u00e5\u00e4\u00f6', true), '&lt;&gt;&quot;\'&amp;&aring;&auml;&ouml;', 'Named encoding attribute');
equal(tinymce.html.Entities.encodeNamed('<>"\'\u00e5\u00e4\u00f6', false, {'\u00e5' : '&aring;'}), '&lt;&gt;"\'&aring;\u00e4\u00f6', 'Named encoding text');
equal(tinymce.html.Entities.encodeNamed('<>"\'\u00e5\u00e4\u00f6', true, {'\u00e5' : '&aring;'}), '&lt;&gt;&quot;\'&aring;\u00e4\u00f6', 'Named encoding attribute');
});
test('getEncodeFunc', function() {
var encodeFunc;
expect(10);
encodeFunc = tinymce.html.Entities.getEncodeFunc('raw');
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '&lt;&gt;"\'&amp;\u00e5\u00e4\u00f6', 'Raw encoding text');
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '&lt;&gt;&quot;\'&amp;\u00e5\u00e4\u00f6', 'Raw encoding attribute');
encodeFunc = tinymce.html.Entities.getEncodeFunc('named');
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '&lt;&gt;"\'&amp;&aring;&auml;&ouml;', 'Named encoding text');
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '&lt;&gt;&quot;\'&amp;&aring;&auml;&ouml;', 'Named encoding attribute');
encodeFunc = tinymce.html.Entities.getEncodeFunc('numeric');
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '&lt;&gt;"\'&amp;&#229;&#228;&#246;', 'Named encoding text');
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '&lt;&gt;&quot;\'&amp;&#229;&#228;&#246;', 'Named encoding attribute');
encodeFunc = tinymce.html.Entities.getEncodeFunc('named+numeric', '229,aring');
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '&lt;&gt;"\'&amp;&aring;&#228;&#246;', 'Named+numeric encoding text');
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '&lt;&gt;&quot;\'&amp;&aring;&#228;&#246;', 'Named+numeric encoding attribute');
encodeFunc = tinymce.html.Entities.getEncodeFunc('named,numeric', '229,aring');
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '&lt;&gt;"\'&amp;&aring;&#228;&#246;', 'Named+numeric encoding text');
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '&lt;&gt;&quot;\'&amp;&aring;&#228;&#246;', 'Named+numeric encoding attribute');
});
test('decode', function() {
equal(tinymce.html.Entities.decode('&lt;&gt;&quot;&#39;&amp;&aring;&auml;&ouml;&unknown;'), '<>"\'&\u00e5\u00e4\u00f6&unknown;', 'Decode text with various entities');
equal(tinymce.html.Entities.decode('&#65;&#66;&#039;'), 'AB\'', 'Decode numeric entities');
equal(tinymce.html.Entities.decode('&#x4F;&#X4F;&#x27;'), 'OO\'', 'Decode hexanumeric entities');
equal(tinymce.html.Entities.decode('&#65&#66&#x43'), '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(
'&#130;&#131;&#132;&#133;&#134;&#135;&#136;&#137;&#138;' +
'&#139;&#140;&#141;&#142;&#143;&#144;&#145;&#146;&#147;&#148;&#149;&#150;&#151;&#152;' +
'&#153;&#154;&#155;&#156;&#157;&#158;&#159;')
), '&#8218;&#402;&#8222;&#8230;&#8224;&#8225;&#710;&#8240;&#352;&#8249;&#338;&#141;&#381;' +
'&#143;&#144;&#8216;&#8217;&#8220;&#8221;&#8226;&#8211;&#8212;&#732;&#8482;&#353;' +
'&#8250;&#339;&#157;&#382;&#376;',
'Entity decode ascii');
equal(tinymce.html.Entities.encodeNumeric(tinymce.html.Entities.decode('&#194564;')), '&#194564;', "High byte non western character.");
});

View File

@ -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.');
});

View File

@ -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 );
});

View File

@ -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=\'"&amp;<>\'></b>');
equal(writer.getContent(), '<b href="&quot;&amp;&lt;&gt;"></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&lt;t3</b></p>te&gt;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="&lt;test" data-test="test&gt;"></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=&#106&#97&#118&#97&#115&#99&#114&#105&#112&#116&#58&#97&#108&#101&#114&#116&#40&#39&#88&#83&#83&#39&#41>?>');
equal(
writer.getContent(),
'<?xml &gt;&lt;iframe SRC=&amp;#106&amp;#97&amp;#118&amp;#97&amp;#115&amp;#99&amp;#114&amp;#105&amp;#112&amp;' +
'#116&amp;#58&amp;#97&amp;#108&amp;#101&amp;#114&amp;#116&amp;#40&amp;#39&amp;#88&amp;#83&amp;#83&amp;#39&amp;#41&gt;?>'
);
});
})();

View File

@ -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': {}
}
});
});

View File

@ -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&lt;text&amp;');
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>'
);
});

View File

@ -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: "&amp;"')), "value: '&amp;';");
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');");
});

View File

@ -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" &lt; &gt;?>');
});
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&lt;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&lt;&quot;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="&lt;&gt;&quot;\'&amp;\u00e5\u00e4\u00f6">&lt;&gt;"\'&amp;\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="&lt;&gt;&quot;\'&amp;&#229;&#228;&#246;">&lt;&gt;"\'&amp;&#229;&#228;&#246;</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="&lt;&gt;&quot;\'&amp;&aring;&auml;&ouml;">&lt;&gt;"\'&amp;&aring;&auml;&ouml;</p>');
});

View File

@ -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();
}
}
});
});

View File

@ -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);
});
});

View File

@ -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');
});
});

View File

@ -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]);
});
})();

View File

@ -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'});
});
})();

View File

@ -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);
});
})();

View File

@ -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'});
});
})();

View File

@ -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('<>"&'), '&#60;&#62;&#34;&#38;');
equal(new tinymce.ui.Control({}).encode('old'), '&#34;new&#34;');
equal(new tinymce.ui.Control({}).encode('old', false), 'old');
});
test("translate", function() {
tinymce.i18n.add('en', {'old': 'new'});
equal(new tinymce.ui.Control({}).translate('old'), 'new');
equal(new tinymce.ui.Control({}).translate('old2'), 'old2');
});
})();

View File

@ -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">&lt;top&gt;</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">&lt;bottom&gt;</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();
});
});
});

View File

@ -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]);
});
})();

View File

@ -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]);
});
})();

View File

@ -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);
});
})();

View File

@ -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'});
});
})();

View File

@ -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);
});
})();

View File

@ -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);
});
})();

View File

@ -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'});
});
})();

View File

@ -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);
});
})();

View File

@ -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]);
});
})();

View File

@ -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]);
});
})();

View File

@ -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

View File

@ -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]]);
});
});

View File

@ -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'
});
});
});

View File

@ -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-->');
});
});

View File

@ -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);
});
});

View File

@ -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');
});
})();

View File

@ -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.");
});
});

View File

@ -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