app/assets/source/tinymce/tinymce.jquery.js in tinymce-rails-4.1.4 vs app/assets/source/tinymce/tinymce.jquery.js in tinymce-rails-4.1.5

- old
+ new

@@ -1,6 +1,6 @@ -// 4.1.4 (2014-08-21) +// 4.1.5 (2014-09-09) /** * Compiled inline version. (Library mode) */ @@ -5271,11 +5271,15 @@ * * // Sets styles to an element by id in the current document * tinymce.DOM.setStyles('mydiv', {'background-color': 'red', 'color': 'green'}); */ setStyles: function(elm, styles) { - this.$$(elm).css(styles); + elm = this.$$(elm).css(styles); + + if (this.settings.update_styles) { + elm.attr('data-mce-style', null); + } }, /** * Removes all attributes from an element or elements. * @@ -6000,11 +6004,11 @@ var self = this, i, attributes, type, walker, name, brCount = 0; node = node.firstChild; if (node) { walker = new TreeWalker(node, node.parentNode); - elements = elements || self.schema ? self.schema.getNonEmptyElements() : null; + elements = elements || (self.schema ? self.schema.getNonEmptyElements() : null); do { type = node.nodeType; if (type === 1) { @@ -7523,11 +7527,15 @@ }); // Fire an extra nodeChange on mouseup for compatibility reasons editor.on('MouseUp', function(e) { if (!e.isDefaultPrevented()) { - editor.nodeChanged(); + // Delay nodeChanged call for WebKit edge case issue where the range + // isn't updated until after you click outside a selected image + setTimeout(function() { + editor.nodeChanged(); + }, 0); } }); /** * Distpaches out a onNodeChange event to all observers. This method should be called when you @@ -7538,11 +7546,11 @@ */ this.nodeChanged = function(args) { var selection = editor.selection, node, parents, root; // Fix for bug #1896577 it seems that this can not be fired while the editor is loading - if (editor.initialized && !editor.settings.disable_nodechange && !editor.settings.readonly) { + if (editor.initialized && selection && !editor.settings.disable_nodechange && !editor.settings.readonly) { // Get start node root = editor.getBody(); node = selection.getStart() || root; node = node.ownerDocument != editor.getDoc() ? editor.getBody() : node; @@ -10114,11 +10122,17 @@ node.empty().append(new Node('#text', '3')).value = '\u00a0'; } else { // Leave nodes that have a name like <a name="name"> if (!node.attributes.map.name && !node.attributes.map.id) { tempNode = node.parent; - node.unwrap(); + + if (blockElements[node.name]) { + node.empty().remove(); + } else { + node.unwrap(); + } + node = tempNode; return; } } } @@ -14166,10 +14180,24 @@ formats[name] = format; } } } + /** + * Unregister a specific format by name. + * + * @method unregister + * @param {String} name Name of the format for example "bold". + */ + function unregister(name) { + if (name && formats[name]) { + delete formats[name]; + } + + return formats; + } + function getTextDecoration(node) { var decoration; ed.dom.getParent(node, function(n) { decoration = ed.dom.getStyle(n, 'text-decoration'); @@ -15063,10 +15091,11 @@ // Expose to public extend(this, { get: get, register: register, + unregister: unregister, apply: apply, remove: remove, toggle: toggle, match: match, matchAll: matchAll, @@ -15947,16 +15976,16 @@ if (child.nodeValue.charAt(0) === INVISIBLE_CHAR) { child.deleteData(0, 1); // Fix for bug #6976 - if (rng.startContainer == child) { - rng.startOffset--; + if (rng.startContainer == child && rng.startOffset > 0) { + rng.setStart(child, rng.startOffset - 1); } - if (rng.endContainer == child) { - rng.endOffset--; + if (rng.endContainer == child && rng.endOffset > 0) { + rng.setEnd(child, rng.endOffset - 1); } } dom.remove(node, 1); } @@ -19948,10 +19977,14 @@ css: function(elm, name, value) { return DOMUtils.DOM.setStyle(elm, name, value); }, + getRuntimeStyle: function(elm, name) { + return DOMUtils.DOM.getStyle(elm, name, true); + }, + on: function(target, name, callback, scope) { return DOMUtils.DOM.bind(target, name, callback, scope); }, off: function(target, name, callback) { @@ -22848,11 +22881,11 @@ // Get pos of target pos = DomUtils.getPos(targetElm); x = pos.x; y = pos.y; - if (ctrl._fixed) { + if (ctrl._fixed && DomUtils.getRuntimeStyle(document.body, 'position') == 'static') { x -= viewport.x; y -= viewport.y; } // Get size of self @@ -23237,10 +23270,50 @@ } } } } + function addRemove(add, ctrl) { + var i, zIndex = FloatPanel.zIndex || 0xFFFF, topModal; + + if (add) { + zOrder.push(ctrl); + } else { + i = zOrder.length; + + while (i--) { + if (zOrder[i] === ctrl) { + zOrder.splice(i, 1); + } + } + } + + if (zOrder.length) { + for (i = 0; i < zOrder.length; i++) { + if (zOrder[i].modal) { + zIndex++; + topModal = zOrder[i]; + } + + zOrder[i].getEl().style.zIndex = zIndex; + zOrder[i].zIndex = zIndex; + zIndex++; + } + } + + var modalBlockEl = document.getElementById(ctrl.classPrefix + 'modal-block'); + + if (topModal) { + DomUtils.css(modalBlockEl, 'z-index', topModal.zIndex - 1); + } else if (modalBlockEl) { + modalBlockEl.parentNode.removeChild(modalBlockEl); + hasModal = false; + } + + FloatPanel.currentZIndex = zIndex; + } + var FloatPanel = Panel.extend({ Mixins: [Movable, Resizable], /** * Constructs a new control instance with the specified settings. @@ -23250,38 +23323,10 @@ * @setting {Boolean} autohide Automatically hide the panel. */ init: function(settings) { var self = this; - function reorder() { - var i, zIndex = FloatPanel.zIndex || 0xFFFF, topModal; - - if (zOrder.length) { - for (i = 0; i < zOrder.length; i++) { - if (zOrder[i].modal) { - zIndex++; - topModal = zOrder[i]; - } - - zOrder[i].getEl().style.zIndex = zIndex; - zOrder[i].zIndex = zIndex; - zIndex++; - } - } - - var modalBlockEl = document.getElementById(self.classPrefix + 'modal-block'); - - if (topModal) { - DomUtils.css(modalBlockEl, 'z-index', topModal.zIndex - 1); - } else if (modalBlockEl) { - modalBlockEl.parentNode.removeChild(modalBlockEl); - hasModal = false; - } - - FloatPanel.currentZIndex = zIndex; - } - self._super(settings); self._eventsRoot = self; self.addClass('floatpanel'); @@ -23317,29 +23362,14 @@ }, 0); hasModal = true; } - zOrder.push(self); - reorder(); + addRemove(true, self); } }); - self.on('close hide', function(e) { - if (e.control == self) { - var i = zOrder.length; - - while (i--) { - if (zOrder[i] === self) { - zOrder.splice(i, 1); - } - } - - reorder(); - } - }); - self.on('show', function() { self.parents().each(function(ctrl) { if (ctrl._fixed) { self.fixed(true); return false; @@ -23403,10 +23433,12 @@ * @method hide * @return {tinymce.ui.FloatPanel} Current floatpanel instance. */ hide: function() { removeVisiblePanel(this); + addRemove(false, this); + return this._super(); }, /** * Hide all visible float panels with he autohide setting enabled. This is for @@ -23424,13 +23456,16 @@ * @method close */ close: function() { var self = this; - self.fire('close'); + if (!self.fire('close').isDefaultPrevented()) { + self.remove(); + addRemove(false, self); + } - return self.remove(); + return self; }, /** * Removes the float panel from page. * @@ -24205,11 +24240,13 @@ if (windows[i] === win) { windows.splice(i, 1); } } - editor.focus(); + if (!windows.length) { + editor.focus(); + } }); // Handle data if (args.data) { win.on('postRender', function() { @@ -24226,11 +24263,13 @@ // store args and parameters win.features = args || {}; win.params = params || {}; // Takes a snapshot in the FocusManager of the selection before focus is lost to dialog - editor.nodeChanged(); + if (windows.length === 1) { + editor.nodeChanged(); + } return win.renderTo().reflow(); }; /** @@ -24743,14 +24782,21 @@ dom.bind(editor.getDoc(), 'focusin', function() { selection.setRng(selection.getRng()); }); // Case 2 IME doesn't initialize if you click the documentElement it also doesn't properly fire the focusin event - dom.bind(editor.getDoc(), 'mousedown', function(e) { + // Needs to be both down/up due to weird rendering bug on Chrome Windows + dom.bind(editor.getDoc(), 'mousedown mouseup', function(e) { if (e.target == editor.getDoc().documentElement) { editor.getBody().focus(); - selection.setRng(selection.getRng()); + + if (e.type == 'mousedown') { + // Edge case for mousedown, drag select and mousedown again within selection on Chrome Windows to render caret + selection.placeCaretAt(e.clientX, e.clientY); + } else { + selection.setRng(selection.getRng()); + } } }); } } @@ -24822,14 +24868,15 @@ editor.on('click', function(e) { 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 + // Needs to be the setBaseAndExtend or it will fail to select floated images if (/^(IMG|HR)$/.test(target.nodeName)) { e.preventDefault(); selection.getSel().setBaseAndExtent(target, 0, target, 1); + editor.nodeChanged(); } if (target.nodeName == 'A' && dom.hasClass(target, 'mce-item-anchor')) { e.preventDefault(); selection.select(target); @@ -25469,10 +25516,11 @@ 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); + editor.nodeChanged(); } }); }); } @@ -28645,19 +28693,19 @@ * Minor version of TinyMCE build. * * @property minorVersion * @type String */ - minorVersion: '1.4', + minorVersion: '1.5', /** * Release date of TinyMCE build. * * @property releaseDate * @type String */ - releaseDate: '2014-08-21', + releaseDate: '2014-09-09', /** * Collection of editor instances. * * @property editors @@ -34021,18 +34069,34 @@ * @method renderHtml * @return {String} HTML representing the control. */ renderHtml: function() { var self = this, id = self._id, prefix = self.classPrefix; - var icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; + var icon = self.settings.icon, image; + image = self.settings.image; + if (image) { + icon = 'none'; + + // Support for [high dpi, low dpi] image sources + if (typeof image != "string") { + image = window.getSelection ? image[0] : image[1]; + } + + image = ' style="background-image: url(\'' + image + '\')"'; + } else { + image = ''; + } + + icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; + self.aria('role', self.parent() instanceof MenuBar ? 'menuitem' : 'button'); return ( '<div id="' + id + '" class="' + self.classes() + '" tabindex="-1" aria-labelledby="' + id + '">' + '<button id="' + id + '-open" role="presentation" type="button" tabindex="-1">' + - (icon ? '<i class="' + icon + '"></i>' : '') + + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + '<span>' + (self._text ? (icon ? '\u00a0' : '') + self.encode(self._text) : '') + '</span>' + ' <i class="' + prefix + 'caret"></i>' + '</button>' + '</div>' ); @@ -34940,16 +35004,32 @@ * * @method renderHtml * @return {String} HTML representing the control. */ renderHtml: function() { - var self = this, id = self._id, prefix = self.classPrefix; - var icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : ''; + var self = this, id = self._id, prefix = self.classPrefix, image; + var icon = self.settings.icon; + image = self.settings.image; + if (image) { + icon = 'none'; + + // Support for [high dpi, low dpi] image sources + if (typeof image != "string") { + image = window.getSelection ? image[0] : image[1]; + } + + image = ' style="background-image: url(\'' + image + '\')"'; + } else { + image = ''; + } + + icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : ''; + return ( '<div id="' + id + '" class="' + self.classes() + '" role="button" tabindex="-1">' + '<button type="button" hidefocus="1" tabindex="-1">' + - (icon ? '<i class="' + icon + '"></i>' : '') + + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + (self._text ? (icon ? ' ' : '') + self._text : '') + '</button>' + '<button type="button" class="' + prefix + 'open" hidefocus="1" tabindex="-1">' + //(icon ? '<i class="' + icon + '"></i>' : '') + (self._menuBtnText ? (icon ? '\u00a0' : '') + self._menuBtnText : '') + \ No newline at end of file