var paste = (function (domGlobals) {
var Cell = function (initial) {
var clone = function () {
var global$1 = tinymce.util.Tools.resolve('tinymce.PluginManager');
var hasProPlugin = function (editor) {
if (/(^|[ ,])powerpaste([, ]|$)/.test(editor.settings.plugins) && global$1.get('powerpaste')) {
if (typeof domGlobals.window.console !== 'undefined' && domGlobals.window.console.log) {
domGlobals.window.console.log('PowerPaste is incompatible with Paste plugin! Remove \'paste\' from the \'plugins\' option.');
var DetectProPlugin = { hasProPlugin: hasProPlugin };
var get = function (clipboard, quirks) {
var firePastePreProcess = function (editor, html, internal, isWordHtml) {
return editor.fire('PastePreProcess', {
var firePastePostProcess = function (editor, node, internal, isWordHtml) {
return editor.fire('PastePostProcess', {
var firePastePlainTextToggle = function (editor, state) {
return editor.fire('PastePlainTextToggle', { state: state });
var firePaste = function (editor, ieFake) {
return editor.fire('paste', { ieFake: ieFake });
firePastePreProcess: firePastePreProcess,
firePastePostProcess: firePastePostProcess,
firePastePlainTextToggle: firePastePlainTextToggle,
var shouldPlainTextInform = function (editor) {
return editor.getParam('paste_plaintext_inform', true);
var shouldBlockDrop = function (editor) {
return editor.getParam('paste_block_drop', false);
var shouldPasteDataImages = function (editor) {
return editor.getParam('paste_data_images', false);
var shouldFilterDrop = function (editor) {
return editor.getParam('paste_filter_drop', true);
var getPreProcess = function (editor) {
return editor.getParam('paste_preprocess');
var getPostProcess = function (editor) {
return editor.getParam('paste_postprocess');
var getWebkitStyles = function (editor) {
return editor.getParam('paste_webkit_styles');
var shouldRemoveWebKitStyles = function (editor) {
return editor.getParam('paste_remove_styles_if_webkit', true);
var shouldMergeFormats = function (editor) {
return editor.getParam('paste_merge_formats', true);
var isSmartPasteEnabled = function (editor) {
return editor.getParam('smart_paste', true);
var isPasteAsTextEnabled = function (editor) {
return editor.getParam('paste_as_text', false);
var getRetainStyleProps = function (editor) {
return editor.getParam('paste_retain_style_properties');
var getWordValidElements = function (editor) {
var defaultValidElements = '-strong/b,-em/i,-u,-span,-p,-ol,-ul,-li,-h1,-h2,-h3,-h4,-h5,-h6,' + '-p/div,-a[href|name],sub,sup,strike,br,del,table[width],tr,' + 'td[colspan|rowspan|width],th[colspan|rowspan|width],thead,tfoot,tbody';
return editor.getParam('paste_word_valid_elements', defaultValidElements);
var shouldConvertWordFakeLists = function (editor) {
return editor.getParam('paste_convert_word_fake_lists', true);
var shouldUseDefaultFilters = function (editor) {
return editor.getParam('paste_enable_default_filters', true);
shouldPlainTextInform: shouldPlainTextInform,
shouldBlockDrop: shouldBlockDrop,
shouldPasteDataImages: shouldPasteDataImages,
shouldFilterDrop: shouldFilterDrop,
getPreProcess: getPreProcess,
getPostProcess: getPostProcess,
getWebkitStyles: getWebkitStyles,
shouldRemoveWebKitStyles: shouldRemoveWebKitStyles,
shouldMergeFormats: shouldMergeFormats,
isSmartPasteEnabled: isSmartPasteEnabled,
isPasteAsTextEnabled: isPasteAsTextEnabled,
getRetainStyleProps: getRetainStyleProps,
getWordValidElements: getWordValidElements,
shouldConvertWordFakeLists: shouldConvertWordFakeLists,
shouldUseDefaultFilters: shouldUseDefaultFilters
var shouldInformUserAboutPlainText = function (editor, userIsInformedState) {
return userIsInformedState.get() === false && Settings.shouldPlainTextInform(editor);
var displayNotification = function (editor, message) {
editor.notificationManager.open({
text: editor.translate(message),
var togglePlainTextPaste = function (editor, clipboard, userIsInformedState) {
if (clipboard.pasteFormat.get() === 'text') {
clipboard.pasteFormat.set('html');
Events.firePastePlainTextToggle(editor, false);
clipboard.pasteFormat.set('text');
Events.firePastePlainTextToggle(editor, true);
if (shouldInformUserAboutPlainText(editor, userIsInformedState)) {
displayNotification(editor, 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.');
userIsInformedState.set(true);
var Actions = { togglePlainTextPaste: togglePlainTextPaste };
var register = function (editor, clipboard, userIsInformedState) {
editor.addCommand('mceTogglePlainTextPaste', function () {
Actions.togglePlainTextPaste(editor, clipboard, userIsInformedState);
editor.addCommand('mceInsertClipboardContent', function (ui, value) {
clipboard.pasteHtml(value.content, value.internal);
clipboard.pasteText(value.text);
var Commands = { register: register };
var global$2 = tinymce.util.Tools.resolve('tinymce.Env');
var global$3 = tinymce.util.Tools.resolve('tinymce.util.Delay');
var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools');
var global$5 = tinymce.util.Tools.resolve('tinymce.util.VK');
var internalMimeType = 'x-tinymce/html';
var internalMark = '<!-- ' + internalMimeType + ' -->';
var mark = function (html) {
return internalMark + html;
var unmark = function (html) {
return html.replace(internalMark, '');
var isMarked = function (html) {
return html.indexOf(internalMark) !== -1;
internalHtmlMime: function () {
var global$6 = tinymce.util.Tools.resolve('tinymce.html.Entities');
var isPlainText = function (text) {
return !/<(?:\/?(?!(?:div|p|br|span)>)\w+|(?:(?!(?:span style="white-space:\s?pre;?">)|br\s?\/>))\w+\s[^>]+)>/i.test(text);
var toBRs = function (text) {
return text.replace(/\r?\n/g, '<br>');
var openContainer = function (rootTag, rootAttrs) {
if (typeof rootAttrs === 'object') {
if (rootAttrs.hasOwnProperty(key)) {
attrs.push(key + '="' + global$6.encodeAllRaw(rootAttrs[key]) + '"');
tag += ' ' + attrs.join(' ');
var toBlockElements = function (text, rootTag, rootAttrs) {
var blocks = text.split(/\n\n/);
var tagOpen = openContainer(rootTag, rootAttrs);
var tagClose = '</' + rootTag + '>';
var paragraphs = global$4.map(blocks, function (p) {
return p.split(/\n/).join('<br />');
var stitch = function (p) {
return tagOpen + p + tagClose;
return paragraphs.length === 1 ? paragraphs[0] : global$4.map(paragraphs, stitch).join('');
var convert = function (text, rootTag, rootAttrs) {
return rootTag ? toBlockElements(text, rootTag, rootAttrs) : toBRs(text);
isPlainText: isPlainText,
toBlockElements: toBlockElements
var global$7 = tinymce.util.Tools.resolve('tinymce.html.DomParser');
var global$8 = tinymce.util.Tools.resolve('tinymce.html.Serializer');
var global$9 = tinymce.util.Tools.resolve('tinymce.html.Node');
var global$a = tinymce.util.Tools.resolve('tinymce.html.Schema');
function filter(content, items) {
global$4.each(items, function (v) {
if (v.constructor === RegExp) {
content = content.replace(v, '');
content = content.replace(v[0], v[1]);
function innerText(html) {
var domParser = global$7({}, schema);
var shortEndedElements = schema.getShortEndedElements();
var ignoreElements = global$4.makeMap('script noscript style textarea video audio iframe object', ' ');
var blockElements = schema.getBlockElements();
var name = node.name, currentNode = node;
if (shortEndedElements[name]) {
if (ignoreElements[name]) {
if (node = node.firstChild) {
} while (node = node.next);
if (blockElements[name] && currentNode.next) {
html = filter(html, [/<!\[[^\]]+\]>/g]);
walk(domParser.parse(html));
function trimHtml(html) {
function trimSpaces(all, s1, s2) {
/^[\s\S]*<body[^>]*>\s*|\s*<\/body[^>]*>[\s\S]*$/ig,
/<!--StartFragment-->|<!--EndFragment-->/g,
/( ?)<span class="Apple-converted-space">\u00a0<\/span>( ?)/g,
/<br class="Apple-interchange-newline">/g,
function createIdGenerator(prefix) {
var isMsEdge = function () {
return domGlobals.navigator.userAgent.indexOf(' Edge/') !== -1;
createIdGenerator: createIdGenerator,
function isWordContent(content) {
return /<font face="Times New Roman"|class="?Mso|style="[^"]*\bmso-|style='[^'']*\bmso-|w:WordDocument/i.test(content) || /class="OutlineElement/.test(content) || /id="?docs\-internal\-guid\-/.test(content);
function isNumericList(text) {
/^[IVXLMCD]{1,2}\.[ \u00a0]/,
/^[ivxlmcd]{1,2}\.[ \u00a0]/,
/^[a-z]{1,2}[\.\)][ \u00a0]/,
/^[A-Z]{1,2}[\.\)][ \u00a0]/,
/^[\u3007\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d]+\.[ \u00a0]/,
/^[\u58f1\u5f10\u53c2\u56db\u4f0d\u516d\u4e03\u516b\u4e5d\u62fe]+\.[ \u00a0]/
text = text.replace(/^[\u00a0 ]+/, '');
global$4.each(patterns, function (pattern) {
if (pattern.test(text)) {
function isBulletList(text) {
return /^[\s\u00a0]*[\u2022\u00b7\u00a7\u25CF]\s*/.test(text);
function convertFakeListsToProperLists(node) {
var currentListNode, prevListNode, lastLevel = 1;
if (node = node.firstChild) {
} while (node = node.next);
function trimListStart(node, regExp) {
if (regExp.test(node.value)) {
node.value = node.value.replace(regExp, '');
if (node = node.firstChild) {
if (!trimListStart(node, regExp)) {
} while (node = node.next);
function removeIgnoredNodes(node) {
if (node = node.firstChild) {
removeIgnoredNodes(node);
} while (node = node.next);
function convertParagraphToLi(paragraphNode, listName, start) {
var level = paragraphNode._listLevel || lastLevel;
if (level !== lastLevel) {
currentListNode = currentListNode.parent.parent;
prevListNode = currentListNode;
if (!currentListNode || currentListNode.name !== listName) {
prevListNode = prevListNode || currentListNode;
currentListNode = new global$9(listName, 1);
currentListNode.attr('start', '' + start);
paragraphNode.wrap(currentListNode);
currentListNode.append(paragraphNode);
paragraphNode.name = 'li';
if (level > lastLevel && prevListNode) {
prevListNode.lastChild.append(currentListNode);
removeIgnoredNodes(paragraphNode);
trimListStart(paragraphNode, /^\u00a0+/);
trimListStart(paragraphNode, /^\s*([\u2022\u00b7\u00a7\u25CF]|\w+\.)/);
trimListStart(paragraphNode, /^\u00a0+/);
var child = node.firstChild;
while (typeof child !== 'undefined' && child !== null) {
while (typeof child !== 'undefined' && child.parent !== node) {
for (var i = 0; i < elements.length; i++) {
if (node.name === 'p' && node.firstChild) {
var nodeText = getText(node);
if (isBulletList(nodeText)) {
convertParagraphToLi(node, 'ul');
if (isNumericList(nodeText)) {
var matches = /([0-9]+)\./.exec(nodeText);
start = parseInt(matches[1], 10);
convertParagraphToLi(node, 'ol', start);
convertParagraphToLi(node, 'ul', 1);
prevListNode = currentListNode;
function filterStyles(editor, validStyles, node, styleValue) {
var outputStyles = {}, matches;
var styles = editor.dom.parseStyle(styleValue);
global$4.each(styles, function (value, name) {
matches = /\w+ \w+([0-9]+)/i.exec(styleValue);
node._listLevel = parseInt(matches[1], 10);
if (/Ignore/i.test(value) && node.firstChild) {
node.firstChild._listIgnore = true;