app/assets/source/tinymce/tinymce.jquery.js in tinymce-rails-4.2.3 vs app/assets/source/tinymce/tinymce.jquery.js in tinymce-rails-4.2.4

- old
+ new

@@ -1,6 +1,6 @@ -// 4.2.3 (2015-07-30) +// 4.2.4 (2015-08-17) /** * Compiled inline version. (Library mode) */ @@ -707,11 +707,11 @@ android = /Android/.test(userAgent); webkit = /WebKit/.test(userAgent); ie = !webkit && !opera && (/MSIE/gi).test(userAgent) && (/Explorer/gi).test(nav.appName); ie = ie && /MSIE (\w+)\./.exec(userAgent)[1]; ie11 = userAgent.indexOf('Trident/') != -1 && (userAgent.indexOf('rv:') != -1 || nav.appName.indexOf('Netscape') != -1) ? 11 : false; - ie12 = (document.msElementsFromPoint && !ie && !ie11) ? 12 : false; + ie12 = (userAgent.indexOf('Edge/') != -1 && !ie && !ie11) ? 12 : false; ie = ie || ie11 || ie12; gecko = !webkit && !ie11 && /Gecko/.test(userAgent); mac = userAgent.indexOf('Mac') != -1; iDevice = /(iPad|iPhone)/.test(userAgent); fileApi = "FormData" in window && "FileReader" in window && "URL" in window && !!URL.createObjectURL; @@ -1338,10 +1338,25 @@ return function() { return value; }; } + function reduce(collection, iteratee, accumulator, thisArg) { + var i = 0; + + if (arguments.length < 3) { + accumulator = collection[0]; + i = 1; + } + + for (; i < collection.length; i++) { + accumulator = iteratee.call(thisArg, accumulator, collection[i], i); + } + + return accumulator; + } + function _addCacheSuffix(url) { var cacheSuffix = Env.cacheSuffix; if (cacheSuffix) { url += (url.indexOf('?') === -1 ? '?' : '&') + cacheSuffix; @@ -1366,10 +1381,11 @@ walk: walk, createNS: createNS, resolve: resolve, explode: explode, constant: constant, + reduce: reduce, _addCacheSuffix: _addCacheSuffix }; }); // Included from: js/tinymce/classes/dom/DomQuery.js @@ -1645,13 +1661,13 @@ if (context && context.nodeType) { self.context = context; } else { if (context) { return DomQuery(selector).attr(context); - } else { - self.context = context = document; } + + self.context = context = document; } if (isString(selector)) { self.selector = selector; @@ -4441,13 +4457,13 @@ // Support upper UTF if (numeric > 0xFFFF) { numeric -= 0x10000; return String.fromCharCode(0xD800 + (numeric >> 10), 0xDC00 + (numeric & 0x3FF)); - } else { - return asciiMap[numeric] || String.fromCharCode(numeric); } + + return asciiMap[numeric] || String.fromCharCode(numeric); } return reverseEntities[all] || namedEntities[all] || nativeDecode(all); }); } @@ -4632,14 +4648,14 @@ style = document.createElement('style'); style.textContent = '@import "' + url + '"'; waitForGeckoLinkLoaded(); appendToHead(style); return; - } else { - // Use the id owner on older webkits - waitForWebKitLinkLoaded(); } + + // Use the id owner on older webkits + waitForWebKitLinkLoaded(); } appendToHead(link); link.href = url; } @@ -5316,11 +5332,11 @@ name = name.replace(/-(\D)/g, function(a, b) { return b.toUpperCase(); }); if (name == 'float') { - name = isIE ? 'styleFloat' : 'cssFloat'; + name = Env.ie && Env.ie < 12 ? 'styleFloat' : 'cssFloat'; } return elm[0] && elm[0].style ? elm[0].style[name] : undefined; }, @@ -6784,13 +6800,13 @@ * @return {tinymce.Theme/tinymce.Plugin} Theme or plugin add-on instance or undefined. */ get: function(name) { if (this.lookup[name]) { return this.lookup[name].instance; - } else { - return undefined; } + + return undefined; }, dependencies: function(name) { var result; @@ -6861,13 +6877,13 @@ }, createUrl: function(baseUrl, dep) { if (typeof dep === "object") { return dep; - } else { - return {prefix: baseUrl.prefix, resource: dep, suffix: baseUrl.suffix}; } + + return {prefix: baseUrl.prefix, resource: dep, suffix: baseUrl.suffix}; }, /** * Add a set of components that will make up the add-on. Using the url of the add-on name as the base url. * This should be used in development mode. A new compressor/javascript munger process will ensure that the @@ -7872,13 +7888,13 @@ } attrs.map[name] = value; return self; - } else { - return attrs.map[name]; } + + return attrs.map[name]; } }, /** * Does a shallow clones the node into a new node. It will also exclude id attributes since @@ -8346,12 +8362,12 @@ // Add HTML5 items to globalAttributes, blockContent, phrasingContent if (type != "html4") { globalAttributes.push.apply(globalAttributes, split("contenteditable contextmenu draggable dropzone " + "hidden spellcheck translate")); blockContent.push.apply(blockContent, split("article aside details dialog figure header footer hgroup section nav")); - phrasingContent.push.apply(phrasingContent, split("audio canvas command datalist mark meter output progress time wbr " + - "video ruby bdi keygen")); + phrasingContent.push.apply(phrasingContent, split("audio canvas command datalist mark meter output picture " + + "progress time wbr video ruby bdi keygen")); } // Add HTML4 elements unless it's html5-strict if (type != "html5-strict") { globalAttributes.push("xml:lang"); @@ -8836,10 +8852,13 @@ // Adds valid children to the schema object function addValidChildren(validChildren) { var childRuleRegExp = /^([+\-]?)(\w+)\[([^\]]+)\]$/; + // Invalidate the schema cache if the schema is mutated + mapCache[settings.schema] = null; + if (validChildren) { each(split(validChildren, ','), function(rule) { var matches = childRuleRegExp.exec(rule), parent, prefix; if (matches) { @@ -8854,14 +8873,10 @@ parent = children[matches[2]]; each(split(matches[3], '|'), function(child) { if (prefix === '-') { - // Clone the element before we delete - // things in it to not mess up default schemas - children[matches[2]] = parent = extend({}, children[matches[2]]); - delete parent[child]; } else { parent[child] = {}; } }); @@ -9744,15 +9759,16 @@ settings.root_name = settings.root_name || 'body'; self.schema = schema = schema || new Schema(); function fixInvalidChildren(nodes) { var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i; - var nonEmptyElements, nonSplitableElements, textBlockElements, sibling, nextNode; + var nonEmptyElements, nonSplitableElements, textBlockElements, specialElements, sibling, nextNode; nonSplitableElements = makeMap('tr,td,th,tbody,thead,tfoot,table'); nonEmptyElements = schema.getNonEmptyElements(); textBlockElements = schema.getTextBlockElements(); + specialElements = schema.getSpecialElements(); for (ni = 0; ni < nodes.length; ni++) { node = nodes[ni]; // Already removed or fixed @@ -9849,11 +9865,11 @@ // Try wrapping the element in a DIV if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) { node.wrap(self.filterNode(new Node('div', 1))); } else { // We failed wrapping it, then remove or unwrap it - if (node.name === 'style' || node.name === 'script') { + if (specialElements[node.name]) { node.empty().remove(); } else { node.unwrap(); } } @@ -11753,14 +11769,14 @@ if (sibling) { sibling.innerHTML = ''; } return; - } else { - startOffset = dom.nodeIndex(startContainer); - startContainer = startContainer.parentNode; } + + startOffset = dom.nodeIndex(startContainer); + startContainer = startContainer.parentNode; } if (startOffset == endOffset - 1) { try { ctrlElm = startContainer.childNodes[startOffset]; @@ -12361,18 +12377,24 @@ lastMouseDownEvent = e; }); } else { disableGeckoResize(); + // Sniff sniff, hard to feature detect this stuff if (Env.ie >= 11) { - // TODO: Drag/drop doesn't work - editor.on('mouseup', function(e) { + // Needs to be mousedown for drag/drop to work on IE 11 + // Needs to be click on Edge to properly select images + editor.on('mousedown click', function(e) { var nodeName = e.target.nodeName; if (!resizeStarted && /^(TABLE|IMG|HR)$/.test(nodeName)) { editor.selection.select(e.target, nodeName == 'TABLE'); - editor.nodeChanged(); + + // Only fire once since nodeChange is expensive + if (e.type == 'mousedown') { + editor.nodeChanged(); + } } }); editor.dom.bind(rootElement, 'mscontrolselect', function(e) { if (/^(TABLE|IMG|HR)$/.test(e.target.nodeName)) { @@ -12388,11 +12410,11 @@ } }); } } - editor.on('nodechange ResizeEditor ResizeWindow', function(e) { + editor.on('nodechange ResizeEditor ResizeWindow drop', function(e) { if (window.requestAnimationFrame) { window.requestAnimationFrame(function() { updateResizeRect(e); }); } else { @@ -13099,25 +13121,25 @@ break; } } return startElement; - } else { - startElement = rng.startContainer; + } - if (startElement.nodeType == 1 && startElement.hasChildNodes()) { - if (!real || !rng.collapsed) { - startElement = startElement.childNodes[Math.min(startElement.childNodes.length - 1, rng.startOffset)]; - } - } + startElement = rng.startContainer; - if (startElement && startElement.nodeType == 3) { - return startElement.parentNode; + if (startElement.nodeType == 1 && startElement.hasChildNodes()) { + if (!real || !rng.collapsed) { + startElement = startElement.childNodes[Math.min(startElement.childNodes.length - 1, rng.startOffset)]; } + } - return startElement; + if (startElement && startElement.nodeType == 3) { + return startElement.parentNode; } + + return startElement; }, /** * Returns the end element of a selection range. If the end is in a text * node the parent element will be returned. @@ -13144,26 +13166,26 @@ if (endElement && endElement.nodeName == 'BODY') { return endElement.lastChild || endElement; } return endElement; - } else { - endElement = rng.endContainer; - endOffset = rng.endOffset; + } - if (endElement.nodeType == 1 && endElement.hasChildNodes()) { - if (!real || !rng.collapsed) { - endElement = endElement.childNodes[endOffset > 0 ? endOffset - 1 : endOffset]; - } - } + endElement = rng.endContainer; + endOffset = rng.endOffset; - if (endElement && endElement.nodeType == 3) { - return endElement.parentNode; + if (endElement.nodeType == 1 && endElement.hasChildNodes()) { + if (!real || !rng.collapsed) { + endElement = endElement.childNodes[endOffset > 0 ? endOffset - 1 : endOffset]; } + } - return endElement; + if (endElement && endElement.nodeType == 3) { + return endElement.parentNode; } + + return endElement; }, /** * Returns a bookmark location for the current selection. This bookmark object * can then be used to restore the selection after some content modification to the document. @@ -13359,11 +13381,11 @@ if (isIE && rng && rng.setStart && doc.selection) { try { // IE will sometimes throw an exception here ieRng = doc.selection.createRange(); } catch (ex) { - + // Ignore } if (ieRng && ieRng.item) { elm = ieRng.item(0); rng = doc.createRange(); @@ -14927,23 +14949,23 @@ !isTableCell(startContainer) && !isTableCell(endContainer)) { startContainer = wrap(startContainer, 'span', {id: '_start', 'data-mce-type': 'bookmark'}); splitToFormatRoot(startContainer); startContainer = unwrap(TRUE); return; - } else { - // Wrap start/end nodes in span element since these might be cloned/moved - startContainer = wrap(startContainer, 'span', {id: '_start', 'data-mce-type': 'bookmark'}); - endContainer = wrap(endContainer, 'span', {id: '_end', 'data-mce-type': 'bookmark'}); + } - // Split start/end - splitToFormatRoot(startContainer); - splitToFormatRoot(endContainer); + // Wrap start/end nodes in span element since these might be cloned/moved + startContainer = wrap(startContainer, 'span', {id: '_start', 'data-mce-type': 'bookmark'}); + endContainer = wrap(endContainer, 'span', {id: '_end', 'data-mce-type': 'bookmark'}); - // Unwrap start/end to get real elements again - startContainer = unwrap(TRUE); - endContainer = unwrap(); - } + // Split start/end + splitToFormatRoot(startContainer); + splitToFormatRoot(endContainer); + + // Unwrap start/end to get real elements again + startContainer = unwrap(TRUE); + endContainer = unwrap(); } else { startContainer = endContainer = splitToFormatRoot(startContainer); } // Update range positions since they might have changed after the split operations @@ -17307,10 +17329,29 @@ dom.add(block, 'br'); } } } + function insertNewBlockAfter() { + // If the caret is at the end of a header we produce a P tag after it similar to Word unless we are in a hgroup + if (/^(H[1-6]|PRE|FIGURE)$/.test(parentBlockName) && containerBlockName != 'HGROUP') { + newBlock = createNewBlock(newBlockName); + } else { + newBlock = createNewBlock(); + } + + // Split the current container block element if enter is pressed inside an empty inner block element + if (settings.end_container_on_empty_block && canSplitBlock(containerBlock) && dom.isEmpty(parentBlock)) { + // Split container block for example a BLOCKQUOTE at the current blockParent location for example a P + newBlock = dom.split(containerBlock, parentBlock); + } else { + dom.insertAfter(newBlock, parentBlock); + } + + moveToCaretPosition(newBlock); + } + rng = selection.getRng(true); // Event is blocked by some other handler for example the lists plugin if (evt.isDefaultPrevented()) { return; @@ -17419,26 +17460,11 @@ // Default block name if it's not configured newBlockName = newBlockName || 'P'; // Insert new block before/after the parent block depending on caret location if (isCaretAtStartOrEndOfBlock()) { - // If the caret is at the end of a header we produce a P tag after it similar to Word unless we are in a hgroup - if (/^(H[1-6]|PRE|FIGURE)$/.test(parentBlockName) && containerBlockName != 'HGROUP') { - newBlock = createNewBlock(newBlockName); - } else { - newBlock = createNewBlock(); - } - - // Split the current container block element if enter is pressed inside an empty inner block element - if (settings.end_container_on_empty_block && canSplitBlock(containerBlock) && dom.isEmpty(parentBlock)) { - // Split container block for example a BLOCKQUOTE at the current blockParent location for example a P - newBlock = dom.split(containerBlock, parentBlock); - } else { - dom.insertAfter(newBlock, parentBlock); - } - - moveToCaretPosition(newBlock); + insertNewBlockAfter(); } else if (isCaretAtStartOrEndOfBlock(true)) { // Insert new block before newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock); renderBlockOnIE(newBlock); moveToCaretPosition(parentBlock); @@ -17450,11 +17476,18 @@ trimLeadingLineBreaks(fragment); newBlock = fragment.firstChild; dom.insertAfter(fragment, parentBlock); trimInlineElementsOnLeftSideOfBlock(newBlock); addBrToBlockIfNeeded(parentBlock); - moveToCaretPosition(newBlock); + + // New block might become empty if it's <p><b>a |</b></p> + if (dom.isEmpty(newBlock)) { + dom.remove(newBlock); + insertNewBlockAfter(); + } else { + moveToCaretPosition(newBlock); + } } dom.setAttrib(newBlock, 'id', ''); // Remove ID since it needs to be document unique // Allow custom handling of new blocks @@ -20057,18 +20090,18 @@ name === 'even' ? index % 2 === 0 : name === 'odd' ? index % 2 === 1 : item[name] ? item[name]() : false; }; - } else { - // Compile not expression - notSelectors = parseChunks(name[1], []); - - return function(item) { - return !match(item, notSelectors); - }; } + + // Compile not expression + notSelectors = parseChunks(name[1], []); + + return function(item) { + return !match(item, notSelectors); + }; } } function compile(selector, filters, direct) { var parts; @@ -21851,14 +21884,14 @@ aria: function(name, value) { var self = this, elm = self.getEl(self.ariaTarget); if (typeof value === "undefined") { return self._aria[name]; - } else { - self._aria[name] = value; } + self._aria[name] = value; + if (self.state.get('rendered')) { elm.setAttribute(name == 'role' ? name : 'aria-' + name, value); } return self; @@ -25519,22 +25552,23 @@ * * @private * @param {DragEvent} e Event object */ function setMceInteralContent(e) { - var selectionHtml; + var selectionHtml, internalContent; if (e.dataTransfer) { if (editor.selection.isCollapsed() && e.target.tagName == 'IMG') { selection.select(e.target); } selectionHtml = editor.selection.getContent(); // Safari/IE doesn't support custom dataTransfer items so we can only use URL and Text if (selectionHtml.length > 0) { - e.dataTransfer.setData(mceInternalDataType, mceInternalUrlPrefix + escape(selectionHtml)); + internalContent = mceInternalUrlPrefix + escape(editor.id) + ',' + escape(selectionHtml); + e.dataTransfer.setData(mceInternalDataType, internalContent); } } } /** @@ -25545,21 +25579,26 @@ * @private * @param {DragEvent} e Event object * @returns {String} mce-internal content */ function getMceInternalContent(e) { - var internalContent, content; + var internalContent; if (e.dataTransfer) { internalContent = e.dataTransfer.getData(mceInternalDataType); if (internalContent && internalContent.indexOf(mceInternalUrlPrefix) >= 0) { - content = unescape(internalContent.substr(mceInternalUrlPrefix.length)); + internalContent = internalContent.substr(mceInternalUrlPrefix.length).split(','); + + return { + id: unescape(internalContent[0]), + html: unescape(internalContent[1]) + }; } } - return content; + return null; } /** * Inserts contents using the paste clipboard command if it's available if it isn't it will fallback * to the core command. @@ -26023,10 +26062,11 @@ }); editor.on('drop', function(e) { if (!isDefaultPrevented(e)) { var internalContent = getMceInternalContent(e); + if (internalContent) { e.preventDefault(); // Safari has a weird issue where drag/dropping images sometimes // produces a green plus icon. When this happens the caretRangeFromPoint @@ -26040,11 +26080,11 @@ dragStartRng = null; } customDelete(); selection.setRng(pointRng); - insertClipboardContents(internalContent); + insertClipboardContents(internalContent.html); }, 0); } } }); @@ -26955,16 +26995,17 @@ }); editor.on('drop', function(e) { if (!isDefaultPrevented(e)) { var internalContent = getMceInternalContent(e); - if (internalContent) { + + if (internalContent && internalContent.id != editor.id) { e.preventDefault(); var rng = RangeUtils.getCaretRangeFromPoint(e.x, e.y, editor.getDoc()); selection.setRng(rng); - insertClipboardContents(internalContent); + insertClipboardContents(internalContent.html); } } }); } @@ -28176,11 +28217,21 @@ function replaceBlobWithBase64(content) { return content.replace(/src="(blob:[^"]+)"/g, function(match, blobUri) { var blobInfo = blobCache.getByUri(blobUri); - return 'src="data:' + blobInfo.blob().type + ';base64,' + blobInfo.base64() + '"'; + if (!blobInfo) { + blobInfo = Tools.reduce(editor.editorManager.editors, function(result, editor) { + return result || editor.editorUpload.blobCache.getByUri(blobUri); + }, null); + } + + if (blobInfo) { + return 'src="data:' + blobInfo.blob().type + ';base64,' + blobInfo.base64() + '"'; + } + + return match[0]; }); } editor.on('setContent paste', scanForImages); @@ -30836,18 +30887,18 @@ * Minor version of TinyMCE build. * * @property minorVersion * @type String */ - minorVersion: '2.3', + minorVersion: '2.4', /** * Release date of TinyMCE build. * * @property releaseDate * @type String */ - releaseDate: '2015-07-30', + releaseDate: '2015-08-17', /** * Collection of editor instances. * * @property editors \ No newline at end of file