1
0
mirror of https://github.com/e107inc/e107.git synced 2025-01-17 20:58:30 +01:00

Tinymce v3.5.8 with fixes

This commit is contained in:
Cameron 2012-11-24 16:29:38 -08:00
parent 10411a2dc3
commit e03a97718e
5 changed files with 243 additions and 68 deletions

File diff suppressed because one or more lines are too long

View File

@ -150,7 +150,7 @@
init : function(ed, url) {
var t = this, s, v, o;
t.editor = ed;
t.url = url;
t.onResolveName = new tinymce.util.Dispatcher(this);
@ -167,7 +167,7 @@
theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap"
}, s);
}
// Default settings
t.settings = s = extend({
theme_advanced_path : true,
@ -678,7 +678,7 @@
if (DOM.get(ed.id + '_path_row')) {
Event.add(ed.id + '_tbl', 'mouseover', function(e) {
var re;
e = e.target;
if (e.nodeName == 'SPAN' && DOM.hasClass(e.parentNode, 'mceButton')) {
@ -956,7 +956,7 @@
a = s.theme_advanced_toolbar_align.toLowerCase();
a = 'mce' + t._ufirst(a);
n = DOM.add(DOM.add(c, 'tr', {role: 'presentation'}), 'td', {'class' : 'mceToolbar ' + a, "role":"presentation"});
n = DOM.add(DOM.add(c, 'tr', {role: 'presentation'}), 'td', {'class' : 'mceToolbar ' + a, "role":"toolbar"});
// Create toolbar and add the controls
for (i=1; (v = s['theme_advanced_buttons' + i]); i++) {
@ -986,7 +986,7 @@
var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td;
n = DOM.add(tb, 'tr');
n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'});
n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'});
n = DOM.add(n, 'div', {id : ed.id + '_path_row', 'role': 'group', 'aria-labelledby': ed.id + '_path_voice'});
if (s.theme_advanced_path) {
DOM.add(n, 'span', {id: ed.id + '_path_voice'}, ed.translate('advanced.path'));
@ -994,7 +994,7 @@
} else {
DOM.add(n, 'span', {}, ' ');
}
if (s.theme_advanced_resizing) {
DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize', tabIndex:"-1"});
@ -1154,7 +1154,7 @@
if (!fn && n.style.fontFamily)
fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase();
if (!fc && n.style.color)
fc = n.style.color;
@ -1185,7 +1185,7 @@
return true;
});
}
if (s.theme_advanced_show_current_color) {
function updateColor(controlId, color) {
if (c = cm.get(controlId)) {

File diff suppressed because one or more lines are too long

View File

@ -6,9 +6,9 @@
var tinymce = {
majorVersion : '3',
minorVersion : '5.6',
minorVersion : '5.8',
releaseDate : '2012-07-26',
releaseDate : '2012-11-20',
_init : function() {
var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
@ -107,12 +107,16 @@
if (!t)
return o !== undef;
if (t == 'array' && (o.hasOwnProperty && o instanceof Array))
if (t == 'array' && tinymce.isArray(o))
return true;
return typeof(o) == t;
},
isArray: Array.isArray || function(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
},
makeMap : function(items, delim, map) {
var i;
@ -1173,7 +1177,7 @@ tinymce.create('tinymce.util.Dispatcher', {
}
if (t == 'object') {
if (o.hasOwnProperty && o instanceof Array) {
if (o.hasOwnProperty && Object.prototype.toString.call(o) === '[object Array]') {
for (i=0, v = '['; i<o.length; i++)
v += (i > 0 ? ',' : '') + serialize(o[i], quote);
@ -1345,7 +1349,8 @@ tinymce.create('static tinymce.util.XHR', {
})(tinymce);
tinymce.util.Quirks = function(editor) {
var VK = tinymce.VK, BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection, settings = editor.settings;
var VK = tinymce.VK, BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection,
settings = editor.settings, parser = editor.parser, serializer = editor.serializer, each = tinymce.each;
function setEditorCommandState(cmd, state) {
try {
@ -1361,6 +1366,10 @@ tinymce.util.Quirks = function(editor) {
return documentMode ? documentMode : 6;
};
function isDefaultPrevented(e) {
return e.isDefaultPrevented();
};
function cleanupStylesWhenDeleting() {
function removeMergedFormatSpans(isDelete) {
var rng, blockElm, node, clonedSpan;
@ -1371,46 +1380,54 @@ tinymce.util.Quirks = function(editor) {
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
// On delete clone the root span of the next block element
if (isDelete)
if (isDelete) {
blockElm = dom.getNext(blockElm, dom.isBlock);
}
// Locate root span element and clone it since it would otherwise get merged by the "apple-style-span" on delete/backspace
if (blockElm) {
node = blockElm.firstChild;
// Ignore empty text nodes
while (node && node.nodeType == 3 && node.nodeValue.length === 0)
while (node && node.nodeType == 3 && node.nodeValue.length === 0) {
node = node.nextSibling;
}
if (node && node.nodeName === 'SPAN') {
clonedSpan = node.cloneNode(false);
}
}
each(dom.select('span', blockElm), function(span) {
span.setAttribute('data-mce-mark', '1');
});
// Do the backspace/delete action
editor.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null);
// Find all odd apple-style-spans
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
tinymce.each(dom.select('span.Apple-style-span,font.Apple-style-span', blockElm), function(span) {
each(dom.select('span', blockElm), function(span) {
var bm = selection.getBookmark();
if (clonedSpan) {
dom.replace(clonedSpan.cloneNode(false), span, true);
} else {
} else if (!span.getAttribute('data-mce-mark')) {
dom.remove(span, true);
} else {
span.removeAttribute('data-mce-mark');
}
// Restore the selection
selection.moveToBookmark(bm);
});
};
}
editor.onKeyDown.add(function(editor, e) {
var isDelete;
isDelete = e.keyCode == DELETE;
if (!e.isDefaultPrevented() && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
if (!isDefaultPrevented(e) && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
e.preventDefault();
removeMergedFormatSpans(isDelete);
}
@ -1441,7 +1458,7 @@ tinymce.util.Quirks = function(editor) {
var keyCode = e.keyCode, isCollapsed;
// Empty the editor if it's needed for example backspace at <p><b>|</b></p>
if (!e.isDefaultPrevented() && (keyCode == DELETE || keyCode == BACKSPACE)) {
if (!isDefaultPrevented(e) && (keyCode == DELETE || keyCode == BACKSPACE)) {
isCollapsed = editor.selection.isCollapsed();
// Selection is collapsed but the editor isn't empty
@ -1469,7 +1486,7 @@ tinymce.util.Quirks = function(editor) {
function selectAll() {
editor.onKeyDown.add(function(editor, e) {
if (e.keyCode == 65 && VK.metaKeyPressed(e)) {
if (!isDefaultPrevented(e) && e.keyCode == 65 && VK.metaKeyPressed(e)) {
e.preventDefault();
editor.execCommand('SelectAll');
}
@ -1495,7 +1512,7 @@ tinymce.util.Quirks = function(editor) {
function removeHrOnBackspace() {
editor.onKeyDown.add(function(editor, e) {
if (!e.isDefaultPrevented() && e.keyCode === BACKSPACE) {
if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
var node = selection.getNode();
var previousSibling = node.previousSibling;
@ -1514,7 +1531,7 @@ tinymce.util.Quirks = function(editor) {
// wouldn't get proper focus if the user clicked on the HTML element
if (!Range.prototype.getClientRects) { // Detect getClientRects got introduced in FF 4
editor.onMouseDown.add(function(editor, e) {
if (e.target.nodeName === "HTML") {
if (!isDefaultPrevented(e) && e.target.nodeName === "HTML") {
var body = editor.getBody();
// Blur the body it's focused but not correctly focused
@ -1558,7 +1575,7 @@ tinymce.util.Quirks = function(editor) {
if (target !== editor.getBody()) {
dom.setAttrib(target, "style", null);
tinymce.each(template, function(attr) {
each(template, function(attr) {
target.setAttributeNode(attr.cloneNode(true));
});
}
@ -1577,7 +1594,7 @@ tinymce.util.Quirks = function(editor) {
editor.onKeyPress.add(function(editor, e) {
var applyAttributes;
if ((e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) {
if (!isDefaultPrevented(e) && (e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) {
applyAttributes = getAttributeApplyFunction();
editor.getDoc().execCommand('delete', false, null);
applyAttributes();
@ -1589,7 +1606,7 @@ tinymce.util.Quirks = function(editor) {
dom.bind(editor.getDoc(), 'cut', function(e) {
var applyAttributes;
if (isSelectionAcrossElements()) {
if (!isDefaultPrevented(e) && isSelectionAcrossElements()) {
applyAttributes = getAttributeApplyFunction();
editor.onKeyUp.addToTop(blockEvent);
@ -1628,7 +1645,7 @@ tinymce.util.Quirks = function(editor) {
function disableBackspaceIntoATable() {
editor.onKeyDown.add(function(editor, e) {
if (!e.isDefaultPrevented() && e.keyCode === BACKSPACE) {
if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
var previousSibling = selection.getNode().previousSibling;
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "table") {
@ -1652,7 +1669,7 @@ tinymce.util.Quirks = function(editor) {
dom.addClass(editor.getBody(), 'mceHideBrInPre');
// Adds a \n before all BR elements in PRE to get them visual
editor.parser.addNodeFilter('pre', function(nodes, name) {
parser.addNodeFilter('pre', function(nodes, name) {
var i = nodes.length, brNodes, j, brElm, sibling;
while (i--) {
@ -1673,7 +1690,7 @@ tinymce.util.Quirks = function(editor) {
});
// Removes any \n before BR elements in PRE since other browsers and in contentEditable=false mode they will be visible
editor.serializer.addNodeFilter('pre', function(nodes, name) {
serializer.addNodeFilter('pre', function(nodes, name) {
var i = nodes.length, brNodes, j, brElm, sibling;
while (i--) {
@ -1716,7 +1733,7 @@ tinymce.util.Quirks = function(editor) {
var isDelete, rng, container, offset, brElm, sibling, collapsed;
isDelete = e.keyCode == DELETE;
if (!e.isDefaultPrevented() && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
if (!isDefaultPrevented(e) && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
rng = selection.getRng();
container = rng.startContainer;
offset = rng.startOffset;
@ -1756,7 +1773,7 @@ tinymce.util.Quirks = function(editor) {
editor.onKeyDown.add(function(editor, e) {
var rng, container, offset, root, parent;
if (e.isDefaultPrevented() || e.keyCode != VK.BACKSPACE) {
if (isDefaultPrevented(e) || e.keyCode != VK.BACKSPACE) {
return;
}
@ -1780,10 +1797,10 @@ tinymce.util.Quirks = function(editor) {
editor.formatter.toggle('blockquote', null, parent);
// Move the caret to the beginning of container
rng = dom.createRng();
rng.setStart(container, 0);
rng.setEnd(container, 0);
selection.setRng(rng);
selection.collapse(false);
}
});
};
@ -1808,7 +1825,7 @@ tinymce.util.Quirks = function(editor) {
function addBrAfterLastLinks() {
function fixLinks(editor, o) {
tinymce.each(dom.select('a'), function(node) {
each(dom.select('a'), function(node) {
var parentNode = node.parentNode, root = dom.getRoot();
if (parentNode.lastChild === node) {
@ -1858,7 +1875,7 @@ tinymce.util.Quirks = function(editor) {
editor.onKeyDown.add(function(editor, e) {
var rng;
if (!e.isDefaultPrevented() && e.keyCode == BACKSPACE) {
if (!isDefaultPrevented(e) && e.keyCode == BACKSPACE) {
rng = editor.getDoc().selection.createRange();
if (rng && rng.item) {
e.preventDefault();
@ -1876,7 +1893,7 @@ tinymce.util.Quirks = function(editor) {
// IE10+
if (getDocumentMode() >= 10) {
emptyBlocksCSS = '';
tinymce.each('p div h1 h2 h3 h4 h5 h6'.split(' '), function(name, i) {
each('p div h1 h2 h3 h4 h5 h6'.split(' '), function(name, i) {
emptyBlocksCSS += (i > 0 ? ',' : '') + name + ':empty';
});
@ -1993,7 +2010,7 @@ tinymce.util.Quirks = function(editor) {
width = height = 0;
}
tinymce.each(resizeHandles, function(handle, name) {
each(resizeHandles, function(handle, name) {
var handleElm;
// Get existing or render resize handle
@ -2090,7 +2107,7 @@ tinymce.util.Quirks = function(editor) {
var controlElm = dom.getParent(selection.getNode(), 'table,img');
// Remove data-mce-selected from all elements since they might have been copied using Ctrl+c/v
tinymce.each(dom.select('img[data-mce-selected]'), function(img) {
each(dom.select('img[data-mce-selected]'), function(img) {
img.removeAttribute('data-mce-selected');
});
@ -2117,6 +2134,46 @@ tinymce.util.Quirks = function(editor) {
});
}
function keepNoScriptContents() {
if (getDocumentMode() < 9) {
parser.addNodeFilter('noscript', function(nodes) {
var i = nodes.length, node, textNode;
while (i--) {
node = nodes[i];
textNode = node.firstChild;
if (textNode) {
node.attr('data-mce-innertext', textNode.value);
}
}
});
serializer.addNodeFilter('noscript', function(nodes) {
var i = nodes.length, node, textNode, value;
while (i--) {
node = nodes[i];
textNode = nodes[i].firstChild;
if (textNode) {
textNode.value = tinymce.html.Entities.decode(textNode.value);
} else {
// Old IE can't retain noscript value so an attribute is used to store it
value = node.attributes.map['data-mce-innertext'];
if (value) {
node.attr('data-mce-innertext', null);
textNode = new tinymce.html.Node('#text', 3);
textNode.value = value;
textNode.raw = true;
node.append(textNode);
}
}
}
});
}
}
// All browsers
disableBackspaceIntoATable();
removeBlockQuoteOnBackSpace();
@ -2147,6 +2204,7 @@ tinymce.util.Quirks = function(editor) {
removePreSerializedStylesWhenSelectingControls();
deleteControlItemOnBackSpace();
renderEmptyBlocksFix();
keepNoScriptContents();
}
// Gecko
@ -2701,7 +2759,7 @@ tinymce.html.Styles = function(settings, schema) {
'form[A|accept-charset|action|autocomplete|enctype|method|name|novalidate|target][C]' +
'fieldset[A|disabled|form|name][C|legend]' +
'label[A|form|for][B]' +
'input[A|type|accept|alt|autocomplete|checked|disabled|form|formaction|formenctype|formmethod|formnovalidate|formtarget|height|list|max|maxlength|min|' +
'input[A|type|accept|alt|autocomplete|autofocus|checked|disabled|form|formaction|formenctype|formmethod|formnovalidate|formtarget|height|list|max|maxlength|min|' +
'multiple|pattern|placeholder|readonly|required|size|src|step|width|files|value|name][]' +
'button[A|autofocus|disabled|form|formaction|formenctype|formmethod|formnovalidate|formtarget|name|value|type][B]' +
'select[A|autofocus|disabled|form|multiple|name|size][option|optgroup]' +
@ -2905,14 +2963,15 @@ tinymce.html.Styles = function(settings, schema) {
}
// Setup map objects
whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script style textarea');
whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea');
selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr');
shortEndedElementsMap = createLookupTable('short_ended_elements', 'area base basefont br col frame hr img input isindex link meta param embed source wbr');
boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected autoplay loop controls');
nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object', shortEndedElementsMap);
blockElementsMap = createLookupTable('block_elements', 'h1 h2 h3 h4 h5 h6 hr p div address pre form table tbody thead tfoot ' +
'th tr td li ol ul caption blockquote center dl dt dd dir fieldset ' +
'noscript menu isindex samp header footer article section hgroup aside nav figure option datalist select optgroup');
textBlockElementsMap = createLookupTable('text_block_elements', 'h1 h2 h3 h4 h5 h6 p div address pre form ' +
'blockquote center dir fieldset header footer article section hgroup aside nav figure');
blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' +
'th tr td li ol ul caption dl dt dd noscript menu isindex samp option datalist select optgroup', textBlockElementsMap);
// Converts a wildcard expression string to a regexp for example *a will become /.*a/.
function patternToRegExp(str) {
@ -3086,8 +3145,15 @@ tinymce.html.Styles = function(settings, schema) {
customElementsMap[name] = cloneName;
// If it's not marked as inline then add it to valid block elements
if (!inline)
if (!inline) {
blockElementsMap[name.toUpperCase()] = {};
blockElementsMap[name] = {};
}
// Add elements clone if needed
if (!elements[name]) {
elements[name] = elements[cloneName];
}
// Add custom elements at span/div positions
each(children, function(element, child) {
@ -3212,6 +3278,10 @@ tinymce.html.Styles = function(settings, schema) {
return blockElementsMap;
};
self.getTextBlockElements = function() {
return textBlockElementsMap;
};
self.getShortEndedElements = function() {
return shortEndedElementsMap;
};
@ -3277,6 +3347,8 @@ tinymce.html.Styles = function(settings, schema) {
self.addCustomElements = addCustomElements;
self.addValidChildren = addValidChildren;
self.elements = elements;
};
})(tinymce);
@ -3375,10 +3447,10 @@ tinymce.html.Styles = function(settings, schema) {
'(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE
'(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI
'(?:\\/([^>]+)>)|' + // End element
'(?:([A-Za-z0-9\\-\\:]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + // Start element
'(?:([A-Za-z0-9\\-\\:\\.]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + // Start element
')', 'g');
attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g;
attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g;
specialElements = {
'script' : /<\/script[^>]*>/gi,
'style' : /<\/style[^>]*>/gi,
@ -3861,7 +3933,7 @@ tinymce.html.Styles = function(settings, schema) {
i = node.attributes.length;
while (i--) {
name = node.attributes[i].name;
if (name === "name" || name.indexOf('data-') === 0)
if (name === "name" || name.indexOf('data-mce-') === 0)
return false;
}
}
@ -3917,18 +3989,41 @@ tinymce.html.Styles = function(settings, schema) {
function fixInvalidChildren(nodes) {
var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i,
childClone, nonEmptyElements, nonSplitableElements, sibling, nextNode;
childClone, nonEmptyElements, nonSplitableElements, textBlockElements, sibling, nextNode;
nonSplitableElements = tinymce.makeMap('tr,td,th,tbody,thead,tfoot,table');
nonEmptyElements = schema.getNonEmptyElements();
textBlockElements = schema.getTextBlockElements();
for (ni = 0; ni < nodes.length; ni++) {
node = nodes[ni];
// Already removed
if (!node.parent)
// Already removed or fixed
if (!node.parent || node.fixed)
continue;
// If the invalid element is a text block and the text block is within a parent LI element
// Then unwrap the first text block and convert other sibling text blocks to LI elements similar to Word/Open Office
if (textBlockElements[node.name] && node.parent.name == 'li') {
// Move sibling text blocks after LI element
sibling = node.next;
while (sibling) {
if (textBlockElements[sibling.name]) {
sibling.name = 'li';
sibling.fixed = true;
node.parent.insert(sibling, node.parent);
} else {
break;
}
sibling = sibling.next;
}
// Unwrap current text block
node.unwrap(node);
continue;
}
// Get list of all parent nodes until we find a valid parent to stick the child into
parents = [node];
for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && !nonSplitableElements[parent.name]; parent = parent.parent)
@ -4306,7 +4401,8 @@ tinymce.html.Styles = function(settings, schema) {
}
// Trim start white space
textNode = node.prev;
// Removed due to: #5424
/*textNode = node.prev;
if (textNode && textNode.type === 3) {
text = textNode.value.replace(startWhiteSpaceRegExp, '');
@ -4314,7 +4410,7 @@ tinymce.html.Styles = function(settings, schema) {
textNode.value = text;
else
textNode.remove();
}
}*/
}
// Check if we exited a whitespace preserved element
@ -4824,6 +4920,12 @@ tinymce.dom = {};
}
}
// Page already loaded then fire it directly
if (doc.readyState == "complete") {
readyHandler();
return;
}
// Use W3C method
if (w3cEventModel) {
addEvent(win, 'DOMContentLoaded', readyHandler);
@ -5367,6 +5469,11 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
blockElementsMap = s.schema ? s.schema.getBlockElements() : {};
t.isBlock = function(node) {
// Fix for #5446
if (!node) {
return false;
}
// This function is called in module pattern style since it might be executed with the wrong this scope
var type = node.nodeType;
@ -9000,6 +9107,16 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
return self;
},
scrollIntoView: function(elm) {
var y, viewPort, self = this, dom = self.dom;
viewPort = dom.getViewPort(self.editor.getWin());
y = dom.getPos(elm).y;
if (y < viewPort.y || y + 25 > viewPort.y + viewPort.h) {
self.editor.getWin().scrollTo(0, y < viewPort.y ? y : y - viewPort.h + 25);
}
},
destroy : function(manual) {
var self = this;
@ -9172,6 +9289,18 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
}
});
htmlParser.addNodeFilter('noscript', function(nodes) {
var i = nodes.length, node;
while (i--) {
node = nodes[i].firstChild;
if (node) {
node.value = tinymce.html.Entities.decode(node.value);
}
}
});
// Force script into CDATA sections and remove the mce- prefix also add comments around styles
htmlParser.addNodeFilter('script,style', function(nodes, name) {
var i = nodes.length, node, value;
@ -11813,6 +11942,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
if (id === undef)
return this.editors;
if (!this.editors.hasOwnProperty(id))
return undef;
return this.editors[id];
},
@ -12339,10 +12471,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
t.iframeHTML += '<base href="' + t.documentBaseURI.getURI() + '" />';
// IE8 doesn't support carets behind images setting ie7_compat would force IE8+ to run in IE7 compat mode.
if (s.ie7_compat)
t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=7" />';
else
t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=edge" />';
if (tinymce.isIE8) {
if (s.ie7_compat)
t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=7" />';
else
t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=edge" />';
}
t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
@ -12970,6 +13104,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// We must save before we hide so Safari doesn't crash
self.save();
// defer the call to hide to prevent an IE9 crash #4921
DOM.hide(self.getContainer());
DOM.setStyle(self.id, 'display', self.orgDisplay);
},
@ -13249,11 +13385,19 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
},
remove : function() {
var self = this, elm = self.getContainer();
var self = this, elm = self.getContainer(), doc = self.getDoc();
if (!self.removed) {
self.removed = 1; // Cancels post remove event execution
self.hide();
// Fixed bug where IE has a blinking cursor left from the editor
if (isIE && doc)
doc.execCommand('SelectAll');
// We must save before we hide so Safari doesn't crash
self.save();
DOM.setStyle(self.id, 'display', self.orgDisplay);
// Don't clear the window or document if content editable
// is enabled since other instances might still be present
@ -14246,7 +14390,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Add undo level on save contents, drag end and blur/focusout
editor.onSaveContent.add(addNonTypingUndoLevel);
editor.dom.bind(editor.dom.getRoot(), 'dragend', addNonTypingUndoLevel);
editor.dom.bind(editor.getDoc(), tinymce.isGecko ? 'blur' : 'focusout', function(e) {
editor.dom.bind(editor.getBody(), 'focusout', function(e) {
if (!editor.removed && self.typing) {
addNonTypingUndoLevel();
}
@ -15029,6 +15173,7 @@ tinymce.ForceBlocks = function(editor) {
TreeWalker = tinymce.dom.TreeWalker,
rangeUtils = new tinymce.dom.RangeUtils(dom),
isValid = ed.schema.isValidChild,
isArray = tinymce.isArray,
isBlock = dom.isBlock,
forcedRootBlock = ed.settings.forced_root_block,
nodeIndex = dom.nodeIndex,
@ -15040,9 +15185,9 @@ tinymce.ForceBlocks = function(editor) {
undef,
getContentEditable = dom.getContentEditable;
function isArray(obj) {
return obj instanceof Array;
};
function isTextBlock(name) {
return !!ed.schema.getTextBlocks()[name.toLowerCase()];
}
function getParents(node, selector) {
return dom.getParents(node, selector, dom.getRoot());
@ -15608,6 +15753,11 @@ tinymce.ForceBlocks = function(editor) {
function process(node) {
var children, i, l, localContentEditable, lastContentEditable, hasContentEditableState;
// Skip on text nodes as they have neither format to remove nor children
if (node.nodeType === 3) {
return;
}
// Node has a contentEditable value
if (node.nodeType === 1 && getContentEditable(node)) {
lastContentEditable = contentEditable;
@ -16101,6 +16251,10 @@ tinymce.ForceBlocks = function(editor) {
siblingName = start ? 'previousSibling' : 'nextSibling';
root = dom.getRoot();
function isBogusBr(node) {
return node.nodeName == "BR" && node.getAttribute('data-mce-bogus') && !node.nextSibling;
};
// If it's a text node and the offset is inside the text
if (container.nodeType == 3 && !isWhiteSpaceNode(container)) {
if (start ? startOffset > 0 : endOffset < container.nodeValue.length) {
@ -16115,7 +16269,7 @@ tinymce.ForceBlocks = function(editor) {
// Walk left/right
for (sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) {
if (!isBookmarkNode(sibling) && !isWhiteSpaceNode(sibling)) {
if (!isBookmarkNode(sibling) && !isWhiteSpaceNode(sibling) && !isBogusBr(sibling)) {
return parent;
}
}
@ -16274,7 +16428,7 @@ tinymce.ForceBlocks = function(editor) {
// Expand to first wrappable block element or any block element
if (!node)
node = dom.getParent(container.nodeType == 3 ? container.parentNode : container, isBlock);
node = dom.getParent(container.nodeType == 3 ? container.parentNode : container, isTextBlock);
// Exclude inner lists from wrapping
if (node && format[0].wrapper)
@ -17221,6 +17375,11 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
if (settings.keep_styles !== false) {
do {
if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(node.nodeName)) {
// Never clone a caret containers
if (node.id == '_mce_caret') {
continue;
}
clonedNode = node.cloneNode(false);
dom.setAttrib(clonedNode, 'id', ''); // Remove ID since it needs to be document unique
@ -17237,7 +17396,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
// BR is needed in empty blocks on non IE browsers
if (!tinymce.isIE) {
caretNode.innerHTML = '<br>';
caretNode.innerHTML = '<br data-mce-bogus="1">';
}
return block;
@ -17413,7 +17572,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
// Inserts a BR element if the forced_root_block option is set to false or empty string
function insertBr() {
var brElm, extraBr;
var brElm, extraBr, marker;
if (container && container.nodeType == 3 && offset >= container.nodeValue.length) {
// Insert extra BR element at the end block elements
@ -17434,6 +17593,12 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
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);
@ -17553,6 +17718,12 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5
containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5
// Enter inside block contained within a LI then split or insert before/after LI
if (containerBlockName == 'LI' && !evt.ctrlKey) {
parentBlock = containerBlock;
parentBlockName = containerBlockName;
}
// Handle enter in LI
if (parentBlockName == 'LI') {
if (!newBlockName && shiftKey) {

View File

@ -60,7 +60,11 @@ class wysiwyg
$text .= "\n /* TinyMce Config: ".$this->configName." */";
$text .= $this->tinyMce_config();
$text .= "\t\t start_tinyMce(); \n";
$text .= "\t\t
$(document).ready(function()
{
start_tinyMce(); \n
}); ";
$text .= "