mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2025-10-16 12:05:38 +00:00
Incorporate the TinyMCE tests into our JS tests:
- Modified the original tests so TinyMCE can be loaded from /src/wp-includes/js/tinymce. - Added "WP" option to the UI to select only tests relevant to our integration (excludes most of the default plugins tests). - Added tests for obsolete HTML elements and attributes (html4 back-compat). See #27014. git-svn-id: https://develop.svn.wordpress.org/trunk@27155 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
4951bdc964
commit
ce2dcccf86
13
Gruntfile.js
13
Gruntfile.js
@ -160,7 +160,8 @@ module.exports = function(grunt) {
|
||||
tests: {
|
||||
src: [
|
||||
'tests/qunit/**/*.js',
|
||||
'!tests/qunit/vendor/qunit.js'
|
||||
'!tests/qunit/vendor/qunit.js',
|
||||
'!tests/qunit/editor/**'
|
||||
],
|
||||
options: grunt.file.readJSON('tests/qunit/.jshintrc')
|
||||
},
|
||||
@ -228,7 +229,10 @@ module.exports = function(grunt) {
|
||||
}
|
||||
},
|
||||
qunit: {
|
||||
files: ['tests/qunit/**/*.html']
|
||||
files: [
|
||||
'tests/qunit/**/*.html',
|
||||
'!tests/qunit/editor/**'
|
||||
]
|
||||
},
|
||||
phpunit: {
|
||||
'default': {
|
||||
@ -340,7 +344,10 @@ module.exports = function(grunt) {
|
||||
}
|
||||
},
|
||||
test: {
|
||||
files: ['tests/qunit/**'],
|
||||
files: [
|
||||
'tests/qunit/**',
|
||||
'!tests/qunit/editor/**'
|
||||
],
|
||||
tasks: ['qunit']
|
||||
}
|
||||
}
|
||||
|
||||
29
tests/qunit/editor/coverage/index.html
Normal file
29
tests/qunit/editor/coverage/index.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Code Coverage</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
|
||||
|
||||
<!-- coverage -->
|
||||
<link rel="stylesheet" href="js/reporter.css" type="text/css" />
|
||||
<script src="js/underscore-min.js"></script>
|
||||
<script src="js/backbone-min.js"></script>
|
||||
<script src="js/reporter.js"></script>
|
||||
<script src="js/JSCovReporter.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="coverage"></div>
|
||||
<div id="menu"></div>
|
||||
|
||||
<script>
|
||||
if (top != window && top.TestRunner) {
|
||||
new JSCovReporter({ coverObject: top.TestRunner.getCoverObject() });
|
||||
//onsole.info(top.TestRunner.getCoverObject());
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
194
tests/qunit/editor/coverage/js/JSCovReporter.js
Normal file
194
tests/qunit/editor/coverage/js/JSCovReporter.js
Normal file
@ -0,0 +1,194 @@
|
||||
JSCovFileReporter = Backbone.View.extend({
|
||||
initialize: function () {
|
||||
_.bindAll(this);
|
||||
this.open = '<tr class="{class}"><td class="line">{line_number}</td><td class="hits">{count}</td><td class="source">';
|
||||
this.close = '</td></tr>';
|
||||
|
||||
this.coverObject = this.options.coverObject;
|
||||
|
||||
this.error = 0;
|
||||
this.pass = 0;
|
||||
this.total = 0;
|
||||
},
|
||||
|
||||
// substitute credits: MooTools
|
||||
substitute: function(string, object){
|
||||
return string.replace(/\\?\{([^{}]+)\}/g, function(match, name){
|
||||
if (match.charAt(0) == '\\') return match.slice(1);
|
||||
return (object[name] !== null) ? object[name] : '';
|
||||
});
|
||||
},
|
||||
|
||||
generateClose: function(count){
|
||||
return this.substitute(this.close, {
|
||||
count: count
|
||||
});
|
||||
},
|
||||
|
||||
generateOpen: function(hit_count, line_number){
|
||||
return this.substitute(this.open, {
|
||||
'count': hit_count,
|
||||
'line_number': line_number,
|
||||
'class': hit_count ? 'hit' : 'miss'
|
||||
});
|
||||
},
|
||||
|
||||
report: function () {
|
||||
var thisview = this;
|
||||
var i, l, k;
|
||||
|
||||
var code = this.coverObject.__code;
|
||||
|
||||
// generate array of all tokens
|
||||
var codez = [];
|
||||
for (i = 0, l = code.length; i < l; i++){
|
||||
codez.push({
|
||||
pos: i,
|
||||
value: code.slice(i, i + 1)
|
||||
});
|
||||
}
|
||||
|
||||
// CoverObject has keys like "12:200" which means from char 12 to 200
|
||||
// This orders all first gaps in a list of dictionaries to ease drawing table lines
|
||||
var gaps = Object.keys(this.coverObject);
|
||||
gaps = _.without(gaps, '__code');
|
||||
var first_gaps = _.map(gaps, function ( gap ) {
|
||||
return {
|
||||
gap: parseInt(gap.split(':')[0], 10),
|
||||
hit_count: thisview.coverObject[gap]
|
||||
};
|
||||
}).sort(function (a, b) {
|
||||
if (a['gap'] > b['gap']) return 1;
|
||||
if (b['gap'] > a['gap']) return -1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
var second_gaps = _.map(gaps, function ( gap ) {
|
||||
return {
|
||||
gap: parseInt(gap.split(':')[1], 10),
|
||||
hit_count: thisview.coverObject[gap]
|
||||
};
|
||||
}).sort(function (a, b) {
|
||||
if (a['gap'] > b['gap']) return 1;
|
||||
if (b['gap'] > a['gap']) return -1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
|
||||
// If it doesn't start from 0 it's because there are comments in the beginning
|
||||
// We add a initial gap with one hit
|
||||
if (first_gaps[0] !== 0) {
|
||||
first_gaps.splice(0, 0, {gap: 0, hit_count: 1});
|
||||
}
|
||||
|
||||
var result = '';
|
||||
var number_trailing_whitespaces = 0;
|
||||
var trailing_whitespaces = '';
|
||||
|
||||
|
||||
// We will go from one gap to the next wrapping them in table lines
|
||||
for (i=0, l = first_gaps.length; i < l; i++){
|
||||
|
||||
var hit_count = first_gaps[i]['hit_count'];
|
||||
|
||||
this.total++;
|
||||
if (hit_count) this.pass++;
|
||||
else this.error++;
|
||||
|
||||
var limit = null;
|
||||
if (i+1 >= l) {
|
||||
limit = codez.length;
|
||||
}
|
||||
else {
|
||||
limit = first_gaps[i+1]['gap'];
|
||||
}
|
||||
|
||||
// Table line opening
|
||||
result += this.generateOpen(hit_count, this.total);
|
||||
|
||||
// Add trailing white space if it existed from previous line without carriage returns
|
||||
if (number_trailing_whitespaces > 0 ) {
|
||||
result += trailing_whitespaces.replace(/(\r\n|\n|\r)/gm,"");
|
||||
}
|
||||
|
||||
// Add lines of code without initial white spaces, and replacing conflictive chars
|
||||
result += _.map(codez.slice(first_gaps[i]['gap'], limit), function (loc) {
|
||||
return loc['value'];
|
||||
}).join('').trimLeft().replace(/</g, '<').replace(/>/g, '>');
|
||||
|
||||
// Count trailing white spaces for future line, then remove them
|
||||
var matches = result.match(/(\s+)$/);
|
||||
result = result.trimRight();
|
||||
|
||||
if (matches !== null) {
|
||||
number_trailing_whitespaces = matches[0].length;
|
||||
trailing_whitespaces = matches[0];
|
||||
}
|
||||
else {
|
||||
number_trailing_whitespaces = 0;
|
||||
}
|
||||
|
||||
// Generate table line closing
|
||||
result += this.generateClose(hit_count);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
JSCovReporter = Backbone.View.extend({
|
||||
initialize: function () {
|
||||
this.coverObject = this.options.coverObject;
|
||||
|
||||
// Generate the report
|
||||
this.report();
|
||||
|
||||
// Activate reporter.js scrolling UX
|
||||
onload();
|
||||
},
|
||||
|
||||
report: function () {
|
||||
var result = '';
|
||||
var index = '';
|
||||
|
||||
for (var file in this.coverObject) {
|
||||
var fileReporter = new JSCovFileReporter({ coverObject: this.coverObject[file] });
|
||||
|
||||
var fileReport = fileReporter.report();
|
||||
var percentage = Math.round(fileReporter.pass / fileReporter.total * 100);
|
||||
|
||||
this.error += fileReporter.error;
|
||||
this.pass += fileReporter.pass;
|
||||
this.total += fileReporter.total;
|
||||
|
||||
var type_coverage = "high";
|
||||
if (percentage < 75 && percentage >= 50) {
|
||||
type_coverage = 'medium';
|
||||
}
|
||||
else if (percentage < 50 && percentage >= 25) {
|
||||
type_coverage = 'low';
|
||||
}
|
||||
else if (percentage < 25) {
|
||||
type_coverage = 'terrible';
|
||||
}
|
||||
|
||||
// Title
|
||||
result += '<h2 id="' + file + '" class="file-title">' + file + '</h2>';
|
||||
// Stats
|
||||
result += '<div class="stats ' + type_coverage + '"><div class="percentage">'+ percentage + '%</div>';
|
||||
result += '<div class="sloc">' + fileReporter.total + '</div><div class="hits">' + fileReporter.pass + '</div>';
|
||||
result += '<div class="misses">' + fileReporter.error + '</div></div>';
|
||||
// Report
|
||||
result += '<div class="file-report">';
|
||||
result += '<table id="source"><tbody>' + fileReport + '</tbody></table>';
|
||||
result += '</div>';
|
||||
|
||||
// Menu index
|
||||
index += '<li><span class="cov ' + type_coverage + '">' + percentage + '</span><a href="#' + file+ '">' + file + '</a></li>';
|
||||
}
|
||||
|
||||
$('#coverage').html(result);
|
||||
$('#menu').html('<ul id="toc">' + index + '</ul>');
|
||||
}
|
||||
});
|
||||
4
tests/qunit/editor/coverage/js/backbone-min.js
vendored
Normal file
4
tests/qunit/editor/coverage/js/backbone-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
310
tests/qunit/editor/coverage/js/reporter.css
Normal file
310
tests/qunit/editor/coverage/js/reporter.css
Normal file
File diff suppressed because one or more lines are too long
31
tests/qunit/editor/coverage/js/reporter.js
Normal file
31
tests/qunit/editor/coverage/js/reporter.js
Normal file
@ -0,0 +1,31 @@
|
||||
headings = [];
|
||||
|
||||
onload = function(){
|
||||
headings = document.querySelectorAll('h2');
|
||||
};
|
||||
|
||||
onscroll = function(e){
|
||||
var heading = find(window.scrollY);
|
||||
if (!heading) return;
|
||||
var links = document.querySelectorAll('#menu a')
|
||||
, link;
|
||||
|
||||
for (var i = 0, len = links.length; i < len; ++i) {
|
||||
link = links[i];
|
||||
link.className = link.getAttribute('href') == '#' + heading.id
|
||||
? 'active'
|
||||
: '';
|
||||
}
|
||||
};
|
||||
|
||||
function find(y) {
|
||||
var i = headings.length
|
||||
, heading;
|
||||
|
||||
while (i--) {
|
||||
heading = headings[i];
|
||||
if (y > heading.offsetTop) {
|
||||
return heading;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
tests/qunit/editor/coverage/js/underscore-min.js
vendored
Normal file
1
tests/qunit/editor/coverage/js/underscore-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
539
tests/qunit/editor/external-plugins/noneditable/plugin.js
Normal file
539
tests/qunit/editor/external-plugins/noneditable/plugin.js
Normal file
@ -0,0 +1,539 @@
|
||||
/**
|
||||
* plugin.js
|
||||
*
|
||||
* Copyright, Moxiecode Systems AB
|
||||
* Released under LGPL License.
|
||||
*
|
||||
* License: http://www.tinymce.com/license
|
||||
* Contributing: http://www.tinymce.com/contributing
|
||||
*/
|
||||
|
||||
/*jshint loopfunc:true */
|
||||
/*global tinymce:true */
|
||||
|
||||
tinymce.PluginManager.add('noneditable', function(editor) {
|
||||
var TreeWalker = tinymce.dom.TreeWalker;
|
||||
var externalName = 'contenteditable', internalName = 'data-mce-' + externalName;
|
||||
var VK = tinymce.util.VK;
|
||||
|
||||
// Returns the content editable state of a node "true/false" or null
|
||||
function getContentEditable(node) {
|
||||
var contentEditable;
|
||||
|
||||
// Ignore non elements
|
||||
if (node.nodeType === 1) {
|
||||
// Check for fake content editable
|
||||
contentEditable = node.getAttribute(internalName);
|
||||
if (contentEditable && contentEditable !== "inherit") {
|
||||
return contentEditable;
|
||||
}
|
||||
|
||||
// Check for real content editable
|
||||
contentEditable = node.contentEditable;
|
||||
if (contentEditable !== "inherit") {
|
||||
return contentEditable;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Returns the noneditable parent or null if there is a editable before it or if it wasn't found
|
||||
function getNonEditableParent(node) {
|
||||
var state;
|
||||
|
||||
while (node) {
|
||||
state = getContentEditable(node);
|
||||
if (state) {
|
||||
return state === "false" ? node : null;
|
||||
}
|
||||
|
||||
node = node.parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
function handleContentEditableSelection() {
|
||||
var dom = editor.dom, selection = editor.selection, caretContainerId = 'mce_noneditablecaret', invisibleChar = '\uFEFF';
|
||||
|
||||
// Get caret container parent for the specified node
|
||||
function getParentCaretContainer(node) {
|
||||
while (node) {
|
||||
if (node.id === caretContainerId) {
|
||||
return node;
|
||||
}
|
||||
|
||||
node = node.parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
// Finds the first text node in the specified node
|
||||
function findFirstTextNode(node) {
|
||||
var walker;
|
||||
|
||||
if (node) {
|
||||
walker = new TreeWalker(node, node);
|
||||
|
||||
for (node = walker.current(); node; node = walker.next()) {
|
||||
if (node.nodeType === 3) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert caret container before/after target or expand selection to include block
|
||||
function insertCaretContainerOrExpandToBlock(target, before) {
|
||||
var caretContainer, rng;
|
||||
|
||||
// Select block
|
||||
if (getContentEditable(target) === "false") {
|
||||
if (dom.isBlock(target)) {
|
||||
selection.select(target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rng = dom.createRng();
|
||||
|
||||
if (getContentEditable(target) === "true") {
|
||||
if (!target.firstChild) {
|
||||
target.appendChild(editor.getDoc().createTextNode('\u00a0'));
|
||||
}
|
||||
|
||||
target = target.firstChild;
|
||||
before = true;
|
||||
}
|
||||
|
||||
/*
|
||||
caretContainer = dom.create('span', {
|
||||
id: caretContainerId,
|
||||
'data-mce-bogus': true,
|
||||
style:'border: 1px solid red'
|
||||
}, invisibleChar);
|
||||
*/
|
||||
|
||||
caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true}, invisibleChar);
|
||||
|
||||
if (before) {
|
||||
target.parentNode.insertBefore(caretContainer, target);
|
||||
} else {
|
||||
dom.insertAfter(caretContainer, target);
|
||||
}
|
||||
|
||||
rng.setStart(caretContainer.firstChild, 1);
|
||||
rng.collapse(true);
|
||||
selection.setRng(rng);
|
||||
|
||||
return caretContainer;
|
||||
}
|
||||
|
||||
// Removes any caret container except the one we might be in
|
||||
function removeCaretContainer(caretContainer) {
|
||||
var rng, child, currentCaretContainer, lastContainer;
|
||||
|
||||
if (caretContainer) {
|
||||
rng = selection.getRng(true);
|
||||
rng.setStartBefore(caretContainer);
|
||||
rng.setEndBefore(caretContainer);
|
||||
|
||||
child = findFirstTextNode(caretContainer);
|
||||
if (child && child.nodeValue.charAt(0) == invisibleChar) {
|
||||
child = child.deleteData(0, 1);
|
||||
}
|
||||
|
||||
dom.remove(caretContainer, true);
|
||||
|
||||
selection.setRng(rng);
|
||||
} else {
|
||||
currentCaretContainer = getParentCaretContainer(selection.getStart());
|
||||
while ((caretContainer = dom.get(caretContainerId)) && caretContainer !== lastContainer) {
|
||||
if (currentCaretContainer !== caretContainer) {
|
||||
child = findFirstTextNode(caretContainer);
|
||||
if (child && child.nodeValue.charAt(0) == invisibleChar) {
|
||||
child = child.deleteData(0, 1);
|
||||
}
|
||||
|
||||
dom.remove(caretContainer, true);
|
||||
}
|
||||
|
||||
lastContainer = caretContainer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Modifies the selection to include contentEditable false elements or insert caret containers
|
||||
function moveSelection() {
|
||||
var nonEditableStart, nonEditableEnd, isCollapsed, rng, element;
|
||||
|
||||
// Checks if there is any contents to the left/right side of caret returns the noneditable element or
|
||||
// any editable element if it finds one inside
|
||||
function hasSideContent(element, left) {
|
||||
var container, offset, walker, node, len;
|
||||
|
||||
container = rng.startContainer;
|
||||
offset = rng.startOffset;
|
||||
|
||||
// If endpoint is in middle of text node then expand to beginning/end of element
|
||||
if (container.nodeType == 3) {
|
||||
len = container.nodeValue.length;
|
||||
if ((offset > 0 && offset < len) || (left ? offset == len : offset === 0)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Can we resolve the node by index
|
||||
if (offset < container.childNodes.length) {
|
||||
// Browser represents caret position as the offset at the start of an element. When moving right
|
||||
// this is the element we are moving into so we consider our container to be child node at offset-1
|
||||
var pos = !left && offset > 0 ? offset-1 : offset;
|
||||
container = container.childNodes[pos];
|
||||
if (container.hasChildNodes()) {
|
||||
container = container.firstChild;
|
||||
}
|
||||
} else {
|
||||
// If not then the caret is at the last position in it's container and the caret container
|
||||
// should be inserted after the noneditable element
|
||||
return !left ? element : null;
|
||||
}
|
||||
}
|
||||
|
||||
// Walk left/right to look for contents
|
||||
walker = new TreeWalker(container, element);
|
||||
while ((node = walker[left ? 'prev' : 'next']())) {
|
||||
if (node.nodeType === 3 && node.nodeValue.length > 0) {
|
||||
return;
|
||||
} else if (getContentEditable(node) === "true") {
|
||||
// Found contentEditable=true element return this one to we can move the caret inside it
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
// Remove any existing caret containers
|
||||
removeCaretContainer();
|
||||
|
||||
// Get noneditable start/end elements
|
||||
isCollapsed = selection.isCollapsed();
|
||||
nonEditableStart = getNonEditableParent(selection.getStart());
|
||||
nonEditableEnd = getNonEditableParent(selection.getEnd());
|
||||
|
||||
// Is any fo the range endpoints noneditable
|
||||
if (nonEditableStart || nonEditableEnd) {
|
||||
rng = selection.getRng(true);
|
||||
|
||||
// If it's a caret selection then look left/right to see if we need to move the caret out side or expand
|
||||
if (isCollapsed) {
|
||||
nonEditableStart = nonEditableStart || nonEditableEnd;
|
||||
|
||||
if ((element = hasSideContent(nonEditableStart, true))) {
|
||||
// We have no contents to the left of the caret then insert a caret container before the noneditable element
|
||||
insertCaretContainerOrExpandToBlock(element, true);
|
||||
} else if ((element = hasSideContent(nonEditableStart, false))) {
|
||||
// We have no contents to the right of the caret then insert a caret container after the noneditable element
|
||||
insertCaretContainerOrExpandToBlock(element, false);
|
||||
} else {
|
||||
// We are in the middle of a noneditable so expand to select it
|
||||
selection.select(nonEditableStart);
|
||||
}
|
||||
} else {
|
||||
rng = selection.getRng(true);
|
||||
|
||||
// Expand selection to include start non editable element
|
||||
if (nonEditableStart) {
|
||||
rng.setStartBefore(nonEditableStart);
|
||||
}
|
||||
|
||||
// Expand selection to include end non editable element
|
||||
if (nonEditableEnd) {
|
||||
rng.setEndAfter(nonEditableEnd);
|
||||
}
|
||||
|
||||
selection.setRng(rng);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleKey(e) {
|
||||
var keyCode = e.keyCode, nonEditableParent, caretContainer, startElement, endElement;
|
||||
|
||||
function getNonEmptyTextNodeSibling(node, prev) {
|
||||
while ((node = node[prev ? 'previousSibling' : 'nextSibling'])) {
|
||||
if (node.nodeType !== 3 || node.nodeValue.length > 0) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function positionCaretOnElement(element, start) {
|
||||
selection.select(element);
|
||||
selection.collapse(start);
|
||||
}
|
||||
|
||||
function canDelete(backspace) {
|
||||
var rng, container, offset, nonEditableParent;
|
||||
|
||||
function removeNodeIfNotParent(node) {
|
||||
var parent = container;
|
||||
|
||||
while (parent) {
|
||||
if (parent === node) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
|
||||
dom.remove(node);
|
||||
moveSelection();
|
||||
}
|
||||
|
||||
function isNextPrevTreeNodeNonEditable() {
|
||||
var node, walker, nonEmptyElements = editor.schema.getNonEmptyElements();
|
||||
|
||||
walker = new tinymce.dom.TreeWalker(container, editor.getBody());
|
||||
while ((node = (backspace ? walker.prev() : walker.next()))) {
|
||||
// Found IMG/INPUT etc
|
||||
if (nonEmptyElements[node.nodeName.toLowerCase()]) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Found text node with contents
|
||||
if (node.nodeType === 3 && tinymce.trim(node.nodeValue).length > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Found non editable node
|
||||
if (getContentEditable(node) === "false") {
|
||||
removeNodeIfNotParent(node);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the content node is within a non editable parent
|
||||
if (getNonEditableParent(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selection.isCollapsed()) {
|
||||
rng = selection.getRng(true);
|
||||
container = rng.startContainer;
|
||||
offset = rng.startOffset;
|
||||
container = getParentCaretContainer(container) || container;
|
||||
|
||||
// Is in noneditable parent
|
||||
if ((nonEditableParent = getNonEditableParent(container))) {
|
||||
removeNodeIfNotParent(nonEditableParent);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the caret is in the middle of a text node
|
||||
if (container.nodeType == 3 && (backspace ? offset > 0 : offset < container.nodeValue.length)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Resolve container index
|
||||
if (container.nodeType == 1) {
|
||||
container = container.childNodes[offset] || container;
|
||||
}
|
||||
|
||||
// Check if previous or next tree node is non editable then block the event
|
||||
if (isNextPrevTreeNodeNonEditable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
startElement = selection.getStart();
|
||||
endElement = selection.getEnd();
|
||||
|
||||
// Disable all key presses in contentEditable=false except delete or backspace
|
||||
nonEditableParent = getNonEditableParent(startElement) || getNonEditableParent(endElement);
|
||||
if (nonEditableParent && (keyCode < 112 || keyCode > 124) && keyCode != VK.DELETE && keyCode != VK.BACKSPACE) {
|
||||
// Is Ctrl+c, Ctrl+v or Ctrl+x then use default browser behavior
|
||||
if ((tinymce.isMac ? e.metaKey : e.ctrlKey) && (keyCode == 67 || keyCode == 88 || keyCode == 86)) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
// Arrow left/right select the element and collapse left/right
|
||||
if (keyCode == VK.LEFT || keyCode == VK.RIGHT) {
|
||||
var left = keyCode == VK.LEFT;
|
||||
// If a block element find previous or next element to position the caret
|
||||
if (editor.dom.isBlock(nonEditableParent)) {
|
||||
var targetElement = left ? nonEditableParent.previousSibling : nonEditableParent.nextSibling;
|
||||
var walker = new TreeWalker(targetElement, targetElement);
|
||||
var caretElement = left ? walker.prev() : walker.next();
|
||||
positionCaretOnElement(caretElement, !left);
|
||||
} else {
|
||||
positionCaretOnElement(nonEditableParent, left);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Is arrow left/right, backspace or delete
|
||||
if (keyCode == VK.LEFT || keyCode == VK.RIGHT || keyCode == VK.BACKSPACE || keyCode == VK.DELETE) {
|
||||
caretContainer = getParentCaretContainer(startElement);
|
||||
if (caretContainer) {
|
||||
// Arrow left or backspace
|
||||
if (keyCode == VK.LEFT || keyCode == VK.BACKSPACE) {
|
||||
nonEditableParent = getNonEmptyTextNodeSibling(caretContainer, true);
|
||||
|
||||
if (nonEditableParent && getContentEditable(nonEditableParent) === "false") {
|
||||
e.preventDefault();
|
||||
|
||||
if (keyCode == VK.LEFT) {
|
||||
positionCaretOnElement(nonEditableParent, true);
|
||||
} else {
|
||||
dom.remove(nonEditableParent);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
removeCaretContainer(caretContainer);
|
||||
}
|
||||
}
|
||||
|
||||
// Arrow right or delete
|
||||
if (keyCode == VK.RIGHT || keyCode == VK.DELETE) {
|
||||
nonEditableParent = getNonEmptyTextNodeSibling(caretContainer);
|
||||
|
||||
if (nonEditableParent && getContentEditable(nonEditableParent) === "false") {
|
||||
e.preventDefault();
|
||||
|
||||
if (keyCode == VK.RIGHT) {
|
||||
positionCaretOnElement(nonEditableParent, false);
|
||||
} else {
|
||||
dom.remove(nonEditableParent);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
removeCaretContainer(caretContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((keyCode == VK.BACKSPACE || keyCode == VK.DELETE) && !canDelete(keyCode == VK.BACKSPACE)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.on('mousedown', function(e) {
|
||||
var node = editor.selection.getNode();
|
||||
|
||||
if (getContentEditable(node) === "false" && node == e.target) {
|
||||
// Expand selection on mouse down we can't block the default event since it's used for drag/drop
|
||||
moveSelection();
|
||||
}
|
||||
});
|
||||
|
||||
editor.on('mouseup keyup', moveSelection);
|
||||
editor.on('keydown', handleKey);
|
||||
}
|
||||
|
||||
var editClass, nonEditClass, nonEditableRegExps;
|
||||
|
||||
// Converts configured regexps to noneditable span items
|
||||
function convertRegExpsToNonEditable(e) {
|
||||
var i = nonEditableRegExps.length, content = e.content, cls = tinymce.trim(nonEditClass);
|
||||
|
||||
// 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], function(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>'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
e.content = content;
|
||||
}
|
||||
|
||||
editClass = " " + tinymce.trim(editor.getParam("noneditable_editable_class", "mceEditable")) + " ";
|
||||
nonEditClass = " " + tinymce.trim(editor.getParam("noneditable_noneditable_class", "mceNonEditable")) + " ";
|
||||
|
||||
// Setup noneditable regexps array
|
||||
nonEditableRegExps = editor.getParam("noneditable_regexp");
|
||||
if (nonEditableRegExps && !nonEditableRegExps.length) {
|
||||
nonEditableRegExps = [nonEditableRegExps];
|
||||
}
|
||||
|
||||
editor.on('PreInit', function() {
|
||||
handleContentEditableSelection();
|
||||
|
||||
if (nonEditableRegExps) {
|
||||
editor.on('BeforeSetContent', convertRegExpsToNonEditable);
|
||||
}
|
||||
|
||||
// Apply contentEditable true/false on elements with the noneditable/editable classes
|
||||
editor.parser.addAttributeFilter('class', function(nodes) {
|
||||
var i = nodes.length, className, node;
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
className = " " + node.attr("class") + " ";
|
||||
|
||||
if (className.indexOf(editClass) !== -1) {
|
||||
node.attr(internalName, "true");
|
||||
} else if (className.indexOf(nonEditClass) !== -1) {
|
||||
node.attr(internalName, "false");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Remove internal name
|
||||
editor.serializer.addAttributeFilter(internalName, function(nodes) {
|
||||
var i = nodes.length, node;
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
|
||||
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(externalName, null);
|
||||
node.attr(internalName, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Convert external name into internal name
|
||||
editor.parser.addAttributeFilter(externalName, function(nodes) {
|
||||
var i = nodes.length, node;
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
node.attr(internalName, node.attr(externalName));
|
||||
node.attr(externalName, null);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
editor.on('drop', function(e) {
|
||||
if (getNonEditableParent(e.target)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
1
tests/qunit/editor/external-plugins/noneditable/plugin.min.js
vendored
Normal file
1
tests/qunit/editor/external-plugins/noneditable/plugin.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
tinymce.PluginManager.add("noneditable",function(e){function t(e){var t;if(1===e.nodeType){if(t=e.getAttribute(u),t&&"inherit"!==t)return t;if(t=e.contentEditable,"inherit"!==t)return t}return null}function n(e){for(var n;e;){if(n=t(e))return"false"===n?e:null;e=e.parentNode}}function r(){function r(e){for(;e;){if(e.id===g)return e;e=e.parentNode}}function a(e){var t;if(e)for(t=new f(e,e),e=t.current();e;e=t.next())if(3===e.nodeType)return e}function i(n,r){var a,i;return"false"===t(n)&&u.isBlock(n)?void s.select(n):(i=u.createRng(),"true"===t(n)&&(n.firstChild||n.appendChild(e.getDoc().createTextNode(" ")),n=n.firstChild,r=!0),a=u.create("span",{id:g,"data-mce-bogus":!0},m),r?n.parentNode.insertBefore(a,n):u.insertAfter(a,n),i.setStart(a.firstChild,1),i.collapse(!0),s.setRng(i),a)}function o(e){var t,n,i,o;if(e)t=s.getRng(!0),t.setStartBefore(e),t.setEndBefore(e),n=a(e),n&&n.nodeValue.charAt(0)==m&&(n=n.deleteData(0,1)),u.remove(e,!0),s.setRng(t);else for(i=r(s.getStart());(e=u.get(g))&&e!==o;)i!==e&&(n=a(e),n&&n.nodeValue.charAt(0)==m&&(n=n.deleteData(0,1)),u.remove(e,!0)),o=e}function l(){function e(e,n){var r,a,i,o,l;if(r=d.startContainer,a=d.startOffset,3==r.nodeType){if(l=r.nodeValue.length,a>0&&l>a||(n?a==l:0===a))return}else{if(!(a<r.childNodes.length))return n?null:e;var u=!n&&a>0?a-1:a;r=r.childNodes[u],r.hasChildNodes()&&(r=r.firstChild)}for(i=new f(r,e);o=i[n?"prev":"next"]();){if(3===o.nodeType&&o.nodeValue.length>0)return;if("true"===t(o))return o}return e}var r,a,l,d,u;o(),l=s.isCollapsed(),r=n(s.getStart()),a=n(s.getEnd()),(r||a)&&(d=s.getRng(!0),l?(r=r||a,(u=e(r,!0))?i(u,!0):(u=e(r,!1))?i(u,!1):s.select(r)):(d=s.getRng(!0),r&&d.setStartBefore(r),a&&d.setEndAfter(a),s.setRng(d)))}function d(a){function i(e,t){for(;e=e[t?"previousSibling":"nextSibling"];)if(3!==e.nodeType||e.nodeValue.length>0)return e}function d(e,t){s.select(e),s.collapse(t)}function g(a){function i(e){for(var t=d;t;){if(t===e)return;t=t.parentNode}u.remove(e),l()}function o(){var r,o,l=e.schema.getNonEmptyElements();for(o=new tinymce.dom.TreeWalker(d,e.getBody());(r=a?o.prev():o.next())&&!l[r.nodeName.toLowerCase()]&&!(3===r.nodeType&&tinymce.trim(r.nodeValue).length>0);)if("false"===t(r))return i(r),!0;return n(r)?!0:!1}var f,d,c,g;if(s.isCollapsed()){if(f=s.getRng(!0),d=f.startContainer,c=f.startOffset,d=r(d)||d,g=n(d))return i(g),!1;if(3==d.nodeType&&(a?c>0:c<d.nodeValue.length))return!0;if(1==d.nodeType&&(d=d.childNodes[c]||d),o())return!1}return!0}var m,p,v,E,h=a.keyCode;if(v=s.getStart(),E=s.getEnd(),m=n(v)||n(E),m&&(112>h||h>124)&&h!=c.DELETE&&h!=c.BACKSPACE){if((tinymce.isMac?a.metaKey:a.ctrlKey)&&(67==h||88==h||86==h))return;if(a.preventDefault(),h==c.LEFT||h==c.RIGHT){var y=h==c.LEFT;if(e.dom.isBlock(m)){var T=y?m.previousSibling:m.nextSibling,C=new f(T,T),b=y?C.prev():C.next();d(b,!y)}else d(m,y)}}else if(h==c.LEFT||h==c.RIGHT||h==c.BACKSPACE||h==c.DELETE){if(p=r(v)){if(h==c.LEFT||h==c.BACKSPACE)if(m=i(p,!0),m&&"false"===t(m)){if(a.preventDefault(),h!=c.LEFT)return void u.remove(m);d(m,!0)}else o(p);if(h==c.RIGHT||h==c.DELETE)if(m=i(p),m&&"false"===t(m)){if(a.preventDefault(),h!=c.RIGHT)return void u.remove(m);d(m,!1)}else o(p)}if((h==c.BACKSPACE||h==c.DELETE)&&!g(h==c.BACKSPACE))return a.preventDefault(),!1}}var u=e.dom,s=e.selection,g="mce_noneditablecaret",m="";e.on("mousedown",function(n){var r=e.selection.getNode();"false"===t(r)&&r==n.target&&l()}),e.on("mouseup keyup",l),e.on("keydown",d)}function a(t){var n=l.length,r=t.content,a=tinymce.trim(o);if("raw"!=t.format){for(;n--;)r=r.replace(l[n],function(t){var n=arguments,i=n[n.length-2];return i>0&&'"'==r.charAt(i-1)?t:'<span class="'+a+'" data-mce-content="'+e.dom.encode(n[0])+'">'+e.dom.encode("string"==typeof n[1]?n[1]:n[0])+"</span>"});t.content=r}}var i,o,l,f=tinymce.dom.TreeWalker,d="contenteditable",u="data-mce-"+d,c=tinymce.util.VK;i=" "+tinymce.trim(e.getParam("noneditable_editable_class","mceEditable"))+" ",o=" "+tinymce.trim(e.getParam("noneditable_noneditable_class","mceNonEditable"))+" ",l=e.getParam("noneditable_regexp"),l&&!l.length&&(l=[l]),e.on("PreInit",function(){r(),l&&e.on("BeforeSetContent",a),e.parser.addAttributeFilter("class",function(e){for(var t,n,r=e.length;r--;)n=e[r],t=" "+n.attr("class")+" ",-1!==t.indexOf(i)?n.attr(u,"true"):-1!==t.indexOf(o)&&n.attr(u,"false")}),e.serializer.addAttributeFilter(u,function(e){for(var t,n=e.length;n--;)t=e[n],l&&t.attr("data-mce-content")?(t.name="#text",t.type=3,t.raw=!0,t.value=t.attr("data-mce-content")):(t.attr(d,null),t.attr(u,null))}),e.parser.addAttributeFilter(d,function(e){for(var t,n=e.length;n--;)t=e[n],t.attr(u,t.attr(d)),t.attr(d,null)})}),e.on("drop",function(e){n(e.target)&&e.preventDefault()})});
|
||||
2170
tests/qunit/editor/external-plugins/table/plugin.js
Normal file
2170
tests/qunit/editor/external-plugins/table/plugin.js
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/qunit/editor/external-plugins/table/plugin.min.js
vendored
Normal file
1
tests/qunit/editor/external-plugins/table/plugin.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
22
tests/qunit/editor/index.html
Normal file
22
tests/qunit/editor/index.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Test Runner</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="js/qunit/testrunner.css" type="text/css" />
|
||||
<script src="js/qunit/testrunner.js"></script>
|
||||
<script>
|
||||
TestRunner.addSuites([
|
||||
"tinymce/tests.js",
|
||||
"tinymce/dom/tests.js",
|
||||
"tinymce/html/tests.js",
|
||||
"tinymce/ui/tests.js",
|
||||
"tinymce/util/tests.js",
|
||||
"plugins/tests.js"
|
||||
]);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
20
tests/qunit/editor/js/qunit/QUnit.LICENSE
Normal file
20
tests/qunit/editor/js/qunit/QUnit.LICENSE
Normal file
@ -0,0 +1,20 @@
|
||||
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.
|
||||
119
tests/qunit/editor/js/qunit/qunit.css
Normal file
119
tests/qunit/editor/js/qunit/qunit.css
Normal file
@ -0,0 +1,119 @@
|
||||
|
||||
ol#qunit-tests {
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
margin:0;
|
||||
padding:0;
|
||||
list-style-position:inside;
|
||||
|
||||
font-size: smaller;
|
||||
}
|
||||
ol#qunit-tests li{
|
||||
padding:0.4em 0.5em 0.4em 2.5em;
|
||||
border-bottom:1px solid #fff;
|
||||
font-size:small;
|
||||
list-style-position:inside;
|
||||
}
|
||||
ol#qunit-tests li ol{
|
||||
box-shadow: inset 0px 2px 13px #999;
|
||||
-moz-box-shadow: inset 0px 2px 13px #999;
|
||||
-webkit-box-shadow: inset 0px 2px 13px #999;
|
||||
margin-top:0.5em;
|
||||
margin-left:0;
|
||||
padding:0.5em;
|
||||
background-color:#fff;
|
||||
border-radius:15px;
|
||||
-moz-border-radius: 15px;
|
||||
-webkit-border-radius: 15px;
|
||||
}
|
||||
ol#qunit-tests li li{
|
||||
border-bottom:none;
|
||||
margin:0.5em;
|
||||
background-color:#fff;
|
||||
list-style-position: inside;
|
||||
padding:0.4em 0.5em 0.4em 0.5em;
|
||||
}
|
||||
|
||||
ol#qunit-tests li li.pass{
|
||||
border-left:26px solid #C6E746;
|
||||
background-color:#fff;
|
||||
color:#5E740B;
|
||||
}
|
||||
ol#qunit-tests li li.fail{
|
||||
border-left:26px solid #EE5757;
|
||||
background-color:#fff;
|
||||
color:#710909;
|
||||
}
|
||||
ol#qunit-tests li.pass{
|
||||
background-color:#D2E0E6;
|
||||
color:#528CE0;
|
||||
}
|
||||
ol#qunit-tests li.fail{
|
||||
background-color:#EE5757;
|
||||
color:#000;
|
||||
}
|
||||
ol#qunit-tests li strong {
|
||||
cursor:pointer;
|
||||
}
|
||||
h1#qunit-header{
|
||||
background-color:#0d3349;
|
||||
margin:0;
|
||||
padding:0.5em 0 0.5em 1em;
|
||||
color:#fff;
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
border-top-right-radius:15px;
|
||||
border-top-left-radius:15px;
|
||||
-moz-border-radius-topright:15px;
|
||||
-moz-border-radius-topleft:15px;
|
||||
-webkit-border-top-right-radius:15px;
|
||||
-webkit-border-top-left-radius:15px;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 4px 4px 1px;
|
||||
}
|
||||
h2#qunit-banner{
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
height:5px;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
h2#qunit-banner.qunit-pass{
|
||||
background-color:#C6E746;
|
||||
}
|
||||
h2#qunit-banner.qunit-fail, #qunit-testrunner-toolbar {
|
||||
background-color:#EE5757;
|
||||
}
|
||||
#qunit-testrunner-toolbar {
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
padding:0;
|
||||
/*width:80%;*/
|
||||
padding:0em 0 0.5em 2em;
|
||||
font-size: small;
|
||||
}
|
||||
h2#qunit-userAgent {
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
background-color:#2b81af;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:#fff;
|
||||
font-size: small;
|
||||
padding:0.5em 0 0.5em 2.5em;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||
}
|
||||
p#qunit-testresult{
|
||||
font-family:"Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
|
||||
margin:0;
|
||||
font-size: small;
|
||||
color:#2b81af;
|
||||
border-bottom-right-radius:15px;
|
||||
border-bottom-left-radius:15px;
|
||||
-moz-border-radius-bottomright:15px;
|
||||
-moz-border-radius-bottomleft:15px;
|
||||
-webkit-border-bottom-right-radius:15px;
|
||||
-webkit-border-bottom-left-radius:15px;
|
||||
background-color:#D2E0E6;
|
||||
padding:0.5em 0.5em 0.5em 2.5em;
|
||||
}
|
||||
strong b.fail{
|
||||
color:#710909;
|
||||
}
|
||||
strong b.pass{
|
||||
color:#5E740B;
|
||||
}
|
||||
1265
tests/qunit/editor/js/qunit/qunit.js
Normal file
1265
tests/qunit/editor/js/qunit/qunit.js
Normal file
File diff suppressed because it is too large
Load Diff
13
tests/qunit/editor/js/qunit/reporter.js
Normal file
13
tests/qunit/editor/js/qunit/reporter.js
Normal file
@ -0,0 +1,13 @@
|
||||
(function() {
|
||||
if (parent != window && window.QUnit) {
|
||||
QUnit.done = function(data) {
|
||||
if (window.__$coverObject) {
|
||||
parent.TestRunner.addCoverObject(window.__$coverObject);
|
||||
}
|
||||
|
||||
if (parent.TestRunner) {
|
||||
parent.TestRunner.done(data.failed, data.total, document.title);
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
151
tests/qunit/editor/js/qunit/testrunner.css
Normal file
151
tests/qunit/editor/js/qunit/testrunner.css
Normal file
@ -0,0 +1,151 @@
|
||||
body, html {
|
||||
margin: 0; padding: 0;
|
||||
overflow: hidden;
|
||||
width: 100%; height: 100%;
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
font-size: 12px;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
color: #111;
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.runner, .sidebar, .controls, .tests {
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background: #DDD;
|
||||
}
|
||||
|
||||
.controls {
|
||||
background: #BBB;
|
||||
}
|
||||
|
||||
.controls div {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.tests {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.suite {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.suite .selection {
|
||||
float: right;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.stats {
|
||||
display: none;
|
||||
float: right;
|
||||
margin-right: 3px;
|
||||
font-size: 10px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.test {
|
||||
margin: 5px;
|
||||
background: #EEE;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.passed a {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
span.passed {
|
||||
color: green;
|
||||
}
|
||||
|
||||
div.failed {
|
||||
background: #EE5757;
|
||||
}
|
||||
|
||||
span.failed {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.failed span.failed {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.running .stats, .failed .stats, .passed .stats, .skipped .stats {
|
||||
display: inline;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.suite-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.gstatus {
|
||||
float: right;
|
||||
}
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
*[unselectable] {
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
button#coverage {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#coverview {
|
||||
display: none;
|
||||
position: fixed;
|
||||
background: #fff;
|
||||
z-index: 9;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
#coverview iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#coverview .close {
|
||||
position: absolute;
|
||||
right: -14px;
|
||||
top: -18px;
|
||||
color: #000;
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
z-index: 11;
|
||||
text-decoration: none;
|
||||
font-family: Verdana;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 0 2px #fff;
|
||||
}
|
||||
|
||||
#overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #ccc;
|
||||
background: rgba(0,0,0,0.3);
|
||||
}
|
||||
540
tests/qunit/editor/js/qunit/testrunner.js
Normal file
540
tests/qunit/editor/js/qunit/testrunner.js
Normal file
@ -0,0 +1,540 @@
|
||||
// Quick and dirty testrunner hack, it's ugly but it works
|
||||
(function() {
|
||||
function TestRunner() {
|
||||
var suites = [], suiteUrls = [], actions = {};
|
||||
var started, currentTest, testUrls = [], globalStats = {};
|
||||
var coverObjects = [];
|
||||
|
||||
function get(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
function addClass(elm, cls) {
|
||||
if (cls && !hasClass(elm, cls)) {
|
||||
elm.className += elm.className ? ' ' + cls : cls;
|
||||
}
|
||||
}
|
||||
|
||||
function removeClass(elm, cls) {
|
||||
if (hasClass(elm, cls)) {
|
||||
elm.className = elm.className.replace(new RegExp("(^|\\s+)" + cls + "(\\s+|$)", "g"), ' ');
|
||||
}
|
||||
}
|
||||
|
||||
function hasClass(elm, cls) {
|
||||
return elm && cls && (' ' + elm.className + ' ').indexOf(' ' + cls + ' ') !== -1;
|
||||
}
|
||||
|
||||
function init() {
|
||||
function loadNext() {
|
||||
var url = suiteUrls.shift();
|
||||
|
||||
if (url) {
|
||||
loadSuite(url, function(json, url) {
|
||||
json.baseURL = url.substring(0, url.lastIndexOf('/'));
|
||||
if (json.baseURL) {
|
||||
json.baseURL += '/';
|
||||
}
|
||||
|
||||
suites.push(json);
|
||||
loadNext();
|
||||
});
|
||||
} else {
|
||||
render();
|
||||
reflow();
|
||||
hashToStates();
|
||||
// WP
|
||||
wpTests();
|
||||
}
|
||||
}
|
||||
|
||||
loadNext();
|
||||
}
|
||||
|
||||
function getHashData() {
|
||||
var pos, hash = location.hash, items, item, data = {}, i;
|
||||
|
||||
pos = hash.indexOf('!');
|
||||
if (pos > 0) {
|
||||
items = hash.substring(pos + 1).split('&');
|
||||
for (i = 0; i < items.length; i++) {
|
||||
item = items[i].split('=');
|
||||
data[item[0]] = item[1];
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function setHashData(data) {
|
||||
var name, hashItems = [];
|
||||
|
||||
for (name in data) {
|
||||
if (data[name] !== null) {
|
||||
hashItems.push(name + '=' + data[name]);
|
||||
}
|
||||
}
|
||||
|
||||
location.hash = '!' + hashItems.join('&');
|
||||
}
|
||||
|
||||
function statesToHash() {
|
||||
var i, checkboxes, states = [], hasDisabled;
|
||||
|
||||
checkboxes = get('tests').getElementsByTagName("input");
|
||||
for (i = 0; i < checkboxes.length; i++) {
|
||||
states[i] = checkboxes[i].checked ? '1' : '0';
|
||||
hasDisabled = hasDisabled || states[i] === '0';
|
||||
}
|
||||
|
||||
setHashData({
|
||||
min: get('min').checked,
|
||||
jsrobot: get('jsrobot').checked,
|
||||
tests: hasDisabled ? states.join('') : null
|
||||
});
|
||||
}
|
||||
|
||||
function hashToStates() {
|
||||
var i, data = getHashData(location.hash), checkboxes;
|
||||
|
||||
if (typeof(data.min) != "undefined") {
|
||||
get('min').checked = data.min === "true";
|
||||
}
|
||||
|
||||
if (typeof(data.jsrobot) != "undefined") {
|
||||
get('jsrobot').checked = data.jsrobot === "true";
|
||||
}
|
||||
|
||||
if (typeof(data.tests) != "undefined") {
|
||||
checkboxes = get('tests').getElementsByTagName("input");
|
||||
for (i = 0; i < checkboxes.length; i++) {
|
||||
checkboxes[i].checked = data.tests.substr(i, 1) === '1';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addAction(name, action) {
|
||||
actions[name] = action;
|
||||
}
|
||||
|
||||
function toggleCheckboxes(elm, state) {
|
||||
var checkboxes = (elm || get('tests')).getElementsByTagName("input"), i;
|
||||
|
||||
for (i = 0; i < checkboxes.length; i++) {
|
||||
checkboxes[i].checked = state;
|
||||
}
|
||||
}
|
||||
|
||||
function start() {
|
||||
var si, ti, tests;
|
||||
|
||||
testUrls = [];
|
||||
for (si = 0; si < suites.length; si++) {
|
||||
tests = suites[si].tests;
|
||||
for (ti = 0; ti < tests.length; ti++) {
|
||||
if (get('c' + si + '-' + ti).checked) {
|
||||
testUrls.push(tests[ti]);
|
||||
}
|
||||
|
||||
removeClass(get('t' + si + '-' + ti), "passed");
|
||||
removeClass(get('t' + si + '-' + ti), "failed");
|
||||
}
|
||||
}
|
||||
|
||||
globalStats = {
|
||||
total: 0,
|
||||
failed: 0
|
||||
};
|
||||
|
||||
// Start first test
|
||||
currentTest = testUrls.shift();
|
||||
if (currentTest) {
|
||||
get('testview').src = currentTest.url + "?min=" + get('min').checked;
|
||||
}
|
||||
|
||||
get('coverage').disabled = true;
|
||||
}
|
||||
|
||||
function stop() {
|
||||
started = false;
|
||||
get('testview').src = 'javascript:""';
|
||||
get('start').innerHTML = 'start';
|
||||
|
||||
if (coverObjects.length) {
|
||||
get('coverage').disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
addAction("start", function(elm) {
|
||||
started = !started;
|
||||
|
||||
if (started) {
|
||||
start();
|
||||
} else {
|
||||
stop();
|
||||
reset();
|
||||
}
|
||||
|
||||
elm.innerHTML = started ? 'stop' : 'start';
|
||||
});
|
||||
|
||||
addAction("select-none", function(elm) {
|
||||
toggleCheckboxes(get('s' + elm.getAttribute("data-suite")), false);
|
||||
reset();
|
||||
});
|
||||
|
||||
addAction("select-all", function(elm) {
|
||||
toggleCheckboxes(get('s' + elm.getAttribute("data-suite")), true);
|
||||
reset();
|
||||
});
|
||||
|
||||
addAction("select-failed", function(elm) {
|
||||
toggleCheckboxes(get('s' + elm.getAttribute("data-suite")), false);
|
||||
reset();
|
||||
|
||||
var targetIndex = elm.getAttribute("data-suite");
|
||||
|
||||
for (si = 0; si < suites.length; si++) {
|
||||
if (targetIndex !== null && targetIndex != si) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tests = suites[si].tests;
|
||||
for (ti = 0; ti < tests.length; ti++) {
|
||||
if (tests[ti].failed) {
|
||||
get('c' + si + '-' + ti).checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// WP
|
||||
function wpTests( element ) {
|
||||
var si, ti, tests, targetIndex = null;
|
||||
|
||||
if ( element ) {
|
||||
targetIndex = element.getAttribute("data-suite");
|
||||
}
|
||||
|
||||
toggleCheckboxes( get( 's' + targetIndex ), false );
|
||||
reset();
|
||||
|
||||
for ( si = 0; si < suites.length; si++ ) {
|
||||
if ( targetIndex !== null && targetIndex != si ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tests = suites[si].tests;
|
||||
|
||||
if ( si === 0 || si === 2 || si === 3 || si === 4 ) {
|
||||
for ( ti in tests ) {
|
||||
get( 'c' + si + '-' + ti ).checked = true;
|
||||
}
|
||||
} else if ( si === 1 ) {
|
||||
for ( ti in tests ) {
|
||||
if ( ti !== '1' ) {
|
||||
// No jQuery integration
|
||||
get( 'c' + si + '-' + ti ).checked = true;
|
||||
}
|
||||
}
|
||||
} else if ( si === 5 ) {
|
||||
for ( ti in tests ) {
|
||||
// Only the media and paste plugins
|
||||
if ( ti === '0' || ti === '2' ) {
|
||||
get( 'c' + si + '-' + ti ).checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WP
|
||||
addAction("select-wordpress", wpTests );
|
||||
|
||||
addAction("coverage", function(elm) {
|
||||
if (elm.disabled) {
|
||||
return;
|
||||
}
|
||||
showCoverage();
|
||||
});
|
||||
|
||||
function render() {
|
||||
var si, ti, tests, html = '';
|
||||
|
||||
var div = document.createElement('div');
|
||||
addClass(div, "runner");
|
||||
|
||||
html += '<div id="sidebar" class="sidebar" unselectable="true">';
|
||||
html += '<div id="controls" class="controls">';
|
||||
html += '<div>';
|
||||
html += '<button id="start" data-action="start">Start</button>';
|
||||
html += '<label><input id="min" type="checkbox" checked>Minified</label>';
|
||||
html += '<label style="display:none"><input id="jsrobot" type="checkbox">JSRobot</label>';
|
||||
html += '<button id="coverage" data-action="coverage" disabled>Coverage</button>';
|
||||
html += '</div>';
|
||||
html += '<div>';
|
||||
html += '<span id="gstatus" class="gstatus"></span>';
|
||||
html += 'Select: ';
|
||||
html += '<a data-action="select-wordpress" href="javascript:;">WP</a> ';
|
||||
html += '<a data-action="select-all" href="javascript:;">[All]</a> ';
|
||||
html += '<a data-action="select-none" href="javascript:;">[None]</a> ';
|
||||
html += '<a data-action="select-failed" href="javascript:;">[Failed]</a>';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
html += '<div id="tests" class="tests">';
|
||||
|
||||
for (si = 0; si < suites.length; si++) {
|
||||
tests = suites[si].tests;
|
||||
html += '<div id="s' + si + '" class="suite"><div class="suite-title">';
|
||||
html += '<div class="selection">';
|
||||
html += '<a data-action="select-wordpress" data-suite="' + si + '" href="javascript:;">WP</a> ';
|
||||
html += '<a data-action="select-all" data-suite="' + si + '" href="javascript:;">[All]</a> ';
|
||||
html += '<a data-action="select-none" data-suite="' + si + '" href="javascript:;">[None]</a> ';
|
||||
html += '<a data-action="select-failed" data-suite="' + si + '" href="javascript:;">[Failed]</a>';
|
||||
html += '</div>' + suites[si].title;
|
||||
html += '</div>';
|
||||
for (ti = 0; ti < tests.length; ti++) {
|
||||
tests[ti].suiteIndex = si;
|
||||
tests[ti].testIndex = ti;
|
||||
tests[ti].url = suites[si].baseURL + tests[ti].url;
|
||||
|
||||
html += (
|
||||
'<div id="t' + si + '-' + ti + '" class="test">' +
|
||||
'<span id="s' + si + '-' + ti + '" class="stats">Running</span>' +
|
||||
'<input id="c' + si + '-' + ti + '" type="checkbox" checked />' +
|
||||
'<a href="' + tests[ti].url + '" target="testview">' + tests[ti].title + '</a>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<iframe id="testview" name="testview" src="javascript:\'\'"></iframe>';
|
||||
|
||||
// coverage
|
||||
html += '<div id="overlay"></div>';
|
||||
html += '<div id="coverview">';
|
||||
html += '<a class="close" href="javascript:TestRunner.hideCoverage();" title="Close">x</a>';
|
||||
html += '<iframe frameborder="0" src="javascript:\'\'"></iframe>';
|
||||
html += '</div>';
|
||||
|
||||
div.innerHTML = html;
|
||||
document.body.appendChild(div);
|
||||
|
||||
get('sidebar').onclick = function(e) {
|
||||
var target;
|
||||
|
||||
e = e || event;
|
||||
target = e.target || e.srcElement;
|
||||
|
||||
if ((action = actions[target.getAttribute("data-action")])) {
|
||||
action(target);
|
||||
}
|
||||
|
||||
statesToHash();
|
||||
};
|
||||
}
|
||||
|
||||
function addSuites(urls) {
|
||||
suiteUrls.push.apply(suiteUrls, urls);
|
||||
}
|
||||
|
||||
function loadSuite(url, callback) {
|
||||
var xhr;
|
||||
|
||||
function ready() {
|
||||
if (xhr.readyState == 4) {
|
||||
callback(eval("(" + xhr.responseText + ")"), url);
|
||||
xhr = null;
|
||||
} else {
|
||||
setTimeout(ready, 10);
|
||||
}
|
||||
}
|
||||
|
||||
xhr = new XMLHttpRequest();
|
||||
|
||||
if (xhr) {
|
||||
xhr.open('GET', url, true);
|
||||
xhr.send();
|
||||
setTimeout(ready, 10);
|
||||
}
|
||||
}
|
||||
|
||||
function reflow() {
|
||||
var viewPortW, viewPortH, sideBarWidth, controlsHeight;
|
||||
|
||||
function rect(id, x, y, w, h) {
|
||||
var style, elm;
|
||||
|
||||
if ((elm = get(id))) {
|
||||
style = elm.style;
|
||||
style.left = x + "px";
|
||||
style.top = y + "px";
|
||||
style.width = w + "px";
|
||||
style.height = h + "px";
|
||||
}
|
||||
}
|
||||
|
||||
viewPortW = window.innerWidth || document.documentElement.clientWidth;
|
||||
viewPortH = window.innerHeight || document.documentElement.clientHeight;
|
||||
|
||||
sideBarWidth = 300;
|
||||
controlsHeight = 60;
|
||||
|
||||
rect('testview', sideBarWidth, 0, viewPortW - sideBarWidth, viewPortH);
|
||||
rect('sidebar', 0, 0, sideBarWidth, viewPortH);
|
||||
rect('controls', 0, 0, sideBarWidth, controlsHeight);
|
||||
rect('tests', 0, controlsHeight, sideBarWidth, viewPortH - controlsHeight);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
var si, tests, ti;
|
||||
|
||||
stop();
|
||||
get('gstatus').innerHTML = '';
|
||||
removeClass(get("controls"), "failed");
|
||||
|
||||
for (si = 0; si < suites.length; si++) {
|
||||
tests = suites[si].tests;
|
||||
for (ti = 0; ti < tests.length; ti++) {
|
||||
removeClass(get('t' + si + '-' + ti), "passed");
|
||||
removeClass(get('t' + si + '-' + ti), "failed");
|
||||
removeClass(get('t' + si + '-' + ti), "running");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateGlobalStatus() {
|
||||
get('gstatus').innerHTML = 'Total: ' + globalStats.total + ", Failed: " + globalStats.failed;
|
||||
addClass(get("controls"), globalStats.failed > 0 ? "failed" : "");
|
||||
}
|
||||
|
||||
function done(failed, total) {
|
||||
var nextTest, currentTestElm;
|
||||
|
||||
function runNextTest() {
|
||||
if ((nextTest = testUrls.shift())) {
|
||||
currentTest = nextTest;
|
||||
currentTestElm = get('t' + currentTest.suiteIndex + '-' + currentTest.testIndex);
|
||||
currentTestElm.scrollIntoView(false);
|
||||
|
||||
if (nextTest.jsrobot === true && !get('jsrobot').checked) {
|
||||
get('s' + currentTest.suiteIndex + '-' + currentTest.testIndex).innerHTML = 'Skipped';
|
||||
addClass(currentTestElm, "skipped");
|
||||
runNextTest();
|
||||
} else {
|
||||
addClass(currentTestElm, "running");
|
||||
get('testview').src = nextTest.url + "?min=" + get('min').checked;
|
||||
}
|
||||
} else {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
if (started) {
|
||||
currentTest.failed = failed;
|
||||
currentTest.total = total;
|
||||
|
||||
globalStats.total += total;
|
||||
globalStats.failed += failed;
|
||||
updateGlobalStatus();
|
||||
|
||||
get('s' + currentTest.suiteIndex + '-' + currentTest.testIndex).innerHTML = (
|
||||
'(<span class="failed">' + failed + '</span>, ' +
|
||||
'<span class="passed">' + (total - failed) + '</span>, ' +
|
||||
'<span class="total">' + total + '</span>)'
|
||||
);
|
||||
|
||||
addClass(get('t' + currentTest.suiteIndex + '-' + currentTest.testIndex), failed > 0 ? 'failed' : 'passed');
|
||||
removeClass(currentTestElm, "running");
|
||||
|
||||
runNextTest();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function addCoverObject(coverObject) {
|
||||
coverObjects.push(coverObject);
|
||||
}
|
||||
|
||||
|
||||
// this is going to be called from the coverage iframe
|
||||
function getCoverObject() {
|
||||
var coverObject = {}, fileName, gaps, gap, count;
|
||||
|
||||
for (var i = 0, length = coverObjects.length; i < length; i++) {
|
||||
for (fileName in coverObjects[i]) {
|
||||
gaps = coverObjects[i][fileName];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function showCoverage() {
|
||||
var overlay, coverView, viewPortW, viewPortH;
|
||||
|
||||
viewPortW = window.innerWidth || document.documentElement.clientWidth;
|
||||
viewPortH = window.innerHeight || document.documentElement.clientHeight;
|
||||
|
||||
overlay = get('overlay');
|
||||
overlay.style.display = 'block';
|
||||
|
||||
coverView = get('coverview');
|
||||
coverView.style.left = '30px';
|
||||
coverView.style.top = '30px';
|
||||
coverView.style.width = (viewPortW - 60) + 'px';
|
||||
coverView.style.height = (viewPortH - 60) + 'px';
|
||||
coverView.style.display = 'block';
|
||||
|
||||
coverView.getElementsByTagName('iframe')[0].src = 'coverage/index.html';
|
||||
}
|
||||
|
||||
function hideCoverage() {
|
||||
get('overlay').style.display = 'none';
|
||||
get('coverview').style.display = 'none';
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
addSuites: addSuites,
|
||||
reflow: reflow,
|
||||
done: done,
|
||||
addCoverObject: addCoverObject,
|
||||
getCoverObject: getCoverObject,
|
||||
showCoverage: showCoverage,
|
||||
hideCoverage: hideCoverage
|
||||
};
|
||||
}
|
||||
|
||||
var testRunner = new TestRunner();
|
||||
|
||||
self.onload = function() {
|
||||
testRunner.init();
|
||||
};
|
||||
|
||||
self.onresize = function() {
|
||||
testRunner.reflow();
|
||||
};
|
||||
|
||||
self.TestRunner = testRunner;
|
||||
})();
|
||||
17
tests/qunit/editor/js/tinymce_loader.js
Normal file
17
tests/qunit/editor/js/tinymce_loader.js
Normal file
@ -0,0 +1,17 @@
|
||||
// Edited for WordPress
|
||||
(function() {
|
||||
var baseURL;
|
||||
|
||||
// Get base where the tinymce script is located
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
for ( var i = 0; i < scripts.length; i++ ) {
|
||||
var src = scripts[i].src;
|
||||
|
||||
if ( /tinymce_loader\.js/.test( src ) ) {
|
||||
baseURL = src.substring( 0, src.indexOf('/tests/qunit/') );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
document.write('<script src="' + baseURL + '/src/wp-includes/js/tinymce/tinymce.min.js"></script>');
|
||||
})();
|
||||
299
tests/qunit/editor/js/utils.js
Normal file
299
tests/qunit/editor/js/utils.js
Normal file
@ -0,0 +1,299 @@
|
||||
function fontFace(face) {
|
||||
if (tinymce.isOpera) {
|
||||
return "'" + face + "'";
|
||||
} else {
|
||||
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 initWhenTinyAndRobotAreReady(initTinyFunction) {
|
||||
function loaded() {
|
||||
QUnit.start();
|
||||
}
|
||||
|
||||
tinymce.on('AddEditor', function(e) {
|
||||
e.editor.on('Init', function() {
|
||||
loaded();
|
||||
});
|
||||
});
|
||||
|
||||
window.robot.onload(initTinyFunction);
|
||||
}
|
||||
|
||||
function trimContent(content) {
|
||||
return content.replace(/^<p> <\/p>\n?/, '').replace(/\n?<p> <\/p>$/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fakes a key event.
|
||||
*
|
||||
* @param {Element/String} e DOM element object or element id to send fake event to.
|
||||
* @param {String} na Event name to fake like "keydown".
|
||||
* @param {Object} o Optional object with data to send with the event like keyCode and charCode.
|
||||
*/
|
||||
function fakeKeyEvent(e, na, o) {
|
||||
var ev;
|
||||
|
||||
o = tinymce.extend({
|
||||
keyCode : 13,
|
||||
charCode : 0
|
||||
}, o);
|
||||
|
||||
e = tinymce.DOM.get(e);
|
||||
|
||||
if (e.fireEvent) {
|
||||
ev = document.createEventObject();
|
||||
tinymce.extend(ev, o);
|
||||
e.fireEvent('on' + na, ev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.createEvent) {
|
||||
try {
|
||||
// Fails in Safari
|
||||
ev = document.createEvent('KeyEvents');
|
||||
ev.initKeyEvent(na, true, true, window, false, false, false, false, o.keyCode, o.charCode);
|
||||
} catch (ex) {
|
||||
ev = document.createEvent('Events');
|
||||
ev.initEvent(na, true, true);
|
||||
|
||||
ev.keyCode = o.keyCode;
|
||||
ev.charCode = o.charCode;
|
||||
}
|
||||
} else {
|
||||
ev = document.createEvent('UIEvents');
|
||||
|
||||
if (ev.initUIEvent)
|
||||
ev.initUIEvent(na, true, true, window, 1);
|
||||
|
||||
ev.keyCode = o.keyCode;
|
||||
ev.charCode = o.charCode;
|
||||
}
|
||||
|
||||
e.dispatchEvent(ev);
|
||||
}
|
||||
|
||||
function normalizeRng(rng) {
|
||||
if (rng.startContainer.nodeType == 3) {
|
||||
if (rng.startOffset == 0)
|
||||
rng.setStartBefore(rng.startContainer);
|
||||
else if (rng.startOffset >= rng.startContainer.nodeValue.length - 1)
|
||||
rng.setStartAfter(rng.startContainer);
|
||||
}
|
||||
|
||||
if (rng.endContainer.nodeType == 3) {
|
||||
if (rng.endOffset == 0)
|
||||
rng.setEndBefore(rng.endContainer);
|
||||
else if (rng.endOffset >= rng.endContainer.nodeValue.length - 1)
|
||||
rng.setEndAfter(rng.endContainer);
|
||||
}
|
||||
|
||||
return rng;
|
||||
}
|
||||
|
||||
// TODO: Replace this with the new event logic in 3.5
|
||||
function type(chr) {
|
||||
var editor = tinymce.activeEditor, keyCode, charCode, event = tinymce.dom.Event, evt, startElm, rng;
|
||||
|
||||
function fakeEvent(target, type, evt) {
|
||||
editor.dom.fire(target, type, evt);
|
||||
}
|
||||
|
||||
// Numeric keyCode
|
||||
if (typeof(chr) == "number") {
|
||||
charCode = keyCode = chr;
|
||||
} 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 = charCode;
|
||||
}
|
||||
} else {
|
||||
evt = chr;
|
||||
}
|
||||
|
||||
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.startContainer.nodeType == 1 && rng.collapsed) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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.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, '');
|
||||
|
||||
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);
|
||||
}
|
||||
170
tests/qunit/editor/plugins/autolink.html
Normal file
170
tests/qunit/editor/plugins/autolink.html
Normal file
@ -0,0 +1,170 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Automatic link tests</title>
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script src="js/dsl.js"></script>
|
||||
<script src="js/autolink.actions.js"></script>
|
||||
<script src="js/states.js"></script>
|
||||
<script><!--
|
||||
window.robotUsesSymbols = true;
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("Automatic Links", {
|
||||
autostart: false,
|
||||
setup: function() {
|
||||
window.queue = new dsl.Queue();
|
||||
}
|
||||
});
|
||||
|
||||
if (!tinymce.isIE) {
|
||||
asyncTest('Typing a HTTP URL', function() {
|
||||
TypingHTTPURL.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="http://www.ephox.com">http://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingHTTPURL.inA(ParagraphWithMarginLeft).gives(new RegExp('^<p style="margin-left: 60px;"><a href="http://www.ephox.com">http://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingHTTPURL.inA(ParagraphWithPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px;"><a href="http://www.ephox.com">http://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingHTTPURL.inA(ParagraphWithMarginAndPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px; margin-left: 60px;"><a href="http://www.ephox.com">http://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingHTTPURL.inA(NonEmptyHeading).gives(new RegExp('^<h1><a href="http://www.ephox.com">http://www.ephox.com</a>(\\s| )Test</h1>$'));
|
||||
TypingHTTPURL.inA(TableCellWithoutBrs2).gives(new RegExp('^<table><tbody><tr><td><a href="http://www.ephox.com">http://www.ephox.com</a>(\\s| )Test</td><td> </td></tr></tbody></table>$'));
|
||||
TypingHTTPURL.inA(TableCellWithBrsFirstLine2).gives(new RegExp('^<table><tbody><tr><td><a href="http://www.ephox.com">http://www.ephox.com</a>(\\s| )Test<br />Line 2</td><td> </td></tr></tbody></table>$'));
|
||||
|
||||
TypingEclipsedHTTPURL.inA(NonEmptyParagraph).gives(new RegExp('^<p>\\(<a href="http://www.ephox.com">http://www.ephox.com</a>\\)(\\s| )Test</p>$'));
|
||||
|
||||
TypingHTTPURLAndNewline.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="http://www.ephox.com">http://www.ephox.com</a></p><p>(Test|<a href=\"http://www.ephox.com\"></a>Test)</p>$'));
|
||||
|
||||
queue.done();
|
||||
});
|
||||
|
||||
asyncTest('Typing a HTTPS URL', function() {
|
||||
TypingHTTPSURL.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="https://www.ephox.com">https://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingHTTPSURL.inA(ParagraphWithMarginLeft).gives(new RegExp('^<p style="margin-left: 60px;"><a href="https://www.ephox.com">https://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingHTTPSURL.inA(ParagraphWithPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px;"><a href="https://www.ephox.com">https://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingHTTPSURL.inA(ParagraphWithMarginAndPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px; margin-left: 60px;"><a href="https://www.ephox.com">https://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingHTTPSURL.inA(NonEmptyHeading).gives(new RegExp('^<h1><a href="https://www.ephox.com">https://www.ephox.com</a>(\\s| )Test</h1>$'));
|
||||
TypingHTTPSURL.inA(TableCellWithoutBrs2).gives(new RegExp('^<table><tbody><tr><td><a href="https://www.ephox.com">https://www.ephox.com</a>(\\s| )Test</td><td> </td></tr></tbody></table>$'));
|
||||
TypingHTTPSURL.inA(TableCellWithBrsFirstLine2).gives(new RegExp('^<table><tbody><tr><td><a href="https://www.ephox.com">https://www.ephox.com</a>(\\s| )Test<br />Line 2</td><td> </td></tr></tbody></table>$'));
|
||||
|
||||
TypingEclipsedHTTPSURL.inA(NonEmptyParagraph).gives(new RegExp('^<p>\\(<a href="https://www.ephox.com">https://www.ephox.com</a>\\)(\\s| )Test</p>$'));
|
||||
|
||||
TypingHTTPSURLAndNewline.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="https://www.ephox.com">https://www.ephox.com</a></p><p>(Test|<a href=\"https://www.ephox.com\"></a>Test)</p>$'));
|
||||
|
||||
queue.done();
|
||||
});
|
||||
|
||||
asyncTest('Typing a SSH URL', function() {
|
||||
TypingSSHURL.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="ssh://www.ephox.com">ssh://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingSSHURL.inA(ParagraphWithMarginLeft).gives(new RegExp('^<p style="margin-left: 60px;"><a href="ssh://www.ephox.com">ssh://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingSSHURL.inA(ParagraphWithPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px;"><a href="ssh://www.ephox.com">ssh://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingSSHURL.inA(ParagraphWithMarginAndPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px; margin-left: 60px;"><a href="ssh://www.ephox.com">ssh://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingSSHURL.inA(NonEmptyHeading).gives(new RegExp('^<h1><a href="ssh://www.ephox.com">ssh://www.ephox.com</a>(\\s| )Test</h1>$'));
|
||||
TypingSSHURL.inA(TableCellWithoutBrs2).gives(new RegExp('^<table><tbody><tr><td><a href="ssh://www.ephox.com">ssh://www.ephox.com</a>(\\s| )Test</td><td> </td></tr></tbody></table>$'));
|
||||
TypingSSHURL.inA(TableCellWithBrsFirstLine2).gives(new RegExp('^<table><tbody><tr><td><a href="ssh://www.ephox.com">ssh://www.ephox.com</a>(\\s| )Test<br />Line 2</td><td> </td></tr></tbody></table>$'));
|
||||
|
||||
TypingEclipsedSSHURL.inA(NonEmptyParagraph).gives(new RegExp('^<p>\\(<a href="ssh://www.ephox.com">ssh://www.ephox.com</a>\\)(\\s| )Test</p>$'));
|
||||
|
||||
TypingSSHURLAndNewline.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="ssh://www.ephox.com">ssh://www.ephox.com</a></p><p>(Test|<a href=\"ssh://www.ephox.com\"></a>Test)</p>$'));
|
||||
|
||||
queue.done();
|
||||
});
|
||||
|
||||
asyncTest('Typing a FTP URL', function() {
|
||||
TypingFTPURL.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="ftp://www.ephox.com">ftp://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingFTPURL.inA(ParagraphWithMarginLeft).gives(new RegExp('^<p style="margin-left: 60px;"><a href="ftp://www.ephox.com">ftp://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingFTPURL.inA(ParagraphWithPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px;"><a href="ftp://www.ephox.com">ftp://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingFTPURL.inA(ParagraphWithMarginAndPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px; margin-left: 60px;"><a href="ftp://www.ephox.com">ftp://www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingFTPURL.inA(NonEmptyHeading).gives(new RegExp('^<h1><a href="ftp://www.ephox.com">ftp://www.ephox.com</a>(\\s| )Test</h1>$'));
|
||||
TypingFTPURL.inA(TableCellWithoutBrs2).gives(new RegExp('^<table><tbody><tr><td><a href="ftp://www.ephox.com">ftp://www.ephox.com</a>(\\s| )Test</td><td> </td></tr></tbody></table>$'));
|
||||
TypingFTPURL.inA(TableCellWithBrsFirstLine2).gives(new RegExp('^<table><tbody><tr><td><a href="ftp://www.ephox.com">ftp://www.ephox.com</a>(\\s| )Test<br />Line 2</td><td> </td></tr></tbody></table>$'));
|
||||
|
||||
TypingEclipsedFTPURL.inA(NonEmptyParagraph).gives(new RegExp('^<p>\\(<a href="ftp://www.ephox.com">ftp://www.ephox.com</a>\\)(\\s| )Test</p>$'));
|
||||
|
||||
TypingFTPURLAndNewline.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="ftp://www.ephox.com">ftp://www.ephox.com</a></p><p>(Test|<a href=\"ftp://www.ephox.com\"></a>Test)</p>$'));
|
||||
|
||||
queue.done();
|
||||
});
|
||||
|
||||
asyncTest('Typing a WWW URL', function() {
|
||||
TypingWWWURL.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="http://www.ephox.com">www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingWWWURL.inA(ParagraphWithMarginLeft).gives(new RegExp('^<p style="margin-left: 60px;"><a href="http://www.ephox.com">www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingWWWURL.inA(ParagraphWithPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px;"><a href="http://www.ephox.com">www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingWWWURL.inA(ParagraphWithMarginAndPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px; margin-left: 60px;"><a href="http://www.ephox.com">www.ephox.com</a>(\\s| )Test</p>$'));
|
||||
TypingWWWURL.inA(NonEmptyHeading).gives(new RegExp('^<h1><a href="http://www.ephox.com">www.ephox.com</a>(\\s| )Test</h1>$'));
|
||||
TypingWWWURL.inA(TableCellWithoutBrs2).gives(new RegExp('^<table><tbody><tr><td><a href="http://www.ephox.com">www.ephox.com</a>(\\s| )Test</td><td> </td></tr></tbody></table>$'));
|
||||
TypingWWWURL.inA(TableCellWithBrsFirstLine2).gives(new RegExp('^<table><tbody><tr><td><a href="http://www.ephox.com">www.ephox.com</a>(\\s| )Test<br />Line 2</td><td> </td></tr></tbody></table>$'));
|
||||
|
||||
TypingEclipsedWWWURL.inA(NonEmptyParagraph).gives(new RegExp('^<p>\\(<a href="http://www.ephox.com">www.ephox.com</a>\\)(\\s| )Test</p>$'));
|
||||
|
||||
TypingWWWURLAndNewline.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="http://www.ephox.com">www.ephox.com</a></p><p>(Test|<a href=\"http://www.ephox.com\"></a>Test)</p>$'));
|
||||
|
||||
queue.done();
|
||||
});
|
||||
|
||||
asyncTest('Typing a WWW URL with end dot', function() {
|
||||
TypingWWWURLWithEndDot.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="http://www.site.com">www.site.com</a>.(\\s| )Test</p>$'));
|
||||
TypingWWWURLWithEndDot.inA(ParagraphWithMarginLeft).gives(new RegExp('^<p style="margin-left: 60px;"><a href="http://www.site.com">www.site.com</a>.(\\s| )Test</p>$'));
|
||||
TypingWWWURLWithEndDot.inA(ParagraphWithPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px;"><a href="http://www.site.com">www.site.com</a>.(\\s| )Test</p>$'));
|
||||
TypingWWWURLWithEndDot.inA(ParagraphWithMarginAndPaddingLeft).gives(new RegExp('^<p style="padding-left: 60px; margin-left: 60px;"><a href="http://www.site.com">www.site.com</a>.(\\s| )Test</p>$'));
|
||||
TypingWWWURLWithEndDot.inA(NonEmptyHeading).gives(new RegExp('^<h1><a href="http://www.site.com">www.site.com</a>.(\\s| )Test</h1>$'));
|
||||
TypingWWWURLWithEndDot.inA(TableCellWithoutBrs2).gives(new RegExp('^<table><tbody><tr><td><a href="http://www.site.com">www.site.com</a>.(\\s| )Test</td><td> </td></tr></tbody></table>$'));
|
||||
TypingWWWURLWithEndDot.inA(TableCellWithBrsFirstLine2).gives(new RegExp('^<table><tbody><tr><td><a href="http://www.site.com">www.site.com</a>.(\\s| )Test<br />Line 2</td><td> </td></tr></tbody></table>$'));
|
||||
queue.done();
|
||||
});
|
||||
|
||||
asyncTest('Typing a mail address', function() {
|
||||
TypingMailAddr.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="mailto:user@domain.com">user@domain.com</a>(\\s| )Test</p>$'));
|
||||
TypingDashedMailAddr.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="mailto:first-last@domain.com">first-last@domain.com</a>(\\s| )Test</p>$'));
|
||||
|
||||
queue.done();
|
||||
});
|
||||
|
||||
asyncTest('Typing a mail address with protocol', function() {
|
||||
TypingMailAddrWithProtocol.inA(NonEmptyParagraph).gives(new RegExp('^<p><a href="mailto:user@domain.com">mailto:user@domain.com</a>(\\s| )Test</p>$'));
|
||||
|
||||
queue.done();
|
||||
});
|
||||
} else {
|
||||
test("IE has built in support", function() {
|
||||
ok(true, "Skipped");
|
||||
});
|
||||
}
|
||||
|
||||
var initTinyFunction = function(){
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
plugins : "autolink",
|
||||
add_unload_trigger : false,
|
||||
webkit_fake_resize: false,
|
||||
theme_advanced_styles : 'test1=test1;test2=test2',
|
||||
valid_styles : {
|
||||
'*' : 'text-align,padding-left,color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display'
|
||||
},
|
||||
indent : 0,
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
}
|
||||
});
|
||||
}
|
||||
--></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Automatic link tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
</div>
|
||||
<script src="../js/jsrobot/robot.js"></script>
|
||||
<script>
|
||||
initWhenTinyAndRobotAreReady(initTinyFunction);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
104
tests/qunit/editor/plugins/autosave.html
Normal file
104
tests/qunit/editor/plugins/autosave.html
Normal file
@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for the Autosave plugin</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("Autosave plugin", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
test("isEmpty true", function() {
|
||||
ok(editor.plugins.autosave.isEmpty(''));
|
||||
ok(editor.plugins.autosave.isEmpty(' '));
|
||||
ok(editor.plugins.autosave.isEmpty('\t\t\t'));
|
||||
|
||||
ok(editor.plugins.autosave.isEmpty('<p id="x"></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p> </p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p>\t</p>'));
|
||||
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br /></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br data-mce-bogus="true" /></p>'));
|
||||
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br><br></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br /><br /></p>'));
|
||||
ok(editor.plugins.autosave.isEmpty('<p><br data-mce-bogus="true" /><br data-mce-bogus="true" /></p>'));
|
||||
});
|
||||
|
||||
test("isEmpty false", function() {
|
||||
ok(!editor.plugins.autosave.isEmpty('X'));
|
||||
ok(!editor.plugins.autosave.isEmpty(' X'));
|
||||
ok(!editor.plugins.autosave.isEmpty('\t\t\tX'));
|
||||
|
||||
ok(!editor.plugins.autosave.isEmpty('<p>X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p> X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p>\tX</p>'));
|
||||
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br>X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br />X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br data-mce-bogus="true" />X</p>'));
|
||||
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br><br>X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br /><br />X</p>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<p><br data-mce-bogus="true" /><br data-mce-bogus="true" />X</p>'));
|
||||
|
||||
ok(!editor.plugins.autosave.isEmpty('<h1></h1>'));
|
||||
ok(!editor.plugins.autosave.isEmpty('<img src="x" />'));
|
||||
});
|
||||
|
||||
test("hasDraft/storeDraft/restoreDraft", function() {
|
||||
ok(!editor.plugins.autosave.hasDraft());
|
||||
|
||||
editor.setContent('X');
|
||||
editor.undoManager.add();
|
||||
editor.plugins.autosave.storeDraft();
|
||||
|
||||
ok(editor.plugins.autosave.hasDraft());
|
||||
|
||||
editor.setContent('Y');
|
||||
editor.undoManager.add();
|
||||
|
||||
editor.plugins.autosave.restoreDraft();
|
||||
equal(editor.getContent(), '<p>X</p>');
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
plugins: 'autosave',
|
||||
autosave_ask_before_unload: false,
|
||||
init_instance_callback: function(ed) {
|
||||
editor = ed;
|
||||
editor.plugins.autosave.removeDraft();
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<h1 id="qunit-header">Unit tests for the Table plugin</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
154
tests/qunit/editor/plugins/fullpage.html
Normal file
154
tests/qunit/editor/plugins/fullpage.html
Normal file
@ -0,0 +1,154 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Fullpage plugin tests</title>
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("Fullpage plugin", {
|
||||
autostart: false,
|
||||
teardown: function() {
|
||||
editor.getBody().dir = 'ltr';
|
||||
}
|
||||
});
|
||||
|
||||
function normalizeHTML(html) {
|
||||
return html.replace(/\s/g, '');
|
||||
}
|
||||
|
||||
function hasLink(href) {
|
||||
var links = editor.getDoc().getElementsByTagName('link');
|
||||
|
||||
for (var i = 0; i < links.length; i++) {
|
||||
if (links[i].href.indexOf('/' + href) != -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test('Keep header/footer intact', function() {
|
||||
expect(2);
|
||||
|
||||
editor.setContent('<html><body><p>Test</p>');
|
||||
equal(normalizeHTML(editor.getContent()), '<html><body><p>Test</p>', 'Invalid HTML content is still editable.');
|
||||
|
||||
editor.setContent('<html><body><p>Test</p></body></html>');
|
||||
equal(normalizeHTML(editor.getContent()), '<html><body><p>Test</p></body></html>', 'Header/footer is intact.');
|
||||
});
|
||||
|
||||
test('Default header/footer', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>Test</p>');
|
||||
equal(editor.getContent(), '<!DOCTYPE html>\n<html>\n<head>\n</head>\n<body>\n<p>Test</p>\n</body>\n</html>', 'Invalid HTML content is still editable.');
|
||||
});
|
||||
|
||||
test('Parse body attributes', function() {
|
||||
expect(9);
|
||||
|
||||
editor.setContent('<html><body><p>Test</p></body></html>');
|
||||
equal(editor.getBody().style.color, '', 'No color on body.');
|
||||
equal(editor.getBody().dir, '', 'No dir on body.');
|
||||
equal(editor.dom.getStyle(editor.getBody().firstChild, 'display', true), 'block', 'No styles added to iframe document');
|
||||
|
||||
editor.setContent('<html><body style="color:#FF0000"><p>Test</p></body></html>');
|
||||
ok(editor.getBody().style.color.length > 0, 'Color added to body');
|
||||
|
||||
editor.setContent('<html><body dir="rtl"><p>Test</p></body></html>');
|
||||
equal(editor.getBody().dir, 'rtl', 'Dir added to body');
|
||||
|
||||
editor.setContent('<html><head><style>p {text-align:right}</style></head><body dir="rtl"><p>Test</p></body></html>');
|
||||
equal(editor.dom.getStyle(editor.getBody().firstChild, 'text-align', true), 'right', 'Styles added to iframe document');
|
||||
|
||||
editor.setContent('<html><body><p>Test</p></body></html>');
|
||||
equal(editor.getBody().style.color, '', 'No color on body.');
|
||||
equal(editor.getBody().dir, '', 'No dir on body.');
|
||||
equal(editor.dom.getStyle(editor.getBody().firstChild, 'display', true), 'block', 'No styles added to iframe document');
|
||||
});
|
||||
|
||||
test('fullpage_hide_in_source_view: false', function() {
|
||||
editor.settings.fullpage_hide_in_source_view = false;
|
||||
editor.setContent('<html><body><p>1</p></body></html>');
|
||||
equal(editor.getContent({source_view: true}), '<html><body>\n<p>1</p>\n</body></html>');
|
||||
});
|
||||
|
||||
test('fullpage_hide_in_source_view: false', function() {
|
||||
editor.settings.fullpage_hide_in_source_view = true;
|
||||
editor.setContent('<html><body><p>1</p></body></html>');
|
||||
equal(editor.getContent({source_view: true}), '<p>1</p>');
|
||||
});
|
||||
|
||||
test('fullpage link elements', function() {
|
||||
editor.setContent('<html><head><link rel="stylesheet" href="a.css"><link rel="something"></head><body><p>c</p></body></html>');
|
||||
equal(editor.getContent(), '<html><head><link rel="stylesheet" href="a.css"><link rel="something"></head><body>\n<p>c</p>\n</body></html>');
|
||||
});
|
||||
|
||||
test('fullpage add/remove stylesheets', function() {
|
||||
editor.setContent('<html><head><link rel="stylesheet" href="a.css"></head><body><p>c</p></body></html>');
|
||||
ok(hasLink("a.css"));
|
||||
ok(!hasLink("b.css"));
|
||||
ok(!hasLink("c.css"));
|
||||
|
||||
editor.setContent('<html><head><link rel="stylesheet" href="a.css"><link rel="stylesheet" href="b.css"></head><body><p>c</p></body></html>');
|
||||
ok(hasLink("a.css"));
|
||||
ok(hasLink("b.css"));
|
||||
ok(!hasLink("c.css"));
|
||||
|
||||
editor.setContent('<html><head><link rel="stylesheet" href="a.css"><link rel="stylesheet" href="b.css"><link rel="stylesheet" href="c.css"></head><body><p>c</p></body></html>');
|
||||
ok(hasLink("a.css"));
|
||||
ok(hasLink("b.css"));
|
||||
ok(hasLink("c.css"));
|
||||
|
||||
editor.setContent('<html><head><link rel="stylesheet" href="a.css"></head><body><p>c</p></body></html>');
|
||||
ok(hasLink("a.css"));
|
||||
ok(!hasLink("b.css"));
|
||||
ok(!hasLink("c.css"));
|
||||
|
||||
editor.setContent('<html><head></head><body><p>c</p></body></html>');
|
||||
ok(!hasLink("a.css"));
|
||||
ok(!hasLink("b.css"));
|
||||
ok(!hasLink("c.css"));
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
plugins : "fullpage",
|
||||
add_unload_trigger : false,
|
||||
valid_styles : {
|
||||
'*' : 'text-align,padding-left,color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display'
|
||||
},
|
||||
indent : 0,
|
||||
setup: function(ed) {
|
||||
ed.on('NodeChange', false);
|
||||
},
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Fullpage plugin tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
126
tests/qunit/editor/plugins/jquery_plugin.html
Normal file
126
tests/qunit/editor/plugins/jquery_plugin.html
Normal file
@ -0,0 +1,126 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>jQuery Plugin tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="http://www.google.com/jsapi"></script>
|
||||
<script>
|
||||
google.load("jquery", "1");
|
||||
</script>
|
||||
<script src="../../js/tinymce/classes/jquery.tinymce.js"></script>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("jQuery plugin", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
test("Get contents using jQuery", function() {
|
||||
expect(4);
|
||||
|
||||
tinymce.get('elm1').setContent('<p>Editor 1</p>');
|
||||
|
||||
equal($('#elm1').html(), '<p>Editor 1</p>');
|
||||
equal($('#elm1').val(), '<p>Editor 1</p>');
|
||||
equal($('#elm1').attr('value'), '<p>Editor 1</p>');
|
||||
equal($('#elm1').text(), 'Editor 1');
|
||||
});
|
||||
|
||||
test("Set contents using jQuery", function() {
|
||||
expect(4);
|
||||
|
||||
$('#elm1').html('Test 1');
|
||||
equal($('#elm1').html(), '<p>Test 1</p>');
|
||||
|
||||
$('#elm1').val('Test 2');
|
||||
equal($('#elm1').html(), '<p>Test 2</p>');
|
||||
|
||||
$('#elm1').text('Test 3');
|
||||
equal($('#elm1').html(), '<p>Test 3</p>');
|
||||
|
||||
$('#elm1').attr('value', 'Test 4');
|
||||
equal($('#elm1').html(), '<p>Test 4</p>');
|
||||
});
|
||||
|
||||
test("append/prepend contents using jQuery", function() {
|
||||
expect(2);
|
||||
|
||||
tinymce.get('elm1').setContent('<p>Editor 1</p>');
|
||||
|
||||
$('#elm1').append('<p>Test 1</p>');
|
||||
equal($('#elm1').html(), '<p>Editor 1</p>\n<p>Test 1</p>');
|
||||
|
||||
$('#elm1').prepend('<p>Test 2</p>');
|
||||
equal($('#elm1').html(), '<p>Test 2</p>\n<p>Editor 1</p>\n<p>Test 1</p>');
|
||||
});
|
||||
|
||||
test("Find using :tinymce selector", function() {
|
||||
expect(1);
|
||||
|
||||
equal($('textarea:tinymce').length, 2);
|
||||
});
|
||||
|
||||
test("Set contents using :tinymce selector", function() {
|
||||
expect(3);
|
||||
|
||||
$('textarea:tinymce').val('Test 1');
|
||||
equal($('#elm1').val(), '<p>Test 1</p>');
|
||||
equal($('#elm2').val(), '<p>Test 1</p>');
|
||||
equal($('#elm3').val(), 'Textarea');
|
||||
});
|
||||
|
||||
test("Get contents using :tinymce selector", function() {
|
||||
expect(1);
|
||||
|
||||
$('textarea:tinymce').val('Test get');
|
||||
equal($('textarea:tinymce').val(), '<p>Test get</p>');
|
||||
});
|
||||
|
||||
QUnit.stop();
|
||||
|
||||
$(function() {
|
||||
$('textarea.tinymce').tinymce({
|
||||
// Location of TinyMCE script
|
||||
script_url : location.search.indexOf('min=true') > 0 ? '../../js/tinymce/tinymce.min.js' : '../../js/tinymce/tinymce.js',
|
||||
|
||||
// General options
|
||||
plugins : "pagebreak,layer,table,save,emoticons,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,template",
|
||||
|
||||
// Theme options
|
||||
theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect",
|
||||
theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
|
||||
theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emoticons,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
|
||||
theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak",
|
||||
theme_advanced_toolbar_location : "top",
|
||||
theme_advanced_toolbar_align : "left",
|
||||
theme_advanced_statusbar_location : "bottom",
|
||||
theme_advanced_resizing : true,
|
||||
|
||||
init_instance_callback : function(ed) {
|
||||
var ed1 = tinymce.get('elm1'), ed2 = tinymce.get('elm2');
|
||||
|
||||
// When both editors are initialized
|
||||
if (ed1 && ed1.initialized && ed2 && ed2.initialized)
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">TinyMCE jQuery plugin tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1" class="tinymce">Editor 1</textarea>
|
||||
<textarea id="elm2" name="elm2" class="tinymce">Editor 2</textarea>
|
||||
<textarea id="elm3" name="elm3">Textarea</textarea>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
52
tests/qunit/editor/plugins/js/autolink.actions.js
Normal file
52
tests/qunit/editor/plugins/js/autolink.actions.js
Normal file
@ -0,0 +1,52 @@
|
||||
function fakeTypeAURL(url) {
|
||||
return function(callback) {
|
||||
// type the URL and then press the space bar
|
||||
tinymce.execCommand('mceInsertContent', false, url);
|
||||
window.robot.type(32, false, callback, editor.selection.getNode());
|
||||
};
|
||||
}
|
||||
|
||||
function fakeTypeAnEclipsedURL(url) {
|
||||
return function(callback) {
|
||||
// type the URL and then type ')'
|
||||
tinymce.execCommand('mceInsertContent', false, '(' + url);
|
||||
window.robot.typeSymbol(")", function() {
|
||||
window.robot.type(32, false, callback, editor.selection.getNode());
|
||||
}, editor.selection.getNode());
|
||||
};
|
||||
}
|
||||
|
||||
function fakeTypeANewlineURL(url) {
|
||||
return function(callback) {
|
||||
// type the URL and then press the enter key
|
||||
tinymce.execCommand('mceInsertContent', false, url);
|
||||
window.robot.type('\n', false, callback, editor.selection.getNode());
|
||||
};
|
||||
}
|
||||
|
||||
createAction('Typing HTTP URL', fakeTypeAURL('http://www.ephox.com'));
|
||||
createAction('Typing HTTPS URL', fakeTypeAURL('https://www.ephox.com'));
|
||||
createAction('Typing SSH URL', fakeTypeAURL('ssh://www.ephox.com'));
|
||||
createAction('Typing FTP URL', fakeTypeAURL('ftp://www.ephox.com'));
|
||||
createAction('Typing WWW URL', fakeTypeAURL('www.ephox.com'));
|
||||
createAction('Typing WWW URL With End Dot', fakeTypeAURL('www.site.com.'));
|
||||
createAction('Typing Mail Addr', fakeTypeAURL('user@domain.com'));
|
||||
createAction('Typing Mail Addr With Protocol', fakeTypeAURL('mailto:user@domain.com'));
|
||||
createAction('Typing Dashed Mail Addr', fakeTypeAURL('first-last@domain.com'));
|
||||
createAction('Typing Eclipsed HTTP URL', fakeTypeAnEclipsedURL('http://www.ephox.com'));
|
||||
createAction('Typing Eclipsed HTTPS URL', fakeTypeAnEclipsedURL('https://www.ephox.com'));
|
||||
createAction('Typing Eclipsed SSH URL', fakeTypeAnEclipsedURL('ssh://www.ephox.com'));
|
||||
createAction('Typing Eclipsed FTP URL', fakeTypeAnEclipsedURL('ftp://www.ephox.com'));
|
||||
createAction('Typing Eclipsed WWW URL', fakeTypeAnEclipsedURL('www.ephox.com'));
|
||||
createAction('Typing HTTP URL And Newline', fakeTypeANewlineURL('http://www.ephox.com'));
|
||||
createAction('Typing HTTPS URL And Newline', fakeTypeANewlineURL('https://www.ephox.com'));
|
||||
createAction('Typing SSH URL And Newline', fakeTypeANewlineURL('ssh://www.ephox.com'));
|
||||
createAction('Typing FTP URL And Newline', fakeTypeANewlineURL('ftp://www.ephox.com'));
|
||||
createAction('Typing WWW URL And Newline', fakeTypeANewlineURL('www.ephox.com'));
|
||||
createAction('Applying OL', 'InsertOrderedList');
|
||||
createAction('Applying UL', 'InsertUnorderedList');
|
||||
createAction('Indenting', 'Indent');
|
||||
createAction('Outdenting', 'Outdent');
|
||||
createAction('Typing Enter', fakeKeyPressAction('\n'));
|
||||
createAction('Typing Tab', fakeKeyPressAction('\t'));
|
||||
createAction('Typing Shift Tab', fakeKeyPressAction('\t', true));
|
||||
138
tests/qunit/editor/plugins/js/dsl.js
Normal file
138
tests/qunit/editor/plugins/js/dsl.js
Normal file
@ -0,0 +1,138 @@
|
||||
var editor;
|
||||
|
||||
function getFunctionName(func) {
|
||||
if (func.name && func.name != "") {
|
||||
return func.name;
|
||||
} else if (typeof func == "function" || typeof func == "object") {
|
||||
var fName = ("" + func).match(/function\s*([\w\$]+)\s*\(/);
|
||||
if (fName !== null && fName != "") {
|
||||
return fName[1];
|
||||
} else {
|
||||
for (var v in window) {
|
||||
if (window[v] === func) {
|
||||
func.name = v;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assertState(expected, message) {
|
||||
var content = editor.getContent().replace(/[\n\r]/g, '');
|
||||
if (expected && expected.replace) expected = expected.replace(/[\n\r]/g, '');
|
||||
// Safari reports "function", while Firefox and IE report "object"
|
||||
if (typeof expected == "function" || typeof expected == "object") {
|
||||
if (expected.test(content))
|
||||
equal(content, content, message);
|
||||
else
|
||||
equal(content, expected.toString(), message);
|
||||
} else {
|
||||
equal(content, expected, message);
|
||||
}
|
||||
}
|
||||
|
||||
tinymce.create('dsl.Queue', {
|
||||
Queue: function() {
|
||||
this.queue = [];
|
||||
},
|
||||
|
||||
add: function(task) {
|
||||
this.queue.push(task);
|
||||
},
|
||||
|
||||
next: function() {
|
||||
if (this.queue.length > 0) {
|
||||
var task = this.queue.shift();
|
||||
task();
|
||||
return true;
|
||||
} else {
|
||||
QUnit.start();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
done: function() {
|
||||
expect(this.queue.length);
|
||||
this.next();
|
||||
}
|
||||
});
|
||||
|
||||
tinymce.create('dsl.Action', {
|
||||
Action: function(name, action) {
|
||||
this.name = name;
|
||||
this.a = this.curryPreposition('a');
|
||||
this.inA = this.curryPreposition('in a');
|
||||
this.to = this.curryPreposition('to');
|
||||
if (tinymce.is(action, 'string')) {
|
||||
this.action = function(callback) {
|
||||
editor.execCommand(action);
|
||||
callback();
|
||||
};
|
||||
} else {
|
||||
this.action = action;
|
||||
}
|
||||
},
|
||||
|
||||
curryPreposition: function(preposition) {
|
||||
return function(state) {
|
||||
return this.go(state, preposition);
|
||||
};
|
||||
},
|
||||
|
||||
go: function(state, preposition) {
|
||||
var message = this.name + " " + preposition + " " + getFunctionName(state);
|
||||
var action = this.action;
|
||||
var actionPerformed = false;
|
||||
function defer(callback) {
|
||||
return function() {
|
||||
var args = arguments;
|
||||
queue.add(function() {
|
||||
if (actionPerformed) {
|
||||
callback.apply(undefined, args);
|
||||
queue.next();
|
||||
return;
|
||||
}
|
||||
editor.focus();
|
||||
state();
|
||||
action(function() {
|
||||
actionPerformed = true;
|
||||
callback.apply(undefined, args);
|
||||
queue.next();
|
||||
});
|
||||
});
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
var dslState = {
|
||||
gives: defer(function(expected) {
|
||||
assertState(expected, message);
|
||||
}),
|
||||
|
||||
enablesState: defer(function(state) {
|
||||
ok(editor.queryCommandState(state), message + " enables " + state + " command");
|
||||
}),
|
||||
|
||||
disablesState: defer(function(state) {
|
||||
ok(!editor.queryCommandState(state), message + " disables " + state + " command");
|
||||
})
|
||||
};
|
||||
dslState.andGives = dslState.gives;
|
||||
return dslState;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Action Utilities
|
||||
function fakeKeyPressAction(keyCode, shiftKey) {
|
||||
return function(callback) {
|
||||
setTimeout(function() {
|
||||
window.robot.type(keyCode, shiftKey, callback, editor.selection.getNode());
|
||||
}, 1);
|
||||
};
|
||||
}
|
||||
|
||||
function createAction(name, action) {
|
||||
window[name.replace(/\s+/g, '')] = new dsl.Action(name, action);
|
||||
}
|
||||
176
tests/qunit/editor/plugins/js/states.js
Normal file
176
tests/qunit/editor/plugins/js/states.js
Normal file
@ -0,0 +1,176 @@
|
||||
function createState(content, startSelector, startOffset, endSelector, endOffset) {
|
||||
return function() {
|
||||
editor.setContent(content);
|
||||
setSelection(startSelector, startOffset, endSelector, endOffset);
|
||||
};
|
||||
}
|
||||
|
||||
/** Collapsed Selection States **/
|
||||
function EmptyParagraph() {
|
||||
var body = editor.getBody();
|
||||
while (body.firstChild) {
|
||||
editor.dom.remove(body.firstChild);
|
||||
}
|
||||
var p = body.ownerDocument.createElement('p');
|
||||
p.appendChild(body.ownerDocument.createTextNode(''));
|
||||
body.appendChild(p, body);
|
||||
setSelection(p.firstChild, 0);
|
||||
}
|
||||
|
||||
function EmptyHeading() {
|
||||
EmptyParagraph();
|
||||
editor.dom.rename(editor.getBody().firstChild, 'h1');
|
||||
setSelection(editor.getBody().firstChild.firstChild, 0);
|
||||
}
|
||||
|
||||
function TextAfterUL() {
|
||||
editor.setContent('<ul><li>Item</li></ul>Test');
|
||||
setSelection(editor.dom.getRoot().lastChild, 2);
|
||||
}
|
||||
|
||||
function TextAfterOL() {
|
||||
editor.setContent('<ol><li>Item</li></ol>Test');
|
||||
setSelection(editor.dom.getRoot().lastChild, 2);
|
||||
}
|
||||
|
||||
EmptyContent = createState('', 'body', 0);
|
||||
PlainText = createState('Test', 'body', 0);
|
||||
NonEmptyParagraph = createState('<p>Test</p>', 'p', 0);
|
||||
ParagraphWithMarginLeft = createState('<p style="margin-left: 60px;">Test</p>', 'p', 0);
|
||||
ParagraphWithPaddingLeft = createState('<p style="padding-left: 60px;">Test</p>', 'p', 0);
|
||||
ParagraphWithMarginAndPaddingLeft = createState('<p style="margin-left: 60px; padding-left: 60px;">Test</p>', 'p', 0);
|
||||
|
||||
CenteredListItem = createState('<ul><li style="text-align: center;">Item1</li><li>Item2</li></ul>', 'li:nth-child(1)', 2);
|
||||
ItemInCenteredList = createState('<ul style="text-align: center;"><li>Item1</li><li>Item2</li></ul>', 'li:nth-child(1)', 2);
|
||||
RightAlignedListItem = createState('<ul><li style="text-align: right;">Item1</li><li>Item2</li></ul>', 'li:nth-child(1)', 2);
|
||||
ItemInRightAlignedList = createState('<ul style="text-align: right;"><li>Item1</li><li>Item2</li></ul>', 'li:nth-child(1)', 2);
|
||||
|
||||
ParagraphBetweenOrderedLists = createState('<ol><li>Item1</li></ol><p>Test</p><ol><li>Item2</li></ol>', 'p', 2);
|
||||
ParagraphBetweenUnorderedLists = createState('<ul><li>Item1</li></ul><p>Test</p><ul><li>Item2</li></ul>', 'p', 2);
|
||||
ParagraphBetweenMixedLists = createState('<ol><li>Item1</li></ol><p>Test</p><ul><li>Item2</li></ul>', 'p', 2);
|
||||
|
||||
NonEmptyHeading = createState('<h1>Test</h1>', 'h1', 0);
|
||||
TableCellWithoutBrs = createState('<table><tbody><tr><td>Test</td><td> </td></tr></tbody></table>', 'td', 4);
|
||||
TableCellWithoutBrs2 = createState('<table><tbody><tr><td>Test</td><td> </td></tr></tbody></table>', 'td', 0);
|
||||
TableCellWithBrsFirstLine = createState('<table><tbody><tr><td>Test<br>Line 2</td><td> </td></tr></tbody></table>', 'td', 1);
|
||||
TableCellWithBrsFirstLine2 = createState('<table><tbody><tr><td>Test<br>Line 2</td><td> </td></tr></tbody></table>', 'td', 0);
|
||||
TableCellWithBrsMiddleLine = createState('<table><tbody><tr><td>Test<br/>Line 2<br/>Line 3</td><td> </td></tr></tbody></table>', 'td br:nth-child(1)', 'afterNextCharacter');
|
||||
TableCellWithBrsLastLine = createState('<table><tbody><tr><td>Test<br>Line 2</td><td> </td></tr></tbody></table>', 'td br:nth-child(1)', 'afterNextCharacter');
|
||||
TableCellWithAdjacentBrsFirstLine = createState('<table><tbody><tr><td>Test<br><br>Line 2</td><td> </td></tr></tbody></table>', 'td', 1);
|
||||
|
||||
HeadingInOrderedList = createState('<ol><li><h2>Test</h2></li></ol>', 'h2', '2');
|
||||
HeadingInUnorderedList = createState('<ul><li><h2>Test</h2></li></ul>', 'h2', '2');
|
||||
HeadingInOrderedListBeforeParagraph = createState('<ol><li><h2>Test</h2></li></ol><p>Content<br />After</p>', 'h2', '2');
|
||||
|
||||
DefinitionListDescription = createState('<dl><dt>Term</dt><dd>Description</dd></dl>', 'dd', 2);
|
||||
DefinitionListTerm = createState('<dl><dt>Term</dt><dd>Description</dd></dl>', 'dt', 2);
|
||||
EndOfParagraphBeforeOL = createState('<p>Test</p><ol><li>Item</li></ol>', 'p', 4);
|
||||
EndOfParagraphBeforeOLWithListType = createState('<p>Test</p><ol style="list-style-type: lower-alpha;"><li>Item</li></ol>', 'p', 4);
|
||||
EndOfParagraphBeforeUL = createState('<p>Test</p><ul><li>Item</li></ul>', 'p', 4);
|
||||
StartOfParagraphAfterOL = createState('<ol><li>Item</li></ol><p>Test</p>', 'p', 1);
|
||||
StartOfParagraphAfterUL = createState('<ul><li>Item</li></ul><p>Test</p>', 'p', 1);
|
||||
StartOfParagraphAfterOLWithListType = createState('<ol style="list-style-type: lower-alpha;"><li>Item</li></ol><p>Test</p>', 'p', 1);
|
||||
EmptyOrderedListItem = createState('<ol><li>Before</li><li> </li><li>After</li></ol>', 'li:nth-child(2)', 0);
|
||||
EmptyUnorderedListItem = createState('<ul><li>Before</li><li> </li><li>After</li></ul>', 'li:nth-child(2)', 0);
|
||||
NonEmptyOrderedListItem = createState('<ol><li>Before</li><li>Test</li><li>After</li></ol>', 'li:nth-child(2)', 0);
|
||||
NonEmptyUnorderedListItem = createState('<ul><li>Before</li><li>Test</li><li>After</li></ul>', 'li:nth-child(2)', 0);
|
||||
NestedEmptyOrderedListItem = createState('<ol><li>Before<ol><li> </li></ol></li><li>After</li></ol>', 'li ol li', 0);
|
||||
NestedEmptyUnorderedListItem = createState('<ul><li>Before<ul><li> </li></ul></li><li>After</li></ul>', 'li ul li', 0);
|
||||
NestedNonEmptyOrderedListItem = createState('<ol><li>Before<ol><li>Test</li></ol></li><li>After</li></ol>', 'li ol li', 0);
|
||||
NestedNonEmptyUnorderedListItem = createState('<ul><li>Before<ul><li>Test</li></ul></li><li>After</li></ul>', 'li ul li', 0);
|
||||
NestedOrderedListWithMultipleItems = createState('<ol><li>Before<ol><li>Item1</li><li>Item2</li></ol></li></ol>', 'li ol li', 0);
|
||||
NestedUnorderedListWithMultipleItems = createState('<ul><li>Before<ul><li>Item1</li><li>Item2</li></ul></li></ul>', 'li ul li', 0);
|
||||
OrderedLowerAlphaListItem = createState('<ol style="list-style-type: lower-alpha;"><li>Item 1</li><li>Item 2</li></ol>', 'li:nth-child(2)', 0);
|
||||
UnorderedSquareListItem = createState('<ul style="list-style-type: square;"><li>Item 1</li><li>Item 2</li></ul>', 'li:nth-child(2)', 0);
|
||||
|
||||
OrderedListItemWithNestedChild = createState('<ol><li>Item1<ol><li>Nested</li></ol></li></ol>', 'li:nth-child(1)', 2);
|
||||
UnorderedListItemWithNestedChild = createState('<ul><li>Item1<ul><li>Nested</li></ul></li></ul>', 'li:nth-child(1)', 2);
|
||||
|
||||
OrderedListWithAdjacentNestedLists = createState('<ol><li style="list-style-type: none;"><ol><li>Item 1</li></ol></li><li>Item 2</li><li style="list-style-type: none;"><ol><li>Item 3</li></ol></li></ol>', 'li:nth-child(2)', 4);
|
||||
UnorderedListWithAdjacentNestedLists = createState('<ul><li style="list-style-type: none;"><ul><li>Item 1</li></ul></li><li>Item 2</li><li style="list-style-type: none;"><ul><li>Item 3</li></ul></li></ul>', 'li:nth-child(2)', 4);
|
||||
|
||||
OrderedListItemWithMargin = createState('<ol><li style="margin-left: 60px;">Test</li></ol>', 'li', 0);
|
||||
UnorderedListItemWithMargin = createState('<ul><li style="margin-left: 60px;">Test</li></ul>', 'li', 0);
|
||||
|
||||
OrderedListItemWithNestedAlphaList = createState('<ol><li>Item<ol style="list-style-type: lower-alpha;"><li>Nested</li></ol></li></ol>', 'li', 2);
|
||||
|
||||
/** Collapsed DIV Tests **/
|
||||
OrderedListItemInsideDiv = createState('<div id="div"><ol>\n<li>Item1</li><li>Item2</li></ol></div>', 'li:nth-child(1)', 2);
|
||||
UnorderedListItemInsideDiv = createState('<div id="div"><ul>\n<li>Item1</li><li>Item2</li></ul></div>', 'li:nth-child(1)', 2);
|
||||
|
||||
ParagraphInDiv = createState('<div><p>Item</p></div>', 'p', 2);
|
||||
TextInDiv = createState('<div>Item</div>', 'div', 2);
|
||||
TextWithBrsInDivFirstLine = createState('<div>Item1<br />Item2</div>', 'div', 2);
|
||||
TextWithBrsInDivMiddleLine = createState('<div>Item1<br />Item2<br />Item3</div>', 'br:nth-child(1)', 'afterNextCharacter');
|
||||
TextWithBrsInDivLastLine = createState('<div>Item1<br />Item2</div>', 'br:nth-child(1)', 'afterNextCharacter');
|
||||
TextWithBrsInFormattingInDiv = function() {
|
||||
var rng;
|
||||
editor.setContent('<div><strong>Before<br /></strong>Item1<br />Item2<br />Item3</div>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('div')[0].childNodes[1], 0);
|
||||
rng.setEnd(editor.dom.select('div')[0], 6);
|
||||
editor.selection.setRng(rng);
|
||||
};
|
||||
TextWithBrInsideFormatting = function() {
|
||||
var rng;
|
||||
editor.setContent('<div><em><strong>Before<br /><span class="foo">Item1</span></strong></em>Item2<br />Item3</div>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].childNodes[0], 2);
|
||||
rng.setEnd(editor.dom.select('div')[0], 4);
|
||||
editor.selection.setRng(rng);
|
||||
};
|
||||
|
||||
/** Expanded Selection States **/
|
||||
SingleParagraphSelection = createState('<p>This is a test</p>', 'p', 5, 'p', 7);
|
||||
MultipleParagraphSelection = createState('<p>This is a test</p><p>Second paragraph</p>', 'p:nth-child(1)', 5, 'p:nth-child(2)', 6);
|
||||
SingleHeadingSelection = createState('<h1>This is a test</h1>', 'h1', 5, 'h1', 7);
|
||||
MultipleHeadingSelection = createState('<h1>This is a test</h1><h1>Second paragraph</h1>', 'h1:nth-child(1)', 5, 'h1:nth-child(2)', 6);
|
||||
SingleBlockSelection = createState('<div>This is a test</div>', 'div', 5, 'div', 7);
|
||||
MultipleBlockSelection = createState('<div>This is a test</div><div>Second paragraph</div>', 'div:nth-child(1)', 5, 'div:nth-child(2)', 6);
|
||||
|
||||
SingleBlockWithBrSelection = createState('<div>Item1<br />Item2</div>', 'div', 3, 'br', 'afterNextCharacter');
|
||||
MultipleBlockWithBrSelection = createState('<div>Item1<br />Item2</div><div>Item3</div>', 'div:nth-child(1)', 2, 'div:nth-child(2)', 3);
|
||||
MultipleBlockWithBrPartialSelection = createState('<div>Item1<br />Item2</div><div>Item3<br />Item4</div>', 'div:nth-child(1)', 2, 'div:nth-child(2)', 3);
|
||||
MultipleBlockWithBrPartialSelectionAtEnd = createState('<div>Item1<br />Item2</div><div>Item3<br />Item4</div>', 'div:nth-child(1) br', 'afterNextCharacter', 'div:nth-child(2) br', 'afterNextCharacter');
|
||||
MultipleBlockWithEmptyDivsAllSelected = createState('<div id="start"> </div><div>a</div><div></div><div>b</div><div></div><div id="end"> </div>', '#start', 0, '#end', 0);
|
||||
|
||||
CellWithoutBrSelection = createState('<table><tbody><tr><td>Cell 1</td></tr></tbody></table>', 'td', 1, 'td', 1); //selection is a single point so it will avoid table selection bugs in ie9.
|
||||
CellWithBrSingleLineSelection = createState('<table><tbody><tr><td>Cell 1<br>Line 2</td></tr></tbody></table>', 'td', 1, 'td', 4);
|
||||
CellWithBrMultipleLineSelection = createState('<table><tbody><tr><td>Cell 1<br>Line 2</td></tr></tbody></table>', 'td', 1, 'td', 4);
|
||||
|
||||
TableCellWithTextAfterUL = createState('<table><tbody><tr><td><ul><li>Existing</li></ul><span id="start">Line1</span><br />Line2<br id="end" />Line3<br />Line4</td></tr></tbody></table>', '#start', 1, '#end', 'afterNextCharacter');
|
||||
|
||||
ParagraphToHeadingSelection = createState('<p>This is a test</p><h1>Second paragraph</h1>', 'p', 5, 'h1', 6);
|
||||
ParagraphToBlockSelection = createState('<p>This is a test</p><div>Second paragraph</div>', 'p', 5, 'div', 6);
|
||||
HeadingToParagraphSelection = createState('<h1>This is a test</h1><p>Second paragraph</p>', 'h1', 5, 'p', 6);
|
||||
BlockToParagraphSelection = createState('<div>This is a test</div><p>Second paragraph</p>', 'div', 5, 'p', 6);
|
||||
MultipleParagraphAndHeadingSelection = createState('<p>This is a test</p><h1>Second paragraph</h1><div>Third paragraph</div>', 'p', 5, 'div', 5);
|
||||
ThreeBoldDivsWithBrSelection = createState('<div><strong>One</strong></div><div><strong>Two</strong></div><div><strong>Three<br></strong></div>', 'div:nth-child(1) strong', 2, 'div:nth-child(3) strong', 2);
|
||||
|
||||
SingleLiOlSelection = createState('<ol><li>Item 1</li></ol>', 'li', 1, 'li', 4);
|
||||
MultiLiOlSelection = createState('<ol><li>Item 1</li><li>Item 2</li></ol>', 'li:nth-child(1)', 1, 'li:nth-child(2)', 4);
|
||||
SingleLiUlSelection = createState('<ul><li>Item 1</li></ul>', 'li', 1, 'li', 4);
|
||||
MultiLiUlSelection = createState('<ul><li>Item 1</li><li>Item 2</li></ul>', 'li:nth-child(1)', 1, 'li:nth-child(2)', 4);
|
||||
MultiNestedLiUlSelection = createState('<ul><li style="list-style-type: none;"><ul><li>Item 1</li><li>Item 2</li></ul></li></ul>', 'li li:nth-child(1)', 1, 'li li:nth-child(2)', 4);
|
||||
MultiNestedLiOlSelection = createState('<ol><li style="list-style-type: none;"><ol><li>Item 1</li><li>Item 2</li></ol></li></ol>', 'li li:nth-child(1)', 1, 'li li:nth-child(2)', 4);
|
||||
|
||||
IndentedOlInOlCorrectSelection = createState('<ol><li>Item 1<ol><li>Indented</li></ol></li></ol>', 'li', 1, 'li li', 4);
|
||||
IndentedUlInUlCorrectSelection = createState('<ul><li>Item 1<ul><li>Indented</li></ul></li></ul>', 'li', 1, 'li li', 4);
|
||||
IndentedOlInOlIncorrectSelection = createState('<ol><li>Item 1</li><ol><li>Indented</li></ol></ol>', 'li', 1, 'ol ol li', 4);
|
||||
IndentedUlInUlIncorrectSelection = createState('<ul><li>Item 1</li><ul><li>Indented</li></ul></ul>', 'li', 1, 'ul ul li', 4);
|
||||
|
||||
IndentedOlInUlCorrectSelection = createState('<ul><li>Item 1<ol><li>Indented</li></ol></li></ul>', 'li', 1, 'li li', 4);
|
||||
IndentedUlInOlCorrectSelection = createState('<ol><li>Item 1<ul><li>Indented</li></ul></li></ol>', 'li', 1, 'li li', 4);
|
||||
IndentedOlInUlIncorrectSelection = createState('<ul><li>Item 1</li><ol><li>Indented</li></ol></ul>', 'li', 1, 'ul ol li', 4);
|
||||
IndentedUlInOlIncorrectSelection = createState('<ol><li>Item 1</li><ul><li>Indented</li></ul></ol>', 'li', 1, 'ol ul li', 4);
|
||||
|
||||
// TODO: Paragraph/heading to list combinations.
|
||||
ParagraphBeforeOlSelection = createState('<p>Before</p><ol><li>Item 1</li></ol>', 'p', 3, 'li', 4);
|
||||
ParagraphBeforeUlSelection = createState('<p>Before</p><ul><li>Item 1</li></ul>', 'p', 3, 'li', 4);
|
||||
ParagraphAfterOlSelection = createState('<ol><li>Item 1</li></ol><p>After</p>', 'li', 4, 'p', 3);
|
||||
ParagraphAfterUlSelection = createState('<ul><li>Item 1</li></ul><p>After</p>', 'li', 4, 'p', 3);
|
||||
ParagraphBeforeAndAfterOlSelection = createState('<p>Before</p><ol><li>Item 1</li></ol><p id="after">After</p>', 'p', 4, '#after', 3);
|
||||
ParagraphBeforeAndAfterUlSelection = createState('<p>Before</p><ul><li>Item 1</li></ul><p id="after">After</p>', 'p', 4, '#after', 3);
|
||||
|
||||
SelectionEndingAtBr = createState('<p>Item<br>After</p>', 'p', 2, 'br', 'after');
|
||||
SelectionStartingAtBr = createState('<p>Before<br>Item</p>', 'p', 'after', 'br', 'afterNextCharacter');
|
||||
130
tests/qunit/editor/plugins/legacyoutput.html
Normal file
130
tests/qunit/editor/plugins/legacyoutput.html
Normal file
@ -0,0 +1,130 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for Media Plugin</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("Legacyoutput plugin", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
test("Font color", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('forecolor', false, '#FF0000');
|
||||
equal(editor.getContent().toLowerCase(), '<p><font color="#ff0000">text</font></p>');
|
||||
});
|
||||
|
||||
test("Font size", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('fontsize', false, 7);
|
||||
equal(editor.getContent(), '<p><font size="7">text</font></p>');
|
||||
});
|
||||
|
||||
test("Font face", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('fontname', false, "times");
|
||||
equal(editor.getContent(), '<p><font face="times">text</font></p>');
|
||||
});
|
||||
|
||||
test("Bold", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('bold');
|
||||
equal(editor.getContent(), '<p><b>text</b></p>');
|
||||
});
|
||||
|
||||
test("Italic", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('italic');
|
||||
equal(editor.getContent(), '<p><i>text</i></p>');
|
||||
});
|
||||
|
||||
test("Underline", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('underline');
|
||||
equal(editor.getContent(), '<p><u>text</u></p>');
|
||||
});
|
||||
|
||||
test("Strikethrough", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('strikethrough');
|
||||
equal(editor.getContent(), '<p><strike>text</strike></p>');
|
||||
});
|
||||
|
||||
test("Justifyleft", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('justifyleft');
|
||||
equal(editor.getContent(), '<p align="left">text</p>');
|
||||
});
|
||||
|
||||
test("Justifycenter", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('justifycenter');
|
||||
equal(editor.getContent(), '<p align="center">text</p>');
|
||||
});
|
||||
|
||||
test("Justifyright", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('justifyright');
|
||||
equal(editor.getContent(), '<p align="right">text</p>');
|
||||
});
|
||||
|
||||
test("Justifyfull", function() {
|
||||
editor.setContent('<p>text</p>');
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.execCommand('justifyfull');
|
||||
equal(editor.getContent(), '<p align="justify">text</p>');
|
||||
});
|
||||
|
||||
function initTiny(settings, load) {
|
||||
var default_settings = {
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
document_base_url : '/tinymce/tinymce/trunk/tests/',
|
||||
plugins : 'legacyoutput',
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
load();
|
||||
}
|
||||
};
|
||||
var settings = tinymce.extend(default_settings, settings);
|
||||
tinymce.init(settings);
|
||||
}
|
||||
|
||||
initTiny({}, QUnit.start);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests for Legacyoutput Plugin</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1770
tests/qunit/editor/plugins/lists.html
Normal file
1770
tests/qunit/editor/plugins/lists.html
Normal file
File diff suppressed because it is too large
Load Diff
180
tests/qunit/editor/plugins/media.html
Normal file
180
tests/qunit/editor/plugins/media.html
Normal file
@ -0,0 +1,180 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for Media Plugin</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("Media plugin", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
test("Object retain as is", function() {
|
||||
editor.setContent(
|
||||
'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355">' +
|
||||
'<param name="movie" value="someurl">' +
|
||||
'<param name="wmode" value="transparent">' +
|
||||
'<embed src="someurl" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355" />' +
|
||||
'</object>'
|
||||
);
|
||||
|
||||
equal(editor.getContent(),
|
||||
'<p><object width="425" height="355" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000">' +
|
||||
'<param name="movie" value="someurl">' +
|
||||
'<param name="wmode" value="transparent">' +
|
||||
'<embed src="someurl" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355" />' +
|
||||
'</object></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Embed retain as is", function() {
|
||||
editor.setContent(
|
||||
'<video src="320x240.ogg" autoplay loop controls>text<a href="#">link</a></video>'
|
||||
);
|
||||
|
||||
equal(editor.getContent(),
|
||||
// IE produces a different attribute order for some odd reason, I love IE
|
||||
tinymce.isIE ?
|
||||
'<p><video width="300" height="150" controls="controls" loop="loop" autoplay="autoplay" src="320x240.ogg">text<a href="#">link</a></video></p>' :
|
||||
'<p><video width="300" height="150" src="320x240.ogg" autoplay="autoplay" loop="loop" controls="controls">text<a href="#">link</a></video></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Video retain as is", function() {
|
||||
editor.setContent(
|
||||
'<video src="320x240.ogg" autoplay loop controls>text<a href="#">link</a></video>'
|
||||
);
|
||||
|
||||
equal(editor.getContent(),
|
||||
// IE produces a different attribute order for some odd reason, I love IE
|
||||
tinymce.isIE ?
|
||||
'<p><video width="300" height="150" controls="controls" loop="loop" autoplay="autoplay" src="320x240.ogg">text<a href="#">link</a></video></p>' :
|
||||
'<p><video width="300" height="150" src="320x240.ogg" autoplay="autoplay" loop="loop" controls="controls">text<a href="#">link</a></video></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Iframe retain as is", function() {
|
||||
editor.setContent(
|
||||
'<iframe src="320x240.ogg" allowfullscreen>text<a href="#">link</a></iframe>'
|
||||
);
|
||||
|
||||
equal(editor.getContent(),
|
||||
'<p><iframe src="320x240.ogg" width="300" height="150" allowfullscreen="allowfullscreen">text<a href="#">link</a></iframe></p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Audio retain as is", function() {
|
||||
editor.setContent(
|
||||
'<audio src="sound.mp3">' +
|
||||
'<track kind="captions" src="foo.en.vtt" srclang="en" label="English">' +
|
||||
'<track kind="captions" src="foo.sv.vtt" srclang="sv" label="Svenska">' +
|
||||
'text<a href="#">link</a>' +
|
||||
'</audio>'
|
||||
);
|
||||
|
||||
equal(editor.getContent(),
|
||||
'<p>' +
|
||||
'<audio src="sound.mp3">' +
|
||||
'<track kind="captions" src="foo.en.vtt" srclang="en" label="English">' +
|
||||
'<track kind="captions" src="foo.sv.vtt" srclang="sv" label="Svenska">' +
|
||||
'text<a href="#">link</a>' +
|
||||
'</audio>' +
|
||||
'</p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Resize complex object", function() {
|
||||
editor.setContent(
|
||||
'<video width="300" height="150" controls="controls">' +
|
||||
'<source src="s" />' +
|
||||
'<object type="application/x-shockwave-flash" data="../../js/tinymce/plugins/media/moxieplayer.swf" width="300" height="150">' +
|
||||
'<param name="allowfullscreen" value="true" />' +
|
||||
'<param name="allowscriptaccess" value="always" />' +
|
||||
'<param name="flashvars" value="video_src=s" />' +
|
||||
'<!--[if IE]><param name="movie" value="../../js/tinymce/plugins/media/moxieplayer.swf" /><![endif]-->' +
|
||||
'</object>' +
|
||||
'</video>'
|
||||
);
|
||||
|
||||
var placeholderElm = editor.getBody().firstChild.firstChild;
|
||||
placeholderElm.width = 100;
|
||||
placeholderElm.height = 200;
|
||||
editor.fire('objectResized', {target: placeholderElm, width: placeholderElm.width, height: placeholderElm.height});
|
||||
|
||||
equal(editor.getContent(),
|
||||
'<p>' +
|
||||
'<video width="100" height="200" controls="controls">' +
|
||||
'<source src="s" />' +
|
||||
'<object type="application/x-shockwave-flash" data="../../js/tinymce/plugins/media/moxieplayer.swf" width="100" height="200">' +
|
||||
'<param name="allowfullscreen" value="true" />' +
|
||||
'<param name="allowscriptaccess" value="always" />' +
|
||||
'<param name="flashvars" value="video_src=s" />' +
|
||||
'<!--[if IE]>' +
|
||||
'<param name="movie" value="../../js/tinymce/plugins/media/moxieplayer.swf" />' +
|
||||
'<![endif]-->' +
|
||||
'</object>' +
|
||||
'</video>' +
|
||||
'</p>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Media script elements", function() {
|
||||
editor.setContent(
|
||||
'<script src="http://media1.tinymce.com/123456"></sc'+'ript>' +
|
||||
'<script src="http://media2.tinymce.com/123456"></sc'+'ript>'
|
||||
);
|
||||
|
||||
equal(editor.getBody().getElementsByTagName('img')[0].className, 'mce-object mce-object-script');
|
||||
equal(editor.getBody().getElementsByTagName('img')[0].width, 300);
|
||||
equal(editor.getBody().getElementsByTagName('img')[0].height, 150);
|
||||
equal(editor.getBody().getElementsByTagName('img')[1].className, 'mce-object mce-object-script');
|
||||
equal(editor.getBody().getElementsByTagName('img')[1].width, 100);
|
||||
equal(editor.getBody().getElementsByTagName('img')[1].height, 200);
|
||||
|
||||
equal(editor.getContent(),
|
||||
'<p>\n' +
|
||||
'<script src="http://media1.tinymce.com/123456" type="text/javascript"></sc'+'ript>\n' +
|
||||
'<script src="http://media2.tinymce.com/123456" type="text/javascript"></sc'+'ript>\n' +
|
||||
'</p>'
|
||||
);
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode: "exact",
|
||||
elements: "elm1",
|
||||
add_unload_trigger: false,
|
||||
document_base_url: '/tinymce/tinymce/trunk/tests/',
|
||||
plugins: 'media',
|
||||
media_scripts: [
|
||||
{filter: 'http://media1.tinymce.com'},
|
||||
{filter: 'http://media2.tinymce.com', width: 100, height: 200}
|
||||
],
|
||||
init_instance_callback: function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests for Media Plugin</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
237
tests/qunit/editor/plugins/noneditable.html
Normal file
237
tests/qunit/editor/plugins/noneditable.html
Normal file
@ -0,0 +1,237 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for noneditable</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor, rng;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
module("Noneditable plugin", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
test('expand to noneditable (start)', function() {
|
||||
editor.setContent('<p><span class="mceNonEditable">no</span>yes</p>');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild.firstChild, 1);
|
||||
rng.setEnd(editor.getBody().firstChild.lastChild, 1);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'mouseup');
|
||||
rng = normalizeRng(editor.selection.getRng(true));
|
||||
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endContainer.nodeName, '#text');
|
||||
equal(rng.endOffset, 1);
|
||||
});
|
||||
|
||||
test('expand to noneditable (end)', function() {
|
||||
editor.setContent('<p>yes<span class="mceNonEditable">no</span></p>');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild, 1);
|
||||
rng.setEnd(editor.getBody().firstChild.lastChild.firstChild, 1);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'mouseup');
|
||||
rng = normalizeRng(editor.selection.getRng(true));
|
||||
|
||||
equal(rng.startContainer.nodeName, '#text');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 2);
|
||||
});
|
||||
|
||||
test('expand to noneditable (start/end)', function() {
|
||||
editor.setContent('<p>yes<span class="mceNonEditable">noedit</span>yes</p>');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 1);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'mouseup');
|
||||
rng = normalizeRng(editor.selection.getRng(true));
|
||||
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'P');
|
||||
equal(rng.endOffset, 2);
|
||||
});
|
||||
|
||||
test('type after non editable', function() {
|
||||
editor.setContent('<p><span class="mceNonEditable">no</span>yes</p>');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 2);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'mouseup');
|
||||
type('X');
|
||||
rng = normalizeRng(editor.selection.getRng(true));
|
||||
|
||||
equal(rng.startContainer.getAttribute('data-mce-bogus'), 'true');
|
||||
equal(rng.startContainer.nodeName, 'SPAN');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'SPAN');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(editor.getContent(), '<p><span class="mceNonEditable">no</span>Xyes</p>');
|
||||
});
|
||||
|
||||
test('type between non editable', function() {
|
||||
editor.setContent('<p><span class="mceNonEditable">no</span><span class="mceNonEditable">no</span></p>');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 2);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'mouseup');
|
||||
type('X');
|
||||
rng = normalizeRng(editor.selection.getRng(true));
|
||||
|
||||
equal(rng.startContainer.getAttribute('data-mce-bogus'), 'true');
|
||||
equal(rng.startContainer.nodeName, 'SPAN');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'SPAN');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(editor.getContent(), '<p><span class="mceNonEditable">no</span>X<span class="mceNonEditable">no</span></p>');
|
||||
});
|
||||
|
||||
test('type after last non editable', function() {
|
||||
editor.setContent('<p><span class="mceNonEditable">no</span></p>');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('span')[0].firstChild, 2);
|
||||
rng.setEnd(editor.dom.select('span')[0].firstChild, 2);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'mouseup');
|
||||
type('X');
|
||||
rng = normalizeRng(editor.selection.getRng(true));
|
||||
|
||||
equal(rng.startContainer.getAttribute('data-mce-bogus'), 'true');
|
||||
equal(rng.startContainer.nodeName, 'SPAN');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, 'SPAN');
|
||||
equal(rng.endOffset, 1);
|
||||
equal(editor.getContent(), '<p><span class="mceNonEditable">no</span>X</p>');
|
||||
});
|
||||
|
||||
test('escape noneditable inline element (left)', function() {
|
||||
editor.setContent('<p>no <span class="mceNonEditable">yes</span> no</p><p class="mceNonEditable">no</p>');
|
||||
var container = editor.dom.select('p')[0];
|
||||
rng = editor.dom.createRng();
|
||||
rng.selectNode(editor.dom.select('span')[0]);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
type({keyCode: 37});
|
||||
rng = normalizeRng(editor.selection.getRng(true));
|
||||
|
||||
equal(rng.startContainer.nodeName, 'SPAN');
|
||||
equal(rng.startContainer.parentNode.nodeName, 'P');
|
||||
equal(editor.dom.nodeIndex(rng.startContainer), 1);
|
||||
equal(rng.collapsed, true);
|
||||
});
|
||||
|
||||
test('escape noneditable inline element (right)', function() {
|
||||
editor.setContent('<p>no <span class="mceNonEditable">yes</span> no</p><p class="mceNonEditable">no</p>');
|
||||
var container = editor.dom.select('p')[0];
|
||||
rng = editor.dom.createRng();
|
||||
rng.selectNode(editor.dom.select('span')[0]);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
type({keyCode: 39});
|
||||
rng = normalizeRng(editor.selection.getRng(true));
|
||||
|
||||
equal(rng.startContainer.nodeName, 'SPAN');
|
||||
equal(rng.startContainer.parentNode.nodeName, 'P');
|
||||
equal(editor.dom.nodeIndex(rng.startContainer), 2);
|
||||
equal(rng.collapsed, true);
|
||||
});
|
||||
|
||||
test('escape noneditable block element (left)', function(){
|
||||
editor.setContent('<p>yes</p><p class="mceNonEditable">no</p><p>yes</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.selectNode(editor.dom.select('p')[1]);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
type({keyCode: 37});
|
||||
rng = normalizeRng(editor.selection.getRng(true));
|
||||
|
||||
equal(rng.startContainer.nodeName, "P");
|
||||
equal(editor.dom.nodeIndex(rng.startContainer), 0);
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.collapsed, true);
|
||||
|
||||
});
|
||||
|
||||
test('escape noneditable block element (right)', function(){
|
||||
editor.setContent('<p>yes</p><p class="mceNonEditable">no</p><p>yes</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.selectNode(editor.dom.select('p')[1]);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
type({keyCode: 39});
|
||||
rng = normalizeRng(editor.selection.getRng(true));
|
||||
|
||||
equal(rng.startContainer.nodeName, "P");
|
||||
equal(editor.dom.nodeIndex(rng.startContainer), 2);
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.collapsed, true);
|
||||
|
||||
});
|
||||
|
||||
test('noneditable regexp', function() {
|
||||
editor.setContent('<p>{test1}{test2}</p>');
|
||||
|
||||
equal(editor.dom.select('span').length, 2);
|
||||
equal(editor.getContent(), '<p>{test1}{test2}</p>');
|
||||
});
|
||||
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
indent : false,
|
||||
theme_advanced_styles : 'test1=test1;test2=test2',
|
||||
noneditable_regexp : [/\{[^\}]+\}/g],
|
||||
valid_elements : '@[contenteditable|id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong,b,em,i,strike,u,#p,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value|tabindex|accesskey],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',
|
||||
plugins: 'noneditable',
|
||||
forced_root_block : '',
|
||||
convert_fonts_to_spans : false,
|
||||
entities : 'raw',
|
||||
valid_styles : {
|
||||
'*' : 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,margin,margin-top,margin-right,margin-bottom,margin-left,display'
|
||||
},
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests noneditable plugin</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
440
tests/qunit/editor/plugins/paste.html
Normal file
440
tests/qunit/editor/plugins/paste.html
Normal file
File diff suppressed because one or more lines are too long
59
tests/qunit/editor/plugins/plugin_dependency_chain.html
Normal file
59
tests/qunit/editor/plugins/plugin_dependency_chain.html
Normal file
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Basic editor functionality tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
function check_plugin_loaded(name){
|
||||
var pluginManager = tinymce.PluginManager;
|
||||
var depPlugin = pluginManager.get(name);
|
||||
ok(depPlugin, name + " plugin should have loaded");
|
||||
|
||||
}
|
||||
test('Dependency Chain Legacy style test', function() {
|
||||
expect(3);
|
||||
check_plugin_loaded("example");
|
||||
check_plugin_loaded("example_dependency");
|
||||
check_plugin_loaded("depend_chain");
|
||||
});
|
||||
|
||||
tinymce.create('tinymce.plugins.DependencyChain', {});
|
||||
|
||||
// Register plugin
|
||||
tinymce.PluginManager.add('depend_chain', tinymce.plugins.DependencyChain, ["example_dependency"]);
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
plugins: "depend_chain",
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Plugin Dependency Functional tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Plugin Dependency Functional tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
function check_plugin_loaded(name){
|
||||
var pluginManager = tinymce.PluginManager;
|
||||
var depPlugin = pluginManager.get(name);
|
||||
ok(depPlugin, name + " plugin should have loaded");
|
||||
|
||||
}
|
||||
test('Dependency Chain Legacy style test', function() {
|
||||
expect(3);
|
||||
check_plugin_loaded("example");
|
||||
check_plugin_loaded("example_dependency");
|
||||
check_plugin_loaded("depend_chain");
|
||||
});
|
||||
|
||||
tinymce.create('tinymce.plugins.DependencyChain', {});
|
||||
|
||||
// Register plugin
|
||||
tinymce.PluginManager.add('depend_chain', tinymce.plugins.DependencyChain, ["example_dependency"]);
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
plugins: "-depend_chain",
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Plugin Dependency Functional tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Basic editor functionality tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
function check_plugin_order(order){
|
||||
deepEqual(plugin_load_order, order, "Load order for plugins");
|
||||
}
|
||||
test('PluginDependencyIsLoaded', function() {
|
||||
expect(1);
|
||||
check_plugin_order(["one", "two", "three", "four"]);
|
||||
});
|
||||
var plugin_load_order =[];
|
||||
tinymce.create('tinymce.plugins.One', {
|
||||
init: function(ed, url) {plugin_load_order.push("one");}
|
||||
});
|
||||
|
||||
tinymce.create('tinymce.plugins.Two', {
|
||||
init: function(ed, url) {plugin_load_order.push("two");}
|
||||
});
|
||||
tinymce.create('tinymce.plugins.Three', {
|
||||
init: function(ed, url) {plugin_load_order.push("three");}
|
||||
});
|
||||
tinymce.create('tinymce.plugins.Four', {
|
||||
init: function(ed, url) {plugin_load_order.push("four");}
|
||||
});
|
||||
|
||||
// Register plugin
|
||||
tinymce.PluginManager.add('two', tinymce.plugins.Two, ["one"]);
|
||||
tinymce.PluginManager.add('three', tinymce.plugins.Three, ["two"]);
|
||||
tinymce.PluginManager.add('one', tinymce.plugins.One);
|
||||
tinymce.PluginManager.add('four', tinymce.plugins.Four, ["one", "two"]);
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
plugins: "-three,-four",
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Plugin Dependency Functional tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
50
tests/qunit/editor/plugins/plugin_dependency_simple.html
Normal file
50
tests/qunit/editor/plugins/plugin_dependency_simple.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Basic editor functionality tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
test('PluginDependencyIsLoaded', function() {
|
||||
expect(2);
|
||||
var pluginManager = tinymce.PluginManager;
|
||||
var depPlugin = pluginManager.get("example_dependency");
|
||||
ok(depPlugin, "Example Dependent plugin should have loaded");
|
||||
var examplePlugin = pluginManager.get("example");
|
||||
ok(examplePlugin, "Example plugin should have loaded via dependencies");
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
plugins: "example_dependency",
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Plugin Dependency Functional tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Basic editor functionality tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
function check_plugin_loaded(name){
|
||||
var pluginManager = tinymce.PluginManager;
|
||||
var depPlugin = pluginManager.get(name);
|
||||
ok(depPlugin, name + " plugin should have loaded");
|
||||
|
||||
}
|
||||
test('Plugin Dependency Loaded from a Specific location', function() {
|
||||
expect(2);
|
||||
check_plugin_loaded("specific_location");
|
||||
check_plugin_loaded("autolink");
|
||||
});
|
||||
|
||||
tinymce.create('tinymce.plugins.SpecificLocation', {});
|
||||
|
||||
// Register plugin
|
||||
tinymce.PluginManager.add('specific_location', tinymce.plugins.SpecificLocation, [{prefix: "plugins/", resource:"autolink", suffix:'/plugin' + tinymce.suffix + '.js'}]);
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
plugins: "-specific_location",
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Plugin Dependency Functional tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
132
tests/qunit/editor/plugins/searchreplace.html
Normal file
132
tests/qunit/editor/plugins/searchreplace.html
Normal file
@ -0,0 +1,132 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for searchreplace plugin</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor, rng;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("tinymce.SearchReplace", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
test('Find no match', function() {
|
||||
editor.getBody().innerHTML = 'a';
|
||||
equal(0, editor.plugins.searchreplace.find('x'));
|
||||
});
|
||||
|
||||
test('Find single match', function() {
|
||||
editor.getBody().innerHTML = 'a';
|
||||
equal(1, editor.plugins.searchreplace.find('a'));
|
||||
});
|
||||
|
||||
test('Find single match in multiple elements', function() {
|
||||
editor.getBody().innerHTML = 't<b>e</b><em>xt</em>';
|
||||
equal(1, editor.plugins.searchreplace.find('text'));
|
||||
});
|
||||
|
||||
test('Find single match, match case: true', function() {
|
||||
editor.getBody().innerHTML = 'a A';
|
||||
equal(1, editor.plugins.searchreplace.find('A', true));
|
||||
});
|
||||
|
||||
test('Find single match, whole words: true', function() {
|
||||
editor.getBody().innerHTML = 'a Ax';
|
||||
equal(1, editor.plugins.searchreplace.find('a', false, true));
|
||||
});
|
||||
|
||||
test('Find multiple matches', function() {
|
||||
editor.getBody().innerHTML = 'a b A';
|
||||
equal(2, editor.plugins.searchreplace.find('a'));
|
||||
});
|
||||
|
||||
test('Find and replace single match', function() {
|
||||
editor.getBody().innerHTML = 'a';
|
||||
editor.plugins.searchreplace.find('a');
|
||||
ok(!editor.plugins.searchreplace.replace('x'));
|
||||
equal("<p>x</p>", editor.getContent());
|
||||
});
|
||||
|
||||
test('Find and replace first in multiple matches', function() {
|
||||
editor.getBody().innerHTML = 'a b a';
|
||||
editor.plugins.searchreplace.find('a');
|
||||
ok(editor.plugins.searchreplace.replace('x'));
|
||||
equal("<p>x b a</p>", editor.getContent());
|
||||
});
|
||||
|
||||
test('Find and replace all in multiple matches', function() {
|
||||
editor.getBody().innerHTML = 'a b a';
|
||||
editor.plugins.searchreplace.find('a');
|
||||
ok(!editor.plugins.searchreplace.replace('x', true, true));
|
||||
equal("<p>x b x</p>", editor.getContent());
|
||||
});
|
||||
|
||||
test('Find multiple matches, move to next and replace', function() {
|
||||
editor.getBody().innerHTML = 'a a';
|
||||
equal(2, editor.plugins.searchreplace.find('a'));
|
||||
editor.plugins.searchreplace.next();
|
||||
ok(!editor.plugins.searchreplace.replace('x'));
|
||||
equal("<p>a x</p>", editor.getContent());
|
||||
});
|
||||
|
||||
test('Find multiple matches, move to next and replace backwards', function() {
|
||||
editor.getBody().innerHTML = 'a a';
|
||||
equal(2, editor.plugins.searchreplace.find('a'));
|
||||
editor.plugins.searchreplace.next();
|
||||
ok(editor.plugins.searchreplace.replace('x', false));
|
||||
ok(!editor.plugins.searchreplace.replace('y', false));
|
||||
equal("<p>y x</p>", editor.getContent());
|
||||
});
|
||||
|
||||
test('Find multiple matches and unmark them', function() {
|
||||
editor.getBody().innerHTML = 'a b a';
|
||||
equal(2, editor.plugins.searchreplace.find('a'));
|
||||
editor.plugins.searchreplace.done();
|
||||
equal('a', editor.selection.getContent());
|
||||
equal(0, editor.getBody().getElementsByTagName('span').length);
|
||||
});
|
||||
|
||||
test('Find multiple matches with pre blocks', function() {
|
||||
editor.getBody().innerHTML = 'abc<pre> abc </pre>abc';
|
||||
equal(3, editor.plugins.searchreplace.find('b'));
|
||||
equal(normalizeHtml(editor.getBody().innerHTML), (
|
||||
'a<span class="mce-match-marker mce-match-marker-selected" data-mce-bogus="1" data-mce-index="0">b</span>c' +
|
||||
'<pre> a<span class="mce-match-marker" data-mce-bogus="1" data-mce-index="1">b</span>c </pre>' +
|
||||
'a<span class="mce-match-marker" data-mce-bogus="1" data-mce-index="2">b</span>c'
|
||||
));
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode: "exact",
|
||||
plugins: "searchreplace",
|
||||
elements: "elm1",
|
||||
add_unload_trigger: false,
|
||||
indent: false,
|
||||
disable_nodechange: true,
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
window.setTimeout(function() {
|
||||
QUnit.start();
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests for lists plugin</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<a href="javascript:;" onclick="alert(tinymce.get('elm1').getContent({format: 'raw'}));return false;">[Get raw]</a>
|
||||
</body>
|
||||
</html>
|
||||
108
tests/qunit/editor/plugins/spellchecker.html
Normal file
108
tests/qunit/editor/plugins/spellchecker.html
Normal file
@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for spellchecker plugin</title>
|
||||
<meta http-eqiv="X-UA-Compatible" content="IE-edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editors = {}, awaitingInit=2;
|
||||
|
||||
initTinyMCE({
|
||||
instance_name: 'no_lang'
|
||||
});
|
||||
|
||||
initTinyMCE({
|
||||
instance_name: 'one_lang',
|
||||
spellchecker_languages: 'English=en'
|
||||
});
|
||||
|
||||
initTinyMCE({
|
||||
instance_name: 'many_lang',
|
||||
spellchecker_languages: 'English=en,French=fr,German=de'
|
||||
});
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("tinymce.Spellchecker", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
// Default spellchecker language should match editor language
|
||||
test('Check default language', function() {
|
||||
var mainLanguage = editors.no_lang.settings.language || 'en';
|
||||
equal(editors.no_lang.settings.spellchecker_language, mainLanguage);
|
||||
});
|
||||
|
||||
// Spellchecker button may include a language menu
|
||||
|
||||
// When no languages are specified, the default list of languages should be
|
||||
// used, matching the list in the old TinyMCE 3 spellchecker plugin.
|
||||
test('Check spellcheck button is a splitbutton (no languages)', function() {
|
||||
var spellcheckButton = editors.no_lang.buttons.spellchecker;
|
||||
equal(spellcheckButton.type, 'splitbutton');
|
||||
});
|
||||
|
||||
// When exactly one spellchecker language is specified, there's no need to
|
||||
// display a selection menu.
|
||||
test('Check spellcheck button is a normal button (one language)', function() {
|
||||
var spellcheckButton = editors.one_lang.buttons.spellchecker;
|
||||
equal(spellcheckButton.type, 'button');
|
||||
});
|
||||
|
||||
// When more than one spellchecker language is specified, a selection menu
|
||||
// should be provided to choose between them.
|
||||
test('Check spellcheck button is a splitbutton (many languages)', function() {
|
||||
var spellcheckButton = editors.many_lang.buttons.spellchecker;
|
||||
equal(spellcheckButton.type, 'splitbutton');
|
||||
});
|
||||
|
||||
function initTinyMCE(args) {
|
||||
var instance_name = args.instance_name;
|
||||
var init_args = {
|
||||
mode: "exact",
|
||||
plugins: "spellchecker",
|
||||
selector: '#' + instance_name,
|
||||
add_unload_trigger: false,
|
||||
disable_nodechange: true,
|
||||
toolbar1: "spellchecker",
|
||||
init_instance_callback: function(ed) {
|
||||
editors[instance_name] = ed;
|
||||
checkEditorsReady();
|
||||
}
|
||||
};
|
||||
if (args.spellchecker_languages) {
|
||||
init_args.spellchecker_languages = args.spellchecker_languages;
|
||||
}
|
||||
tinymce.init(init_args);
|
||||
}
|
||||
|
||||
function checkEditorsReady() {
|
||||
awaitingInit--;
|
||||
if (awaitingInit == 0) {
|
||||
window.setTimeout(function() {
|
||||
QUnit.start();
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests for spellchecker plugin</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<textarea id="no_lang"></textarea>
|
||||
<a href="javascript:;" onclick="alert(tinymce.get('no_lang').getContent({format: 'raw'}));return false;">[Get raw]</a>
|
||||
<textarea id="one_lang"></textarea>
|
||||
<a href="javascript:;" onclick="alert(tinymce.get('one_lang').getContent({format: 'raw'}));return false;">[Get raw]</a>
|
||||
<textarea id="many_lang"></textarea>
|
||||
<a href="javascript:;" onclick="alert(tinymce.get('many_lang').getContent({format: 'raw'}));return false;">[Get raw]</a>
|
||||
</body>
|
||||
</html>
|
||||
348
tests/qunit/editor/plugins/table.html
Normal file
348
tests/qunit/editor/plugins/table.html
Normal file
@ -0,0 +1,348 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for the Table plugin</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("Table plugin", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
function getFontmostWindow() {
|
||||
return editor.windowManager.windows[editor.windowManager.windows.length - 1];
|
||||
}
|
||||
|
||||
function fillAndSubmitWindowForm(data) {
|
||||
var win = getFontmostWindow();
|
||||
|
||||
win.fromJSON(data);
|
||||
win.find('form')[0].submit();
|
||||
win.close();
|
||||
}
|
||||
|
||||
function cleanTableHtml(html) {
|
||||
return cleanHtml(html).replace(/<p>( |<br[^>]+>)<\/p>$/, '');
|
||||
}
|
||||
|
||||
test("Table properties dialog (get data from plain table)", function() {
|
||||
editor.setContent('<table><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceInsertTable');
|
||||
|
||||
deepEqual(getFontmostWindow().toJSON(), {
|
||||
"align": false,
|
||||
"border": "",
|
||||
"caption": false,
|
||||
"cellpadding": "",
|
||||
"cellspacing": "",
|
||||
"height": "",
|
||||
"width": ""
|
||||
});
|
||||
|
||||
getFontmostWindow().close();
|
||||
});
|
||||
|
||||
test("Table properties dialog (get data from full table)", function() {
|
||||
editor.setContent(
|
||||
'<table style="width: 100px; height: 101px;" border="4" cellspacing="2" cellpadding="3">' +
|
||||
'<caption> </caption>' +
|
||||
'<tbody>' +
|
||||
'<tr>' +
|
||||
'<td> </td>' +
|
||||
'</tr>' +
|
||||
'</tbody>' +
|
||||
'</table>'
|
||||
);
|
||||
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceInsertTable');
|
||||
|
||||
deepEqual(getFontmostWindow().toJSON(), {
|
||||
"align": false,
|
||||
"border": "4",
|
||||
"caption": true,
|
||||
"cellpadding": "3",
|
||||
"cellspacing": "2",
|
||||
"height": "101",
|
||||
"width": "100"
|
||||
});
|
||||
|
||||
getFontmostWindow().close();
|
||||
});
|
||||
|
||||
test("Table properties dialog (add caption)", function() {
|
||||
editor.setContent('<table><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceInsertTable');
|
||||
fillAndSubmitWindowForm({
|
||||
caption: true
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanTableHtml(editor.getContent()),
|
||||
'<table><caption> </caption><tbody><tr><td>x</td></tr></tbody></table>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Table properties dialog (remove caption)", function() {
|
||||
editor.setContent('<table><caption> </caption><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceInsertTable');
|
||||
fillAndSubmitWindowForm({
|
||||
caption: false
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanTableHtml(editor.getContent()),
|
||||
'<table><tbody><tr><td>x</td></tr></tbody></table>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Table properties dialog (change size in pixels)", function() {
|
||||
editor.setContent('<table><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceInsertTable');
|
||||
fillAndSubmitWindowForm({
|
||||
width: 100,
|
||||
height: 101
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanTableHtml(editor.getContent()),
|
||||
'<table style="width: 100px; height: 101px;"><tbody><tr><td>x</td></tr></tbody></table>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Table properties dialog (change size in %)", function() {
|
||||
editor.setContent('<table><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceInsertTable');
|
||||
fillAndSubmitWindowForm({
|
||||
width: "100%",
|
||||
height: "101%"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanTableHtml(editor.getContent()),
|
||||
'<table style="width: 100%; height: 101%;"><tbody><tr><td>x</td></tr></tbody></table>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Table properties dialog (change: border,cellpadding,cellspacing,align)", function() {
|
||||
editor.setContent('<table><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceInsertTable');
|
||||
fillAndSubmitWindowForm({
|
||||
border: "1",
|
||||
cellpadding: "2",
|
||||
cellspacing: "3",
|
||||
align: "right"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanTableHtml(editor.getContent()),
|
||||
'<table style="float: right;" border="1" cellspacing="3" cellpadding="2"><tbody><tr><td>x</td></tr></tbody></table>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Table cell properties dialog (get data from plain cell)", function() {
|
||||
editor.setContent('<table><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableCellProps');
|
||||
|
||||
deepEqual(getFontmostWindow().toJSON(), {
|
||||
"align": false,
|
||||
"height": "",
|
||||
"scope": "",
|
||||
"type": "td",
|
||||
"width": ""
|
||||
});
|
||||
|
||||
getFontmostWindow().close();
|
||||
});
|
||||
|
||||
test("Table cell properties dialog (get data from complex cell)", function() {
|
||||
editor.setContent('<table><tr><th style="text-align: right; width: 10px; height: 11px" scope="row">X</th></tr></table>');
|
||||
setSelection('th', 0);
|
||||
editor.execCommand('mceTableCellProps');
|
||||
|
||||
deepEqual(getFontmostWindow().toJSON(), {
|
||||
"align": "right",
|
||||
"height": "11",
|
||||
"scope": "row",
|
||||
"type": "th",
|
||||
"width": "10"
|
||||
});
|
||||
|
||||
getFontmostWindow().close();
|
||||
});
|
||||
|
||||
test("Table cell properties dialog (update all)", function() {
|
||||
editor.setContent('<table><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableCellProps');
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"align": "right",
|
||||
"height": "11",
|
||||
"scope": "row",
|
||||
"type": "th",
|
||||
"width": "10"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanTableHtml(editor.getContent()),
|
||||
'<table><tbody><tr><th style="width: 10px; height: 11px; text-align: right;" scope="row">x</th></tr></tbody></table>'
|
||||
);
|
||||
});
|
||||
|
||||
test("Table row properties dialog (get data from plain cell)", function() {
|
||||
editor.setContent('<table><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableRowProps');
|
||||
|
||||
deepEqual(getFontmostWindow().toJSON(), {
|
||||
"align": false,
|
||||
"height": "",
|
||||
"type": "tbody"
|
||||
});
|
||||
|
||||
getFontmostWindow().close();
|
||||
});
|
||||
|
||||
test("Table row properties dialog (get data from complex cell)", function() {
|
||||
editor.setContent('<table><thead><tr style="height: 10px; text-align: right"><td>X</td></tr></thead></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableRowProps');
|
||||
|
||||
deepEqual(getFontmostWindow().toJSON(), {
|
||||
"align": "right",
|
||||
"height": "10",
|
||||
"type": "thead"
|
||||
});
|
||||
|
||||
getFontmostWindow().close();
|
||||
});
|
||||
|
||||
test("Table row properties dialog (update all)", function() {
|
||||
editor.setContent('<table><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableRowProps');
|
||||
|
||||
fillAndSubmitWindowForm({
|
||||
"align": "right",
|
||||
"height": "10",
|
||||
"type": "thead"
|
||||
});
|
||||
|
||||
equal(
|
||||
cleanTableHtml(editor.getContent()),
|
||||
'<table><thead><tr style="height: 10px; text-align: right;"><td>x</td></tr></thead></table>'
|
||||
);
|
||||
});
|
||||
|
||||
test("mceTableDelete command", function() {
|
||||
editor.setContent('<table><tr><td>X</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableDelete');
|
||||
equal(cleanTableHtml(editor.getContent()), '');
|
||||
});
|
||||
|
||||
test("mceTableDeleteCol command", function() {
|
||||
editor.setContent('<table><tr><td>1</td><td>2</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableDeleteCol');
|
||||
equal(cleanTableHtml(editor.getContent()), '<table><tbody><tr><td>2</td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test("mceTableDeleteRow command", function() {
|
||||
editor.setContent('<table><tr><td>1</td></tr><tr><td>2</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableDeleteRow');
|
||||
equal(cleanTableHtml(editor.getContent()), '<table><tbody><tr><td>2</td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test("mceTableInsertColAfter command", function() {
|
||||
editor.setContent('<table><tr><td>1</td></tr><tr><td>2</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableInsertColAfter');
|
||||
equal(cleanTableHtml(editor.getContent()), '<table><tbody><tr><td>1</td><td> </td></tr><tr><td>2</td><td> </td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test("mceTableInsertColBefore command", function() {
|
||||
editor.setContent('<table><tr><td>1</td></tr><tr><td>2</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableInsertColBefore');
|
||||
equal(cleanTableHtml(editor.getContent()), '<table><tbody><tr><td> </td><td>1</td></tr><tr><td> </td><td>2</td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test("mceTableInsertRowAfter command", function() {
|
||||
editor.setContent('<table><tr><td>1</td><td>2</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableInsertRowAfter');
|
||||
equal(cleanTableHtml(editor.getContent()), '<table><tbody><tr><td>1</td><td>2</td></tr><tr><td> </td><td> </td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test("mceTableInsertRowBefore command", function() {
|
||||
editor.setContent('<table><tr><td>1</td><td>2</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableInsertRowBefore');
|
||||
equal(cleanTableHtml(editor.getContent()), '<table><tbody><tr><td> </td><td> </td></tr><tr><td>1</td><td>2</td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test("mceTableMergeCells command with cell selection", function() {
|
||||
editor.setContent('<table><tr><td class="mce-item-selected">1</td><td class="mce-item-selected">2</td></tr></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableMergeCells');
|
||||
equal(cleanTableHtml(editor.getContent()), '<table><tbody><tr><td colspan="2">12</td></tr></tbody></table>');
|
||||
});
|
||||
|
||||
test("mceTableSplitCells command", function() {
|
||||
editor.setContent('<table><tbody><tr><td colspan="2">12</td></tr></tbody></table>');
|
||||
setSelection('td', 0);
|
||||
editor.execCommand('mceTableSplitCells');
|
||||
equal(
|
||||
cleanTableHtml(editor.getContent()),
|
||||
'<table><tbody><tr><td>12</td><td> </td></tr></tbody></table>'
|
||||
);
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
selector: "textarea",
|
||||
add_unload_trigger: false,
|
||||
plugins: 'table',
|
||||
valid_styles: {
|
||||
'*' : 'width,height,text-align,float'
|
||||
},
|
||||
init_instance_callback: function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<h1 id="qunit-header">Unit tests for the Table plugin</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
189
tests/qunit/editor/plugins/table_robot.html
Normal file
189
tests/qunit/editor/plugins/table_robot.html
Normal file
@ -0,0 +1,189 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Table plugin tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script src="../js/jsrobot/robot.js"></script>
|
||||
<script>
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module('Table plugin', {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
var VK;
|
||||
var UP_ARROW = 0x26;
|
||||
var DOWN_ARROW = 0x28;
|
||||
var ENTER = 0xA;
|
||||
|
||||
if (tinymce.isWebKit) {
|
||||
asyncTest('Selecting Cell and typing should update cell correctly in WebKit', function() {
|
||||
editor.setContent('<table><tr><td><p>first cell</p></td><td><p>second cell</p></td></tr></table>');
|
||||
// in order for the robot to work well, we need to focus the editor before performing selection on it.
|
||||
editor.focus();
|
||||
// in order to simulate the section on tables as per the plugin we do a select then call out to the fix table selection
|
||||
// (which is called by selection events).
|
||||
editor.selection.select(editor.dom.select('td')[0]);
|
||||
editor.fire('keydown');
|
||||
robot.type('g',false, function(){
|
||||
var expected = '<table><tbody><tr><td><p>g</p></td><td><p>second cell</p></td></tr></tbody></table>';
|
||||
var actual = editor.getContent();
|
||||
equal(actual, expected);
|
||||
start();
|
||||
}, editor.getBody());
|
||||
});
|
||||
} else {
|
||||
asyncTest('Empty stub', function() {
|
||||
start();
|
||||
ok(true, "Dummy");
|
||||
});
|
||||
}
|
||||
|
||||
function testCursorKey(html, nodeToSelect, keyCode, expected) {
|
||||
editor.setContent(html);
|
||||
editor.focus();
|
||||
setSelection(nodeToSelect, 0);
|
||||
editor.focus();
|
||||
robot.type(keyCode, false, function() {
|
||||
var node = editor.selection.getNode();
|
||||
var actual = node.firstChild.nodeValue;
|
||||
equal(actual, expected);
|
||||
start();
|
||||
}, editor.getBody());
|
||||
}
|
||||
|
||||
asyncTest('space key does not nuke content in th cells', 1, function() {
|
||||
editor.setContent('<table><tbody><tr><th id="a">abcdef</th></tr></tbody></table>');
|
||||
editor.focus();
|
||||
setSelection('#a', 3);
|
||||
editor.focus();
|
||||
robot.type(VK.SPACEBAR, false, function() {
|
||||
var actual = editor.dom.get('a').innerHTML;
|
||||
var expected = 'abc def';
|
||||
equal(actual, expected);
|
||||
start()
|
||||
}, editor.getBody());
|
||||
});
|
||||
|
||||
asyncTest('arrow up key moves to row above', function() {
|
||||
var html = '<table><tr><td>0</td><td>1</td></tr><tr><td>0</td><td id="b">2</td></tr></table>';
|
||||
testCursorKey(html, '#b', UP_ARROW, '1');
|
||||
});
|
||||
|
||||
asyncTest('arrow up key moves to row above for heading cells', function() {
|
||||
var html = '<table><tr><td>0</td><td>1</td></tr><tr><td>0</td><th id="b">2</th></tr></table>';
|
||||
testCursorKey(html, '#b', UP_ARROW, '1');
|
||||
});
|
||||
|
||||
|
||||
asyncTest('arrow down key moves to row below', function() {
|
||||
var html = '<table><tr><td id="a"></td></tr><tr><td>2</td></tr></table>';
|
||||
testCursorKey(html, '#a', DOWN_ARROW, '2');
|
||||
});
|
||||
|
||||
asyncTest('arrow up key in cell with colspan moves to row above', function() {
|
||||
var html = '<table><tr><td>1</td><td></td></tr><tr><td id="b" colspan="2"></td></tr></table>';
|
||||
testCursorKey(html, '#b', UP_ARROW, '1');
|
||||
});
|
||||
|
||||
asyncTest('arrow down key in cell with colspan moves to row below', function() {
|
||||
var html = '<table><tr><td id="a" colspan="2"></td></tr><tr><td>2</td><td></td></tr></table>';
|
||||
testCursorKey(html, '#a', DOWN_ARROW, '2');
|
||||
});
|
||||
|
||||
asyncTest('arrow key up in top row escapes table', function() {
|
||||
var html = '<p>outside</p><table><tr><td id="a"></td></tr><tr><td></td></tr></table>';
|
||||
testCursorKey(html, '#a', UP_ARROW, 'outside');
|
||||
});
|
||||
|
||||
asyncTest('arrow key down in bottom row escapes table', function() {
|
||||
var html = '<table><tr><td></td></tr><tr><td id="b"></td></tr></table><p>outside</p>';
|
||||
testCursorKey(html, '#b', DOWN_ARROW, 'outside');
|
||||
});
|
||||
|
||||
asyncTest('arrow key up in bottom row to last p in above tr', 1, function() {
|
||||
var html = "<table><tr><td><p id='a'>a</p><p id='b'>b</p></td></tr><tr><td><p id='c'>c</p><p>d</p></td></tr></table>";
|
||||
testCursorKey(html, '#c', UP_ARROW, 'b');
|
||||
});
|
||||
|
||||
asyncTest('arrow key down in top row to first p in below tr', 1, function() {
|
||||
var html = "<table><tr><td><p id='a'>a</p><p id='b'>b</p></td></tr><tr><td><p id='c'>c</p><p>d</p></td></tr></table>";
|
||||
testCursorKey(html, '#b', DOWN_ARROW, 'c');
|
||||
});
|
||||
|
||||
asyncTest('arrow key down into table cell with br', 1, function() {
|
||||
var html = "<table><tr><td id='a'></td></tr><tr><td>something<br></td></tr></table>";
|
||||
testCursorKey(html, '#a', DOWN_ARROW, 'something');
|
||||
});
|
||||
|
||||
asyncTest('shift-enter in table cell ending with BR places caret on new line', function() {
|
||||
editor.setContent('<table><tr><td>d <strong>e</strong><br></td></tr></table>');
|
||||
setSelection('strong', 1);
|
||||
robot.type(ENTER, true, function(){
|
||||
var expected = '<table><tbody><tr><td>d <strong>e<br /></strong></td></tr></tbody></table>';
|
||||
var actual = editor.getContent();
|
||||
var range = editor.selection.getRng(true);
|
||||
equal(cleanHtml(actual), expected);
|
||||
equal(range.startContainer.nodeName, 'STRONG');
|
||||
equal(range.startOffset, 2);
|
||||
equal(range.collapsed, true);
|
||||
start();
|
||||
}, editor.getBody());
|
||||
});
|
||||
|
||||
// Only run on Gecko since WebKit and IE can place a caret after a table
|
||||
if (tinymce.Env.gecko) {
|
||||
test("Insert table and remove caret placeholder", function() {
|
||||
editor.setContent('<table><tbody><tr><td>x</td></tr></tbody></table>');
|
||||
equal(editor.getBody().firstChild.nodeName, "TABLE");
|
||||
equal(editor.getBody().lastChild.nodeName, "P");
|
||||
equal(editor.getContent(), '<table><tbody><tr><td>x</td></tr></tbody></table>');
|
||||
});
|
||||
} else {
|
||||
test("Skipped since it works in this browser", function() {
|
||||
ok(true, "Dummy assert");
|
||||
});
|
||||
}
|
||||
|
||||
var initTinyFunction = function(){
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
cleanup: true,
|
||||
indent: false,
|
||||
add_unload_trigger : false,
|
||||
webkit_fake_resize: false,
|
||||
plugins: "table",
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
VK = tinymce.util.VK;
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Table plugin tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
initWhenTinyAndRobotAreReady(initTinyFunction);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
24
tests/qunit/editor/plugins/tests.js
Normal file
24
tests/qunit/editor/plugins/tests.js
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"title": "Plugins tests",
|
||||
"tests": [
|
||||
{"title": "Media", "url": "media.html"},
|
||||
{"title": "Noneditable", "url": "noneditable.html"},
|
||||
{"title": "Paste", "url": "paste.html"},
|
||||
{"title": "Table", "url": "table.html"},
|
||||
{"title": "Table (robot)", "url": "table_robot.html", "jsrobot": true},
|
||||
{"title": "jQuery", "url": "jquery_plugin.html"},
|
||||
{"title": "Autolink (robot)", "url": "autolink.html", "jsrobot": true},
|
||||
{"title": "Autosave", "url": "autosave.html"},
|
||||
{"title": "Wordcount", "url": "wordcount.html"},
|
||||
{"title": "Fullpage", "url": "fullpage.html"},
|
||||
{"title": "Legacyoutput", "url": "legacyoutput.html"},
|
||||
{"title": "Plugin Dependencies", "url": "plugin_dependency_simple.html"},
|
||||
{"title": "Plugin Dependency Chain", "url": "plugin_dependency_chain.html"},
|
||||
{"title": "Plugin Dependency Chain Legacy", "url": "plugin_dependency_chain_legacy.html"},
|
||||
{"title": "Dependency Chain Init Call Order", "url": "plugin_dependency_init_call_order.html"},
|
||||
{"title": "Dependency With Specific Location", "url": "plugin_dependency_specific_location.html"},
|
||||
{"title": "Lists", "url": "lists.html"},
|
||||
{"title": "Searchreplace", "url": "searchreplace.html"},
|
||||
{"title": "Spellchecker", "url": "spellchecker.html"}
|
||||
]
|
||||
}
|
||||
122
tests/qunit/editor/plugins/wordcount.html
Normal file
122
tests/qunit/editor/plugins/wordcount.html
Normal file
@ -0,0 +1,122 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for the Wordcount plugin</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("tinymce.plugins.Wordcount", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
test("Blank document has 0 words", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 0);
|
||||
});
|
||||
|
||||
test("Simple word count", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>My sentence is this.</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 4);
|
||||
});
|
||||
|
||||
test("Does not count dashes", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>Something -- ok</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 2);
|
||||
});
|
||||
|
||||
test("Does not count asterisks, non-word characters", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>* something\n· something else</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 3);
|
||||
});
|
||||
|
||||
test("Does not count htmlentities", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>It’s my life – don\'t you forget.</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 6);
|
||||
});
|
||||
|
||||
test("Counts hyphenated words as one word", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>Hello some-word here.</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 3);
|
||||
});
|
||||
|
||||
test("Counts words between blocks as two words", function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>Hello</p><p>world</p>');
|
||||
var result = editor.plugins.wordcount.getCount();
|
||||
equal(result, 2);
|
||||
});
|
||||
|
||||
/*
|
||||
The blocking functionality in the wordcount plugin prevents this code from
|
||||
being tested correctly.
|
||||
|
||||
I'm of the opinion that the blocking code isn't really doing
|
||||
anything crucial, and should be ripped out, so this module can be tested.
|
||||
---------
|
||||
test("should set the word count in the target html element", function() {
|
||||
expect(1);
|
||||
editor.setContent('<p>Hey, it\'s me!</p>');
|
||||
equal(parseInt(document.getElementById('elm1-word-count').innerHTML), 3);
|
||||
});
|
||||
*/
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
wordcount_target_id: 'current-count',
|
||||
plugins : 'wordcount',
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<h1 id="qunit-header">Unit tests for the Wordcount plugin</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
|
||||
<div id="word-count">
|
||||
Current Count: <span id="current-count"></span>
|
||||
</div>
|
||||
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
tests/qunit/editor/test.gif
Normal file
BIN
tests/qunit/editor/test.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 B |
221
tests/qunit/editor/tinymce/Editor.html
Normal file
221
tests/qunit/editor/tinymce/Editor.html
Normal file
@ -0,0 +1,221 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for tinymce.Editor</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
module("tinymce.Editor", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
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 level, lastLevel, 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>\n<table>\n<tbody>\n<tr>\n<td>X</td>\n</tr>\n</tbody>\n</table>\n<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('custom elements', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<custom1>c1</custom1><custom2>c1</custom2>');
|
||||
equal(editor.getContent().replace(/[\r\n]/g, ''), '<custom1>c1</custom1><p><custom2>c1</custom2></p>');
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : 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'
|
||||
},
|
||||
custom_elements: 'custom1,~custom2',
|
||||
extended_valid_elements: 'custom1,custom2',
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests for tinymce.Editor</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
765
tests/qunit/editor/tinymce/EditorCommands.html
Normal file
765
tests/qunit/editor/tinymce/EditorCommands.html
Normal file
@ -0,0 +1,765 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for tinymce.EditorCommands</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
module("tinymce.EditorCommands", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
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 = 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 - 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 = 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 = 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 = 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 = 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 = 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>';
|
||||
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 = 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 = 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" alt="" /></p>');
|
||||
rng = 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, '<u>u</u><strike>strike</strike><font size="7">font</font>');
|
||||
equal(editor.getContent(), '<p><span style="text-decoration: underline;">u</span><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 = 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() {
|
||||
var rng;
|
||||
|
||||
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() {
|
||||
var rng;
|
||||
|
||||
expect(1);
|
||||
|
||||
// Forced root block
|
||||
editor.getBody().innerHTML = '<table><tr><td>X</td></tr></table>';
|
||||
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);
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
setSelection('p', 1);
|
||||
editor.execCommand('mceInsertContent', false, ' <p>b</p> ');
|
||||
equal(editor.getContent(), '<p>a</p><p>b</p><p>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 = 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>');
|
||||
setSelection('#a', 0, '#b', 3);
|
||||
equal(editor.queryCommandState('JustifyLeft'), false);
|
||||
ok(editor.queryCommandState('JustifyRight'));
|
||||
});
|
||||
|
||||
test('Formatting commands (xhtmlTextStyles)', function() {
|
||||
var c;
|
||||
|
||||
expect(19);
|
||||
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: ' + 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><u>test 123</u></p>');
|
||||
equal(editor.getContent(), '<p><span style="text-decoration: underline;">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: ' + 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: ' + 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: ' + 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: ' + 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="../media/logo.jpg" />');
|
||||
editor.selection.select(editor.dom.select('img')[0]);
|
||||
editor.execCommand('JustifyLeft');
|
||||
equal(editor.getContent(), '<p><img style="float: left;" src="../media/logo.jpg" alt="" /></p>');
|
||||
|
||||
editor.setContent('<img src="../media/logo.jpg" />');
|
||||
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="../media/logo.jpg" alt="" /></p>');
|
||||
|
||||
editor.setContent('<img src="../media/logo.jpg" />');
|
||||
editor.selection.select(editor.dom.select('img')[0]);
|
||||
editor.execCommand('JustifyRight');
|
||||
equal(editor.getContent(), '<p><img style="float: right;" src="../media/logo.jpg" alt="" /></p>');
|
||||
});
|
||||
|
||||
test('mceBlockQuote', function() {
|
||||
expect(2);
|
||||
|
||||
editor.focus();
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceBlockQuote');
|
||||
equal(editor.getContent().replace(/\s+/g, ''), '<blockquote><p>test123</p></blockquote>');
|
||||
|
||||
editor.setContent('<p>test 123</p><p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceBlockQuote');
|
||||
equal(editor.getContent().replace(/\s+/g, ''), '<blockquote><p>test123</p><p>test123</p></blockquote>');
|
||||
});
|
||||
|
||||
test('FormatBlock', function() {
|
||||
expect(9);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h1');
|
||||
equal(editor.getContent(), '<h1>test 123</h1>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h2');
|
||||
equal(editor.getContent(), '<h2>test 123</h2>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h3');
|
||||
equal(editor.getContent(), '<h3>test 123</h3>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h4');
|
||||
equal(editor.getContent(), '<h4>test 123</h4>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h5');
|
||||
equal(editor.getContent(), '<h5>test 123</h5>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'h6');
|
||||
equal(editor.getContent(), '<h6>test 123</h6>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
|
||||
try {
|
||||
editor.execCommand('FormatBlock', false, 'div');
|
||||
} catch (ex) {
|
||||
//t.log('Failed: ' + ex.message);
|
||||
}
|
||||
|
||||
equal(editor.getContent(), '<div>test 123</div>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'address');
|
||||
equal(editor.getContent(), '<address>test 123</address>');
|
||||
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('FormatBlock', false, 'pre');
|
||||
equal(editor.getContent(), '<pre>test 123</pre>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (relative)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('test 123');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, 'test');
|
||||
equal(editor.getContent(), '<p><a href="test">test 123</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link absolute)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, 'http://www.site.com');
|
||||
equal(editor.getContent(), '<p><a href="http://www.site.com">test 123</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link encoded)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, '"&<>');
|
||||
equal(editor.getContent(), '<p><a href=""&<>">test 123</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link encoded and with class)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, {href : '"&<>', 'class' : 'test'});
|
||||
equal(editor.getContent(), '<p><a class="test" href=""&<>">test 123</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link with space)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p>test 123</p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, {href : 'foo bar'});
|
||||
equal(editor.getContent(), '<p><a href="foo%20bar">test 123</a></p>');
|
||||
});
|
||||
|
||||
test('mceInsertLink (link floated img)', function() {
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p><img style="float: right;" src="about:blank" /></p>');
|
||||
editor.execCommand('SelectAll');
|
||||
editor.execCommand('mceInsertLink', false, 'link');
|
||||
equal(editor.getContent(), '<p><a href="link"><img style="float: right;" src="about:blank" alt="" /></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() {
|
||||
var rng;
|
||||
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p><a href="#"><em>abc</em></a></p>');
|
||||
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() {
|
||||
var rng;
|
||||
|
||||
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() {
|
||||
var rng;
|
||||
|
||||
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() {
|
||||
var rng;
|
||||
|
||||
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() {
|
||||
var rng;
|
||||
|
||||
expect(1);
|
||||
|
||||
editor.setContent('<p><a href="#">test</a></p>');
|
||||
setSelection('p', 0, 'p', 1);
|
||||
editor.execCommand('SelectAll');
|
||||
|
||||
editor.execCommand('mceInsertLink', false, 'link');
|
||||
equal(editor.getContent(), '<p><a href="link">test</a></p>');
|
||||
});
|
||||
|
||||
test('unlink', function() {
|
||||
expect(1);
|
||||
|
||||
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('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('RemoveFormat', function() {
|
||||
var t = this;
|
||||
|
||||
expect(3);
|
||||
|
||||
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>');
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
indent : 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) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests for tinymce.EditorCommands</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1018
tests/qunit/editor/tinymce/EnterKey.html
Normal file
1018
tests/qunit/editor/tinymce/EnterKey.html
Normal file
File diff suppressed because it is too large
Load Diff
116
tests/qunit/editor/tinymce/ForceBlocks.html
Normal file
116
tests/qunit/editor/tinymce/ForceBlocks.html
Normal file
@ -0,0 +1,116 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for tinymce.ForceBlocks</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("tinymce.ForceBlocks", {
|
||||
autostart: false,
|
||||
setup: function() {
|
||||
editor.settings.forced_root_block = 'p';
|
||||
editor.settings.forced_root_block_attrs = null;
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
test('Wrap single root text node in P', function() {
|
||||
editor.getBody().innerHTML = 'abcd';
|
||||
setSelection('body', 2);
|
||||
pressArrowKey();
|
||||
equal(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';
|
||||
setSelection('body', 2);
|
||||
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>';
|
||||
setSelection('body', 2);
|
||||
pressArrowKey();
|
||||
equal(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>';
|
||||
setSelection('em', 2);
|
||||
pressArrowKey();
|
||||
equal(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';
|
||||
setSelection('body', 2);
|
||||
pressArrowKey();
|
||||
equal(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>';
|
||||
setSelection('body', 2);
|
||||
body.insertBefore(editor.getDoc().createTextNode(''), body.firstChild);
|
||||
body.appendChild(editor.getDoc().createTextNode(''));
|
||||
pressArrowKey();
|
||||
equal(cleanHtml(body.innerHTML), '<div>abcd</div><div>abcd</div>');
|
||||
equal(editor.selection.getNode().nodeName, 'DIV');
|
||||
equal(body.childNodes.length, 2);
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
indent : false,
|
||||
schema: 'html5',
|
||||
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) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests for tinymce.ForceBlocks</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
</body>
|
||||
</html>
|
||||
1228
tests/qunit/editor/tinymce/Formatter_apply.html
Normal file
1228
tests/qunit/editor/tinymce/Formatter_apply.html
Normal file
File diff suppressed because it is too large
Load Diff
271
tests/qunit/editor/tinymce/Formatter_check.html
Normal file
271
tests/qunit/editor/tinymce/Formatter_check.html
Normal file
@ -0,0 +1,271 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for check formatting</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script>
|
||||
var editor, inlineEditor, rng, format;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
module("Check formatting", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
function getContent() {
|
||||
return editor.getContent().toLowerCase().replace(/[\r\n]+/g, '');
|
||||
};
|
||||
|
||||
test('Selected style element text', function() {
|
||||
editor.formatter.register('bold', {inline : 'b'});
|
||||
editor.getBody().innerHTML = '<p><b>1234</b></p>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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');
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
theme_advanced_styles : 'test1=test1;test2=test2',
|
||||
valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong,b,em,i,strike,u,#p,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value|tabindex|accesskey],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',
|
||||
fix_list_elements : 0,
|
||||
fix_table_elements : 0,
|
||||
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) {
|
||||
editor = ed;
|
||||
|
||||
if (inlineEditor) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var url = document.location.href.substring( 0, document.location.href.lastIndexOf('tinymce/') );
|
||||
|
||||
tinymce.init({
|
||||
selector: "#elm2",
|
||||
inline: true,
|
||||
external_plugins: {
|
||||
noneditable: url + 'external-plugins/noneditable/plugin.js'
|
||||
},
|
||||
add_unload_trigger: false,
|
||||
indent: false,
|
||||
theme_advanced_styles: 'test1=test1;test2=test2',
|
||||
forced_root_block: '',
|
||||
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) {
|
||||
inlineEditor = ed;
|
||||
|
||||
if (editor) {
|
||||
QUnit.start();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests for text formatting</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
<div id="elm2"></div>
|
||||
</body>
|
||||
</html>
|
||||
401
tests/qunit/editor/tinymce/Formatter_remove.html
Normal file
401
tests/qunit/editor/tinymce/Formatter_remove.html
Normal file
@ -0,0 +1,401 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for remove formatting</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor, rng, format;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
module("Remove formatting", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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>';
|
||||
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});
|
||||
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'});
|
||||
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'});
|
||||
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'});
|
||||
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'});
|
||||
setSelection('b', 3, 'b', 3);
|
||||
editor.formatter.remove('format');
|
||||
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'});
|
||||
setSelection('b', 3, 'b', 3);
|
||||
editor.formatter.remove('format');
|
||||
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'});
|
||||
setSelection('b', 3, 'b', 3);
|
||||
editor.formatter.remove('format');
|
||||
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'});
|
||||
setSelection('b', 3, 'b', 3);
|
||||
editor.formatter.remove('format');
|
||||
type('d');
|
||||
equal(editor.getContent(), '<p><em><b>abc</b></em><b>d</b>e</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'});
|
||||
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() {
|
||||
var rng;
|
||||
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
editor.setContent('<p>abc</p><p contenteditable="false"><b>def</b></p><p><b>ghj</b></p>');
|
||||
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><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>');
|
||||
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><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>');
|
||||
setSelection('b', 0, 'b', 3);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p>abc</p><p><span>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>');
|
||||
setSelection('h1:nth-child(2)', 0, 'h1:nth-child(2)', 3);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p>abc</p><h1>def</h1>', 'H1 is still not h1');
|
||||
});
|
||||
|
||||
/*
|
||||
test('Remove format bug 1', function() {
|
||||
editor.setContent('<p><b>ab<em>cde</em>fgh</b></p>');
|
||||
editor.formatter.register('format', {inline: 'b'});
|
||||
setSelection('em', 0, 'em', 2);
|
||||
editor.formatter.remove('format');
|
||||
equal(editor.getContent(), '<p><b>ab</b><em>cd</em><b><em>e</em>fgh</b></p>');
|
||||
});
|
||||
*/
|
||||
|
||||
var url = document.location.href.substring( 0, document.location.href.lastIndexOf('tinymce/') );
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
external_plugins: {
|
||||
noneditable: url + 'external-plugins/noneditable/plugin.js'
|
||||
},
|
||||
indent : false,
|
||||
add_unload_trigger : false,
|
||||
theme_advanced_styles : 'test1=test1;test2=test2',
|
||||
valid_elements : '@[contenteditable|id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong,b,em,i,strike,u,#p,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value|tabindex|accesskey],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',
|
||||
fix_list_elements : 0,
|
||||
fix_table_elements : 0,
|
||||
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) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests for text formatting</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
94
tests/qunit/editor/tinymce/Formatter_robot.html
Normal file
94
tests/qunit/editor/tinymce/Formatter_robot.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Basic editor functionality tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script src="../js/jsrobot/robot.js"></script>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module('Formatting - Robot Tests', {
|
||||
autostart: false
|
||||
});
|
||||
function checkExpectedAfterNewParagraph(expected) {
|
||||
robot.type('\n', false, function() {
|
||||
robot.type('g', false, function() {
|
||||
var actual = editor.getContent();
|
||||
var cleaned = actual.replace("<br />","");
|
||||
equal(cleaned, expected);
|
||||
start();
|
||||
}, editor.getBody())
|
||||
}, editor.getBody());
|
||||
}
|
||||
asyncTest('Should not be bold after turning off bold and going to a new paragraph', function() {
|
||||
editor.setContent('<p><strong>text</strong></p>');
|
||||
// in order for the robot to work well, we need to focus the editor before performing selection on it.
|
||||
editor.focus();
|
||||
setSelection("strong",4);
|
||||
editor.execCommand("Bold");
|
||||
var expected = '<p><strong>text</strong></p>\n<p>g</p>';
|
||||
checkExpectedAfterNewParagraph(expected);
|
||||
});
|
||||
|
||||
asyncTest('Format with nested formatting turned off handled correctly', function(){
|
||||
editor.setContent('<p><strong>bold<em>italic<span style="text-decoration: underline;">under</span></em></strong></p>');
|
||||
editor.focus();
|
||||
setSelection("span",5);
|
||||
editor.execCommand("Italic");
|
||||
var expected ='<p><strong>bold<em>italic<span style="text-decoration: underline;">under</span></em></strong></p>\n<p><strong><span style="text-decoration: underline;">g</span></strong></p>';
|
||||
checkExpectedAfterNewParagraph(expected);
|
||||
});
|
||||
|
||||
asyncTest('Format selection over two lines', function(){
|
||||
editor.setContent("<div id='a'>one</div><div id='b'>two</div>");
|
||||
editor.focus();
|
||||
setSelection('#a', 0, '#b', 0);
|
||||
editor.execCommand('formatBlock', false, 'h1');
|
||||
equal(editor.dom.select('#a')[0].tagName, 'H1');
|
||||
equal(editor.dom.select('#b')[0].tagName, 'DIV');
|
||||
start();
|
||||
});
|
||||
|
||||
var initTinyFunction = function(){
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
cleanup: true,
|
||||
|
||||
add_unload_trigger : false,
|
||||
plugins: "table",
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Plugin Dependency Functional tests</h1>
|
||||
|
||||
<h2 id="qunit-banner"></h2>
|
||||
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
initWhenTinyAndRobotAreReady(initTinyFunction);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
189
tests/qunit/editor/tinymce/UndoManager.html
Normal file
189
tests/qunit/editor/tinymce/UndoManager.html
Normal file
@ -0,0 +1,189 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>tinymce.UndoManager tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
module("tinymce.UndoManager", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
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() {
|
||||
editor.undoManager.clear();
|
||||
editor.setContent('test');
|
||||
|
||||
expect(2);
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'keydown', {keyCode : 65});
|
||||
ok(editor.undoManager.typing)
|
||||
|
||||
editor.dom.fire(editor.getBody(), 'keyup', {keyCode : 13});
|
||||
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('Undo added when typing and losing focus', function() {
|
||||
editor.focus();
|
||||
editor.undoManager.clear();
|
||||
editor.setContent("<p>some text</p>");
|
||||
setSelection('p', 4, 'p', 9);
|
||||
type('\b');
|
||||
window.focus();
|
||||
editor.dom.fire(editor.getBody(), 'focusout');
|
||||
editor.execCommand('FormatBlock', false, 'h1');
|
||||
editor.undoManager.undo();
|
||||
equal(editor.getContent(), "<p>some</p>");
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
theme_advanced_styles : 'test1=test1;test2=test2',
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">tinymce.UndoManager tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"><textarea id="elm1" name="elm1"></textarea></div>
|
||||
</body>
|
||||
</html>
|
||||
115
tests/qunit/editor/tinymce/UndoManager_robot.html
Normal file
115
tests/qunit/editor/tinymce/UndoManager_robot.html
Normal file
@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Undo Tests</title>
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../js/qunit/reporter.js"></script>
|
||||
<script src="../js/utils.js"></script>
|
||||
<script src="../js/tinymce_loader.js"></script>
|
||||
<script src="../js/jsrobot/robot.js"></script>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
var BACKSPACE = 0x8;
|
||||
|
||||
module('Undo', {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
function isUndoEnabled() {
|
||||
return editor.undoManager.hasUndo();
|
||||
}
|
||||
|
||||
// The following code never made it into the main codebase -- but it might be useful one day.
|
||||
// If you're seeing this in August 2011 or later, please delete.
|
||||
// in webkit the iframe window needs to be given focus before selection
|
||||
// will behave correctly. This code assigns focus to the tinymce window, giving it back to the
|
||||
// main window if it started with it.
|
||||
// if (tinymce.isWebKit) {
|
||||
// var hadFocus = document.hasFocus();
|
||||
// t.getWin().focus();
|
||||
// if (hadFocus) {
|
||||
// window.focus();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
function assertUndoEnabledWhenTyping(c, expectedContent) {
|
||||
editor.setContent('<p>Content</p>');
|
||||
|
||||
editor.undoManager.clear();
|
||||
editor.undoManager.add();
|
||||
editor.execCommand('mceRepaint');
|
||||
// Need to focus the editor before setting selection in order to get the editor typing working correctly.
|
||||
// All evidence points to the normal APIs not needing an editor.focus() call
|
||||
editor.focus();
|
||||
setSelection('p', 4);
|
||||
ok(!isUndoEnabled(), 'Undo starts disabled.');
|
||||
robot.type(c, false, function() {
|
||||
equal(editor.getContent(), expectedContent);
|
||||
ok(isUndoEnabled(), 'Undo is enabled.');
|
||||
QUnit.start();
|
||||
}, editor.selection.getNode());
|
||||
}
|
||||
|
||||
asyncTest('Undo added when typing character', function() {
|
||||
assertUndoEnabledWhenTyping('b', '<p>Contbent</p>');
|
||||
});
|
||||
|
||||
asyncTest('Undo added when typing enter', function() {
|
||||
assertUndoEnabledWhenTyping('\n', '<p>Cont</p><p>ent</p>');
|
||||
});
|
||||
|
||||
asyncTest('Forward delete triggers undo in IE', function() {
|
||||
editor.setContent('<p>Test1 Test2</p>');
|
||||
editor.undoManager.clear();
|
||||
editor.execCommand('mceRepaint');
|
||||
ok(!isUndoEnabled(), 'Undo is disabled.');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('p')[0].firstChild, 0);
|
||||
rng.setEnd(editor.dom.select('p')[0].firstChild, 6);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
robot.forwardDelete(function() {
|
||||
equal(editor.getContent(), '<p>Test2</p>', 'First word has been deleted');
|
||||
ok(isUndoEnabled(), 'Undo is enabled.');
|
||||
|
||||
editor.undoManager.undo();
|
||||
equal(editor.getContent(), '<p>Test1 Test2</p>', 'First word has been restored');
|
||||
|
||||
QUnit.start();
|
||||
}, editor.selection.getNode());
|
||||
});
|
||||
|
||||
var initTinyFunction = function(){
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
cleanup: true,
|
||||
add_unload_trigger : false,
|
||||
indent : 0,
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Undo Tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1">Content
|
||||
</textarea>
|
||||
</div>
|
||||
<script>
|
||||
initWhenTinyAndRobotAreReady(initTinyFunction);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
27
tests/qunit/editor/tinymce/dom/DOMUtils.html
Normal file
27
tests/qunit/editor/tinymce/dom/DOMUtils.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for tinymce.dom.DOMUtils</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("tinymce.dom.DOMUtils", {
|
||||
});
|
||||
</script>
|
||||
<script src="DOMUtils.js"></script>
|
||||
<h1 id="qunit-header">Unit tests for tinymce.dom.DOMUtils</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
680
tests/qunit/editor/tinymce/dom/DOMUtils.js
Normal file
680
tests/qunit/editor/tinymce/dom/DOMUtils.js
Normal file
@ -0,0 +1,680 @@
|
||||
(function() {
|
||||
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, n, e) {
|
||||
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', 10, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.get('test').className = '';
|
||||
DOM.addClass('test', 'abc');
|
||||
equal(DOM.get('test').className, 'abc');
|
||||
|
||||
DOM.get('test').className = '';
|
||||
equal(DOM.addClass('test', 'abc'), 'abc');
|
||||
equal(DOM.addClass(null, 'abc'), false);
|
||||
|
||||
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.get('test').innerHTML = '<span id="test2"></span><span id="test3"></span><span id="test4"></span>';
|
||||
DOM.addClass(['test2', 'test3', 'test4'], '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', 4, 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 = '';
|
||||
|
||||
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', 4, 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'), '<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', 10, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.show('test');
|
||||
equal(DOM.get('test').style.display, 'block');
|
||||
ok(!DOM.isHidden('test'));
|
||||
|
||||
DOM.hide('test');
|
||||
equal(DOM.get('test').style.display, 'none');
|
||||
ok(DOM.isHidden('test'));
|
||||
|
||||
DOM.get('test').innerHTML = '<span id="test2"></span><span id="test3"></span><span id="test4"></span>';
|
||||
DOM.hide(['test2', 'test3', 'test4'], 'test');
|
||||
equal(DOM.get('test2').style.display, 'none');
|
||||
equal(DOM.get('test3').style.display, 'none');
|
||||
equal(DOM.get('test4').style.display, 'none');
|
||||
|
||||
DOM.get('test').innerHTML = '<span id="test2"></span><span id="test3"></span><span id="test4"></span>';
|
||||
DOM.show(['test2', 'test3', 'test4'], 'test');
|
||||
equal(DOM.get('test2').style.display, 'block');
|
||||
equal(DOM.get('test3').style.display, 'block');
|
||||
equal(DOM.get('test4').style.display, 'block');
|
||||
|
||||
// Cleanup
|
||||
DOM.setAttrib('test', 'style', '');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('select', 4, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setHTML('test', '<div>test 1</div><div>test 2 <div>test 3</div></div><div>test 4</div>');
|
||||
equal(DOM.select('div', 'test').length, 4);
|
||||
ok(DOM.select('div', 'test').reverse);
|
||||
|
||||
DOM.setHTML('test', '<div class="test1 test2 test3">test 1</div><div class="test2">test 2 <div>test 3</div></div><div>test 4</div>')
|
||||
equal(DOM.select('div.test2', 'test').length, 2);
|
||||
|
||||
DOM.setHTML('test', '<div class="test1 test2 test3">test 1</div><div class="test2">test 2 <div>test 3</div></div><div>test 4</div>')
|
||||
equal(DOM.select('div div', 'test').length, 1, null, tinymce.isWebKit); // Issue: http://bugs.webkit.org/show_bug.cgi?id=17461
|
||||
//alert(DOM.select('div div', 'test').length +","+DOM.get('test').querySelectorAll('div div').length);
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('is', 3, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
DOM.setHTML('test', '<div id="textX" class="test">test 1</div>');
|
||||
|
||||
ok(DOM.is(DOM.get('textX'), 'div'));
|
||||
ok(DOM.is(DOM.get('textX'), 'div#textX.test'));
|
||||
ok(!DOM.is(DOM.get('textX'), 'div#textX2'));
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('encode', 1, function() {
|
||||
equal(DOM.encode('abc<>"&\'\u00e5\u00e4\u00f6'), 'abc<>"&'\u00e5\u00e4\u00f6');
|
||||
});
|
||||
|
||||
test('setGetAttrib', 16, 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, e) {
|
||||
return '&<>"' + u + '&<>"' + n;
|
||||
}});
|
||||
|
||||
dom.setAttribs('test', {src : '123', href : 'abc'});
|
||||
equal(DOM.getAttrib('test', 'src'), '&<>"123&<>"src');
|
||||
equal(DOM.getAttrib('test', 'href'), '&<>"abc&<>"href');
|
||||
|
||||
DOM.get('test').innerHTML = '<span id="test2"></span><span id="test3"></span><span id="test4"></span>';
|
||||
DOM.setAttribs(['test2', 'test3', 'test4'], {test1 : "1", test2 : "2"});
|
||||
equal(DOM.getAttrib('test2', 'test1'), '1');
|
||||
equal(DOM.getAttrib('test3', 'test2'), '2');
|
||||
equal(DOM.getAttrib('test4', 'test1'), '1');
|
||||
|
||||
equal(DOM.getAttrib(document, 'test'), false);
|
||||
equal(DOM.getAttrib(document, 'test', ''), '');
|
||||
equal(DOM.getAttrib(document, 'test', 'x'), 'x');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('getAttribs', 2, function() {
|
||||
var dom;
|
||||
|
||||
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', 7, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setStyle('test', 'font-size', '20px');
|
||||
equal(DOM.getStyle('test', 'font-size'), '20px', null, tinymce.isWebKit);
|
||||
|
||||
DOM.setStyle('test', 'fontSize', '21px');
|
||||
equal(DOM.getStyle('test', 'fontSize'), '21px', null, tinymce.isWebKit);
|
||||
|
||||
DOM.setStyles('test', {fontSize : '22px', display : 'inline'});
|
||||
equal(DOM.getStyle('test', 'fontSize'), '22px', null, tinymce.isWebKit);
|
||||
equal(DOM.getStyle('test', 'display'), 'inline', null, tinymce.isWebKit);
|
||||
|
||||
DOM.get('test').innerHTML = '<span id="test2"></span><span id="test3"></span><span id="test4"></span>';
|
||||
DOM.setStyles(['test2', 'test3', 'test4'], {fontSize : "22px"});
|
||||
equal(DOM.getStyle('test2', 'fontSize'), '22px');
|
||||
equal(DOM.getStyle('test3', 'fontSize'), '22px');
|
||||
equal(DOM.getStyle('test4', 'fontSize'), '22px');
|
||||
|
||||
DOM.setAttrib('test', 'style', '');
|
||||
|
||||
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');
|
||||
});
|
||||
|
||||
test('getParent', 6, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.get('test').innerHTML = '<div><span>ab<a id="test2" href="">abc</a>c</span></div>';
|
||||
|
||||
equal(DOM.getParent('test2', function(n) {return n.nodeName == 'SPAN';}).nodeName, 'SPAN');
|
||||
equal(DOM.getParent('test2', function(n) {return n.nodeName == 'BODY';}).nodeName, 'BODY');
|
||||
equal(DOM.getParent('test2', function(n) {return n.nodeName == 'BODY';}, document.body), null);
|
||||
equal(DOM.getParent('test2', function(n) {return false;}), 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', function(n) {return n.nodeName == '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() {
|
||||
var r;
|
||||
|
||||
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, function(n) {return n.nodeName == 'EM'}).nodeName, 'EM');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('getPrev', 5, function() {
|
||||
var r;
|
||||
|
||||
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, function(n) {return n.nodeName == 'STRONG'}).nodeName, 'STRONG');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('loadCSS', 1, function() {
|
||||
var c = 0;
|
||||
|
||||
DOM.loadCSS('css/test.css?a=1,css/test.css?a=2,css/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', 3, 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.get('test').innerHTML = '<span id="test2"></span><span id="test3"></span><span id="test4"></span>';
|
||||
DOM.remove(['test2', 'test4']);
|
||||
equal(DOM.select('span', 'test').length, 1);
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('replace', 2, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
DOM.replace(DOM.create('div', {id : 'test2'}), 'test2', 1);
|
||||
equal(DOM.get('test2').innerHTML.toLowerCase(), '<span>test</span><span>test2</span>');
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
DOM.replace(DOM.create('div', {id : 'test2'}), 'test2');
|
||||
equal(DOM.get('test2').innerHTML, '');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('toHex', 5, function() {
|
||||
equal(DOM.toHex('rgb(0, 255, 255)'), '#00ffff');
|
||||
equal(DOM.toHex('rgb(255, 0, 0)'), '#ff0000');
|
||||
equal(DOM.toHex('rgb(0, 0, 255)'), '#0000ff');
|
||||
equal(DOM.toHex('rgb ( 0 , 0 , 255 ) '), '#0000ff');
|
||||
equal(DOM.toHex(' RGB ( 0 , 0 , 255 ) '), '#0000ff');
|
||||
});
|
||||
|
||||
test('getOuterHTML', 4, function() {
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
equal(DOM.getOuterHTML('test2').toLowerCase().replace(/\"/g, ''), '<span id=test2><span>test</span><span>test2</span></span>');
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
DOM.setOuterHTML('test2', '<div id="test2">123</div>');
|
||||
equal(tinymce.trim(DOM.getOuterHTML('test2') || '').toLowerCase().replace(/\"/g, ''), '<div id=test2>123</div>');
|
||||
|
||||
DOM.setHTML('test', '<span id="test2"><span>test</span><span>test2</span></span>');
|
||||
DOM.setOuterHTML('test2', '<div id="test2">123</div><div id="test3">abc</div>');
|
||||
equal(tinymce.trim(DOM.get('test').innerHTML).toLowerCase().replace(/>\s+</g, '><').replace(/\"/g, ''), '<div id=test2>123</div><div id=test3>abc</div>');
|
||||
|
||||
DOM.setHTML('test', 'test');
|
||||
equal(tinymce.trim(DOM.getOuterHTML(DOM.get('test').firstChild)), 'test');
|
||||
|
||||
DOM.remove('test');
|
||||
});
|
||||
|
||||
test('encodeDecode', 2, function() {
|
||||
equal(DOM.encode('\u00e5\u00e4\u00f6&<>"'), '\u00e5\u00e4\u00f6&<>"');
|
||||
equal(DOM.decode('åäö&<>"'), '\u00e5\u00e4\u00f6&<>"');
|
||||
});
|
||||
|
||||
test('split', 2, function() {
|
||||
var point, parent;
|
||||
DOM.add(document.body, 'div', {id : 'test'});
|
||||
|
||||
DOM.setHTML('test', '<p><b>text1<span>inner</span>text2</b></p>');
|
||||
parent = DOM.select('p', DOM.get('test'))[0];
|
||||
point = DOM.select('span', DOM.get('test'))[0];
|
||||
DOM.split(parent, point);
|
||||
equal(DOM.get('test').innerHTML.toLowerCase().replace(/\s+/g, ''), '<p><b>text1</b></p><span>inner</span><p><b>text2</b></p>');
|
||||
|
||||
DOM.setHTML('test', '<ul><li>first line<br><ul><li><span>second</span> <span>line</span></li><li>third line<br></li></ul></li></ul>');
|
||||
parent = DOM.select('li:nth-child(1)', DOM.get('test'))[0];
|
||||
point = DOM.select('ul li:nth-child(2)', DOM.get('test'))[0];
|
||||
DOM.split(parent, point);
|
||||
equal(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', 14, 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="x">');
|
||||
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.remove('test');
|
||||
});
|
||||
|
||||
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');
|
||||
})();
|
||||
29
tests/qunit/editor/tinymce/dom/DOMUtils_jquery.html
Normal file
29
tests/qunit/editor/tinymce/dom/DOMUtils_jquery.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for tinymce.dom.DOMUtils</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../../js/tinymce/tinymce.jquery.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("tinymce.dom.DOMUtils (jQuery)", {
|
||||
});
|
||||
</script>
|
||||
<script src="DOMUtils.js"></script>
|
||||
|
||||
<h1 id="qunit-header">Unit tests for tinymce.dom.DOMUtils</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
459
tests/qunit/editor/tinymce/dom/EventUtils.html
Normal file
459
tests/qunit/editor/tinymce/dom/EventUtils.html
Normal file
@ -0,0 +1,459 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for the EventUtils class</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var eventUtils = tinymce.dom.Event;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("tinymce.dom.Event", {
|
||||
teardown: function() {
|
||||
eventUtils.clean(window);
|
||||
}
|
||||
});
|
||||
|
||||
// Bind dummy ready so it gets the domLoaded ready state
|
||||
eventUtils.bind(window, "ready", function() {});
|
||||
|
||||
test("unbind all", function() {
|
||||
var result;
|
||||
|
||||
eventUtils.bind(window, 'click', function(e) {
|
||||
result.click = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'keydown', function(e) {
|
||||
result.keydown1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'keydown', function(e) {
|
||||
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(e) {
|
||||
result.click = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'keydown', function(e) {
|
||||
result.keydown1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'keydown', function(e) {
|
||||
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(e) {
|
||||
result.click = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'keydown', function(e) {
|
||||
result.keydown1 = true;
|
||||
});
|
||||
|
||||
function callback2(e) {
|
||||
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(e) {
|
||||
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(e) {
|
||||
result.click1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'click', function(e) {
|
||||
result.click2 = true;
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
|
||||
eventUtils.bind(window, 'click', function(e) {
|
||||
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(e) {
|
||||
result.click1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.body, 'click', function(e) {
|
||||
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(e) {
|
||||
result.click1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.body, 'click', function(e) {
|
||||
result.click2 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('content'), 'click', function(e) {
|
||||
result.click3 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('inner'), 'click', function(e) {
|
||||
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(e) {
|
||||
result.click1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document, 'click', function(e) {
|
||||
result.click2 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.body, 'click', function(e) {
|
||||
result.click3 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('content'), 'click', function(e) {
|
||||
result.click4 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('inner'), 'click', function(e) {
|
||||
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(e) {
|
||||
result.click1 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.body, 'click', function(e) {
|
||||
result.click2 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('content'), 'click', function(e) {
|
||||
result.click3 = true;
|
||||
});
|
||||
|
||||
eventUtils.bind(document.getElementById('inner'), 'click', function(e) {
|
||||
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, {});
|
||||
});
|
||||
|
||||
test("focusin/focusout bind/unbind", function() {
|
||||
var result = {};
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
document.getElementById('inner').focus();
|
||||
document.getElementById('content').focus();
|
||||
|
||||
deepEqual(result, {focusin: 2, focusout: 1});
|
||||
});
|
||||
|
||||
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");
|
||||
});
|
||||
</script>
|
||||
|
||||
<h1 id="qunit-header">Unit tests for DOM Selection IE implementation</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content" tabindex="0">
|
||||
<div id="inner" tabindex="0"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
606
tests/qunit/editor/tinymce/dom/Range.html
Normal file
606
tests/qunit/editor/tinymce/dom/Range.html
Normal file
@ -0,0 +1,606 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for DOM Range IE implementation</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
module("Range", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
function createRng() {
|
||||
return document.createRange ? document.createRange() : new tinymce.dom.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;
|
||||
};
|
||||
|
||||
function setup() {
|
||||
if (this.orgHTML)
|
||||
document.getElementById('sample').innerHTML = this.orgHTML;
|
||||
|
||||
// Remove whitespace nodes to normalize IE and other browsers
|
||||
function clean(n) {
|
||||
var i;
|
||||
|
||||
if (n.nodeType == 3 && /^[\s]+$/.test(n.nodeValue))
|
||||
return n.parentNode.removeChild(n);
|
||||
|
||||
for (i = n.childNodes.length - 1; i >= 0; i--)
|
||||
clean(n.childNodes[i]);
|
||||
};
|
||||
|
||||
clean(document.getElementById('sample'));
|
||||
|
||||
this.orgHTML = document.getElementById('sample').innerHTML;
|
||||
};
|
||||
|
||||
test("Initial state", function() {
|
||||
var r = createRng();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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();
|
||||
|
||||
setup();
|
||||
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;
|
||||
setup();
|
||||
|
||||
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");
|
||||
});
|
||||
}
|
||||
|
||||
tinymce.DOM.bind(window, 'load', function() {
|
||||
QUnit.start();
|
||||
});
|
||||
</script>
|
||||
<h1 id="qunit-header">Unit tests for DOM Range IE implementation</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<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>
|
||||
</body>
|
||||
</html>
|
||||
878
tests/qunit/editor/tinymce/dom/Selection.html
Normal file
878
tests/qunit/editor/tinymce/dom/Selection.html
Normal file
@ -0,0 +1,878 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for tinymce.dom.Selection</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
module("Selection", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
test('getContent', function() {
|
||||
var rng, eventObj;
|
||||
|
||||
// Get selected contents
|
||||
editor.setContent('<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(rng);
|
||||
equal(editor.selection.getContent(), '<p>text</p>', 'Get selected contents');
|
||||
|
||||
// Get selected contents (collapsed)
|
||||
editor.setContent('<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 0);
|
||||
editor.selection.setRng(rng);
|
||||
equal(editor.selection.getContent(), '', 'Get selected contents (collapsed)');
|
||||
|
||||
// Get selected contents, onGetContent event
|
||||
eventObj = {};
|
||||
|
||||
function handler(event) {
|
||||
eventObj = event;
|
||||
};
|
||||
|
||||
editor.on('GetContent', handler);
|
||||
editor.setContent('<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.getContent();
|
||||
equal(eventObj.content, '<p>text</p>', 'Get selected contents, onGetContent event');
|
||||
editor.off('GetContent', handler);
|
||||
});
|
||||
|
||||
test('setContent', function() {
|
||||
var rng, eventObj;
|
||||
|
||||
// Set contents at selection
|
||||
editor.setContent('<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.setContent('<div>test</div>');
|
||||
equal(editor.getContent(), '<div>test</div>', 'Set contents at selection');
|
||||
|
||||
// Set contents at selection (collapsed)
|
||||
editor.setContent('<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 0);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.setContent('<div>test</div>');
|
||||
equal(editor.getContent(), '<div>test</div>\n<p>text</p>', 'Set contents at selection (collapsed)');
|
||||
|
||||
// Insert in middle of paragraph
|
||||
editor.setContent('<p>beforeafter</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild, 'before'.length);
|
||||
rng.setEnd(editor.getBody().firstChild.firstChild, 'before'.length);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.setContent('<br />');
|
||||
equal(editor.getContent(), '<p>before<br />after</p>', 'Set contents at selection (inside paragraph)');
|
||||
|
||||
// Check the caret is left in the correct position.
|
||||
rng = editor.selection.getRng(true);
|
||||
if (document.createRange) {
|
||||
equal(rng.startContainer, editor.getBody().firstChild, 'Selection start container');
|
||||
equal(rng.startOffset, 2, 'Selection start offset');
|
||||
equal(rng.endContainer, editor.getBody().firstChild, 'Selection end container');
|
||||
equal(rng.endOffset, 2, 'Selection end offset');
|
||||
} else {
|
||||
// TridentSelection resolves indexed text nodes
|
||||
equal(rng.startContainer, editor.getBody().firstChild.lastChild, 'Selection start container');
|
||||
equal(rng.startOffset, 0, 'Selection start offset');
|
||||
equal(rng.endContainer, editor.getBody().firstChild.lastChild, 'Selection end container');
|
||||
equal(rng.endOffset, 0, 'Selection end offset');
|
||||
}
|
||||
|
||||
editor.setContent('<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 0);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.setContent('');
|
||||
equal(editor.getContent(), '<p>text</p>', 'Set contents to empty at selection (collapsed)');
|
||||
rng = editor.selection.getRng(true);
|
||||
if (!document.createRange) {
|
||||
// The old IE selection can only be positioned in text nodes
|
||||
equal(rng.startContainer, editor.getBody().firstChild.firstChild, 'Selection start container');
|
||||
equal(rng.startOffset, 0, 'Selection start offset');
|
||||
equal(rng.endContainer, editor.getBody().firstChild.firstChild, 'Selection end container');
|
||||
equal(rng.endOffset, 0, 'Selection end offset');
|
||||
} else {
|
||||
equal(rng.startContainer, editor.getBody(), 'Selection start container');
|
||||
equal(rng.startOffset, 0, 'Selection start offset');
|
||||
equal(rng.endContainer, editor.getBody(), 'Selection end container');
|
||||
equal(rng.endOffset, 0, 'Selection end offset');
|
||||
}
|
||||
|
||||
// Set selected contents, onSetContent event
|
||||
eventObj = {};
|
||||
|
||||
function handler(event) {
|
||||
eventObj = event;
|
||||
};
|
||||
|
||||
editor.on('SetContent', handler);
|
||||
editor.setContent('<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.setContent('<div>text</div>');
|
||||
equal(eventObj.content, '<div>text</div>', 'Set selected contents, onSetContent event');
|
||||
editor.off('SetContent', handler);
|
||||
});
|
||||
|
||||
test('getStart/getEnd', function() {
|
||||
var rng;
|
||||
|
||||
// Selected contents
|
||||
editor.setContent('<p id="a">text</p><p id="b">text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild, 0);
|
||||
rng.setEnd(editor.getBody().lastChild.firstChild, 0);
|
||||
editor.selection.setRng(rng);
|
||||
equal(editor.selection.getStart().id, 'a', 'Selected contents (getStart)');
|
||||
equal(editor.selection.getEnd().id, 'b', 'Selected contents (getEnd)');
|
||||
|
||||
// Selected contents (collapsed)
|
||||
editor.setContent('<p id="a">text</p>\n<p id="b">text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild, 0);
|
||||
rng.setEnd(editor.getBody().firstChild.firstChild, 0);
|
||||
editor.selection.setRng(rng);
|
||||
equal(editor.selection.getStart().id, 'a', 'Selected contents (getStart, collapsed)');
|
||||
equal(editor.selection.getEnd().id, 'a', 'Selected contents (getEnd, collapsed)');
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (persistent)', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
// Get persistent bookmark simple text selection
|
||||
editor.setContent('text');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 1);
|
||||
rng.setEnd(editor.getBody().firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark();
|
||||
equal(editor.getContent(), 'text', 'Editor contents (text)');
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
equal(editor.selection.getContent(), 'ex', 'Selected contents (text)');
|
||||
|
||||
// Get persistent bookmark multiple elements text selection
|
||||
editor.setContent('<p>text</p>\n<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild, 1);
|
||||
rng.setEnd(editor.getBody().lastChild.firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark();
|
||||
equal(editor.getContent(), '<p>text</p>\n<p>text</p>', 'Editor contents (elements)');
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
equal(editor.selection.getContent(), '<p>ext</p>\n<p>tex</p>', 'Selected contents (elements)');
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (simple)', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
// Get persistent bookmark simple text selection
|
||||
editor.setContent('text');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 1);
|
||||
rng.setEnd(editor.getBody().firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(1);
|
||||
equal(editor.getContent(), 'text', 'Editor contents (text)');
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
equal(editor.selection.getContent(), 'ex', 'Selected contents (text)');
|
||||
|
||||
// Get persistent bookmark multiple elements text selection
|
||||
editor.setContent('<p>text</p>\n<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild, 1);
|
||||
rng.setEnd(editor.getBody().lastChild.firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(1);
|
||||
equal(editor.getContent(), '<p>text</p>\n<p>text</p>', 'Editor contents (elements)');
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
equal(editor.selection.getContent(), '<p>ext</p>\n<p>tex</p>', 'Selected contents (elements)');
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - simple text selection', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(2);
|
||||
|
||||
editor.setContent('text');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 1);
|
||||
rng.setEnd(editor.getBody().firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2);
|
||||
equal(editor.getContent(), 'text', 'Editor contents (text)');
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
equal(editor.selection.getContent(), 'ex', 'Selected contents (text)');
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - Get non intrusive bookmark simple element selection', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(1);
|
||||
|
||||
// Get non intrusive bookmark simple element selection
|
||||
editor.setContent('<p>text<em>a<strong>b</strong>c</em></p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.select('em')[0], 1);
|
||||
rng.setEnd(editor.dom.select('em')[0], 2);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2);
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
equal(editor.selection.getContent(), '<strong>b</strong>', 'Selected contents (element)');
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - Get non intrusive bookmark multiple elements text selection', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(2);
|
||||
|
||||
// Get non intrusive bookmark multiple elements text selection
|
||||
editor.setContent('<p>text</p>\n<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.firstChild, 1);
|
||||
rng.setEnd(editor.getBody().lastChild.firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2);
|
||||
equal(editor.getContent(), '<p>text</p>\n<p>text</p>', 'Editor contents (elements)');
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
equal(editor.selection.getContent(), '<p>ext</p>\n<p>tex</p>', 'Selected contents (elements)');
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive)', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(2);
|
||||
|
||||
// Get non intrusive bookmark multiple elements text selection fragmented
|
||||
editor.setContent('<p>text</p><p>text</p>');
|
||||
editor.dom.select('p')[0].appendChild(editor.dom.doc.createTextNode('a'));
|
||||
editor.dom.select('p')[0].appendChild(editor.dom.doc.createTextNode('a'));
|
||||
editor.dom.select('p')[0].appendChild(editor.dom.doc.createTextNode('a'));
|
||||
editor.dom.select('p')[0].appendChild(editor.dom.doc.createTextNode('text'));
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.lastChild, 1);
|
||||
rng.setEnd(editor.getBody().lastChild.firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2);
|
||||
equal(editor.getContent(), '<p>textaaatext</p>\n<p>text</p>', 'Editor contents (fragmented, elements)');
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
equal(editor.selection.getContent(), '<p>ext</p>\n<p>tex</p>', 'Selected contents (fragmented, elements)');
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - fragmentext text (normalized)', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(2);
|
||||
|
||||
// Get non intrusive bookmark multiple elements text selection fragmented
|
||||
editor.setContent('<p>text</p><p>text</p>');
|
||||
editor.dom.select('p')[0].appendChild(editor.dom.doc.createTextNode('a'));
|
||||
editor.dom.select('p')[0].appendChild(editor.dom.doc.createTextNode('a'));
|
||||
editor.dom.select('p')[0].appendChild(editor.dom.doc.createTextNode('a'));
|
||||
editor.dom.select('p')[0].appendChild(editor.dom.doc.createTextNode('text'));
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild.lastChild, 1);
|
||||
rng.setEnd(editor.getBody().lastChild.firstChild, 3);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2, true);
|
||||
editor.setContent(editor.getContent());
|
||||
equal(editor.getContent(), '<p>textaaatext</p>\n<p>text</p>', 'Editor contents (fragmented, elements)');
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
equal(editor.selection.getContent(), '<p>ext</p>\n<p>tex</p>', 'Selected contents (fragmented, elements)');
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - Get bookmark before image', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(4);
|
||||
|
||||
editor.setContent('<p><img src="about:blank" /></p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 0);
|
||||
rng.setEnd(editor.getBody().firstChild, 0);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2, true);
|
||||
editor.getBody().innerHTML = editor.getBody().innerHTML;
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer, editor.getBody().firstChild);
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endContainer, editor.getBody().firstChild);
|
||||
equal(rng.endOffset, 0);
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - Get bookmark before/after image', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(4);
|
||||
|
||||
editor.setContent('<p><img src="about:blank" /></p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 0);
|
||||
rng.setEnd(editor.getBody().firstChild, 1);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2, true);
|
||||
editor.getBody().innerHTML = editor.getBody().innerHTML;
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer, editor.getBody().firstChild);
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endContainer, editor.getBody().firstChild);
|
||||
equal(rng.endOffset, 1);
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - Get bookmark after image', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(4);
|
||||
|
||||
editor.setContent('<p><img src="about:blank" /></p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 1);
|
||||
rng.setEnd(editor.getBody().firstChild, 1);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2, true);
|
||||
editor.getBody().innerHTML = editor.getBody().innerHTML;
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer, editor.getBody().firstChild);
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer, editor.getBody().firstChild);
|
||||
equal(rng.endOffset, 1);
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - Get bookmark before element', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(4);
|
||||
|
||||
editor.setContent('abc<b>123</b>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 0);
|
||||
rng.setEnd(editor.getBody().firstChild, 2);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2, true);
|
||||
editor.getBody().innerHTML = editor.getBody().innerHTML;
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer, editor.getBody().firstChild);
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endContainer, editor.getBody().firstChild);
|
||||
equal(rng.endOffset, 2);
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - Get bookmark after element', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(4);
|
||||
|
||||
// Get bookmark after element
|
||||
editor.setContent('<b>123</b>abc');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().lastChild, 1);
|
||||
rng.setEnd(editor.getBody().lastChild, 2);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2, true);
|
||||
editor.getBody().innerHTML = editor.getBody().innerHTML;
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer, editor.getBody().lastChild);
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer, editor.getBody().lastChild);
|
||||
equal(rng.endOffset, 2);
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - Get bookmark inside element', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(4);
|
||||
|
||||
editor.setContent('abc<b>123</b>abc');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().childNodes[1].firstChild, 1);
|
||||
rng.setEnd(editor.getBody().childNodes[1].firstChild, 2);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2, true);
|
||||
editor.getBody().innerHTML = editor.getBody().innerHTML;
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer, editor.getBody().childNodes[1].firstChild);
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer, editor.getBody().childNodes[1].firstChild);
|
||||
equal(rng.endOffset, 2);
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - Get bookmark inside root text', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(4);
|
||||
|
||||
editor.setContent('abc');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody().firstChild, 1);
|
||||
rng.setEnd(editor.getBody().firstChild, 2);
|
||||
editor.selection.setRng(rng);
|
||||
bookmark = editor.selection.getBookmark(2, true);
|
||||
editor.getBody().innerHTML = editor.getBody().innerHTML;
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer, editor.getBody().firstChild);
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer, editor.getBody().firstChild);
|
||||
equal(rng.endOffset, 2);
|
||||
});
|
||||
|
||||
test('getBookmark/setBookmark (nonintrusive) - Get bookmark inside complex html', function() {
|
||||
var rng, bookmark;
|
||||
|
||||
expect(4);
|
||||
|
||||
editor.setContent('<p>abc</p>123<p>123</p><p>123<b>123</b><table><tr><td>abc</td></tr></table></p>');
|
||||
editor.execCommand('SelectAll');
|
||||
setSelection('td', 1, 'td', 2);
|
||||
bookmark = editor.selection.getBookmark(2, true);
|
||||
editor.getBody().innerHTML = editor.getBody().innerHTML;
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer, editor.dom.select('td')[0].firstChild);
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer, editor.dom.select('td')[0].firstChild);
|
||||
equal(rng.endOffset, 2);
|
||||
});
|
||||
|
||||
test('select first p', 2, function() {
|
||||
editor.setContent('<p>text1</p><p>text2</p>');
|
||||
editor.selection.select(editor.dom.select('p')[0]);
|
||||
equal(editor.selection.getContent(), '<p>text1</p>', 'Select simple element, content');
|
||||
equal(editor.selection.getStart().nodeName, 'P', 'Select simple element, nodeName');
|
||||
});
|
||||
|
||||
test('select table', 2, function() {
|
||||
editor.setContent('<table><tbody><tr><td>text1</td></tr></tbody></table>');
|
||||
editor.selection.select(editor.dom.select('table')[0]);
|
||||
equal(editor.selection.getContent(), '<table>\n<tbody>\n<tr>\n<td>text1</td>\n</tr>\n</tbody>\n</table>', 'Select complex element, content');
|
||||
equal(editor.selection.getNode().nodeName, 'TABLE', 'Select complex element, nodeName');
|
||||
});
|
||||
|
||||
test('select table text 1', 2, function() {
|
||||
editor.setContent('<table><tbody><tr><td id="a">text1</td><td id="b">text2</td></tr></tbody></table>');
|
||||
editor.selection.select(editor.dom.select('table')[0], true);
|
||||
equal(editor.selection.getStart().id, 'a', 'Expand to text content 1 (start)');
|
||||
equal(editor.selection.getEnd().id, 'b', 'Expand to text content 1 (end)');
|
||||
});
|
||||
|
||||
test('select table text 2', 2, function() {
|
||||
editor.setContent('<table><tbody><tr><td id="a"><br /></td><td id="b"><br /></td></tr></tbody></table>');
|
||||
editor.selection.select(editor.dom.select('table')[0], true);
|
||||
equal(editor.dom.getParent(editor.selection.getStart(), 'td').id, 'a', 'Expand to text content 2 (start)');
|
||||
equal(editor.dom.getParent(editor.selection.getEnd(), 'td').id, 'b', 'Expand to text content 2 (end)');
|
||||
});
|
||||
|
||||
test('getNode', function() {
|
||||
var rng;
|
||||
|
||||
editor.setContent('<p id="p1"><span id="s1">span1</span> word <span id="s2">span2</span> word <span id="s3">span3</span></p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.get('s1').firstChild, 0);
|
||||
rng.setEnd(editor.dom.get('s1').nextSibling, 0);
|
||||
editor.selection.setRng(rng);
|
||||
deepEqual(editor.selection.getNode(), editor.dom.get('s1'), 'Detect selection ends immediately after node at start of paragraph.');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.get('s2').previousSibling, editor.dom.get('s2').previousSibling.length);
|
||||
rng.setEnd(editor.dom.get('s2').nextSibling, 0);
|
||||
editor.selection.setRng(rng);
|
||||
deepEqual(editor.selection.getNode(), editor.dom.get('s2'), 'Detect selection immediately surrounds node in middle of paragraph.');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.get('s3').previousSibling, editor.dom.get('s3').previousSibling.length);
|
||||
rng.setEnd(editor.dom.get('s3').lastChild, editor.dom.get('s3').lastChild.length);
|
||||
editor.selection.setRng(rng);
|
||||
deepEqual(editor.selection.getNode(), editor.dom.get('s3'), 'Detect selection starts immediately before node at end of paragraph.');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.dom.get('s2').previousSibling, editor.dom.get('s2').previousSibling.length);
|
||||
rng.setEnd(editor.dom.get('s3').lastChild, editor.dom.get('s3').lastChild.length);
|
||||
editor.selection.setRng(rng);
|
||||
deepEqual(editor.selection.getNode(), editor.dom.get('p1'), 'Detect selection wrapping multiple nodes does not collapse.');
|
||||
});
|
||||
|
||||
test('normalize to text node from document', function() {
|
||||
var rng;
|
||||
|
||||
if (tinymce.isOpera || tinymce.isIE) {
|
||||
ok(true, "Skipped on Opera/IE since Opera doesn't let you to set the range to document and IE will steal focus.");
|
||||
return;
|
||||
}
|
||||
|
||||
editor.setContent('<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getDoc(), 0);
|
||||
rng.setEnd(editor.getDoc(), 0);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeType, 3, 'startContainer node type');
|
||||
equal(rng.startOffset, 0, 'startContainer offset');
|
||||
equal(rng.endContainer.nodeType, 3, 'endContainer node type');
|
||||
equal(rng.endOffset, 0, 'endOffset offset');
|
||||
});
|
||||
|
||||
test('normalize to br from document', function() {
|
||||
var rng;
|
||||
|
||||
if (tinymce.isOpera || tinymce.isIE) {
|
||||
ok(true, "Skipped on Opera/IE since Opera doesn't let you to set the range to document and IE will steal focus.");
|
||||
return;
|
||||
}
|
||||
|
||||
editor.setContent('<p><br /></p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getDoc(), 0);
|
||||
rng.setEnd(editor.getDoc(), 0);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'P', 'startContainer node name');
|
||||
equal(rng.startContainer.nodeType, 1, 'startContainer node type');
|
||||
equal(rng.startOffset, 0, 'startContainer offset');
|
||||
equal(rng.endContainer.nodeType, 1, 'endContainer node type');
|
||||
equal(rng.endOffset, 0, 'endOffset offset');
|
||||
});
|
||||
|
||||
// Only run on non IE browsers since it's not an issue on IE
|
||||
if (!tinymce.isIE) {
|
||||
test('normalize to text node from body', function() {
|
||||
var rng;
|
||||
|
||||
editor.setContent('<p>text</p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 0);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeType, 3, 'startContainer node type');
|
||||
equal(rng.startOffset, 0, 'startContainer offset');
|
||||
equal(rng.endContainer.nodeType, 3, 'endContainer node type');
|
||||
equal(rng.endOffset, 0, 'endOffset offset');
|
||||
});
|
||||
|
||||
test('normalize to br from body', function() {
|
||||
var rng;
|
||||
|
||||
editor.setContent('<p><br /></p>');
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 0);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'P', 'startContainer node name');
|
||||
equal(rng.startContainer.nodeType, 1, 'startContainer node type');
|
||||
equal(rng.startOffset, 0, 'startContainer offset');
|
||||
equal(rng.endContainer.nodeType, 1, 'endContainer node type');
|
||||
equal(rng.endOffset, 0, 'endOffset offset');
|
||||
});
|
||||
|
||||
test('normalize ignore img', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<img src="about:blank " />';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'BODY', 'startContainer node name');
|
||||
equal(rng.startContainer.nodeType, 1, 'startContainer node type');
|
||||
equal(rng.startOffset, 0, 'startContainer offset');
|
||||
equal(rng.endContainer.nodeName, 'BODY', 'endContainer node name');
|
||||
equal(rng.endContainer.nodeType, 1, 'endContainer node type');
|
||||
equal(rng.endOffset, 1, 'endOffset offset');
|
||||
});
|
||||
|
||||
test('normalize to before/after img', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p><img src="about:blank " /></p>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'P', 'startContainer node name');
|
||||
equal(rng.startContainer.nodeType, 1, 'startContainer node type');
|
||||
equal(rng.startOffset, 0, 'startContainer offset');
|
||||
equal(rng.endContainer.nodeName, 'P', 'endContainer node name');
|
||||
equal(rng.endContainer.nodeType, 1, 'endContainer node type');
|
||||
equal(rng.endOffset, 1, 'endOffset offset');
|
||||
});
|
||||
|
||||
test('normalize to text node inside P', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p>abc</p>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 1);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, '#text', 'startContainer node name');
|
||||
equal(rng.startOffset, 0, 'startContainer offset');
|
||||
equal(rng.endContainer.nodeName, '#text', 'endContainer node name');
|
||||
equal(rng.endOffset, 3, 'endOffset offset');
|
||||
});
|
||||
|
||||
test('normalize lean left if at the start of text node', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p><b>a</b><i>b</i></p>';
|
||||
setSelection('i', 0);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, '#text', 'startContainer node name');
|
||||
equal(rng.startContainer.parentNode.nodeName, 'B');
|
||||
equal(rng.startOffset, 1, 'startContainer offset');
|
||||
equal(rng.endContainer.nodeName, '#text');
|
||||
equal(rng.endContainer.parentNode.nodeName, 'B');
|
||||
equal(rng.endOffset, 1, 'endOffset offset');
|
||||
});
|
||||
|
||||
test('normalize lean start to the right if at end of text node', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p><b>a</b><i>b</i></p>';
|
||||
setSelection('b', 1, 'i', 1);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, '#text', 'startContainer node name');
|
||||
equal(rng.startContainer.parentNode.nodeName, 'I');
|
||||
equal(rng.startOffset, 0, 'startContainer offset');
|
||||
equal(rng.endContainer.nodeName, '#text');
|
||||
equal(rng.endContainer.parentNode.nodeName, 'I');
|
||||
equal(rng.endOffset, 1, 'endOffset offset');
|
||||
});
|
||||
|
||||
test('normalize lean left but break before br', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p>a<br><b>b</b></p>';
|
||||
setSelection('b', 0);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeValue, 'b');
|
||||
equal(rng.startOffset, 0);
|
||||
});
|
||||
|
||||
test('normalize lean left but break before img', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p>a<img><b>b</b></p>';
|
||||
setSelection('b', 0);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeValue, 'b');
|
||||
equal(rng.startOffset, 0);
|
||||
});
|
||||
|
||||
test('normalize lean left but don\'t walk out the parent block', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p>a</p><p><b>b</b></p>';
|
||||
setSelection('b', 0);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeValue, 'b');
|
||||
equal(rng.startOffset, 0);
|
||||
});
|
||||
|
||||
test('normalize lean left into empty inline elements when caret is before br', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p><i><b></b></i><br /></p>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.getBody().firstChild.lastChild);
|
||||
rng.setEndBefore(editor.getBody().firstChild.lastChild);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'B');
|
||||
equal(rng.startOffset, 0);
|
||||
});
|
||||
|
||||
test('normalize don\'t lean left into empty inline elements if there is a br element after caret', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p><i><b></b></i><br /><br /></p>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.getBody().firstChild.lastChild);
|
||||
rng.setEndBefore(editor.getBody().firstChild.lastChild);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 2);
|
||||
});
|
||||
|
||||
test('normalize don\'t lean left into empty inline elements if there is a br element before caret', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p><i><b><br /></b></i><br /></p>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.getBody().firstChild.lastChild);
|
||||
rng.setEndBefore(editor.getBody().firstChild.lastChild);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'P');
|
||||
equal(rng.startOffset, 1);
|
||||
});
|
||||
|
||||
test('normalize don\'t move start/end if it\'s before/after table', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<table><tr><td>X</td></tr></table>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.getBody().firstChild);
|
||||
rng.setEndAfter(editor.getBody().lastChild);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, 'BODY');
|
||||
equal(rng.startOffset, 0);
|
||||
equal(rng.endContainer.nodeName, 'BODY');
|
||||
equal(rng.endOffset, 1);
|
||||
});
|
||||
|
||||
test('normalize after paragraph', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p>a</p>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStartAfter(editor.getBody().firstChild);
|
||||
rng.setEndAfter(editor.getBody().lastChild);
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.normalize();
|
||||
|
||||
rng = editor.selection.getRng(true);
|
||||
equal(rng.startContainer.nodeName, '#text');
|
||||
equal(rng.startOffset, 1);
|
||||
equal(rng.endContainer.nodeName, '#text');
|
||||
equal(rng.endOffset, 1);
|
||||
});
|
||||
}
|
||||
|
||||
test('custom elements', function() {
|
||||
var rng;
|
||||
|
||||
editor.setContent('<custom1>test</custom1><custom2>test</custom2>');
|
||||
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStart(editor.getBody(), 0);
|
||||
rng.setEnd(editor.getBody(), 2);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
equal(editor.selection.getContent(), '<custom1>test</custom1><custom2>test</custom2>');
|
||||
});
|
||||
|
||||
test('selectorChanged', function() {
|
||||
var newState, newArgs;
|
||||
|
||||
editor.selection.selectorChanged('a[href]', function(state, args) {
|
||||
newState = state;
|
||||
newArgs = args;
|
||||
});
|
||||
|
||||
editor.getBody().innerHTML = '<p><a href="#">text</a></p>';
|
||||
setSelection('a', 0, 'a', 4);
|
||||
editor.nodeChanged();
|
||||
|
||||
ok(newState);
|
||||
equal(newArgs.selector, 'a[href]');
|
||||
equal(newArgs.node, editor.getBody().firstChild.firstChild);
|
||||
equal(newArgs.parents.length, 2);
|
||||
|
||||
editor.getBody().innerHTML = '<p>text</p>';
|
||||
setSelection('p', 0, 'p', 4);
|
||||
editor.nodeChanged();
|
||||
equal(newArgs.selector, 'a[href]');
|
||||
equal(newArgs.node, editor.getBody().firstChild);
|
||||
equal(newArgs.parents.length, 1);
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
fix_list_elements : 0,
|
||||
fix_table_elements : 0,
|
||||
forced_root_block : '',
|
||||
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'
|
||||
},
|
||||
custom_elements : 'custom1,~custom2',
|
||||
extended_valid_elements : 'custom1,custom2',
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Unit tests for tinymce.dom.Selection</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
515
tests/qunit/editor/tinymce/dom/Serializer.html
Normal file
515
tests/qunit/editor/tinymce/dom/Serializer.html
Normal file
@ -0,0 +1,515 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for tinymce.dom.Serializer</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var DOM = tinymce.DOM;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("tinymce.dom.Serializer", {
|
||||
});
|
||||
|
||||
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="file.gif" data-mce-src="file.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="file.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="file.gif" data-mce-src="file.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="file.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">link</a><a href="#" title="forced value">test2</a>');
|
||||
|
||||
ser.setRules('img[src|border=0|alt=]');
|
||||
DOM.setHTML('test', '<img src="file.gif" data-mce-src="file.gif" border="0" alt="" />');
|
||||
equal(ser.serialize(DOM.get('test')), '<img src="file.gif" border="0" alt="" />', 'Default attribute with empty value');
|
||||
|
||||
ser.setRules('img[src|border=0|alt=],*[*]');
|
||||
DOM.setHTML('test', '<img src="file.gif" data-mce-src="file.gif" /><hr />');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><img src="file.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="file.gif" data-mce-src="file.gif" alt="" />');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><img src="file.gif" alt="" /></div>');
|
||||
|
||||
ser = new tinymce.dom.Serializer({invalid_elements : 'hr,br'});
|
||||
DOM.setHTML('test', '<img src="file.gif" data-mce-src="file.gif" /><hr /><br />');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><img src="file.gif" alt="" /></div>');
|
||||
});
|
||||
|
||||
test('Entity encoding', function() {
|
||||
var ser;
|
||||
|
||||
expect(4);
|
||||
|
||||
ser = new tinymce.dom.Serializer({entity_encoding : 'numeric'});
|
||||
DOM.setHTML('test', '<>&" åäö');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><>&" åäö</div>');
|
||||
|
||||
ser = new tinymce.dom.Serializer({entity_encoding : 'named'});
|
||||
DOM.setHTML('test', '<>&" åäö');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><>&" åäö</div>');
|
||||
|
||||
ser = new tinymce.dom.Serializer({entity_encoding : 'named+numeric', entities : '160,nbsp,34,quot,38,amp,60,lt,62,gt'});
|
||||
DOM.setHTML('test', '<>&" åäö');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><>&" åäö</div>');
|
||||
|
||||
ser = new tinymce.dom.Serializer({entity_encoding : 'raw'});
|
||||
DOM.setHTML('test', '<>&" åäö');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><>&"\u00a0\u00e5\u00e4\u00f6</div>');
|
||||
});
|
||||
|
||||
test('Form elements (general)', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(5);
|
||||
|
||||
ser.setRules('form[method],label[for],input[type|name|value|checked|disabled|readonly|length|maxlength],select[multiple],option[value|selected],textarea[name|disabled|readonly]');
|
||||
|
||||
DOM.setHTML('test', '<input type="text" />');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="text" />');
|
||||
|
||||
DOM.setHTML('test', '<input type="text" value="text" length="128" maxlength="129" />');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="text" value="text" length="128" maxlength="129" />');
|
||||
|
||||
DOM.setHTML('test', '<form method="post"><input type="hidden" name="method" value="get" /></form>');
|
||||
equal(ser.serialize(DOM.get('test')), '<form method="post"><input type="hidden" name="method" value="get" /></form>');
|
||||
|
||||
DOM.setHTML('test', '<label for="test">label</label>');
|
||||
equal(ser.serialize(DOM.get('test')), '<label for="test">label</label>');
|
||||
|
||||
DOM.setHTML('test', '<input type="checkbox" value="test" /><input type="button" /><textarea></textarea>');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="checkbox" value="test" /><input type="button" /><textarea></textarea>');
|
||||
});
|
||||
|
||||
test('Form elements (checkbox)', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(4);
|
||||
|
||||
ser.setRules('form[method],label[for],input[type|name|value|checked|disabled|readonly|length|maxlength],select[multiple],option[value|selected]');
|
||||
|
||||
DOM.setHTML('test', '<input type="checkbox" value="1">');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="checkbox" value="1" />');
|
||||
|
||||
DOM.setHTML('test', '<input type="checkbox" value="1" checked disabled readonly>');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="checkbox" value="1" checked="checked" disabled="disabled" readonly="readonly" />');
|
||||
|
||||
DOM.setHTML('test', '<input type="checkbox" value="1" checked="1" disabled="1" readonly="1">');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="checkbox" value="1" checked="checked" disabled="disabled" readonly="readonly" />');
|
||||
|
||||
DOM.setHTML('test', '<input type="checkbox" value="1" checked="true" disabled="true" readonly="true">');
|
||||
equal(ser.serialize(DOM.get('test')), '<input type="checkbox" value="1" checked="checked" disabled="disabled" readonly="readonly" />');
|
||||
});
|
||||
|
||||
test('Form elements (select)', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(7);
|
||||
|
||||
ser.setRules('form[method],label[for],input[type|name|value|checked|disabled|readonly|length|maxlength],select[multiple],option[value|selected]');
|
||||
|
||||
DOM.setHTML('test', '<select><option value="1">test1</option><option value="2" selected>test2</option></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select><option value="1">test1</option><option value="2" selected="selected">test2</option></select>');
|
||||
|
||||
DOM.setHTML('test', '<select><option value="1">test1</option><option selected="1" value="2">test2</option></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select><option value="1">test1</option><option value="2" selected="selected">test2</option></select>');
|
||||
|
||||
DOM.setHTML('test', '<select><option value="1">test1</option><option value="2" selected="true">test2</option></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select><option value="1">test1</option><option value="2" selected="selected">test2</option></select>');
|
||||
|
||||
DOM.setHTML('test', '<select multiple></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select multiple="multiple"></select>');
|
||||
|
||||
DOM.setHTML('test', '<select multiple="multiple"></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select multiple="multiple"></select>');
|
||||
|
||||
DOM.setHTML('test', '<select multiple="1"></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select multiple="multiple"></select>');
|
||||
|
||||
DOM.setHTML('test', '<select></select>');
|
||||
equal(ser.serialize(DOM.get('test')), '<select></select>');
|
||||
});
|
||||
|
||||
test('List elements', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(5);
|
||||
|
||||
ser.setRules('ul[compact],ol,li');
|
||||
|
||||
DOM.setHTML('test', '<ul compact></ul>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ul compact="compact"></ul>');
|
||||
|
||||
DOM.setHTML('test', '<ul compact="compact"></ul>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ul compact="compact"></ul>');
|
||||
|
||||
DOM.setHTML('test', '<ul compact="1"></ul>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ul compact="compact"></ul>');
|
||||
|
||||
DOM.setHTML('test', '<ul></ul>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ul></ul>');
|
||||
|
||||
DOM.setHTML('test', '<ol><li>a</li><ol><li>b</li><li>c</li></ol><li>e</li></ol>');
|
||||
equal(ser.serialize(DOM.get('test')), '<ol><li>a<ol><li>b</li><li>c</li></ol></li><li>e</li></ol>');
|
||||
});
|
||||
|
||||
test('Tables', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(4);
|
||||
|
||||
ser.setRules('table,tr,td[nowrap]');
|
||||
|
||||
DOM.setHTML('test', '<table><tr><td></td></tr></table>');
|
||||
equal(ser.serialize(DOM.get('test')), '<table><tr><td></td></tr></table>');
|
||||
|
||||
DOM.setHTML('test', '<table><tr><td nowrap></td></tr></table>');
|
||||
equal(ser.serialize(DOM.get('test')), '<table><tr><td nowrap="nowrap"></td></tr></table>');
|
||||
|
||||
DOM.setHTML('test', '<table><tr><td nowrap="nowrap"></td></tr></table>');
|
||||
equal(ser.serialize(DOM.get('test')), '<table><tr><td nowrap="nowrap"></td></tr></table>');
|
||||
|
||||
DOM.setHTML('test', '<table><tr><td nowrap="1"></td></tr></table>');
|
||||
equal(ser.serialize(DOM.get('test')), '<table><tr><td nowrap="nowrap"></td></tr></table>');
|
||||
});
|
||||
|
||||
test('Styles', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(1);
|
||||
|
||||
ser.setRules('*[*]');
|
||||
|
||||
DOM.setHTML('test', '<span style="border: 1px solid red" data-mce-style="border: 1px solid red;">test</span>');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><span style="border: 1px solid red;">test</span></div>');
|
||||
});
|
||||
|
||||
test('Comments', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(1);
|
||||
|
||||
ser.setRules('*[*]');
|
||||
|
||||
DOM.setHTML('test', '<!-- abc -->');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test"><!-- abc --></div>');
|
||||
});
|
||||
|
||||
test('Non HTML elements and attributes', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(2);
|
||||
|
||||
ser.setRules('*[*]');
|
||||
ser.schema.addValidChildren('+div[prefix:test]');
|
||||
|
||||
DOM.setHTML('test', '<div test:attr="test">test</div>');
|
||||
equal(ser.serialize(DOM.get('test'), {getInner : 1}), '<div test:attr="test">test</div>');
|
||||
|
||||
DOM.setHTML('test', 'test1<prefix:test>Test</prefix:test>test2');
|
||||
equal(ser.serialize(DOM.get('test')), '<div id="test">test1<prefix:test>Test</prefix:test>test2</div>');
|
||||
});
|
||||
|
||||
test('Padd empty elements', function() {
|
||||
var ser = new tinymce.dom.Serializer({fix_list_elements : true});
|
||||
|
||||
expect(1);
|
||||
|
||||
ser.setRules('#p');
|
||||
|
||||
DOM.setHTML('test', '<p>test</p><p></p>');
|
||||
equal(ser.serialize(DOM.get('test')), '<p>test</p><p> </p>');
|
||||
});
|
||||
|
||||
test('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>// <![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('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>');
|
||||
});
|
||||
</script>
|
||||
|
||||
<h1 id="qunit-header">Unit tests for tinymce.dom.Serializer</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<div id="test"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
586
tests/qunit/editor/tinymce/dom/TridentSelection.html
Normal file
586
tests/qunit/editor/tinymce/dom/TridentSelection.html
Normal file
@ -0,0 +1,586 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Unit tests for DOM Selection IE implementation</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var editor, rng;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
module("IE Selection", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
if (tinymce.isIE && !window.getSelection) {
|
||||
test("Selection of element containing text", function(){
|
||||
expect(5);
|
||||
|
||||
editor.setContent('<p>123</p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
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'
|
||||
});
|
||||
|
||||
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(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'
|
||||
});
|
||||
|
||||
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'
|
||||
});
|
||||
|
||||
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'
|
||||
});
|
||||
|
||||
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'
|
||||
});
|
||||
/*
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.dom.select('p')[1]);
|
||||
rng.setEndAfter(editor.dom.select('p')[2]);
|
||||
editor.selection.setRng(rng);
|
||||
rng = editor.selection.getRng(1);
|
||||
equal(rng.startContainer.nodeName, 'BODY', "startContainer type check");
|
||||
equal(rng.startOffset, 1, "startOffset doesn't match");
|
||||
equal(rng.endContainer.nodeName, 'BODY', "endContainer type check");
|
||||
equal(rng.endOffset, 3, "endOffset doesn't match");
|
||||
equal(editor.dom.getOuterHTML(rng.cloneContents()).replace(/[\r\n]/g, '').toLowerCase(), '<p>1234</p><p>abcd</p>');*/
|
||||
});
|
||||
|
||||
test("Mixed selection start at element end at text", function(){
|
||||
expect(5);
|
||||
|
||||
editor.setContent('<p><img src="about:blank" />text</p>', {
|
||||
format: 'raw'
|
||||
});
|
||||
|
||||
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'
|
||||
});
|
||||
|
||||
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'
|
||||
});
|
||||
|
||||
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'
|
||||
});
|
||||
|
||||
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'
|
||||
});
|
||||
|
||||
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'
|
||||
});
|
||||
|
||||
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'
|
||||
});
|
||||
|
||||
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");
|
||||
});
|
||||
}
|
||||
|
||||
function getCaretInfo() {
|
||||
editor.focus();
|
||||
var rng = editor.selection.getRng(1);
|
||||
alert(rng.startContainer + " - " + rng.startOffset);
|
||||
alert(rng.endContainer + " - " + rng.endOffset);
|
||||
editor.focus();
|
||||
}
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<h1 id="qunit-header">Unit tests for DOM Selection IE implementation</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content">
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
<a href="javascript:getCaretInfo();">[getCaretInfo]</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
120
tests/qunit/editor/tinymce/dom/test.css
Normal file
120
tests/qunit/editor/tinymce/dom/test.css
Normal file
@ -0,0 +1,120 @@
|
||||
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; }
|
||||
12
tests/qunit/editor/tinymce/dom/tests.js
Normal file
12
tests/qunit/editor/tinymce/dom/tests.js
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"title": "tinymce.dom",
|
||||
"tests": [
|
||||
{"title": "DOMUtils", "url": "DOMUtils.html"},
|
||||
{"title": "DOMUtils (jQuery)", "url": "DOMUtils_jquery.html"},
|
||||
{"title": "EventUtils", "url": "EventUtils.html"},
|
||||
{"title": "Range (IE/Native)", "url": "Range.html"},
|
||||
{"title": "Selection", "url": "Selection.html"},
|
||||
{"title": "Serializer", "url": "Serializer.html"},
|
||||
{"title": "TridentSelection (IE)", "url": "TridentSelection.html"}
|
||||
]
|
||||
}
|
||||
506
tests/qunit/editor/tinymce/html/DomParser.html
Normal file
506
tests/qunit/editor/tinymce/html/DomParser.html
Normal file
@ -0,0 +1,506 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>tinymce.html.DomParser tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
module("tinymce.html.DomParser");
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
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" alt="" /></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 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('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('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, result;
|
||||
|
||||
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, result, 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({}, schema);
|
||||
root = parser.parse('<span></span><a href="#"><!-'+'- x -'+'-></a>');
|
||||
equal(serializer.serialize(root), '<span></span>', 'Remove empty a element containing comment');*/
|
||||
|
||||
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 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>');
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">tinymce.html.DomParser tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
98
tests/qunit/editor/tinymce/html/Entities.html
Normal file
98
tests/qunit/editor/tinymce/html/Entities.html
Normal file
@ -0,0 +1,98 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>tinymce.html.Entities tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
module("tinymce.html.Entities");
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
test('encodeRaw', function() {
|
||||
expect(2);
|
||||
|
||||
equal(tinymce.html.Entities.encodeRaw('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&\u00e5\u00e4\u00f6', 'Raw encoding text');
|
||||
equal(tinymce.html.Entities.encodeRaw('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&\u00e5\u00e4\u00f6', 'Raw encoding attribute');
|
||||
});
|
||||
|
||||
test('encodeAllRaw', function() {
|
||||
expect(1);
|
||||
|
||||
equal(tinymce.html.Entities.encodeAllRaw('<>"\'&\u00e5\u00e4\u00f6'), '<>"'&\u00e5\u00e4\u00f6', 'Raw encoding all');
|
||||
});
|
||||
|
||||
test('encodeNumeric', function() {
|
||||
expect(2);
|
||||
|
||||
equal(tinymce.html.Entities.encodeNumeric('<>"\'&\u00e5\u00e4\u00f6\u03b8\u2170\ufa11'), '<>"\'&åäöθⅰ﨑', 'Numeric encoding text');
|
||||
equal(tinymce.html.Entities.encodeNumeric('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Numeric encoding attribute');
|
||||
});
|
||||
|
||||
test('encodeNamed', function() {
|
||||
expect(4);
|
||||
|
||||
equal(tinymce.html.Entities.encodeNamed('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&åäö', 'Named encoding text');
|
||||
equal(tinymce.html.Entities.encodeNamed('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Named encoding attribute');
|
||||
equal(tinymce.html.Entities.encodeNamed('<>"\'\u00e5\u00e4\u00f6', false, {'\u00e5' : 'å'}), '<>"\'å\u00e4\u00f6', 'Named encoding text');
|
||||
equal(tinymce.html.Entities.encodeNamed('<>"\'\u00e5\u00e4\u00f6', true, {'\u00e5' : 'å'}), '<>"\'å\u00e4\u00f6', 'Named encoding attribute');
|
||||
});
|
||||
|
||||
test('getEncodeFunc', function() {
|
||||
var encodeFunc;
|
||||
|
||||
expect(10);
|
||||
|
||||
encodeFunc = tinymce.html.Entities.getEncodeFunc('raw');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&\u00e5\u00e4\u00f6', 'Raw encoding text');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&\u00e5\u00e4\u00f6', 'Raw encoding attribute');
|
||||
|
||||
encodeFunc = tinymce.html.Entities.getEncodeFunc('named');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&åäö', 'Named encoding text');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Named encoding attribute');
|
||||
|
||||
encodeFunc = tinymce.html.Entities.getEncodeFunc('numeric');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&åäö', 'Named encoding text');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Named encoding attribute');
|
||||
|
||||
encodeFunc = tinymce.html.Entities.getEncodeFunc('named+numeric', '229,aring');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&åäö', 'Named+numeric encoding text');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Named+numeric encoding attribute');
|
||||
|
||||
encodeFunc = tinymce.html.Entities.getEncodeFunc('named,numeric', '229,aring');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6'), '<>"\'&åäö', 'Named+numeric encoding text');
|
||||
equal(encodeFunc('<>"\'&\u00e5\u00e4\u00f6', true), '<>"\'&åäö', 'Named+numeric encoding attribute');
|
||||
});
|
||||
|
||||
test('decode', function() {
|
||||
expect(3);
|
||||
|
||||
equal(tinymce.html.Entities.decode('<>"'&åäö&unknown;'''), '<>"\'&\u00e5\u00e4\u00f6&unknown;\'\'', 'Decode text with various entities');
|
||||
|
||||
equal(tinymce.html.Entities.encodeNumeric(tinymce.html.Entities.decode(
|
||||
'‚ƒ„…†‡ˆ‰Š' +
|
||||
'‹ŒŽ‘’“”•–—˜' +
|
||||
'™š›œžŸ')
|
||||
), '‚ƒ„…†‡ˆ‰Š‹ŒŽ' +
|
||||
'‘’“”•–—˜™š' +
|
||||
'›œžŸ',
|
||||
'Entity decode ascii');
|
||||
|
||||
equal(tinymce.html.Entities.encodeNumeric(tinymce.html.Entities.decode('你')), '你', "High byte non western character.");
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">tinymce.html.Entities tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
466
tests/qunit/editor/tinymce/html/Node.html
Normal file
466
tests/qunit/editor/tinymce/html/Node.html
Normal file
@ -0,0 +1,466 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>tinymce.html.Node tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
module("tinymce.html.Node");
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
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, node2;
|
||||
|
||||
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, node2, node3;
|
||||
|
||||
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');
|
||||
ok(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;
|
||||
|
||||
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;
|
||||
|
||||
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.');
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">tinymce.html.Node tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
616
tests/qunit/editor/tinymce/html/SaxParser.html
Normal file
616
tests/qunit/editor/tinymce/html/SaxParser.html
Normal file
@ -0,0 +1,616 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>tinymce.html.SaxParser tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
module("tinymce.html.SaxParser");
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
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() {
|
||||
expect(46);
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('<b href=\'"&<>\'></b>');
|
||||
equal(writer.getContent(), '<b href=""&<>"></b>', 'Parse attributes with <> in them.');
|
||||
deepEqual(counter.counts, {start:1, end:1}, 'Parse attributes with <> in them (count).');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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).');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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).');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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).');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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).');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<P>text2<B>tex<t3</p>te>xt4</b>text5');
|
||||
equal(writer.getContent(), 'text1<p>text2<b>tex<t3</b></p>te>xt4text5', 'Parse tag soup 3.');
|
||||
deepEqual(counter.counts, {text: 5, start: 2, end: 2}, 'Parse tag soup 3 counts.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('text1<span title="<test" data-test="test>"></span>');
|
||||
equal(writer.getContent(), 'text1<span title="<test" data-test="test>"></span>', 'Parse element with </> in attributes.');
|
||||
deepEqual(counter.counts, {text: 1, start: 1, end: 1}, 'Parse element with </> in attributes counts.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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() {
|
||||
expect(8);
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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() {
|
||||
expect(8);
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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() {
|
||||
expect(10);
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse('');
|
||||
equal(writer.getContent(), '', 'Parse empty.');
|
||||
deepEqual(counter.counts, {}, 'Parse empty counts.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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() {
|
||||
expect(8);
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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() {
|
||||
expect(8);
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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() {
|
||||
expect(6);
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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() {
|
||||
expect(4);
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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.');
|
||||
|
||||
var counter = createCounter(writer);
|
||||
var 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() {
|
||||
expect(2);
|
||||
|
||||
var counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
var 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() {
|
||||
expect(1);
|
||||
|
||||
var counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
var 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() {
|
||||
expect(2);
|
||||
|
||||
var schema = new tinymce.html.Schema({valid_elements : 'b'});
|
||||
var counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
var 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.');
|
||||
|
||||
var schema = new tinymce.html.Schema({valid_elements : 'b,span[class]'});
|
||||
var counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
var 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() {
|
||||
expect(2);
|
||||
|
||||
var schema = new tinymce.html.Schema({valid_elements : 'b'});
|
||||
var counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
counter.remove_internals = true;
|
||||
var 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.');
|
||||
|
||||
var schema = new tinymce.html.Schema({valid_elements : 'b,span[class]'});
|
||||
var counter = createCounter(writer);
|
||||
counter.validate = true;
|
||||
counter.remove_internals = true;
|
||||
var 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 = createCounter(writer);
|
||||
var 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 = createCounter(writer);
|
||||
counter.validate = true;
|
||||
var 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 = createCounter(writer);
|
||||
counter.validate = false;
|
||||
counter.allow_conditional_comments = true;
|
||||
var 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 = createCounter(writer);
|
||||
counter.validate = false;
|
||||
counter.allow_conditional_comments = false;
|
||||
var 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]-->');
|
||||
});
|
||||
|
||||
test('Parse script urls (allowed)', function() {
|
||||
var counter = createCounter(writer);
|
||||
counter.validate = false;
|
||||
counter.allow_script_urls = true;
|
||||
var parser = new tinymce.html.SaxParser(counter, schema);
|
||||
writer.reset();
|
||||
parser.parse(
|
||||
'<a href="javascript:alert(1)">1</a>' +
|
||||
'<a href=" 2 ">2</a>'
|
||||
);
|
||||
equal(writer.getContent(), '<a href="javascript:alert(1)">1</a><a href=" 2 ">2</a>');
|
||||
});
|
||||
|
||||
test('Parse script urls (denied)', function() {
|
||||
var counter = createCounter(writer);
|
||||
counter.validate = false;
|
||||
var 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="%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 href="%E3%82%AA%E3%83%BC%E3%83">Invalid url</a>');
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">tinymce.html.SaxParser tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
374
tests/qunit/editor/tinymce/html/Schema.html
Normal file
374
tests/qunit/editor/tinymce/html/Schema.html
Normal file
@ -0,0 +1,374 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>tinymce.html.Schema tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
module("tinymce.html.Schema");
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
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() {
|
||||
expect(17);
|
||||
|
||||
var schema = new tinymce.html.Schema({valid_elements: '*[id|class]'});
|
||||
deepEqual(schema.getElementRule('b').attributes, {"id": {}, "class": {} });
|
||||
deepEqual(schema.getElementRule('b').attributesOrder, ["id", "class"]);
|
||||
|
||||
var 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);
|
||||
|
||||
var 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);
|
||||
|
||||
var 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() {
|
||||
expect(13);
|
||||
|
||||
var 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'));
|
||||
|
||||
var 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'));
|
||||
|
||||
var 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() {
|
||||
expect(3);
|
||||
|
||||
var 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() {
|
||||
expect(1);
|
||||
|
||||
var 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() {
|
||||
expect(1);
|
||||
|
||||
var 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() {
|
||||
expect(1);
|
||||
|
||||
var 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() {
|
||||
expect(1);
|
||||
|
||||
var 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() {
|
||||
expect(1);
|
||||
|
||||
var schema = new tinymce.html.Schema({valid_elements: 'span[dir<ltr?rtl]'});
|
||||
deepEqual(schema.getElementRule('span'), {"attributes": {"dir": {"validValues": {"rtl": {}, "ltr": {}}}}, "attributesOrder": ["dir"]});
|
||||
});
|
||||
|
||||
test('Remove empty elements', function() {
|
||||
expect(2);
|
||||
|
||||
var schema = new tinymce.html.Schema({valid_elements: '-span'});
|
||||
deepEqual(schema.getElementRule('span'), {"attributes": {}, "attributesOrder": [], "removeEmpty": true});
|
||||
|
||||
var schema = new tinymce.html.Schema({valid_elements: '#span'});
|
||||
deepEqual(schema.getElementRule('span'), {"attributes": {}, "attributesOrder": [], "paddEmpty": true});
|
||||
});
|
||||
|
||||
test('addValidElements', function() {
|
||||
expect(1);
|
||||
|
||||
var 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() {
|
||||
expect(3);
|
||||
|
||||
var 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"]});
|
||||
|
||||
var 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() {
|
||||
expect(1);
|
||||
|
||||
var 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() {
|
||||
expect(1);
|
||||
|
||||
var schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getBlockElements(), {
|
||||
ASIDE: {}, HGROUP: {}, SECTION: {}, ARTICLE: {}, FOOTER: {}, HEADER: {}, SAMP: {},
|
||||
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: {}, DATALIST: {}, OPTGROUP: {}, OPTION: {}, SELECT: {},
|
||||
aside: {}, hgroup: {}, section: {}, article: {}, footer: {}, header: {}, samp: {},
|
||||
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: {}, datalist: {}, optgroup: {},
|
||||
option: {}, select: {}
|
||||
});
|
||||
});
|
||||
|
||||
test('getShortEndedElements', function() {
|
||||
expect(1);
|
||||
|
||||
var 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() {
|
||||
expect(1);
|
||||
|
||||
var 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" : {},
|
||||
"embed": {}, "param": {}, "meta": {}, "link": {}, "isindex": {},
|
||||
"input": {}, "img": {}, "hr": {}, "frame": {}, "col": {}, "br": {},
|
||||
"basefont": {}, "base": {}, "area": {}, "source" : {},
|
||||
"td": {}, "th": {}, "iframe": {}, "video": {}, "audio": {}, "object": {}, "wbr" : {}, "track" : {}, "script" : {},
|
||||
});
|
||||
});
|
||||
|
||||
test('getWhiteSpaceElements', function() {
|
||||
expect(1);
|
||||
|
||||
var schema = new tinymce.html.Schema();
|
||||
deepEqual(schema.getWhiteSpaceElements(), {
|
||||
"IFRAME": {}, "NOSCRIPT": {}, "OBJECT": {}, "PRE": {},
|
||||
"SCRIPT": {}, "STYLE": {}, "TEXTAREA": {}, "VIDEO": {}, "AUDIO": {},
|
||||
"iframe": {}, "noscript": {}, "object": {}, "pre": {},
|
||||
"script": {}, "style": {}, "textarea": {}, "video": {}, "audio": {}
|
||||
});
|
||||
});
|
||||
|
||||
test('getTextBlockElements', function() {
|
||||
expect(1);
|
||||
|
||||
var 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('isValidChild', function() {
|
||||
expect(4);
|
||||
|
||||
var 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() {
|
||||
expect(3);
|
||||
|
||||
var schema = new tinymce.html.Schema();
|
||||
ok(schema.getElementRule('b'));
|
||||
ok(!schema.getElementRule('bx'));
|
||||
ok(!schema.getElementRule(null));
|
||||
});
|
||||
|
||||
test('addCustomElements', function() {
|
||||
expect(5);
|
||||
|
||||
var 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() {
|
||||
expect(7);
|
||||
|
||||
var 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'));
|
||||
|
||||
var schema = new tinymce.html.Schema();
|
||||
ok(schema.isValidChild('body', 'p'));
|
||||
schema.addValidChildren('-body[p]');
|
||||
ok(!schema.isValidChild('body', 'p'));
|
||||
});
|
||||
|
||||
test('addCustomElements/getCustomElements', function() {
|
||||
expect(4);
|
||||
|
||||
var 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() {
|
||||
expect(3);
|
||||
|
||||
var schema = new tinymce.html.Schema({whitespace_elements : 'pre,p'});
|
||||
ok(schema.getWhiteSpaceElements()['pre']);
|
||||
ok(!schema.getWhiteSpaceElements()['span']);
|
||||
|
||||
var schema = new tinymce.html.Schema({whitespace_elements : 'code'});
|
||||
ok(schema.getWhiteSpaceElements()['code']);
|
||||
});
|
||||
|
||||
test('selfClosingElements', function() {
|
||||
expect(3);
|
||||
|
||||
var 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() {
|
||||
expect(3);
|
||||
|
||||
var 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() {
|
||||
expect(3);
|
||||
|
||||
var schema = new tinymce.html.Schema({boolean_attributes : 'href,alt'});
|
||||
ok(schema.getBoolAttrs()['href']);
|
||||
ok(schema.getBoolAttrs()['alt']);
|
||||
ok(!schema.getBoolAttrs()['checked']);
|
||||
});
|
||||
|
||||
test('nonEmptyElements', function() {
|
||||
expect(3);
|
||||
|
||||
var 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() {
|
||||
expect(3);
|
||||
|
||||
var 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 = 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'));
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">tinymce.html.Schema tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
46
tests/qunit/editor/tinymce/html/Serializer.html
Normal file
46
tests/qunit/editor/tinymce/html/Serializer.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>tinymce.html.Serializer tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
module("tinymce.html.Serializer");
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
test('Basic serialization', function() {
|
||||
var serializer = new tinymce.html.Serializer();
|
||||
|
||||
expect(6);
|
||||
|
||||
equal(serializer.serialize(new tinymce.html.DomParser().parse('text<text&')), 'text<text&');
|
||||
equal(serializer.serialize(new tinymce.html.DomParser().parse('<B>text</B><IMG src="1.gif">')), '<strong>text</strong><img src="1.gif" alt="" />');
|
||||
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>');
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">tinymce.html.Serializer tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
176
tests/qunit/editor/tinymce/html/Styles.html
Normal file
176
tests/qunit/editor/tinymce/html/Styles.html
Normal file
@ -0,0 +1,176 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>tinymce.html.Styles tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
module("tinymce.html.Styles");
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
test('Basic parsing/serializing', function() {
|
||||
var styles = new tinymce.html.Styles();
|
||||
|
||||
expect(11);
|
||||
|
||||
equal(styles.serialize(styles.parse('FONT-SIZE:10px')), "font-size: 10px;");
|
||||
equal(styles.serialize(styles.parse('FONT-SIZE:10px;COLOR:red')), "font-size: 10px; color: red;");
|
||||
equal(styles.serialize(styles.parse(' FONT-SIZE : 10px ; COLOR : red ')), "font-size: 10px; color: red;");
|
||||
equal(styles.serialize(styles.parse('key:"value"')), "key: 'value';");
|
||||
equal(styles.serialize(styles.parse('key:"value1" \'value2\'')), "key: 'value1' 'value2';");
|
||||
equal(styles.serialize(styles.parse('key:"val\\"ue1" \'val\\\'ue2\'')), "key: 'val\"ue1' 'val\\'ue2';");
|
||||
equal(styles.serialize(styles.parse('width:100%')), 'width: 100%;');
|
||||
equal(styles.serialize(styles.parse('value:_; value2:"_"')), 'value: _; value2: \'_\';');
|
||||
equal(styles.serialize(styles.parse('value: "&"')), "value: '&';");
|
||||
equal(styles.serialize(styles.parse('value: "&"')), "value: '&';");
|
||||
equal(styles.serialize(styles.parse('value: ')), "");
|
||||
});
|
||||
|
||||
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('Script urls denied', function() {
|
||||
var styles = new tinymce.html.Styles();
|
||||
|
||||
equal(styles.serialize(styles.parse('behavior:url(test.htc)')), "");
|
||||
equal(styles.serialize(styles.parse('color:expression(alert(1))')), "");
|
||||
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(vbscript:alert(1)')), "");
|
||||
equal(styles.serialize(styles.parse('background:url(j\navas\u0000cr\tipt:alert(1)')), "");
|
||||
});
|
||||
|
||||
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');");
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">tinymce.html.Styles tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
174
tests/qunit/editor/tinymce/html/Writer.html
Normal file
174
tests/qunit/editor/tinymce/html/Writer.html
Normal file
@ -0,0 +1,174 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>tinymce.html.Writer tests</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
module("tinymce.html.Writer");
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
test('Comment', function() {
|
||||
expect(2);
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.comment('text');
|
||||
equal(writer.getContent(), '<!--text-->');
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.comment('');
|
||||
equal(writer.getContent(), '<!---->');
|
||||
});
|
||||
|
||||
test('CDATA', function() {
|
||||
expect(2);
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.cdata('text');
|
||||
equal(writer.getContent(), '<![CDATA[text]]>');
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.cdata('');
|
||||
equal(writer.getContent(), '<![CDATA[]]>');
|
||||
});
|
||||
|
||||
test('PI', function() {
|
||||
expect(2);
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.pi('xml', 'someval');
|
||||
equal(writer.getContent(), '<?xml someval?>');
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.pi('xml');
|
||||
equal(writer.getContent(), '<?xml?>');
|
||||
});
|
||||
|
||||
test('Doctype', function() {
|
||||
expect(2);
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.doctype(' text');
|
||||
equal(writer.getContent(), '<!DOCTYPE text>');
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.doctype('');
|
||||
equal(writer.getContent(), '<!DOCTYPE>');
|
||||
});
|
||||
|
||||
test('Text', function() {
|
||||
expect(2);
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.text('te<xt');
|
||||
equal(writer.getContent(), 'te<xt');
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.text('');
|
||||
equal(writer.getContent(), '');
|
||||
});
|
||||
|
||||
test('Text raw', function() {
|
||||
expect(2);
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.text('te<xt', true);
|
||||
equal(writer.getContent(), 'te<xt');
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.text('', true);
|
||||
equal(writer.getContent(), '');
|
||||
});
|
||||
|
||||
test('Start', function() {
|
||||
expect(5);
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.start('b');
|
||||
equal(writer.getContent(), '<b>');
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.start('b', [{name: 'attr1', value: 'value1'}, {name: 'attr2', value: 'value2'}]);
|
||||
equal(writer.getContent(), '<b attr1="value1" attr2="value2">');
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.start('b', [{name: 'attr1', value: 'val<"ue1'}]);
|
||||
equal(writer.getContent(), '<b attr1="val<"ue1">');
|
||||
|
||||
var 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" />');
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.start('br', null, true);
|
||||
equal(writer.getContent(), '<br />');
|
||||
});
|
||||
|
||||
test('End', function() {
|
||||
expect(1);
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.end('b');
|
||||
equal(writer.getContent(), '</b>');
|
||||
});
|
||||
|
||||
test('Indentation', function() {
|
||||
expect(2);
|
||||
|
||||
var 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>');
|
||||
|
||||
var 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() {
|
||||
expect(3);
|
||||
|
||||
var writer = new tinymce.html.Writer();
|
||||
writer.start('p', [{name: "title", value: '<>"\'&\u00e5\u00e4\u00f6'}]);
|
||||
writer.text('<>"\'&\u00e5\u00e4\u00f6');
|
||||
writer.end('p');
|
||||
equal(writer.getContent(), '<p title="<>"\'&\u00e5\u00e4\u00f6"><>"\'&\u00e5\u00e4\u00f6</p>');
|
||||
|
||||
var writer = new tinymce.html.Writer({entity_encoding: 'numeric'});
|
||||
writer.start('p', [{name: "title", value: '<>"\'&\u00e5\u00e4\u00f6'}]);
|
||||
writer.text('<>"\'&\u00e5\u00e4\u00f6');
|
||||
writer.end('p');
|
||||
equal(writer.getContent(), '<p title="<>"\'&åäö"><>"\'&åäö</p>');
|
||||
|
||||
var writer = new tinymce.html.Writer({entity_encoding: 'named'});
|
||||
writer.start('p', [{name: "title", value: '<>"\'&\u00e5\u00e4\u00f6'}]);
|
||||
writer.text('<>"\'&\u00e5\u00e4\u00f6');
|
||||
writer.end('p');
|
||||
equal(writer.getContent(), '<p title="<>"\'&åäö"><>"\'&åäö</p>');
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">tinymce.html.Writer tests</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
294
tests/qunit/editor/tinymce/html/obsolete.html
Normal file
294
tests/qunit/editor/tinymce/html/obsolete.html
Normal file
@ -0,0 +1,294 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Support for obsolete tags and attributes in the default HTML 5.0 schema</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script>
|
||||
var editor;
|
||||
|
||||
QUnit.config.reorder = false;
|
||||
QUnit.config.autostart = false;
|
||||
module("tinymce.html.Schema", {
|
||||
autostart: false
|
||||
});
|
||||
|
||||
function getContent() {
|
||||
return editor.getContent().replace(/[\r\n]+/g, '');
|
||||
};
|
||||
|
||||
/**
|
||||
* 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( getContent(), testString, text );
|
||||
|
||||
text = 'strike, converted to span';
|
||||
editor.setContent( '<strike>test</strike>' );
|
||||
equal( getContent(), '<p><span style="text-decoration: line-through;">test</span></p>', text );
|
||||
|
||||
text = 'big';
|
||||
testString = '<p><big>test</big></p>';
|
||||
editor.setContent( testString );
|
||||
equal( getContent(), testString, text );
|
||||
|
||||
text = 'center';
|
||||
testString = '<center>test</center>';
|
||||
editor.setContent( testString );
|
||||
equal( getContent(), testString, text );
|
||||
|
||||
text = 'font, converted to span';
|
||||
editor.setContent( '<p><font size="4">test</font></p>' );
|
||||
equal( getContent(), '<p><span style="font-size: large;">test</span></p>', text );
|
||||
|
||||
text = 'tt';
|
||||
testString = '<p><tt>test</tt></p>';
|
||||
editor.setContent( testString );
|
||||
equal( 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( getContent(), testString, text );
|
||||
|
||||
text = 'Old style anchors';
|
||||
testString = '<p><a name="test"></a></p>';
|
||||
editor.setContent( testString );
|
||||
equal( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( getContent(), testString, text );
|
||||
|
||||
text = 'compact on dl elements';
|
||||
testString = '<dl compact="compact"><dd>1</dd></dl>';
|
||||
editor.setContent( testString );
|
||||
equal( 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( 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( 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( 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( 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( getContent(), { object: 'align border hspace vspace' } ), text );
|
||||
|
||||
text = 'compact on ol elements';
|
||||
testString = '<ol compact="compact"><li>test</li></ol>';
|
||||
editor.setContent( testString );
|
||||
equal( getContent(), testString, text );
|
||||
|
||||
text = 'compact, type on ul elements';
|
||||
testString = '<ul type="disc" compact="compact"><li>test</li></ul>';
|
||||
editor.setContent( testString );
|
||||
ok( hasAttr( getContent(), { ul: 'compact type' } ), text );
|
||||
|
||||
text = 'width on pre elements';
|
||||
testString = '<pre width="100">1</pre>';
|
||||
editor.setContent( testString );
|
||||
equal( getContent(), testString, text );
|
||||
});
|
||||
|
||||
tinymce.init({
|
||||
mode : "exact",
|
||||
elements : "elm1",
|
||||
add_unload_trigger : false,
|
||||
indent : false,
|
||||
entities : 'raw',
|
||||
plugins: 'media',
|
||||
convert_urls : false,
|
||||
init_instance_callback : function(ed) {
|
||||
editor = ed;
|
||||
QUnit.start();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Support for obsolete tags and attributes in the default HTML 5.0 schema</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<textarea id="elm1" name="elm1"></textarea>
|
||||
<div>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent({format : 'raw'}));">[getRawContents]</a>
|
||||
<a href="javascript:alert(tinymce.EditorManager.get('elm1').getContent());">[getContents]</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
14
tests/qunit/editor/tinymce/html/tests.js
Normal file
14
tests/qunit/editor/tinymce/html/tests.js
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "tinymce.html",
|
||||
"tests": [
|
||||
{"title": "DomParser", "url": "DomParser.html"},
|
||||
{"title": "Entities", "url": "Entities.html"},
|
||||
{"title": "Node", "url": "Node.html"},
|
||||
{"title": "SaxParser", "url": "SaxParser.html"},
|
||||
{"title": "Schema", "url": "Schema.html"},
|
||||
{"title": "Serializer", "url": "Serializer.html"},
|
||||
{"title": "Styles", "url": "Styles.html"},
|
||||
{"title": "Writer", "url": "Writer.html"},
|
||||
{"title": "Obsolete tags and attributes", "url": "obsolete.html"}
|
||||
]
|
||||
}
|
||||
15
tests/qunit/editor/tinymce/tests.js
Normal file
15
tests/qunit/editor/tinymce/tests.js
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"title": "tinymce",
|
||||
"tests": [
|
||||
{"title": "Editor", "url": "Editor.html"},
|
||||
{"title": "EditorCommands", "url": "EditorCommands.html"},
|
||||
{"title": "EnterKey", "url": "EnterKey.html"},
|
||||
{"title": "ForceBlocks", "url": "ForceBlocks.html"},
|
||||
{"title": "Formatter (Apply)", "url": "Formatter_apply.html"},
|
||||
{"title": "Formatter (Remove)", "url": "Formatter_remove.html"},
|
||||
{"title": "Formatter (Check)", "url": "Formatter_check.html"},
|
||||
{"title": "Formatter (jsrobot)", "url": "Formatter_robot.html", "jsrobot":true},
|
||||
{"title": "UndoManager", "url": "UndoManager.html"},
|
||||
{"title": "Undo", "url": "UndoManager_robot.html", "jsrobot": true}
|
||||
]
|
||||
}
|
||||
63
tests/qunit/editor/tinymce/ui/AbsoluteLayout.html
Normal file
63
tests/qunit/editor/tinymce/ui/AbsoluteLayout.html
Normal file
@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.AbsoluteLayout Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.AbsoluteLayout", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
|
||||
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() {
|
||||
panel = createPanel({
|
||||
items: [
|
||||
{type: 'spacer', x: 10, y: 20, w: 100, h: 120, classes: 'red'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 200, 200]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [10, 20, 100, 120]);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.AbsoluteLayout Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
133
tests/qunit/editor/tinymce/ui/Button.html
Normal file
133
tests/qunit/editor/tinymce/ui/Button.html
Normal file
@ -0,0 +1,133 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Button Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.Button", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
|
||||
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'});
|
||||
|
||||
nearlyEqualRects(rect(button), [0, 0, 34, 30], 4);
|
||||
});
|
||||
|
||||
test("button text, size large", function() {
|
||||
var button = createButton({text: 'X', size: 'large'});
|
||||
|
||||
nearlyEqualRects(rect(button), [0, 0, 41, 39], 4);
|
||||
});
|
||||
|
||||
test("button text, size small", function() {
|
||||
var button = createButton({text: 'X', size: 'small'});
|
||||
|
||||
nearlyEqualRects(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(rect(button), [0, 0, 100, 100]);
|
||||
deepEqual(rect(button.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("button icon, size default", function() {
|
||||
var button = createButton({icon: 'test'});
|
||||
|
||||
nearlyEqualRects(rect(button), [0, 0, 40, 30], 4);
|
||||
});
|
||||
|
||||
test("button icon, size small", function() {
|
||||
var button = createButton({icon: 'test', size: 'small'});
|
||||
|
||||
nearlyEqualRects(rect(button), [0, 0, 28, 24], 4);
|
||||
});
|
||||
|
||||
test("button icon, size large", function() {
|
||||
var button = createButton({icon: 'test', size: 'large'});
|
||||
|
||||
nearlyEqualRects(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(rect(button), [0, 0, 100, 100]);
|
||||
deepEqual(rect(button.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("button text & icon, size default", function() {
|
||||
var button = createButton({text: 'X', icon: 'test'});
|
||||
|
||||
nearlyEqualRects(rect(button), [0, 0, 52, 30], 4);
|
||||
});
|
||||
|
||||
test("button text & icon, size large", function() {
|
||||
var button = createButton({text: 'X', icon: 'test', size: 'large'});
|
||||
|
||||
nearlyEqualRects(rect(button), [0, 0, 59, 40], 4);
|
||||
});
|
||||
|
||||
test("button text & icon, size small", function() {
|
||||
var button = createButton({text: 'X', icon: 'test', size: 'small'});
|
||||
|
||||
nearlyEqualRects(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(rect(button), [0, 0, 100, 100]);
|
||||
deepEqual(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'});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Button Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/ButtonGroup.html
Normal file
43
tests/qunit/editor/tinymce/ui/ButtonGroup.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.ButtonGroup Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.ButtonGroup", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.ButtonGroup Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/Checkbox.html
Normal file
43
tests/qunit/editor/tinymce/ui/Checkbox.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.Checkbox Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.Checkbox", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.Checkbox Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
273
tests/qunit/editor/tinymce/ui/Collection.html
Normal file
273
tests/qunit/editor/tinymce/ui/Collection.html
Normal file
@ -0,0 +1,273 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Collection Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
module("ui.Collection");
|
||||
|
||||
window.onload = 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'));
|
||||
|
||||
QUnit.start();
|
||||
};
|
||||
|
||||
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, index) {
|
||||
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);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.Collection Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
132
tests/qunit/editor/tinymce/ui/ColorButton.html
Normal file
132
tests/qunit/editor/tinymce/ui/ColorButton.html
Normal file
@ -0,0 +1,132 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Button Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.ColorButton", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
|
||||
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'});
|
||||
|
||||
nearlyEqualRects(rect(colorButton), [0, 0, 42, 30], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text, size large", function() {
|
||||
var colorButton = createColorButton({text: 'X', size: 'large'});
|
||||
|
||||
nearlyEqualRects(rect(colorButton), [0, 0, 49, 39], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text, size small", function() {
|
||||
var colorButton = createColorButton({text: 'X', size: 'small'});
|
||||
|
||||
nearlyEqualRects(rect(colorButton), [0, 0, 34, 23], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text, width 100, height 100", function() {
|
||||
var colorButton = createColorButton({text: 'X', width: 100, height: 100});
|
||||
|
||||
deepEqual(rect(colorButton), [0, 0, 100, 100]);
|
||||
deepEqual(rect(colorButton.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("colorbutton icon, size default", function() {
|
||||
var colorButton = createColorButton({icon: 'test'});
|
||||
|
||||
nearlyEqualRects(rect(colorButton), [0, 0, 50, 30], 4);
|
||||
});
|
||||
|
||||
test("colorbutton icon, size small", function() {
|
||||
var colorButton = createColorButton({icon: 'test', size: 'small'});
|
||||
|
||||
nearlyEqualRects(rect(colorButton), [0, 0, 43, 24], 4);
|
||||
});
|
||||
|
||||
test("colorbutton icon, size large", function() {
|
||||
var colorButton = createColorButton({icon: 'test', size: 'large'});
|
||||
|
||||
nearlyEqualRects(rect(colorButton), [0, 0, 54, 40], 4);
|
||||
});
|
||||
|
||||
test("colorbutton icon, width 100, height 100", function() {
|
||||
var colorButton = createColorButton({icon: 'test', width: 100, height: 100});
|
||||
|
||||
deepEqual(rect(colorButton), [0, 0, 100, 100]);
|
||||
deepEqual(rect(colorButton.getEl().firstChild), [1, 1, 98, 98]);
|
||||
});
|
||||
|
||||
test("colorbutton text & icon, size default", function() {
|
||||
var colorButton = createColorButton({text: 'X', icon: 'test'});
|
||||
|
||||
nearlyEqualRects(rect(colorButton), [0, 0, 62, 30], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text & icon, size large", function() {
|
||||
var colorButton = createColorButton({text: 'X', icon: 'test', size: 'large'});
|
||||
|
||||
nearlyEqualRects(rect(colorButton), [0, 0, 69, 40], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text & icon, size small", function() {
|
||||
var colorButton = createColorButton({text: 'X', icon: 'test', size: 'small'});
|
||||
|
||||
nearlyEqualRects(rect(colorButton), [0, 0, 53, 24], 4);
|
||||
});
|
||||
|
||||
test("colorbutton text & icon, width 100, height 100", function() {
|
||||
var colorButton = createColorButton({text: 'X', icon: 'test', width: 100, height: 100});
|
||||
|
||||
deepEqual(rect(colorButton), [0, 0, 100, 100]);
|
||||
deepEqual(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'});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Button Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
49
tests/qunit/editor/tinymce/ui/ComboBox.html
Normal file
49
tests/qunit/editor/tinymce/ui/ComboBox.html
Normal file
@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.ComboBox Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.TextBox", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
|
||||
/*
|
||||
test("combobox text, size default", function() {
|
||||
var combobox = new tinymce.ui.ComboBox({text: 'abc'}).renderTo(document.getElementById('view'));
|
||||
|
||||
deepEqual(rect(combobox), [0, 0, 40, 22]);
|
||||
});
|
||||
*/
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.ComboBox Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/Container.html
Normal file
43
tests/qunit/editor/tinymce/ui/Container.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.Container Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.Container", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.Container Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
229
tests/qunit/editor/tinymce/ui/Control.html
Normal file
229
tests/qunit/editor/tinymce/ui/Control.html
Normal file
@ -0,0 +1,229 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Control Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
module("ui.Control");
|
||||
|
||||
test("Initial states", function() {
|
||||
var ctrl;
|
||||
|
||||
ctrl = new tinymce.ui.Control({});
|
||||
|
||||
// Check inital states
|
||||
equal(ctrl.disabled(), false);
|
||||
equal(ctrl.active(), false);
|
||||
equal(ctrl.visible(), true);
|
||||
equal(ctrl.text(), "");
|
||||
equal(ctrl.width(), 0);
|
||||
equal(ctrl.height(), 0);
|
||||
equal(ctrl.name(), "");
|
||||
equal(ctrl.title(), "");
|
||||
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',
|
||||
width: 100,
|
||||
height: 200,
|
||||
name: 'Name'
|
||||
});
|
||||
|
||||
// Check settings states
|
||||
equal(ctrl.disabled(), true);
|
||||
equal(ctrl.active(), true);
|
||||
equal(ctrl.visible(), true);
|
||||
equal(ctrl.text(), "Text");
|
||||
equal(ctrl.width(), 100);
|
||||
equal(ctrl.height(), 200);
|
||||
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',
|
||||
width: 100,
|
||||
height: 200,
|
||||
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").
|
||||
width(100).
|
||||
height(200).
|
||||
name("Name").parent(cont);
|
||||
|
||||
// Check states
|
||||
equal(ctrl.disabled(), true);
|
||||
equal(ctrl.active(), true);
|
||||
equal(ctrl.visible(), true);
|
||||
equal(ctrl.text(), "Text");
|
||||
equal(ctrl.width(), 100);
|
||||
equal(ctrl.height(), 200);
|
||||
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.
|
||||
refresh().
|
||||
bind('click', function() {}).
|
||||
unbind().
|
||||
renderTo(document.getElementById('viewport')).
|
||||
fire("nothing").
|
||||
remove();
|
||||
|
||||
// Check so that the chain worked
|
||||
ok(ctrl instanceof tinymce.ui.Control);
|
||||
});
|
||||
|
||||
test("Events", function() {
|
||||
var ctrl = new tinymce.ui.Control({
|
||||
handlers: {
|
||||
handler1: function() {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}), count;
|
||||
|
||||
ctrl.bind('MyEvent', function(target, args) {
|
||||
ok(target === ctrl);
|
||||
ok(ctrl === this);
|
||||
deepEqual(args, {myKey: 'myVal'});
|
||||
});
|
||||
|
||||
ctrl.fire('MyEvent', {myKey: 'myVal'});
|
||||
|
||||
function countAndBreak(target, args) {
|
||||
count++;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bind two events
|
||||
ctrl.bind('MyEvent2', countAndBreak);
|
||||
ctrl.bind('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.unbind();
|
||||
count = 0;
|
||||
ctrl.fire('MyEvent2', {myKey: 'myVal'});
|
||||
equal(count, 0, 'Unbind all');
|
||||
|
||||
// Unbind by name
|
||||
ctrl.bind('MyEvent1', countAndBreak);
|
||||
ctrl.bind('MyEvent2', countAndBreak);
|
||||
ctrl.unbind('MyEvent2');
|
||||
count = 0;
|
||||
ctrl.fire('MyEvent1', {myKey: 'myVal'});
|
||||
ctrl.fire('MyEvent2', {myKey: 'myVal'});
|
||||
equal(count, 1);
|
||||
|
||||
// Unbind by name callback
|
||||
ctrl.bind('MyEvent1', countAndBreak);
|
||||
ctrl.bind('MyEvent1', function() {count++;});
|
||||
ctrl.unbind('MyEvent1', countAndBreak);
|
||||
count = 0;
|
||||
ctrl.fire('MyEvent1', {myKey: 'myVal'});
|
||||
equal(count, 1);
|
||||
|
||||
// Bind by named handler
|
||||
ctrl.unbind();
|
||||
ctrl.bind('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(), 'class1 class2 class3');
|
||||
ok(ctrl.hasClass('class1'));
|
||||
ok(ctrl.hasClass('class2'));
|
||||
ok(ctrl.hasClass('class3'));
|
||||
ok(!ctrl.hasClass('class4'));
|
||||
|
||||
ctrl.addClass('class4');
|
||||
equal(ctrl.classes(), 'class1 class2 class3 class4');
|
||||
ok(ctrl.hasClass('class1'));
|
||||
ok(ctrl.hasClass('class2'));
|
||||
ok(ctrl.hasClass('class3'));
|
||||
ok(ctrl.hasClass('class4'));
|
||||
|
||||
ctrl.removeClass('class4');
|
||||
equal(ctrl.classes(), 'class1 class2 class3');
|
||||
ok(ctrl.hasClass('class1'));
|
||||
ok(ctrl.hasClass('class2'));
|
||||
ok(ctrl.hasClass('class3'));
|
||||
ok(!ctrl.hasClass('class4'));
|
||||
|
||||
ctrl.removeClass('class3').removeClass('class2');
|
||||
equal(ctrl.classes(), 'class1');
|
||||
ok(ctrl.hasClass('class1'));
|
||||
ok(!ctrl.hasClass('class2'));
|
||||
ok(!ctrl.hasClass('class3'));
|
||||
|
||||
ctrl.removeClass('class3').removeClass('class1');
|
||||
equal(ctrl.classes(), '');
|
||||
ok(!ctrl.hasClass('class1'));
|
||||
ok(!ctrl.hasClass('class2'));
|
||||
ok(!ctrl.hasClass('class3'));
|
||||
});
|
||||
*/
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.Control Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/DragHelper.html
Normal file
43
tests/qunit/editor/tinymce/ui/DragHelper.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.DragHelper Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.DragHelper", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.DragHelper Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/ElementPath.html
Normal file
43
tests/qunit/editor/tinymce/ui/ElementPath.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.ElementPath Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.ElementPath", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.ElementPath Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/Factory.html
Normal file
43
tests/qunit/editor/tinymce/ui/Factory.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.Factory Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.Factory", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.Factory Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/FieldSet.html
Normal file
43
tests/qunit/editor/tinymce/ui/FieldSet.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.FieldSet Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.FieldSet", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.FieldSet Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/FilePicker.html
Normal file
43
tests/qunit/editor/tinymce/ui/FilePicker.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.FilePicker Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.FilePicker", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.FilePicker Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
87
tests/qunit/editor/tinymce/ui/FitLayout.html
Normal file
87
tests/qunit/editor/tinymce/ui/FitLayout.html
Normal file
@ -0,0 +1,87 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.FitLayout Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.FitLayout", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
|
||||
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(rect(panel), [0, 0, 200, 200]);
|
||||
deepEqual(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(rect(panel), [0, 0, 200, 200]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [4, 4, 192, 192]);
|
||||
});
|
||||
|
||||
test("fit with panel inside", function() {
|
||||
panel = createFitPanel({
|
||||
items: [
|
||||
{type: 'panel', border: 1}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 200, 200]);
|
||||
deepEqual(rect(panel.find('panel')[0]), [1, 1, 198, 198]);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.FitLayout Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
915
tests/qunit/editor/tinymce/ui/FlexLayout.html
Normal file
915
tests/qunit/editor/tinymce/ui/FlexLayout.html
Normal file
@ -0,0 +1,915 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.FlexLayout Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.FlexLayout", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
resetScroll(panel.getEl('body'));
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
test("pack: default, align: default, flex: default", function() {
|
||||
panel = renderPanel({});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [20, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [40, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: default, align: default, flex: default, borders", function() {
|
||||
panel = renderPanel({defaults: {border: 1}});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 22, 22]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [22, 0, 22, 22]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [44, 0, 22, 22]);
|
||||
});
|
||||
|
||||
test("pack: default, flex: 1", function() {
|
||||
panel = renderPanel({
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 67, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [67, 0, 67, 20]);
|
||||
deepEqual(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'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 62, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [62, 0, 67, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [128, 0, 72, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, flex: default", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [20, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [40, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, flex: 1", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 67, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [67, 0, 67, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [133, 0, 67, 20]);
|
||||
});
|
||||
|
||||
test("pack: end, flex: default", function() {
|
||||
panel = renderPanel({
|
||||
pack: "end"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [140, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [160, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [180, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: end, flex: 1", function() {
|
||||
panel = renderPanel({
|
||||
pack: "end",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 67, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [67, 0, 67, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [133, 0, 67, 20]);
|
||||
});
|
||||
|
||||
test("pack: center, flex: default", function() {
|
||||
panel = renderPanel({
|
||||
pack: "center"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [70, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [90, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [110, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: center, flex: 1", function() {
|
||||
panel = renderPanel({
|
||||
pack: "center",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 67, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [67, 0, 67, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [133, 0, 67, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, spacing: 3", function() {
|
||||
panel = renderPanel({
|
||||
layout: "flex",
|
||||
pack: "start",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [23, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [46, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: end, spacing: 3", function() {
|
||||
panel = renderPanel({
|
||||
pack: "end",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [134, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [157, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [180, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: center, spacing: 3", function() {
|
||||
panel = renderPanel({
|
||||
pack: "center",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [67, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [90, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [113, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, padding: 3", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
padding: 3
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [23, 3, 20, 20]);
|
||||
deepEqual(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
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [26, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [49, 3, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, align: start", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
align: "start"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [20, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [40, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack start, align: center", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
align: "center"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 90, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [20, 90, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [40, 90, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, align: end", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
align: "end"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 180, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [20, 180, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [40, 180, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: start, align: stretch", function() {
|
||||
panel = renderPanel({
|
||||
pack: "start",
|
||||
align: "stretch"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 200]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [20, 0, 20, 200]);
|
||||
deepEqual(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
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 194]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [23, 3, 20, 194]);
|
||||
deepEqual(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}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 43, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [43, 0, 98, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [141, 0, 59, 20]);
|
||||
});
|
||||
|
||||
test("pack: justify", function() {
|
||||
panel = renderPanel({
|
||||
pack: "justify"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [90, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [180, 0, 20, 20]);
|
||||
});
|
||||
|
||||
test("pack: justify, padding: 3", function() {
|
||||
panel = renderPanel({
|
||||
pack: "justify",
|
||||
padding: 3
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [90, 3, 20, 20]);
|
||||
deepEqual(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}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [45, 3, 80, 20]);
|
||||
deepEqual(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}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 160, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [160, 0, 80, 20]);
|
||||
deepEqual(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}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 90, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [90, 0, 220, 20]);
|
||||
deepEqual(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'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [20, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [40, 0, 20, 20]);
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 60, 20]);
|
||||
panel.items().eq(0).hide();
|
||||
panel.reflow();
|
||||
|
||||
deepEqual(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}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 67, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [67, 0, 67, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [133, 0, 67, 20]);
|
||||
|
||||
panel.layoutRect({w: 400, h: 400}).reflow();
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 400, 400]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 133, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [133, 0, 133, 20]);
|
||||
deepEqual(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'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 100, 100]);
|
||||
deepEqual(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'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 100, 100]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [20, 20, 100, 100]);
|
||||
deepEqual(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'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(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'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(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'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 200, 20]);
|
||||
deepEqual(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();
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 402, 402]);
|
||||
deepEqual(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();
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 110, 40]);
|
||||
deepEqual(rect(panel.find("panel")[0]), [20, 0, 70, 40]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 20, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [30, 10, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [60, 10, 20, 20]);
|
||||
deepEqual(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();
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 80, 40]);
|
||||
deepEqual(rect(panel.find("panel")[0]), [20, 0, 40, 40]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 20, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [30, 10, 20, 20]);
|
||||
deepEqual(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({});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 20, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 40, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: default, flex: 1", function() {
|
||||
panel = renderColumnPanel({
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 67]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 67, 20, 67]);
|
||||
deepEqual(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'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 62]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 62, 20, 67]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 128, 20, 72]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, flex: default", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 20, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 40, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, flex: 1", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 67]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 67, 20, 67]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 133, 20, 67]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: end, flex: default", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "end"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 140, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 160, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 180, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: end, flex: 1", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "end",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 67]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 67, 20, 67]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 133, 20, 67]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: center, flex: default", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "center"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 70, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 90, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 110, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: center, flex: 1", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "center",
|
||||
defaults: {flex: 1}
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 67]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 67, 20, 67]);
|
||||
deepEqual(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
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 23, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 46, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: end, spacing: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "end",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 134, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 157, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 180, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: center, spacing: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "center",
|
||||
spacing: 3
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 67, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 90, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 113, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, padding: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
padding: 3
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [3, 23, 20, 20]);
|
||||
deepEqual(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
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [3, 26, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [3, 49, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, align: start", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
align: "start"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 20, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 40, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack start, align: center", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
align: "center"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [90, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [90, 20, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [90, 40, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, align: end", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
align: "end"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [180, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [180, 20, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [180, 40, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: start, align: stretch", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "start",
|
||||
align: "stretch"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 200, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 20, 200, 20]);
|
||||
deepEqual(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
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 194, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [3, 23, 194, 20]);
|
||||
deepEqual(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}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 43]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 43, 20, 98]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 141, 20, 59]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: justify", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "justify"
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 90, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 180, 20, 20]);
|
||||
});
|
||||
|
||||
test("direction: column, pack: justify, padding: 3", function() {
|
||||
panel = renderColumnPanel({
|
||||
pack: "justify",
|
||||
padding: 3
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [3, 90, 20, 20]);
|
||||
deepEqual(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}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [3, 45, 20, 80]);
|
||||
deepEqual(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}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 160]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 160, 20, 80]);
|
||||
deepEqual(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}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 90]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 90, 20, 220]);
|
||||
deepEqual(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}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 67]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 67, 20, 67]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 133, 20, 67]);
|
||||
|
||||
panel.layoutRect({w: 400, h: 400}).reflow();
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 400, 400]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 133]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [0, 133, 20, 133]);
|
||||
deepEqual(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();
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 402, 402]);
|
||||
deepEqual(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();
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 110, 40]);
|
||||
deepEqual(rect(panel.find("panel")[0]), [20, 0, 70, 40]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 20, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [30, 10, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [60, 10, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[3]), [90, 20, 20, 20]);
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.FlexLayout Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/FloatPanel.html
Normal file
43
tests/qunit/editor/tinymce/ui/FloatPanel.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.FloatPanel Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.FloatPanel", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.FloatPanel Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/FlowLayout.html
Normal file
43
tests/qunit/editor/tinymce/ui/FlowLayout.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.FlowLayout Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.FlowLayout", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.FlowLayout Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/Form.html
Normal file
43
tests/qunit/editor/tinymce/ui/Form.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.Form Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.Form", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.Form Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/FormItem.html
Normal file
43
tests/qunit/editor/tinymce/ui/FormItem.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.FormItem Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.FormItem", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.FormItem Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
244
tests/qunit/editor/tinymce/ui/GridLayout.html
Normal file
244
tests/qunit/editor/tinymce/ui/GridLayout.html
Normal file
@ -0,0 +1,244 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.GridLayout Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.GridLayout", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
|
||||
function renderGridPanel(settings) {
|
||||
var panel = tinymce.ui.Factory.create(tinymce.extend({
|
||||
type: "panel",
|
||||
layout: "grid",
|
||||
defaults: {type: 'spacer'}
|
||||
}, settings)).renderTo(document.getElementById('view')).reflow();
|
||||
|
||||
resetScroll(panel.getEl('body'));
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
test("automatic grid size 2x2", function() {
|
||||
panel = renderGridPanel({
|
||||
items: [
|
||||
{classes: 'red'}, {classes: 'green'},
|
||||
{classes: 'blue'}, {classes: 'cyan'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 40, 40]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [20, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 20, 20, 20]);
|
||||
deepEqual(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(rect(panel), [0, 0, 200, 200]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 17, 22]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [17, 0, 17, 22]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 22, 16, 22]);
|
||||
deepEqual(rect(panel.find('spacer')[3]), [17, 22, 17, 22]);
|
||||
});
|
||||
*/
|
||||
|
||||
test("spacing: 3, automatic grid size 2x2", function() {
|
||||
panel = renderGridPanel({
|
||||
spacing: 3,
|
||||
items: [
|
||||
{classes: 'red'}, {classes: 'green'},
|
||||
{classes: 'blue'}, {classes: 'cyan'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 43, 43]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [23, 0, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 23, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[3]), [23, 23, 20, 20]);
|
||||
});
|
||||
|
||||
test("padding: 3, automatic grid size 2x2", function() {
|
||||
panel = renderGridPanel({
|
||||
padding: 3,
|
||||
items: [
|
||||
{classes: 'red'}, {classes: 'green'},
|
||||
{classes: 'blue'}, {classes: 'cyan'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 46, 46]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [23, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [3, 23, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[3]), [23, 23, 20, 20]);
|
||||
});
|
||||
|
||||
test("spacing: 3, padding: 3, automatic grid size 2x2", function() {
|
||||
panel = renderGridPanel({
|
||||
padding: 3,
|
||||
spacing: 3,
|
||||
items: [
|
||||
{classes: 'red'}, {classes: 'green'},
|
||||
{classes: 'blue'}, {classes: 'cyan'}
|
||||
]
|
||||
});
|
||||
|
||||
deepEqual(rect(panel), [0, 0, 49, 49]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [3, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [26, 3, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [3, 26, 20, 20]);
|
||||
deepEqual(rect(panel.find('spacer')[3]), [26, 26, 20, 20]);
|
||||
});
|
||||
|
||||
test("inner elements 100x100 maxWidth/maxHeight: 118 (overflow W+H)", function() {
|
||||
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(rect(panel), [0, 0, 118, 118]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [0, 0, 100, 100]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [100, 0, 100, 100]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 100, 100, 100]);
|
||||
deepEqual(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() {
|
||||
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(rect(panel), [0, 0, 118, 118]);
|
||||
deepEqual(rect(panel.find('spacer')[0]), [20, 20, 100, 100]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [130, 20, 100, 100]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [20, 130, 100, 100]);
|
||||
deepEqual(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() {
|
||||
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(rect(panel.find('spacer')[0]), [0, 0, 100, 100]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [100, 0, 100, 100]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 100, 100, 100]);
|
||||
deepEqual(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() {
|
||||
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(rect(panel.find('spacer')[0]), [0, 0, 100, 100]);
|
||||
deepEqual(rect(panel.find('spacer')[1]), [100, 0, 100, 100]);
|
||||
deepEqual(rect(panel.find('spacer')[2]), [0, 100, 100, 100]);
|
||||
deepEqual(rect(panel.find('spacer')[3]), [100, 100, 100, 100]);
|
||||
equal(panel.layoutRect().contentW, 200);
|
||||
equal(panel.layoutRect().contentH, 200);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.GridLayout Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/Iframe.html
Normal file
43
tests/qunit/editor/tinymce/ui/Iframe.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.Iframe Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.Iframe", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.Iframe Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/KeyboardNavigation.html
Normal file
43
tests/qunit/editor/tinymce/ui/KeyboardNavigation.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.KeyboardNavigation Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.KeyboardNavigation", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.KeyboardNavigation Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/Label.html
Normal file
43
tests/qunit/editor/tinymce/ui/Label.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.Label Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.Label", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.Label Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
43
tests/qunit/editor/tinymce/ui/Layout.html
Normal file
43
tests/qunit/editor/tinymce/ui/Layout.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ui.Layout Test Suite</title>
|
||||
<link type="text/css" rel="stylesheet" href="../../../../../src/wp-includes/js/tinymce/skins/lightgray/skin.min.css" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||
<link rel="stylesheet" href="css/ui-overrides.css" type="text/css" />
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" />
|
||||
<script src="http://code.jquery.com/qunit/qunit-git.js"></script>
|
||||
<script src="../../js/qunit/reporter.js"></script>
|
||||
<script src="../../js/utils.js"></script>
|
||||
<script src="../../js/tinymce_loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
var panel;
|
||||
|
||||
QUnit.config.autostart = false;
|
||||
QUnit.config.reorder = false;
|
||||
|
||||
module("ui.Layout", {
|
||||
setup: function() {
|
||||
document.getElementById('view').innerHTML = '';
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
//document.getElementById('view').innerHTML = '';
|
||||
}
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
QUnit.start();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">ui.Layout Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests">
|
||||
</ol>
|
||||
<div id="view" style="position: absolute; right: 0; top: 0"></div>
|
||||
</body>
|
||||
</html>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user