TinyMCE: update to 4.2.7. Changelog: http://www.tinymce.com/develop/changelog/?ctrl=version&act=view&pr_id=1&vr_id=888
Fixes #34620. git-svn-id: https://develop.svn.wordpress.org/trunk@35574 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
5acf79fa7e
commit
71d22131e6
@ -30,6 +30,10 @@ tinymce.PluginManager.add('lists', function(editor) {
|
||||
return node && !!editor.schema.getTextBlockElements()[node.nodeName];
|
||||
}
|
||||
|
||||
function isEditorBody(elm) {
|
||||
return elm === editor.getBody();
|
||||
}
|
||||
|
||||
editor.on('init', function() {
|
||||
var dom = editor.dom, selection = editor.selection;
|
||||
|
||||
@ -318,6 +322,10 @@ tinymce.PluginManager.add('lists', function(editor) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isEditorBody(ul)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (li.nodeName == 'DD') {
|
||||
dom.rename(li, 'DT');
|
||||
return true;
|
||||
@ -602,6 +610,10 @@ tinymce.PluginManager.add('lists', function(editor) {
|
||||
tinymce.each(getSelectedListItems(), function(li) {
|
||||
var node, rootList;
|
||||
|
||||
if (isEditorBody(li.parentNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEmpty(li)) {
|
||||
outdent(li);
|
||||
return;
|
||||
@ -622,6 +634,10 @@ tinymce.PluginManager.add('lists', function(editor) {
|
||||
function toggleList(listName) {
|
||||
var parentList = dom.getParent(selection.getStart(), 'OL,UL,DL');
|
||||
|
||||
if (isEditorBody(parentList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parentList) {
|
||||
if (parentList.nodeName == listName) {
|
||||
removeList(listName);
|
||||
@ -698,17 +714,22 @@ tinymce.PluginManager.add('lists', function(editor) {
|
||||
|
||||
dom.remove(fromElm);
|
||||
|
||||
if (isEmpty(ul)) {
|
||||
if (isEmpty(ul) && !isEditorBody(ul)) {
|
||||
dom.remove(ul);
|
||||
}
|
||||
}
|
||||
|
||||
if (selection.isCollapsed()) {
|
||||
var li = dom.getParent(selection.getStart(), 'LI');
|
||||
var li = dom.getParent(selection.getStart(), 'LI'), ul, rng, otherLi;
|
||||
|
||||
if (li) {
|
||||
var rng = selection.getRng(true);
|
||||
var otherLi = dom.getParent(findNextCaretContainer(rng, isForward), 'LI');
|
||||
ul = li.parentNode;
|
||||
if (isEditorBody(ul) && dom.isEmpty(ul)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
rng = selection.getRng(true);
|
||||
otherLi = dom.getParent(findNextCaretContainer(rng, isForward), 'LI');
|
||||
|
||||
if (otherLi && otherLi != li) {
|
||||
var bookmark = createBookmark(rng);
|
||||
@ -723,7 +744,7 @@ tinymce.PluginManager.add('lists', function(editor) {
|
||||
|
||||
return true;
|
||||
} else if (!otherLi) {
|
||||
if (!isForward && removeList(li.parentNode.nodeName)) {
|
||||
if (!isForward && removeList(ul.nodeName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -1411,7 +1411,9 @@ define("tinymce/pasteplugin/WordFilter", [
|
||||
}
|
||||
|
||||
// Serialize DOM back to HTML
|
||||
e.content = new Serializer({}, schema).serialize(rootNode);
|
||||
e.content = new Serializer({
|
||||
validate: settings.validate
|
||||
}, schema).serialize(rootNode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -41,8 +41,8 @@ tinymce.ThemeManager.add('modern', function(editor) {
|
||||
function bindSelectorChanged() {
|
||||
var selection = editor.selection;
|
||||
|
||||
if (itemName == "bullist") {
|
||||
selection.selectorChanged('ul > li', function(state, args) {
|
||||
function setActiveItem(name) {
|
||||
return function(state, args) {
|
||||
var nodeName, i = args.parents.length;
|
||||
|
||||
while (i--) {
|
||||
@ -52,23 +52,16 @@ tinymce.ThemeManager.add('modern', function(editor) {
|
||||
}
|
||||
}
|
||||
|
||||
item.active(state && nodeName == "UL");
|
||||
});
|
||||
item.active(state && nodeName == name);
|
||||
};
|
||||
}
|
||||
|
||||
if (itemName == "bullist") {
|
||||
selection.selectorChanged('ul > li', setActiveItem("UL"));
|
||||
}
|
||||
|
||||
if (itemName == "numlist") {
|
||||
selection.selectorChanged('ol > li', function(state, args) {
|
||||
var nodeName, i = args.parents.length;
|
||||
|
||||
while (i--) {
|
||||
nodeName = args.parents[i].nodeName;
|
||||
if (nodeName == "OL" || nodeName == "UL") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
item.active(state && nodeName == "OL");
|
||||
});
|
||||
selection.selectorChanged('ol > li', setActiveItem("OL"));
|
||||
}
|
||||
|
||||
if (item.settings.stateSelector) {
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
||||
// 4.2.6 (2015-09-28)
|
||||
// 4.2.7 (2015-10-27)
|
||||
|
||||
/**
|
||||
* Compiled inline version. (Library mode)
|
||||
@ -6392,7 +6392,7 @@ define("tinymce/html/Entities", [
|
||||
|
||||
var Entities = {
|
||||
/**
|
||||
* Encodes the specified string using raw entities. This means only the required XML base entities will be endoded.
|
||||
* Encodes the specified string using raw entities. This means only the required XML base entities will be encoded.
|
||||
*
|
||||
* @method encodeRaw
|
||||
* @param {String} text Text to encode.
|
||||
@ -6834,6 +6834,27 @@ define("tinymce/dom/DOMUtils", [
|
||||
$elm.attr('data-mce-style', value);
|
||||
}
|
||||
|
||||
function nodeIndex(node, normalized) {
|
||||
var idx = 0, lastNodeType, nodeType;
|
||||
|
||||
if (node) {
|
||||
for (lastNodeType = node.nodeType, node = node.previousSibling; node; node = node.previousSibling) {
|
||||
nodeType = node.nodeType;
|
||||
|
||||
// Normalize text nodes
|
||||
if (normalized && nodeType == 3) {
|
||||
if (nodeType == lastNodeType || !node.nodeValue.length) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
lastNodeType = nodeType;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new DOMUtils instance. Consult the Wiki for more details on settings etc for this class.
|
||||
*
|
||||
@ -8250,26 +8271,7 @@ define("tinymce/dom/DOMUtils", [
|
||||
* @param {boolean} normalized Optional true/false state if the index is what it would be after a normalization.
|
||||
* @return {Number} Index of the specified node.
|
||||
*/
|
||||
nodeIndex: function(node, normalized) {
|
||||
var idx = 0, lastNodeType, nodeType;
|
||||
|
||||
if (node) {
|
||||
for (lastNodeType = node.nodeType, node = node.previousSibling; node; node = node.previousSibling) {
|
||||
nodeType = node.nodeType;
|
||||
|
||||
// Normalize text nodes
|
||||
if (normalized && nodeType == 3) {
|
||||
if (nodeType == lastNodeType || !node.nodeValue.length) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
lastNodeType = nodeType;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
},
|
||||
nodeIndex: nodeIndex,
|
||||
|
||||
/**
|
||||
* Splits an element into two new elements and places the specified split
|
||||
@ -8578,6 +8580,7 @@ define("tinymce/dom/DOMUtils", [
|
||||
* tinymce.DOM.addClass('someid', 'someclass');
|
||||
*/
|
||||
DOMUtils.DOM = new DOMUtils(document);
|
||||
DOMUtils.nodeIndex = nodeIndex;
|
||||
|
||||
return DOMUtils;
|
||||
});
|
||||
@ -9381,6 +9384,10 @@ define("tinymce/dom/RangeUtils", [
|
||||
var container, offset, walker, body = dom.getRoot(), node, nonEmptyElementsMap;
|
||||
var directionLeft, isAfterNode;
|
||||
|
||||
function isTableCell(node) {
|
||||
return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);
|
||||
}
|
||||
|
||||
function hasBrBeforeAfter(node, left) {
|
||||
var walker = new TreeWalker(node, dom.getParent(node.parentNode, dom.isBlock) || body);
|
||||
|
||||
@ -9494,7 +9501,7 @@ define("tinymce/dom/RangeUtils", [
|
||||
}
|
||||
|
||||
// Found a BR/IMG element that we can place the caret before
|
||||
if (nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
|
||||
if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCell(node)) {
|
||||
offset = dom.nodeIndex(node);
|
||||
container = node.parentNode;
|
||||
|
||||
@ -12926,27 +12933,29 @@ define("tinymce/html/Serializer", [
|
||||
sortedAttrs.map = {};
|
||||
|
||||
elementRule = schema.getElementRule(node.name);
|
||||
for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) {
|
||||
attrName = elementRule.attributesOrder[i];
|
||||
if (elementRule) {
|
||||
for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) {
|
||||
attrName = elementRule.attributesOrder[i];
|
||||
|
||||
if (attrName in attrs.map) {
|
||||
attrValue = attrs.map[attrName];
|
||||
sortedAttrs.map[attrName] = attrValue;
|
||||
sortedAttrs.push({name: attrName, value: attrValue});
|
||||
if (attrName in attrs.map) {
|
||||
attrValue = attrs.map[attrName];
|
||||
sortedAttrs.map[attrName] = attrValue;
|
||||
sortedAttrs.push({name: attrName, value: attrValue});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0, l = attrs.length; i < l; i++) {
|
||||
attrName = attrs[i].name;
|
||||
for (i = 0, l = attrs.length; i < l; i++) {
|
||||
attrName = attrs[i].name;
|
||||
|
||||
if (!(attrName in sortedAttrs.map)) {
|
||||
attrValue = attrs.map[attrName];
|
||||
sortedAttrs.map[attrName] = attrValue;
|
||||
sortedAttrs.push({name: attrName, value: attrValue});
|
||||
if (!(attrName in sortedAttrs.map)) {
|
||||
attrValue = attrs.map[attrName];
|
||||
sortedAttrs.map[attrName] = attrValue;
|
||||
sortedAttrs.push({name: attrName, value: attrValue});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attrs = sortedAttrs;
|
||||
attrs = sortedAttrs;
|
||||
}
|
||||
}
|
||||
|
||||
writer.start(node.name, attrs, isEmpty);
|
||||
@ -14061,6 +14070,10 @@ define("tinymce/dom/ControlSelection", [
|
||||
return false;
|
||||
}
|
||||
|
||||
if (elm == editor.getBody()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return editor.dom.is(elm, selector);
|
||||
}
|
||||
|
||||
@ -18502,9 +18515,13 @@ define("tinymce/Formatter", [
|
||||
|
||||
removeCaretContainer();
|
||||
|
||||
// Remove caret container on keydown and it's a backspace, enter or left/right arrow keys
|
||||
// Backspace key needs to check if the range is collapsed due to bug #6780
|
||||
if ((keyCode == 8 && selection.isCollapsed()) || keyCode == 37 || keyCode == 39) {
|
||||
// Remove caret container if it's empty
|
||||
if (keyCode == 8 && selection.isCollapsed() && selection.getStart().innerHTML == INVISIBLE_CHAR) {
|
||||
removeCaretContainer(getParentCaretContainer(selection.getStart()));
|
||||
}
|
||||
|
||||
// Remove caret container on keydown and it's left/right arrow keys
|
||||
if (keyCode == 37 || keyCode == 39) {
|
||||
removeCaretContainer(getParentCaretContainer(selection.getStart()));
|
||||
}
|
||||
|
||||
@ -19018,6 +19035,10 @@ define("tinymce/EnterKey", [
|
||||
dom.getContentEditable(node) !== "true";
|
||||
}
|
||||
|
||||
function isTableCell(node) {
|
||||
return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);
|
||||
}
|
||||
|
||||
// Renders empty block on IE
|
||||
function renderBlockOnIE(block) {
|
||||
var oldRng;
|
||||
@ -19284,10 +19305,15 @@ define("tinymce/EnterKey", [
|
||||
|
||||
// Not in a block element or in a table cell or caption
|
||||
parentBlock = dom.getParent(container, dom.isBlock);
|
||||
rootBlockName = editor.getBody().nodeName.toLowerCase();
|
||||
if (!parentBlock || !canSplitBlock(parentBlock)) {
|
||||
parentBlock = parentBlock || editableRoot;
|
||||
|
||||
if (parentBlock == editor.getBody() || isTableCell(parentBlock)) {
|
||||
rootBlockName = parentBlock.nodeName.toLowerCase();
|
||||
} else {
|
||||
rootBlockName = parentBlock.parentNode.nodeName.toLowerCase();
|
||||
}
|
||||
|
||||
if (!parentBlock.hasChildNodes()) {
|
||||
newBlock = dom.create(blockName);
|
||||
setForcedBlockAttrs(newBlock);
|
||||
@ -19358,6 +19384,10 @@ define("tinymce/EnterKey", [
|
||||
return containerBlock;
|
||||
}
|
||||
|
||||
if (containerBlock == editor.getBody()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we are in an nested list
|
||||
var containerBlockParentName = containerBlock.parentNode.nodeName;
|
||||
if (/^(OL|UL|LI)$/.test(containerBlockParentName)) {
|
||||
@ -20321,7 +20351,9 @@ define("tinymce/EditorCommands", [
|
||||
|
||||
// Setup parser and serializer
|
||||
parser = editor.parser;
|
||||
serializer = new Serializer({}, editor.schema);
|
||||
serializer = new Serializer({
|
||||
validate: settings.validate
|
||||
}, editor.schema);
|
||||
bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">​</span>';
|
||||
|
||||
// Run beforeSetContent handlers on the HTML to be inserted
|
||||
@ -27637,6 +27669,59 @@ define("tinymce/WindowManager", [
|
||||
};
|
||||
});
|
||||
|
||||
// Included from: js/tinymce/classes/dom/NodePath.js
|
||||
|
||||
/**
|
||||
* NodePath.js
|
||||
*
|
||||
* Released under LGPL License.
|
||||
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
||||
*
|
||||
* License: http://www.tinymce.com/license
|
||||
* Contributing: http://www.tinymce.com/contributing
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles paths of nodes within an element.
|
||||
*
|
||||
* @private
|
||||
* @class tinymce.dom.NodePath
|
||||
*/
|
||||
define("tinymce/dom/NodePath", [
|
||||
"tinymce/dom/DOMUtils"
|
||||
], function(DOMUtils) {
|
||||
function create(rootNode, targetNode, normalized) {
|
||||
var path = [];
|
||||
|
||||
for (; targetNode && targetNode != rootNode; targetNode = targetNode.parentNode) {
|
||||
path.push(DOMUtils.nodeIndex(targetNode, normalized));
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
function resolve(rootNode, path) {
|
||||
var i, node, children;
|
||||
|
||||
for (node = rootNode, i = path.length - 1; i >= 0; i--) {
|
||||
children = node.childNodes;
|
||||
|
||||
if (path[i] > children.length - 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
node = children[path[i]];
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
return {
|
||||
create: create,
|
||||
resolve: resolve
|
||||
};
|
||||
});
|
||||
|
||||
// Included from: js/tinymce/classes/util/Quirks.js
|
||||
|
||||
/**
|
||||
@ -27661,11 +27746,12 @@ define("tinymce/util/Quirks", [
|
||||
"tinymce/util/VK",
|
||||
"tinymce/dom/RangeUtils",
|
||||
"tinymce/dom/TreeWalker",
|
||||
"tinymce/dom/NodePath",
|
||||
"tinymce/html/Node",
|
||||
"tinymce/html/Entities",
|
||||
"tinymce/Env",
|
||||
"tinymce/util/Tools"
|
||||
], function(VK, RangeUtils, TreeWalker, Node, Entities, Env, Tools) {
|
||||
], function(VK, RangeUtils, TreeWalker, NodePath, Node, Entities, Env, Tools) {
|
||||
return function(editor) {
|
||||
var each = Tools.each, $ = editor.$;
|
||||
var BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection,
|
||||
@ -28044,6 +28130,111 @@ define("tinymce/util/Quirks", [
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This retains the formatting if the last character is to be deleted.
|
||||
*
|
||||
* Backspace on this: <p><b><i>a|</i></b></p> would become <p>|</p> in WebKit.
|
||||
* With this patch: <p><b><i>|<br></i></b></p>
|
||||
*/
|
||||
function handleLastBlockCharacterDelete(isForward, rng) {
|
||||
var path, blockElm, newBlockElm, clonedBlockElm, sibling,
|
||||
container, offset, br, currentFormatNodes;
|
||||
|
||||
function cloneTextBlockWithFormats(blockElm, node) {
|
||||
currentFormatNodes = $(node).parents().filter(function(idx, node) {
|
||||
return !!editor.schema.getTextInlineElements()[node.nodeName];
|
||||
});
|
||||
|
||||
newBlockElm = blockElm.cloneNode(false);
|
||||
|
||||
currentFormatNodes = Tools.map(currentFormatNodes, function(formatNode) {
|
||||
formatNode = formatNode.cloneNode(false);
|
||||
|
||||
if (newBlockElm.hasChildNodes()) {
|
||||
formatNode.appendChild(newBlockElm.firstChild);
|
||||
newBlockElm.appendChild(formatNode);
|
||||
} else {
|
||||
newBlockElm.appendChild(formatNode);
|
||||
}
|
||||
|
||||
newBlockElm.appendChild(formatNode);
|
||||
|
||||
return formatNode;
|
||||
});
|
||||
|
||||
if (currentFormatNodes.length) {
|
||||
br = dom.create('br');
|
||||
currentFormatNodes[0].appendChild(br);
|
||||
dom.replace(newBlockElm, blockElm);
|
||||
|
||||
rng.setStartBefore(br);
|
||||
rng.setEndBefore(br);
|
||||
editor.selection.setRng(rng);
|
||||
|
||||
return br;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function isTextBlock(node) {
|
||||
return node && editor.schema.getTextBlockElements()[node.tagName];
|
||||
}
|
||||
|
||||
if (!rng.collapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
container = rng.startContainer;
|
||||
offset = rng.startOffset;
|
||||
blockElm = dom.getParent(container, dom.isBlock);
|
||||
if (!isTextBlock(blockElm)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (container.nodeType == 1) {
|
||||
container = container.childNodes[offset];
|
||||
if (container && container.tagName != 'BR') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isForward) {
|
||||
sibling = blockElm.nextSibling;
|
||||
} else {
|
||||
sibling = blockElm.previousSibling;
|
||||
}
|
||||
|
||||
if (dom.isEmpty(blockElm) && isTextBlock(sibling) && dom.isEmpty(sibling)) {
|
||||
if (cloneTextBlockWithFormats(blockElm, container)) {
|
||||
dom.remove(sibling);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (container.nodeType == 3) {
|
||||
path = NodePath.create(blockElm, container);
|
||||
clonedBlockElm = blockElm.cloneNode(true);
|
||||
container = NodePath.resolve(clonedBlockElm, path);
|
||||
|
||||
if (isForward) {
|
||||
if (offset >= container.data.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
container.deleteData(offset, 1);
|
||||
} else {
|
||||
if (offset <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
container.deleteData(offset - 1, 1);
|
||||
}
|
||||
|
||||
if (dom.isEmpty(clonedBlockElm)) {
|
||||
return cloneTextBlockWithFormats(blockElm, container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function customDelete(isForward) {
|
||||
var mutationObserver, rng, caretElement;
|
||||
|
||||
@ -28133,6 +28324,11 @@ define("tinymce/util/Quirks", [
|
||||
return;
|
||||
}
|
||||
|
||||
if (handleLastBlockCharacterDelete(isForward, rng)) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore non meta delete in the where there is text before/after the caret
|
||||
if (!isMetaOrCtrl && rng.collapsed && container.nodeType == 3) {
|
||||
if (isForward ? offset < container.data.length : offset > 0) {
|
||||
@ -28152,7 +28348,7 @@ define("tinymce/util/Quirks", [
|
||||
|
||||
// Handle case where text is deleted by typing over
|
||||
editor.on('keypress', function(e) {
|
||||
if (!isDefaultPrevented(e) && !selection.isCollapsed() && e.charCode && !VK.metaKeyPressed(e)) {
|
||||
if (!isDefaultPrevented(e) && !selection.isCollapsed() && e.charCode > 31 && !VK.metaKeyPressed(e)) {
|
||||
var rng, currentFormatNodes, fragmentNode, blockParent, caretNode, charText;
|
||||
|
||||
rng = editor.selection.getRng();
|
||||
@ -31371,11 +31567,14 @@ define("tinymce/Editor", [
|
||||
|
||||
// Keep scripts from executing
|
||||
self.parser.addNodeFilter('script', function(nodes) {
|
||||
var i = nodes.length, node;
|
||||
var i = nodes.length, node, type;
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
node.attr('type', 'mce-' + (node.attr('type') || 'no/type'));
|
||||
type = node.attr('type') || 'no/type';
|
||||
if (type.indexOf('mce-') !== 0) {
|
||||
node.attr('type', 'mce-' + type);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -32178,7 +32377,7 @@ define("tinymce/Editor", [
|
||||
* tinymce.activeEditor.setContent('[b]some[/b] html', {format: 'bbcode'});
|
||||
*/
|
||||
setContent: function(content, args) {
|
||||
var self = this, body = self.getBody(), forcedRootBlockName;
|
||||
var self = this, body = self.getBody(), forcedRootBlockName, padd;
|
||||
|
||||
// Setup args object
|
||||
args = args || {};
|
||||
@ -32196,14 +32395,24 @@ define("tinymce/Editor", [
|
||||
// Padd empty content in Gecko and Safari. Commands will otherwise fail on the content
|
||||
// It will also be impossible to place the caret in the editor unless there is a BR element present
|
||||
if (content.length === 0 || /^\s+$/.test(content)) {
|
||||
padd = ie && ie < 11 ? '' : '<br data-mce-bogus="1">';
|
||||
|
||||
// Todo: There is a lot more root elements that need special padding
|
||||
// so separate this and add all of them at some point.
|
||||
if (body.nodeName == 'TABLE') {
|
||||
content = '<tr><td>' + padd + '</td></tr>';
|
||||
} else if (/^(UL|OL)$/.test(body.nodeName)) {
|
||||
content = '<li>' + padd + '</li>';
|
||||
}
|
||||
|
||||
forcedRootBlockName = self.settings.forced_root_block;
|
||||
|
||||
// Check if forcedRootBlock is configured and that the block is a valid child of the body
|
||||
if (forcedRootBlockName && self.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) {
|
||||
// Padd with bogus BR elements on modern browsers and IE 7 and 8 since they don't render empty P tags properly
|
||||
content = ie && ie < 11 ? '' : '<br data-mce-bogus="1">';
|
||||
content = padd;
|
||||
content = self.dom.createHTML(forcedRootBlockName, self.settings.forced_root_block_attrs, content);
|
||||
} else if (!ie) {
|
||||
} else if (!ie && !content) {
|
||||
// We need to add a BR when forced_root_block is disabled on non IE browsers to place the caret
|
||||
content = '<br data-mce-bogus="1">';
|
||||
}
|
||||
@ -32214,7 +32423,9 @@ define("tinymce/Editor", [
|
||||
} else {
|
||||
// Parse and serialize the html
|
||||
if (args.format !== 'raw') {
|
||||
content = new Serializer({}, self.schema).serialize(
|
||||
content = new Serializer({
|
||||
validate: self.validate
|
||||
}, self.schema).serialize(
|
||||
self.parser.parse(content, {isRootContent: true})
|
||||
);
|
||||
}
|
||||
@ -33146,7 +33357,7 @@ define("tinymce/EditorManager", [
|
||||
* @property minorVersion
|
||||
* @type String
|
||||
*/
|
||||
minorVersion: '2.6',
|
||||
minorVersion: '2.7',
|
||||
|
||||
/**
|
||||
* Release date of TinyMCE build.
|
||||
@ -33154,7 +33365,7 @@ define("tinymce/EditorManager", [
|
||||
* @property releaseDate
|
||||
* @type String
|
||||
*/
|
||||
releaseDate: '2015-09-28',
|
||||
releaseDate: '2015-10-27',
|
||||
|
||||
/**
|
||||
* Collection of editor instances.
|
||||
@ -37558,6 +37769,23 @@ define("tinymce/ui/FormatControls", [
|
||||
|
||||
formatMenu = createFormatMenu();
|
||||
|
||||
function initOnPostRender() {
|
||||
var self = this;
|
||||
|
||||
// TODO: Fix this
|
||||
if (editor.formatter) {
|
||||
editor.formatter.formatChanged(name, function(state) {
|
||||
self.active(state);
|
||||
});
|
||||
} else {
|
||||
editor.on('init', function() {
|
||||
editor.formatter.formatChanged(name, function(state) {
|
||||
self.active(state);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Simple format controls <control/format>:<UI text>
|
||||
each({
|
||||
bold: 'Bold',
|
||||
@ -37570,20 +37798,7 @@ define("tinymce/ui/FormatControls", [
|
||||
editor.addButton(name, {
|
||||
tooltip: text,
|
||||
onPostRender: function() {
|
||||
var self = this;
|
||||
|
||||
// TODO: Fix this
|
||||
if (editor.formatter) {
|
||||
editor.formatter.formatChanged(name, function(state) {
|
||||
self.active(state);
|
||||
});
|
||||
} else {
|
||||
editor.on('init', function() {
|
||||
editor.formatter.formatChanged(name, function(state) {
|
||||
self.active(state);
|
||||
});
|
||||
});
|
||||
}
|
||||
initOnPostRender();
|
||||
},
|
||||
onclick: function() {
|
||||
toggleFormat(name);
|
||||
@ -37627,20 +37842,7 @@ define("tinymce/ui/FormatControls", [
|
||||
tooltip: item[0],
|
||||
cmd: item[1],
|
||||
onPostRender: function() {
|
||||
var self = this;
|
||||
|
||||
// TODO: Fix this
|
||||
if (editor.formatter) {
|
||||
editor.formatter.formatChanged(name, function(state) {
|
||||
self.active(state);
|
||||
});
|
||||
} else {
|
||||
editor.on('init', function() {
|
||||
editor.formatter.formatChanged(name, function(state) {
|
||||
self.active(state);
|
||||
});
|
||||
});
|
||||
}
|
||||
initOnPostRender();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
24
src/wp-includes/js/tinymce/tinymce.min.js
vendored
24
src/wp-includes/js/tinymce/tinymce.min.js
vendored
File diff suppressed because one or more lines are too long
@ -18,7 +18,7 @@ $wp_db_version = 35465;
|
||||
*
|
||||
* @global string $tinymce_version
|
||||
*/
|
||||
$tinymce_version = '4206-20151020';
|
||||
$tinymce_version = '4207-20151107';
|
||||
|
||||
/**
|
||||
* Holds the required PHP version
|
||||
|
@ -47,6 +47,7 @@
|
||||
<script src="tinymce/dom/Selection.js"></script>
|
||||
<script src="tinymce/dom/Serializer.js"></script>
|
||||
<script src="tinymce/dom/TridentSelection.js"></script>
|
||||
<script src="tinymce/dom/NodePath.js"></script>
|
||||
|
||||
<!-- tinymce.html.* -->
|
||||
<script src="tinymce/html/DomParser.js"></script>
|
||||
|
@ -15,7 +15,7 @@ module("tinymce.Editor", {
|
||||
'*': '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',
|
||||
extended_valid_elements: 'custom1,custom2,script[*]',
|
||||
init_instance_callback: function(ed) {
|
||||
window.editor = ed;
|
||||
|
||||
@ -403,6 +403,22 @@ test('addQueryStateHandler', function() {
|
||||
ok(lastScope === editor, "Scope is not editor");
|
||||
});
|
||||
|
||||
test('Block script execution', function() {
|
||||
editor.setContent('<script></script><script type="x"></script><script type="mce-x"></script>');
|
||||
equal(
|
||||
Utils.cleanHtml(editor.getBody().innerHTML),
|
||||
'<script type="mce-no/type"></script>' +
|
||||
'<script type="mce-x"></script>' +
|
||||
'<script type="mce-x"></script>'
|
||||
);
|
||||
equal(
|
||||
editor.getContent(),
|
||||
'<script></script>' +
|
||||
'<script type="x"></script>' +
|
||||
'<script type="x"></script>'
|
||||
);
|
||||
});
|
||||
|
||||
test('addQueryValueHandler', function() {
|
||||
var scope = {}, lastScope, currentValue;
|
||||
|
||||
|
29
tests/qunit/editor/tinymce/dom/NodePath.js
Normal file
29
tests/qunit/editor/tinymce/dom/NodePath.js
Normal file
@ -0,0 +1,29 @@
|
||||
ModuleLoader.require([
|
||||
"tinymce/dom/NodePath"
|
||||
], function(NodePath) {
|
||||
module("tinymce.dom.NodePath", {});
|
||||
|
||||
function getRoot() {
|
||||
return document.getElementById('view');
|
||||
}
|
||||
|
||||
function setupHtml(html) {
|
||||
getRoot().innerHTML = html;
|
||||
}
|
||||
|
||||
test("create", function() {
|
||||
setupHtml('<p>a<b>12<input></b></p>');
|
||||
|
||||
deepEqual(NodePath.create(getRoot(), getRoot().firstChild), [0]);
|
||||
deepEqual(NodePath.create(getRoot(), getRoot().firstChild.firstChild), [0, 0]);
|
||||
deepEqual(NodePath.create(getRoot(), getRoot().firstChild.lastChild.lastChild), [1, 1, 0]);
|
||||
});
|
||||
|
||||
test("resolve", function() {
|
||||
setupHtml('<p>a<b>12<input></b></p>');
|
||||
|
||||
deepEqual(NodePath.resolve(getRoot(), NodePath.create(getRoot(), getRoot().firstChild)), getRoot().firstChild);
|
||||
deepEqual(NodePath.resolve(getRoot(), NodePath.create(getRoot(), getRoot().firstChild.firstChild)), getRoot().firstChild.firstChild);
|
||||
deepEqual(NodePath.resolve(getRoot(), NodePath.create(getRoot(), getRoot().firstChild.lastChild.lastChild)), getRoot().firstChild.lastChild.lastChild);
|
||||
});
|
||||
});
|
@ -20,3 +20,13 @@ test('Sorting of attributes', function() {
|
||||
|
||||
equal(serializer.serialize(new tinymce.html.DomParser().parse('<b class="class" id="id">x</b>')), '<strong id="id" class="class">x</strong>');
|
||||
});
|
||||
|
||||
test('Serialize with validate: true, when parsing with validate:false bug', function() {
|
||||
var schema = new tinymce.html.Schema({valid_elements: 'b'});
|
||||
var serializer = new tinymce.html.Serializer({}, schema);
|
||||
|
||||
equal(
|
||||
serializer.serialize(new tinymce.html.DomParser({validate: false}, schema).parse('<b a="1" b="2">a</b><i a="1" b="2">b</i>')),
|
||||
'<b a="1" b="2">a</b><i a="1" b="2">b</i>'
|
||||
);
|
||||
});
|
||||
|
@ -268,6 +268,48 @@ if (tinymce.isWebKit) {
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p><i>1<b>a</b>3</i></p>');
|
||||
equal(editor.selection.getStart().nodeName, 'B');
|
||||
});
|
||||
|
||||
test('Delete last character in formats', function() {
|
||||
editor.getBody().innerHTML = '<p><b><i>b</i></b></p>';
|
||||
Utils.setSelection('i', 1);
|
||||
editor.fire("keydown", {keyCode: 8});
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p><b><i><br></i></b></p>');
|
||||
equal(editor.selection.getStart(true).nodeName, 'I');
|
||||
});
|
||||
|
||||
test('ForwardDelete last character in formats', function() {
|
||||
editor.getBody().innerHTML = '<p><b><i>b</i></b></p>';
|
||||
Utils.setSelection('i', 0);
|
||||
editor.fire("keydown", {keyCode: 46});
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p><b><i><br></i></b></p>');
|
||||
equal(editor.selection.getStart(true).nodeName, 'I');
|
||||
});
|
||||
|
||||
test('Delete in empty in formats text block', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p>a</p><p><b><i><br></i></b></p><p><b><i><br></i></b></p>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.$('br:last')[0]);
|
||||
rng.setEndBefore(editor.$('br:last')[0]);
|
||||
editor.selection.setRng(rng);
|
||||
editor.fire("keydown", {keyCode: 8});
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p>a</p><p><b><i><br></i></b></p>');
|
||||
equal(editor.selection.getStart(true).nodeName, 'I');
|
||||
});
|
||||
|
||||
test('ForwardDelete in empty formats text block', function() {
|
||||
var rng;
|
||||
|
||||
editor.getBody().innerHTML = '<p>a</p><p><b><i><br></i></b></p><p><b><i><br></i></b></p>';
|
||||
rng = editor.dom.createRng();
|
||||
rng.setStartBefore(editor.$('br:first')[0]);
|
||||
rng.setEndBefore(editor.$('br:first')[0]);
|
||||
editor.selection.setRng(rng);
|
||||
editor.fire("keydown", {keyCode: 46});
|
||||
equal(Utils.cleanHtml(editor.getBody().innerHTML), '<p>a</p><p><b><i><br></i></b></p>');
|
||||
equal(editor.selection.getStart(true).nodeName, 'I');
|
||||
});
|
||||
} else {
|
||||
test("Skipped since the browser isn't WebKit", function() {
|
||||
ok(true, "Skipped");
|
||||
|
Loading…
Reference in New Issue
Block a user