TinyMCE: update to 4.0.28+. Includes all changes until 09-06-2014: 32cb108d41. Changelog: 32cb108d41/changelog.txt.

See #28391.

git-svn-id: https://develop.svn.wordpress.org/trunk@28768 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Ozz
2014-06-17 23:49:00 +00:00
parent f1172ba195
commit b8fd9d997e
42 changed files with 2693 additions and 566 deletions

View File

@@ -40,14 +40,27 @@ tinymce.PluginManager.add('image', function(editor) {
img.src = url;
}
function applyPreview(items) {
tinymce.each(items, function(item) {
item.textStyle = function() {
return editor.formatter.getCssText({inline: 'img', classes: [item.value]});
};
});
function buildListItems(inputList, itemCallback, startItems) {
function appendItems(values, output) {
output = output || [];
return items;
tinymce.each(values, function(item) {
var menuItem = {text: item.text || item.title};
if (item.menu) {
menuItem.menu = appendItems(item.menu);
} else {
menuItem.value = item.value;
itemCallback(menuItem);
}
output.push(menuItem);
});
return output;
}
return appendItems(inputList, startItems || []);
}
function createImageList(callback) {
@@ -71,53 +84,7 @@ tinymce.PluginManager.add('image', function(editor) {
function showDialog(imageList) {
var win, data = {}, dom = editor.dom, imgElm = editor.selection.getNode();
var width, height, imageListCtrl, classListCtrl;
function buildValues(listSettingName, dataItemName, defaultItems) {
var selectedItem, items = [];
tinymce.each(editor.settings[listSettingName] || defaultItems, function(target) {
var item = {
text: target.text || target.title,
value: target.value
};
items.push(item);
if (data[dataItemName] === target.value || (!selectedItem && target.selected)) {
selectedItem = item;
}
});
if (selectedItem && !data[dataItemName]) {
data[dataItemName] = selectedItem.value;
selectedItem.selected = true;
}
return items;
}
function buildImageList() {
function appendItems(values, output) {
output = output || [];
tinymce.each(values, function(value) {
var item = {text: value.text || value.title};
if (value.menu) {
item.menu = appendItems(value.menu);
} else {
item.value = editor.convertURL(value.value || value.url, 'src');
}
output.push(item);
});
return output;
}
return appendItems(imageList, [{text: 'None', value: ''}]);
}
var width, height, imageListCtrl, classListCtrl, imageDimensions = editor.settings.image_dimensions !== false;
function recalcSize() {
var widthCtrl, heightCtrl, newWidth, newHeight;
@@ -125,6 +92,10 @@ tinymce.PluginManager.add('image', function(editor) {
widthCtrl = win.find('#width')[0];
heightCtrl = win.find('#height')[0];
if (!widthCtrl || !heightCtrl) {
return;
}
newWidth = widthCtrl.value();
newHeight = heightCtrl.value();
@@ -146,12 +117,15 @@ tinymce.PluginManager.add('image', function(editor) {
function waitLoad(imgElm) {
function selectImage() {
imgElm.onload = imgElm.onerror = null;
editor.selection.select(imgElm);
editor.nodeChanged();
if (editor.selection) {
editor.selection.select(imgElm);
editor.nodeChanged();
}
}
imgElm.onload = function() {
if (!data.width && !data.height) {
if (!data.width && !data.height && imageDimensions) {
dom.setAttribs(imgElm, {
width: imgElm.clientWidth,
height: imgElm.clientHeight
@@ -188,6 +162,7 @@ tinymce.PluginManager.add('image', function(editor) {
data.style = null;
}
// Setup new data excluding style properties
data = {
src: data.src,
alt: data.alt,
@@ -197,10 +172,6 @@ tinymce.PluginManager.add('image', function(editor) {
"class": data["class"]
};
if (!data["class"]) {
delete data["class"];
}
editor.undoManager.transact(function() {
// WP
var eventData = { node: imgElm, data: data, caption: caption };
@@ -251,7 +222,7 @@ tinymce.PluginManager.add('image', function(editor) {
}
getImageSize(this.value(), function(data) {
if (data.width && data.height) {
if (data.width && data.height && imageDimensions) {
width = data.width;
height = data.height;
@@ -283,7 +254,13 @@ tinymce.PluginManager.add('image', function(editor) {
imageListCtrl = {
type: 'listbox',
label: 'Image list',
values: buildImageList(),
values: buildListItems(
imageList,
function(item) {
item.value = editor.convertURL(item.value || item.url, 'src');
},
[{text: 'None', value: ''}]
),
value: data.src && editor.convertURL(data.src, 'src'),
onselect: function(e) {
var altCtrl = win.find('#alt');
@@ -305,7 +282,16 @@ tinymce.PluginManager.add('image', function(editor) {
name: 'class',
type: 'listbox',
label: 'Class',
values: applyPreview(buildValues('image_class_list', 'class'))
values: buildListItems(
editor.settings.image_class_list,
function(item) {
if (item.value) {
item.textStyle = function() {
return editor.formatter.getCssText({inline: 'img', classes: [item.value]});
};
}
}
)
};
}
@@ -319,7 +305,7 @@ tinymce.PluginManager.add('image', function(editor) {
generalFormItems.push({name: 'alt', type: 'textbox', label: 'Image description'});
}
if (editor.settings.image_dimensions !== false) {
if (imageDimensions) {
generalFormItems.push({
type: 'container',
label: 'Dimensions',
@@ -430,11 +416,6 @@ tinymce.PluginManager.add('image', function(editor) {
}
}
// WP
editor.addCommand( 'mceImage', function() {
createImageList( showDialog )();
});
editor.addButton('image', {
icon: 'image',
tooltip: 'Insert/edit image',
@@ -449,4 +430,6 @@ tinymce.PluginManager.add('image', function(editor) {
context: 'insert',
prependToContext: true
});
editor.addCommand('mceImage', createImageList(showDialog));
});

File diff suppressed because one or more lines are too long

View File

@@ -162,7 +162,23 @@ tinymce.PluginManager.add('media', function(editor, url) {
}
],
onSubmit: function() {
var beforeObjects, afterObjects, i, y;
beforeObjects = editor.dom.select('img[data-mce-object]');
editor.insertContent(dataToHtml(this.toJSON()));
afterObjects = editor.dom.select('img[data-mce-object]');
// Find new image placeholder so we can select it
for (i = 0; i < beforeObjects.length; i++) {
for (y = afterObjects.length - 1; y >= 0; y--) {
if (beforeObjects[i] == afterObjects[y]) {
afterObjects.splice(y, 1);
}
}
}
editor.selection.select(afterObjects[0]);
editor.nodeChanged();
}
});
}
@@ -223,7 +239,7 @@ tinymce.PluginManager.add('media', function(editor, url) {
if (data.embed) {
html = updateHtml(data.embed, data, true);
} else {
} else {
var videoScript = getVideoScriptMatch(data.source1);
if (videoScript) {
data.type = 'script';

File diff suppressed because one or more lines are too long

View File

@@ -361,7 +361,7 @@ define("tinymce/pasteplugin/Clipboard", [
pasteBinElm = dom.add(editor.getBody(), 'div', {
id: "mcepastebin",
contentEditable: true,
"data-mce-bogus": "1",
"data-mce-bogus": "all",
style: 'position: absolute; top: ' + top + 'px;' +
'width: 10px; height: 10px; overflow: hidden; opacity: 0'
}, pasteBinDefaultContent);
@@ -471,42 +471,44 @@ define("tinymce/pasteplugin/Clipboard", [
* Checks if the clipboard contains image data if it does it will take that data
* and convert it into a data url image and paste that image at the caret location.
*
* @param {ClipboardEvent} e Paste event object.
* @param {Object} clipboardContent Collection of clipboard contents.
* @param {ClipboardEvent} e Paste/drop event object.
* @param {DOMRange} rng Optional rng object to move selection to.
* @return {Boolean} true/false if the image data was found or not.
*/
function pasteImageData(e, clipboardContent) {
function pasteImage(item) {
if (items[i].type == 'image/png') {
var reader = new FileReader();
function pasteImageData(e, rng) {
var dataTransfer = e.clipboardData || e.dataTransfer;
reader.onload = function() {
pasteHtml('<img src="' + reader.result + '">');
};
function processItems(items) {
var i, item, reader;
reader.readAsDataURL(item.getAsFile());
function pasteImage() {
if (rng) {
editor.selection.setRng(rng);
rng = null;
}
return true;
pasteHtml('<img src="' + reader.result + '">');
}
}
// If paste data images are disabled or there is HTML or plain text
// contents then proceed with the normal paste process
if (!editor.settings.paste_data_images || "text/html" in clipboardContent || "text/plain" in clipboardContent) {
return;
}
if (e.clipboardData) {
var items = e.clipboardData.items;
if (items) {
for (var i = 0; i < items.length; i++) {
if (pasteImage(items[i])) {
for (i = 0; i < items.length; i++) {
item = items[i];
if (/^image\/(jpeg|png|gif)$/.test(item.type)) {
reader = new FileReader();
reader.onload = pasteImage;
reader.readAsDataURL(item.getAsFile ? item.getAsFile() : item);
e.preventDefault();
return true;
}
}
}
}
if (editor.settings.paste_data_images && dataTransfer) {
return processItems(dataTransfer.items) || processItems(dataTransfer.files);
}
}
/**
@@ -546,6 +548,13 @@ define("tinymce/pasteplugin/Clipboard", [
function registerEventHandlers() {
editor.on('keydown', function(e) {
function removePasteBinOnKeyUp(e) {
// Ctrl+V or Shift+Insert
if (isKeyboardPasteEvent(e) && !e.isDefaultPrevented()) {
removePasteBin();
}
}
// Ctrl+V or Shift+Insert
if (isKeyboardPasteEvent(e) && !e.isDefaultPrevented()) {
keyboardPastePlainTextState = e.shiftKey && e.keyCode == 86;
@@ -571,13 +580,13 @@ define("tinymce/pasteplugin/Clipboard", [
removePasteBin();
createPasteBin();
}
});
editor.on('keyup', function(e) {
// Ctrl+V or Shift+Insert
if (isKeyboardPasteEvent(e) && !e.isDefaultPrevented()) {
removePasteBin();
// Remove pastebin if we get a keyup and no paste event
// For example pasting a file in IE 11 will not produce a paste event
editor.once('keyup', removePasteBinOnKeyUp);
editor.once('paste', function() {
editor.off('keyup', removePasteBinOnKeyUp);
});
}
});
@@ -593,7 +602,7 @@ define("tinymce/pasteplugin/Clipboard", [
return;
}
if (pasteImageData(e, clipboardContent)) {
if (pasteImageData(e)) {
removePasteBin();
return;
}
@@ -683,7 +692,15 @@ define("tinymce/pasteplugin/Clipboard", [
editor.on('drop', function(e) {
var rng = getCaretRangeFromEvent(e);
if (rng && !e.isDefaultPrevented()) {
if (e.isDefaultPrevented()) {
return;
}
if (pasteImageData(e, rng)) {
return;
}
if (rng) {
var dropContent = getDataTransferItems(e.dataTransfer);
var content = dropContent['mce-internal'] || dropContent['text/html'] || dropContent['text/plain'];
@@ -706,6 +723,20 @@ define("tinymce/pasteplugin/Clipboard", [
}
}
});
editor.on('dragover dragend', function(e) {
var i, dataTransfer = e.dataTransfer;
if (editor.settings.paste_data_images && dataTransfer) {
for (i = 0; i < dataTransfer.types.length; i++) {
// Prevent default if we have files dragged into the editor since the pasteImageData handles that
if (dataTransfer.types[i] == "Files") {
e.preventDefault();
return false;
}
}
}
});
}
self.pasteHtml = pasteHtml;
@@ -722,7 +753,10 @@ define("tinymce/pasteplugin/Clipboard", [
while (i--) {
var src = nodes[i].attributes.map.src;
if (src && src.indexOf('data:image') === 0) {
// Some browsers automatically produce data uris on paste
// Safari on Mac produces webkit-fake-url see: https://bugs.webkit.org/show_bug.cgi?id=49141
if (src && /^(data:image|webkit\-fake\-url)/.test(src)) {
if (!nodes[i].attr('data-mce-object') && src !== Env.transparentSrc) {
nodes[i].remove();
}
@@ -731,14 +765,6 @@ define("tinymce/pasteplugin/Clipboard", [
}
});
});
editor.on('BeforeAddUndo', function(e) {
// Remove pastebin HTML incase it should be added to an undo
// level for example when you paste a file on older IE
if (e.level.content) {
e.level.content = e.level.content.replace(/<div id="?mcepastebin"?[^>]+>%MCEPASTEBIN%<\/div>/gi, '');
}
});
};
});

File diff suppressed because one or more lines are too long

View File

@@ -12,6 +12,8 @@
/*eslint consistent-this:0 */
tinymce.PluginManager.add('textcolor', function(editor) {
var VK = tinymce.util.VK;
function mapColors() {
var i, colors = [], colorMap;
@@ -105,6 +107,29 @@ tinymce.PluginManager.add('textcolor', function(editor) {
html += '</tr>';
}
if (editor.settings.textcolor_enable_hex) {
var hexIdN = last + 1;
var hexInputColSpan = cols - 1;
html += (
'<tr>' +
'<td>' +
'<div id="' + ctrl._id + '-' + hexIdN + '"' +
'data-mce-color=""' +
'style="background-color: #FFFFFF"' +
'data-mce-hex-picker="true"' +
'role="option" ' +
'>' +
'</div>' +
'</td>' +
'<td colspan="' + hexInputColSpan + '">' +
'# <input type="text" class="mce-textcolor-hexpicker"' +
'role="textbox" name="mce-hexcolorpicker"' +
'id="' + ctrl._id + '-hexcolorpicker" maxlength="6" >' +
'</td>' +
'</tr>'
);
}
html += '</tbody></table>';
return html;
@@ -112,7 +137,10 @@ tinymce.PluginManager.add('textcolor', function(editor) {
function onPanelClick(e) {
var buttonCtrl = this.parent(), value;
if (e.target.getAttribute('disabled')) {
return;
}
if ((value = e.target.getAttribute('data-mce-color'))) {
if (this.lastId) {
document.getElementById(this.lastId).setAttribute('aria-selected', false);
@@ -136,6 +164,95 @@ tinymce.PluginManager.add('textcolor', function(editor) {
}
}
/**
* isValidHex checks if the provided string is valid hex color string
*
* @param {string} hexString 3 or 6 chars string representing a color.
* @return {Boolean} [true] the string is valid hex color
* [false] the string is not valid hex color
*/
function isValidHex(hexString) {
return /(^[0-9A-F]{3,6}$)/i.test(hexString);
}
/**
* isSpecialStroke checks if the keyCode is currently a special one:
* backspace, delete, arrow keys (left/right)
* or if it's a special ctrl+x/c/v
*
* @param {string} keyCode
* @return {Boolean}
*/
function isSpecialStroke(e) {
var keyCode = e.keyCode;
// Allow delete and backspace
if (keyCode === VK.BACKSPACE || keyCode === VK.DELETE ) {
return true;
}
// Allow arrow movements
if (keyCode === VK.LEFT || keyCode === VK.RIGHT) {
return true;
}
// Allow CTRL/CMD + C/V/X
if ((tinymce.isMac ? e.metaKey : e.ctrlKey) && (keyCode == 67 || keyCode == 88 || keyCode == 86)) {
return true;
}
return false;
}
function initHexPicker(e) {
if (!editor.settings.textcolor_enable_hex) {
return;
}
var wrapper = document.querySelector('#' + e.target._id);
var input = wrapper.querySelector('[name="mce-hexcolorpicker"]');
var hexcolorDiv = wrapper.querySelector('[data-mce-hex-picker]');
var inputEvent = 'input';
editor.dom.events.bind(input, 'keydown', function(e){
var keyCode = e.keyCode;
if (isSpecialStroke(e)) {
return;
}
// Look for anything which is not A-Z or 0-9 and it is not a special char.
if (!((keyCode >= 48 && keyCode <= 57) || (keyCode >= 65 && keyCode <= 70) || (keyCode >= 96 && keyCode <= 105)) ) {
e.preventDefault();
}
// On Enter, take it like a click on the hexcolorDiv
if ( (keyCode === VK.ENTER && isValidHex(input.value) ) ) {
hexcolorDiv.click();
}
});
// If IE8 we can't use the input event, so we have to
// listen for keypress and paste events.
// In IE9 the input implementation is buggy so
// we use the same events as we'd like on IE8
if (tinymce.Env.ie && tinymce.Env.ie <= 9) {
inputEvent = 'keypress paste blur keydown keyup propertychange';
}
editor.dom.events.bind(input, inputEvent, function(){
if (isValidHex(input.value)) {
hexcolorDiv.setAttribute('data-mce-color', input.value);
hexcolorDiv.setAttribute('style', 'background-color:#' + input.value);
hexcolorDiv.removeAttribute('disabled');
} else {
hexcolorDiv.setAttribute('disabled', 'disabled');
}
});
}
editor.addButton('forecolor', {
type: 'colorbutton',
tooltip: 'Text color',
@@ -144,7 +261,8 @@ tinymce.PluginManager.add('textcolor', function(editor) {
role: 'application',
ariaRemember: true,
html: renderColorPicker,
onclick: onPanelClick
onclick: onPanelClick,
onPostRender: initHexPicker
},
onclick: onButtonClick
});
@@ -157,7 +275,8 @@ tinymce.PluginManager.add('textcolor', function(editor) {
role: 'application',
ariaRemember: true,
html: renderColorPicker,
onclick: onPanelClick
onclick: onPanelClick,
onPostRender: initHexPicker
},
onclick: onButtonClick
});

View File

@@ -1 +1 @@
tinymce.PluginManager.add("textcolor",function(e){function t(){var t,o,l=[];for(o=e.settings.textcolor_map||["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Red violet","C0C0C0","Silver","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum","FFFFFF","White"],t=0;t<o.length;t+=2)l.push({text:o[t+1],color:o[t]});return l}function o(){var o,l,r,a,c,i,n,F,d,s=this;for(o=t(),r='<table class="mce-grid mce-grid-border mce-colorbutton-grid" role="list" cellspacing="0"><tbody>',a=o.length-1,c=e.settings.textcolor_rows||5,i=e.settings.textcolor_cols||8,F=0;c>F;F++){for(r+="<tr>",n=0;i>n;n++)d=F*i+n,d>a?r+="<td></td>":(l=o[d],r+='<td><div id="'+s._id+"-"+d+'" data-mce-color="'+l.color+'" role="option" tabIndex="-1" style="'+(l?"background-color: #"+l.color:"")+'" title="'+l.text+'"></div></td>');r+="</tr>"}return r+="</tbody></table>"}function l(t){var o,l=this.parent();(o=t.target.getAttribute("data-mce-color"))&&(this.lastId&&document.getElementById(this.lastId).setAttribute("aria-selected",!1),t.target.setAttribute("aria-selected",!0),this.lastId=t.target.id,l.hidePanel(),o="#"+o,l.color(o),e.execCommand(l.settings.selectcmd,!1,o))}function r(){var t=this;t._color&&e.execCommand(t.settings.selectcmd,!1,t._color)}e.addButton("forecolor",{type:"colorbutton",tooltip:"Text color",selectcmd:"ForeColor",panel:{role:"application",ariaRemember:!0,html:o,onclick:l},onclick:r}),e.addButton("backcolor",{type:"colorbutton",tooltip:"Background color",selectcmd:"HiliteColor",panel:{role:"application",ariaRemember:!0,html:o,onclick:l},onclick:r})});
tinymce.PluginManager.add("textcolor",function(e){function t(){var t,o,r=[];for(o=e.settings.textcolor_map||["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Red violet","C0C0C0","Silver","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum","FFFFFF","White"],t=0;t<o.length;t+=2)r.push({text:o[t+1],color:o[t]});return r}function o(){var o,r,l,c,i,a,n,d,s,u=this;for(o=t(),l='<table class="mce-grid mce-grid-border mce-colorbutton-grid" role="list" cellspacing="0"><tbody>',c=o.length-1,i=e.settings.textcolor_rows||5,a=e.settings.textcolor_cols||8,d=0;i>d;d++){for(l+="<tr>",n=0;a>n;n++)s=d*a+n,s>c?l+="<td></td>":(r=o[s],l+='<td><div id="'+u._id+"-"+s+'" data-mce-color="'+r.color+'" role="option" tabIndex="-1" style="'+(r?"background-color: #"+r.color:"")+'" title="'+r.text+'"></div></td>');l+="</tr>"}if(e.settings.textcolor_enable_hex){var F=c+1,m=a-1;l+='<tr><td><div id="'+u._id+"-"+F+'"data-mce-color=""style="background-color: #FFFFFF"data-mce-hex-picker="true"role="option" ></div></td><td colspan="'+m+'"># <input type="text" class="mce-textcolor-hexpicker"role="textbox" name="mce-hexcolorpicker"id="'+u._id+'-hexcolorpicker" maxlength="6" ></td></tr>'}return l+="</tbody></table>"}function r(t){var o,r=this.parent();t.target.getAttribute("disabled")||(o=t.target.getAttribute("data-mce-color"))&&(this.lastId&&document.getElementById(this.lastId).setAttribute("aria-selected",!1),t.target.setAttribute("aria-selected",!0),this.lastId=t.target.id,r.hidePanel(),o="#"+o,r.color(o),e.execCommand(r.settings.selectcmd,!1,o))}function l(){var t=this;t._color&&e.execCommand(t.settings.selectcmd,!1,t._color)}function c(e){return/(^[0-9A-F]{3,6}$)/i.test(e)}function i(e){var t=e.keyCode;return t===n.BACKSPACE||t===n.DELETE?!0:t===n.LEFT||t===n.RIGHT?!0:(tinymce.isMac?e.metaKey:e.ctrlKey)&&(67==t||88==t||86==t)?!0:!1}function a(t){if(e.settings.textcolor_enable_hex){var o=document.querySelector("#"+t.target._id),r=o.querySelector('[name="mce-hexcolorpicker"]'),l=o.querySelector("[data-mce-hex-picker]"),a="input";e.dom.events.bind(r,"keydown",function(e){var t=e.keyCode;i(e)||(t>=48&&57>=t||t>=65&&70>=t||t>=96&&105>=t||e.preventDefault(),t===n.ENTER&&c(r.value)&&l.click())}),tinymce.Env.ie&&tinymce.Env.ie<=9&&(a="keypress paste blur keydown keyup propertychange"),e.dom.events.bind(r,a,function(){c(r.value)?(l.setAttribute("data-mce-color",r.value),l.setAttribute("style","background-color:#"+r.value),l.removeAttribute("disabled")):l.setAttribute("disabled","disabled")})}}var n=tinymce.util.VK;e.addButton("forecolor",{type:"colorbutton",tooltip:"Text color",selectcmd:"ForeColor",panel:{role:"application",ariaRemember:!0,html:o,onclick:r,onPostRender:a},onclick:l}),e.addButton("backcolor",{type:"colorbutton",tooltip:"Background color",selectcmd:"HiliteColor",panel:{role:"application",ariaRemember:!0,html:o,onclick:r,onPostRender:a},onclick:l})});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -6154,7 +6154,7 @@ define("tinymce/dom/DOMUtils", [
outHtml += '<' + name;
for (key in attrs) {
if (attrs.hasOwnProperty(key) && attrs[key] !== null) {
if (attrs.hasOwnProperty(key) && attrs[key] !== null && typeof attrs[key] != 'undefined') {
outHtml += ' ' + key + '="' + this.encode(attrs[key]) + '"';
}
}
@@ -6390,70 +6390,72 @@ define("tinymce/dom/DOMUtils", [
* // Sets class attribute on a specific element in the current page
* tinymce.dom.setAttrib('mydiv', 'class', 'myclass');
*/
setAttrib: function(e, n, v) {
setAttrib: function(elm, name, value) {
var self = this;
// What's the point
if (!e || !n) {
if (!elm || !name) {
return;
}
return this.run(e, function(e) {
var s = self.settings;
var originalValue = e.getAttribute(n);
if (v !== null) {
switch (n) {
return this.run(elm, function(elm) {
var settings = self.settings;
var originalValue = elm.getAttribute(name);
if (value !== null) {
switch (name) {
case "style":
if (!is(v, 'string')) {
each(v, function(v, n) {
self.setStyle(e, n, v);
if (!is(value, 'string')) {
each(value, function(value, name) {
self.setStyle(elm, name, value);
});
return;
}
// No mce_style for elements with these since they might get resized by the user
if (s.keep_values) {
if (v) {
e.setAttribute('data-mce-style', v, 2);
if (settings.keep_values) {
if (value) {
elm.setAttribute('data-mce-style', value, 2);
} else {
e.removeAttribute('data-mce-style', 2);
elm.removeAttribute('data-mce-style', 2);
}
}
e.style.cssText = v;
elm.style.cssText = value;
break;
case "class":
e.className = v || ''; // Fix IE null bug
elm.className = value || ''; // Fix IE null bug
break;
case "src":
case "href":
if (s.keep_values) {
if (s.url_converter) {
v = s.url_converter.call(s.url_converter_scope || self, v, n, e);
if (settings.keep_values) {
if (settings.url_converter) {
value = settings.url_converter.call(settings.url_converter_scope || self, value, name, elm);
}
self.setAttrib(e, 'data-mce-' + n, v, 2);
self.setAttrib(elm, 'data-mce-' + name, value, 2);
}
break;
case "shape":
e.setAttribute('data-mce-style', v);
elm.setAttribute('data-mce-style', value);
break;
}
}
if (is(v) && v !== null && v.length !== 0) {
e.setAttribute(n, '' + v, 2);
if (is(value) && value !== null && value.length !== 0) {
elm.setAttribute(name, '' + value, 2);
} else {
e.removeAttribute(n, 2);
elm.removeAttribute(name, 2);
}
// fire onChangeAttrib event for attributes that have changed
if (originalValue != v && s.onSetAttrib) {
s.onSetAttrib({attrElm: e, attrName: n, attrValue: v});
if (originalValue != value && settings.onSetAttrib) {
settings.onSetAttrib({attrElm: elm, attrName: name, attrValue: value});
}
});
},
@@ -9828,15 +9830,24 @@ define("tinymce/html/SaxParser", [
/**
* Returns the index of the end tag for a specific start tag. This can be
* used to skip all children of a parent element from being processed.
*
* @private
* @method findEndTag
* @param {tinymce.html.Schema} schema Schema instance to use to match short ended elements.
* @param {String} html HTML string to find the end tag in.
* @param {Number} startIndex Indext to start searching at should be after the start tag.
* @return {Number} Index of the end tag.
*/
function skipUntilEndTag(schema, html, startIndex) {
var count = 1, matches, tokenRegExp, shortEndedElements;
function findEndTag(schema, html, startIndex) {
var count = 1, index, matches, tokenRegExp, shortEndedElements;
shortEndedElements = schema.getShortEndedElements();
tokenRegExp = /<([!?\/])?([A-Za-z0-9\-\:\.]+)((?:\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\/|\s+)>/g;
tokenRegExp.lastIndex = startIndex;
tokenRegExp.lastIndex = index = startIndex;
while ((matches = tokenRegExp.exec(html))) {
index = tokenRegExp.lastIndex;
if (matches[1] === '/') { // End element
count--;
} else if (!matches[1]) { // Start element
@@ -9852,7 +9863,7 @@ define("tinymce/html/SaxParser", [
}
}
return tokenRegExp.lastIndex;
return index;
}
/**
@@ -9863,7 +9874,7 @@ define("tinymce/html/SaxParser", [
* @param {Object} settings Name/value collection of settings. comment, cdata, text, start and end are callbacks.
* @param {tinymce.html.Schema} schema HTML Schema class to use when parsing.
*/
return function(settings, schema) {
function SaxParser(settings, schema) {
var self = this;
function noop() {}
@@ -10138,7 +10149,7 @@ define("tinymce/html/SaxParser", [
// Invalidate element if it's marked as bogus
if ((attr = attrList.map['data-mce-bogus'])) {
if (attr === 'all') {
index = skipUntilEndTag(schema, html, tokenRegExp.lastIndex);
index = findEndTag(schema, html, tokenRegExp.lastIndex);
tokenRegExp.lastIndex = index;
continue;
}
@@ -10225,7 +10236,11 @@ define("tinymce/html/SaxParser", [
}
}
};
};
}
SaxParser.findEndTag = findEndTag;
return SaxParser;
});
// Included from: js/tinymce/classes/html/DomParser.js
@@ -11490,8 +11505,12 @@ define("tinymce/dom/Serializer", [
while (i--) {
node = nodes[i];
value = node.attr('class').replace(/(?:^|\s)mce-item-\w+(?!\S)/g, '');
node.attr('class', value.length > 0 ? value : null);
value = node.attr('class');
if (value) {
value = node.attr('class').replace(/(?:^|\s)mce-item-\w+(?!\S)/g, '');
node.attr('class', value.length > 0 ? value : null);
}
}
});
@@ -12423,6 +12442,7 @@ define("tinymce/dom/ControlSelection", [
'margin: 5px 10px;' +
'padding: 5px;' +
'position: absolute;' +
'z-index: 10001' +
'}'
);
@@ -12463,7 +12483,7 @@ define("tinymce/dom/ControlSelection", [
if (selectedElm.nodeName == "IMG" && editor.settings.resize_img_proportional !== false) {
proportional = !VK.modifierPressed(e);
} else {
proportional = VK.modifierPressed(e) || selectedHandle[2] * selectedHandle[3] !== 0;
proportional = VK.modifierPressed(e) || (selectedElm.nodeName == "IMG" && selectedHandle[2] * selectedHandle[3] !== 0);
}
// Constrain proportions
@@ -12604,6 +12624,7 @@ define("tinymce/dom/ControlSelection", [
selectedElmGhost = selectedElm.cloneNode(true);
dom.addClass(selectedElmGhost, 'mce-clonedresizable');
dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all');
selectedElmGhost.contentEditable = false; // Hides IE move layer cursor
selectedElmGhost.unSelectabe = true;
dom.setStyles(selectedElmGhost, {
@@ -12645,7 +12666,7 @@ define("tinymce/dom/ControlSelection", [
handleElm = dom.add(handlerContainerElm, 'div', {
id: 'mceResizeHandle' + name,
'data-mce-bogus': true,
'data-mce-bogus': 'all',
'class': 'mce-resizehandle',
unselectable: true,
style: 'cursor:' + name + '-resize; margin:0; padding:0'
@@ -17154,7 +17175,16 @@ define("tinymce/Formatter", [
child = findFirstTextNode(node);
if (child.nodeValue.charAt(0) === INVISIBLE_CHAR) {
child = child.deleteData(0, 1);
child.deleteData(0, 1);
// Fix for bug #6976
if (rng.startContainer == child) {
rng.startOffset--;
}
if (rng.endContainer == child) {
rng.endOffset--;
}
}
dom.remove(node, 1);
@@ -17424,22 +17454,52 @@ define("tinymce/Formatter", [
*/
define("tinymce/UndoManager", [
"tinymce/Env",
"tinymce/util/Tools"
], function(Env, Tools) {
"tinymce/util/Tools",
"tinymce/html/SaxParser"
], function(Env, Tools, SaxParser) {
var trim = Tools.trim, trimContentRegExp;
trimContentRegExp = new RegExp([
'<span[^>]+data-mce-bogus[^>]+>[\u200B\uFEFF]+<\\/span>', // Trim bogus spans like caret containers
'<div[^>]+data-mce-bogus[^>]+>[^>]*<\\/div>', // Trim bogus divs like resize handles/resize helper
'\\s?data-mce-selected="[^"]+"' // Trim temporaty data-mce prefixed attributes like data-mce-selected
].join('|'), 'gi');
return function(editor) {
var self = this, index = 0, data = [], beforeBookmark, isFirstTypedCharacter, locks = 0;
// Returns a trimmed version of the current editor contents
/**
* Returns a trimmed version of the editor contents to be used for the undo level. This
* will remove any data-mce-bogus="all" marked elements since these are used for UI it will also
* remove the data-mce-selected attributes used for selection of objects and caret containers.
* It will keep all data-mce-bogus="1" elements since these can be used to place the caret etc and will
* be removed by the serialization logic when you save.
*
* @return {String} HTML contents of the editor excluding some internal bogus elements.
*/
function getContent() {
return trim(editor.getContent({format: 'raw', no_events: 1}).replace(trimContentRegExp, ''));
var content = trim(editor.getContent({format: 'raw', no_events: 1}));
var bogusAllRegExp = /<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g;
var endTagIndex, index, matchLength, matches, shortEndedElements, schema = editor.schema;
content = content.replace(trimContentRegExp, '');
shortEndedElements = schema.getShortEndedElements();
// Remove all bogus elements marked with "all"
while ((matches = bogusAllRegExp.exec(content))) {
index = bogusAllRegExp.lastIndex;
matchLength = matches[0].length;
if (shortEndedElements[matches[1]]) {
endTagIndex = index;
} else {
endTagIndex = SaxParser.findEndTag(schema, content, index);
}
content = content.substring(0, index - matchLength) + content.substring(endTagIndex);
bogusAllRegExp.lastIndex = index - matchLength;
}
return content;
}
function addNonTypingUndoLevel(e) {
@@ -17538,12 +17598,44 @@ define("tinymce/UndoManager", [
editor.addShortcut('ctrl+z', '', 'Undo');
editor.addShortcut('ctrl+y,ctrl+shift+z', '', 'Redo');
editor.on('AddUndo Undo Redo ClearUndos MouseUp', function(e) {
editor.on('AddUndo Undo Redo ClearUndos', function(e) {
if (!e.isDefaultPrevented()) {
editor.nodeChanged();
}
});
// Selection range isn't updated until after the click events default handler is executed
// so we need to wait for the selection to update on Gecko/WebKit it happens right away.
// On IE it might take a while so we listen for the SelectionChange event.
//
// We can't use the SelectionChange on all browsers event since Gecko doesn't support that.
if (Env.ie) {
editor.on('MouseUp', function(e) {
if (!e.isDefaultPrevented()) {
editor.once('SelectionChange', function() {
// Selection change might fire when focus is lost
if (editor.dom.isChildOf(editor.selection.getStart(), editor.getBody())) {
editor.nodeChanged();
}
});
editor.nodeChanged();
}
});
} else {
editor.on('MouseUp', function() {
editor.nodeChanged();
});
editor.on('Click', function(e) {
if (!e.isDefaultPrevented()) {
setTimeout(function() {
editor.nodeChanged();
}, 0);
}
});
}
self = {
// Explose for debugging reasons
data: data,
@@ -18176,56 +18268,9 @@ define("tinymce/EnterKey", [
undoManager.add();
}
// Walks the parent block to the right and look for BR elements
function hasRightSideContent() {
var walker = new TreeWalker(container, parentBlock), node;
while ((node = walker.next())) {
if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) {
return true;
}
}
}
// Inserts a BR element if the forced_root_block option is set to false or empty string
function insertBr() {
var brElm, extraBr, marker;
if (container && container.nodeType == 3 && offset >= container.nodeValue.length) {
// Insert extra BR element at the end block elements
if (!isIE && !hasRightSideContent()) {
brElm = dom.create('br');
rng.insertNode(brElm);
rng.setStartAfter(brElm);
rng.setEndAfter(brElm);
extraBr = true;
}
}
brElm = dom.create('br');
rng.insertNode(brElm);
// Rendering modes below IE8 doesn't display BR elements in PRE unless we have a \n before it
if (isIE && parentBlockName == 'PRE' && (!documentMode || documentMode < 8)) {
brElm.parentNode.insertBefore(dom.doc.createTextNode('\r'), brElm);
}
// Insert temp marker and scroll to that
marker = dom.create('span', {}, '&nbsp;');
brElm.parentNode.insertBefore(marker, brElm);
selection.scrollIntoView(marker);
dom.remove(marker);
if (!extraBr) {
rng.setStartAfter(brElm);
rng.setEndAfter(brElm);
} else {
rng.setStartBefore(brElm);
rng.setEndBefore(brElm);
}
selection.setRng(rng);
undoManager.add();
editor.execCommand("InsertLineBreak", false, evt);
}
// Trims any linebreaks at the beginning of node user for example when pressing enter in a PRE element
@@ -18593,12 +18638,14 @@ define("tinymce/EditorCommands", [
"tinymce/html/Serializer",
"tinymce/Env",
"tinymce/util/Tools",
"tinymce/dom/ElementUtils"
], function(Serializer, Env, Tools, ElementUtils) {
"tinymce/dom/ElementUtils",
"tinymce/dom/RangeUtils",
"tinymce/dom/TreeWalker"
], function(Serializer, Env, Tools, ElementUtils, RangeUtils, TreeWalker) {
// Added for compression purposes
var each = Tools.each, extend = Tools.extend;
var map = Tools.map, inArray = Tools.inArray, explode = Tools.explode;
var isGecko = Env.gecko, isIE = Env.ie;
var isGecko = Env.gecko, isIE = Env.ie, isOldIE = Env.ie && Env.ie < 11;
var TRUE = true, FALSE = false;
return function(editor) {
@@ -19248,6 +19295,93 @@ define("tinymce/EditorCommands", [
mceNewDocument: function() {
editor.setContent('');
},
"InsertLineBreak": function (command, ui, value) {
// We load the current event in from EnterKey.js when appropriate to heed
// certain event-specific variations such as ctrl-enter in a list
var evt = value;
var brElm, extraBr, marker;
var rng = selection.getRng(true);
new RangeUtils(dom).normalize(rng);
var offset = rng.startOffset;
var container = rng.startContainer;
// Resolve node index
if (container.nodeType == 1 && container.hasChildNodes()) {
var isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
if (isAfterLastNodeInContainer && container.nodeType == 3) {
offset = container.nodeValue.length;
} else {
offset = 0;
}
}
var parentBlock = dom.getParent(container, dom.isBlock);
var parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5
var containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5
// Enter inside block contained within a LI then split or insert before/after LI
var isControlKey = evt && evt.ctrlKey;
if (containerBlockName == 'LI' && !isControlKey) {
parentBlock = containerBlock;
parentBlockName = containerBlockName;
}
// Walks the parent block to the right and look for BR elements
function hasRightSideContent() {
var walker = new TreeWalker(container, parentBlock), node;
var nonEmptyElementsMap = editor.schema.getNonEmptyElements();
while ((node = walker.next())) {
if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) {
return true;
}
}
}
if (container && container.nodeType == 3 && offset >= container.nodeValue.length) {
// Insert extra BR element at the end block elements
if (!isOldIE && !hasRightSideContent()) {
brElm = dom.create('br');
rng.insertNode(brElm);
rng.setStartAfter(brElm);
rng.setEndAfter(brElm);
extraBr = true;
}
}
brElm = dom.create('br');
rng.insertNode(brElm);
// Rendering modes below IE8 doesn't display BR elements in PRE unless we have a \n before it
var documentMode = dom.doc.documentMode;
if (isOldIE && parentBlockName == 'PRE' && (!documentMode || documentMode < 8)) {
brElm.parentNode.insertBefore(dom.doc.createTextNode('\r'), brElm);
}
// Insert temp marker and scroll to that
marker = dom.create('span', {}, '&nbsp;');
brElm.parentNode.insertBefore(marker, brElm);
selection.scrollIntoView(marker);
dom.remove(marker);
if (!extraBr) {
rng.setStartAfter(brElm);
rng.setEndAfter(brElm);
} else {
rng.setStartBefore(brElm);
rng.setEndBefore(brElm);
}
selection.setRng(rng);
editor.undoManager.add();
return TRUE;
}
});
@@ -20000,6 +20134,11 @@ define("tinymce/util/EventDispatcher", [
for (i = 0, l = handlers.length; i < l; i++) {
handlers[i] = callback = handlers[i];
// Unbind handlers marked with "once"
if (callback.once) {
off(name, callback);
}
// Stop immediate propagation if needed
if (args.isImmediatePropagationStopped()) {
args.stopPropagation();
@@ -20105,7 +20244,8 @@ define("tinymce/util/EventDispatcher", [
hi = handlers.length;
while (hi--) {
if (handlers[hi] === callback) {
handlers.splice(hi, 1);
handlers = handlers.slice(0, hi).concat(handlers.slice(hi + 1));
bindings[name] = handlers;
}
}
}
@@ -20127,6 +20267,25 @@ define("tinymce/util/EventDispatcher", [
return self;
}
/**
* Binds an event listener to a specific event by name
* and automatically unbind the event once the callback fires.
*
* @method once
* @param {String} name Event name or space separated list of events to bind.
* @param {callback} callback Callback to be executed when the event occurs.
* @param {Boolean} first Optional flag if the event should be prepended. Use this with care.
* @return {Object} Current class instance.
* @example
* instance.once('event', function(e) {
* // Callback logic
* });
*/
function once(name, callback, prepend) {
callback.once = true;
return on(name, callback, prepend);
}
/**
* Returns true/false if the dispatcher has a event of the specified name.
*
@@ -20143,6 +20302,7 @@ define("tinymce/util/EventDispatcher", [
self.fire = fire;
self.on = on;
self.off = off;
self.once = once;
self.has = has;
}
@@ -25855,6 +26015,11 @@ define("tinymce/util/Quirks", [
function removeHrOnBackspace() {
editor.on('keydown', function(e) {
if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
// Check if there is any HR elements this is faster since getRng on IE 7 & 8 is slow
if (!editor.getBody().getElementsByTagName('hr').length) {
return;
}
if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
var node = selection.getNode();
var previousSibling = node.previousSibling;
@@ -26548,7 +26713,6 @@ define("tinymce/util/Quirks", [
}
// All browsers
disableBackspaceIntoATable();
removeBlockQuoteOnBackSpace();
emptyEditorWhenDeleting();
normalizeSelection();
@@ -26560,6 +26724,7 @@ define("tinymce/util/Quirks", [
selectControlElements();
setDefaultBlockType();
blockFormSubmitInsideEditor();
disableBackspaceIntoATable();
// iOS
if (Env.iOS) {
@@ -26587,6 +26752,7 @@ define("tinymce/util/Quirks", [
if (Env.ie >= 11) {
bodyHeight();
doubleTrailingBrElements();
disableBackspaceIntoATable();
}
if (Env.ie) {
@@ -26604,6 +26770,7 @@ define("tinymce/util/Quirks", [
removeGhostSelection();
showBrokenImageIcon();
blockCmdArrowNavigation();
disableBackspaceIntoATable();
}
};
});
@@ -26715,6 +26882,18 @@ define("tinymce/util/Observable", [
return getEventDispatcher(this).off(name, callback);
},
/**
* Bind the event callback and once it fires the callback is removed.
*
* @method once
* @param {String} name Name of the event to bind.
* @param {callback} callback Callback to bind only once.
* @return {Object} Current class instance.
*/
once: function(name, callback) {
return getEventDispatcher(this).once(name, callback);
},
/**
* Returns true/false if the object has a event of the specified name.
*
@@ -26760,7 +26939,7 @@ define("tinymce/EditorObservable", [
// Need to bind mousedown/mouseup etc to document not body in iframe mode
// Since the user might click on the HTML element not the BODY
if (!editor.inline && /^mouse|click|contextmenu|drop/.test(eventName)) {
if (!editor.inline && /^mouse|click|contextmenu|drop|dragover|dragend/.test(eventName)) {
return editor.getDoc();
}
@@ -28150,8 +28329,9 @@ define("tinymce/Editor", [
* need to update the UI states or element path etc.
*
* @method nodeChanged
* @param {Object} args Optional args to pass to NodeChange event handlers.
*/
nodeChanged: function() {
nodeChanged: function(args) {
var self = this, selection = self.selection, node, parents, root;
// Fix for bug #1896577 it seems that this can not be fired while the editor is loading
@@ -28176,7 +28356,11 @@ define("tinymce/Editor", [
parents.push(node);
});
self.fire('NodeChange', {element: node, parents: parents});
args = args || {};
args.element = node;
args.parents = parents;
self.fire('NodeChange', args);
}
},
@@ -29022,8 +29206,8 @@ define("tinymce/Editor", [
var self = this;
if (!self.removed) {
self.removed = 1;
self.save();
self.removed = 1;
// Remove any hidden input
if (self.hasHiddenInput) {
@@ -29620,9 +29804,9 @@ define("tinymce/EditorManager", [
// Get base URL for the current document
documentBaseURL = document.location.href;
// Check if the URL is a document based format like: http://site/dir/file
// Check if the URL is a document based format like: http://site/dir/file and file:///
// leave other formats like applewebdata://... intact
if (/^[^:]+:\/\/[^\/]+\//.test(documentBaseURL)) {
if (/^[^:]+:\/\/\/?[^\/]+\//.test(documentBaseURL)) {
documentBaseURL = documentBaseURL.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
if (!/[\/\\]$/.test(documentBaseURL)) {
@@ -30246,6 +30430,9 @@ define("tinymce/util/XHR", [], function() {
xhr.open(settings.type || (settings.data ? 'POST' : 'GET'), settings.url, settings.async);
if (settings.crossDomain) {
xhr.withCredentials = true;
}
if (settings.content_type) {
xhr.setRequestHeader('Content-Type', settings.content_type);
}
@@ -34484,7 +34671,9 @@ define("tinymce/ui/ListBox", [
self._values = values = settings.values;
if (values) {
setSelected(values);
if (typeof settings.value != "undefined") {
setSelected(values);
}
// Default with first item
if (!selected && values.length > 0) {

File diff suppressed because one or more lines are too long

View File

@@ -18,7 +18,7 @@ $wp_db_version = 27916;
*
* @global string $tinymce_version
*/
$tinymce_version = '4028-20140528';
$tinymce_version = '4028-20140617';
/**
* Holds the required PHP version