plugin.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /**
  2. * TinyMCE version 6.4.2 (2023-04-26)
  3. */
  4. (function () {
  5. 'use strict';
  6. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  7. const hasProto = (v, constructor, predicate) => {
  8. var _a;
  9. if (predicate(v, constructor.prototype)) {
  10. return true;
  11. } else {
  12. return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
  13. }
  14. };
  15. const typeOf = x => {
  16. const t = typeof x;
  17. if (x === null) {
  18. return 'null';
  19. } else if (t === 'object' && Array.isArray(x)) {
  20. return 'array';
  21. } else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
  22. return 'string';
  23. } else {
  24. return t;
  25. }
  26. };
  27. const isType$1 = type => value => typeOf(value) === type;
  28. const isSimpleType = type => value => typeof value === type;
  29. const isString = isType$1('string');
  30. const isBoolean = isSimpleType('boolean');
  31. const isNullable = a => a === null || a === undefined;
  32. const isNonNullable = a => !isNullable(a);
  33. const isFunction = isSimpleType('function');
  34. const isNumber = isSimpleType('number');
  35. const compose1 = (fbc, fab) => a => fbc(fab(a));
  36. const constant = value => {
  37. return () => {
  38. return value;
  39. };
  40. };
  41. const never = constant(false);
  42. class Optional {
  43. constructor(tag, value) {
  44. this.tag = tag;
  45. this.value = value;
  46. }
  47. static some(value) {
  48. return new Optional(true, value);
  49. }
  50. static none() {
  51. return Optional.singletonNone;
  52. }
  53. fold(onNone, onSome) {
  54. if (this.tag) {
  55. return onSome(this.value);
  56. } else {
  57. return onNone();
  58. }
  59. }
  60. isSome() {
  61. return this.tag;
  62. }
  63. isNone() {
  64. return !this.tag;
  65. }
  66. map(mapper) {
  67. if (this.tag) {
  68. return Optional.some(mapper(this.value));
  69. } else {
  70. return Optional.none();
  71. }
  72. }
  73. bind(binder) {
  74. if (this.tag) {
  75. return binder(this.value);
  76. } else {
  77. return Optional.none();
  78. }
  79. }
  80. exists(predicate) {
  81. return this.tag && predicate(this.value);
  82. }
  83. forall(predicate) {
  84. return !this.tag || predicate(this.value);
  85. }
  86. filter(predicate) {
  87. if (!this.tag || predicate(this.value)) {
  88. return this;
  89. } else {
  90. return Optional.none();
  91. }
  92. }
  93. getOr(replacement) {
  94. return this.tag ? this.value : replacement;
  95. }
  96. or(replacement) {
  97. return this.tag ? this : replacement;
  98. }
  99. getOrThunk(thunk) {
  100. return this.tag ? this.value : thunk();
  101. }
  102. orThunk(thunk) {
  103. return this.tag ? this : thunk();
  104. }
  105. getOrDie(message) {
  106. if (!this.tag) {
  107. throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
  108. } else {
  109. return this.value;
  110. }
  111. }
  112. static from(value) {
  113. return isNonNullable(value) ? Optional.some(value) : Optional.none();
  114. }
  115. getOrNull() {
  116. return this.tag ? this.value : null;
  117. }
  118. getOrUndefined() {
  119. return this.value;
  120. }
  121. each(worker) {
  122. if (this.tag) {
  123. worker(this.value);
  124. }
  125. }
  126. toArray() {
  127. return this.tag ? [this.value] : [];
  128. }
  129. toString() {
  130. return this.tag ? `some(${ this.value })` : 'none()';
  131. }
  132. }
  133. Optional.singletonNone = new Optional(false);
  134. const map = (xs, f) => {
  135. const len = xs.length;
  136. const r = new Array(len);
  137. for (let i = 0; i < len; i++) {
  138. const x = xs[i];
  139. r[i] = f(x, i);
  140. }
  141. return r;
  142. };
  143. const each = (xs, f) => {
  144. for (let i = 0, len = xs.length; i < len; i++) {
  145. const x = xs[i];
  146. f(x, i);
  147. }
  148. };
  149. const filter = (xs, pred) => {
  150. const r = [];
  151. for (let i = 0, len = xs.length; i < len; i++) {
  152. const x = xs[i];
  153. if (pred(x, i)) {
  154. r.push(x);
  155. }
  156. }
  157. return r;
  158. };
  159. const DOCUMENT = 9;
  160. const DOCUMENT_FRAGMENT = 11;
  161. const ELEMENT = 1;
  162. const TEXT = 3;
  163. const fromHtml = (html, scope) => {
  164. const doc = scope || document;
  165. const div = doc.createElement('div');
  166. div.innerHTML = html;
  167. if (!div.hasChildNodes() || div.childNodes.length > 1) {
  168. const message = 'HTML does not have a single root node';
  169. console.error(message, html);
  170. throw new Error(message);
  171. }
  172. return fromDom(div.childNodes[0]);
  173. };
  174. const fromTag = (tag, scope) => {
  175. const doc = scope || document;
  176. const node = doc.createElement(tag);
  177. return fromDom(node);
  178. };
  179. const fromText = (text, scope) => {
  180. const doc = scope || document;
  181. const node = doc.createTextNode(text);
  182. return fromDom(node);
  183. };
  184. const fromDom = node => {
  185. if (node === null || node === undefined) {
  186. throw new Error('Node cannot be null or undefined');
  187. }
  188. return { dom: node };
  189. };
  190. const fromPoint = (docElm, x, y) => Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom);
  191. const SugarElement = {
  192. fromHtml,
  193. fromTag,
  194. fromText,
  195. fromDom,
  196. fromPoint
  197. };
  198. const is = (element, selector) => {
  199. const dom = element.dom;
  200. if (dom.nodeType !== ELEMENT) {
  201. return false;
  202. } else {
  203. const elem = dom;
  204. if (elem.matches !== undefined) {
  205. return elem.matches(selector);
  206. } else if (elem.msMatchesSelector !== undefined) {
  207. return elem.msMatchesSelector(selector);
  208. } else if (elem.webkitMatchesSelector !== undefined) {
  209. return elem.webkitMatchesSelector(selector);
  210. } else if (elem.mozMatchesSelector !== undefined) {
  211. return elem.mozMatchesSelector(selector);
  212. } else {
  213. throw new Error('Browser lacks native selectors');
  214. }
  215. }
  216. };
  217. typeof window !== 'undefined' ? window : Function('return this;')();
  218. const name = element => {
  219. const r = element.dom.nodeName;
  220. return r.toLowerCase();
  221. };
  222. const type = element => element.dom.nodeType;
  223. const isType = t => element => type(element) === t;
  224. const isElement = isType(ELEMENT);
  225. const isText = isType(TEXT);
  226. const isDocument = isType(DOCUMENT);
  227. const isDocumentFragment = isType(DOCUMENT_FRAGMENT);
  228. const isTag = tag => e => isElement(e) && name(e) === tag;
  229. const owner = element => SugarElement.fromDom(element.dom.ownerDocument);
  230. const documentOrOwner = dos => isDocument(dos) ? dos : owner(dos);
  231. const parent = element => Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
  232. const children$2 = element => map(element.dom.childNodes, SugarElement.fromDom);
  233. const rawSet = (dom, key, value) => {
  234. if (isString(value) || isBoolean(value) || isNumber(value)) {
  235. dom.setAttribute(key, value + '');
  236. } else {
  237. console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
  238. throw new Error('Attribute value was not simple');
  239. }
  240. };
  241. const set = (element, key, value) => {
  242. rawSet(element.dom, key, value);
  243. };
  244. const remove = (element, key) => {
  245. element.dom.removeAttribute(key);
  246. };
  247. const isShadowRoot = dos => isDocumentFragment(dos) && isNonNullable(dos.dom.host);
  248. const supported = isFunction(Element.prototype.attachShadow) && isFunction(Node.prototype.getRootNode);
  249. const getRootNode = supported ? e => SugarElement.fromDom(e.dom.getRootNode()) : documentOrOwner;
  250. const getShadowRoot = e => {
  251. const r = getRootNode(e);
  252. return isShadowRoot(r) ? Optional.some(r) : Optional.none();
  253. };
  254. const getShadowHost = e => SugarElement.fromDom(e.dom.host);
  255. const inBody = element => {
  256. const dom = isText(element) ? element.dom.parentNode : element.dom;
  257. if (dom === undefined || dom === null || dom.ownerDocument === null) {
  258. return false;
  259. }
  260. const doc = dom.ownerDocument;
  261. return getShadowRoot(SugarElement.fromDom(dom)).fold(() => doc.body.contains(dom), compose1(inBody, getShadowHost));
  262. };
  263. const ancestor$1 = (scope, predicate, isRoot) => {
  264. let element = scope.dom;
  265. const stop = isFunction(isRoot) ? isRoot : never;
  266. while (element.parentNode) {
  267. element = element.parentNode;
  268. const el = SugarElement.fromDom(element);
  269. if (predicate(el)) {
  270. return Optional.some(el);
  271. } else if (stop(el)) {
  272. break;
  273. }
  274. }
  275. return Optional.none();
  276. };
  277. const ancestor = (scope, selector, isRoot) => ancestor$1(scope, e => is(e, selector), isRoot);
  278. const isSupported = dom => dom.style !== undefined && isFunction(dom.style.getPropertyValue);
  279. const get = (element, property) => {
  280. const dom = element.dom;
  281. const styles = window.getComputedStyle(dom);
  282. const r = styles.getPropertyValue(property);
  283. return r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;
  284. };
  285. const getUnsafeProperty = (dom, property) => isSupported(dom) ? dom.style.getPropertyValue(property) : '';
  286. const getDirection = element => get(element, 'direction') === 'rtl' ? 'rtl' : 'ltr';
  287. const children$1 = (scope, predicate) => filter(children$2(scope), predicate);
  288. const children = (scope, selector) => children$1(scope, e => is(e, selector));
  289. const getParentElement = element => parent(element).filter(isElement);
  290. const getNormalizedBlock = (element, isListItem) => {
  291. const normalizedElement = isListItem ? ancestor(element, 'ol,ul') : Optional.some(element);
  292. return normalizedElement.getOr(element);
  293. };
  294. const isListItem = isTag('li');
  295. const setDir = (editor, dir) => {
  296. const selectedBlocks = editor.selection.getSelectedBlocks();
  297. if (selectedBlocks.length > 0) {
  298. each(selectedBlocks, block => {
  299. const blockElement = SugarElement.fromDom(block);
  300. const isBlockElementListItem = isListItem(blockElement);
  301. const normalizedBlock = getNormalizedBlock(blockElement, isBlockElementListItem);
  302. const normalizedBlockParent = getParentElement(normalizedBlock);
  303. normalizedBlockParent.each(parent => {
  304. const parentDirection = getDirection(parent);
  305. if (parentDirection !== dir) {
  306. set(normalizedBlock, 'dir', dir);
  307. } else if (getDirection(normalizedBlock) !== dir) {
  308. remove(normalizedBlock, 'dir');
  309. }
  310. if (isBlockElementListItem) {
  311. const listItems = children(normalizedBlock, 'li[dir]');
  312. each(listItems, listItem => remove(listItem, 'dir'));
  313. }
  314. });
  315. });
  316. editor.nodeChanged();
  317. }
  318. };
  319. const register$1 = editor => {
  320. editor.addCommand('mceDirectionLTR', () => {
  321. setDir(editor, 'ltr');
  322. });
  323. editor.addCommand('mceDirectionRTL', () => {
  324. setDir(editor, 'rtl');
  325. });
  326. };
  327. const getNodeChangeHandler = (editor, dir) => api => {
  328. const nodeChangeHandler = e => {
  329. const element = SugarElement.fromDom(e.element);
  330. api.setActive(getDirection(element) === dir);
  331. };
  332. editor.on('NodeChange', nodeChangeHandler);
  333. return () => editor.off('NodeChange', nodeChangeHandler);
  334. };
  335. const register = editor => {
  336. editor.ui.registry.addToggleButton('ltr', {
  337. tooltip: 'Left to right',
  338. icon: 'ltr',
  339. onAction: () => editor.execCommand('mceDirectionLTR'),
  340. onSetup: getNodeChangeHandler(editor, 'ltr')
  341. });
  342. editor.ui.registry.addToggleButton('rtl', {
  343. tooltip: 'Right to left',
  344. icon: 'rtl',
  345. onAction: () => editor.execCommand('mceDirectionRTL'),
  346. onSetup: getNodeChangeHandler(editor, 'rtl')
  347. });
  348. };
  349. var Plugin = () => {
  350. global.add('directionality', editor => {
  351. register$1(editor);
  352. register(editor);
  353. });
  354. };
  355. Plugin();
  356. })();