diff -r 318533413200 -r a1707c607eec src/pyams_skin/resources/js/ext/tinymce/dev/classes/EditorCommands.js --- a/src/pyams_skin/resources/js/ext/tinymce/dev/classes/EditorCommands.js Sun Jul 19 02:02:20 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,999 +0,0 @@ -/** - * EditorCommands.js - * - * Copyright, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://www.tinymce.com/license - * Contributing: http://www.tinymce.com/contributing - */ - -/** - * This class enables you to add custom editor commands and it contains - * overrides for native browser commands to address various bugs and issues. - * - * @class tinymce.EditorCommands - */ -define("tinymce/EditorCommands", [ - "tinymce/html/Serializer", - "tinymce/Env", - "tinymce/util/Tools", - "tinymce/dom/ElementUtils", - "tinymce/dom/RangeUtils", - "tinymce/dom/TreeWalker" -], function(Serializer, Env, Tools, ElementUtils, RangeUtils, TreeWalker) { - // Added for compression purposes - var each = Tools.each, extend = Tools.extend; - var map = Tools.map, inArray = Tools.inArray, explode = Tools.explode; - var isGecko = Env.gecko, isIE = Env.ie, isOldIE = Env.ie && Env.ie < 11; - var TRUE = true, FALSE = false; - - return function(editor) { - var dom, selection, formatter, - commands = {state: {}, exec: {}, value: {}}, - settings = editor.settings, - bookmark; - - editor.on('PreInit', function() { - dom = editor.dom; - selection = editor.selection; - settings = editor.settings; - formatter = editor.formatter; - }); - - /** - * Executes the specified command. - * - * @method execCommand - * @param {String} command Command to execute. - * @param {Boolean} ui Optional user interface state. - * @param {Object} value Optional value for command. - * @return {Boolean} true/false if the command was found or not. - */ - function execCommand(command, ui, value, args) { - var func, customCommand, state = 0; - - if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(command) && (!args || !args.skip_focus)) { - editor.focus(); - } - - args = extend({}, args); - args = editor.fire('BeforeExecCommand', {command: command, ui: ui, value: value}); - if (args.isDefaultPrevented()) { - return false; - } - - customCommand = command.toLowerCase(); - if ((func = commands.exec[customCommand])) { - func(customCommand, ui, value); - editor.fire('ExecCommand', {command: command, ui: ui, value: value}); - return true; - } - - // Plugin commands - each(editor.plugins, function(p) { - if (p.execCommand && p.execCommand(command, ui, value)) { - editor.fire('ExecCommand', {command: command, ui: ui, value: value}); - state = true; - return false; - } - }); - - if (state) { - return state; - } - - // Theme commands - if (editor.theme && editor.theme.execCommand && editor.theme.execCommand(command, ui, value)) { - editor.fire('ExecCommand', {command: command, ui: ui, value: value}); - return true; - } - - // Browser commands - try { - state = editor.getDoc().execCommand(command, ui, value); - } catch (ex) { - // Ignore old IE errors - } - - if (state) { - editor.fire('ExecCommand', {command: command, ui: ui, value: value}); - return true; - } - - return false; - } - - /** - * Queries the current state for a command for example if the current selection is "bold". - * - * @method queryCommandState - * @param {String} command Command to check the state of. - * @return {Boolean/Number} true/false if the selected contents is bold or not, -1 if it's not found. - */ - function queryCommandState(command) { - var func; - - // Is hidden then return undefined - if (editor._isHidden()) { - return; - } - - command = command.toLowerCase(); - if ((func = commands.state[command])) { - return func(command); - } - - // Browser commands - try { - return editor.getDoc().queryCommandState(command); - } catch (ex) { - // Fails sometimes see bug: 1896577 - } - - return false; - } - - /** - * Queries the command value for example the current fontsize. - * - * @method queryCommandValue - * @param {String} command Command to check the value of. - * @return {Object} Command value of false if it's not found. - */ - function queryCommandValue(command) { - var func; - - // Is hidden then return undefined - if (editor._isHidden()) { - return; - } - - command = command.toLowerCase(); - if ((func = commands.value[command])) { - return func(command); - } - - // Browser commands - try { - return editor.getDoc().queryCommandValue(command); - } catch (ex) { - // Fails sometimes see bug: 1896577 - } - } - - /** - * Adds commands to the command collection. - * - * @method addCommands - * @param {Object} command_list Name/value collection with commands to add, the names can also be comma separated. - * @param {String} type Optional type to add, defaults to exec. Can be value or state as well. - */ - function addCommands(command_list, type) { - type = type || 'exec'; - - each(command_list, function(callback, command) { - each(command.toLowerCase().split(','), function(command) { - commands[type][command] = callback; - }); - }); - } - - function addCommand(command, callback, scope) { - command = command.toLowerCase(); - commands.exec[command] = function(command, ui, value, args) { - return callback.call(scope || editor, ui, value, args); - }; - } - - /** - * Returns true/false if the command is supported or not. - * - * @method queryCommandSupported - * @param {String} cmd Command that we check support for. - * @return {Boolean} true/false if the command is supported or not. - */ - function queryCommandSupported(command) { - command = command.toLowerCase(); - - if (commands.exec[command]) { - return true; - } - - // Browser commands - try { - return editor.getDoc().queryCommandSupported(command); - } catch (ex) { - // Fails sometimes see bug: 1896577 - } - - return false; - } - - function addQueryStateHandler(command, callback, scope) { - command = command.toLowerCase(); - commands.state[command] = function() { - return callback.call(scope || editor); - }; - } - - function addQueryValueHandler(command, callback, scope) { - command = command.toLowerCase(); - commands.value[command] = function() { - return callback.call(scope || editor); - }; - } - - function hasCustomCommand(command) { - command = command.toLowerCase(); - return !!commands.exec[command]; - } - - // Expose public methods - extend(this, { - execCommand: execCommand, - queryCommandState: queryCommandState, - queryCommandValue: queryCommandValue, - queryCommandSupported: queryCommandSupported, - addCommands: addCommands, - addCommand: addCommand, - addQueryStateHandler: addQueryStateHandler, - addQueryValueHandler: addQueryValueHandler, - hasCustomCommand: hasCustomCommand - }); - - // Private methods - - function execNativeCommand(command, ui, value) { - if (ui === undefined) { - ui = FALSE; - } - - if (value === undefined) { - value = null; - } - - return editor.getDoc().execCommand(command, ui, value); - } - - function isFormatMatch(name) { - return formatter.match(name); - } - - function toggleFormat(name, value) { - formatter.toggle(name, value ? {value: value} : undefined); - editor.nodeChanged(); - } - - function storeSelection(type) { - bookmark = selection.getBookmark(type); - } - - function restoreSelection() { - selection.moveToBookmark(bookmark); - } - - // Add execCommand overrides - addCommands({ - // Ignore these, added for compatibility - 'mceResetDesignMode,mceBeginUndoLevel': function() {}, - - // Add undo manager logic - 'mceEndUndoLevel,mceAddUndoLevel': function() { - editor.undoManager.add(); - }, - - 'Cut,Copy,Paste': function(command) { - var doc = editor.getDoc(), failed; - - // Try executing the native command - try { - execNativeCommand(command); - } catch (ex) { - // Command failed - failed = TRUE; - } - - // Present alert message about clipboard access not being available - if (failed || !doc.queryCommandSupported(command)) { - var msg = editor.translate( - "Your browser doesn't support direct access to the clipboard. " + - "Please use the Ctrl+X/C/V keyboard shortcuts instead." - ); - - if (Env.mac) { - msg = msg.replace(/Ctrl\+/g, '\u2318+'); - } - - editor.windowManager.alert(msg); - } - }, - - // Override unlink command - unlink: function() { - if (selection.isCollapsed()) { - var elm = selection.getNode(); - if (elm.tagName == 'A') { - editor.dom.remove(elm, true); - } - - return; - } - - formatter.remove("link"); - }, - - // Override justify commands to use the text formatter engine - 'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull': function(command) { - var align = command.substring(7); - - if (align == 'full') { - align = 'justify'; - } - - // Remove all other alignments first - each('left,center,right,justify'.split(','), function(name) { - if (align != name) { - formatter.remove('align' + name); - } - }); - - toggleFormat('align' + align); - execCommand('mceRepaint'); - }, - - // Override list commands to fix WebKit bug - 'InsertUnorderedList,InsertOrderedList': function(command) { - var listElm, listParent; - - execNativeCommand(command); - - // WebKit produces lists within block elements so we need to split them - // we will replace the native list creation logic to custom logic later on - // TODO: Remove this when the list creation logic is removed - listElm = dom.getParent(selection.getNode(), 'ol,ul'); - if (listElm) { - listParent = listElm.parentNode; - - // If list is within a text block then split that block - if (/^(H[1-6]|P|ADDRESS|PRE)$/.test(listParent.nodeName)) { - storeSelection(); - dom.split(listParent, listElm); - restoreSelection(); - } - } - }, - - // Override commands to use the text formatter engine - 'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function(command) { - toggleFormat(command); - }, - - // Override commands to use the text formatter engine - 'ForeColor,HiliteColor,FontName': function(command, ui, value) { - toggleFormat(command, value); - }, - - FontSize: function(command, ui, value) { - var fontClasses, fontSizes; - - // Convert font size 1-7 to styles - if (value >= 1 && value <= 7) { - fontSizes = explode(settings.font_size_style_values); - fontClasses = explode(settings.font_size_classes); - - if (fontClasses) { - value = fontClasses[value - 1] || value; - } else { - value = fontSizes[value - 1] || value; - } - } - - toggleFormat(command, value); - }, - - RemoveFormat: function(command) { - formatter.remove(command); - }, - - mceBlockQuote: function() { - toggleFormat('blockquote'); - }, - - FormatBlock: function(command, ui, value) { - return toggleFormat(value || 'p'); - }, - - mceCleanup: function() { - var bookmark = selection.getBookmark(); - - editor.setContent(editor.getContent({cleanup: TRUE}), {cleanup: TRUE}); - - selection.moveToBookmark(bookmark); - }, - - mceRemoveNode: function(command, ui, value) { - var node = value || selection.getNode(); - - // Make sure that the body node isn't removed - if (node != editor.getBody()) { - storeSelection(); - editor.dom.remove(node, TRUE); - restoreSelection(); - } - }, - - mceSelectNodeDepth: function(command, ui, value) { - var counter = 0; - - dom.getParent(selection.getNode(), function(node) { - if (node.nodeType == 1 && counter++ == value) { - selection.select(node); - return FALSE; - } - }, editor.getBody()); - }, - - mceSelectNode: function(command, ui, value) { - selection.select(value); - }, - - mceInsertContent: function(command, ui, value) { - var parser, serializer, parentNode, rootNode, fragment, args; - var marker, rng, node, node2, bookmarkHtml, merge; - var textInlineElements = editor.schema.getTextInlineElements(); - - function trimOrPaddLeftRight(html) { - var rng, container, offset; - - rng = selection.getRng(true); - container = rng.startContainer; - offset = rng.startOffset; - - function hasSiblingText(siblingName) { - return container[siblingName] && container[siblingName].nodeType == 3; - } - - if (container.nodeType == 3) { - if (offset > 0) { - html = html.replace(/^ /, ' '); - } else if (!hasSiblingText('previousSibling')) { - html = html.replace(/^ /, ' '); - } - - if (offset < container.length) { - html = html.replace(/ (
|)$/, ' '); - } else if (!hasSiblingText('nextSibling')) { - html = html.replace(/( | )(
|)$/, ' '); - } - } - - return html; - } - - // Removes   from a [b] c -> a  c -> a c - function trimNbspAfterDeleteAndPaddValue() { - var rng, container, offset; - - rng = selection.getRng(true); - container = rng.startContainer; - offset = rng.startOffset; - - if (container.nodeType == 3 && rng.collapsed) { - if (container.data[offset] === '\u00a0') { - container.deleteData(offset, 1); - - if (!/[\u00a0| ]$/.test(value)) { - value += ' '; - } - } else if (container.data[offset - 1] === '\u00a0') { - container.deleteData(offset - 1, 1); - - if (!/[\u00a0| ]$/.test(value)) { - value = ' ' + value; - } - } - } - } - - function markInlineFormatElements(fragment) { - if (merge) { - for (node = fragment.firstChild; node; node = node.walk(true)) { - if (textInlineElements[node.name]) { - node.attr('data-mce-new', "true"); - } - } - } - } - - function reduceInlineTextElements() { - if (merge) { - var root = editor.getBody(), elementUtils = new ElementUtils(dom); - - each(dom.select('*[data-mce-new]'), function(node) { - node.removeAttribute('data-mce-new'); - - for (var testNode = node.parentNode; testNode && testNode != root; testNode = testNode.parentNode) { - if (elementUtils.compare(testNode, node)) { - dom.remove(node, true); - } - } - }); - } - } - - if (typeof value != 'string') { - merge = value.merge; - value = value.content; - } - - // Check for whitespace before/after value - if (/^ | $/.test(value)) { - value = trimOrPaddLeftRight(value); - } - - // Setup parser and serializer - parser = editor.parser; - serializer = new Serializer({}, editor.schema); - bookmarkHtml = '​'; - - // Run beforeSetContent handlers on the HTML to be inserted - args = {content: value, format: 'html', selection: true}; - editor.fire('BeforeSetContent', args); - value = args.content; - - // Add caret at end of contents if it's missing - if (value.indexOf('{$caret}') == -1) { - value += '{$caret}'; - } - - // Replace the caret marker with a span bookmark element - value = value.replace(/\{\$caret\}/, bookmarkHtml); - - // If selection is at |

then move it into

|

- rng = selection.getRng(); - var caretElement = rng.startContainer || (rng.parentElement ? rng.parentElement() : null); - var body = editor.getBody(); - if (caretElement === body && selection.isCollapsed()) { - if (dom.isBlock(body.firstChild) && dom.isEmpty(body.firstChild)) { - rng = dom.createRng(); - rng.setStart(body.firstChild, 0); - rng.setEnd(body.firstChild, 0); - selection.setRng(rng); - } - } - - // Insert node maker where we will insert the new HTML and get it's parent - if (!selection.isCollapsed()) { - editor.getDoc().execCommand('Delete', false, null); - trimNbspAfterDeleteAndPaddValue(); - } - - parentNode = selection.getNode(); - - // Parse the fragment within the context of the parent node - var parserArgs = {context: parentNode.nodeName.toLowerCase()}; - fragment = parser.parse(value, parserArgs); - - markInlineFormatElements(fragment); - - // Move the caret to a more suitable location - node = fragment.lastChild; - if (node.attr('id') == 'mce_marker') { - marker = node; - - 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; - } - } - } - - // If parser says valid we can insert the contents into that parent - if (!parserArgs.invalid) { - value = serializer.serialize(fragment); - - // Check if parent is empty or only has one BR element then set the innerHTML of that parent - node = parentNode.firstChild; - node2 = parentNode.lastChild; - if (!node || (node === node2 && node.nodeName === 'BR')) { - dom.setHTML(parentNode, value); - } else { - selection.setContent(value); - } - } else { - // If the fragment was invalid within that context then we need - // to parse and process the parent it's inserted into - - // Insert bookmark node and get the parent - selection.setContent(bookmarkHtml); - parentNode = selection.getNode(); - rootNode = editor.getBody(); - - // Opera will return the document node when selection is in root - if (parentNode.nodeType == 9) { - parentNode = node = rootNode; - } else { - node = parentNode; - } - - // Find the ancestor just before the root element - while (node !== rootNode) { - parentNode = node; - node = node.parentNode; - } - - // Get the outer/inner HTML depending on if we are in the root and parser and serialize that - value = parentNode == rootNode ? rootNode.innerHTML : dom.getOuterHTML(parentNode); - value = serializer.serialize( - parser.parse( - // Need to replace by using a function since $ in the contents would otherwise be a problem - value.replace(//i, function() { - return serializer.serialize(fragment); - }) - ) - ); - - // Set the inner/outer HTML depending on if we are in the root or not - if (parentNode == rootNode) { - dom.setHTML(rootNode, value); - } else { - dom.setOuterHTML(parentNode, value); - } - } - - reduceInlineTextElements(); - - marker = dom.get('mce_marker'); - selection.scrollIntoView(marker); - - // Move selection before marker and remove it - rng = dom.createRng(); - - // If previous sibling is a text node set the selection to the end of that node - node = marker.previousSibling; - if (node && node.nodeType == 3) { - rng.setStart(node, node.nodeValue.length); - - // TODO: Why can't we normalize on IE - if (!isIE) { - node2 = marker.nextSibling; - if (node2 && node2.nodeType == 3) { - node.appendData(node2.data); - node2.parentNode.removeChild(node2); - } - } - } else { - // If the previous sibling isn't a text node or doesn't exist set the selection before the marker node - rng.setStartBefore(marker); - rng.setEndBefore(marker); - } - - // Remove the marker node and set the new range - dom.remove(marker); - selection.setRng(rng); - - // Dispatch after event and add any visual elements needed - editor.fire('SetContent', args); - editor.addVisual(); - }, - - mceInsertRawHTML: function(command, ui, value) { - selection.setContent('tiny_mce_marker'); - editor.setContent( - editor.getContent().replace(/tiny_mce_marker/g, function() { - return value; - }) - ); - }, - - mceToggleFormat: function(command, ui, value) { - toggleFormat(value); - }, - - mceSetContent: function(command, ui, value) { - editor.setContent(value); - }, - - 'Indent,Outdent': function(command) { - var intentValue, indentUnit, value; - - // Setup indent level - intentValue = settings.indentation; - indentUnit = /[a-z%]+$/i.exec(intentValue); - intentValue = parseInt(intentValue, 10); - - if (!queryCommandState('InsertUnorderedList') && !queryCommandState('InsertOrderedList')) { - // If forced_root_blocks is set to false we don't have a block to indent so lets create a div - if (!settings.forced_root_block && !dom.getParent(selection.getNode(), dom.isBlock)) { - formatter.apply('div'); - } - - each(selection.getSelectedBlocks(), function(element) { - if (element.nodeName != "LI") { - var indentStyleName = editor.getParam('indent_use_margin', false) ? 'margin' : 'padding'; - - indentStyleName += dom.getStyle(element, 'direction', true) == 'rtl' ? 'Right' : 'Left'; - - if (command == 'outdent') { - value = Math.max(0, parseInt(element.style[indentStyleName] || 0, 10) - intentValue); - dom.setStyle(element, indentStyleName, value ? value + indentUnit : ''); - } else { - value = (parseInt(element.style[indentStyleName] || 0, 10) + intentValue) + indentUnit; - dom.setStyle(element, indentStyleName, value); - } - } - }); - } else { - execNativeCommand(command); - } - }, - - mceRepaint: function() { - if (isGecko) { - try { - storeSelection(TRUE); - - if (selection.getSel()) { - selection.getSel().selectAllChildren(editor.getBody()); - } - - selection.collapse(TRUE); - restoreSelection(); - } catch (ex) { - // Ignore - } - } - }, - - InsertHorizontalRule: function() { - editor.execCommand('mceInsertContent', false, '
'); - }, - - mceToggleVisualAid: function() { - editor.hasVisual = !editor.hasVisual; - editor.addVisual(); - }, - - mceReplaceContent: function(command, ui, value) { - editor.execCommand('mceInsertContent', false, value.replace(/\{\$selection\}/g, selection.getContent({format: 'text'}))); - }, - - mceInsertLink: function(command, ui, value) { - var anchor; - - if (typeof value == 'string') { - value = {href: value}; - } - - anchor = dom.getParent(selection.getNode(), 'a'); - - // Spaces are never valid in URLs and it's a very common mistake for people to make so we fix it here. - value.href = value.href.replace(' ', '%20'); - - // Remove existing links if there could be child links or that the href isn't specified - if (!anchor || !value.href) { - formatter.remove('link'); - } - - // Apply new link to selection - if (value.href) { - formatter.apply('link', value, anchor); - } - }, - - selectAll: function() { - var root = dom.getRoot(), rng; - - if (selection.getRng().setStart) { - rng = dom.createRng(); - rng.setStart(root, 0); - rng.setEnd(root, root.childNodes.length); - selection.setRng(rng); - } else { - // IE will render it's own root level block elements and sometimes - // even put font elements in them when the user starts typing. So we need to - // move the selection to a more suitable element from this: - // |

to this:

|

- rng = selection.getRng(); - if (!rng.item) { - rng.moveToElementText(root); - rng.select(); - } - } - }, - - "delete": function() { - execNativeCommand("Delete"); - - // Check if body is empty after the delete call if so then set the contents - // to an empty string and move the caret to any block produced by that operation - // this fixes the issue with root blocks not being properly produced after a delete call on IE - var body = editor.getBody(); - - if (dom.isEmpty(body)) { - editor.setContent(''); - - if (body.firstChild && dom.isBlock(body.firstChild)) { - editor.selection.setCursorLocation(body.firstChild, 0); - } else { - editor.selection.setCursorLocation(body, 0); - } - } - }, - - mceNewDocument: function() { - editor.setContent(''); - }, - - InsertLineBreak: function(command, ui, value) { - // We load the current event in from EnterKey.js when appropriate to heed - // certain event-specific variations such as ctrl-enter in a list - var evt = value; - var brElm, extraBr, marker; - var rng = selection.getRng(true); - new RangeUtils(dom).normalize(rng); - - var offset = rng.startOffset; - var container = rng.startContainer; - - // Resolve node index - if (container.nodeType == 1 && container.hasChildNodes()) { - var isAfterLastNodeInContainer = offset > container.childNodes.length - 1; - - container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container; - if (isAfterLastNodeInContainer && container.nodeType == 3) { - offset = container.nodeValue.length; - } else { - offset = 0; - } - } - - var parentBlock = dom.getParent(container, dom.isBlock); - var parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5 - var containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null; - var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5 - - // Enter inside block contained within a LI then split or insert before/after LI - var isControlKey = evt && evt.ctrlKey; - if (containerBlockName == 'LI' && !isControlKey) { - parentBlock = containerBlock; - parentBlockName = containerBlockName; - } - - // Walks the parent block to the right and look for BR elements - function hasRightSideContent() { - var walker = new TreeWalker(container, parentBlock), node; - var nonEmptyElementsMap = editor.schema.getNonEmptyElements(); - - while ((node = walker.next())) { - if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) { - return true; - } - } - } - - if (container && container.nodeType == 3 && offset >= container.nodeValue.length) { - // Insert extra BR element at the end block elements - if (!isOldIE && !hasRightSideContent()) { - brElm = dom.create('br'); - rng.insertNode(brElm); - rng.setStartAfter(brElm); - rng.setEndAfter(brElm); - extraBr = true; - } - } - - brElm = dom.create('br'); - rng.insertNode(brElm); - - // Rendering modes below IE8 doesn't display BR elements in PRE unless we have a \n before it - var documentMode = dom.doc.documentMode; - if (isOldIE && parentBlockName == 'PRE' && (!documentMode || documentMode < 8)) { - brElm.parentNode.insertBefore(dom.doc.createTextNode('\r'), brElm); - } - - // Insert temp marker and scroll to that - marker = dom.create('span', {}, ' '); - brElm.parentNode.insertBefore(marker, brElm); - selection.scrollIntoView(marker); - dom.remove(marker); - - if (!extraBr) { - rng.setStartAfter(brElm); - rng.setEndAfter(brElm); - } else { - rng.setStartBefore(brElm); - rng.setEndBefore(brElm); - } - - selection.setRng(rng); - editor.undoManager.add(); - - return TRUE; - } - }); - - // Add queryCommandState overrides - addCommands({ - // Override justify commands - 'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull': function(command) { - var name = 'align' + command.substring(7); - var nodes = selection.isCollapsed() ? [dom.getParent(selection.getNode(), dom.isBlock)] : selection.getSelectedBlocks(); - var matches = map(nodes, function(node) { - return !!formatter.matchNode(node, name); - }); - return inArray(matches, TRUE) !== -1; - }, - - 'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function(command) { - return isFormatMatch(command); - }, - - mceBlockQuote: function() { - return isFormatMatch('blockquote'); - }, - - Outdent: function() { - var node; - - if (settings.inline_styles) { - if ((node = dom.getParent(selection.getStart(), dom.isBlock)) && parseInt(node.style.paddingLeft, 10) > 0) { - return TRUE; - } - - if ((node = dom.getParent(selection.getEnd(), dom.isBlock)) && parseInt(node.style.paddingLeft, 10) > 0) { - return TRUE; - } - } - - return ( - queryCommandState('InsertUnorderedList') || - queryCommandState('InsertOrderedList') || - (!settings.inline_styles && !!dom.getParent(selection.getNode(), 'BLOCKQUOTE')) - ); - }, - - 'InsertUnorderedList,InsertOrderedList': function(command) { - var list = dom.getParent(selection.getNode(), 'ul,ol'); - - return list && - ( - command === 'insertunorderedlist' && list.tagName === 'UL' || - command === 'insertorderedlist' && list.tagName === 'OL' - ); - } - }, 'state'); - - // Add queryCommandValue overrides - addCommands({ - 'FontSize,FontName': function(command) { - var value = 0, parent; - - if ((parent = dom.getParent(selection.getNode(), 'span'))) { - if (command == 'fontsize') { - value = parent.style.fontSize; - } else { - value = parent.style.fontFamily.replace(/, /g, ',').replace(/[\'\"]/g, '').toLowerCase(); - } - } - - return value; - } - }, 'value'); - - // Add undo manager logic - addCommands({ - Undo: function() { - editor.undoManager.undo(); - }, - - Redo: function() { - editor.undoManager.redo(); - } - }); - }; -});