plugin.js 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683
  1. /**
  2. * Copyright (c) Tiny Technologies, Inc. All rights reserved.
  3. * Licensed under the LGPL or a commercial license.
  4. * For LGPL see License.txt in the project root for license information.
  5. * For commercial licenses see https://www.tiny.cloud/
  6. *
  7. * Version: 5.3.0 (2020-05-21)
  8. */
  9. (function (domGlobals) {
  10. 'use strict';
  11. var Cell = function (initial) {
  12. var value = initial;
  13. var get = function () {
  14. return value;
  15. };
  16. var set = function (v) {
  17. value = v;
  18. };
  19. return {
  20. get: get,
  21. set: set
  22. };
  23. };
  24. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  25. var hasProPlugin = function (editor) {
  26. if (/(^|[ ,])powerpaste([, ]|$)/.test(editor.settings.plugins) && global.get('powerpaste')) {
  27. if (typeof domGlobals.window.console !== 'undefined' && domGlobals.window.console.log) {
  28. domGlobals.window.console.log('PowerPaste is incompatible with Paste plugin! Remove \'paste\' from the \'plugins\' option.');
  29. }
  30. return true;
  31. } else {
  32. return false;
  33. }
  34. };
  35. var get = function (clipboard, quirks) {
  36. return {
  37. clipboard: clipboard,
  38. quirks: quirks
  39. };
  40. };
  41. var firePastePreProcess = function (editor, html, internal, isWordHtml) {
  42. return editor.fire('PastePreProcess', {
  43. content: html,
  44. internal: internal,
  45. wordContent: isWordHtml
  46. });
  47. };
  48. var firePastePostProcess = function (editor, node, internal, isWordHtml) {
  49. return editor.fire('PastePostProcess', {
  50. node: node,
  51. internal: internal,
  52. wordContent: isWordHtml
  53. });
  54. };
  55. var firePastePlainTextToggle = function (editor, state) {
  56. return editor.fire('PastePlainTextToggle', { state: state });
  57. };
  58. var firePaste = function (editor, ieFake) {
  59. return editor.fire('paste', { ieFake: ieFake });
  60. };
  61. var togglePlainTextPaste = function (editor, clipboard) {
  62. if (clipboard.pasteFormat.get() === 'text') {
  63. clipboard.pasteFormat.set('html');
  64. firePastePlainTextToggle(editor, false);
  65. } else {
  66. clipboard.pasteFormat.set('text');
  67. firePastePlainTextToggle(editor, true);
  68. }
  69. editor.focus();
  70. };
  71. var register = function (editor, clipboard) {
  72. editor.addCommand('mceTogglePlainTextPaste', function () {
  73. togglePlainTextPaste(editor, clipboard);
  74. });
  75. editor.addCommand('mceInsertClipboardContent', function (ui, value) {
  76. if (value.content) {
  77. clipboard.pasteHtml(value.content, value.internal);
  78. }
  79. if (value.text) {
  80. clipboard.pasteText(value.text);
  81. }
  82. });
  83. };
  84. var noop = function () {
  85. };
  86. var constant = function (value) {
  87. return function () {
  88. return value;
  89. };
  90. };
  91. var never = constant(false);
  92. var always = constant(true);
  93. var none = function () {
  94. return NONE;
  95. };
  96. var NONE = function () {
  97. var eq = function (o) {
  98. return o.isNone();
  99. };
  100. var call = function (thunk) {
  101. return thunk();
  102. };
  103. var id = function (n) {
  104. return n;
  105. };
  106. var me = {
  107. fold: function (n, _s) {
  108. return n();
  109. },
  110. is: never,
  111. isSome: never,
  112. isNone: always,
  113. getOr: id,
  114. getOrThunk: call,
  115. getOrDie: function (msg) {
  116. throw new Error(msg || 'error: getOrDie called on none.');
  117. },
  118. getOrNull: constant(null),
  119. getOrUndefined: constant(undefined),
  120. or: id,
  121. orThunk: call,
  122. map: none,
  123. each: noop,
  124. bind: none,
  125. exists: never,
  126. forall: always,
  127. filter: none,
  128. equals: eq,
  129. equals_: eq,
  130. toArray: function () {
  131. return [];
  132. },
  133. toString: constant('none()')
  134. };
  135. return me;
  136. }();
  137. var some = function (a) {
  138. var constant_a = constant(a);
  139. var self = function () {
  140. return me;
  141. };
  142. var bind = function (f) {
  143. return f(a);
  144. };
  145. var me = {
  146. fold: function (n, s) {
  147. return s(a);
  148. },
  149. is: function (v) {
  150. return a === v;
  151. },
  152. isSome: always,
  153. isNone: never,
  154. getOr: constant_a,
  155. getOrThunk: constant_a,
  156. getOrDie: constant_a,
  157. getOrNull: constant_a,
  158. getOrUndefined: constant_a,
  159. or: self,
  160. orThunk: self,
  161. map: function (f) {
  162. return some(f(a));
  163. },
  164. each: function (f) {
  165. f(a);
  166. },
  167. bind: bind,
  168. exists: bind,
  169. forall: bind,
  170. filter: function (f) {
  171. return f(a) ? me : NONE;
  172. },
  173. toArray: function () {
  174. return [a];
  175. },
  176. toString: function () {
  177. return 'some(' + a + ')';
  178. },
  179. equals: function (o) {
  180. return o.is(a);
  181. },
  182. equals_: function (o, elementEq) {
  183. return o.fold(never, function (b) {
  184. return elementEq(a, b);
  185. });
  186. }
  187. };
  188. return me;
  189. };
  190. var from = function (value) {
  191. return value === null || value === undefined ? NONE : some(value);
  192. };
  193. var Option = {
  194. some: some,
  195. none: none,
  196. from: from
  197. };
  198. var isSimpleType = function (type) {
  199. return function (value) {
  200. return typeof value === type;
  201. };
  202. };
  203. var isFunction = isSimpleType('function');
  204. var nativeSlice = Array.prototype.slice;
  205. var map = function (xs, f) {
  206. var len = xs.length;
  207. var r = new Array(len);
  208. for (var i = 0; i < len; i++) {
  209. var x = xs[i];
  210. r[i] = f(x, i);
  211. }
  212. return r;
  213. };
  214. var each = function (xs, f) {
  215. for (var i = 0, len = xs.length; i < len; i++) {
  216. var x = xs[i];
  217. f(x, i);
  218. }
  219. };
  220. var filter = function (xs, pred) {
  221. var r = [];
  222. for (var i = 0, len = xs.length; i < len; i++) {
  223. var x = xs[i];
  224. if (pred(x, i)) {
  225. r.push(x);
  226. }
  227. }
  228. return r;
  229. };
  230. var foldl = function (xs, f, acc) {
  231. each(xs, function (x) {
  232. acc = f(acc, x);
  233. });
  234. return acc;
  235. };
  236. var from$1 = isFunction(Array.from) ? Array.from : function (x) {
  237. return nativeSlice.call(x);
  238. };
  239. var value = function () {
  240. var subject = Cell(Option.none());
  241. var clear = function () {
  242. subject.set(Option.none());
  243. };
  244. var set = function (s) {
  245. subject.set(Option.some(s));
  246. };
  247. var on = function (f) {
  248. subject.get().each(f);
  249. };
  250. var isSet = function () {
  251. return subject.get().isSome();
  252. };
  253. return {
  254. clear: clear,
  255. set: set,
  256. isSet: isSet,
  257. on: on
  258. };
  259. };
  260. var global$1 = tinymce.util.Tools.resolve('tinymce.Env');
  261. var global$2 = tinymce.util.Tools.resolve('tinymce.util.Delay');
  262. var global$3 = tinymce.util.Tools.resolve('tinymce.util.Promise');
  263. var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools');
  264. var global$5 = tinymce.util.Tools.resolve('tinymce.util.VK');
  265. var internalMimeType = 'x-tinymce/html';
  266. var internalMark = '<!-- ' + internalMimeType + ' -->';
  267. var mark = function (html) {
  268. return internalMark + html;
  269. };
  270. var unmark = function (html) {
  271. return html.replace(internalMark, '');
  272. };
  273. var isMarked = function (html) {
  274. return html.indexOf(internalMark) !== -1;
  275. };
  276. var internalHtmlMime = function () {
  277. return internalMimeType;
  278. };
  279. var global$6 = tinymce.util.Tools.resolve('tinymce.html.Entities');
  280. var isPlainText = function (text) {
  281. return !/<(?:\/?(?!(?:div|p|br|span)>)\w+|(?:(?!(?:span style="white-space:\s?pre;?">)|br\s?\/>))\w+\s[^>]+)>/i.test(text);
  282. };
  283. var toBRs = function (text) {
  284. return text.replace(/\r?\n/g, '<br>');
  285. };
  286. var openContainer = function (rootTag, rootAttrs) {
  287. var key;
  288. var attrs = [];
  289. var tag = '<' + rootTag;
  290. if (typeof rootAttrs === 'object') {
  291. for (key in rootAttrs) {
  292. if (rootAttrs.hasOwnProperty(key)) {
  293. attrs.push(key + '="' + global$6.encodeAllRaw(rootAttrs[key]) + '"');
  294. }
  295. }
  296. if (attrs.length) {
  297. tag += ' ' + attrs.join(' ');
  298. }
  299. }
  300. return tag + '>';
  301. };
  302. var toBlockElements = function (text, rootTag, rootAttrs) {
  303. var blocks = text.split(/\n\n/);
  304. var tagOpen = openContainer(rootTag, rootAttrs);
  305. var tagClose = '</' + rootTag + '>';
  306. var paragraphs = global$4.map(blocks, function (p) {
  307. return p.split(/\n/).join('<br />');
  308. });
  309. var stitch = function (p) {
  310. return tagOpen + p + tagClose;
  311. };
  312. return paragraphs.length === 1 ? paragraphs[0] : global$4.map(paragraphs, stitch).join('');
  313. };
  314. var convert = function (text, rootTag, rootAttrs) {
  315. return rootTag ? toBlockElements(text, rootTag === true ? 'p' : rootTag, rootAttrs) : toBRs(text);
  316. };
  317. var global$7 = tinymce.util.Tools.resolve('tinymce.html.DomParser');
  318. var global$8 = tinymce.util.Tools.resolve('tinymce.html.Serializer');
  319. var global$9 = tinymce.util.Tools.resolve('tinymce.html.Node');
  320. var global$a = tinymce.util.Tools.resolve('tinymce.html.Schema');
  321. var shouldBlockDrop = function (editor) {
  322. return editor.getParam('paste_block_drop', false);
  323. };
  324. var shouldPasteDataImages = function (editor) {
  325. return editor.getParam('paste_data_images', false);
  326. };
  327. var shouldFilterDrop = function (editor) {
  328. return editor.getParam('paste_filter_drop', true);
  329. };
  330. var getPreProcess = function (editor) {
  331. return editor.getParam('paste_preprocess');
  332. };
  333. var getPostProcess = function (editor) {
  334. return editor.getParam('paste_postprocess');
  335. };
  336. var getWebkitStyles = function (editor) {
  337. return editor.getParam('paste_webkit_styles');
  338. };
  339. var shouldRemoveWebKitStyles = function (editor) {
  340. return editor.getParam('paste_remove_styles_if_webkit', true);
  341. };
  342. var shouldMergeFormats = function (editor) {
  343. return editor.getParam('paste_merge_formats', true);
  344. };
  345. var isSmartPasteEnabled = function (editor) {
  346. return editor.getParam('smart_paste', true);
  347. };
  348. var isPasteAsTextEnabled = function (editor) {
  349. return editor.getParam('paste_as_text', false);
  350. };
  351. var getRetainStyleProps = function (editor) {
  352. return editor.getParam('paste_retain_style_properties');
  353. };
  354. var getWordValidElements = function (editor) {
  355. 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';
  356. return editor.getParam('paste_word_valid_elements', defaultValidElements);
  357. };
  358. var shouldConvertWordFakeLists = function (editor) {
  359. return editor.getParam('paste_convert_word_fake_lists', true);
  360. };
  361. var shouldUseDefaultFilters = function (editor) {
  362. return editor.getParam('paste_enable_default_filters', true);
  363. };
  364. var nbsp = '\xA0';
  365. function filter$1(content, items) {
  366. global$4.each(items, function (v) {
  367. if (v.constructor === RegExp) {
  368. content = content.replace(v, '');
  369. } else {
  370. content = content.replace(v[0], v[1]);
  371. }
  372. });
  373. return content;
  374. }
  375. function innerText(html) {
  376. var schema = global$a();
  377. var domParser = global$7({}, schema);
  378. var text = '';
  379. var shortEndedElements = schema.getShortEndedElements();
  380. var ignoreElements = global$4.makeMap('script noscript style textarea video audio iframe object', ' ');
  381. var blockElements = schema.getBlockElements();
  382. function walk(node) {
  383. var name = node.name, currentNode = node;
  384. if (name === 'br') {
  385. text += '\n';
  386. return;
  387. }
  388. if (name === 'wbr') {
  389. return;
  390. }
  391. if (shortEndedElements[name]) {
  392. text += ' ';
  393. }
  394. if (ignoreElements[name]) {
  395. text += ' ';
  396. return;
  397. }
  398. if (node.type === 3) {
  399. text += node.value;
  400. }
  401. if (!node.shortEnded) {
  402. if (node = node.firstChild) {
  403. do {
  404. walk(node);
  405. } while (node = node.next);
  406. }
  407. }
  408. if (blockElements[name] && currentNode.next) {
  409. text += '\n';
  410. if (name === 'p') {
  411. text += '\n';
  412. }
  413. }
  414. }
  415. html = filter$1(html, [/<!\[[^\]]+\]>/g]);
  416. walk(domParser.parse(html));
  417. return text;
  418. }
  419. function trimHtml(html) {
  420. function trimSpaces(all, s1, s2) {
  421. if (!s1 && !s2) {
  422. return ' ';
  423. }
  424. return nbsp;
  425. }
  426. html = filter$1(html, [
  427. /^[\s\S]*<body[^>]*>\s*|\s*<\/body[^>]*>[\s\S]*$/ig,
  428. /<!--StartFragment-->|<!--EndFragment-->/g,
  429. [
  430. /( ?)<span class="Apple-converted-space">\u00a0<\/span>( ?)/g,
  431. trimSpaces
  432. ],
  433. /<br class="Apple-interchange-newline">/g,
  434. /<br>$/i
  435. ]);
  436. return html;
  437. }
  438. function createIdGenerator(prefix) {
  439. var count = 0;
  440. return function () {
  441. return prefix + count++;
  442. };
  443. }
  444. var isMsEdge = function () {
  445. return domGlobals.navigator.userAgent.indexOf(' Edge/') !== -1;
  446. };
  447. function isWordContent(content) {
  448. 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);
  449. }
  450. function isNumericList(text) {
  451. var found, patterns;
  452. patterns = [
  453. /^[IVXLMCD]{1,2}\.[ \u00a0]/,
  454. /^[ivxlmcd]{1,2}\.[ \u00a0]/,
  455. /^[a-z]{1,2}[\.\)][ \u00a0]/,
  456. /^[A-Z]{1,2}[\.\)][ \u00a0]/,
  457. /^[0-9]+\.[ \u00a0]/,
  458. /^[\u3007\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d]+\.[ \u00a0]/,
  459. /^[\u58f1\u5f10\u53c2\u56db\u4f0d\u516d\u4e03\u516b\u4e5d\u62fe]+\.[ \u00a0]/
  460. ];
  461. text = text.replace(/^[\u00a0 ]+/, '');
  462. global$4.each(patterns, function (pattern) {
  463. if (pattern.test(text)) {
  464. found = true;
  465. return false;
  466. }
  467. });
  468. return found;
  469. }
  470. function isBulletList(text) {
  471. return /^[\s\u00a0]*[\u2022\u00b7\u00a7\u25CF]\s*/.test(text);
  472. }
  473. function convertFakeListsToProperLists(node) {
  474. var currentListNode, prevListNode, lastLevel = 1;
  475. function getText(node) {
  476. var txt = '';
  477. if (node.type === 3) {
  478. return node.value;
  479. }
  480. if (node = node.firstChild) {
  481. do {
  482. txt += getText(node);
  483. } while (node = node.next);
  484. }
  485. return txt;
  486. }
  487. function trimListStart(node, regExp) {
  488. if (node.type === 3) {
  489. if (regExp.test(node.value)) {
  490. node.value = node.value.replace(regExp, '');
  491. return false;
  492. }
  493. }
  494. if (node = node.firstChild) {
  495. do {
  496. if (!trimListStart(node, regExp)) {
  497. return false;
  498. }
  499. } while (node = node.next);
  500. }
  501. return true;
  502. }
  503. function removeIgnoredNodes(node) {
  504. if (node._listIgnore) {
  505. node.remove();
  506. return;
  507. }
  508. if (node = node.firstChild) {
  509. do {
  510. removeIgnoredNodes(node);
  511. } while (node = node.next);
  512. }
  513. }
  514. function convertParagraphToLi(paragraphNode, listName, start) {
  515. var level = paragraphNode._listLevel || lastLevel;
  516. if (level !== lastLevel) {
  517. if (level < lastLevel) {
  518. if (currentListNode) {
  519. currentListNode = currentListNode.parent.parent;
  520. }
  521. } else {
  522. prevListNode = currentListNode;
  523. currentListNode = null;
  524. }
  525. }
  526. if (!currentListNode || currentListNode.name !== listName) {
  527. prevListNode = prevListNode || currentListNode;
  528. currentListNode = new global$9(listName, 1);
  529. if (start > 1) {
  530. currentListNode.attr('start', '' + start);
  531. }
  532. paragraphNode.wrap(currentListNode);
  533. } else {
  534. currentListNode.append(paragraphNode);
  535. }
  536. paragraphNode.name = 'li';
  537. if (level > lastLevel && prevListNode) {
  538. prevListNode.lastChild.append(currentListNode);
  539. }
  540. lastLevel = level;
  541. removeIgnoredNodes(paragraphNode);
  542. trimListStart(paragraphNode, /^\u00a0+/);
  543. trimListStart(paragraphNode, /^\s*([\u2022\u00b7\u00a7\u25CF]|\w+\.)/);
  544. trimListStart(paragraphNode, /^\u00a0+/);
  545. }
  546. var elements = [];
  547. var child = node.firstChild;
  548. while (typeof child !== 'undefined' && child !== null) {
  549. elements.push(child);
  550. child = child.walk();
  551. if (child !== null) {
  552. while (typeof child !== 'undefined' && child.parent !== node) {
  553. child = child.walk();
  554. }
  555. }
  556. }
  557. for (var i = 0; i < elements.length; i++) {
  558. node = elements[i];
  559. if (node.name === 'p' && node.firstChild) {
  560. var nodeText = getText(node);
  561. if (isBulletList(nodeText)) {
  562. convertParagraphToLi(node, 'ul');
  563. continue;
  564. }
  565. if (isNumericList(nodeText)) {
  566. var matches = /([0-9]+)\./.exec(nodeText);
  567. var start = 1;
  568. if (matches) {
  569. start = parseInt(matches[1], 10);
  570. }
  571. convertParagraphToLi(node, 'ol', start);
  572. continue;
  573. }
  574. if (node._listLevel) {
  575. convertParagraphToLi(node, 'ul', 1);
  576. continue;
  577. }
  578. currentListNode = null;
  579. } else {
  580. prevListNode = currentListNode;
  581. currentListNode = null;
  582. }
  583. }
  584. }
  585. function filterStyles(editor, validStyles, node, styleValue) {
  586. var outputStyles = {}, matches;
  587. var styles = editor.dom.parseStyle(styleValue);
  588. global$4.each(styles, function (value, name) {
  589. switch (name) {
  590. case 'mso-list':
  591. matches = /\w+ \w+([0-9]+)/i.exec(styleValue);
  592. if (matches) {
  593. node._listLevel = parseInt(matches[1], 10);
  594. }
  595. if (/Ignore/i.test(value) && node.firstChild) {
  596. node._listIgnore = true;
  597. node.firstChild._listIgnore = true;
  598. }
  599. break;
  600. case 'horiz-align':
  601. name = 'text-align';
  602. break;
  603. case 'vert-align':
  604. name = 'vertical-align';
  605. break;
  606. case 'font-color':
  607. case 'mso-foreground':
  608. name = 'color';
  609. break;
  610. case 'mso-background':
  611. case 'mso-highlight':
  612. name = 'background';
  613. break;
  614. case 'font-weight':
  615. case 'font-style':
  616. if (value !== 'normal') {
  617. outputStyles[name] = value;
  618. }
  619. return;
  620. case 'mso-element':
  621. if (/^(comment|comment-list)$/i.test(value)) {
  622. node.remove();
  623. return;
  624. }
  625. break;
  626. }
  627. if (name.indexOf('mso-comment') === 0) {
  628. node.remove();
  629. return;
  630. }
  631. if (name.indexOf('mso-') === 0) {
  632. return;
  633. }
  634. if (getRetainStyleProps(editor) === 'all' || validStyles && validStyles[name]) {
  635. outputStyles[name] = value;
  636. }
  637. });
  638. if (/(bold)/i.test(outputStyles['font-weight'])) {
  639. delete outputStyles['font-weight'];
  640. node.wrap(new global$9('b', 1));
  641. }
  642. if (/(italic)/i.test(outputStyles['font-style'])) {
  643. delete outputStyles['font-style'];
  644. node.wrap(new global$9('i', 1));
  645. }
  646. outputStyles = editor.dom.serializeStyle(outputStyles, node.name);
  647. if (outputStyles) {
  648. return outputStyles;
  649. }
  650. return null;
  651. }
  652. var filterWordContent = function (editor, content) {
  653. var retainStyleProperties, validStyles;
  654. retainStyleProperties = getRetainStyleProps(editor);
  655. if (retainStyleProperties) {
  656. validStyles = global$4.makeMap(retainStyleProperties.split(/[, ]/));
  657. }
  658. content = filter$1(content, [
  659. /<br class="?Apple-interchange-newline"?>/gi,
  660. /<b[^>]+id="?docs-internal-[^>]*>/gi,
  661. /<!--[\s\S]+?-->/gi,
  662. /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,
  663. [
  664. /<(\/?)s>/gi,
  665. '<$1strike>'
  666. ],
  667. [
  668. /&nbsp;/gi,
  669. nbsp
  670. ],
  671. [
  672. /<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi,
  673. function (str, spaces) {
  674. return spaces.length > 0 ? spaces.replace(/./, ' ').slice(Math.floor(spaces.length / 2)).split('').join(nbsp) : '';
  675. }
  676. ]
  677. ]);
  678. var validElements = getWordValidElements(editor);
  679. var schema = global$a({
  680. valid_elements: validElements,
  681. valid_children: '-li[p]'
  682. });
  683. global$4.each(schema.elements, function (rule) {
  684. if (!rule.attributes.class) {
  685. rule.attributes.class = {};
  686. rule.attributesOrder.push('class');
  687. }
  688. if (!rule.attributes.style) {
  689. rule.attributes.style = {};
  690. rule.attributesOrder.push('style');
  691. }
  692. });
  693. var domParser = global$7({}, schema);
  694. domParser.addAttributeFilter('style', function (nodes) {
  695. var i = nodes.length, node;
  696. while (i--) {
  697. node = nodes[i];
  698. node.attr('style', filterStyles(editor, validStyles, node, node.attr('style')));
  699. if (node.name === 'span' && node.parent && !node.attributes.length) {
  700. node.unwrap();
  701. }
  702. }
  703. });
  704. domParser.addAttributeFilter('class', function (nodes) {
  705. var i = nodes.length, node, className;
  706. while (i--) {
  707. node = nodes[i];
  708. className = node.attr('class');
  709. if (/^(MsoCommentReference|MsoCommentText|msoDel)$/i.test(className)) {
  710. node.remove();
  711. }
  712. node.attr('class', null);
  713. }
  714. });
  715. domParser.addNodeFilter('del', function (nodes) {
  716. var i = nodes.length;
  717. while (i--) {
  718. nodes[i].remove();
  719. }
  720. });
  721. domParser.addNodeFilter('a', function (nodes) {
  722. var i = nodes.length, node, href, name;
  723. while (i--) {
  724. node = nodes[i];
  725. href = node.attr('href');
  726. name = node.attr('name');
  727. if (href && href.indexOf('#_msocom_') !== -1) {
  728. node.remove();
  729. continue;
  730. }
  731. if (href && href.indexOf('file://') === 0) {
  732. href = href.split('#')[1];
  733. if (href) {
  734. href = '#' + href;
  735. }
  736. }
  737. if (!href && !name) {
  738. node.unwrap();
  739. } else {
  740. if (name && !/^_?(?:toc|edn|ftn)/i.test(name)) {
  741. node.unwrap();
  742. continue;
  743. }
  744. node.attr({
  745. href: href,
  746. name: name
  747. });
  748. }
  749. }
  750. });
  751. var rootNode = domParser.parse(content);
  752. if (shouldConvertWordFakeLists(editor)) {
  753. convertFakeListsToProperLists(rootNode);
  754. }
  755. content = global$8({ validate: editor.settings.validate }, schema).serialize(rootNode);
  756. return content;
  757. };
  758. var preProcess = function (editor, content) {
  759. return shouldUseDefaultFilters(editor) ? filterWordContent(editor, content) : content;
  760. };
  761. var preProcess$1 = function (editor, html) {
  762. var parser = global$7({}, editor.schema);
  763. parser.addNodeFilter('meta', function (nodes) {
  764. global$4.each(nodes, function (node) {
  765. return node.remove();
  766. });
  767. });
  768. var fragment = parser.parse(html, {
  769. forced_root_block: false,
  770. isRootContent: true
  771. });
  772. return global$8({ validate: editor.settings.validate }, editor.schema).serialize(fragment);
  773. };
  774. var processResult = function (content, cancelled) {
  775. return {
  776. content: content,
  777. cancelled: cancelled
  778. };
  779. };
  780. var postProcessFilter = function (editor, html, internal, isWordHtml) {
  781. var tempBody = editor.dom.create('div', { style: 'display:none' }, html);
  782. var postProcessArgs = firePastePostProcess(editor, tempBody, internal, isWordHtml);
  783. return processResult(postProcessArgs.node.innerHTML, postProcessArgs.isDefaultPrevented());
  784. };
  785. var filterContent = function (editor, content, internal, isWordHtml) {
  786. var preProcessArgs = firePastePreProcess(editor, content, internal, isWordHtml);
  787. var filteredContent = preProcess$1(editor, preProcessArgs.content);
  788. if (editor.hasEventListeners('PastePostProcess') && !preProcessArgs.isDefaultPrevented()) {
  789. return postProcessFilter(editor, filteredContent, internal, isWordHtml);
  790. } else {
  791. return processResult(filteredContent, preProcessArgs.isDefaultPrevented());
  792. }
  793. };
  794. var process = function (editor, html, internal) {
  795. var isWordHtml = isWordContent(html);
  796. var content = isWordHtml ? preProcess(editor, html) : html;
  797. return filterContent(editor, content, internal, isWordHtml);
  798. };
  799. var pasteHtml = function (editor, html) {
  800. editor.insertContent(html, {
  801. merge: shouldMergeFormats(editor),
  802. paste: true
  803. });
  804. return true;
  805. };
  806. var isAbsoluteUrl = function (url) {
  807. return /^https?:\/\/[\w\?\-\/+=.&%@~#]+$/i.test(url);
  808. };
  809. var isImageUrl = function (url) {
  810. return isAbsoluteUrl(url) && /.(gif|jpe?g|png)$/.test(url);
  811. };
  812. var createImage = function (editor, url, pasteHtmlFn) {
  813. editor.undoManager.extra(function () {
  814. pasteHtmlFn(editor, url);
  815. }, function () {
  816. editor.insertContent('<img src="' + url + '">');
  817. });
  818. return true;
  819. };
  820. var createLink = function (editor, url, pasteHtmlFn) {
  821. editor.undoManager.extra(function () {
  822. pasteHtmlFn(editor, url);
  823. }, function () {
  824. editor.execCommand('mceInsertLink', false, url);
  825. });
  826. return true;
  827. };
  828. var linkSelection = function (editor, html, pasteHtmlFn) {
  829. return editor.selection.isCollapsed() === false && isAbsoluteUrl(html) ? createLink(editor, html, pasteHtmlFn) : false;
  830. };
  831. var insertImage = function (editor, html, pasteHtmlFn) {
  832. return isImageUrl(html) ? createImage(editor, html, pasteHtmlFn) : false;
  833. };
  834. var smartInsertContent = function (editor, html) {
  835. global$4.each([
  836. linkSelection,
  837. insertImage,
  838. pasteHtml
  839. ], function (action) {
  840. return action(editor, html, pasteHtml) !== true;
  841. });
  842. };
  843. var insertContent = function (editor, html, pasteAsText) {
  844. if (pasteAsText || isSmartPasteEnabled(editor) === false) {
  845. pasteHtml(editor, html);
  846. } else {
  847. smartInsertContent(editor, html);
  848. }
  849. };
  850. var isCollapsibleWhitespace = function (c) {
  851. return ' \f\t\x0B'.indexOf(c) !== -1;
  852. };
  853. var isNewLineChar = function (c) {
  854. return c === '\n' || c === '\r';
  855. };
  856. var isNewline = function (text, idx) {
  857. return idx < text.length && idx >= 0 ? isNewLineChar(text[idx]) : false;
  858. };
  859. var normalizeWhitespace = function (text) {
  860. var result = foldl(text, function (acc, c) {
  861. if (isCollapsibleWhitespace(c) || c === nbsp) {
  862. if (acc.pcIsSpace || acc.str === '' || acc.str.length === text.length - 1 || isNewline(text, acc.str.length + 1)) {
  863. return {
  864. pcIsSpace: false,
  865. str: acc.str + nbsp
  866. };
  867. } else {
  868. return {
  869. pcIsSpace: true,
  870. str: acc.str + ' '
  871. };
  872. }
  873. } else {
  874. return {
  875. pcIsSpace: isNewLineChar(c),
  876. str: acc.str + c
  877. };
  878. }
  879. }, {
  880. pcIsSpace: false,
  881. str: ''
  882. });
  883. return result.str;
  884. };
  885. var doPaste = function (editor, content, internal, pasteAsText) {
  886. var args = process(editor, content, internal);
  887. if (args.cancelled === false) {
  888. insertContent(editor, args.content, pasteAsText);
  889. }
  890. };
  891. var pasteHtml$1 = function (editor, html, internalFlag) {
  892. var internal = internalFlag ? internalFlag : isMarked(html);
  893. doPaste(editor, unmark(html), internal, false);
  894. };
  895. var pasteText = function (editor, text) {
  896. var encodedText = editor.dom.encode(text).replace(/\r\n/g, '\n');
  897. var normalizedText = normalizeWhitespace(encodedText);
  898. var html = convert(normalizedText, editor.settings.forced_root_block, editor.settings.forced_root_block_attrs);
  899. doPaste(editor, html, false, true);
  900. };
  901. var getDataTransferItems = function (dataTransfer) {
  902. var items = {};
  903. var mceInternalUrlPrefix = 'data:text/mce-internal,';
  904. if (dataTransfer) {
  905. if (dataTransfer.getData) {
  906. var legacyText = dataTransfer.getData('Text');
  907. if (legacyText && legacyText.length > 0) {
  908. if (legacyText.indexOf(mceInternalUrlPrefix) === -1) {
  909. items['text/plain'] = legacyText;
  910. }
  911. }
  912. }
  913. if (dataTransfer.types) {
  914. for (var i = 0; i < dataTransfer.types.length; i++) {
  915. var contentType = dataTransfer.types[i];
  916. try {
  917. items[contentType] = dataTransfer.getData(contentType);
  918. } catch (ex) {
  919. items[contentType] = '';
  920. }
  921. }
  922. }
  923. }
  924. return items;
  925. };
  926. var getClipboardContent = function (editor, clipboardEvent) {
  927. var content = getDataTransferItems(clipboardEvent.clipboardData || editor.getDoc().dataTransfer);
  928. return isMsEdge() ? global$4.extend(content, { 'text/html': '' }) : content;
  929. };
  930. var hasContentType = function (clipboardContent, mimeType) {
  931. return mimeType in clipboardContent && clipboardContent[mimeType].length > 0;
  932. };
  933. var hasHtmlOrText = function (content) {
  934. return hasContentType(content, 'text/html') || hasContentType(content, 'text/plain');
  935. };
  936. var parseDataUri = function (uri) {
  937. var matches = /data:([^;]+);base64,([a-z0-9\+\/=]+)/i.exec(uri);
  938. if (matches) {
  939. return {
  940. type: matches[1],
  941. data: decodeURIComponent(matches[2])
  942. };
  943. } else {
  944. return {
  945. type: null,
  946. data: null
  947. };
  948. }
  949. };
  950. var isValidDataUriImage = function (settings, imgElm) {
  951. return settings.images_dataimg_filter ? settings.images_dataimg_filter(imgElm) : true;
  952. };
  953. var extractFilename = function (editor, str) {
  954. var m = str.match(/([\s\S]+?)\.(?:jpeg|jpg|png|gif)$/i);
  955. return m ? editor.dom.encode(m[1]) : null;
  956. };
  957. var uniqueId = createIdGenerator('mceclip');
  958. var pasteImage = function (editor, imageItem) {
  959. var _a = parseDataUri(imageItem.uri), base64 = _a.data, type = _a.type;
  960. var id = uniqueId();
  961. var name = editor.settings.images_reuse_filename && imageItem.blob.name ? extractFilename(editor, imageItem.blob.name) : id;
  962. var img = new domGlobals.Image();
  963. img.src = imageItem.uri;
  964. if (isValidDataUriImage(editor.settings, img)) {
  965. var blobCache = editor.editorUpload.blobCache;
  966. var blobInfo = void 0;
  967. var existingBlobInfo = blobCache.getByData(base64, type);
  968. if (!existingBlobInfo) {
  969. blobInfo = blobCache.create(id, imageItem.blob, base64, name);
  970. blobCache.add(blobInfo);
  971. } else {
  972. blobInfo = existingBlobInfo;
  973. }
  974. pasteHtml$1(editor, '<img src="' + blobInfo.blobUri() + '">', false);
  975. } else {
  976. pasteHtml$1(editor, '<img src="' + imageItem.uri + '">', false);
  977. }
  978. };
  979. var isClipboardEvent = function (event) {
  980. return event.type === 'paste';
  981. };
  982. var readBlobsAsDataUris = function (items) {
  983. return global$3.all(map(items, function (item) {
  984. return new global$3(function (resolve) {
  985. var blob = item.getAsFile ? item.getAsFile() : item;
  986. var reader = new window.FileReader();
  987. reader.onload = function () {
  988. resolve({
  989. blob: blob,
  990. uri: reader.result
  991. });
  992. };
  993. reader.readAsDataURL(blob);
  994. });
  995. }));
  996. };
  997. var getImagesFromDataTransfer = function (dataTransfer) {
  998. var items = dataTransfer.items ? map(from$1(dataTransfer.items), function (item) {
  999. return item.getAsFile();
  1000. }) : [];
  1001. var files = dataTransfer.files ? from$1(dataTransfer.files) : [];
  1002. var images = filter(items.length > 0 ? items : files, function (file) {
  1003. return /^image\/(jpeg|png|gif|bmp)$/.test(file.type);
  1004. });
  1005. return images;
  1006. };
  1007. var pasteImageData = function (editor, e, rng) {
  1008. var dataTransfer = isClipboardEvent(e) ? e.clipboardData : e.dataTransfer;
  1009. if (editor.settings.paste_data_images && dataTransfer) {
  1010. var images = getImagesFromDataTransfer(dataTransfer);
  1011. if (images.length > 0) {
  1012. e.preventDefault();
  1013. readBlobsAsDataUris(images).then(function (blobResults) {
  1014. if (rng) {
  1015. editor.selection.setRng(rng);
  1016. }
  1017. each(blobResults, function (result) {
  1018. pasteImage(editor, result);
  1019. });
  1020. });
  1021. return true;
  1022. }
  1023. }
  1024. return false;
  1025. };
  1026. var isBrokenAndroidClipboardEvent = function (e) {
  1027. var clipboardData = e.clipboardData;
  1028. return domGlobals.navigator.userAgent.indexOf('Android') !== -1 && clipboardData && clipboardData.items && clipboardData.items.length === 0;
  1029. };
  1030. var isKeyboardPasteEvent = function (e) {
  1031. return global$5.metaKeyPressed(e) && e.keyCode === 86 || e.shiftKey && e.keyCode === 45;
  1032. };
  1033. var registerEventHandlers = function (editor, pasteBin, pasteFormat) {
  1034. var keyboardPasteEvent = value();
  1035. var keyboardPastePlainTextState;
  1036. editor.on('keydown', function (e) {
  1037. function removePasteBinOnKeyUp(e) {
  1038. if (isKeyboardPasteEvent(e) && !e.isDefaultPrevented()) {
  1039. pasteBin.remove();
  1040. }
  1041. }
  1042. if (isKeyboardPasteEvent(e) && !e.isDefaultPrevented()) {
  1043. keyboardPastePlainTextState = e.shiftKey && e.keyCode === 86;
  1044. if (keyboardPastePlainTextState && global$1.webkit && domGlobals.navigator.userAgent.indexOf('Version/') !== -1) {
  1045. return;
  1046. }
  1047. e.stopImmediatePropagation();
  1048. keyboardPasteEvent.set(e);
  1049. window.setTimeout(function () {
  1050. keyboardPasteEvent.clear();
  1051. }, 100);
  1052. if (global$1.ie && keyboardPastePlainTextState) {
  1053. e.preventDefault();
  1054. firePaste(editor, true);
  1055. return;
  1056. }
  1057. pasteBin.remove();
  1058. pasteBin.create();
  1059. editor.once('keyup', removePasteBinOnKeyUp);
  1060. editor.once('paste', function () {
  1061. editor.off('keyup', removePasteBinOnKeyUp);
  1062. });
  1063. }
  1064. });
  1065. function insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode, internal) {
  1066. var content, isPlainTextHtml, isImage;
  1067. if (hasContentType(clipboardContent, 'text/html')) {
  1068. content = clipboardContent['text/html'];
  1069. } else {
  1070. content = pasteBin.getHtml();
  1071. internal = internal ? internal : isMarked(content);
  1072. if (pasteBin.isDefaultContent(content)) {
  1073. plainTextMode = true;
  1074. }
  1075. }
  1076. content = trimHtml(content);
  1077. pasteBin.remove();
  1078. isPlainTextHtml = internal === false && isPlainText(content);
  1079. isImage = isImageUrl(content);
  1080. if (!content.length || isPlainTextHtml && !isImage) {
  1081. plainTextMode = true;
  1082. }
  1083. if (plainTextMode || isImage) {
  1084. if (hasContentType(clipboardContent, 'text/plain') && isPlainTextHtml) {
  1085. content = clipboardContent['text/plain'];
  1086. } else {
  1087. content = innerText(content);
  1088. }
  1089. }
  1090. if (pasteBin.isDefaultContent(content)) {
  1091. if (!isKeyBoardPaste) {
  1092. editor.windowManager.alert('Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents.');
  1093. }
  1094. return;
  1095. }
  1096. if (plainTextMode) {
  1097. pasteText(editor, content);
  1098. } else {
  1099. pasteHtml$1(editor, content, internal);
  1100. }
  1101. }
  1102. var getLastRng = function () {
  1103. return pasteBin.getLastRng() || editor.selection.getRng();
  1104. };
  1105. editor.on('paste', function (e) {
  1106. var isKeyBoardPaste = keyboardPasteEvent.isSet();
  1107. var clipboardContent = getClipboardContent(editor, e);
  1108. var plainTextMode = pasteFormat.get() === 'text' || keyboardPastePlainTextState;
  1109. var internal = hasContentType(clipboardContent, internalHtmlMime());
  1110. keyboardPastePlainTextState = false;
  1111. if (e.isDefaultPrevented() || isBrokenAndroidClipboardEvent(e)) {
  1112. pasteBin.remove();
  1113. return;
  1114. }
  1115. if (!hasHtmlOrText(clipboardContent) && pasteImageData(editor, e, getLastRng())) {
  1116. pasteBin.remove();
  1117. return;
  1118. }
  1119. if (!isKeyBoardPaste) {
  1120. e.preventDefault();
  1121. }
  1122. if (global$1.ie && (!isKeyBoardPaste || e.ieFake) && !hasContentType(clipboardContent, 'text/html')) {
  1123. pasteBin.create();
  1124. editor.dom.bind(pasteBin.getEl(), 'paste', function (e) {
  1125. e.stopPropagation();
  1126. });
  1127. editor.getDoc().execCommand('Paste', false, null);
  1128. clipboardContent['text/html'] = pasteBin.getHtml();
  1129. }
  1130. if (hasContentType(clipboardContent, 'text/html')) {
  1131. e.preventDefault();
  1132. if (!internal) {
  1133. internal = isMarked(clipboardContent['text/html']);
  1134. }
  1135. insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode, internal);
  1136. } else {
  1137. global$2.setEditorTimeout(editor, function () {
  1138. insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode, internal);
  1139. }, 0);
  1140. }
  1141. });
  1142. };
  1143. var registerEventsAndFilters = function (editor, pasteBin, pasteFormat) {
  1144. registerEventHandlers(editor, pasteBin, pasteFormat);
  1145. var src;
  1146. editor.parser.addNodeFilter('img', function (nodes, name, args) {
  1147. var isPasteInsert = function (args) {
  1148. return args.data && args.data.paste === true;
  1149. };
  1150. var remove = function (node) {
  1151. if (!node.attr('data-mce-object') && src !== global$1.transparentSrc) {
  1152. node.remove();
  1153. }
  1154. };
  1155. var isWebKitFakeUrl = function (src) {
  1156. return src.indexOf('webkit-fake-url') === 0;
  1157. };
  1158. var isDataUri = function (src) {
  1159. return src.indexOf('data:') === 0;
  1160. };
  1161. if (!editor.settings.paste_data_images && isPasteInsert(args)) {
  1162. var i = nodes.length;
  1163. while (i--) {
  1164. src = nodes[i].attr('src');
  1165. if (!src) {
  1166. continue;
  1167. }
  1168. if (isWebKitFakeUrl(src)) {
  1169. remove(nodes[i]);
  1170. } else if (!editor.settings.allow_html_data_urls && isDataUri(src)) {
  1171. remove(nodes[i]);
  1172. }
  1173. }
  1174. }
  1175. });
  1176. };
  1177. var getPasteBinParent = function (editor) {
  1178. return global$1.ie && editor.inline ? domGlobals.document.body : editor.getBody();
  1179. };
  1180. var isExternalPasteBin = function (editor) {
  1181. return getPasteBinParent(editor) !== editor.getBody();
  1182. };
  1183. var delegatePasteEvents = function (editor, pasteBinElm, pasteBinDefaultContent) {
  1184. if (isExternalPasteBin(editor)) {
  1185. editor.dom.bind(pasteBinElm, 'paste keyup', function (_e) {
  1186. if (!isDefault(editor, pasteBinDefaultContent)) {
  1187. editor.fire('paste');
  1188. }
  1189. });
  1190. }
  1191. };
  1192. var create = function (editor, lastRngCell, pasteBinDefaultContent) {
  1193. var dom = editor.dom, body = editor.getBody();
  1194. var pasteBinElm;
  1195. lastRngCell.set(editor.selection.getRng());
  1196. pasteBinElm = editor.dom.add(getPasteBinParent(editor), 'div', {
  1197. 'id': 'mcepastebin',
  1198. 'class': 'mce-pastebin',
  1199. 'contentEditable': true,
  1200. 'data-mce-bogus': 'all',
  1201. 'style': 'position: fixed; top: 50%; width: 10px; height: 10px; overflow: hidden; opacity: 0'
  1202. }, pasteBinDefaultContent);
  1203. if (global$1.ie || global$1.gecko) {
  1204. dom.setStyle(pasteBinElm, 'left', dom.getStyle(body, 'direction', true) === 'rtl' ? 65535 : -65535);
  1205. }
  1206. dom.bind(pasteBinElm, 'beforedeactivate focusin focusout', function (e) {
  1207. e.stopPropagation();
  1208. });
  1209. delegatePasteEvents(editor, pasteBinElm, pasteBinDefaultContent);
  1210. pasteBinElm.focus();
  1211. editor.selection.select(pasteBinElm, true);
  1212. };
  1213. var remove = function (editor, lastRngCell) {
  1214. if (getEl(editor)) {
  1215. var pasteBinClone = void 0;
  1216. var lastRng = lastRngCell.get();
  1217. while (pasteBinClone = editor.dom.get('mcepastebin')) {
  1218. editor.dom.remove(pasteBinClone);
  1219. editor.dom.unbind(pasteBinClone);
  1220. }
  1221. if (lastRng) {
  1222. editor.selection.setRng(lastRng);
  1223. }
  1224. }
  1225. lastRngCell.set(null);
  1226. };
  1227. var getEl = function (editor) {
  1228. return editor.dom.get('mcepastebin');
  1229. };
  1230. var getHtml = function (editor) {
  1231. var pasteBinElm, pasteBinClones, i, dirtyWrappers, cleanWrapper;
  1232. var copyAndRemove = function (toElm, fromElm) {
  1233. toElm.appendChild(fromElm);
  1234. editor.dom.remove(fromElm, true);
  1235. };
  1236. pasteBinClones = global$4.grep(getPasteBinParent(editor).childNodes, function (elm) {
  1237. return elm.id === 'mcepastebin';
  1238. });
  1239. pasteBinElm = pasteBinClones.shift();
  1240. global$4.each(pasteBinClones, function (pasteBinClone) {
  1241. copyAndRemove(pasteBinElm, pasteBinClone);
  1242. });
  1243. dirtyWrappers = editor.dom.select('div[id=mcepastebin]', pasteBinElm);
  1244. for (i = dirtyWrappers.length - 1; i >= 0; i--) {
  1245. cleanWrapper = editor.dom.create('div');
  1246. pasteBinElm.insertBefore(cleanWrapper, dirtyWrappers[i]);
  1247. copyAndRemove(cleanWrapper, dirtyWrappers[i]);
  1248. }
  1249. return pasteBinElm ? pasteBinElm.innerHTML : '';
  1250. };
  1251. var getLastRng = function (lastRng) {
  1252. return lastRng.get();
  1253. };
  1254. var isDefaultContent = function (pasteBinDefaultContent, content) {
  1255. return content === pasteBinDefaultContent;
  1256. };
  1257. var isPasteBin = function (elm) {
  1258. return elm && elm.id === 'mcepastebin';
  1259. };
  1260. var isDefault = function (editor, pasteBinDefaultContent) {
  1261. var pasteBinElm = getEl(editor);
  1262. return isPasteBin(pasteBinElm) && isDefaultContent(pasteBinDefaultContent, pasteBinElm.innerHTML);
  1263. };
  1264. var PasteBin = function (editor) {
  1265. var lastRng = Cell(null);
  1266. var pasteBinDefaultContent = '%MCEPASTEBIN%';
  1267. return {
  1268. create: function () {
  1269. return create(editor, lastRng, pasteBinDefaultContent);
  1270. },
  1271. remove: function () {
  1272. return remove(editor, lastRng);
  1273. },
  1274. getEl: function () {
  1275. return getEl(editor);
  1276. },
  1277. getHtml: function () {
  1278. return getHtml(editor);
  1279. },
  1280. getLastRng: function () {
  1281. return getLastRng(lastRng);
  1282. },
  1283. isDefault: function () {
  1284. return isDefault(editor, pasteBinDefaultContent);
  1285. },
  1286. isDefaultContent: function (content) {
  1287. return isDefaultContent(pasteBinDefaultContent, content);
  1288. }
  1289. };
  1290. };
  1291. var Clipboard = function (editor, pasteFormat) {
  1292. var pasteBin = PasteBin(editor);
  1293. editor.on('PreInit', function () {
  1294. return registerEventsAndFilters(editor, pasteBin, pasteFormat);
  1295. });
  1296. return {
  1297. pasteFormat: pasteFormat,
  1298. pasteHtml: function (html, internalFlag) {
  1299. return pasteHtml$1(editor, html, internalFlag);
  1300. },
  1301. pasteText: function (text) {
  1302. return pasteText(editor, text);
  1303. },
  1304. pasteImageData: function (e, rng) {
  1305. return pasteImageData(editor, e, rng);
  1306. },
  1307. getDataTransferItems: getDataTransferItems,
  1308. hasHtmlOrText: hasHtmlOrText,
  1309. hasContentType: hasContentType
  1310. };
  1311. };
  1312. var hasWorkingClipboardApi = function (clipboardData) {
  1313. return global$1.iOS === false && clipboardData !== undefined && typeof clipboardData.setData === 'function' && isMsEdge() !== true;
  1314. };
  1315. var setHtml5Clipboard = function (clipboardData, html, text) {
  1316. if (hasWorkingClipboardApi(clipboardData)) {
  1317. try {
  1318. clipboardData.clearData();
  1319. clipboardData.setData('text/html', html);
  1320. clipboardData.setData('text/plain', text);
  1321. clipboardData.setData(internalHtmlMime(), html);
  1322. return true;
  1323. } catch (e) {
  1324. return false;
  1325. }
  1326. } else {
  1327. return false;
  1328. }
  1329. };
  1330. var setClipboardData = function (evt, data, fallback, done) {
  1331. if (setHtml5Clipboard(evt.clipboardData, data.html, data.text)) {
  1332. evt.preventDefault();
  1333. done();
  1334. } else {
  1335. fallback(data.html, done);
  1336. }
  1337. };
  1338. var fallback = function (editor) {
  1339. return function (html, done) {
  1340. var markedHtml = mark(html);
  1341. var outer = editor.dom.create('div', {
  1342. 'contenteditable': 'false',
  1343. 'data-mce-bogus': 'all'
  1344. });
  1345. var inner = editor.dom.create('div', { contenteditable: 'true' }, markedHtml);
  1346. editor.dom.setStyles(outer, {
  1347. position: 'fixed',
  1348. top: '0',
  1349. left: '-3000px',
  1350. width: '1000px',
  1351. overflow: 'hidden'
  1352. });
  1353. outer.appendChild(inner);
  1354. editor.dom.add(editor.getBody(), outer);
  1355. var range = editor.selection.getRng();
  1356. inner.focus();
  1357. var offscreenRange = editor.dom.createRng();
  1358. offscreenRange.selectNodeContents(inner);
  1359. editor.selection.setRng(offscreenRange);
  1360. global$2.setTimeout(function () {
  1361. editor.selection.setRng(range);
  1362. outer.parentNode.removeChild(outer);
  1363. done();
  1364. }, 0);
  1365. };
  1366. };
  1367. var getData = function (editor) {
  1368. return {
  1369. html: editor.selection.getContent({ contextual: true }),
  1370. text: editor.selection.getContent({ format: 'text' })
  1371. };
  1372. };
  1373. var isTableSelection = function (editor) {
  1374. return !!editor.dom.getParent(editor.selection.getStart(), 'td[data-mce-selected],th[data-mce-selected]', editor.getBody());
  1375. };
  1376. var hasSelectedContent = function (editor) {
  1377. return !editor.selection.isCollapsed() || isTableSelection(editor);
  1378. };
  1379. var cut = function (editor) {
  1380. return function (evt) {
  1381. if (hasSelectedContent(editor)) {
  1382. setClipboardData(evt, getData(editor), fallback(editor), function () {
  1383. if (global$1.browser.isChrome()) {
  1384. var rng_1 = editor.selection.getRng();
  1385. global$2.setEditorTimeout(editor, function () {
  1386. editor.selection.setRng(rng_1);
  1387. editor.execCommand('Delete');
  1388. }, 0);
  1389. } else {
  1390. editor.execCommand('Delete');
  1391. }
  1392. });
  1393. }
  1394. };
  1395. };
  1396. var copy = function (editor) {
  1397. return function (evt) {
  1398. if (hasSelectedContent(editor)) {
  1399. setClipboardData(evt, getData(editor), fallback(editor), function () {
  1400. });
  1401. }
  1402. };
  1403. };
  1404. var register$1 = function (editor) {
  1405. editor.on('cut', cut(editor));
  1406. editor.on('copy', copy(editor));
  1407. };
  1408. var global$b = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils');
  1409. var getCaretRangeFromEvent = function (editor, e) {
  1410. return global$b.getCaretRangeFromPoint(e.clientX, e.clientY, editor.getDoc());
  1411. };
  1412. var isPlainTextFileUrl = function (content) {
  1413. var plainTextContent = content['text/plain'];
  1414. return plainTextContent ? plainTextContent.indexOf('file://') === 0 : false;
  1415. };
  1416. var setFocusedRange = function (editor, rng) {
  1417. editor.focus();
  1418. editor.selection.setRng(rng);
  1419. };
  1420. var setup = function (editor, clipboard, draggingInternallyState) {
  1421. if (shouldBlockDrop(editor)) {
  1422. editor.on('dragend dragover draggesture dragdrop drop drag', function (e) {
  1423. e.preventDefault();
  1424. e.stopPropagation();
  1425. });
  1426. }
  1427. if (!shouldPasteDataImages(editor)) {
  1428. editor.on('drop', function (e) {
  1429. var dataTransfer = e.dataTransfer;
  1430. if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
  1431. e.preventDefault();
  1432. }
  1433. });
  1434. }
  1435. editor.on('drop', function (e) {
  1436. var dropContent, rng;
  1437. rng = getCaretRangeFromEvent(editor, e);
  1438. if (e.isDefaultPrevented() || draggingInternallyState.get()) {
  1439. return;
  1440. }
  1441. dropContent = clipboard.getDataTransferItems(e.dataTransfer);
  1442. var internal = clipboard.hasContentType(dropContent, internalHtmlMime());
  1443. if ((!clipboard.hasHtmlOrText(dropContent) || isPlainTextFileUrl(dropContent)) && clipboard.pasteImageData(e, rng)) {
  1444. return;
  1445. }
  1446. if (rng && shouldFilterDrop(editor)) {
  1447. var content_1 = dropContent['mce-internal'] || dropContent['text/html'] || dropContent['text/plain'];
  1448. if (content_1) {
  1449. e.preventDefault();
  1450. global$2.setEditorTimeout(editor, function () {
  1451. editor.undoManager.transact(function () {
  1452. if (dropContent['mce-internal']) {
  1453. editor.execCommand('Delete');
  1454. }
  1455. setFocusedRange(editor, rng);
  1456. content_1 = trimHtml(content_1);
  1457. if (!dropContent['text/html']) {
  1458. clipboard.pasteText(content_1);
  1459. } else {
  1460. clipboard.pasteHtml(content_1, internal);
  1461. }
  1462. });
  1463. });
  1464. }
  1465. }
  1466. });
  1467. editor.on('dragstart', function (_e) {
  1468. draggingInternallyState.set(true);
  1469. });
  1470. editor.on('dragover dragend', function (e) {
  1471. if (shouldPasteDataImages(editor) && draggingInternallyState.get() === false) {
  1472. e.preventDefault();
  1473. setFocusedRange(editor, getCaretRangeFromEvent(editor, e));
  1474. }
  1475. if (e.type === 'dragend') {
  1476. draggingInternallyState.set(false);
  1477. }
  1478. });
  1479. };
  1480. var setup$1 = function (editor) {
  1481. var plugin = editor.plugins.paste;
  1482. var preProcess = getPreProcess(editor);
  1483. if (preProcess) {
  1484. editor.on('PastePreProcess', function (e) {
  1485. preProcess.call(plugin, plugin, e);
  1486. });
  1487. }
  1488. var postProcess = getPostProcess(editor);
  1489. if (postProcess) {
  1490. editor.on('PastePostProcess', function (e) {
  1491. postProcess.call(plugin, plugin, e);
  1492. });
  1493. }
  1494. };
  1495. function addPreProcessFilter(editor, filterFunc) {
  1496. editor.on('PastePreProcess', function (e) {
  1497. e.content = filterFunc(editor, e.content, e.internal, e.wordContent);
  1498. });
  1499. }
  1500. function addPostProcessFilter(editor, filterFunc) {
  1501. editor.on('PastePostProcess', function (e) {
  1502. filterFunc(editor, e.node);
  1503. });
  1504. }
  1505. function removeExplorerBrElementsAfterBlocks(editor, html) {
  1506. if (!isWordContent(html)) {
  1507. return html;
  1508. }
  1509. var blockElements = [];
  1510. global$4.each(editor.schema.getBlockElements(), function (block, blockName) {
  1511. blockElements.push(blockName);
  1512. });
  1513. var explorerBlocksRegExp = new RegExp('(?:<br>&nbsp;[\\s\\r\\n]+|<br>)*(<\\/?(' + blockElements.join('|') + ')[^>]*>)(?:<br>&nbsp;[\\s\\r\\n]+|<br>)*', 'g');
  1514. html = filter$1(html, [[
  1515. explorerBlocksRegExp,
  1516. '$1'
  1517. ]]);
  1518. html = filter$1(html, [
  1519. [
  1520. /<br><br>/g,
  1521. '<BR><BR>'
  1522. ],
  1523. [
  1524. /<br>/g,
  1525. ' '
  1526. ],
  1527. [
  1528. /<BR><BR>/g,
  1529. '<br>'
  1530. ]
  1531. ]);
  1532. return html;
  1533. }
  1534. function removeWebKitStyles(editor, content, internal, isWordHtml) {
  1535. if (isWordHtml || internal) {
  1536. return content;
  1537. }
  1538. var webKitStylesSetting = getWebkitStyles(editor);
  1539. var webKitStyles;
  1540. if (shouldRemoveWebKitStyles(editor) === false || webKitStylesSetting === 'all') {
  1541. return content;
  1542. }
  1543. if (webKitStylesSetting) {
  1544. webKitStyles = webKitStylesSetting.split(/[, ]/);
  1545. }
  1546. if (webKitStyles) {
  1547. var dom_1 = editor.dom, node_1 = editor.selection.getNode();
  1548. content = content.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi, function (all, before, value, after) {
  1549. var inputStyles = dom_1.parseStyle(dom_1.decode(value));
  1550. var outputStyles = {};
  1551. if (webKitStyles === 'none') {
  1552. return before + after;
  1553. }
  1554. for (var i = 0; i < webKitStyles.length; i++) {
  1555. var inputValue = inputStyles[webKitStyles[i]], currentValue = dom_1.getStyle(node_1, webKitStyles[i], true);
  1556. if (/color/.test(webKitStyles[i])) {
  1557. inputValue = dom_1.toHex(inputValue);
  1558. currentValue = dom_1.toHex(currentValue);
  1559. }
  1560. if (currentValue !== inputValue) {
  1561. outputStyles[webKitStyles[i]] = inputValue;
  1562. }
  1563. }
  1564. outputStyles = dom_1.serializeStyle(outputStyles, 'span');
  1565. if (outputStyles) {
  1566. return before + ' style="' + outputStyles + '"' + after;
  1567. }
  1568. return before + after;
  1569. });
  1570. } else {
  1571. content = content.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi, '$1$3');
  1572. }
  1573. content = content.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi, function (all, before, value, after) {
  1574. return before + ' style="' + value + '"' + after;
  1575. });
  1576. return content;
  1577. }
  1578. function removeUnderlineAndFontInAnchor(editor, root) {
  1579. editor.$('a', root).find('font,u').each(function (i, node) {
  1580. editor.dom.remove(node, true);
  1581. });
  1582. }
  1583. var setup$2 = function (editor) {
  1584. if (global$1.webkit) {
  1585. addPreProcessFilter(editor, removeWebKitStyles);
  1586. }
  1587. if (global$1.ie) {
  1588. addPreProcessFilter(editor, removeExplorerBrElementsAfterBlocks);
  1589. addPostProcessFilter(editor, removeUnderlineAndFontInAnchor);
  1590. }
  1591. };
  1592. var makeSetupHandler = function (editor, clipboard) {
  1593. return function (api) {
  1594. api.setActive(clipboard.pasteFormat.get() === 'text');
  1595. var pastePlainTextToggleHandler = function (e) {
  1596. return api.setActive(e.state);
  1597. };
  1598. editor.on('PastePlainTextToggle', pastePlainTextToggleHandler);
  1599. return function () {
  1600. return editor.off('PastePlainTextToggle', pastePlainTextToggleHandler);
  1601. };
  1602. };
  1603. };
  1604. var register$2 = function (editor, clipboard) {
  1605. editor.ui.registry.addToggleButton('pastetext', {
  1606. active: false,
  1607. icon: 'paste-text',
  1608. tooltip: 'Paste as text',
  1609. onAction: function () {
  1610. return editor.execCommand('mceTogglePlainTextPaste');
  1611. },
  1612. onSetup: makeSetupHandler(editor, clipboard)
  1613. });
  1614. editor.ui.registry.addToggleMenuItem('pastetext', {
  1615. text: 'Paste as text',
  1616. icon: 'paste-text',
  1617. onAction: function () {
  1618. return editor.execCommand('mceTogglePlainTextPaste');
  1619. },
  1620. onSetup: makeSetupHandler(editor, clipboard)
  1621. });
  1622. };
  1623. function Plugin () {
  1624. global.add('paste', function (editor) {
  1625. if (hasProPlugin(editor) === false) {
  1626. var draggingInternallyState = Cell(false);
  1627. var pasteFormat = Cell(isPasteAsTextEnabled(editor) ? 'text' : 'html');
  1628. var clipboard = Clipboard(editor, pasteFormat);
  1629. var quirks = setup$2(editor);
  1630. register$2(editor, clipboard);
  1631. register(editor, clipboard);
  1632. setup$1(editor);
  1633. register$1(editor);
  1634. setup(editor, clipboard, draggingInternallyState);
  1635. return get(clipboard, quirks);
  1636. }
  1637. });
  1638. }
  1639. Plugin();
  1640. }(window));