PHP Classes

File: public/js/tinymce/src/core/src/main/js/fmt/ApplyFormat.js

Recommend this page to a friend!
  Classes of Abed Nego Ragil Putra   GoLavaCMS   public/js/tinymce/src/core/src/main/js/fmt/ApplyFormat.js   Download  
File: public/js/tinymce/src/core/src/main/js/fmt/ApplyFormat.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: GoLavaCMS
Publish content on Web pages with SEO support
Author: By
Last change:
Date: 6 years ago
Size: 12,304 bytes
 

Contents

Class file image Download
/** * ApplyFormat.js * * Released under LGPL License. * Copyright (c) 1999-2017 Ephox Corp. All rights reserved * * License: http://www.tinymce.com/license * Contributing: http://www.tinymce.com/contributing */ define( 'tinymce.core.fmt.ApplyFormat', [ 'tinymce.core.dom.Bookmarks', 'tinymce.core.dom.NodeType', 'tinymce.core.fmt.CaretFormat', 'tinymce.core.fmt.ExpandRange', 'tinymce.core.fmt.FormatUtils', 'tinymce.core.fmt.Hooks', 'tinymce.core.fmt.MatchFormat', 'tinymce.core.fmt.MergeFormats', 'tinymce.core.selection.RangeNormalizer', 'tinymce.core.selection.RangeWalk', 'tinymce.core.util.Tools' ], function (Bookmarks, NodeType, CaretFormat, ExpandRange, FormatUtils, Hooks, MatchFormat, MergeFormats, RangeNormalizer, RangeWalk, Tools) { var each = Tools.each; var isElementNode = function (node) { return node && node.nodeType === 1 && !Bookmarks.isBookmarkNode(node) && !CaretFormat.isCaretNode(node) && !NodeType.isBogus(node); }; var processChildElements = function (node, filter, process) { each(node.childNodes, function (node) { if (isElementNode(node)) { if (filter(node)) { process(node); } if (node.hasChildNodes()) { processChildElements(node, filter, process); } } }); }; var applyFormat = function (ed, name, vars, node) { var formatList = ed.formatter.get(name), format = formatList[0], bookmark, rng, isCollapsed = !node && ed.selection.isCollapsed(); var dom = ed.dom, selection = ed.selection; var setElementFormat = function (elm, fmt) { fmt = fmt || format; if (elm) { if (fmt.onformat) { fmt.onformat(elm, fmt, vars, node); } each(fmt.styles, function (value, name) { dom.setStyle(elm, name, FormatUtils.replaceVars(value, vars)); }); // Needed for the WebKit span spam bug // TODO: Remove this once WebKit/Blink fixes this if (fmt.styles) { var styleVal = dom.getAttrib(elm, 'style'); if (styleVal) { elm.setAttribute('data-mce-style', styleVal); } } each(fmt.attributes, function (value, name) { dom.setAttrib(elm, name, FormatUtils.replaceVars(value, vars)); }); each(fmt.classes, function (value) { value = FormatUtils.replaceVars(value, vars); if (!dom.hasClass(elm, value)) { dom.addClass(elm, value); } }); } }; var applyNodeStyle = function (formatList, node) { var found = false; if (!format.selector) { return false; } // Look for matching formats each(formatList, function (format) { // Check collapsed state if it exists if ('collapsed' in format && format.collapsed !== isCollapsed) { return; } if (dom.is(node, format.selector) && !CaretFormat.isCaretNode(node)) { setElementFormat(node, format); found = true; return false; } }); return found; }; var applyRngStyle = function (dom, rng, bookmark, nodeSpecific) { var newWrappers = [], wrapName, wrapElm, contentEditable = true; // Setup wrapper element wrapName = format.inline || format.block; wrapElm = dom.create(wrapName); setElementFormat(wrapElm); RangeWalk.walk(dom, rng, function (nodes) { var currentWrapElm; /** * Process a list of nodes wrap them. */ var process = function (node) { var nodeName, parentName, hasContentEditableState, lastContentEditable; lastContentEditable = contentEditable; nodeName = node.nodeName.toLowerCase(); parentName = node.parentNode.nodeName.toLowerCase(); // Node has a contentEditable value if (node.nodeType === 1 && dom.getContentEditable(node)) { lastContentEditable = contentEditable; contentEditable = dom.getContentEditable(node) === "true"; hasContentEditableState = true; // We don't want to wrap the container only it's children } // Stop wrapping on br elements if (FormatUtils.isEq(nodeName, 'br')) { currentWrapElm = 0; // Remove any br elements when we wrap things if (format.block) { dom.remove(node); } return; } // If node is wrapper type if (format.wrapper && MatchFormat.matchNode(ed, node, name, vars)) { currentWrapElm = 0; return; } // Can we rename the block // TODO: Break this if up, too complex if (contentEditable && !hasContentEditableState && format.block && !format.wrapper && FormatUtils.isTextBlock(ed, nodeName) && FormatUtils.isValid(ed, parentName, wrapName)) { node = dom.rename(node, wrapName); setElementFormat(node); newWrappers.push(node); currentWrapElm = 0; return; } // Handle selector patterns if (format.selector) { var found = applyNodeStyle(formatList, node); // Continue processing if a selector match wasn't found and a inline element is defined if (!format.inline || found) { currentWrapElm = 0; return; } } // Is it valid to wrap this item // TODO: Break this if up, too complex if (contentEditable && !hasContentEditableState && FormatUtils.isValid(ed, wrapName, nodeName) && FormatUtils.isValid(ed, parentName, wrapName) && !(!nodeSpecific && node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279) && !CaretFormat.isCaretNode(node) && (!format.inline || !dom.isBlock(node))) { // Start wrapping if (!currentWrapElm) { // Wrap the node currentWrapElm = dom.clone(wrapElm, false); node.parentNode.insertBefore(currentWrapElm, node); newWrappers.push(currentWrapElm); } currentWrapElm.appendChild(node); } else { // Start a new wrapper for possible children currentWrapElm = 0; each(Tools.grep(node.childNodes), process); if (hasContentEditableState) { contentEditable = lastContentEditable; // Restore last contentEditable state from stack } // End the last wrapper currentWrapElm = 0; } }; // Process siblings from range each(nodes, process); }); // Apply formats to links as well to get the color of the underline to change as well if (format.links === true) { each(newWrappers, function (node) { var process = function (node) { if (node.nodeName === 'A') { setElementFormat(node, format); } each(Tools.grep(node.childNodes), process); }; process(node); }); } // Cleanup each(newWrappers, function (node) { var childCount; var getChildCount = function (node) { var count = 0; each(node.childNodes, function (node) { if (!FormatUtils.isWhiteSpaceNode(node) && !Bookmarks.isBookmarkNode(node)) { count++; } }); return count; }; var getChildElementNode = function (root) { var child = false; each(root.childNodes, function (node) { if (isElementNode(node)) { child = node; return false; // break loop } }); return child; }; var mergeStyles = function (node) { var child, clone; child = getChildElementNode(node); // If child was found and of the same type as the current node if (child && !Bookmarks.isBookmarkNode(child) && MatchFormat.matchName(dom, child, format)) { clone = dom.clone(child, false); setElementFormat(clone); dom.replace(clone, node, true); dom.remove(child, 1); } return clone || node; }; childCount = getChildCount(node); // Remove empty nodes but only if there is multiple wrappers and they are not block // elements so never remove single <h1></h1> since that would remove the // current empty block element where the caret is at if ((newWrappers.length > 1 || !dom.isBlock(node)) && childCount === 0) { dom.remove(node, 1); return; } if (format.inline || format.wrapper) { // Merges the current node with it's children of similar type to reduce the number of elements if (!format.exact && childCount === 1) { node = mergeStyles(node); } MergeFormats.mergeWithChildren(ed, formatList, vars, node); MergeFormats.mergeWithParents(ed, format, name, vars, node); MergeFormats.mergeBackgroundColorAndFontSize(dom, format, vars, node); MergeFormats.mergeSubSup(dom, format, vars, node); MergeFormats.mergeSiblings(dom, format, vars, node); } }); }; if (dom.getContentEditable(selection.getNode()) === "false") { node = selection.getNode(); for (var i = 0, l = formatList.length; i < l; i++) { if (formatList[i].ceFalseOverride && dom.is(node, formatList[i].selector)) { setElementFormat(node, formatList[i]); return; } } return; } if (format) { if (node) { if (node.nodeType) { if (!applyNodeStyle(formatList, node)) { rng = dom.createRng(); rng.setStartBefore(node); rng.setEndAfter(node); applyRngStyle(dom, ExpandRange.expandRng(ed, rng, formatList), null, true); } } else { applyRngStyle(dom, node, null, true); } } else { if (!isCollapsed || !format.inline || dom.select('td[data-mce-selected],th[data-mce-selected]').length) { // Obtain selection node before selection is unselected by applyRngStyle var curSelNode = ed.selection.getNode(); // If the formats have a default block and we can't find a parent block then // start wrapping it with a DIV this is for forced_root_blocks: false // It's kind of a hack but people should be using the default block type P since all desktop editors work that way if (!ed.settings.forced_root_block && formatList[0].defaultBlock && !dom.getParent(curSelNode, dom.isBlock)) { applyFormat(ed, formatList[0].defaultBlock); } // Apply formatting to selection ed.selection.setRng(RangeNormalizer.normalize(ed.selection.getRng())); bookmark = selection.getBookmark(); applyRngStyle(dom, ExpandRange.expandRng(ed, selection.getRng(true), formatList), bookmark); if (format.styles) { MergeFormats.mergeUnderlineAndColor(dom, format, vars, curSelNode); } selection.moveToBookmark(bookmark); FormatUtils.moveStart(dom, selection, selection.getRng(true)); ed.nodeChanged(); } else { CaretFormat.applyCaretFormat(ed, name, vars); } } Hooks.postProcess(name, ed); } }; return { applyFormat: applyFormat }; } );