Browse Source

Added 4.1.4 release

pull/6/head 4.1.4
Spocke 11 years ago
parent
commit
8734ce39ab
  1. 2
      bower.json
  2. 21
      changelog.txt
  3. 2
      composer.json
  4. 2
      package.json
  5. 52
      plugins/media/plugin.js
  6. 2
      plugins/media/plugin.min.js
  7. 6
      plugins/paste/plugin.js
  8. 2
      plugins/paste/plugin.min.js
  9. 5
      plugins/spellchecker/plugin.js
  10. 2
      plugins/spellchecker/plugin.min.js
  11. 20
      plugins/table/plugin.js
  12. 2
      plugins/table/plugin.min.js
  13. 178
      tinymce.jquery.js
  14. 20
      tinymce.jquery.min.js
  15. 178
      tinymce.js
  16. 18
      tinymce.min.js

2
bower.json

@ -1,6 +1,6 @@
{
"name": "tinymce",
"version": "4.1.3",
"version": "4.1.4",
"description": "Web based JavaScript HTML WYSIWYG editor control.",
"license": "http://www.tinymce.com/license",
"keywords": [

21
changelog.txt

@ -1,3 +1,22 @@
Version 4.1.4 (2014-08-21)
Added new media_filter_html option to media plugin that blocks any conditional comments, scripts etc within a video element.
Added new content_security_policy option allows you to set custom policy for iframe contents. Patch contributed by Francois Chagnon.
Fixed bug where activate/deactivate events wasn't firing properly when switching between editors.
Fixed bug where placing the caret on iOS was difficult due to a WebKit bug with touch events.
Fixed bug where the resize helper wouldn't render properly on older IE versions.
Fixed bug where resizing images inside tables on older IE versions would sometimes fail depending mouse position.
Fixed bug where editor.insertContent would produce an exception when inserting select/option elements.
Fixed bug where extra empty paragraphs would be produced if block elements where inserted inside span elements.
Fixed bug where the spellchecker menu item wouldn't be properly checked if spell checking was started before it was rendered.
Fixed bug where the DomQuery filter function wouldn't remove non elements from collection.
Fixed bug where document with custom document.domain wouldn't properly render the editor.
Fixed bug where IE 8 would throw exception when trying to enter invalid color values into colorboxes.
Fixed bug where undo manager could incorrectly add an extra undo level when custom resize handles was removed.
Fixed bug where it wouldn't be possible to alter cell properties properly on table cells on IE 8.
Fixed so the color picker button in table dialog isn't shown unless you include the colorpicker plugin or add your own custom color picker.
Fixed so activate/deactivate events fire when windowManager opens a window since.
Fixed so the table advtab options isn't separated by an underscore to normalize naming with image_advtab option.
Fixed so the table cell dialog has proper padding when the advanced tab in disabled.
Version 4.1.3 (2014-07-29)
Added event binding logic to tinymce.util.XHR making it possible to override headers and settings before any request is made.
Fixed bug where drag events wasn't fireing properly on older IE versions since the event handlers where bound to document.
@ -243,7 +262,7 @@ Version 4.0.17 (2014-02-26)
Fixed bug where older IE versions would fire focus/blur events even though the editor focus didn't change.
Fixed bug where IE 11 would add two trailing BR elements to the editor iframe body if the editor was hidden.
Fixed bug where the visualchars plugin wouldn't display non breaking spaces if they where inserted while the state was enabled.
Fixed bug where the wordcount plugin would be very slow some HTML where to much backtracking occured.
Fixed bug where the wordcount plugin would be very slow some HTML where to much backtracking occurred.
Fixed so pagebreak elements in the editor breaks pages when printing. Patch contributed by penc.
Fixed so UndoManager events pass though the original event that created the undo level such as a keydown, blur etc.
Fixed so the inserttime button is callsed insertdatetime the same as the menu item and plugin name.

2
composer.json

@ -1,6 +1,6 @@
{
"name": "tinymce/tinymce",
"version": "4.1.3",
"version": "4.1.4",
"description": "Web based JavaScript HTML WYSIWYG editor control.",
"license": [
"LGPL-2.1"

2
package.json

@ -1,6 +1,6 @@
{
"name": "tinymce",
"version": "4.1.3",
"version": "4.1.4",
"description": "Web based JavaScript HTML WYSIWYG editor control.",
"license": "LGPL-2.1",
"keywords": [

52
plugins/media/plugin.js

@ -381,6 +381,56 @@ tinymce.PluginManager.add('media', function(editor, url) {
return {};
}
function sanitize(html) {
if (editor.settings.media_filter_html === false) {
return html;
}
var writer = new tinymce.html.Writer();
new tinymce.html.SaxParser({
validate: false,
allow_conditional_comments: false,
special: 'script,noscript',
comment: function(text) {
writer.comment(text);
},
cdata: function(text) {
writer.cdata(text);
},
text: function(text, raw) {
writer.text(text, raw);
},
start: function(name, attrs, empty) {
if (name == 'script' || name == 'noscript') {
return;
}
for (var i = 0; i < attrs.length; i++) {
if (attrs[i].name.indexOf('on') === 0) {
return;
}
}
writer.start(name, attrs, empty);
},
end: function(name) {
if (name == 'script' || name == 'noscript') {
return;
}
writer.end(name);
}
}, new tinymce.html.Schema({})).parse(html);
return writer.getContent();
}
function updateHtml(html, data, updateAll) {
var writer = new tinymce.html.Writer();
var sourceCount = 0, hasImage;
@ -674,7 +724,7 @@ tinymce.PluginManager.add('media', function(editor, url) {
if (innerHtml) {
innerNode = new tinymce.html.Node('#text', 3);
innerNode.raw = true;
innerNode.value = unescape(innerHtml);
innerNode.value = sanitize(unescape(innerHtml));
realElm.append(innerNode);
}

2
plugins/media/plugin.min.js
File diff suppressed because it is too large
View File

6
plugins/paste/plugin.js

@ -620,8 +620,12 @@ define("tinymce/pasteplugin/Clipboard", [
});
editor.on('paste', function(e) {
// Getting content from the Clipboard can take some time
var clipboardTimer = new Date().getTime();
var clipboardContent = getClipboardContent(e);
var isKeyBoardPaste = new Date().getTime() - keyboardPasteTimeStamp < 1000;
var clipboardDelay = new Date().getTime() - clipboardTimer;
var isKeyBoardPaste = (new Date().getTime() - keyboardPasteTimeStamp - clipboardDelay) < 1000;
var plainTextMode = self.pasteFormat == "text" || keyboardPastePlainTextState;
keyboardPastePlainTextState = false;

2
plugins/paste/plugin.min.js
File diff suppressed because it is too large
View File

5
plugins/spellchecker/plugin.js

@ -771,8 +771,6 @@ define("tinymce/spellcheckerplugin/Plugin", [
finish();
}
started = true;
function errorCallback(message) {
editor.windowManager.alert(message);
editor.setProgressState(false);
@ -886,6 +884,8 @@ define("tinymce/spellcheckerplugin/Plugin", [
onPostRender: function() {
var self = this;
self.active(started);
editor.on('SpellcheckStart SpellcheckEnd', function() {
self.active(started);
});
@ -943,6 +943,7 @@ define("tinymce/spellcheckerplugin/Plugin", [
});
});
started = true;
editor.fire('SpellcheckStart');
}

2
plugins/spellchecker/plugin.min.js
File diff suppressed because it is too large
View File

20
plugins/table/plugin.js

@ -1528,10 +1528,13 @@ define("tinymce/tableplugin/Dialogs", [
return function(editor) {
var self = this;
function pickColorAction() {
var self = this, colorPickerCallback = editor.settings.color_picker_callback;
function createColorPickAction() {
var colorPickerCallback = editor.settings.color_picker_callback;
if (colorPickerCallback) {
return function() {
var self = this;
colorPickerCallback.call(
editor,
function(value) {
@ -1539,6 +1542,7 @@ define("tinymce/tableplugin/Dialogs", [
},
self.value()
);
};
}
}
@ -1573,14 +1577,14 @@ define("tinymce/tableplugin/Dialogs", [
label: 'Border color',
type: 'colorbox',
name: 'borderColor',
onaction: pickColorAction
onaction: createColorPickAction()
},
{
label: 'Background color',
type: 'colorbox',
name: 'backgroundColor',
onaction: pickColorAction
onaction: createColorPickAction()
}
]
}
@ -1825,7 +1829,7 @@ define("tinymce/tableplugin/Dialogs", [
]
};
if (editor.settings.table_adv_tab !== false) {
if (editor.settings.table_advtab !== false) {
appendStylesToData(dom, data, tableElm);
editor.windowManager.open({
@ -2047,7 +2051,7 @@ define("tinymce/tableplugin/Dialogs", [
]
};
if (editor.settings.table_cell_adv_tab !== false) {
if (editor.settings.table_cell_advtab !== false) {
appendStylesToData(dom, data, cellElm);
editor.windowManager.open({
@ -2070,7 +2074,7 @@ define("tinymce/tableplugin/Dialogs", [
editor.windowManager.open({
title: "Cell properties",
data: data,
items: generalCellForm,
body: generalCellForm,
onsubmit: onSubmitCellForm
});
}
@ -2219,7 +2223,7 @@ define("tinymce/tableplugin/Dialogs", [
]
};
if (editor.settings.table_row_adv_tab !== false) {
if (editor.settings.table_row_advtab !== false) {
appendStylesToData(dom, data, rowElm);
editor.windowManager.open({

2
plugins/table/plugin.min.js
File diff suppressed because it is too large
View File

178
tinymce.jquery.js

@ -1,4 +1,4 @@
// 4.1.3 (2014-07-29)
// 4.1.4 (2014-08-21)
/**
* Compiled inline version. (Library mode)
@ -1921,7 +1921,7 @@ define("tinymce/dom/DomQuery", [
self[i].innerHTML = value;
}
} catch (ex) {
// Workaround for "Unkown runtime error" when DIV is added to P on IE
// Workaround for "Unknown runtime error" when DIV is added to P on IE
DomQuery(self[i]).empty().append(value);
}
@ -2512,10 +2512,18 @@ define("tinymce/dom/DomQuery", [
text: Sizzle.getText,
contains: Sizzle.contains,
filter: function(expr, elems, not) {
var i = elems.length;
if (not) {
expr = ":not(" + expr + ")";
}
while (i--) {
if (elems[i].nodeType != 1) {
elems.splice(i, 1);
}
}
if (elems.length === 1) {
elems = DomQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : [];
} else {
@ -7508,8 +7516,8 @@ define("tinymce/NodeChange", [
editor.on('SelectionChange', function() {
var startElm = editor.selection.getStart(true);
// Selection change might fire when focus is lost so check if the start is still within the body
if (!isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) {
// Fire a nodechange only when the selection isn't collapsed since focusout will collapse and remove the selection
if (!editor.selection.isCollapsed() && !isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) {
editor.nodeChanged({selectionChange: true});
}
});
@ -7998,11 +8006,11 @@ define("tinymce/html/Node", [], function() {
return false;
}
// Keep elements with data attributes or name attribute like <a name="1"></a>
// Keep bookmark nodes and name attribute like <a name="1"></a>
i = node.attributes.length;
while (i--) {
name = node.attributes[i].name;
if (name === "name" || name.indexOf('data-mce-') === 0) {
if (name === "name" || name.indexOf('data-mce-bookmark') === 0) {
return false;
}
}
@ -11717,8 +11725,8 @@ define("tinymce/dom/ControlSelection", [
'z-index: 10000' +
'}' +
rootClass + ' .mce-resize-helper {' +
'background-color: #555;' +
'background-color: rgba(0,0,0,0.75);' +
'background: #555;' +
'background: rgba(0,0,0,0.75);' +
'border-radius: 3px;' +
'border: 1px;' +
'color: white;' +
@ -12028,6 +12036,11 @@ define("tinymce/dom/ControlSelection", [
}
}
// Ignore all events while resizing
if (resizeStarted) {
return;
}
// Remove data-mce-selected from all elements since they might have been copied using Ctrl+c/v
each(dom.select('img[data-mce-selected],hr[data-mce-selected]'), function(img) {
img.removeAttribute('data-mce-selected');
@ -13110,7 +13123,7 @@ define("tinymce/dom/Selection", [
getRng: function(w3c) {
var self = this, selection, rng, elm, doc = self.win.document, ieRng;
function tryCompareBounderyPoints(how, sourceRange, destinationRange) {
function tryCompareBoundaryPoints(how, sourceRange, destinationRange) {
try {
return sourceRange.compareBoundaryPoints(how, destinationRange);
} catch (ex) {
@ -13190,8 +13203,8 @@ define("tinymce/dom/Selection", [
}
if (self.selectedRange && self.explicitRange) {
if (tryCompareBounderyPoints(rng.START_TO_START, rng, self.selectedRange) === 0 &&
tryCompareBounderyPoints(rng.END_TO_END, rng, self.selectedRange) === 0) {
if (tryCompareBoundaryPoints(rng.START_TO_START, rng, self.selectedRange) === 0 &&
tryCompareBoundaryPoints(rng.END_TO_END, rng, self.selectedRange) === 0) {
// Safari, Opera and Chrome only ever select text which causes the range to change.
// This lets us use the originally set range if the selection hasn't been changed by the user.
rng = self.explicitRange;
@ -13532,6 +13545,30 @@ define("tinymce/dom/Selection", [
}
},
placeCaretAt: function(clientX, clientY) {
var doc = this.editor.getDoc(), rng, point;
if (doc.caretPositionFromPoint) {
point = doc.caretPositionFromPoint(clientX, clientY);
rng = doc.createRange();
rng.setStart(point.offsetNode, point.offset);
rng.collapse(true);
} else if (doc.caretRangeFromPoint) {
rng = doc.caretRangeFromPoint(clientX, clientY);
} else if (doc.body.createTextRange) {
rng = doc.body.createTextRange();
try {
rng.moveToPoint(clientX, clientY);
rng.collapse(true);
} catch (ex) {
rng.collapse(clientY < doc.body.clientHeight);
}
}
this.setRng(rng);
},
_moveEndPoint: function(rng, node, start) {
var root = node, walker = new TreeWalker(node, root);
var nonEmptyElementsMap = this.dom.schema.getNonEmptyElements();
@ -16212,7 +16249,7 @@ define("tinymce/UndoManager", [
* @return {String} HTML contents of the editor excluding some internal bogus elements.
*/
function getContent() {
var content = trim(editor.getContent({format: 'raw', no_events: 1}));
var content = editor.getContent({format: 'raw', no_events: 1});
var bogusAllRegExp = /<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g;
var endTagIndex, index, matchLength, matches, shortEndedElements, schema = editor.schema;
@ -16234,7 +16271,7 @@ define("tinymce/UndoManager", [
bogusAllRegExp.lastIndex = index - matchLength;
}
return content;
return trim(content);
}
function addNonTypingUndoLevel(e) {
@ -17709,7 +17746,7 @@ define("tinymce/EditorCommands", [
// Setup parser and serializer
parser = editor.parser;
serializer = new Serializer({}, editor.schema);
bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">&#xFEFF;&#200B;</span>';
bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">&#xFEFF;&#x200B;</span>';
// Run beforeSetContent handlers on the HTML to be inserted
args = {content: value, format: 'html', selection: true};
@ -17757,7 +17794,9 @@ define("tinymce/EditorCommands", [
for (node = node.prev; node; node = node.walk(true)) {
if (node.type == 3 || !dom.isBlock(node.name)) {
if (editor.schema.isValidChild(node.parent.name, 'span')) {
node.parent.insert(marker, node, node.name === 'br');
}
break;
}
}
@ -21672,7 +21711,7 @@ define("tinymce/ui/KeyboardNavigation", [
/**
* Returns the navigation root control for the specified control. The navigation root
* is the control that the keyboard navigation gets scoped to for example a menubar or toolbar group.
* It will look for parents of the specified target control or the currenty focused control if this option is omitted.
* It will look for parents of the specified target control or the currently focused control if this option is omitted.
*
* @private
* @param {tinymce.ui.Control} targetControl Optional target control to find root of.
@ -24124,7 +24163,7 @@ define("tinymce/WindowManager", [
self.open = function(args, params) {
var win;
editor.editorManager.activeEditor = editor;
editor.editorManager.setActive(editor);
args.title = args.title || ' ';
@ -24781,17 +24820,19 @@ define("tinymce/util/Quirks", [
*/
function selectControlElements() {
editor.on('click', function(e) {
e = e.target;
var target = e.target;
// Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250
// WebKit can't even do simple things like selecting an image
// Needs tobe the setBaseAndExtend or it will fail to select floated images
if (/^(IMG|HR)$/.test(e.nodeName)) {
selection.getSel().setBaseAndExtent(e, 0, e, 1);
if (/^(IMG|HR)$/.test(target.nodeName)) {
e.preventDefault();
selection.getSel().setBaseAndExtent(target, 0, target, 1);
}
if (e.nodeName == 'A' && dom.hasClass(e, 'mce-item-anchor')) {
selection.select(e);
if (target.nodeName == 'A' && dom.hasClass(target, 'mce-item-anchor')) {
e.preventDefault();
selection.select(target);
}
});
}
@ -25424,6 +25465,13 @@ define("tinymce/util/Quirks", [
});
args = editor.fire('click', args);
if (!args.isDefaultPrevented()) {
// iOS WebKit can't place the caret properly once
// you bind touch events so we need to do this manually
// TODO: Expand to the closest word? Touble tap still works.
editor.selection.placeCaretAt(endTouch.clientX, endTouch.clientY);
}
});
});
}
@ -26621,6 +26669,10 @@ define("tinymce/Editor", [
bodyClass = bodyClass[self.id] || '';
}
if (settings.content_security_policy) {
self.iframeHTML += '<meta http-equiv="Content-Security-Policy" content="' + settings.content_security_policy + '" />';
}
self.iframeHTML += '</head><body id="' + bodyId +
'" class="mce-content-body ' + bodyClass +
'" data-id="' + self.id + '"><br></body></html>';
@ -26659,7 +26711,7 @@ define("tinymce/Editor", [
self.fire("load");
};
DOM.setAttrib("src", url || 'javascript:""');
DOM.setAttrib(ifr, "src", url || 'javascript:""');
self.contentAreaContainer = o.iframeContainer;
self.iframeElement = ifr;
@ -27010,7 +27062,7 @@ define("tinymce/Editor", [
* @param {Boolean} skipFocus Skip DOM focus. Just set is as the active editor.
*/
focus: function(skipFocus) {
var oed, self = this, selection = self.selection, contentEditable = self.settings.content_editable, rng;
var self = this, selection = self.selection, contentEditable = self.settings.content_editable, rng;
var controlElm, doc = self.getDoc(), body;
if (!skipFocus) {
@ -27064,15 +27116,7 @@ define("tinymce/Editor", [
}
}
if (self.editorManager.activeEditor != self) {
if ((oed = self.editorManager.activeEditor)) {
oed.fire('deactivate', {relatedTarget: self});
}
self.fire('activate', {relatedTarget: oed});
}
self.editorManager.activeEditor = self;
self.editorManager.setActive(self);
},
/**
@ -28328,7 +28372,11 @@ define("tinymce/FocusManager", [
if (editor.inline || Env.ie) {
// Use the onbeforedeactivate event when available since it works better see #7023
if ("onbeforedeactivate" in document && Env.ie < 9) {
editor.dom.bind(editor.getBody(), 'beforedeactivate', function() {
editor.dom.bind(editor.getBody(), 'beforedeactivate', function(e) {
if (e.target != editor.getBody()) {
return;
}
try {
editor.lastRng = editor.selection.getRng();
} catch (ex) {
@ -28399,7 +28447,7 @@ define("tinymce/FocusManager", [
focusedEditor.fire('blur', {focusedEditor: editor});
}
editorManager.activeEditor = editor;
editorManager.setActive(editor);
editorManager.focusedEditor = editor;
editor.fire('focus', {blurredEditor: focusedEditor});
editor.focus(true);
@ -28439,7 +28487,7 @@ define("tinymce/FocusManager", [
}
// Fire a blur event if the element isn't a UI element
if (!isUIElement(e.target) && editorManager.focusedEditor == activeEditor) {
if (e.target != document.body && !isUIElement(e.target) && editorManager.focusedEditor == activeEditor) {
activeEditor.fire('blur', {focusedEditor: null});
editorManager.focusedEditor = null;
}
@ -28599,7 +28647,7 @@ define("tinymce/EditorManager", [
* @property minorVersion
* @type String
*/
minorVersion: '1.3',
minorVersion: '1.4',
/**
* Release date of TinyMCE build.
@ -28607,7 +28655,7 @@ define("tinymce/EditorManager", [
* @property releaseDate
* @type String
*/
releaseDate: '2014-07-29',
releaseDate: '2014-08-21',
/**
* Collection of editor instances.
@ -28745,7 +28793,7 @@ define("tinymce/EditorManager", [
* });
*/
init: function(settings) {
var self = this, editors = [], editor;
var self = this, editors = [];
function createId(elm) {
var id = elm.id;
@ -28770,6 +28818,7 @@ define("tinymce/EditorManager", [
function createEditor(id, settings, targetElm) {
if (!purgeDestroyedEditor(self.get(id))) {
var editor = new Editor(id, settings, self);
editor.targetElm = editor.targetElm || targetElm;
editors.push(editor);
editor.render();
@ -28823,18 +28872,18 @@ define("tinymce/EditorManager", [
l = settings.elements || '';
if (l.length > 0) {
each(explode(l), function(v) {
if (DOM.get(v)) {
editor = new Editor(v, settings, self);
editors.push(editor);
editor.render();
each(explode(l), function(id) {
var elm;
if ((elm = DOM.get(id))) {
createEditor(id, settings, elm);
} else {
each(document.forms, function(f) {
each(f.elements, function(e) {
if (e.name === v) {
v = 'mce_editor_' + instanceCounter++;
DOM.setAttrib(e, 'id', v);
createEditor(v, settings, e);
if (e.name === id) {
id = 'mce_editor_' + instanceCounter++;
DOM.setAttrib(e, 'id', id);
createEditor(id, settings, e);
}
});
});
@ -28930,6 +28979,8 @@ define("tinymce/EditorManager", [
editors[editor.id] = editor;
editors.push(editor);
// Doesn't call setActive method since we don't want
// to fire a bunch of activate/deactivate calls while initializing
self.activeEditor = editor;
/**
@ -29122,6 +29173,26 @@ define("tinymce/EditorManager", [
*/
translate: function(text) {
return I18n.translate(text);
},
/**
* Sets the active editor instance and fires the deactivate/activate events.
*
* @method setActive
* @param {tinymce.Editor} editor Editor instance to set as the active instance.
*/
setActive: function(editor) {
var activeEditor = this.activeEditor;
if (this.activeEditor != editor) {
if (activeEditor) {
activeEditor.fire('deactivate', {relatedTarget: editor});
}
editor.fire('activate', {relatedTarget: activeEditor});
}
this.activeEditor = editor;
}
};
@ -31048,7 +31119,10 @@ define("tinymce/ui/ColorBox", [
var self = this;
settings.spellcheck = false;
if (settings.onaction) {
settings.icon = 'none';
}
self._super(settings);
@ -31059,7 +31133,15 @@ define("tinymce/ui/ColorBox", [
},
repaintColor: function(value) {
this.getEl().getElementsByTagName('i')[0].style.background = value;
var elm = this.getEl().getElementsByTagName('i')[0];
if (elm) {
try {
elm.style.background = value;
} catch (ex) {
// Ignore
}
}
},
value: function(value) {

20
tinymce.jquery.min.js
File diff suppressed because it is too large
View File

178
tinymce.js

@ -1,4 +1,4 @@
// 4.1.3 (2014-07-29)
// 4.1.4 (2014-08-21)
/**
* Compiled inline version. (Library mode)
@ -3936,7 +3936,7 @@ define("tinymce/dom/DomQuery", [
self[i].innerHTML = value;
}
} catch (ex) {
// Workaround for "Unkown runtime error" when DIV is added to P on IE
// Workaround for "Unknown runtime error" when DIV is added to P on IE
DomQuery(self[i]).empty().append(value);
}
@ -4527,10 +4527,18 @@ define("tinymce/dom/DomQuery", [
text: Sizzle.getText,
contains: Sizzle.contains,
filter: function(expr, elems, not) {
var i = elems.length;
if (not) {
expr = ":not(" + expr + ")";
}
while (i--) {
if (elems[i].nodeType != 1) {
elems.splice(i, 1);
}
}
if (elems.length === 1) {
elems = DomQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : [];
} else {
@ -9523,8 +9531,8 @@ define("tinymce/NodeChange", [
editor.on('SelectionChange', function() {
var startElm = editor.selection.getStart(true);
// Selection change might fire when focus is lost so check if the start is still within the body
if (!isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) {
// Fire a nodechange only when the selection isn't collapsed since focusout will collapse and remove the selection
if (!editor.selection.isCollapsed() && !isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) {
editor.nodeChanged({selectionChange: true});
}
});
@ -10013,11 +10021,11 @@ define("tinymce/html/Node", [], function() {
return false;
}
// Keep elements with data attributes or name attribute like <a name="1"></a>
// Keep bookmark nodes and name attribute like <a name="1"></a>
i = node.attributes.length;
while (i--) {
name = node.attributes[i].name;
if (name === "name" || name.indexOf('data-mce-') === 0) {
if (name === "name" || name.indexOf('data-mce-bookmark') === 0) {
return false;
}
}
@ -13732,8 +13740,8 @@ define("tinymce/dom/ControlSelection", [
'z-index: 10000' +
'}' +
rootClass + ' .mce-resize-helper {' +
'background-color: #555;' +
'background-color: rgba(0,0,0,0.75);' +
'background: #555;' +
'background: rgba(0,0,0,0.75);' +
'border-radius: 3px;' +
'border: 1px;' +
'color: white;' +
@ -14043,6 +14051,11 @@ define("tinymce/dom/ControlSelection", [
}
}
// Ignore all events while resizing
if (resizeStarted) {
return;
}
// Remove data-mce-selected from all elements since they might have been copied using Ctrl+c/v
each(dom.select('img[data-mce-selected],hr[data-mce-selected]'), function(img) {
img.removeAttribute('data-mce-selected');
@ -15125,7 +15138,7 @@ define("tinymce/dom/Selection", [
getRng: function(w3c) {
var self = this, selection, rng, elm, doc = self.win.document, ieRng;
function tryCompareBounderyPoints(how, sourceRange, destinationRange) {
function tryCompareBoundaryPoints(how, sourceRange, destinationRange) {
try {
return sourceRange.compareBoundaryPoints(how, destinationRange);
} catch (ex) {
@ -15205,8 +15218,8 @@ define("tinymce/dom/Selection", [
}
if (self.selectedRange && self.explicitRange) {
if (tryCompareBounderyPoints(rng.START_TO_START, rng, self.selectedRange) === 0 &&
tryCompareBounderyPoints(rng.END_TO_END, rng, self.selectedRange) === 0) {
if (tryCompareBoundaryPoints(rng.START_TO_START, rng, self.selectedRange) === 0 &&
tryCompareBoundaryPoints(rng.END_TO_END, rng, self.selectedRange) === 0) {
// Safari, Opera and Chrome only ever select text which causes the range to change.
// This lets us use the originally set range if the selection hasn't been changed by the user.
rng = self.explicitRange;
@ -15547,6 +15560,30 @@ define("tinymce/dom/Selection", [
}
},
placeCaretAt: function(clientX, clientY) {
var doc = this.editor.getDoc(), rng, point;
if (doc.caretPositionFromPoint) {
point = doc.caretPositionFromPoint(clientX, clientY);
rng = doc.createRange();
rng.setStart(point.offsetNode, point.offset);
rng.collapse(true);
} else if (doc.caretRangeFromPoint) {
rng = doc.caretRangeFromPoint(clientX, clientY);
} else if (doc.body.createTextRange) {
rng = doc.body.createTextRange();
try {
rng.moveToPoint(clientX, clientY);
rng.collapse(true);
} catch (ex) {
rng.collapse(clientY < doc.body.clientHeight);
}
}
this.setRng(rng);
},
_moveEndPoint: function(rng, node, start) {
var root = node, walker = new TreeWalker(node, root);
var nonEmptyElementsMap = this.dom.schema.getNonEmptyElements();
@ -18227,7 +18264,7 @@ define("tinymce/UndoManager", [
* @return {String} HTML contents of the editor excluding some internal bogus elements.
*/
function getContent() {
var content = trim(editor.getContent({format: 'raw', no_events: 1}));
var content = editor.getContent({format: 'raw', no_events: 1});
var bogusAllRegExp = /<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g;
var endTagIndex, index, matchLength, matches, shortEndedElements, schema = editor.schema;
@ -18249,7 +18286,7 @@ define("tinymce/UndoManager", [
bogusAllRegExp.lastIndex = index - matchLength;
}
return content;
return trim(content);
}
function addNonTypingUndoLevel(e) {
@ -19724,7 +19761,7 @@ define("tinymce/EditorCommands", [
// Setup parser and serializer
parser = editor.parser;
serializer = new Serializer({}, editor.schema);
bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">&#xFEFF;&#200B;</span>';
bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">&#xFEFF;&#x200B;</span>';
// Run beforeSetContent handlers on the HTML to be inserted
args = {content: value, format: 'html', selection: true};
@ -19772,7 +19809,9 @@ define("tinymce/EditorCommands", [
for (node = node.prev; node; node = node.walk(true)) {
if (node.type == 3 || !dom.isBlock(node.name)) {
if (editor.schema.isValidChild(node.parent.name, 'span')) {
node.parent.insert(marker, node, node.name === 'br');
}
break;
}
}
@ -23687,7 +23726,7 @@ define("tinymce/ui/KeyboardNavigation", [
/**
* Returns the navigation root control for the specified control. The navigation root
* is the control that the keyboard navigation gets scoped to for example a menubar or toolbar group.
* It will look for parents of the specified target control or the currenty focused control if this option is omitted.
* It will look for parents of the specified target control or the currently focused control if this option is omitted.
*
* @private
* @param {tinymce.ui.Control} targetControl Optional target control to find root of.
@ -26139,7 +26178,7 @@ define("tinymce/WindowManager", [
self.open = function(args, params) {
var win;
editor.editorManager.activeEditor = editor;
editor.editorManager.setActive(editor);
args.title = args.title || ' ';
@ -26796,17 +26835,19 @@ define("tinymce/util/Quirks", [
*/
function selectControlElements() {
editor.on('click', function(e) {
e = e.target;
var target = e.target;
// Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250
// WebKit can't even do simple things like selecting an image
// Needs tobe the setBaseAndExtend or it will fail to select floated images
if (/^(IMG|HR)$/.test(e.nodeName)) {
selection.getSel().setBaseAndExtent(e, 0, e, 1);
if (/^(IMG|HR)$/.test(target.nodeName)) {
e.preventDefault();
selection.getSel().setBaseAndExtent(target, 0, target, 1);
}
if (e.nodeName == 'A' && dom.hasClass(e, 'mce-item-anchor')) {
selection.select(e);
if (target.nodeName == 'A' && dom.hasClass(target, 'mce-item-anchor')) {
e.preventDefault();
selection.select(target);
}
});
}
@ -27439,6 +27480,13 @@ define("tinymce/util/Quirks", [
});
args = editor.fire('click', args);
if (!args.isDefaultPrevented()) {
// iOS WebKit can't place the caret properly once
// you bind touch events so we need to do this manually
// TODO: Expand to the closest word? Touble tap still works.
editor.selection.placeCaretAt(endTouch.clientX, endTouch.clientY);
}
});
});
}
@ -28636,6 +28684,10 @@ define("tinymce/Editor", [
bodyClass = bodyClass[self.id] || '';
}
if (settings.content_security_policy) {
self.iframeHTML += '<meta http-equiv="Content-Security-Policy" content="' + settings.content_security_policy + '" />';
}
self.iframeHTML += '</head><body id="' + bodyId +
'" class="mce-content-body ' + bodyClass +
'" data-id="' + self.id + '"><br></body></html>';
@ -28674,7 +28726,7 @@ define("tinymce/Editor", [
self.fire("load");
};
DOM.setAttrib("src", url || 'javascript:""');
DOM.setAttrib(ifr, "src", url || 'javascript:""');
self.contentAreaContainer = o.iframeContainer;
self.iframeElement = ifr;
@ -29025,7 +29077,7 @@ define("tinymce/Editor", [
* @param {Boolean} skipFocus Skip DOM focus. Just set is as the active editor.
*/
focus: function(skipFocus) {
var oed, self = this, selection = self.selection, contentEditable = self.settings.content_editable, rng;
var self = this, selection = self.selection, contentEditable = self.settings.content_editable, rng;
var controlElm, doc = self.getDoc(), body;
if (!skipFocus) {
@ -29079,15 +29131,7 @@ define("tinymce/Editor", [
}
}
if (self.editorManager.activeEditor != self) {
if ((oed = self.editorManager.activeEditor)) {
oed.fire('deactivate', {relatedTarget: self});
}
self.fire('activate', {relatedTarget: oed});
}
self.editorManager.activeEditor = self;
self.editorManager.setActive(self);
},
/**
@ -30343,7 +30387,11 @@ define("tinymce/FocusManager", [
if (editor.inline || Env.ie) {
// Use the onbeforedeactivate event when available since it works better see #7023
if ("onbeforedeactivate" in document && Env.ie < 9) {
editor.dom.bind(editor.getBody(), 'beforedeactivate', function() {
editor.dom.bind(editor.getBody(), 'beforedeactivate', function(e) {
if (e.target != editor.getBody()) {
return;
}
try {
editor.lastRng = editor.selection.getRng();
} catch (ex) {
@ -30414,7 +30462,7 @@ define("tinymce/FocusManager", [
focusedEditor.fire('blur', {focusedEditor: editor});
}
editorManager.activeEditor = editor;
editorManager.setActive(editor);
editorManager.focusedEditor = editor;
editor.fire('focus', {blurredEditor: focusedEditor});
editor.focus(true);
@ -30454,7 +30502,7 @@ define("tinymce/FocusManager", [
}
// Fire a blur event if the element isn't a UI element
if (!isUIElement(e.target) && editorManager.focusedEditor == activeEditor) {
if (e.target != document.body && !isUIElement(e.target) && editorManager.focusedEditor == activeEditor) {
activeEditor.fire('blur', {focusedEditor: null});
editorManager.focusedEditor = null;
}
@ -30614,7 +30662,7 @@ define("tinymce/EditorManager", [
* @property minorVersion
* @type String
*/
minorVersion: '1.3',
minorVersion: '1.4',
/**
* Release date of TinyMCE build.
@ -30622,7 +30670,7 @@ define("tinymce/EditorManager", [
* @property releaseDate
* @type String
*/
releaseDate: '2014-07-29',
releaseDate: '2014-08-21',
/**
* Collection of editor instances.
@ -30760,7 +30808,7 @@ define("tinymce/EditorManager", [
* });
*/
init: function(settings) {
var self = this, editors = [], editor;
var self = this, editors = [];
function createId(elm) {
var id = elm.id;
@ -30785,6 +30833,7 @@ define("tinymce/EditorManager", [
function createEditor(id, settings, targetElm) {
if (!purgeDestroyedEditor(self.get(id))) {
var editor = new Editor(id, settings, self);
editor.targetElm = editor.targetElm || targetElm;
editors.push(editor);
editor.render();
@ -30838,18 +30887,18 @@ define("tinymce/EditorManager", [
l = settings.elements || '';
if (l.length > 0) {
each(explode(l), function(v) {
if (DOM.get(v)) {
editor = new Editor(v, settings, self);
editors.push(editor);
editor.render();
each(explode(l), function(id) {
var elm;
if ((elm = DOM.get(id))) {
createEditor(id, settings, elm);
} else {
each(document.forms, function(f) {
each(f.elements, function(e) {
if (e.name === v) {
v = 'mce_editor_' + instanceCounter++;
DOM.setAttrib(e, 'id', v);
createEditor(v, settings, e);
if (e.name === id) {
id = 'mce_editor_' + instanceCounter++;
DOM.setAttrib(e, 'id', id);
createEditor(id, settings, e);
}
});
});
@ -30945,6 +30994,8 @@ define("tinymce/EditorManager", [
editors[editor.id] = editor;
editors.push(editor);
// Doesn't call setActive method since we don't want
// to fire a bunch of activate/deactivate calls while initializing
self.activeEditor = editor;
/**
@ -31137,6 +31188,26 @@ define("tinymce/EditorManager", [
*/
translate: function(text) {
return I18n.translate(text);
},
/**
* Sets the active editor instance and fires the deactivate/activate events.
*
* @method setActive
* @param {tinymce.Editor} editor Editor instance to set as the active instance.
*/
setActive: function(editor) {
var activeEditor = this.activeEditor;
if (this.activeEditor != editor) {
if (activeEditor) {
activeEditor.fire('deactivate', {relatedTarget: editor});
}
editor.fire('activate', {relatedTarget: activeEditor});
}
this.activeEditor = editor;
}
};
@ -33063,7 +33134,10 @@ define("tinymce/ui/ColorBox", [
var self = this;
settings.spellcheck = false;
if (settings.onaction) {
settings.icon = 'none';
}
self._super(settings);
@ -33074,7 +33148,15 @@ define("tinymce/ui/ColorBox", [
},
repaintColor: function(value) {
this.getEl().getElementsByTagName('i')[0].style.background = value;
var elm = this.getEl().getElementsByTagName('i')[0];
if (elm) {
try {
elm.style.background = value;
} catch (ex) {
// Ignore
}
}
},
value: function(value) {

18
tinymce.min.js
File diff suppressed because it is too large
View File

Loading…
Cancel
Save