plugin.js 59 KB

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