plugin.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  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$3 = tinymce.util.Tools.resolve('tinymce.PluginManager');
  25. var get$5 = function (fullscreenState) {
  26. return {
  27. isFullscreen: function () {
  28. return fullscreenState.get() !== null;
  29. }
  30. };
  31. };
  32. var typeOf = function (x) {
  33. var t = typeof x;
  34. if (x === null) {
  35. return 'null';
  36. } else if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
  37. return 'array';
  38. } else if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
  39. return 'string';
  40. } else {
  41. return t;
  42. }
  43. };
  44. var isType$1 = function (type) {
  45. return function (value) {
  46. return typeOf(value) === type;
  47. };
  48. };
  49. var isSimpleType = function (type) {
  50. return function (value) {
  51. return typeof value === type;
  52. };
  53. };
  54. var isString = isType$1('string');
  55. var isArray = isType$1('array');
  56. var isBoolean = isSimpleType('boolean');
  57. var isNullable = function (a) {
  58. return a === null || a === undefined;
  59. };
  60. var isNonNullable = function (a) {
  61. return !isNullable(a);
  62. };
  63. var isFunction = isSimpleType('function');
  64. var isNumber = isSimpleType('number');
  65. var noop = function () {
  66. };
  67. var compose = function (fa, fb) {
  68. return function () {
  69. var args = [];
  70. for (var _i = 0; _i < arguments.length; _i++) {
  71. args[_i] = arguments[_i];
  72. }
  73. return fa(fb.apply(null, args));
  74. };
  75. };
  76. var compose1 = function (fbc, fab) {
  77. return function (a) {
  78. return fbc(fab(a));
  79. };
  80. };
  81. var constant = function (value) {
  82. return function () {
  83. return value;
  84. };
  85. };
  86. var identity = function (x) {
  87. return x;
  88. };
  89. function curry(fn) {
  90. var initialArgs = [];
  91. for (var _i = 1; _i < arguments.length; _i++) {
  92. initialArgs[_i - 1] = arguments[_i];
  93. }
  94. return function () {
  95. var restArgs = [];
  96. for (var _i = 0; _i < arguments.length; _i++) {
  97. restArgs[_i] = arguments[_i];
  98. }
  99. var all = initialArgs.concat(restArgs);
  100. return fn.apply(null, all);
  101. };
  102. }
  103. var never = constant(false);
  104. var always = constant(true);
  105. var none = function () {
  106. return NONE;
  107. };
  108. var NONE = function () {
  109. var call = function (thunk) {
  110. return thunk();
  111. };
  112. var id = identity;
  113. var me = {
  114. fold: function (n, _s) {
  115. return n();
  116. },
  117. isSome: never,
  118. isNone: always,
  119. getOr: id,
  120. getOrThunk: call,
  121. getOrDie: function (msg) {
  122. throw new Error(msg || 'error: getOrDie called on none.');
  123. },
  124. getOrNull: constant(null),
  125. getOrUndefined: constant(undefined),
  126. or: id,
  127. orThunk: call,
  128. map: none,
  129. each: noop,
  130. bind: none,
  131. exists: never,
  132. forall: always,
  133. filter: function () {
  134. return none();
  135. },
  136. toArray: function () {
  137. return [];
  138. },
  139. toString: constant('none()')
  140. };
  141. return me;
  142. }();
  143. var some = function (a) {
  144. var constant_a = constant(a);
  145. var self = function () {
  146. return me;
  147. };
  148. var bind = function (f) {
  149. return f(a);
  150. };
  151. var me = {
  152. fold: function (n, s) {
  153. return s(a);
  154. },
  155. isSome: always,
  156. isNone: never,
  157. getOr: constant_a,
  158. getOrThunk: constant_a,
  159. getOrDie: constant_a,
  160. getOrNull: constant_a,
  161. getOrUndefined: constant_a,
  162. or: self,
  163. orThunk: self,
  164. map: function (f) {
  165. return some(f(a));
  166. },
  167. each: function (f) {
  168. f(a);
  169. },
  170. bind: bind,
  171. exists: bind,
  172. forall: bind,
  173. filter: function (f) {
  174. return f(a) ? me : NONE;
  175. },
  176. toArray: function () {
  177. return [a];
  178. },
  179. toString: function () {
  180. return 'some(' + a + ')';
  181. }
  182. };
  183. return me;
  184. };
  185. var from = function (value) {
  186. return value === null || value === undefined ? NONE : some(value);
  187. };
  188. var Optional = {
  189. some: some,
  190. none: none,
  191. from: from
  192. };
  193. var __assign = function () {
  194. __assign = Object.assign || function __assign(t) {
  195. for (var s, i = 1, n = arguments.length; i < n; i++) {
  196. s = arguments[i];
  197. for (var p in s)
  198. if (Object.prototype.hasOwnProperty.call(s, p))
  199. t[p] = s[p];
  200. }
  201. return t;
  202. };
  203. return __assign.apply(this, arguments);
  204. };
  205. var singleton = function (doRevoke) {
  206. var subject = Cell(Optional.none());
  207. var revoke = function () {
  208. return subject.get().each(doRevoke);
  209. };
  210. var clear = function () {
  211. revoke();
  212. subject.set(Optional.none());
  213. };
  214. var isSet = function () {
  215. return subject.get().isSome();
  216. };
  217. var get = function () {
  218. return subject.get();
  219. };
  220. var set = function (s) {
  221. revoke();
  222. subject.set(Optional.some(s));
  223. };
  224. return {
  225. clear: clear,
  226. isSet: isSet,
  227. get: get,
  228. set: set
  229. };
  230. };
  231. var unbindable = function () {
  232. return singleton(function (s) {
  233. return s.unbind();
  234. });
  235. };
  236. var value = function () {
  237. var subject = singleton(noop);
  238. var on = function (f) {
  239. return subject.get().each(f);
  240. };
  241. return __assign(__assign({}, subject), { on: on });
  242. };
  243. var nativePush = Array.prototype.push;
  244. var map = function (xs, f) {
  245. var len = xs.length;
  246. var r = new Array(len);
  247. for (var i = 0; i < len; i++) {
  248. var x = xs[i];
  249. r[i] = f(x, i);
  250. }
  251. return r;
  252. };
  253. var each$1 = function (xs, f) {
  254. for (var i = 0, len = xs.length; i < len; i++) {
  255. var x = xs[i];
  256. f(x, i);
  257. }
  258. };
  259. var filter$1 = function (xs, pred) {
  260. var r = [];
  261. for (var i = 0, len = xs.length; i < len; i++) {
  262. var x = xs[i];
  263. if (pred(x, i)) {
  264. r.push(x);
  265. }
  266. }
  267. return r;
  268. };
  269. var flatten = function (xs) {
  270. var r = [];
  271. for (var i = 0, len = xs.length; i < len; ++i) {
  272. if (!isArray(xs[i])) {
  273. throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
  274. }
  275. nativePush.apply(r, xs[i]);
  276. }
  277. return r;
  278. };
  279. var bind$3 = function (xs, f) {
  280. return flatten(map(xs, f));
  281. };
  282. var get$4 = function (xs, i) {
  283. return i >= 0 && i < xs.length ? Optional.some(xs[i]) : Optional.none();
  284. };
  285. var head = function (xs) {
  286. return get$4(xs, 0);
  287. };
  288. var keys = Object.keys;
  289. var each = function (obj, f) {
  290. var props = keys(obj);
  291. for (var k = 0, len = props.length; k < len; k++) {
  292. var i = props[k];
  293. var x = obj[i];
  294. f(x, i);
  295. }
  296. };
  297. var isSupported$1 = function (dom) {
  298. return dom.style !== undefined && isFunction(dom.style.getPropertyValue);
  299. };
  300. var fromHtml = function (html, scope) {
  301. var doc = scope || document;
  302. var div = doc.createElement('div');
  303. div.innerHTML = html;
  304. if (!div.hasChildNodes() || div.childNodes.length > 1) {
  305. console.error('HTML does not have a single root node', html);
  306. throw new Error('HTML must have a single root node');
  307. }
  308. return fromDom(div.childNodes[0]);
  309. };
  310. var fromTag = function (tag, scope) {
  311. var doc = scope || document;
  312. var node = doc.createElement(tag);
  313. return fromDom(node);
  314. };
  315. var fromText = function (text, scope) {
  316. var doc = scope || document;
  317. var node = doc.createTextNode(text);
  318. return fromDom(node);
  319. };
  320. var fromDom = function (node) {
  321. if (node === null || node === undefined) {
  322. throw new Error('Node cannot be null or undefined');
  323. }
  324. return { dom: node };
  325. };
  326. var fromPoint = function (docElm, x, y) {
  327. return Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom);
  328. };
  329. var SugarElement = {
  330. fromHtml: fromHtml,
  331. fromTag: fromTag,
  332. fromText: fromText,
  333. fromDom: fromDom,
  334. fromPoint: fromPoint
  335. };
  336. typeof window !== 'undefined' ? window : Function('return this;')();
  337. var DOCUMENT = 9;
  338. var DOCUMENT_FRAGMENT = 11;
  339. var ELEMENT = 1;
  340. var TEXT = 3;
  341. var type = function (element) {
  342. return element.dom.nodeType;
  343. };
  344. var isType = function (t) {
  345. return function (element) {
  346. return type(element) === t;
  347. };
  348. };
  349. var isElement = isType(ELEMENT);
  350. var isText = isType(TEXT);
  351. var isDocument = isType(DOCUMENT);
  352. var isDocumentFragment = isType(DOCUMENT_FRAGMENT);
  353. var is = function (element, selector) {
  354. var dom = element.dom;
  355. if (dom.nodeType !== ELEMENT) {
  356. return false;
  357. } else {
  358. var elem = dom;
  359. if (elem.matches !== undefined) {
  360. return elem.matches(selector);
  361. } else if (elem.msMatchesSelector !== undefined) {
  362. return elem.msMatchesSelector(selector);
  363. } else if (elem.webkitMatchesSelector !== undefined) {
  364. return elem.webkitMatchesSelector(selector);
  365. } else if (elem.mozMatchesSelector !== undefined) {
  366. return elem.mozMatchesSelector(selector);
  367. } else {
  368. throw new Error('Browser lacks native selectors');
  369. }
  370. }
  371. };
  372. var bypassSelector = function (dom) {
  373. return dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT && dom.nodeType !== DOCUMENT_FRAGMENT || dom.childElementCount === 0;
  374. };
  375. var all$1 = function (selector, scope) {
  376. var base = scope === undefined ? document : scope.dom;
  377. return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), SugarElement.fromDom);
  378. };
  379. var eq = function (e1, e2) {
  380. return e1.dom === e2.dom;
  381. };
  382. var owner = function (element) {
  383. return SugarElement.fromDom(element.dom.ownerDocument);
  384. };
  385. var documentOrOwner = function (dos) {
  386. return isDocument(dos) ? dos : owner(dos);
  387. };
  388. var parent = function (element) {
  389. return Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
  390. };
  391. var parents = function (element, isRoot) {
  392. var stop = isFunction(isRoot) ? isRoot : never;
  393. var dom = element.dom;
  394. var ret = [];
  395. while (dom.parentNode !== null && dom.parentNode !== undefined) {
  396. var rawParent = dom.parentNode;
  397. var p = SugarElement.fromDom(rawParent);
  398. ret.push(p);
  399. if (stop(p) === true) {
  400. break;
  401. } else {
  402. dom = rawParent;
  403. }
  404. }
  405. return ret;
  406. };
  407. var siblings$2 = function (element) {
  408. var filterSelf = function (elements) {
  409. return filter$1(elements, function (x) {
  410. return !eq(element, x);
  411. });
  412. };
  413. return parent(element).map(children).map(filterSelf).getOr([]);
  414. };
  415. var children = function (element) {
  416. return map(element.dom.childNodes, SugarElement.fromDom);
  417. };
  418. var isShadowRoot = function (dos) {
  419. return isDocumentFragment(dos) && isNonNullable(dos.dom.host);
  420. };
  421. var supported = isFunction(Element.prototype.attachShadow) && isFunction(Node.prototype.getRootNode);
  422. var isSupported = constant(supported);
  423. var getRootNode = supported ? function (e) {
  424. return SugarElement.fromDom(e.dom.getRootNode());
  425. } : documentOrOwner;
  426. var getShadowRoot = function (e) {
  427. var r = getRootNode(e);
  428. return isShadowRoot(r) ? Optional.some(r) : Optional.none();
  429. };
  430. var getShadowHost = function (e) {
  431. return SugarElement.fromDom(e.dom.host);
  432. };
  433. var getOriginalEventTarget = function (event) {
  434. if (isSupported() && isNonNullable(event.target)) {
  435. var el = SugarElement.fromDom(event.target);
  436. if (isElement(el) && isOpenShadowHost(el)) {
  437. if (event.composed && event.composedPath) {
  438. var composedPath = event.composedPath();
  439. if (composedPath) {
  440. return head(composedPath);
  441. }
  442. }
  443. }
  444. }
  445. return Optional.from(event.target);
  446. };
  447. var isOpenShadowHost = function (element) {
  448. return isNonNullable(element.dom.shadowRoot);
  449. };
  450. var inBody = function (element) {
  451. var dom = isText(element) ? element.dom.parentNode : element.dom;
  452. if (dom === undefined || dom === null || dom.ownerDocument === null) {
  453. return false;
  454. }
  455. var doc = dom.ownerDocument;
  456. return getShadowRoot(SugarElement.fromDom(dom)).fold(function () {
  457. return doc.body.contains(dom);
  458. }, compose1(inBody, getShadowHost));
  459. };
  460. var getBody = function (doc) {
  461. var b = doc.dom.body;
  462. if (b === null || b === undefined) {
  463. throw new Error('Body is not available yet');
  464. }
  465. return SugarElement.fromDom(b);
  466. };
  467. var rawSet = function (dom, key, value) {
  468. if (isString(value) || isBoolean(value) || isNumber(value)) {
  469. dom.setAttribute(key, value + '');
  470. } else {
  471. console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
  472. throw new Error('Attribute value was not simple');
  473. }
  474. };
  475. var set = function (element, key, value) {
  476. rawSet(element.dom, key, value);
  477. };
  478. var get$3 = function (element, key) {
  479. var v = element.dom.getAttribute(key);
  480. return v === null ? undefined : v;
  481. };
  482. var remove = function (element, key) {
  483. element.dom.removeAttribute(key);
  484. };
  485. var internalSet = function (dom, property, value) {
  486. if (!isString(value)) {
  487. console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
  488. throw new Error('CSS value must be a string: ' + value);
  489. }
  490. if (isSupported$1(dom)) {
  491. dom.style.setProperty(property, value);
  492. }
  493. };
  494. var setAll = function (element, css) {
  495. var dom = element.dom;
  496. each(css, function (v, k) {
  497. internalSet(dom, k, v);
  498. });
  499. };
  500. var get$2 = function (element, property) {
  501. var dom = element.dom;
  502. var styles = window.getComputedStyle(dom);
  503. var r = styles.getPropertyValue(property);
  504. return r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;
  505. };
  506. var getUnsafeProperty = function (dom, property) {
  507. return isSupported$1(dom) ? dom.style.getPropertyValue(property) : '';
  508. };
  509. var mkEvent = function (target, x, y, stop, prevent, kill, raw) {
  510. return {
  511. target: target,
  512. x: x,
  513. y: y,
  514. stop: stop,
  515. prevent: prevent,
  516. kill: kill,
  517. raw: raw
  518. };
  519. };
  520. var fromRawEvent = function (rawEvent) {
  521. var target = SugarElement.fromDom(getOriginalEventTarget(rawEvent).getOr(rawEvent.target));
  522. var stop = function () {
  523. return rawEvent.stopPropagation();
  524. };
  525. var prevent = function () {
  526. return rawEvent.preventDefault();
  527. };
  528. var kill = compose(prevent, stop);
  529. return mkEvent(target, rawEvent.clientX, rawEvent.clientY, stop, prevent, kill, rawEvent);
  530. };
  531. var handle = function (filter, handler) {
  532. return function (rawEvent) {
  533. if (filter(rawEvent)) {
  534. handler(fromRawEvent(rawEvent));
  535. }
  536. };
  537. };
  538. var binder = function (element, event, filter, handler, useCapture) {
  539. var wrapped = handle(filter, handler);
  540. element.dom.addEventListener(event, wrapped, useCapture);
  541. return { unbind: curry(unbind, element, event, wrapped, useCapture) };
  542. };
  543. var bind$2 = function (element, event, filter, handler) {
  544. return binder(element, event, filter, handler, false);
  545. };
  546. var unbind = function (element, event, handler, useCapture) {
  547. element.dom.removeEventListener(event, handler, useCapture);
  548. };
  549. var filter = always;
  550. var bind$1 = function (element, event, handler) {
  551. return bind$2(element, event, filter, handler);
  552. };
  553. var r = function (left, top) {
  554. var translate = function (x, y) {
  555. return r(left + x, top + y);
  556. };
  557. return {
  558. left: left,
  559. top: top,
  560. translate: translate
  561. };
  562. };
  563. var SugarPosition = r;
  564. var get$1 = function (_DOC) {
  565. var doc = _DOC !== undefined ? _DOC.dom : document;
  566. var x = doc.body.scrollLeft || doc.documentElement.scrollLeft;
  567. var y = doc.body.scrollTop || doc.documentElement.scrollTop;
  568. return SugarPosition(x, y);
  569. };
  570. var get = function (_win) {
  571. var win = _win === undefined ? window : _win;
  572. return Optional.from(win['visualViewport']);
  573. };
  574. var bounds = function (x, y, width, height) {
  575. return {
  576. x: x,
  577. y: y,
  578. width: width,
  579. height: height,
  580. right: x + width,
  581. bottom: y + height
  582. };
  583. };
  584. var getBounds = function (_win) {
  585. var win = _win === undefined ? window : _win;
  586. var doc = win.document;
  587. var scroll = get$1(SugarElement.fromDom(doc));
  588. return get(win).fold(function () {
  589. var html = win.document.documentElement;
  590. var width = html.clientWidth;
  591. var height = html.clientHeight;
  592. return bounds(scroll.left, scroll.top, width, height);
  593. }, function (visualViewport) {
  594. return bounds(Math.max(visualViewport.pageLeft, scroll.left), Math.max(visualViewport.pageTop, scroll.top), visualViewport.width, visualViewport.height);
  595. });
  596. };
  597. var bind = function (name, callback, _win) {
  598. return get(_win).map(function (visualViewport) {
  599. var handler = function (e) {
  600. return callback(fromRawEvent(e));
  601. };
  602. visualViewport.addEventListener(name, handler);
  603. return {
  604. unbind: function () {
  605. return visualViewport.removeEventListener(name, handler);
  606. }
  607. };
  608. }).getOrThunk(function () {
  609. return { unbind: noop };
  610. });
  611. };
  612. var global$2 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
  613. var global$1 = tinymce.util.Tools.resolve('tinymce.Env');
  614. var global = tinymce.util.Tools.resolve('tinymce.util.Delay');
  615. var fireFullscreenStateChanged = function (editor, state) {
  616. editor.fire('FullscreenStateChanged', { state: state });
  617. };
  618. var getFullscreenNative = function (editor) {
  619. return editor.getParam('fullscreen_native', false, 'boolean');
  620. };
  621. var getFullscreenRoot = function (editor) {
  622. var elem = SugarElement.fromDom(editor.getElement());
  623. return getShadowRoot(elem).map(getShadowHost).getOrThunk(function () {
  624. return getBody(owner(elem));
  625. });
  626. };
  627. var getFullscreenElement = function (root) {
  628. if (root.fullscreenElement !== undefined) {
  629. return root.fullscreenElement;
  630. } else if (root.msFullscreenElement !== undefined) {
  631. return root.msFullscreenElement;
  632. } else if (root.webkitFullscreenElement !== undefined) {
  633. return root.webkitFullscreenElement;
  634. } else {
  635. return null;
  636. }
  637. };
  638. var getFullscreenchangeEventName = function () {
  639. if (document.fullscreenElement !== undefined) {
  640. return 'fullscreenchange';
  641. } else if (document.msFullscreenElement !== undefined) {
  642. return 'MSFullscreenChange';
  643. } else if (document.webkitFullscreenElement !== undefined) {
  644. return 'webkitfullscreenchange';
  645. } else {
  646. return 'fullscreenchange';
  647. }
  648. };
  649. var requestFullscreen = function (sugarElem) {
  650. var elem = sugarElem.dom;
  651. if (elem.requestFullscreen) {
  652. elem.requestFullscreen();
  653. } else if (elem.msRequestFullscreen) {
  654. elem.msRequestFullscreen();
  655. } else if (elem.webkitRequestFullScreen) {
  656. elem.webkitRequestFullScreen();
  657. }
  658. };
  659. var exitFullscreen = function (sugarDoc) {
  660. var doc = sugarDoc.dom;
  661. if (doc.exitFullscreen) {
  662. doc.exitFullscreen();
  663. } else if (doc.msExitFullscreen) {
  664. doc.msExitFullscreen();
  665. } else if (doc.webkitCancelFullScreen) {
  666. doc.webkitCancelFullScreen();
  667. }
  668. };
  669. var isFullscreenElement = function (elem) {
  670. return elem.dom === getFullscreenElement(owner(elem).dom);
  671. };
  672. var ancestors$1 = function (scope, predicate, isRoot) {
  673. return filter$1(parents(scope, isRoot), predicate);
  674. };
  675. var siblings$1 = function (scope, predicate) {
  676. return filter$1(siblings$2(scope), predicate);
  677. };
  678. var all = function (selector) {
  679. return all$1(selector);
  680. };
  681. var ancestors = function (scope, selector, isRoot) {
  682. return ancestors$1(scope, function (e) {
  683. return is(e, selector);
  684. }, isRoot);
  685. };
  686. var siblings = function (scope, selector) {
  687. return siblings$1(scope, function (e) {
  688. return is(e, selector);
  689. });
  690. };
  691. var attr = 'data-ephox-mobile-fullscreen-style';
  692. var siblingStyles = 'display:none!important;';
  693. var ancestorPosition = 'position:absolute!important;';
  694. var ancestorStyles = 'top:0!important;left:0!important;margin:0!important;padding:0!important;width:100%!important;height:100%!important;overflow:visible!important;';
  695. var bgFallback = 'background-color:rgb(255,255,255)!important;';
  696. var isAndroid = global$1.os.isAndroid();
  697. var matchColor = function (editorBody) {
  698. var color = get$2(editorBody, 'background-color');
  699. return color !== undefined && color !== '' ? 'background-color:' + color + '!important' : bgFallback;
  700. };
  701. var clobberStyles = function (dom, container, editorBody) {
  702. var gatherSiblings = function (element) {
  703. return siblings(element, '*:not(.tox-silver-sink)');
  704. };
  705. var clobber = function (clobberStyle) {
  706. return function (element) {
  707. var styles = get$3(element, 'style');
  708. var backup = styles === undefined ? 'no-styles' : styles.trim();
  709. if (backup === clobberStyle) {
  710. return;
  711. } else {
  712. set(element, attr, backup);
  713. setAll(element, dom.parseStyle(clobberStyle));
  714. }
  715. };
  716. };
  717. var ancestors$1 = ancestors(container, '*');
  718. var siblings$1 = bind$3(ancestors$1, gatherSiblings);
  719. var bgColor = matchColor(editorBody);
  720. each$1(siblings$1, clobber(siblingStyles));
  721. each$1(ancestors$1, clobber(ancestorPosition + ancestorStyles + bgColor));
  722. var containerStyles = isAndroid === true ? '' : ancestorPosition;
  723. clobber(containerStyles + ancestorStyles + bgColor)(container);
  724. };
  725. var restoreStyles = function (dom) {
  726. var clobberedEls = all('[' + attr + ']');
  727. each$1(clobberedEls, function (element) {
  728. var restore = get$3(element, attr);
  729. if (restore !== 'no-styles') {
  730. setAll(element, dom.parseStyle(restore));
  731. } else {
  732. remove(element, 'style');
  733. }
  734. remove(element, attr);
  735. });
  736. };
  737. var DOM = global$2.DOM;
  738. var getScrollPos = function () {
  739. return getBounds(window);
  740. };
  741. var setScrollPos = function (pos) {
  742. return window.scrollTo(pos.x, pos.y);
  743. };
  744. var viewportUpdate = get().fold(function () {
  745. return {
  746. bind: noop,
  747. unbind: noop
  748. };
  749. }, function (visualViewport) {
  750. var editorContainer = value();
  751. var resizeBinder = unbindable();
  752. var scrollBinder = unbindable();
  753. var refreshScroll = function () {
  754. document.body.scrollTop = 0;
  755. document.documentElement.scrollTop = 0;
  756. };
  757. var refreshVisualViewport = function () {
  758. window.requestAnimationFrame(function () {
  759. editorContainer.on(function (container) {
  760. return setAll(container, {
  761. top: visualViewport.offsetTop + 'px',
  762. left: visualViewport.offsetLeft + 'px',
  763. height: visualViewport.height + 'px',
  764. width: visualViewport.width + 'px'
  765. });
  766. });
  767. });
  768. };
  769. var update = global.throttle(function () {
  770. refreshScroll();
  771. refreshVisualViewport();
  772. }, 50);
  773. var bind$1 = function (element) {
  774. editorContainer.set(element);
  775. update();
  776. resizeBinder.set(bind('resize', update));
  777. scrollBinder.set(bind('scroll', update));
  778. };
  779. var unbind = function () {
  780. editorContainer.on(function () {
  781. resizeBinder.clear();
  782. scrollBinder.clear();
  783. });
  784. editorContainer.clear();
  785. };
  786. return {
  787. bind: bind$1,
  788. unbind: unbind
  789. };
  790. });
  791. var toggleFullscreen = function (editor, fullscreenState) {
  792. var body = document.body;
  793. var documentElement = document.documentElement;
  794. var editorContainer = editor.getContainer();
  795. var editorContainerS = SugarElement.fromDom(editorContainer);
  796. var fullscreenRoot = getFullscreenRoot(editor);
  797. var fullscreenInfo = fullscreenState.get();
  798. var editorBody = SugarElement.fromDom(editor.getBody());
  799. var isTouch = global$1.deviceType.isTouch();
  800. var editorContainerStyle = editorContainer.style;
  801. var iframe = editor.iframeElement;
  802. var iframeStyle = iframe.style;
  803. var handleClasses = function (handler) {
  804. handler(body, 'tox-fullscreen');
  805. handler(documentElement, 'tox-fullscreen');
  806. handler(editorContainer, 'tox-fullscreen');
  807. getShadowRoot(editorContainerS).map(function (root) {
  808. return getShadowHost(root).dom;
  809. }).each(function (host) {
  810. handler(host, 'tox-fullscreen');
  811. handler(host, 'tox-shadowhost');
  812. });
  813. };
  814. var cleanup = function () {
  815. if (isTouch) {
  816. restoreStyles(editor.dom);
  817. }
  818. handleClasses(DOM.removeClass);
  819. viewportUpdate.unbind();
  820. Optional.from(fullscreenState.get()).each(function (info) {
  821. return info.fullscreenChangeHandler.unbind();
  822. });
  823. };
  824. if (!fullscreenInfo) {
  825. var fullscreenChangeHandler = bind$1(owner(fullscreenRoot), getFullscreenchangeEventName(), function (_evt) {
  826. if (getFullscreenNative(editor)) {
  827. if (!isFullscreenElement(fullscreenRoot) && fullscreenState.get() !== null) {
  828. toggleFullscreen(editor, fullscreenState);
  829. }
  830. }
  831. });
  832. var newFullScreenInfo = {
  833. scrollPos: getScrollPos(),
  834. containerWidth: editorContainerStyle.width,
  835. containerHeight: editorContainerStyle.height,
  836. containerTop: editorContainerStyle.top,
  837. containerLeft: editorContainerStyle.left,
  838. iframeWidth: iframeStyle.width,
  839. iframeHeight: iframeStyle.height,
  840. fullscreenChangeHandler: fullscreenChangeHandler
  841. };
  842. if (isTouch) {
  843. clobberStyles(editor.dom, editorContainerS, editorBody);
  844. }
  845. iframeStyle.width = iframeStyle.height = '100%';
  846. editorContainerStyle.width = editorContainerStyle.height = '';
  847. handleClasses(DOM.addClass);
  848. viewportUpdate.bind(editorContainerS);
  849. editor.on('remove', cleanup);
  850. fullscreenState.set(newFullScreenInfo);
  851. if (getFullscreenNative(editor)) {
  852. requestFullscreen(fullscreenRoot);
  853. }
  854. fireFullscreenStateChanged(editor, true);
  855. } else {
  856. fullscreenInfo.fullscreenChangeHandler.unbind();
  857. if (getFullscreenNative(editor) && isFullscreenElement(fullscreenRoot)) {
  858. exitFullscreen(owner(fullscreenRoot));
  859. }
  860. iframeStyle.width = fullscreenInfo.iframeWidth;
  861. iframeStyle.height = fullscreenInfo.iframeHeight;
  862. editorContainerStyle.width = fullscreenInfo.containerWidth;
  863. editorContainerStyle.height = fullscreenInfo.containerHeight;
  864. editorContainerStyle.top = fullscreenInfo.containerTop;
  865. editorContainerStyle.left = fullscreenInfo.containerLeft;
  866. setScrollPos(fullscreenInfo.scrollPos);
  867. fullscreenState.set(null);
  868. fireFullscreenStateChanged(editor, false);
  869. cleanup();
  870. editor.off('remove', cleanup);
  871. }
  872. };
  873. var register$1 = function (editor, fullscreenState) {
  874. editor.addCommand('mceFullScreen', function () {
  875. toggleFullscreen(editor, fullscreenState);
  876. });
  877. };
  878. var makeSetupHandler = function (editor, fullscreenState) {
  879. return function (api) {
  880. api.setActive(fullscreenState.get() !== null);
  881. var editorEventCallback = function (e) {
  882. return api.setActive(e.state);
  883. };
  884. editor.on('FullscreenStateChanged', editorEventCallback);
  885. return function () {
  886. return editor.off('FullscreenStateChanged', editorEventCallback);
  887. };
  888. };
  889. };
  890. var register = function (editor, fullscreenState) {
  891. var onAction = function () {
  892. return editor.execCommand('mceFullScreen');
  893. };
  894. editor.ui.registry.addToggleMenuItem('fullscreen', {
  895. text: 'Fullscreen',
  896. icon: 'fullscreen',
  897. shortcut: 'Meta+Shift+F',
  898. onAction: onAction,
  899. onSetup: makeSetupHandler(editor, fullscreenState)
  900. });
  901. editor.ui.registry.addToggleButton('fullscreen', {
  902. tooltip: 'Fullscreen',
  903. icon: 'fullscreen',
  904. onAction: onAction,
  905. onSetup: makeSetupHandler(editor, fullscreenState)
  906. });
  907. };
  908. function Plugin () {
  909. global$3.add('fullscreen', function (editor) {
  910. var fullscreenState = Cell(null);
  911. if (editor.inline) {
  912. return get$5(fullscreenState);
  913. }
  914. register$1(editor, fullscreenState);
  915. register(editor, fullscreenState);
  916. editor.addShortcut('Meta+Shift+F', '', 'mceFullScreen');
  917. return get$5(fullscreenState);
  918. });
  919. }
  920. Plugin();
  921. }());