plugin.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  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.1.0 (2019-10-17)
  8. */
  9. (function (domGlobals) {
  10. 'use strict';
  11. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  12. var unique = 0;
  13. var generate = function (prefix) {
  14. var date = new Date();
  15. var time = date.getTime();
  16. var random = Math.floor(Math.random() * 1000000000);
  17. unique++;
  18. return prefix + '_' + random + unique + String(time);
  19. };
  20. var createTableHtml = function (cols, rows) {
  21. var x, y, html;
  22. html = '<table data-mce-id="mce" style="width: 100%">';
  23. html += '<tbody>';
  24. for (y = 0; y < rows; y++) {
  25. html += '<tr>';
  26. for (x = 0; x < cols; x++) {
  27. html += '<td><br></td>';
  28. }
  29. html += '</tr>';
  30. }
  31. html += '</tbody>';
  32. html += '</table>';
  33. return html;
  34. };
  35. var getInsertedElement = function (editor) {
  36. var elms = editor.dom.select('*[data-mce-id]');
  37. return elms[0];
  38. };
  39. var insertTableHtml = function (editor, cols, rows) {
  40. editor.undoManager.transact(function () {
  41. var tableElm, cellElm;
  42. editor.insertContent(createTableHtml(cols, rows));
  43. tableElm = getInsertedElement(editor);
  44. tableElm.removeAttribute('data-mce-id');
  45. cellElm = editor.dom.select('td,th', tableElm);
  46. editor.selection.setCursorLocation(cellElm[0], 0);
  47. });
  48. };
  49. var insertTable = function (editor, cols, rows) {
  50. editor.plugins.table ? editor.plugins.table.insertTable(cols, rows) : insertTableHtml(editor, cols, rows);
  51. };
  52. var insertBlob = function (editor, base64, blob) {
  53. var blobCache, blobInfo;
  54. blobCache = editor.editorUpload.blobCache;
  55. blobInfo = blobCache.create(generate('mceu'), blob, base64);
  56. blobCache.add(blobInfo);
  57. editor.insertContent(editor.dom.createHTML('img', { src: blobInfo.blobUri() }));
  58. };
  59. var Actions = {
  60. insertTable: insertTable,
  61. insertBlob: insertBlob
  62. };
  63. var global$1 = tinymce.util.Tools.resolve('tinymce.util.Promise');
  64. var blobToBase64 = function (blob) {
  65. return new global$1(function (resolve) {
  66. var reader = new domGlobals.FileReader();
  67. reader.onloadend = function () {
  68. resolve(reader.result.split(',')[1]);
  69. };
  70. reader.readAsDataURL(blob);
  71. });
  72. };
  73. var Conversions = { blobToBase64: blobToBase64 };
  74. var pickFile = function () {
  75. return new global$1(function (resolve) {
  76. var fileInput;
  77. fileInput = domGlobals.document.createElement('input');
  78. fileInput.type = 'file';
  79. fileInput.style.position = 'fixed';
  80. fileInput.style.left = 0;
  81. fileInput.style.top = 0;
  82. fileInput.style.opacity = 0.001;
  83. domGlobals.document.body.appendChild(fileInput);
  84. fileInput.onchange = function (e) {
  85. resolve(Array.prototype.slice.call(e.target.files));
  86. };
  87. fileInput.click();
  88. fileInput.parentNode.removeChild(fileInput);
  89. });
  90. };
  91. var Picker = { pickFile: pickFile };
  92. var setupButtons = function (editor) {
  93. editor.ui.registry.addButton('quickimage', {
  94. icon: 'image',
  95. tooltip: 'Insert image',
  96. onAction: function () {
  97. Picker.pickFile().then(function (files) {
  98. var blob = files[0];
  99. Conversions.blobToBase64(blob).then(function (base64) {
  100. Actions.insertBlob(editor, base64, blob);
  101. });
  102. });
  103. }
  104. });
  105. editor.ui.registry.addButton('quicktable', {
  106. icon: 'table',
  107. tooltip: 'Insert table',
  108. onAction: function () {
  109. Actions.insertTable(editor, 2, 2);
  110. }
  111. });
  112. };
  113. var InsertButtons = { setupButtons: setupButtons };
  114. var noop = function () {
  115. };
  116. var constant = function (value) {
  117. return function () {
  118. return value;
  119. };
  120. };
  121. var never = constant(false);
  122. var always = constant(true);
  123. var none = function () {
  124. return NONE;
  125. };
  126. var NONE = function () {
  127. var eq = function (o) {
  128. return o.isNone();
  129. };
  130. var call = function (thunk) {
  131. return thunk();
  132. };
  133. var id = function (n) {
  134. return n;
  135. };
  136. var me = {
  137. fold: function (n, s) {
  138. return n();
  139. },
  140. is: never,
  141. isSome: never,
  142. isNone: always,
  143. getOr: id,
  144. getOrThunk: call,
  145. getOrDie: function (msg) {
  146. throw new Error(msg || 'error: getOrDie called on none.');
  147. },
  148. getOrNull: constant(null),
  149. getOrUndefined: constant(undefined),
  150. or: id,
  151. orThunk: call,
  152. map: none,
  153. each: noop,
  154. bind: none,
  155. exists: never,
  156. forall: always,
  157. filter: none,
  158. equals: eq,
  159. equals_: eq,
  160. toArray: function () {
  161. return [];
  162. },
  163. toString: constant('none()')
  164. };
  165. if (Object.freeze) {
  166. Object.freeze(me);
  167. }
  168. return me;
  169. }();
  170. var some = function (a) {
  171. var constant_a = constant(a);
  172. var self = function () {
  173. return me;
  174. };
  175. var bind = function (f) {
  176. return f(a);
  177. };
  178. var me = {
  179. fold: function (n, s) {
  180. return s(a);
  181. },
  182. is: function (v) {
  183. return a === v;
  184. },
  185. isSome: always,
  186. isNone: never,
  187. getOr: constant_a,
  188. getOrThunk: constant_a,
  189. getOrDie: constant_a,
  190. getOrNull: constant_a,
  191. getOrUndefined: constant_a,
  192. or: self,
  193. orThunk: self,
  194. map: function (f) {
  195. return some(f(a));
  196. },
  197. each: function (f) {
  198. f(a);
  199. },
  200. bind: bind,
  201. exists: bind,
  202. forall: bind,
  203. filter: function (f) {
  204. return f(a) ? me : NONE;
  205. },
  206. toArray: function () {
  207. return [a];
  208. },
  209. toString: function () {
  210. return 'some(' + a + ')';
  211. },
  212. equals: function (o) {
  213. return o.is(a);
  214. },
  215. equals_: function (o, elementEq) {
  216. return o.fold(never, function (b) {
  217. return elementEq(a, b);
  218. });
  219. }
  220. };
  221. return me;
  222. };
  223. var from = function (value) {
  224. return value === null || value === undefined ? NONE : some(value);
  225. };
  226. var Option = {
  227. some: some,
  228. none: none,
  229. from: from
  230. };
  231. var fromHtml = function (html, scope) {
  232. var doc = scope || domGlobals.document;
  233. var div = doc.createElement('div');
  234. div.innerHTML = html;
  235. if (!div.hasChildNodes() || div.childNodes.length > 1) {
  236. domGlobals.console.error('HTML does not have a single root node', html);
  237. throw new Error('HTML must have a single root node');
  238. }
  239. return fromDom(div.childNodes[0]);
  240. };
  241. var fromTag = function (tag, scope) {
  242. var doc = scope || domGlobals.document;
  243. var node = doc.createElement(tag);
  244. return fromDom(node);
  245. };
  246. var fromText = function (text, scope) {
  247. var doc = scope || domGlobals.document;
  248. var node = doc.createTextNode(text);
  249. return fromDom(node);
  250. };
  251. var fromDom = function (node) {
  252. if (node === null || node === undefined) {
  253. throw new Error('Node cannot be null or undefined');
  254. }
  255. return { dom: constant(node) };
  256. };
  257. var fromPoint = function (docElm, x, y) {
  258. var doc = docElm.dom();
  259. return Option.from(doc.elementFromPoint(x, y)).map(fromDom);
  260. };
  261. var Element = {
  262. fromHtml: fromHtml,
  263. fromTag: fromTag,
  264. fromText: fromText,
  265. fromDom: fromDom,
  266. fromPoint: fromPoint
  267. };
  268. var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE;
  269. var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE;
  270. var COMMENT = domGlobals.Node.COMMENT_NODE;
  271. var DOCUMENT = domGlobals.Node.DOCUMENT_NODE;
  272. var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE;
  273. var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE;
  274. var ELEMENT = domGlobals.Node.ELEMENT_NODE;
  275. var TEXT = domGlobals.Node.TEXT_NODE;
  276. var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE;
  277. var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE;
  278. var ENTITY = domGlobals.Node.ENTITY_NODE;
  279. var NOTATION = domGlobals.Node.NOTATION_NODE;
  280. var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')();
  281. var name = function (element) {
  282. var r = element.dom().nodeName;
  283. return r.toLowerCase();
  284. };
  285. var typeOf = function (x) {
  286. if (x === null) {
  287. return 'null';
  288. }
  289. var t = typeof x;
  290. if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
  291. return 'array';
  292. }
  293. if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
  294. return 'string';
  295. }
  296. return t;
  297. };
  298. var isType = function (type) {
  299. return function (value) {
  300. return typeOf(value) === type;
  301. };
  302. };
  303. var isString = isType('string');
  304. var isObject = isType('object');
  305. var isArray = isType('array');
  306. var isBoolean = isType('boolean');
  307. var isUndefined = isType('undefined');
  308. var isFunction = isType('function');
  309. var nativeSlice = Array.prototype.slice;
  310. var find = function (xs, pred) {
  311. for (var i = 0, len = xs.length; i < len; i++) {
  312. var x = xs[i];
  313. if (pred(x, i)) {
  314. return Option.some(x);
  315. }
  316. }
  317. return Option.none();
  318. };
  319. var from$1 = isFunction(Array.from) ? Array.from : function (x) {
  320. return nativeSlice.call(x);
  321. };
  322. function ClosestOrAncestor (is, ancestor, scope, a, isRoot) {
  323. return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot);
  324. }
  325. var compareDocumentPosition = function (a, b, match) {
  326. return (a.compareDocumentPosition(b) & match) !== 0;
  327. };
  328. var documentPositionPreceding = function (a, b) {
  329. return compareDocumentPosition(a, b, domGlobals.Node.DOCUMENT_POSITION_PRECEDING);
  330. };
  331. var documentPositionContainedBy = function (a, b) {
  332. return compareDocumentPosition(a, b, domGlobals.Node.DOCUMENT_POSITION_CONTAINED_BY);
  333. };
  334. var Node = {
  335. documentPositionPreceding: documentPositionPreceding,
  336. documentPositionContainedBy: documentPositionContainedBy
  337. };
  338. var Cell = function (initial) {
  339. var value = initial;
  340. var get = function () {
  341. return value;
  342. };
  343. var set = function (v) {
  344. value = v;
  345. };
  346. var clone = function () {
  347. return Cell(get());
  348. };
  349. return {
  350. get: get,
  351. set: set,
  352. clone: clone
  353. };
  354. };
  355. var firstMatch = function (regexes, s) {
  356. for (var i = 0; i < regexes.length; i++) {
  357. var x = regexes[i];
  358. if (x.test(s)) {
  359. return x;
  360. }
  361. }
  362. return undefined;
  363. };
  364. var find$1 = function (regexes, agent) {
  365. var r = firstMatch(regexes, agent);
  366. if (!r) {
  367. return {
  368. major: 0,
  369. minor: 0
  370. };
  371. }
  372. var group = function (i) {
  373. return Number(agent.replace(r, '$' + i));
  374. };
  375. return nu(group(1), group(2));
  376. };
  377. var detect = function (versionRegexes, agent) {
  378. var cleanedAgent = String(agent).toLowerCase();
  379. if (versionRegexes.length === 0) {
  380. return unknown();
  381. }
  382. return find$1(versionRegexes, cleanedAgent);
  383. };
  384. var unknown = function () {
  385. return nu(0, 0);
  386. };
  387. var nu = function (major, minor) {
  388. return {
  389. major: major,
  390. minor: minor
  391. };
  392. };
  393. var Version = {
  394. nu: nu,
  395. detect: detect,
  396. unknown: unknown
  397. };
  398. var edge = 'Edge';
  399. var chrome = 'Chrome';
  400. var ie = 'IE';
  401. var opera = 'Opera';
  402. var firefox = 'Firefox';
  403. var safari = 'Safari';
  404. var isBrowser = function (name, current) {
  405. return function () {
  406. return current === name;
  407. };
  408. };
  409. var unknown$1 = function () {
  410. return nu$1({
  411. current: undefined,
  412. version: Version.unknown()
  413. });
  414. };
  415. var nu$1 = function (info) {
  416. var current = info.current;
  417. var version = info.version;
  418. return {
  419. current: current,
  420. version: version,
  421. isEdge: isBrowser(edge, current),
  422. isChrome: isBrowser(chrome, current),
  423. isIE: isBrowser(ie, current),
  424. isOpera: isBrowser(opera, current),
  425. isFirefox: isBrowser(firefox, current),
  426. isSafari: isBrowser(safari, current)
  427. };
  428. };
  429. var Browser = {
  430. unknown: unknown$1,
  431. nu: nu$1,
  432. edge: constant(edge),
  433. chrome: constant(chrome),
  434. ie: constant(ie),
  435. opera: constant(opera),
  436. firefox: constant(firefox),
  437. safari: constant(safari)
  438. };
  439. var windows = 'Windows';
  440. var ios = 'iOS';
  441. var android = 'Android';
  442. var linux = 'Linux';
  443. var osx = 'OSX';
  444. var solaris = 'Solaris';
  445. var freebsd = 'FreeBSD';
  446. var isOS = function (name, current) {
  447. return function () {
  448. return current === name;
  449. };
  450. };
  451. var unknown$2 = function () {
  452. return nu$2({
  453. current: undefined,
  454. version: Version.unknown()
  455. });
  456. };
  457. var nu$2 = function (info) {
  458. var current = info.current;
  459. var version = info.version;
  460. return {
  461. current: current,
  462. version: version,
  463. isWindows: isOS(windows, current),
  464. isiOS: isOS(ios, current),
  465. isAndroid: isOS(android, current),
  466. isOSX: isOS(osx, current),
  467. isLinux: isOS(linux, current),
  468. isSolaris: isOS(solaris, current),
  469. isFreeBSD: isOS(freebsd, current)
  470. };
  471. };
  472. var OperatingSystem = {
  473. unknown: unknown$2,
  474. nu: nu$2,
  475. windows: constant(windows),
  476. ios: constant(ios),
  477. android: constant(android),
  478. linux: constant(linux),
  479. osx: constant(osx),
  480. solaris: constant(solaris),
  481. freebsd: constant(freebsd)
  482. };
  483. var DeviceType = function (os, browser, userAgent, mediaMatch) {
  484. var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;
  485. var isiPhone = os.isiOS() && !isiPad;
  486. var isMobile = os.isiOS() || os.isAndroid();
  487. var isTouch = isMobile || mediaMatch('(pointer:coarse)');
  488. var isTablet = isiPad || !isiPhone && isMobile && mediaMatch('(min-device-width:768px)');
  489. var isPhone = isiPhone || isMobile && !isTablet;
  490. var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;
  491. var isDesktop = !isPhone && !isTablet && !iOSwebview;
  492. return {
  493. isiPad: constant(isiPad),
  494. isiPhone: constant(isiPhone),
  495. isTablet: constant(isTablet),
  496. isPhone: constant(isPhone),
  497. isTouch: constant(isTouch),
  498. isAndroid: os.isAndroid,
  499. isiOS: os.isiOS,
  500. isWebView: constant(iOSwebview),
  501. isDesktop: constant(isDesktop)
  502. };
  503. };
  504. var detect$1 = function (candidates, userAgent) {
  505. var agent = String(userAgent).toLowerCase();
  506. return find(candidates, function (candidate) {
  507. return candidate.search(agent);
  508. });
  509. };
  510. var detectBrowser = function (browsers, userAgent) {
  511. return detect$1(browsers, userAgent).map(function (browser) {
  512. var version = Version.detect(browser.versionRegexes, userAgent);
  513. return {
  514. current: browser.name,
  515. version: version
  516. };
  517. });
  518. };
  519. var detectOs = function (oses, userAgent) {
  520. return detect$1(oses, userAgent).map(function (os) {
  521. var version = Version.detect(os.versionRegexes, userAgent);
  522. return {
  523. current: os.name,
  524. version: version
  525. };
  526. });
  527. };
  528. var UaString = {
  529. detectBrowser: detectBrowser,
  530. detectOs: detectOs
  531. };
  532. var contains = function (str, substr) {
  533. return str.indexOf(substr) !== -1;
  534. };
  535. var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
  536. var checkContains = function (target) {
  537. return function (uastring) {
  538. return contains(uastring, target);
  539. };
  540. };
  541. var browsers = [
  542. {
  543. name: 'Edge',
  544. versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],
  545. search: function (uastring) {
  546. return contains(uastring, 'edge/') && contains(uastring, 'chrome') && contains(uastring, 'safari') && contains(uastring, 'applewebkit');
  547. }
  548. },
  549. {
  550. name: 'Chrome',
  551. versionRegexes: [
  552. /.*?chrome\/([0-9]+)\.([0-9]+).*/,
  553. normalVersionRegex
  554. ],
  555. search: function (uastring) {
  556. return contains(uastring, 'chrome') && !contains(uastring, 'chromeframe');
  557. }
  558. },
  559. {
  560. name: 'IE',
  561. versionRegexes: [
  562. /.*?msie\ ?([0-9]+)\.([0-9]+).*/,
  563. /.*?rv:([0-9]+)\.([0-9]+).*/
  564. ],
  565. search: function (uastring) {
  566. return contains(uastring, 'msie') || contains(uastring, 'trident');
  567. }
  568. },
  569. {
  570. name: 'Opera',
  571. versionRegexes: [
  572. normalVersionRegex,
  573. /.*?opera\/([0-9]+)\.([0-9]+).*/
  574. ],
  575. search: checkContains('opera')
  576. },
  577. {
  578. name: 'Firefox',
  579. versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
  580. search: checkContains('firefox')
  581. },
  582. {
  583. name: 'Safari',
  584. versionRegexes: [
  585. normalVersionRegex,
  586. /.*?cpu os ([0-9]+)_([0-9]+).*/
  587. ],
  588. search: function (uastring) {
  589. return (contains(uastring, 'safari') || contains(uastring, 'mobile/')) && contains(uastring, 'applewebkit');
  590. }
  591. }
  592. ];
  593. var oses = [
  594. {
  595. name: 'Windows',
  596. search: checkContains('win'),
  597. versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
  598. },
  599. {
  600. name: 'iOS',
  601. search: function (uastring) {
  602. return contains(uastring, 'iphone') || contains(uastring, 'ipad');
  603. },
  604. versionRegexes: [
  605. /.*?version\/\ ?([0-9]+)\.([0-9]+).*/,
  606. /.*cpu os ([0-9]+)_([0-9]+).*/,
  607. /.*cpu iphone os ([0-9]+)_([0-9]+).*/
  608. ]
  609. },
  610. {
  611. name: 'Android',
  612. search: checkContains('android'),
  613. versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
  614. },
  615. {
  616. name: 'OSX',
  617. search: checkContains('os x'),
  618. versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/]
  619. },
  620. {
  621. name: 'Linux',
  622. search: checkContains('linux'),
  623. versionRegexes: []
  624. },
  625. {
  626. name: 'Solaris',
  627. search: checkContains('sunos'),
  628. versionRegexes: []
  629. },
  630. {
  631. name: 'FreeBSD',
  632. search: checkContains('freebsd'),
  633. versionRegexes: []
  634. }
  635. ];
  636. var PlatformInfo = {
  637. browsers: constant(browsers),
  638. oses: constant(oses)
  639. };
  640. var detect$2 = function (userAgent, mediaMatch) {
  641. var browsers = PlatformInfo.browsers();
  642. var oses = PlatformInfo.oses();
  643. var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu);
  644. var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);
  645. var deviceType = DeviceType(os, browser, userAgent, mediaMatch);
  646. return {
  647. browser: browser,
  648. os: os,
  649. deviceType: deviceType
  650. };
  651. };
  652. var PlatformDetection = { detect: detect$2 };
  653. var mediaMatch = function (query) {
  654. return domGlobals.window.matchMedia(query).matches;
  655. };
  656. var platform = Cell(PlatformDetection.detect(domGlobals.navigator.userAgent, mediaMatch));
  657. var detect$3 = function () {
  658. return platform.get();
  659. };
  660. var ELEMENT$1 = ELEMENT;
  661. var is = function (element, selector) {
  662. var dom = element.dom();
  663. if (dom.nodeType !== ELEMENT$1) {
  664. return false;
  665. } else {
  666. var elem = dom;
  667. if (elem.matches !== undefined) {
  668. return elem.matches(selector);
  669. } else if (elem.msMatchesSelector !== undefined) {
  670. return elem.msMatchesSelector(selector);
  671. } else if (elem.webkitMatchesSelector !== undefined) {
  672. return elem.webkitMatchesSelector(selector);
  673. } else if (elem.mozMatchesSelector !== undefined) {
  674. return elem.mozMatchesSelector(selector);
  675. } else {
  676. throw new Error('Browser lacks native selectors');
  677. }
  678. }
  679. };
  680. var regularContains = function (e1, e2) {
  681. var d1 = e1.dom();
  682. var d2 = e2.dom();
  683. return d1 === d2 ? false : d1.contains(d2);
  684. };
  685. var ieContains = function (e1, e2) {
  686. return Node.documentPositionContainedBy(e1.dom(), e2.dom());
  687. };
  688. var browser = detect$3().browser;
  689. var contains$1 = browser.isIE() ? ieContains : regularContains;
  690. var ancestor = function (scope, predicate, isRoot) {
  691. var element = scope.dom();
  692. var stop = isFunction(isRoot) ? isRoot : constant(false);
  693. while (element.parentNode) {
  694. element = element.parentNode;
  695. var el = Element.fromDom(element);
  696. if (predicate(el)) {
  697. return Option.some(el);
  698. } else if (stop(el)) {
  699. break;
  700. }
  701. }
  702. return Option.none();
  703. };
  704. var closest = function (scope, predicate, isRoot) {
  705. var is = function (s, test) {
  706. return test(s);
  707. };
  708. return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot);
  709. };
  710. var ancestor$1 = function (scope, selector, isRoot) {
  711. return ancestor(scope, function (e) {
  712. return is(e, selector);
  713. }, isRoot);
  714. };
  715. var closest$1 = function (scope, selector, isRoot) {
  716. return ClosestOrAncestor(is, ancestor$1, scope, selector, isRoot);
  717. };
  718. var validDefaultOrDie = function (value, predicate) {
  719. if (predicate(value)) {
  720. return true;
  721. }
  722. throw new Error('Default value doesn\'t match requested type.');
  723. };
  724. var items = function (value, defaultValue) {
  725. if (isArray(value) || isObject(value)) {
  726. throw new Error('expected a string but found: ' + value);
  727. }
  728. if (isUndefined(value)) {
  729. return defaultValue;
  730. }
  731. if (isBoolean(value)) {
  732. return value === false ? '' : defaultValue;
  733. }
  734. return value;
  735. };
  736. var getToolbarItemsOr = function (predicate) {
  737. return function (editor, name, defaultValue) {
  738. validDefaultOrDie(defaultValue, predicate);
  739. var value = editor.getParam(name, defaultValue);
  740. return items(value, defaultValue);
  741. };
  742. };
  743. var EditorSettings = { getToolbarItemsOr: getToolbarItemsOr(isString) };
  744. var getTextSelectionToolbarItems = function (editor) {
  745. return EditorSettings.getToolbarItemsOr(editor, 'quickbars_selection_toolbar', 'bold italic | quicklink h2 h3 blockquote');
  746. };
  747. var getInsertToolbarItems = function (editor) {
  748. return EditorSettings.getToolbarItemsOr(editor, 'quickbars_insert_toolbar', 'quickimage quicktable');
  749. };
  750. var Settings = {
  751. getTextSelectionToolbarItems: getTextSelectionToolbarItems,
  752. getInsertToolbarItems: getInsertToolbarItems
  753. };
  754. var addToEditor = function (editor) {
  755. var insertToolbarItems = Settings.getInsertToolbarItems(editor);
  756. if (insertToolbarItems.trim().length > 0) {
  757. editor.ui.registry.addContextToolbar('quickblock', {
  758. predicate: function (node) {
  759. var sugarNode = Element.fromDom(node);
  760. var textBlockElementsMap = editor.schema.getTextBlockElements();
  761. var isRoot = function (elem) {
  762. return elem.dom() === editor.getBody();
  763. };
  764. return closest$1(sugarNode, 'table', isRoot).fold(function () {
  765. return closest(sugarNode, function (elem) {
  766. return name(elem) in textBlockElementsMap && editor.dom.isEmpty(elem.dom());
  767. }, isRoot).isSome();
  768. }, function () {
  769. return false;
  770. });
  771. },
  772. items: insertToolbarItems,
  773. position: 'line',
  774. scope: 'editor'
  775. });
  776. }
  777. };
  778. var InsertToolbars = { addToEditor: addToEditor };
  779. var addToEditor$1 = function (editor) {
  780. editor.ui.registry.addContextToolbar('imageselection', {
  781. predicate: function (node) {
  782. return node.nodeName === 'IMG' || node.nodeName === 'FIGURE' && /image/i.test(node.className);
  783. },
  784. items: 'alignleft aligncenter alignright',
  785. position: 'node'
  786. });
  787. var textToolbarItems = Settings.getTextSelectionToolbarItems(editor);
  788. if (textToolbarItems.trim().length > 0) {
  789. editor.ui.registry.addContextToolbar('textselection', {
  790. predicate: function (node) {
  791. return !editor.selection.isCollapsed();
  792. },
  793. items: textToolbarItems,
  794. position: 'selection'
  795. });
  796. }
  797. };
  798. var SelectionToolbars = { addToEditor: addToEditor$1 };
  799. function Plugin () {
  800. global.add('quickbars', function (editor) {
  801. InsertButtons.setupButtons(editor);
  802. InsertToolbars.addToEditor(editor);
  803. SelectionToolbars.addToEditor(editor);
  804. });
  805. }
  806. Plugin();
  807. }(window));