diff --git a/wp-includes/class-wp-editor.php b/wp-includes/class-wp-editor.php index 4ccdea7119..9745623f20 100644 --- a/wp-includes/class-wp-editor.php +++ b/wp-includes/class-wp-editor.php @@ -316,7 +316,7 @@ final class _WP_Editors { * @param array $plugins An array of teenyMCE plugins. * @param string $editor_id Unique editor identifier, e.g. 'content'. */ - self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array( 'fullscreen', 'image', 'wordpress', 'wpeditimage', 'wplink' ), $editor_id ); + self::$plugins = $plugins = apply_filters( 'teeny_mce_plugins', array( 'colorpicker', 'lists', 'fullscreen', 'image', 'wordpress', 'wpeditimage', 'wplink' ), $editor_id ); } else { /** @@ -340,7 +340,9 @@ final class _WP_Editors { $plugins = array( 'charmap', + 'colorpicker', 'hr', + 'lists', 'media', 'paste', 'tabfocus', diff --git a/wp-includes/js/tinymce/plugins/colorpicker/plugin.js b/wp-includes/js/tinymce/plugins/colorpicker/plugin.js new file mode 100644 index 0000000000..11d0af3b2a --- /dev/null +++ b/wp-includes/js/tinymce/plugins/colorpicker/plugin.js @@ -0,0 +1,112 @@ +/** + * plugin.js + * + * Copyright, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*global tinymce:true */ + +tinymce.PluginManager.add('colorpicker', function(editor) { + function colorPickerCallback(callback, value) { + function setColor(value) { + var color = new tinymce.util.Color(value), rgb = color.toRgb(); + + win.fromJSON({ + r: rgb.r, + g: rgb.g, + b: rgb.b, + hex: color.toHex().substr(1) + }); + + showPreview(color.toHex()); + } + + function showPreview(hexColor) { + win.find('#preview')[0].getEl().style.background = hexColor; + } + + var win = editor.windowManager.open({ + title: 'Color', + items: { + type: 'container', + layout: 'flex', + direction: 'row', + align: 'stretch', + padding: 5, + spacing: 10, + items: [ + { + type: 'colorpicker', + value: value, + onchange: function() { + var rgb = this.rgb(); + + if (win) { + win.find('#r').value(rgb.r); + win.find('#g').value(rgb.g); + win.find('#b').value(rgb.b); + win.find('#hex').value(this.value().substr(1)); + showPreview(this.value()); + } + } + }, + { + type: 'form', + padding: 0, + labelGap: 5, + defaults: { + type: 'textbox', + size: 7, + value: '0', + flex: 1, + spellcheck: false, + onchange: function() { + var colorPickerCtrl = win.find('colorpicker')[0]; + var name, value; + + name = this.name(); + value = this.value(); + + if (name == "hex") { + value = '#' + value; + setColor(value); + colorPickerCtrl.value(value); + return; + } + + value = { + r: win.find('#r').value(), + g: win.find('#g').value(), + b: win.find('#b').value() + }; + + colorPickerCtrl.value(value); + setColor(value); + } + }, + items: [ + {name: 'r', label: 'R', autofocus: 1}, + {name: 'g', label: 'G'}, + {name: 'b', label: 'B'}, + {name: 'hex', label: '#', value: '000000'}, + {name: 'preview', type: 'container', border: 1} + ] + } + ] + }, + onSubmit: function() { + callback('#' + this.toJSON().hex); + } + }); + + setColor(value); + } + + if (!editor.settings.color_picker_callback) { + editor.settings.color_picker_callback = colorPickerCallback; + } +}); \ No newline at end of file diff --git a/wp-includes/js/tinymce/plugins/colorpicker/plugin.min.js b/wp-includes/js/tinymce/plugins/colorpicker/plugin.min.js new file mode 100644 index 0000000000..d50c7cc450 --- /dev/null +++ b/wp-includes/js/tinymce/plugins/colorpicker/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("colorpicker",function(e){function n(n,a){function i(e){var n=new tinymce.util.Color(e),a=n.toRgb();l.fromJSON({r:a.r,g:a.g,b:a.b,hex:n.toHex().substr(1)}),t(n.toHex())}function t(e){l.find("#preview")[0].getEl().style.background=e}var l=e.windowManager.open({title:"Color",items:{type:"container",layout:"flex",direction:"row",align:"stretch",padding:5,spacing:10,items:[{type:"colorpicker",value:a,onchange:function(){var e=this.rgb();l&&(l.find("#r").value(e.r),l.find("#g").value(e.g),l.find("#b").value(e.b),l.find("#hex").value(this.value().substr(1)),t(this.value()))}},{type:"form",padding:0,labelGap:5,defaults:{type:"textbox",size:7,value:"0",flex:1,spellcheck:!1,onchange:function(){var e,n,a=l.find("colorpicker")[0];return e=this.name(),n=this.value(),"hex"==e?(n="#"+n,i(n),void a.value(n)):(n={r:l.find("#r").value(),g:l.find("#g").value(),b:l.find("#b").value()},a.value(n),void i(n))}},items:[{name:"r",label:"R",autofocus:1},{name:"g",label:"G"},{name:"b",label:"B"},{name:"hex",label:"#",value:"000000"},{name:"preview",type:"container",border:1}]}]},onSubmit:function(){n("#"+this.toJSON().hex)}});i(a)}e.settings.color_picker_callback||(e.settings.color_picker_callback=n)}); \ No newline at end of file diff --git a/wp-includes/js/tinymce/plugins/lists/plugin.js b/wp-includes/js/tinymce/plugins/lists/plugin.js new file mode 100644 index 0000000000..d764982610 --- /dev/null +++ b/wp-includes/js/tinymce/plugins/lists/plugin.js @@ -0,0 +1,769 @@ +/** + * plugin.js + * + * Copyright, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +/*global tinymce:true */ +/*eslint consistent-this:0 */ + +tinymce.PluginManager.add('lists', function(editor) { + var self = this; + + function isListNode(node) { + return node && (/^(OL|UL|DL)$/).test(node.nodeName); + } + + function isFirstChild(node) { + return node.parentNode.firstChild == node; + } + + function isLastChild(node) { + return node.parentNode.lastChild == node; + } + + function isTextBlock(node) { + return node && !!editor.schema.getTextBlockElements()[node.nodeName]; + } + + editor.on('init', function() { + var dom = editor.dom, selection = editor.selection; + + /** + * Returns a range bookmark. This will convert indexed bookmarks into temporary span elements with + * index 0 so that they can be restored properly after the DOM has been modified. Text bookmarks will not have spans + * added to them since they can be restored after a dom operation. + * + * So this:
||
+ * becomes:||
+ * + * @param {DOMRange} rng DOM Range to get bookmark on. + * @return {Object} Bookmark object. + */ + function createBookmark(rng) { + var bookmark = {}; + + function setupEndPoint(start) { + var offsetNode, container, offset; + + container = rng[start ? 'startContainer' : 'endContainer']; + offset = rng[start ? 'startOffset' : 'endOffset']; + + if (container.nodeType == 1) { + offsetNode = dom.create('span', {'data-mce-type': 'bookmark'}); + + if (container.hasChildNodes()) { + offset = Math.min(offset, container.childNodes.length - 1); + + if (start) { + container.insertBefore(offsetNode, container.childNodes[offset]); + } else { + dom.insertAfter(offsetNode, container.childNodes[offset]); + } + } else { + container.appendChild(offsetNode); + } + + container = offsetNode; + offset = 0; + } + + bookmark[start ? 'startContainer' : 'endContainer'] = container; + bookmark[start ? 'startOffset' : 'endOffset'] = offset; + } + + setupEndPoint(true); + + if (!rng.collapsed) { + setupEndPoint(); + } + + return bookmark; + } + + /** + * Moves the selection to the current bookmark and removes any selection container wrappers. + * + * @param {Object} bookmark Bookmark object to move selection to. + */ + function moveToBookmark(bookmark) { + function restoreEndPoint(start) { + var container, offset, node; + + function nodeIndex(container) { + var node = container.parentNode.firstChild, idx = 0; + + while (node) { + if (node == container) { + return idx; + } + + // Skip data-mce-type=bookmark nodes + if (node.nodeType != 1 || node.getAttribute('data-mce-type') != 'bookmark') { + idx++; + } + + node = node.nextSibling; + } + + return -1; + } + + container = node = bookmark[start ? 'startContainer' : 'endContainer']; + offset = bookmark[start ? 'startOffset' : 'endOffset']; + + if (!container) { + return; + } + + if (container.nodeType == 1) { + offset = nodeIndex(container); + container = container.parentNode; + dom.remove(node); + } + + bookmark[start ? 'startContainer' : 'endContainer'] = container; + bookmark[start ? 'startOffset' : 'endOffset'] = offset; + } + + restoreEndPoint(true); + restoreEndPoint(); + + var rng = dom.createRng(); + + rng.setStart(bookmark.startContainer, bookmark.startOffset); + + if (bookmark.endContainer) { + rng.setEnd(bookmark.endContainer, bookmark.endOffset); + } + + selection.setRng(rng); + } + + function createNewTextBlock(contentNode, blockName) { + var node, textBlock, fragment = dom.createFragment(), hasContentNode; + var blockElements = editor.schema.getBlockElements(); + + if (editor.settings.forced_root_block) { + blockName = blockName || editor.settings.forced_root_block; + } + + if (blockName) { + textBlock = dom.create(blockName); + + if (textBlock.tagName === editor.settings.forced_root_block) { + dom.setAttribs(textBlock, editor.settings.forced_root_block_attrs); + } + + fragment.appendChild(textBlock); + } + + if (contentNode) { + while ((node = contentNode.firstChild)) { + var nodeName = node.nodeName; + + if (!hasContentNode && (nodeName != 'SPAN' || node.getAttribute('data-mce-type') != 'bookmark')) { + hasContentNode = true; + } + + if (blockElements[nodeName]) { + fragment.appendChild(node); + textBlock = null; + } else { + if (blockName) { + if (!textBlock) { + textBlock = dom.create(blockName); + fragment.appendChild(textBlock); + } + + textBlock.appendChild(node); + } else { + fragment.appendChild(node); + } + } + } + } + + if (!editor.settings.forced_root_block) { + fragment.appendChild(dom.create('br')); + } else { + // BR is needed in empty blocks on non IE browsers + if (!hasContentNode && (!tinymce.Env.ie || tinymce.Env.ie > 10)) { + textBlock.appendChild(dom.create('br', {'data-mce-bogus': '1'})); + } + } + + return fragment; + } + + function getSelectedListItems() { + return tinymce.grep(selection.getSelectedBlocks(), function(block) { + return /^(LI|DT|DD)$/.test(block.nodeName); + }); + } + + function splitList(ul, li, newBlock) { + var tmpRng, fragment; + + var bookmarks = dom.select('span[data-mce-type="bookmark"]', ul); + + newBlock = newBlock || createNewTextBlock(li); + tmpRng = dom.createRng(); + tmpRng.setStartAfter(li); + tmpRng.setEndAfter(ul); + fragment = tmpRng.extractContents(); + + if (!dom.isEmpty(fragment)) { + dom.insertAfter(fragment, ul); + } + + dom.insertAfter(newBlock, ul); + + if (dom.isEmpty(li.parentNode)) { + tinymce.each(bookmarks, function(node) { + li.parentNode.parentNode.insertBefore(node, li.parentNode); + }); + + dom.remove(li.parentNode); + } + + dom.remove(li); + } + + function mergeWithAdjacentLists(listBlock) { + var sibling, node; + + sibling = listBlock.nextSibling; + if (sibling && isListNode(sibling) && sibling.nodeName == listBlock.nodeName) { + while ((node = sibling.firstChild)) { + listBlock.appendChild(node); + } + + dom.remove(sibling); + } + + sibling = listBlock.previousSibling; + if (sibling && isListNode(sibling) && sibling.nodeName == listBlock.nodeName) { + while ((node = sibling.firstChild)) { + listBlock.insertBefore(node, listBlock.firstChild); + } + + dom.remove(sibling); + } + } + + /** + * Normalizes the all lists in the specified element. + */ + function normalizeList(element) { + tinymce.each(tinymce.grep(dom.select('ol,ul', element)), function(ul) { + var sibling, parentNode = ul.parentNode; + + // Move UL/OL to previous LI if it's the only child of a LI + if (parentNode.nodeName == 'LI' && parentNode.firstChild == ul) { + sibling = parentNode.previousSibling; + if (sibling && sibling.nodeName == 'LI') { + sibling.appendChild(ul); + + if (dom.isEmpty(parentNode)) { + dom.remove(parentNode); + } + } + } + + // Append OL/UL to previous LI if it's in a parent OL/UL i.e. old HTML4 + if (isListNode(parentNode)) { + sibling = parentNode.previousSibling; + if (sibling && sibling.nodeName == 'LI') { + sibling.appendChild(ul); + } + } + }); + } + + function outdent(li) { + var ul = li.parentNode, ulParent = ul.parentNode, newBlock; + + function removeEmptyLi(li) { + if (dom.isEmpty(li)) { + dom.remove(li); + } + } + + if (li.nodeName == 'DD') { + dom.rename(li, 'DT'); + return true; + } + + if (isFirstChild(li) && isLastChild(li)) { + if (ulParent.nodeName == "LI") { + dom.insertAfter(li, ulParent); + removeEmptyLi(ulParent); + dom.remove(ul); + } else if (isListNode(ulParent)) { + dom.remove(ul, true); + } else { + ulParent.insertBefore(createNewTextBlock(li), ul); + dom.remove(ul); + } + + return true; + } else if (isFirstChild(li)) { + if (ulParent.nodeName == "LI") { + dom.insertAfter(li, ulParent); + li.appendChild(ul); + removeEmptyLi(ulParent); + } else if (isListNode(ulParent)) { + ulParent.insertBefore(li, ul); + } else { + ulParent.insertBefore(createNewTextBlock(li), ul); + dom.remove(li); + } + + return true; + } else if (isLastChild(li)) { + if (ulParent.nodeName == "LI") { + dom.insertAfter(li, ulParent); + } else if (isListNode(ulParent)) { + dom.insertAfter(li, ul); + } else { + dom.insertAfter(createNewTextBlock(li), ul); + dom.remove(li); + } + + return true; + } else { + if (ulParent.nodeName == 'LI') { + ul = ulParent; + newBlock = createNewTextBlock(li, 'LI'); + } else if (isListNode(ulParent)) { + newBlock = createNewTextBlock(li, 'LI'); + } else { + newBlock = createNewTextBlock(li); + } + + splitList(ul, li, newBlock); + normalizeList(ul.parentNode); + + return true; + } + + return false; + } + + function indent(li) { + var sibling, newList; + + function mergeLists(from, to) { + var node; + + if (isListNode(from)) { + while ((node = li.lastChild.firstChild)) { + to.appendChild(node); + } + + dom.remove(from); + } + } + + if (li.nodeName == 'DT') { + dom.rename(li, 'DD'); + return true; + } + + sibling = li.previousSibling; + + if (sibling && isListNode(sibling)) { + sibling.appendChild(li); + return true; + } + + if (sibling && sibling.nodeName == 'LI' && isListNode(sibling.lastChild)) { + sibling.lastChild.appendChild(li); + mergeLists(li.lastChild, sibling.lastChild); + return true; + } + + sibling = li.nextSibling; + + if (sibling && isListNode(sibling)) { + sibling.insertBefore(li, sibling.firstChild); + return true; + } + + if (sibling && sibling.nodeName == 'LI' && isListNode(li.lastChild)) { + return false; + } + + sibling = li.previousSibling; + if (sibling && sibling.nodeName == 'LI') { + newList = dom.create(li.parentNode.nodeName); + sibling.appendChild(newList); + newList.appendChild(li); + mergeLists(li.lastChild, newList); + return true; + } + + return false; + } + + function indentSelection() { + var listElements = getSelectedListItems(); + + if (listElements.length) { + var bookmark = createBookmark(selection.getRng(true)); + + for (var i = 0; i < listElements.length; i++) { + if (!indent(listElements[i]) && i === 0) { + break; + } + } + + moveToBookmark(bookmark); + editor.nodeChanged(); + + return true; + } + } + + function outdentSelection() { + var listElements = getSelectedListItems(); + + if (listElements.length) { + var bookmark = createBookmark(selection.getRng(true)); + var i, y, root = editor.getBody(); + + i = listElements.length; + while (i--) { + var node = listElements[i].parentNode; + + while (node && node != root) { + y = listElements.length; + while (y--) { + if (listElements[y] === node) { + listElements.splice(i, 1); + break; + } + } + + node = node.parentNode; + } + } + + for (i = 0; i < listElements.length; i++) { + if (!outdent(listElements[i]) && i === 0) { + break; + } + } + + moveToBookmark(bookmark); + editor.nodeChanged(); + + return true; + } + } + + function applyList(listName) { + var rng = selection.getRng(true), bookmark = createBookmark(rng), listItemName = 'LI'; + + listName = listName.toUpperCase(); + + if (listName == 'DL') { + listItemName = 'DT'; + } + + function getSelectedTextBlocks() { + var textBlocks = [], root = editor.getBody(); + + function getEndPointNode(start) { + var container, offset; + + container = rng[start ? 'startContainer' : 'endContainer']; + offset = rng[start ? 'startOffset' : 'endOffset']; + + // Resolve node index + if (container.nodeType == 1) { + container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container; + } + + while (container.parentNode != root) { + if (isTextBlock(container)) { + return container; + } + + if (/^(TD|TH)$/.test(container.parentNode.nodeName)) { + return container; + } + + container = container.parentNode; + } + + return container; + } + + var startNode = getEndPointNode(true); + var endNode = getEndPointNode(); + var block, siblings = []; + + for (var node = startNode; node; node = node.nextSibling) { + siblings.push(node); + + if (node == endNode) { + break; + } + } + + tinymce.each(siblings, function(node) { + if (isTextBlock(node)) { + textBlocks.push(node); + block = null; + return; + } + + if (dom.isBlock(node) || node.nodeName == 'BR') { + if (node.nodeName == 'BR') { + dom.remove(node); + } + + block = null; + return; + } + + var nextSibling = node.nextSibling; + if (tinymce.dom.BookmarkManager.isBookmarkNode(node)) { + if (isTextBlock(nextSibling) || (!nextSibling && node.parentNode == root)) { + block = null; + return; + } + } + + if (!block) { + block = dom.create('p'); + node.parentNode.insertBefore(block, node); + textBlocks.push(block); + } + + block.appendChild(node); + }); + + return textBlocks; + } + + tinymce.each(getSelectedTextBlocks(), function(block) { + var listBlock, sibling; + + sibling = block.previousSibling; + if (sibling && isListNode(sibling) && sibling.nodeName == listName) { + listBlock = sibling; + block = dom.rename(block, listItemName); + sibling.appendChild(block); + } else { + listBlock = dom.create(listName); + block.parentNode.insertBefore(listBlock, block); + listBlock.appendChild(block); + block = dom.rename(block, listItemName); + } + + mergeWithAdjacentLists(listBlock); + }); + + moveToBookmark(bookmark); + } + + function removeList() { + var bookmark = createBookmark(selection.getRng(true)), root = editor.getBody(); + + tinymce.each(getSelectedListItems(), function(li) { + var node, rootList; + + if (dom.isEmpty(li)) { + outdent(li); + return; + } + + for (node = li; node && node != root; node = node.parentNode) { + if (isListNode(node)) { + rootList = node; + } + } + + splitList(rootList, li); + }); + + moveToBookmark(bookmark); + } + + function toggleList(listName) { + var parentList = dom.getParent(selection.getStart(), 'OL,UL,DL'); + + if (parentList) { + if (parentList.nodeName == listName) { + removeList(listName); + } else { + var bookmark = createBookmark(selection.getRng(true)); + mergeWithAdjacentLists(dom.rename(parentList, listName)); + moveToBookmark(bookmark); + } + } else { + applyList(listName); + } + } + + function queryListCommandState(listName) { + return function() { + var parentList = dom.getParent(editor.selection.getStart(), 'UL,OL,DL'); + + return parentList && parentList.nodeName == listName; + }; + } + + self.backspaceDelete = function(isForward) { + function findNextCaretContainer(rng, isForward) { + var node = rng.startContainer, offset = rng.startOffset; + + if (node.nodeType == 3 && (isForward ? offset < node.data.length : offset > 0)) { + return node; + } + + var walker = new tinymce.dom.TreeWalker(rng.startContainer); + while ((node = walker[isForward ? 'next' : 'prev']())) { + if (node.nodeType == 3 && node.data.length > 0) { + return node; + } + } + } + + function mergeLiElements(fromElm, toElm) { + var node, listNode, ul = fromElm.parentNode; + + if (isListNode(toElm.lastChild)) { + listNode = toElm.lastChild; + } + + node = toElm.lastChild; + if (node && node.nodeName == 'BR' && fromElm.hasChildNodes()) { + dom.remove(node); + } + + while ((node = fromElm.firstChild)) { + toElm.appendChild(node); + } + + if (listNode) { + toElm.appendChild(listNode); + } + + dom.remove(fromElm); + + if (dom.isEmpty(ul)) { + dom.remove(ul); + } + } + + if (selection.isCollapsed()) { + var li = dom.getParent(selection.getStart(), 'LI'); + + if (li) { + var rng = selection.getRng(true); + var otherLi = dom.getParent(findNextCaretContainer(rng, isForward), 'LI'); + + if (otherLi && otherLi != li) { + var bookmark = createBookmark(rng); + + if (isForward) { + mergeLiElements(otherLi, li); + } else { + mergeLiElements(li, otherLi); + } + + moveToBookmark(bookmark); + + return true; + } else if (!otherLi) { + if (!isForward && removeList(li.parentNode.nodeName)) { + return true; + } + } + } + } + }; + + editor.addCommand('Indent', function() { + if (!indentSelection()) { + return true; + } + }); + + editor.addCommand('Outdent', function() { + if (!outdentSelection()) { + return true; + } + }); + + editor.addCommand('InsertUnorderedList', function() { + toggleList('UL'); + }); + + editor.addCommand('InsertOrderedList', function() { + toggleList('OL'); + }); + + editor.addCommand('InsertDefinitionList', function() { + toggleList('DL'); + }); + + editor.addQueryStateHandler('InsertUnorderedList', queryListCommandState('UL')); + editor.addQueryStateHandler('InsertOrderedList', queryListCommandState('OL')); + editor.addQueryStateHandler('InsertDefinitionList', queryListCommandState('DL')); + + editor.on('keydown', function(e) { + if (e.keyCode == 9 && editor.dom.getParent(editor.selection.getStart(), 'LI,DT,DD')) { + e.preventDefault(); + + if (e.shiftKey) { + outdentSelection(); + } else { + indentSelection(); + } + } + }); + }); + + editor.addButton('indent', { + icon: 'indent', + title: 'Increase indent', + cmd: 'Indent', + onPostRender: function() { + var ctrl = this; + + editor.on('nodechange', function() { + var blocks = editor.selection.getSelectedBlocks(); + var disable = false; + + for (var i = 0, l = blocks.length; !disable && i < l; i++) { + var tag = blocks[i].nodeName; + + disable = (tag == 'LI' && isFirstChild(blocks[i]) || tag == 'UL' || tag == 'OL' || tag == 'DD'); + } + + ctrl.disabled(disable); + }); + } + }); + + editor.on('keydown', function(e) { + if (e.keyCode == tinymce.util.VK.BACKSPACE) { + if (self.backspaceDelete()) { + e.preventDefault(); + } + } else if (e.keyCode == tinymce.util.VK.DELETE) { + if (self.backspaceDelete(true)) { + e.preventDefault(); + } + } + }); +}); diff --git a/wp-includes/js/tinymce/plugins/lists/plugin.min.js b/wp-includes/js/tinymce/plugins/lists/plugin.min.js new file mode 100644 index 0000000000..cf0e600dd8 --- /dev/null +++ b/wp-includes/js/tinymce/plugins/lists/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("lists",function(e){function t(e){return e&&/^(OL|UL|DL)$/.test(e.nodeName)}function n(e){return e.parentNode.firstChild==e}function r(e){return e.parentNode.lastChild==e}function a(t){return t&&!!e.schema.getTextBlockElements()[t.nodeName]}var o=this;e.on("init",function(){function i(e){function t(t){var r,a,o;a=e[t?"startContainer":"endContainer"],o=e[t?"startOffset":"endOffset"],1==a.nodeType&&(r=y.create("span",{"data-mce-type":"bookmark"}),a.hasChildNodes()?(o=Math.min(o,a.childNodes.length-1),t?a.insertBefore(r,a.childNodes[o]):y.insertAfter(r,a.childNodes[o])):a.appendChild(r),a=r,o=0),n[t?"startContainer":"endContainer"]=a,n[t?"startOffset":"endOffset"]=o}var n={};return t(!0),e.collapsed||t(),n}function d(e){function t(t){function n(e){for(var t=e.parentNode.firstChild,n=0;t;){if(t==e)return n;(1!=t.nodeType||"bookmark"!=t.getAttribute("data-mce-type"))&&n++,t=t.nextSibling}return-1}var r,a,o;r=o=e[t?"startContainer":"endContainer"],a=e[t?"startOffset":"endOffset"],r&&(1==r.nodeType&&(a=n(r),r=r.parentNode,y.remove(o)),e[t?"startContainer":"endContainer"]=r,e[t?"startOffset":"endOffset"]=a)}t(!0),t();var n=y.createRng();n.setStart(e.startContainer,e.startOffset),e.endContainer&&n.setEnd(e.endContainer,e.endOffset),k.setRng(n)}function s(t,n){var r,a,o,i=y.createFragment(),d=e.schema.getBlockElements();if(e.settings.forced_root_block&&(n=n||e.settings.forced_root_block),n&&(a=y.create(n),a.tagName===e.settings.forced_root_block&&y.setAttribs(a,e.settings.forced_root_block_attrs),i.appendChild(a)),t)for(;r=t.firstChild;){var s=r.nodeName;o||"SPAN"==s&&"bookmark"==r.getAttribute("data-mce-type")||(o=!0),d[s]?(i.appendChild(r),a=null):n?(a||(a=y.create(n),i.appendChild(a)),a.appendChild(r)):i.appendChild(r)}return e.settings.forced_root_block?o||tinymce.Env.ie&&!(tinymce.Env.ie>10)||a.appendChild(y.create("br",{"data-mce-bogus":"1"})):i.appendChild(y.create("br")),i}function f(){return tinymce.grep(k.getSelectedBlocks(),function(e){return/^(LI|DT|DD)$/.test(e.nodeName)})}function l(e,t,n){var r,a,o=y.select('span[data-mce-type="bookmark"]',e);n=n||s(t),r=y.createRng(),r.setStartAfter(t),r.setEndAfter(e),a=r.extractContents(),y.isEmpty(a)||y.insertAfter(a,e),y.insertAfter(n,e),y.isEmpty(t.parentNode)&&(tinymce.each(o,function(e){t.parentNode.parentNode.insertBefore(e,t.parentNode)}),y.remove(t.parentNode)),y.remove(t)}function c(e){var n,r;if(n=e.nextSibling,n&&t(n)&&n.nodeName==e.nodeName){for(;r=n.firstChild;)e.appendChild(r);y.remove(n)}if(n=e.previousSibling,n&&t(n)&&n.nodeName==e.nodeName){for(;r=n.firstChild;)e.insertBefore(r,e.firstChild);y.remove(n)}}function p(e){tinymce.each(tinymce.grep(y.select("ol,ul",e)),function(e){var n,r=e.parentNode;"LI"==r.nodeName&&r.firstChild==e&&(n=r.previousSibling,n&&"LI"==n.nodeName&&(n.appendChild(e),y.isEmpty(r)&&y.remove(r))),t(r)&&(n=r.previousSibling,n&&"LI"==n.nodeName&&n.appendChild(e))})}function m(e){function a(e){y.isEmpty(e)&&y.remove(e)}var o,i=e.parentNode,d=i.parentNode;return"DD"==e.nodeName?(y.rename(e,"DT"),!0):n(e)&&r(e)?("LI"==d.nodeName?(y.insertAfter(e,d),a(d),y.remove(i)):t(d)?y.remove(i,!0):(d.insertBefore(s(e),i),y.remove(i)),!0):n(e)?("LI"==d.nodeName?(y.insertAfter(e,d),e.appendChild(i),a(d)):t(d)?d.insertBefore(e,i):(d.insertBefore(s(e),i),y.remove(e)),!0):r(e)?("LI"==d.nodeName?y.insertAfter(e,d):t(d)?y.insertAfter(e,i):(y.insertAfter(s(e),i),y.remove(e)),!0):("LI"==d.nodeName?(i=d,o=s(e,"LI")):o=t(d)?s(e,"LI"):s(e),l(i,e,o),p(i.parentNode),!0)}function u(e){function n(n,r){var a;if(t(n)){for(;a=e.lastChild.firstChild;)r.appendChild(a);y.remove(n)}}var r,a;return"DT"==e.nodeName?(y.rename(e,"DD"),!0):(r=e.previousSibling,r&&t(r)?(r.appendChild(e),!0):r&&"LI"==r.nodeName&&t(r.lastChild)?(r.lastChild.appendChild(e),n(e.lastChild,r.lastChild),!0):(r=e.nextSibling,r&&t(r)?(r.insertBefore(e,r.firstChild),!0):r&&"LI"==r.nodeName&&t(e.lastChild)?!1:(r=e.previousSibling,r&&"LI"==r.nodeName?(a=y.create(e.parentNode.nodeName),r.appendChild(a),a.appendChild(e),n(e.lastChild,a),!0):!1)))}function h(){var t=f();if(t.length){for(var n=i(k.getRng(!0)),r=0;r