plugin.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  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.0.1 (2019-02-21)
  8. */
  9. (function () {
  10. var template = (function () {
  11. 'use strict';
  12. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  13. var constant = function (value) {
  14. return function () {
  15. return value;
  16. };
  17. };
  18. function curry(fn) {
  19. var initialArgs = [];
  20. for (var _i = 1; _i < arguments.length; _i++) {
  21. initialArgs[_i - 1] = arguments[_i];
  22. }
  23. return function () {
  24. var restArgs = [];
  25. for (var _i = 0; _i < arguments.length; _i++) {
  26. restArgs[_i] = arguments[_i];
  27. }
  28. var all = initialArgs.concat(restArgs);
  29. return fn.apply(null, all);
  30. };
  31. }
  32. var never = constant(false);
  33. var always = constant(true);
  34. var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools');
  35. var global$2 = tinymce.util.Tools.resolve('tinymce.util.XHR');
  36. var getCreationDateClasses = function (editor) {
  37. return editor.getParam('template_cdate_classes', 'cdate');
  38. };
  39. var getModificationDateClasses = function (editor) {
  40. return editor.getParam('template_mdate_classes', 'mdate');
  41. };
  42. var getSelectedContentClasses = function (editor) {
  43. return editor.getParam('template_selected_content_classes', 'selcontent');
  44. };
  45. var getPreviewReplaceValues = function (editor) {
  46. return editor.getParam('template_preview_replace_values');
  47. };
  48. var getTemplateReplaceValues = function (editor) {
  49. return editor.getParam('template_replace_values');
  50. };
  51. var getTemplates = function (editorSettings) {
  52. return editorSettings.templates;
  53. };
  54. var getCdateFormat = function (editor) {
  55. return editor.getParam('template_cdate_format', editor.translate('%Y-%m-%d'));
  56. };
  57. var getMdateFormat = function (editor) {
  58. return editor.getParam('template_mdate_format', editor.translate('%Y-%m-%d'));
  59. };
  60. var Settings = {
  61. getCreationDateClasses: getCreationDateClasses,
  62. getModificationDateClasses: getModificationDateClasses,
  63. getSelectedContentClasses: getSelectedContentClasses,
  64. getPreviewReplaceValues: getPreviewReplaceValues,
  65. getTemplateReplaceValues: getTemplateReplaceValues,
  66. getTemplates: getTemplates,
  67. getCdateFormat: getCdateFormat,
  68. getMdateFormat: getMdateFormat
  69. };
  70. var addZeros = function (value, len) {
  71. value = '' + value;
  72. if (value.length < len) {
  73. for (var i = 0; i < len - value.length; i++) {
  74. value = '0' + value;
  75. }
  76. }
  77. return value;
  78. };
  79. var getDateTime = function (editor, fmt, date) {
  80. var daysShort = 'Sun Mon Tue Wed Thu Fri Sat Sun'.split(' ');
  81. var daysLong = 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday'.split(' ');
  82. var monthsShort = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ');
  83. var monthsLong = 'January February March April May June July August September October November December'.split(' ');
  84. date = date || new Date();
  85. fmt = fmt.replace('%D', '%m/%d/%Y');
  86. fmt = fmt.replace('%r', '%I:%M:%S %p');
  87. fmt = fmt.replace('%Y', '' + date.getFullYear());
  88. fmt = fmt.replace('%y', '' + date.getYear());
  89. fmt = fmt.replace('%m', addZeros(date.getMonth() + 1, 2));
  90. fmt = fmt.replace('%d', addZeros(date.getDate(), 2));
  91. fmt = fmt.replace('%H', '' + addZeros(date.getHours(), 2));
  92. fmt = fmt.replace('%M', '' + addZeros(date.getMinutes(), 2));
  93. fmt = fmt.replace('%S', '' + addZeros(date.getSeconds(), 2));
  94. fmt = fmt.replace('%I', '' + ((date.getHours() + 11) % 12 + 1));
  95. fmt = fmt.replace('%p', '' + (date.getHours() < 12 ? 'AM' : 'PM'));
  96. fmt = fmt.replace('%B', '' + editor.translate(monthsLong[date.getMonth()]));
  97. fmt = fmt.replace('%b', '' + editor.translate(monthsShort[date.getMonth()]));
  98. fmt = fmt.replace('%A', '' + editor.translate(daysLong[date.getDay()]));
  99. fmt = fmt.replace('%a', '' + editor.translate(daysShort[date.getDay()]));
  100. fmt = fmt.replace('%%', '%');
  101. return fmt;
  102. };
  103. var DateTimeHelper = { getDateTime: getDateTime };
  104. var createTemplateList = function (editorSettings, callback) {
  105. return function () {
  106. var templateList = Settings.getTemplates(editorSettings);
  107. if (typeof templateList === 'function') {
  108. templateList(callback);
  109. return;
  110. }
  111. if (typeof templateList === 'string') {
  112. global$2.send({
  113. url: templateList,
  114. success: function (text) {
  115. callback(JSON.parse(text));
  116. }
  117. });
  118. } else {
  119. callback(templateList);
  120. }
  121. };
  122. };
  123. var replaceTemplateValues = function (html, templateValues) {
  124. global$1.each(templateValues, function (v, k) {
  125. if (typeof v === 'function') {
  126. v = v(k);
  127. }
  128. html = html.replace(new RegExp('\\{\\$' + k + '\\}', 'g'), v);
  129. });
  130. return html;
  131. };
  132. var replaceVals = function (editor, e) {
  133. var dom = editor.dom, vl = Settings.getTemplateReplaceValues(editor);
  134. global$1.each(dom.select('*', e), function (e) {
  135. global$1.each(vl, function (v, k) {
  136. if (dom.hasClass(e, k)) {
  137. if (typeof vl[k] === 'function') {
  138. vl[k](e);
  139. }
  140. }
  141. });
  142. });
  143. };
  144. var hasClass = function (n, c) {
  145. return new RegExp('\\b' + c + '\\b', 'g').test(n.className);
  146. };
  147. var insertTemplate = function (editor, ui, html) {
  148. var el;
  149. var n;
  150. var dom = editor.dom;
  151. var sel = editor.selection.getContent();
  152. html = replaceTemplateValues(html, Settings.getTemplateReplaceValues(editor));
  153. el = dom.create('div', null, html);
  154. n = dom.select('.mceTmpl', el);
  155. if (n && n.length > 0) {
  156. el = dom.create('div', null);
  157. el.appendChild(n[0].cloneNode(true));
  158. }
  159. global$1.each(dom.select('*', el), function (n) {
  160. if (hasClass(n, Settings.getCreationDateClasses(editor).replace(/\s+/g, '|'))) {
  161. n.innerHTML = DateTimeHelper.getDateTime(editor, Settings.getCdateFormat(editor));
  162. }
  163. if (hasClass(n, Settings.getModificationDateClasses(editor).replace(/\s+/g, '|'))) {
  164. n.innerHTML = DateTimeHelper.getDateTime(editor, Settings.getMdateFormat(editor));
  165. }
  166. if (hasClass(n, Settings.getSelectedContentClasses(editor).replace(/\s+/g, '|'))) {
  167. n.innerHTML = sel;
  168. }
  169. });
  170. replaceVals(editor, el);
  171. editor.execCommand('mceInsertContent', false, el.innerHTML);
  172. editor.addVisual();
  173. };
  174. var Templates = {
  175. createTemplateList: createTemplateList,
  176. replaceTemplateValues: replaceTemplateValues,
  177. replaceVals: replaceVals,
  178. insertTemplate: insertTemplate
  179. };
  180. var register = function (editor) {
  181. editor.addCommand('mceInsertTemplate', curry(Templates.insertTemplate, editor));
  182. };
  183. var Commands = { register: register };
  184. var setup = function (editor) {
  185. editor.on('PreProcess', function (o) {
  186. var dom = editor.dom, dateFormat = Settings.getMdateFormat(editor);
  187. global$1.each(dom.select('div', o.node), function (e) {
  188. if (dom.hasClass(e, 'mceTmpl')) {
  189. global$1.each(dom.select('*', e), function (e) {
  190. if (dom.hasClass(e, editor.getParam('template_mdate_classes', 'mdate').replace(/\s+/g, '|'))) {
  191. e.innerHTML = DateTimeHelper.getDateTime(editor, dateFormat);
  192. }
  193. });
  194. Templates.replaceVals(editor, e);
  195. }
  196. });
  197. });
  198. };
  199. var FilterContent = { setup: setup };
  200. var never$1 = never;
  201. var always$1 = always;
  202. var none = function () {
  203. return NONE;
  204. };
  205. var NONE = function () {
  206. var eq = function (o) {
  207. return o.isNone();
  208. };
  209. var call = function (thunk) {
  210. return thunk();
  211. };
  212. var id = function (n) {
  213. return n;
  214. };
  215. var noop = function () {
  216. };
  217. var nul = function () {
  218. return null;
  219. };
  220. var undef = function () {
  221. return undefined;
  222. };
  223. var me = {
  224. fold: function (n, s) {
  225. return n();
  226. },
  227. is: never$1,
  228. isSome: never$1,
  229. isNone: always$1,
  230. getOr: id,
  231. getOrThunk: call,
  232. getOrDie: function (msg) {
  233. throw new Error(msg || 'error: getOrDie called on none.');
  234. },
  235. getOrNull: nul,
  236. getOrUndefined: undef,
  237. or: id,
  238. orThunk: call,
  239. map: none,
  240. ap: none,
  241. each: noop,
  242. bind: none,
  243. flatten: none,
  244. exists: never$1,
  245. forall: always$1,
  246. filter: none,
  247. equals: eq,
  248. equals_: eq,
  249. toArray: function () {
  250. return [];
  251. },
  252. toString: constant('none()')
  253. };
  254. if (Object.freeze)
  255. Object.freeze(me);
  256. return me;
  257. }();
  258. var some = function (a) {
  259. var constant_a = function () {
  260. return a;
  261. };
  262. var self = function () {
  263. return me;
  264. };
  265. var map = function (f) {
  266. return some(f(a));
  267. };
  268. var bind = function (f) {
  269. return f(a);
  270. };
  271. var me = {
  272. fold: function (n, s) {
  273. return s(a);
  274. },
  275. is: function (v) {
  276. return a === v;
  277. },
  278. isSome: always$1,
  279. isNone: never$1,
  280. getOr: constant_a,
  281. getOrThunk: constant_a,
  282. getOrDie: constant_a,
  283. getOrNull: constant_a,
  284. getOrUndefined: constant_a,
  285. or: self,
  286. orThunk: self,
  287. map: map,
  288. ap: function (optfab) {
  289. return optfab.fold(none, function (fab) {
  290. return some(fab(a));
  291. });
  292. },
  293. each: function (f) {
  294. f(a);
  295. },
  296. bind: bind,
  297. flatten: constant_a,
  298. exists: bind,
  299. forall: bind,
  300. filter: function (f) {
  301. return f(a) ? me : NONE;
  302. },
  303. equals: function (o) {
  304. return o.is(a);
  305. },
  306. equals_: function (o, elementEq) {
  307. return o.fold(never$1, function (b) {
  308. return elementEq(a, b);
  309. });
  310. },
  311. toArray: function () {
  312. return [a];
  313. },
  314. toString: function () {
  315. return 'some(' + a + ')';
  316. }
  317. };
  318. return me;
  319. };
  320. var from = function (value) {
  321. return value === null || value === undefined ? NONE : some(value);
  322. };
  323. var Option = {
  324. some: some,
  325. none: none,
  326. from: from
  327. };
  328. var typeOf = function (x) {
  329. if (x === null)
  330. return 'null';
  331. var t = typeof x;
  332. if (t === 'object' && Array.prototype.isPrototypeOf(x))
  333. return 'array';
  334. if (t === 'object' && String.prototype.isPrototypeOf(x))
  335. return 'string';
  336. return t;
  337. };
  338. var isType = function (type) {
  339. return function (value) {
  340. return typeOf(value) === type;
  341. };
  342. };
  343. var isFunction = isType('function');
  344. var map = function (xs, f) {
  345. var len = xs.length;
  346. var r = new Array(len);
  347. for (var i = 0; i < len; i++) {
  348. var x = xs[i];
  349. r[i] = f(x, i, xs);
  350. }
  351. return r;
  352. };
  353. var find = function (xs, pred) {
  354. for (var i = 0, len = xs.length; i < len; i++) {
  355. var x = xs[i];
  356. if (pred(x, i, xs)) {
  357. return Option.some(x);
  358. }
  359. }
  360. return Option.none();
  361. };
  362. var slice = Array.prototype.slice;
  363. var from$1 = isFunction(Array.from) ? Array.from : function (x) {
  364. return slice.call(x);
  365. };
  366. var global$3 = tinymce.util.Tools.resolve('tinymce.util.Promise');
  367. var getPreviewContent = function (editor, html) {
  368. if (html.indexOf('<html>') === -1) {
  369. var contentCssLinks_1 = '';
  370. global$1.each(editor.contentCSS, function (url) {
  371. contentCssLinks_1 += '<link type="text/css" rel="stylesheet" href="' + editor.documentBaseURI.toAbsolute(url) + '">';
  372. });
  373. var bodyClass = editor.settings.body_class || '';
  374. if (bodyClass.indexOf('=') !== -1) {
  375. bodyClass = editor.getParam('body_class', '', 'hash');
  376. bodyClass = bodyClass[editor.id] || '';
  377. }
  378. html = '<!DOCTYPE html>' + '<html>' + '<head>' + contentCssLinks_1 + '</head>' + '<body class="' + bodyClass + '">' + html + '</body>' + '</html>';
  379. }
  380. return Templates.replaceTemplateValues(html, Settings.getPreviewReplaceValues(editor));
  381. };
  382. var open = function (editor, templateList) {
  383. var createTemplates = function () {
  384. if (!templateList || templateList.length === 0) {
  385. var message = editor.translate('No templates defined.');
  386. editor.notificationManager.open({
  387. text: message,
  388. type: 'info'
  389. });
  390. return Option.none();
  391. }
  392. return Option.from(global$1.map(templateList, function (template, index) {
  393. return {
  394. selected: index === 0,
  395. text: template.title,
  396. value: {
  397. url: template.url,
  398. content: template.content,
  399. description: template.description
  400. }
  401. };
  402. }));
  403. };
  404. var createSelectBoxItems = function (templates) {
  405. return map(templates, function (v) {
  406. return {
  407. text: v.text,
  408. value: v.text
  409. };
  410. });
  411. };
  412. var findTemplate = function (templates, templateTitle) {
  413. return find(templates, function (t) {
  414. return t.text === templateTitle;
  415. });
  416. };
  417. var getTemplateContent = function (t) {
  418. return new global$3(function (resolve, reject) {
  419. if (t.value.url) {
  420. global$2.send({
  421. url: t.value.url,
  422. success: function (html) {
  423. resolve(html);
  424. },
  425. error: function (e) {
  426. reject(e);
  427. }
  428. });
  429. } else {
  430. resolve(t.value.content);
  431. }
  432. });
  433. };
  434. var onChange = function (templates) {
  435. return function (api, change) {
  436. if (change.name === 'template') {
  437. var newTemplateTitle = api.getData().template;
  438. findTemplate(templates, newTemplateTitle).each(function (t) {
  439. api.block('Loading...');
  440. getTemplateContent(t).then(function (previewHtml) {
  441. var previewContent = getPreviewContent(editor, previewHtml);
  442. api.setData({ preview: previewContent });
  443. api.unblock();
  444. });
  445. });
  446. }
  447. };
  448. };
  449. var onSubmit = function (templates) {
  450. return function (api) {
  451. var data = api.getData();
  452. findTemplate(templates, data.template).each(function (t) {
  453. getTemplateContent(t).then(function (previewHtml) {
  454. Templates.insertTemplate(editor, false, previewHtml);
  455. api.close();
  456. });
  457. });
  458. };
  459. };
  460. var openDialog = function (templates) {
  461. var selectBoxItems = createSelectBoxItems(templates);
  462. var dialogSpec = function (bodyItems, initialData) {
  463. return {
  464. title: 'Insert Template',
  465. size: 'large',
  466. body: {
  467. type: 'panel',
  468. items: bodyItems
  469. },
  470. initialData: initialData,
  471. buttons: [
  472. {
  473. type: 'cancel',
  474. name: 'cancel',
  475. text: 'Cancel'
  476. },
  477. {
  478. type: 'submit',
  479. name: 'save',
  480. text: 'Save',
  481. primary: true
  482. }
  483. ],
  484. onSubmit: onSubmit(templates),
  485. onChange: onChange(templates)
  486. };
  487. };
  488. var dialogApi = editor.windowManager.open(dialogSpec([], {
  489. template: '',
  490. preview: ''
  491. }));
  492. dialogApi.block('Loading...');
  493. getTemplateContent(templates[0]).then(function (previewHtml) {
  494. var content = getPreviewContent(editor, previewHtml);
  495. var bodyItems = [
  496. {
  497. type: 'selectbox',
  498. name: 'template',
  499. label: 'Templates',
  500. items: selectBoxItems
  501. },
  502. {
  503. label: 'Preview',
  504. type: 'iframe',
  505. name: 'preview',
  506. sandboxed: false
  507. }
  508. ];
  509. var initialData = {
  510. template: templates[0].text,
  511. preview: content
  512. };
  513. dialogApi.unblock();
  514. dialogApi.redial(dialogSpec(bodyItems, initialData));
  515. dialogApi.focus('template');
  516. });
  517. };
  518. var optTemplates = createTemplates();
  519. optTemplates.each(openDialog);
  520. };
  521. var Dialog = { open: open };
  522. var showDialog = function (editor) {
  523. return function (templates) {
  524. Dialog.open(editor, templates);
  525. };
  526. };
  527. var register$1 = function (editor) {
  528. editor.ui.registry.addButton('template', {
  529. icon: 'template',
  530. tooltip: 'Insert template',
  531. onAction: Templates.createTemplateList(editor.settings, showDialog(editor))
  532. });
  533. editor.ui.registry.addMenuItem('template', {
  534. icon: 'template',
  535. text: 'Insert template...',
  536. onAction: Templates.createTemplateList(editor.settings, showDialog(editor))
  537. });
  538. };
  539. var Buttons = { register: register$1 };
  540. global.add('template', function (editor) {
  541. Buttons.register(editor);
  542. Commands.register(editor);
  543. FilterContent.setup(editor);
  544. });
  545. function Plugin () {
  546. }
  547. return Plugin;
  548. }());
  549. })();