tinymce-rails 7.5.1 → 7.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/source/tinymce/tinymce.js +1803 -1597
  3. data/lib/tinymce/rails/version.rb +2 -2
  4. data/vendor/assets/javascripts/tinymce/icons/default/icons.js +1 -1
  5. data/vendor/assets/javascripts/tinymce/models/dom/model.js +2 -2
  6. data/vendor/assets/javascripts/tinymce/plugins/accordion/plugin.js +1 -1
  7. data/vendor/assets/javascripts/tinymce/plugins/advlist/plugin.js +2 -2
  8. data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.js +1 -1
  9. data/vendor/assets/javascripts/tinymce/plugins/autolink/plugin.js +1 -1
  10. data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.js +1 -1
  11. data/vendor/assets/javascripts/tinymce/plugins/autosave/plugin.js +1 -1
  12. data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.js +1 -1
  13. data/vendor/assets/javascripts/tinymce/plugins/code/plugin.js +1 -1
  14. data/vendor/assets/javascripts/tinymce/plugins/codesample/plugin.js +1 -1
  15. data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.js +1 -1
  16. data/vendor/assets/javascripts/tinymce/plugins/emoticons/plugin.js +1 -1
  17. data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.js +1 -1
  18. data/vendor/assets/javascripts/tinymce/plugins/help/plugin.js +2 -2
  19. data/vendor/assets/javascripts/tinymce/plugins/image/plugin.js +1 -1
  20. data/vendor/assets/javascripts/tinymce/plugins/importcss/plugin.js +1 -1
  21. data/vendor/assets/javascripts/tinymce/plugins/insertdatetime/plugin.js +1 -1
  22. data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +1 -1
  23. data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +1 -1
  24. data/vendor/assets/javascripts/tinymce/plugins/media/plugin.js +1 -1
  25. data/vendor/assets/javascripts/tinymce/plugins/nonbreaking/plugin.js +1 -1
  26. data/vendor/assets/javascripts/tinymce/plugins/pagebreak/plugin.js +1 -1
  27. data/vendor/assets/javascripts/tinymce/plugins/preview/plugin.js +1 -1
  28. data/vendor/assets/javascripts/tinymce/plugins/quickbars/plugin.js +2 -2
  29. data/vendor/assets/javascripts/tinymce/plugins/save/plugin.js +1 -1
  30. data/vendor/assets/javascripts/tinymce/plugins/searchreplace/plugin.js +1 -1
  31. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +1 -1
  32. data/vendor/assets/javascripts/tinymce/plugins/visualblocks/plugin.js +1 -1
  33. data/vendor/assets/javascripts/tinymce/plugins/visualchars/plugin.js +1 -1
  34. data/vendor/assets/javascripts/tinymce/plugins/wordcount/plugin.js +1 -1
  35. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.css +1 -1
  36. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.css +1 -1
  37. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.js +1 -1
  38. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.min.css +1 -1
  39. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.js +1 -1
  40. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.min.css +1 -1
  41. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.css +1 -1
  42. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.js +1 -1
  43. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.min.css +1 -1
  44. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.shadowdom.js +1 -1
  45. data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.css +1 -1
  46. data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.css +1 -1
  47. data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.js +1 -1
  48. data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.min.css +1 -1
  49. data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.js +1 -1
  50. data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.min.css +1 -1
  51. data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.css +1 -1
  52. data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.js +1 -1
  53. data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.min.css +1 -1
  54. data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.shadowdom.js +1 -1
  55. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.css +1 -1
  56. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.css +1 -1
  57. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.js +1 -1
  58. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.min.css +1 -1
  59. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.js +1 -1
  60. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.min.css +1 -1
  61. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.css +1 -1
  62. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.js +1 -1
  63. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.min.css +1 -1
  64. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.css +1 -1
  65. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.css +1 -1
  66. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.js +1 -1
  67. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.min.css +1 -1
  68. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.js +1 -1
  69. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.min.css +1 -1
  70. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.css +1 -1
  71. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.js +1 -1
  72. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.min.css +1 -1
  73. data/vendor/assets/javascripts/tinymce/themes/silver/theme.js +68 -68
  74. data/vendor/assets/javascripts/tinymce/tinymce.d.ts +51 -15
  75. data/vendor/assets/javascripts/tinymce/tinymce.js +57 -57
  76. metadata +5 -5
@@ -1,5 +1,5 @@
1
1
  /**
2
- * TinyMCE version 7.5.1 (TBD)
2
+ * TinyMCE version 7.6.0 (2024-12-11)
3
3
  */
4
4
 
5
5
  (function () {
@@ -1178,7 +1178,7 @@
1178
1178
  throw new Error('Attribute value was not simple');
1179
1179
  }
1180
1180
  };
1181
- const set$3 = (element, key, value) => {
1181
+ const set$4 = (element, key, value) => {
1182
1182
  rawSet(element.dom, key, value);
1183
1183
  };
1184
1184
  const setAll$1 = (element, attrs) => {
@@ -1215,13 +1215,13 @@
1215
1215
  const add$4 = (element, attr, id) => {
1216
1216
  const old = read$4(element, attr);
1217
1217
  const nu = old.concat([id]);
1218
- set$3(element, attr, nu.join(' '));
1218
+ set$4(element, attr, nu.join(' '));
1219
1219
  return true;
1220
1220
  };
1221
1221
  const remove$8 = (element, attr, id) => {
1222
1222
  const nu = filter$5(read$4(element, attr), v => v !== id);
1223
1223
  if (nu.length > 0) {
1224
- set$3(element, attr, nu.join(' '));
1224
+ set$4(element, attr, nu.join(' '));
1225
1225
  } else {
1226
1226
  remove$9(element, attr);
1227
1227
  }
@@ -1508,6 +1508,9 @@
1508
1508
  }
1509
1509
  };
1510
1510
  const getRaw$1 = element => element.dom.contentEditable;
1511
+ const set$3 = (element, editable) => {
1512
+ element.dom.contentEditable = editable ? 'true' : 'false';
1513
+ };
1511
1514
 
1512
1515
  const isSupported = dom => dom.style !== undefined && isFunction(dom.style.getPropertyValue);
1513
1516
 
@@ -2426,16 +2429,16 @@
2426
2429
  id: state.id
2427
2430
  });
2428
2431
  if (settings.contentCssCors) {
2429
- set$3(linkElem, 'crossOrigin', 'anonymous');
2432
+ set$4(linkElem, 'crossOrigin', 'anonymous');
2430
2433
  }
2431
2434
  if (settings.referrerPolicy) {
2432
- set$3(linkElem, 'referrerpolicy', settings.referrerPolicy);
2435
+ set$4(linkElem, 'referrerpolicy', settings.referrerPolicy);
2433
2436
  }
2434
2437
  link = linkElem.dom;
2435
2438
  link.onload = passed;
2436
2439
  link.onerror = failed;
2437
2440
  addStyle(linkElem);
2438
- set$3(linkElem, 'href', urlWithSuffix);
2441
+ set$4(linkElem, 'href', urlWithSuffix);
2439
2442
  });
2440
2443
  const loadRawCss = (key, css) => {
2441
2444
  const state = getOrCreateState(key);
@@ -2443,9 +2446,10 @@
2443
2446
  state.count++;
2444
2447
  const styleElem = SugarElement.fromTag('style', doc.dom);
2445
2448
  setAll$1(styleElem, {
2446
- rel: 'stylesheet',
2447
- type: 'text/css',
2448
- id: state.id
2449
+ 'rel': 'stylesheet',
2450
+ 'type': 'text/css',
2451
+ 'id': state.id,
2452
+ 'data-mce-key': key
2449
2453
  });
2450
2454
  styleElem.dom.innerHTML = css;
2451
2455
  addStyle(styleElem);
@@ -4148,7 +4152,7 @@
4148
4152
  if (isNullable(value) || value === '') {
4149
4153
  remove$9(elm, name);
4150
4154
  } else {
4151
- set$3(elm, name, value);
4155
+ set$4(elm, name, value);
4152
4156
  }
4153
4157
  };
4154
4158
  const camelCaseToHyphens = name => name.replace(/[A-Z]/g, v => '-' + v.toLowerCase());
@@ -5356,7 +5360,7 @@
5356
5360
  const toggleActiveAttr = (uid, state) => {
5357
5361
  each$e(findMarkers(editor, uid), elem => {
5358
5362
  if (state) {
5359
- set$3(elem, dataAnnotationActive(), 'true');
5363
+ set$4(elem, dataAnnotationActive(), 'true');
5360
5364
  } else {
5361
5365
  remove$9(elem, dataAnnotationActive());
5362
5366
  }
@@ -5655,7 +5659,7 @@
5655
5659
  };
5656
5660
  const createPaddingBr = () => {
5657
5661
  const br = SugarElement.fromTag('br');
5658
- set$3(br, 'data-mce-bogus', '1');
5662
+ set$4(br, 'data-mce-bogus', '1');
5659
5663
  return br;
5660
5664
  };
5661
5665
  const fillWithPaddingBr = elm => {
@@ -6826,6 +6830,90 @@
6826
6830
  };
6827
6831
  };
6828
6832
 
6833
+ const firePreProcess = (editor, args) => editor.dispatch('PreProcess', args);
6834
+ const firePostProcess = (editor, args) => editor.dispatch('PostProcess', args);
6835
+ const fireRemove = editor => {
6836
+ editor.dispatch('remove');
6837
+ };
6838
+ const fireDetach = editor => {
6839
+ editor.dispatch('detach');
6840
+ };
6841
+ const fireSwitchMode = (editor, mode) => {
6842
+ editor.dispatch('SwitchMode', { mode });
6843
+ };
6844
+ const fireObjectResizeStart = (editor, target, width, height, origin) => {
6845
+ editor.dispatch('ObjectResizeStart', {
6846
+ target,
6847
+ width,
6848
+ height,
6849
+ origin
6850
+ });
6851
+ };
6852
+ const fireObjectResized = (editor, target, width, height, origin) => {
6853
+ editor.dispatch('ObjectResized', {
6854
+ target,
6855
+ width,
6856
+ height,
6857
+ origin
6858
+ });
6859
+ };
6860
+ const firePreInit = editor => {
6861
+ editor.dispatch('PreInit');
6862
+ };
6863
+ const firePostRender = editor => {
6864
+ editor.dispatch('PostRender');
6865
+ };
6866
+ const fireInit = editor => {
6867
+ editor.dispatch('Init');
6868
+ };
6869
+ const firePlaceholderToggle = (editor, state) => {
6870
+ editor.dispatch('PlaceholderToggle', { state });
6871
+ };
6872
+ const fireError = (editor, errorType, error) => {
6873
+ editor.dispatch(errorType, error);
6874
+ };
6875
+ const fireFormatApply = (editor, format, node, vars) => {
6876
+ editor.dispatch('FormatApply', {
6877
+ format,
6878
+ node,
6879
+ vars
6880
+ });
6881
+ };
6882
+ const fireFormatRemove = (editor, format, node, vars) => {
6883
+ editor.dispatch('FormatRemove', {
6884
+ format,
6885
+ node,
6886
+ vars
6887
+ });
6888
+ };
6889
+ const fireBeforeSetContent = (editor, args) => editor.dispatch('BeforeSetContent', args);
6890
+ const fireSetContent = (editor, args) => editor.dispatch('SetContent', args);
6891
+ const fireBeforeGetContent = (editor, args) => editor.dispatch('BeforeGetContent', args);
6892
+ const fireGetContent = (editor, args) => editor.dispatch('GetContent', args);
6893
+ const fireAutocompleterStart = (editor, args) => {
6894
+ editor.dispatch('AutocompleterStart', args);
6895
+ };
6896
+ const fireAutocompleterUpdate = (editor, args) => {
6897
+ editor.dispatch('AutocompleterUpdate', args);
6898
+ };
6899
+ const fireAutocompleterUpdateActiveRange = (editor, args) => {
6900
+ editor.dispatch('AutocompleterUpdateActiveRange', args);
6901
+ };
6902
+ const fireAutocompleterEnd = editor => {
6903
+ editor.dispatch('AutocompleterEnd');
6904
+ };
6905
+ const firePastePreProcess = (editor, html, internal) => editor.dispatch('PastePreProcess', {
6906
+ content: html,
6907
+ internal
6908
+ });
6909
+ const firePastePostProcess = (editor, node, internal) => editor.dispatch('PastePostProcess', {
6910
+ node,
6911
+ internal
6912
+ });
6913
+ const firePastePlainTextToggle = (editor, state) => editor.dispatch('PastePlainTextToggle', { state });
6914
+ const fireEditableRootStateChange = (editor, state) => editor.dispatch('EditableRootStateChange', { state });
6915
+ const fireDisabledStateChange = (editor, state) => editor.dispatch('DisabledStateChange', { state });
6916
+
6829
6917
  const deviceDetection$1 = detect$1().deviceType;
6830
6918
  const isTouch = deviceDetection$1.isTouch();
6831
6919
  const DOM$a = DOMUtils.DOM;
@@ -7219,6 +7307,26 @@
7219
7307
  processor: 'boolean',
7220
7308
  default: false
7221
7309
  });
7310
+ registerOption('disabled', {
7311
+ processor: value => {
7312
+ if (isBoolean(value)) {
7313
+ if (editor.initialized && isDisabled$1(editor) !== value) {
7314
+ Promise.resolve().then(() => {
7315
+ fireDisabledStateChange(editor, value);
7316
+ });
7317
+ }
7318
+ return {
7319
+ valid: true,
7320
+ value
7321
+ };
7322
+ }
7323
+ return {
7324
+ valid: false,
7325
+ message: 'The value must be a boolean.'
7326
+ };
7327
+ },
7328
+ default: false
7329
+ });
7222
7330
  registerOption('readonly', {
7223
7331
  processor: 'boolean',
7224
7332
  default: false
@@ -7738,6 +7846,7 @@
7738
7846
  const shouldConvertUnsafeEmbeds = option('convert_unsafe_embeds');
7739
7847
  const getLicenseKey = option('license_key');
7740
7848
  const getApiKey = option('api_key');
7849
+ const isDisabled$1 = option('disabled');
7741
7850
 
7742
7851
  const isElement$3 = isElement$6;
7743
7852
  const isText$5 = isText$b;
@@ -9303,18 +9412,18 @@
9303
9412
  const applyAnnotation = (elem, masterUId, data, annotationName, decorate, directAnnotation) => {
9304
9413
  const {uid = masterUId, ...otherData} = data;
9305
9414
  add$2(elem, annotation());
9306
- set$3(elem, `${ dataAnnotationId() }`, uid);
9307
- set$3(elem, `${ dataAnnotation() }`, annotationName);
9415
+ set$4(elem, `${ dataAnnotationId() }`, uid);
9416
+ set$4(elem, `${ dataAnnotation() }`, annotationName);
9308
9417
  const {attributes = {}, classes = []} = decorate(uid, otherData);
9309
9418
  setAll$1(elem, attributes);
9310
9419
  add(elem, classes);
9311
9420
  if (directAnnotation) {
9312
9421
  if (classes.length > 0) {
9313
- set$3(elem, `${ dataAnnotationClasses() }`, classes.join(','));
9422
+ set$4(elem, `${ dataAnnotationClasses() }`, classes.join(','));
9314
9423
  }
9315
9424
  const attributeNames = keys(attributes);
9316
9425
  if (attributeNames.length > 0) {
9317
- set$3(elem, `${ dataAnnotationAttributes() }`, attributeNames.join(','));
9426
+ set$4(elem, `${ dataAnnotationAttributes() }`, attributeNames.join(','));
9318
9427
  }
9319
9428
  }
9320
9429
  };
@@ -9470,1563 +9579,1480 @@
9470
9579
  }
9471
9580
  };
9472
9581
 
9473
- const firePreProcess = (editor, args) => editor.dispatch('PreProcess', args);
9474
- const firePostProcess = (editor, args) => editor.dispatch('PostProcess', args);
9475
- const fireRemove = editor => {
9476
- editor.dispatch('remove');
9477
- };
9478
- const fireDetach = editor => {
9479
- editor.dispatch('detach');
9582
+ const getDocument = () => SugarElement.fromDom(document);
9583
+
9584
+ const focus$1 = (element, preventScroll = false) => element.dom.focus({ preventScroll });
9585
+ const hasFocus$1 = element => {
9586
+ const root = getRootNode(element).dom;
9587
+ return element.dom === root.activeElement;
9480
9588
  };
9481
- const fireSwitchMode = (editor, mode) => {
9482
- editor.dispatch('SwitchMode', { mode });
9589
+ const active$1 = (root = getDocument()) => Optional.from(root.dom.activeElement).map(SugarElement.fromDom);
9590
+ const search = element => active$1(getRootNode(element)).filter(e => element.dom.contains(e.dom));
9591
+
9592
+ const create$9 = (start, soffset, finish, foffset) => ({
9593
+ start,
9594
+ soffset,
9595
+ finish,
9596
+ foffset
9597
+ });
9598
+ const SimRange = { create: create$9 };
9599
+
9600
+ const adt$3 = Adt.generate([
9601
+ { before: ['element'] },
9602
+ {
9603
+ on: [
9604
+ 'element',
9605
+ 'offset'
9606
+ ]
9607
+ },
9608
+ { after: ['element'] }
9609
+ ]);
9610
+ const cata = (subject, onBefore, onOn, onAfter) => subject.fold(onBefore, onOn, onAfter);
9611
+ const getStart$2 = situ => situ.fold(identity, identity, identity);
9612
+ const before$1 = adt$3.before;
9613
+ const on = adt$3.on;
9614
+ const after$1 = adt$3.after;
9615
+ const Situ = {
9616
+ before: before$1,
9617
+ on,
9618
+ after: after$1,
9619
+ cata,
9620
+ getStart: getStart$2
9483
9621
  };
9484
- const fireObjectResizeStart = (editor, target, width, height, origin) => {
9485
- editor.dispatch('ObjectResizeStart', {
9486
- target,
9487
- width,
9488
- height,
9489
- origin
9490
- });
9622
+
9623
+ const adt$2 = Adt.generate([
9624
+ { domRange: ['rng'] },
9625
+ {
9626
+ relative: [
9627
+ 'startSitu',
9628
+ 'finishSitu'
9629
+ ]
9630
+ },
9631
+ {
9632
+ exact: [
9633
+ 'start',
9634
+ 'soffset',
9635
+ 'finish',
9636
+ 'foffset'
9637
+ ]
9638
+ }
9639
+ ]);
9640
+ const exactFromRange = simRange => adt$2.exact(simRange.start, simRange.soffset, simRange.finish, simRange.foffset);
9641
+ const getStart$1 = selection => selection.match({
9642
+ domRange: rng => SugarElement.fromDom(rng.startContainer),
9643
+ relative: (startSitu, _finishSitu) => Situ.getStart(startSitu),
9644
+ exact: (start, _soffset, _finish, _foffset) => start
9645
+ });
9646
+ const domRange = adt$2.domRange;
9647
+ const relative = adt$2.relative;
9648
+ const exact = adt$2.exact;
9649
+ const getWin = selection => {
9650
+ const start = getStart$1(selection);
9651
+ return defaultView(start);
9491
9652
  };
9492
- const fireObjectResized = (editor, target, width, height, origin) => {
9493
- editor.dispatch('ObjectResized', {
9494
- target,
9495
- width,
9496
- height,
9497
- origin
9498
- });
9653
+ const range = SimRange.create;
9654
+ const SimSelection = {
9655
+ domRange,
9656
+ relative,
9657
+ exact,
9658
+ exactFromRange,
9659
+ getWin,
9660
+ range
9499
9661
  };
9500
- const firePreInit = editor => {
9501
- editor.dispatch('PreInit');
9662
+
9663
+ const clamp$1 = (offset, element) => {
9664
+ const max = isText$c(element) ? get$3(element).length : children$1(element).length + 1;
9665
+ if (offset > max) {
9666
+ return max;
9667
+ } else if (offset < 0) {
9668
+ return 0;
9669
+ }
9670
+ return offset;
9502
9671
  };
9503
- const firePostRender = editor => {
9504
- editor.dispatch('PostRender');
9672
+ const normalizeRng = rng => SimSelection.range(rng.start, clamp$1(rng.soffset, rng.start), rng.finish, clamp$1(rng.foffset, rng.finish));
9673
+ const isOrContains = (root, elm) => !isRestrictedNode(elm.dom) && (contains(root, elm) || eq(root, elm));
9674
+ const isRngInRoot = root => rng => isOrContains(root, rng.start) && isOrContains(root, rng.finish);
9675
+ const shouldStore = editor => editor.inline || Env.browser.isFirefox();
9676
+ const nativeRangeToSelectionRange = r => SimSelection.range(SugarElement.fromDom(r.startContainer), r.startOffset, SugarElement.fromDom(r.endContainer), r.endOffset);
9677
+ const readRange = win => {
9678
+ const selection = win.getSelection();
9679
+ const rng = !selection || selection.rangeCount === 0 ? Optional.none() : Optional.from(selection.getRangeAt(0));
9680
+ return rng.map(nativeRangeToSelectionRange);
9505
9681
  };
9506
- const fireInit = editor => {
9507
- editor.dispatch('Init');
9682
+ const getBookmark$1 = root => {
9683
+ const win = defaultView(root);
9684
+ return readRange(win.dom).filter(isRngInRoot(root));
9508
9685
  };
9509
- const firePlaceholderToggle = (editor, state) => {
9510
- editor.dispatch('PlaceholderToggle', { state });
9686
+ const validate = (root, bookmark) => Optional.from(bookmark).filter(isRngInRoot(root)).map(normalizeRng);
9687
+ const bookmarkToNativeRng = bookmark => {
9688
+ const rng = document.createRange();
9689
+ try {
9690
+ rng.setStart(bookmark.start.dom, bookmark.soffset);
9691
+ rng.setEnd(bookmark.finish.dom, bookmark.foffset);
9692
+ return Optional.some(rng);
9693
+ } catch (_) {
9694
+ return Optional.none();
9695
+ }
9511
9696
  };
9512
- const fireError = (editor, errorType, error) => {
9513
- editor.dispatch(errorType, error);
9697
+ const store = editor => {
9698
+ const newBookmark = shouldStore(editor) ? getBookmark$1(SugarElement.fromDom(editor.getBody())) : Optional.none();
9699
+ editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;
9514
9700
  };
9515
- const fireFormatApply = (editor, format, node, vars) => {
9516
- editor.dispatch('FormatApply', {
9517
- format,
9518
- node,
9519
- vars
9520
- });
9701
+ const getRng = editor => {
9702
+ const bookmark = editor.bookmark ? editor.bookmark : Optional.none();
9703
+ return bookmark.bind(x => validate(SugarElement.fromDom(editor.getBody()), x)).bind(bookmarkToNativeRng);
9521
9704
  };
9522
- const fireFormatRemove = (editor, format, node, vars) => {
9523
- editor.dispatch('FormatRemove', {
9524
- format,
9525
- node,
9526
- vars
9527
- });
9705
+ const restore = editor => {
9706
+ getRng(editor).each(rng => editor.selection.setRng(rng));
9528
9707
  };
9529
- const fireBeforeSetContent = (editor, args) => editor.dispatch('BeforeSetContent', args);
9530
- const fireSetContent = (editor, args) => editor.dispatch('SetContent', args);
9531
- const fireBeforeGetContent = (editor, args) => editor.dispatch('BeforeGetContent', args);
9532
- const fireGetContent = (editor, args) => editor.dispatch('GetContent', args);
9533
- const fireAutocompleterStart = (editor, args) => {
9534
- editor.dispatch('AutocompleterStart', args);
9535
- };
9536
- const fireAutocompleterUpdate = (editor, args) => {
9537
- editor.dispatch('AutocompleterUpdate', args);
9708
+
9709
+ const isEditorUIElement$1 = elm => {
9710
+ const className = elm.className.toString();
9711
+ return className.indexOf('tox-') !== -1 || className.indexOf('mce-') !== -1;
9538
9712
  };
9539
- const fireAutocompleterUpdateActiveRange = (editor, args) => {
9540
- editor.dispatch('AutocompleterUpdateActiveRange', args);
9713
+ const FocusManager = { isEditorUIElement: isEditorUIElement$1 };
9714
+
9715
+ const wrappedSetTimeout = (callback, time) => {
9716
+ if (!isNumber(time)) {
9717
+ time = 0;
9718
+ }
9719
+ return setTimeout(callback, time);
9541
9720
  };
9542
- const fireAutocompleterEnd = editor => {
9543
- editor.dispatch('AutocompleterEnd');
9721
+ const wrappedSetInterval = (callback, time) => {
9722
+ if (!isNumber(time)) {
9723
+ time = 0;
9724
+ }
9725
+ return setInterval(callback, time);
9544
9726
  };
9545
- const firePastePreProcess = (editor, html, internal) => editor.dispatch('PastePreProcess', {
9546
- content: html,
9547
- internal
9548
- });
9549
- const firePastePostProcess = (editor, node, internal) => editor.dispatch('PastePostProcess', {
9550
- node,
9551
- internal
9552
- });
9553
- const firePastePlainTextToggle = (editor, state) => editor.dispatch('PastePlainTextToggle', { state });
9554
- const fireEditableRootStateChange = (editor, state) => editor.dispatch('EditableRootStateChange', { state });
9555
-
9556
- const VK = {
9557
- BACKSPACE: 8,
9558
- DELETE: 46,
9559
- DOWN: 40,
9560
- ENTER: 13,
9561
- ESC: 27,
9562
- LEFT: 37,
9563
- RIGHT: 39,
9564
- SPACEBAR: 32,
9565
- TAB: 9,
9566
- UP: 38,
9567
- PAGE_UP: 33,
9568
- PAGE_DOWN: 34,
9569
- END: 35,
9570
- HOME: 36,
9571
- modifierPressed: e => {
9572
- return e.shiftKey || e.ctrlKey || e.altKey || VK.metaKeyPressed(e);
9727
+ const Delay = {
9728
+ setEditorTimeout: (editor, callback, time) => {
9729
+ return wrappedSetTimeout(() => {
9730
+ if (!editor.removed) {
9731
+ callback();
9732
+ }
9733
+ }, time);
9573
9734
  },
9574
- metaKeyPressed: e => {
9575
- return Env.os.isMacOS() || Env.os.isiOS() ? e.metaKey : e.ctrlKey && !e.altKey;
9735
+ setEditorInterval: (editor, callback, time) => {
9736
+ const timer = wrappedSetInterval(() => {
9737
+ if (!editor.removed) {
9738
+ callback();
9739
+ } else {
9740
+ clearInterval(timer);
9741
+ }
9742
+ }, time);
9743
+ return timer;
9576
9744
  }
9577
9745
  };
9578
9746
 
9579
- const elementSelectionAttr = 'data-mce-selected';
9580
- const controlElmSelector = 'table,img,figure.image,hr,video,span.mce-preview-object,details';
9581
- const abs = Math.abs;
9582
- const round$1 = Math.round;
9583
- const resizeHandles = {
9584
- nw: [
9585
- 0,
9586
- 0,
9587
- -1,
9588
- -1
9589
- ],
9590
- ne: [
9591
- 1,
9592
- 0,
9593
- 1,
9594
- -1
9595
- ],
9596
- se: [
9597
- 1,
9598
- 1,
9599
- 1,
9600
- 1
9601
- ],
9602
- sw: [
9603
- 0,
9604
- 1,
9605
- -1,
9606
- 1
9607
- ]
9747
+ const isManualNodeChange = e => {
9748
+ return e.type === 'nodechange' && e.selectionChange;
9608
9749
  };
9609
- const isTouchEvent = evt => evt.type === 'longpress' || evt.type.indexOf('touch') === 0;
9610
- const ControlSelection = (selection, editor) => {
9611
- const dom = editor.dom;
9612
- const editableDoc = editor.getDoc();
9613
- const rootDocument = document;
9614
- const rootElement = editor.getBody();
9615
- let selectedElm, selectedElmGhost, resizeHelper, selectedHandle, resizeBackdrop;
9616
- let startX, startY, selectedElmX, selectedElmY, startW, startH, ratio, resizeStarted;
9617
- let width;
9618
- let height;
9619
- let startScrollWidth;
9620
- let startScrollHeight;
9621
- const isImage = elm => isNonNullable(elm) && (isImg(elm) || dom.is(elm, 'figure.image'));
9622
- const isMedia = elm => isMedia$2(elm) || dom.hasClass(elm, 'mce-preview-object');
9623
- const isEventOnImageOutsideRange = (evt, range) => {
9624
- if (isTouchEvent(evt)) {
9625
- const touch = evt.touches[0];
9626
- return isImage(evt.target) && !isXYWithinRange(touch.clientX, touch.clientY, range);
9627
- } else {
9628
- return isImage(evt.target) && !isXYWithinRange(evt.clientX, evt.clientY, range);
9629
- }
9630
- };
9631
- const contextMenuSelectImage = evt => {
9632
- const target = evt.target;
9633
- if (isEventOnImageOutsideRange(evt, editor.selection.getRng()) && !evt.isDefaultPrevented()) {
9634
- editor.selection.select(target);
9635
- }
9636
- };
9637
- const getResizeTargets = elm => {
9638
- if (dom.hasClass(elm, 'mce-preview-object') && isNonNullable(elm.firstElementChild)) {
9639
- return [
9640
- elm,
9641
- elm.firstElementChild
9642
- ];
9643
- } else if (dom.is(elm, 'figure.image')) {
9644
- return [elm.querySelector('img')];
9645
- } else {
9646
- return [elm];
9647
- }
9750
+ const registerPageMouseUp = (editor, throttledStore) => {
9751
+ const mouseUpPage = () => {
9752
+ throttledStore.throttle();
9648
9753
  };
9649
- const isResizable = elm => {
9650
- const selector = getObjectResizing(editor);
9651
- if (!selector || editor.mode.isReadOnly()) {
9652
- return false;
9653
- }
9654
- if (elm.getAttribute('data-mce-resize') === 'false') {
9655
- return false;
9754
+ DOMUtils.DOM.bind(document, 'mouseup', mouseUpPage);
9755
+ editor.on('remove', () => {
9756
+ DOMUtils.DOM.unbind(document, 'mouseup', mouseUpPage);
9757
+ });
9758
+ };
9759
+ const registerMouseUp = (editor, throttledStore) => {
9760
+ editor.on('mouseup touchend', _e => {
9761
+ throttledStore.throttle();
9762
+ });
9763
+ };
9764
+ const registerEditorEvents = (editor, throttledStore) => {
9765
+ registerMouseUp(editor, throttledStore);
9766
+ editor.on('keyup NodeChange AfterSetSelectionRange', e => {
9767
+ if (!isManualNodeChange(e)) {
9768
+ store(editor);
9656
9769
  }
9657
- if (elm === editor.getBody()) {
9658
- return false;
9770
+ });
9771
+ };
9772
+ const register$6 = editor => {
9773
+ const throttledStore = first$1(() => {
9774
+ store(editor);
9775
+ }, 0);
9776
+ editor.on('init', () => {
9777
+ if (editor.inline) {
9778
+ registerPageMouseUp(editor, throttledStore);
9659
9779
  }
9660
- if (dom.hasClass(elm, 'mce-preview-object') && isNonNullable(elm.firstElementChild)) {
9661
- return is$1(SugarElement.fromDom(elm.firstElementChild), selector);
9662
- } else {
9663
- return is$1(SugarElement.fromDom(elm), selector);
9780
+ registerEditorEvents(editor, throttledStore);
9781
+ });
9782
+ editor.on('remove', () => {
9783
+ throttledStore.cancel();
9784
+ });
9785
+ };
9786
+
9787
+ let documentFocusInHandler;
9788
+ const DOM$9 = DOMUtils.DOM;
9789
+ const isEditorUIElement = elm => {
9790
+ return isElement$6(elm) && FocusManager.isEditorUIElement(elm);
9791
+ };
9792
+ const isEditorContentAreaElement = elm => {
9793
+ const classList = elm.classList;
9794
+ if (classList !== undefined) {
9795
+ return classList.contains('tox-edit-area') || classList.contains('tox-edit-area__iframe') || classList.contains('mce-content-body');
9796
+ } else {
9797
+ return false;
9798
+ }
9799
+ };
9800
+ const isUIElement = (editor, elm) => {
9801
+ const customSelector = getCustomUiSelector(editor);
9802
+ const parent = DOM$9.getParent(elm, elm => {
9803
+ return isEditorUIElement(elm) || (customSelector ? editor.dom.is(elm, customSelector) : false);
9804
+ });
9805
+ return parent !== null;
9806
+ };
9807
+ const getActiveElement = editor => {
9808
+ try {
9809
+ const root = getRootNode(SugarElement.fromDom(editor.getElement()));
9810
+ return active$1(root).fold(() => document.body, x => x.dom);
9811
+ } catch (ex) {
9812
+ return document.body;
9813
+ }
9814
+ };
9815
+ const registerEvents$1 = (editorManager, e) => {
9816
+ const editor = e.editor;
9817
+ register$6(editor);
9818
+ const toggleContentAreaOnFocus = (editor, fn) => {
9819
+ if (shouldHighlightOnFocus(editor) && editor.inline !== true) {
9820
+ const contentArea = SugarElement.fromDom(editor.getContainer());
9821
+ fn(contentArea, 'tox-edit-focus');
9664
9822
  }
9665
9823
  };
9666
- const createGhostElement = (dom, elm) => {
9667
- if (isMedia(elm)) {
9668
- return dom.create('img', { src: Env.transparentSrc });
9669
- } else if (isTable$2(elm)) {
9670
- const isNorth = startsWith(selectedHandle.name, 'n');
9671
- const rowSelect = isNorth ? head : last$2;
9672
- const tableElm = elm.cloneNode(true);
9673
- rowSelect(dom.select('tr', tableElm)).each(tr => {
9674
- const cells = dom.select('td,th', tr);
9675
- dom.setStyle(tr, 'height', null);
9676
- each$e(cells, cell => dom.setStyle(cell, 'height', null));
9677
- });
9678
- return tableElm;
9679
- } else {
9680
- return elm.cloneNode(true);
9824
+ editor.on('focusin', () => {
9825
+ const focusedEditor = editorManager.focusedEditor;
9826
+ if (isEditorContentAreaElement(getActiveElement(editor))) {
9827
+ toggleContentAreaOnFocus(editor, add$2);
9681
9828
  }
9682
- };
9683
- const setSizeProp = (element, name, value) => {
9684
- if (isNonNullable(value)) {
9685
- const targets = getResizeTargets(element);
9686
- each$e(targets, target => {
9687
- if (target.style[name] || !editor.schema.isValid(target.nodeName.toLowerCase(), name)) {
9688
- dom.setStyle(target, name, value);
9689
- } else {
9690
- dom.setAttrib(target, name, '' + value);
9691
- }
9692
- });
9693
- }
9694
- };
9695
- const setGhostElmSize = (ghostElm, width, height) => {
9696
- setSizeProp(ghostElm, 'width', width);
9697
- setSizeProp(ghostElm, 'height', height);
9698
- };
9699
- const resizeGhostElement = e => {
9700
- let deltaX, deltaY, proportional;
9701
- let resizeHelperX, resizeHelperY;
9702
- deltaX = e.screenX - startX;
9703
- deltaY = e.screenY - startY;
9704
- width = deltaX * selectedHandle[2] + startW;
9705
- height = deltaY * selectedHandle[3] + startH;
9706
- width = width < 5 ? 5 : width;
9707
- height = height < 5 ? 5 : height;
9708
- if ((isImage(selectedElm) || isMedia(selectedElm)) && getResizeImgProportional(editor) !== false) {
9709
- proportional = !VK.modifierPressed(e);
9710
- } else {
9711
- proportional = VK.modifierPressed(e);
9712
- }
9713
- if (proportional) {
9714
- if (abs(deltaX) > abs(deltaY)) {
9715
- height = round$1(width * ratio);
9716
- width = round$1(height / ratio);
9717
- } else {
9718
- width = round$1(height / ratio);
9719
- height = round$1(width * ratio);
9720
- }
9721
- }
9722
- setGhostElmSize(selectedElmGhost, width, height);
9723
- resizeHelperX = selectedHandle.startPos.x + deltaX;
9724
- resizeHelperY = selectedHandle.startPos.y + deltaY;
9725
- resizeHelperX = resizeHelperX > 0 ? resizeHelperX : 0;
9726
- resizeHelperY = resizeHelperY > 0 ? resizeHelperY : 0;
9727
- dom.setStyles(resizeHelper, {
9728
- left: resizeHelperX,
9729
- top: resizeHelperY,
9730
- display: 'block'
9731
- });
9732
- resizeHelper.innerHTML = width + ' &times; ' + height;
9733
- if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) {
9734
- dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width));
9735
- }
9736
- if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) {
9737
- dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height));
9738
- }
9739
- deltaX = rootElement.scrollWidth - startScrollWidth;
9740
- deltaY = rootElement.scrollHeight - startScrollHeight;
9741
- if (deltaX + deltaY !== 0) {
9742
- dom.setStyles(resizeHelper, {
9743
- left: resizeHelperX - deltaX,
9744
- top: resizeHelperY - deltaY
9745
- });
9746
- }
9747
- if (!resizeStarted) {
9748
- fireObjectResizeStart(editor, selectedElm, startW, startH, 'corner-' + selectedHandle.name);
9749
- resizeStarted = true;
9750
- }
9751
- };
9752
- const endGhostResize = () => {
9753
- const wasResizeStarted = resizeStarted;
9754
- resizeStarted = false;
9755
- if (wasResizeStarted) {
9756
- setSizeProp(selectedElm, 'width', width);
9757
- setSizeProp(selectedElm, 'height', height);
9758
- }
9759
- dom.unbind(editableDoc, 'mousemove', resizeGhostElement);
9760
- dom.unbind(editableDoc, 'mouseup', endGhostResize);
9761
- if (rootDocument !== editableDoc) {
9762
- dom.unbind(rootDocument, 'mousemove', resizeGhostElement);
9763
- dom.unbind(rootDocument, 'mouseup', endGhostResize);
9764
- }
9765
- dom.remove(selectedElmGhost);
9766
- dom.remove(resizeHelper);
9767
- dom.remove(resizeBackdrop);
9768
- showResizeRect(selectedElm);
9769
- if (wasResizeStarted) {
9770
- fireObjectResized(editor, selectedElm, width, height, 'corner-' + selectedHandle.name);
9771
- dom.setAttrib(selectedElm, 'style', dom.getAttrib(selectedElm, 'style'));
9772
- }
9773
- editor.nodeChanged();
9774
- };
9775
- const showResizeRect = targetElm => {
9776
- unbindResizeHandleEvents();
9777
- const position = dom.getPos(targetElm, rootElement);
9778
- const selectedElmX = position.x;
9779
- const selectedElmY = position.y;
9780
- const rect = targetElm.getBoundingClientRect();
9781
- const targetWidth = rect.width || rect.right - rect.left;
9782
- const targetHeight = rect.height || rect.bottom - rect.top;
9783
- if (selectedElm !== targetElm) {
9784
- hideResizeRect();
9785
- selectedElm = targetElm;
9786
- width = height = 0;
9787
- }
9788
- const e = editor.dispatch('ObjectSelected', { target: targetElm });
9789
- if (isResizable(targetElm) && !e.isDefaultPrevented()) {
9790
- each$d(resizeHandles, (handle, name) => {
9791
- const startDrag = e => {
9792
- const target = getResizeTargets(selectedElm)[0];
9793
- startX = e.screenX;
9794
- startY = e.screenY;
9795
- startW = target.clientWidth;
9796
- startH = target.clientHeight;
9797
- ratio = startH / startW;
9798
- selectedHandle = handle;
9799
- selectedHandle.name = name;
9800
- selectedHandle.startPos = {
9801
- x: targetWidth * handle[0] + selectedElmX,
9802
- y: targetHeight * handle[1] + selectedElmY
9803
- };
9804
- startScrollWidth = rootElement.scrollWidth;
9805
- startScrollHeight = rootElement.scrollHeight;
9806
- resizeBackdrop = dom.add(rootElement, 'div', {
9807
- 'class': 'mce-resize-backdrop',
9808
- 'data-mce-bogus': 'all'
9809
- });
9810
- dom.setStyles(resizeBackdrop, {
9811
- position: 'fixed',
9812
- left: '0',
9813
- top: '0',
9814
- width: '100%',
9815
- height: '100%'
9816
- });
9817
- selectedElmGhost = createGhostElement(dom, selectedElm);
9818
- dom.addClass(selectedElmGhost, 'mce-clonedresizable');
9819
- dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all');
9820
- selectedElmGhost.contentEditable = 'false';
9821
- dom.setStyles(selectedElmGhost, {
9822
- left: selectedElmX,
9823
- top: selectedElmY,
9824
- margin: 0
9825
- });
9826
- setGhostElmSize(selectedElmGhost, targetWidth, targetHeight);
9827
- selectedElmGhost.removeAttribute(elementSelectionAttr);
9828
- rootElement.appendChild(selectedElmGhost);
9829
- dom.bind(editableDoc, 'mousemove', resizeGhostElement);
9830
- dom.bind(editableDoc, 'mouseup', endGhostResize);
9831
- if (rootDocument !== editableDoc) {
9832
- dom.bind(rootDocument, 'mousemove', resizeGhostElement);
9833
- dom.bind(rootDocument, 'mouseup', endGhostResize);
9834
- }
9835
- resizeHelper = dom.add(rootElement, 'div', {
9836
- 'class': 'mce-resize-helper',
9837
- 'data-mce-bogus': 'all'
9838
- }, startW + ' &times; ' + startH);
9839
- };
9840
- let handleElm = dom.get('mceResizeHandle' + name);
9841
- if (handleElm) {
9842
- dom.remove(handleElm);
9843
- }
9844
- handleElm = dom.add(rootElement, 'div', {
9845
- 'id': 'mceResizeHandle' + name,
9846
- 'data-mce-bogus': 'all',
9847
- 'class': 'mce-resizehandle',
9848
- 'unselectable': true,
9849
- 'style': 'cursor:' + name + '-resize; margin:0; padding:0'
9850
- });
9851
- dom.bind(handleElm, 'mousedown', e => {
9852
- e.stopImmediatePropagation();
9853
- e.preventDefault();
9854
- startDrag(e);
9855
- });
9856
- handle.elm = handleElm;
9857
- dom.setStyles(handleElm, {
9858
- left: targetWidth * handle[0] + selectedElmX - handleElm.offsetWidth / 2,
9859
- top: targetHeight * handle[1] + selectedElmY - handleElm.offsetHeight / 2
9860
- });
9861
- });
9862
- } else {
9863
- hideResizeRect(false);
9864
- }
9865
- };
9866
- const throttledShowResizeRect = first$1(showResizeRect, 0);
9867
- const hideResizeRect = (removeSelected = true) => {
9868
- throttledShowResizeRect.cancel();
9869
- unbindResizeHandleEvents();
9870
- if (selectedElm && removeSelected) {
9871
- selectedElm.removeAttribute(elementSelectionAttr);
9872
- }
9873
- each$d(resizeHandles, (value, name) => {
9874
- const handleElm = dom.get('mceResizeHandle' + name);
9875
- if (handleElm) {
9876
- dom.unbind(handleElm);
9877
- dom.remove(handleElm);
9878
- }
9879
- });
9880
- };
9881
- const isChildOrEqual = (node, parent) => dom.isChildOf(node, parent);
9882
- const updateResizeRect = e => {
9883
- if (resizeStarted || editor.removed || editor.composing) {
9884
- return;
9885
- }
9886
- const targetElm = e.type === 'mousedown' ? e.target : selection.getNode();
9887
- const controlElm = closest$3(SugarElement.fromDom(targetElm), controlElmSelector).map(e => e.dom).filter(e => dom.isEditable(e.parentElement) || e.nodeName === 'IMG' && dom.isEditable(e)).getOrUndefined();
9888
- const selectedValue = isNonNullable(controlElm) ? dom.getAttrib(controlElm, elementSelectionAttr, '1') : '1';
9889
- each$e(dom.select(`img[${ elementSelectionAttr }],hr[${ elementSelectionAttr }]`), img => {
9890
- img.removeAttribute(elementSelectionAttr);
9891
- });
9892
- if (isNonNullable(controlElm) && isChildOrEqual(controlElm, rootElement) && editor.hasFocus()) {
9893
- disableGeckoResize();
9894
- const startElm = selection.getStart(true);
9895
- if (isChildOrEqual(startElm, controlElm) && isChildOrEqual(selection.getEnd(true), controlElm)) {
9896
- dom.setAttrib(controlElm, elementSelectionAttr, selectedValue);
9897
- throttledShowResizeRect.throttle(controlElm);
9898
- return;
9899
- }
9900
- }
9901
- hideResizeRect();
9902
- };
9903
- const unbindResizeHandleEvents = () => {
9904
- each$d(resizeHandles, handle => {
9905
- if (handle.elm) {
9906
- dom.unbind(handle.elm);
9907
- delete handle.elm;
9908
- }
9909
- });
9910
- };
9911
- const disableGeckoResize = () => {
9912
- try {
9913
- editor.getDoc().execCommand('enableObjectResizing', false, 'false');
9914
- } catch (ex) {
9915
- }
9916
- };
9917
- editor.on('init', () => {
9918
- disableGeckoResize();
9919
- editor.on('NodeChange ResizeEditor ResizeWindow ResizeContent drop', updateResizeRect);
9920
- editor.on('keyup compositionend', e => {
9921
- if (selectedElm && selectedElm.nodeName === 'TABLE') {
9922
- updateResizeRect(e);
9923
- }
9924
- });
9925
- editor.on('hide blur', hideResizeRect);
9926
- editor.on('contextmenu longpress', contextMenuSelectImage, true);
9927
- });
9928
- editor.on('remove', unbindResizeHandleEvents);
9929
- const destroy = () => {
9930
- throttledShowResizeRect.cancel();
9931
- selectedElm = selectedElmGhost = resizeBackdrop = null;
9932
- };
9933
- return {
9934
- isResizable,
9935
- showResizeRect,
9936
- hideResizeRect,
9937
- updateResizeRect,
9938
- destroy
9939
- };
9940
- };
9941
-
9942
- const setStart = (rng, situ) => {
9943
- situ.fold(e => {
9944
- rng.setStartBefore(e.dom);
9945
- }, (e, o) => {
9946
- rng.setStart(e.dom, o);
9947
- }, e => {
9948
- rng.setStartAfter(e.dom);
9949
- });
9950
- };
9951
- const setFinish = (rng, situ) => {
9952
- situ.fold(e => {
9953
- rng.setEndBefore(e.dom);
9954
- }, (e, o) => {
9955
- rng.setEnd(e.dom, o);
9956
- }, e => {
9957
- rng.setEndAfter(e.dom);
9958
- });
9959
- };
9960
- const relativeToNative = (win, startSitu, finishSitu) => {
9961
- const range = win.document.createRange();
9962
- setStart(range, startSitu);
9963
- setFinish(range, finishSitu);
9964
- return range;
9965
- };
9966
- const exactToNative = (win, start, soffset, finish, foffset) => {
9967
- const rng = win.document.createRange();
9968
- rng.setStart(start.dom, soffset);
9969
- rng.setEnd(finish.dom, foffset);
9970
- return rng;
9971
- };
9972
-
9973
- const adt$3 = Adt.generate([
9974
- {
9975
- ltr: [
9976
- 'start',
9977
- 'soffset',
9978
- 'finish',
9979
- 'foffset'
9980
- ]
9981
- },
9982
- {
9983
- rtl: [
9984
- 'start',
9985
- 'soffset',
9986
- 'finish',
9987
- 'foffset'
9988
- ]
9989
- }
9990
- ]);
9991
- const fromRange = (win, type, range) => type(SugarElement.fromDom(range.startContainer), range.startOffset, SugarElement.fromDom(range.endContainer), range.endOffset);
9992
- const getRanges = (win, selection) => selection.match({
9993
- domRange: rng => {
9994
- return {
9995
- ltr: constant(rng),
9996
- rtl: Optional.none
9997
- };
9998
- },
9999
- relative: (startSitu, finishSitu) => {
10000
- return {
10001
- ltr: cached(() => relativeToNative(win, startSitu, finishSitu)),
10002
- rtl: cached(() => Optional.some(relativeToNative(win, finishSitu, startSitu)))
10003
- };
10004
- },
10005
- exact: (start, soffset, finish, foffset) => {
10006
- return {
10007
- ltr: cached(() => exactToNative(win, start, soffset, finish, foffset)),
10008
- rtl: cached(() => Optional.some(exactToNative(win, finish, foffset, start, soffset)))
10009
- };
10010
- }
10011
- });
10012
- const doDiagnose = (win, ranges) => {
10013
- const rng = ranges.ltr();
10014
- if (rng.collapsed) {
10015
- const reversed = ranges.rtl().filter(rev => rev.collapsed === false);
10016
- return reversed.map(rev => adt$3.rtl(SugarElement.fromDom(rev.endContainer), rev.endOffset, SugarElement.fromDom(rev.startContainer), rev.startOffset)).getOrThunk(() => fromRange(win, adt$3.ltr, rng));
10017
- } else {
10018
- return fromRange(win, adt$3.ltr, rng);
10019
- }
10020
- };
10021
- const diagnose = (win, selection) => {
10022
- const ranges = getRanges(win, selection);
10023
- return doDiagnose(win, ranges);
10024
- };
10025
- adt$3.ltr;
10026
- adt$3.rtl;
10027
-
10028
- const create$9 = (start, soffset, finish, foffset) => ({
10029
- start,
10030
- soffset,
10031
- finish,
10032
- foffset
10033
- });
10034
- const SimRange = { create: create$9 };
10035
-
10036
- const caretPositionFromPoint = (doc, x, y) => {
10037
- var _a;
10038
- return Optional.from((_a = doc.caretPositionFromPoint) === null || _a === void 0 ? void 0 : _a.call(doc, x, y)).bind(pos => {
10039
- if (pos.offsetNode === null) {
10040
- return Optional.none();
9829
+ if (focusedEditor !== editor) {
9830
+ if (focusedEditor) {
9831
+ focusedEditor.dispatch('blur', { focusedEditor: editor });
9832
+ }
9833
+ editorManager.setActive(editor);
9834
+ editorManager.focusedEditor = editor;
9835
+ editor.dispatch('focus', { blurredEditor: focusedEditor });
9836
+ editor.focus(true);
10041
9837
  }
10042
- const r = doc.createRange();
10043
- r.setStart(pos.offsetNode, pos.offset);
10044
- r.collapse();
10045
- return Optional.some(r);
10046
9838
  });
10047
- };
10048
- const caretRangeFromPoint = (doc, x, y) => {
10049
- var _a;
10050
- return Optional.from((_a = doc.caretRangeFromPoint) === null || _a === void 0 ? void 0 : _a.call(doc, x, y));
10051
- };
10052
- const availableSearch = (doc, x, y) => {
10053
- if (doc.caretPositionFromPoint) {
10054
- return caretPositionFromPoint(doc, x, y);
10055
- } else if (doc.caretRangeFromPoint) {
10056
- return caretRangeFromPoint(doc, x, y);
10057
- } else {
10058
- return Optional.none();
9839
+ editor.on('focusout', () => {
9840
+ Delay.setEditorTimeout(editor, () => {
9841
+ const focusedEditor = editorManager.focusedEditor;
9842
+ if (!isEditorContentAreaElement(getActiveElement(editor)) || focusedEditor !== editor) {
9843
+ toggleContentAreaOnFocus(editor, remove$6);
9844
+ }
9845
+ if (!isUIElement(editor, getActiveElement(editor)) && focusedEditor === editor) {
9846
+ editor.dispatch('blur', { focusedEditor: null });
9847
+ editorManager.focusedEditor = null;
9848
+ }
9849
+ });
9850
+ });
9851
+ if (!documentFocusInHandler) {
9852
+ documentFocusInHandler = e => {
9853
+ const activeEditor = editorManager.activeEditor;
9854
+ if (activeEditor) {
9855
+ getOriginalEventTarget(e).each(target => {
9856
+ const elem = target;
9857
+ if (elem.ownerDocument === document) {
9858
+ if (elem !== document.body && !isUIElement(activeEditor, elem) && editorManager.focusedEditor === activeEditor) {
9859
+ activeEditor.dispatch('blur', { focusedEditor: null });
9860
+ editorManager.focusedEditor = null;
9861
+ }
9862
+ }
9863
+ });
9864
+ }
9865
+ };
9866
+ DOM$9.bind(document, 'focusin', documentFocusInHandler);
10059
9867
  }
10060
9868
  };
10061
- const fromPoint$1 = (win, x, y) => {
10062
- const doc = win.document;
10063
- return availableSearch(doc, x, y).map(rng => SimRange.create(SugarElement.fromDom(rng.startContainer), rng.startOffset, SugarElement.fromDom(rng.endContainer), rng.endOffset));
10064
- };
10065
-
10066
- const adt$2 = Adt.generate([
10067
- { before: ['element'] },
10068
- {
10069
- on: [
10070
- 'element',
10071
- 'offset'
10072
- ]
10073
- },
10074
- { after: ['element'] }
10075
- ]);
10076
- const cata = (subject, onBefore, onOn, onAfter) => subject.fold(onBefore, onOn, onAfter);
10077
- const getStart$2 = situ => situ.fold(identity, identity, identity);
10078
- const before$1 = adt$2.before;
10079
- const on = adt$2.on;
10080
- const after$1 = adt$2.after;
10081
- const Situ = {
10082
- before: before$1,
10083
- on,
10084
- after: after$1,
10085
- cata,
10086
- getStart: getStart$2
10087
- };
10088
-
10089
- const adt$1 = Adt.generate([
10090
- { domRange: ['rng'] },
10091
- {
10092
- relative: [
10093
- 'startSitu',
10094
- 'finishSitu'
10095
- ]
10096
- },
10097
- {
10098
- exact: [
10099
- 'start',
10100
- 'soffset',
10101
- 'finish',
10102
- 'foffset'
10103
- ]
9869
+ const unregisterDocumentEvents = (editorManager, e) => {
9870
+ if (editorManager.focusedEditor === e.editor) {
9871
+ editorManager.focusedEditor = null;
9872
+ }
9873
+ if (!editorManager.activeEditor && documentFocusInHandler) {
9874
+ DOM$9.unbind(document, 'focusin', documentFocusInHandler);
9875
+ documentFocusInHandler = null;
10104
9876
  }
10105
- ]);
10106
- const exactFromRange = simRange => adt$1.exact(simRange.start, simRange.soffset, simRange.finish, simRange.foffset);
10107
- const getStart$1 = selection => selection.match({
10108
- domRange: rng => SugarElement.fromDom(rng.startContainer),
10109
- relative: (startSitu, _finishSitu) => Situ.getStart(startSitu),
10110
- exact: (start, _soffset, _finish, _foffset) => start
10111
- });
10112
- const domRange = adt$1.domRange;
10113
- const relative = adt$1.relative;
10114
- const exact = adt$1.exact;
10115
- const getWin = selection => {
10116
- const start = getStart$1(selection);
10117
- return defaultView(start);
10118
9877
  };
10119
- const range = SimRange.create;
10120
- const SimSelection = {
10121
- domRange,
10122
- relative,
10123
- exact,
10124
- exactFromRange,
10125
- getWin,
10126
- range
9878
+ const setup$w = editorManager => {
9879
+ editorManager.on('AddEditor', curry(registerEvents$1, editorManager));
9880
+ editorManager.on('RemoveEditor', curry(unregisterDocumentEvents, editorManager));
10127
9881
  };
10128
9882
 
10129
- const beforeSpecial = (element, offset) => {
10130
- const name$1 = name(element);
10131
- if ('input' === name$1) {
10132
- return Situ.after(element);
10133
- } else if (!contains$2([
10134
- 'br',
10135
- 'img'
10136
- ], name$1)) {
10137
- return Situ.on(element, offset);
9883
+ const getContentEditableHost = (editor, node) => editor.dom.getParent(node, node => editor.dom.getContentEditable(node) === 'true');
9884
+ const hasContentEditableFalseParent$1 = (editor, node) => editor.dom.getParent(node, node => editor.dom.getContentEditable(node) === 'false') !== null;
9885
+ const getCollapsedNode = rng => rng.collapsed ? Optional.from(getNode$1(rng.startContainer, rng.startOffset)).map(SugarElement.fromDom) : Optional.none();
9886
+ const getFocusInElement = (root, rng) => getCollapsedNode(rng).bind(node => {
9887
+ if (isTableSection(node)) {
9888
+ return Optional.some(node);
9889
+ } else if (!contains(root, node)) {
9890
+ return Optional.some(root);
10138
9891
  } else {
10139
- return offset === 0 ? Situ.before(element) : Situ.after(element);
9892
+ return Optional.none();
10140
9893
  }
10141
- };
10142
- const preprocessRelative = (startSitu, finishSitu) => {
10143
- const start = startSitu.fold(Situ.before, beforeSpecial, Situ.after);
10144
- const finish = finishSitu.fold(Situ.before, beforeSpecial, Situ.after);
10145
- return SimSelection.relative(start, finish);
10146
- };
10147
- const preprocessExact = (start, soffset, finish, foffset) => {
10148
- const startSitu = beforeSpecial(start, soffset);
10149
- const finishSitu = beforeSpecial(finish, foffset);
10150
- return SimSelection.relative(startSitu, finishSitu);
10151
- };
10152
- const preprocess = selection => selection.match({
10153
- domRange: rng => {
10154
- const start = SugarElement.fromDom(rng.startContainer);
10155
- const finish = SugarElement.fromDom(rng.endContainer);
10156
- return preprocessExact(start, rng.startOffset, finish, rng.endOffset);
10157
- },
10158
- relative: preprocessRelative,
10159
- exact: preprocessExact
10160
9894
  });
10161
-
10162
- const fromElements = (elements, scope) => {
10163
- const doc = scope || document;
10164
- const fragment = doc.createDocumentFragment();
10165
- each$e(elements, element => {
10166
- fragment.appendChild(element.dom);
10167
- });
10168
- return SugarElement.fromDom(fragment);
10169
- };
10170
-
10171
- const toNative = selection => {
10172
- const win = SimSelection.getWin(selection).dom;
10173
- const getDomRange = (start, soffset, finish, foffset) => exactToNative(win, start, soffset, finish, foffset);
10174
- const filtered = preprocess(selection);
10175
- return diagnose(win, filtered).match({
10176
- ltr: getDomRange,
10177
- rtl: getDomRange
10178
- });
10179
- };
10180
- const getAtPoint = (win, x, y) => fromPoint$1(win, x, y);
10181
-
10182
- const fromPoint = (clientX, clientY, doc) => {
10183
- const win = defaultView(SugarElement.fromDom(doc));
10184
- return getAtPoint(win.dom, clientX, clientY).map(simRange => {
10185
- const rng = doc.createRange();
10186
- rng.setStart(simRange.start.dom, simRange.soffset);
10187
- rng.setEnd(simRange.finish.dom, simRange.foffset);
10188
- return rng;
10189
- }).getOrUndefined();
10190
- };
10191
-
10192
- const isEq$4 = (rng1, rng2) => {
10193
- return isNonNullable(rng1) && isNonNullable(rng2) && (rng1.startContainer === rng2.startContainer && rng1.startOffset === rng2.startOffset) && (rng1.endContainer === rng2.endContainer && rng1.endOffset === rng2.endOffset);
10194
- };
10195
-
10196
- const findParent = (node, rootNode, predicate) => {
10197
- let currentNode = node;
10198
- while (currentNode && currentNode !== rootNode) {
10199
- if (predicate(currentNode)) {
10200
- return currentNode;
10201
- }
10202
- currentNode = currentNode.parentNode;
10203
- }
10204
- return null;
10205
- };
10206
- const hasParent$1 = (node, rootNode, predicate) => findParent(node, rootNode, predicate) !== null;
10207
- const hasParentWithName = (node, rootNode, name) => hasParent$1(node, rootNode, node => node.nodeName === name);
10208
- const isCeFalseCaretContainer = (node, rootNode) => isCaretContainer$2(node) && !hasParent$1(node, rootNode, isCaretNode);
10209
- const hasBrBeforeAfter = (dom, node, left) => {
10210
- const parentNode = node.parentNode;
10211
- if (parentNode) {
10212
- const walker = new DomTreeWalker(node, dom.getParent(parentNode, dom.isBlock) || dom.getRoot());
10213
- let currentNode;
10214
- while (currentNode = walker[left ? 'prev' : 'next']()) {
10215
- if (isBr$6(currentNode)) {
10216
- return true;
10217
- }
10218
- }
10219
- }
10220
- return false;
10221
- };
10222
- const isPrevNode = (node, name) => {
10223
- var _a;
10224
- return ((_a = node.previousSibling) === null || _a === void 0 ? void 0 : _a.nodeName) === name;
9895
+ const normalizeSelection = (editor, rng) => {
9896
+ getFocusInElement(SugarElement.fromDom(editor.getBody()), rng).bind(elm => {
9897
+ return firstPositionIn(elm.dom);
9898
+ }).fold(() => {
9899
+ editor.selection.normalize();
9900
+ }, caretPos => editor.selection.setRng(caretPos.toRange()));
10225
9901
  };
10226
- const hasContentEditableFalseParent$1 = (root, node) => {
10227
- let currentNode = node;
10228
- while (currentNode && currentNode !== root) {
10229
- if (isContentEditableFalse$b(currentNode)) {
10230
- return true;
9902
+ const focusBody = body => {
9903
+ if (body.setActive) {
9904
+ try {
9905
+ body.setActive();
9906
+ } catch (ex) {
9907
+ body.focus();
10231
9908
  }
10232
- currentNode = currentNode.parentNode;
10233
- }
10234
- return false;
10235
- };
10236
- const findTextNodeRelative = (dom, isAfterNode, collapsed, left, startNode) => {
10237
- const body = dom.getRoot();
10238
- const nonEmptyElementsMap = dom.schema.getNonEmptyElements();
10239
- const parentNode = startNode.parentNode;
10240
- let lastInlineElement;
10241
- let node;
10242
- if (!parentNode) {
10243
- return Optional.none();
9909
+ } else {
9910
+ body.focus();
10244
9911
  }
10245
- const parentBlockContainer = dom.getParent(parentNode, dom.isBlock) || body;
10246
- if (left && isBr$6(startNode) && isAfterNode && dom.isEmpty(parentBlockContainer)) {
10247
- return Optional.some(CaretPosition(parentNode, dom.nodeIndex(startNode)));
9912
+ };
9913
+ const hasElementFocus = elm => hasFocus$1(elm) || search(elm).isSome();
9914
+ const hasIframeFocus = editor => isNonNullable(editor.iframeElement) && hasFocus$1(SugarElement.fromDom(editor.iframeElement));
9915
+ const hasInlineFocus = editor => {
9916
+ const rawBody = editor.getBody();
9917
+ return rawBody && hasElementFocus(SugarElement.fromDom(rawBody));
9918
+ };
9919
+ const hasUiFocus = editor => {
9920
+ const dos = getRootNode(SugarElement.fromDom(editor.getElement()));
9921
+ return active$1(dos).filter(elem => !isEditorContentAreaElement(elem.dom) && isUIElement(editor, elem.dom)).isSome();
9922
+ };
9923
+ const hasFocus = editor => editor.inline ? hasInlineFocus(editor) : hasIframeFocus(editor);
9924
+ const hasEditorOrUiFocus = editor => hasFocus(editor) || hasUiFocus(editor);
9925
+ const focusEditor = editor => {
9926
+ const selection = editor.selection;
9927
+ const body = editor.getBody();
9928
+ let rng = selection.getRng();
9929
+ editor.quirks.refreshContentEditable();
9930
+ const restoreBookmark = editor => {
9931
+ getRng(editor).each(bookmarkRng => {
9932
+ editor.selection.setRng(bookmarkRng);
9933
+ rng = bookmarkRng;
9934
+ });
9935
+ };
9936
+ if (!hasFocus(editor) && editor.hasEditableRoot()) {
9937
+ restoreBookmark(editor);
10248
9938
  }
10249
- const walker = new DomTreeWalker(startNode, parentBlockContainer);
10250
- while (node = walker[left ? 'prev' : 'next']()) {
10251
- if (dom.getContentEditableParent(node) === 'false' || isCeFalseCaretContainer(node, body)) {
10252
- return Optional.none();
10253
- }
10254
- if (isText$b(node) && node.data.length > 0) {
10255
- if (!hasParentWithName(node, body, 'A')) {
10256
- return Optional.some(CaretPosition(node, left ? node.data.length : 0));
10257
- }
10258
- return Optional.none();
9939
+ const contentEditableHost = getContentEditableHost(editor, selection.getNode());
9940
+ if (contentEditableHost && editor.dom.isChildOf(contentEditableHost, body)) {
9941
+ if (!hasContentEditableFalseParent$1(editor, contentEditableHost)) {
9942
+ focusBody(body);
10259
9943
  }
10260
- if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
10261
- return Optional.none();
9944
+ focusBody(contentEditableHost);
9945
+ if (!editor.hasEditableRoot()) {
9946
+ restoreBookmark(editor);
10262
9947
  }
10263
- lastInlineElement = node;
9948
+ normalizeSelection(editor, rng);
9949
+ activateEditor(editor);
9950
+ return;
10264
9951
  }
10265
- if (isComment(lastInlineElement)) {
10266
- return Optional.none();
9952
+ if (!editor.inline) {
9953
+ if (!Env.browser.isOpera()) {
9954
+ focusBody(body);
9955
+ }
9956
+ editor.getWin().focus();
10267
9957
  }
10268
- if (collapsed && lastInlineElement) {
10269
- return Optional.some(CaretPosition(lastInlineElement, 0));
9958
+ if (Env.browser.isFirefox() || editor.inline) {
9959
+ focusBody(body);
9960
+ normalizeSelection(editor, rng);
10270
9961
  }
10271
- return Optional.none();
9962
+ activateEditor(editor);
10272
9963
  };
10273
- const normalizeEndPoint = (dom, collapsed, start, rng) => {
10274
- const body = dom.getRoot();
10275
- let node;
10276
- let normalized = false;
10277
- let container = start ? rng.startContainer : rng.endContainer;
10278
- let offset = start ? rng.startOffset : rng.endOffset;
10279
- const isAfterNode = isElement$6(container) && offset === container.childNodes.length;
10280
- const nonEmptyElementsMap = dom.schema.getNonEmptyElements();
10281
- let directionLeft = start;
10282
- if (isCaretContainer$2(container)) {
10283
- return Optional.none();
9964
+ const activateEditor = editor => editor.editorManager.setActive(editor);
9965
+ const focus = (editor, skipFocus) => {
9966
+ if (editor.removed) {
9967
+ return;
10284
9968
  }
10285
- if (isElement$6(container) && offset > container.childNodes.length - 1) {
10286
- directionLeft = false;
9969
+ if (skipFocus) {
9970
+ activateEditor(editor);
9971
+ } else {
9972
+ focusEditor(editor);
10287
9973
  }
10288
- if (isDocument$1(container)) {
10289
- container = body;
10290
- offset = 0;
9974
+ };
9975
+
9976
+ const VK = {
9977
+ BACKSPACE: 8,
9978
+ DELETE: 46,
9979
+ DOWN: 40,
9980
+ ENTER: 13,
9981
+ ESC: 27,
9982
+ LEFT: 37,
9983
+ RIGHT: 39,
9984
+ SPACEBAR: 32,
9985
+ TAB: 9,
9986
+ UP: 38,
9987
+ PAGE_UP: 33,
9988
+ PAGE_DOWN: 34,
9989
+ END: 35,
9990
+ HOME: 36,
9991
+ modifierPressed: e => {
9992
+ return e.shiftKey || e.ctrlKey || e.altKey || VK.metaKeyPressed(e);
9993
+ },
9994
+ metaKeyPressed: e => {
9995
+ return Env.os.isMacOS() || Env.os.isiOS() ? e.metaKey : e.ctrlKey && !e.altKey;
10291
9996
  }
10292
- if (container === body) {
10293
- if (directionLeft) {
10294
- node = container.childNodes[offset > 0 ? offset - 1 : 0];
10295
- if (node) {
10296
- if (isCaretContainer$2(node)) {
10297
- return Optional.none();
10298
- }
10299
- if (nonEmptyElementsMap[node.nodeName] || isTable$2(node)) {
10300
- return Optional.none();
10301
- }
10302
- }
9997
+ };
9998
+
9999
+ const elementSelectionAttr = 'data-mce-selected';
10000
+ const controlElmSelector = 'table,img,figure.image,hr,video,span.mce-preview-object,details';
10001
+ const abs = Math.abs;
10002
+ const round$1 = Math.round;
10003
+ const resizeHandles = {
10004
+ nw: [
10005
+ 0,
10006
+ 0,
10007
+ -1,
10008
+ -1
10009
+ ],
10010
+ ne: [
10011
+ 1,
10012
+ 0,
10013
+ 1,
10014
+ -1
10015
+ ],
10016
+ se: [
10017
+ 1,
10018
+ 1,
10019
+ 1,
10020
+ 1
10021
+ ],
10022
+ sw: [
10023
+ 0,
10024
+ 1,
10025
+ -1,
10026
+ 1
10027
+ ]
10028
+ };
10029
+ const isTouchEvent = evt => evt.type === 'longpress' || evt.type.indexOf('touch') === 0;
10030
+ const ControlSelection = (selection, editor) => {
10031
+ const dom = editor.dom;
10032
+ const editableDoc = editor.getDoc();
10033
+ const rootDocument = document;
10034
+ const rootElement = editor.getBody();
10035
+ let selectedElm, selectedElmGhost, resizeHelper, selectedHandle, resizeBackdrop;
10036
+ let startX, startY, selectedElmX, selectedElmY, startW, startH, ratio, resizeStarted;
10037
+ let width;
10038
+ let height;
10039
+ let startScrollWidth;
10040
+ let startScrollHeight;
10041
+ const isImage = elm => isNonNullable(elm) && (isImg(elm) || dom.is(elm, 'figure.image'));
10042
+ const isMedia = elm => isMedia$2(elm) || dom.hasClass(elm, 'mce-preview-object');
10043
+ const isEventOnImageOutsideRange = (evt, range) => {
10044
+ if (isTouchEvent(evt)) {
10045
+ const touch = evt.touches[0];
10046
+ return isImage(evt.target) && !isXYWithinRange(touch.clientX, touch.clientY, range);
10047
+ } else {
10048
+ return isImage(evt.target) && !isXYWithinRange(evt.clientX, evt.clientY, range);
10303
10049
  }
10304
- if (container.hasChildNodes()) {
10305
- offset = Math.min(!directionLeft && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1);
10306
- container = container.childNodes[offset];
10307
- offset = isText$b(container) && isAfterNode ? container.data.length : 0;
10308
- if (!collapsed && container === body.lastChild && isTable$2(container)) {
10309
- return Optional.none();
10310
- }
10311
- if (hasContentEditableFalseParent$1(body, container) || isCaretContainer$2(container)) {
10312
- return Optional.none();
10313
- }
10314
- if (isDetails(container)) {
10315
- return Optional.none();
10316
- }
10317
- if (container.hasChildNodes() && !isTable$2(container)) {
10318
- node = container;
10319
- const walker = new DomTreeWalker(container, body);
10320
- do {
10321
- if (isContentEditableFalse$b(node) || isCaretContainer$2(node)) {
10322
- normalized = false;
10323
- break;
10324
- }
10325
- if (isText$b(node) && node.data.length > 0) {
10326
- offset = directionLeft ? 0 : node.data.length;
10327
- container = node;
10328
- normalized = true;
10329
- break;
10330
- }
10331
- if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCellOrCaption(node)) {
10332
- offset = dom.nodeIndex(node);
10333
- container = node.parentNode;
10334
- if (!directionLeft) {
10335
- offset++;
10336
- }
10337
- normalized = true;
10338
- break;
10339
- }
10340
- } while (node = directionLeft ? walker.next() : walker.prev());
10341
- }
10050
+ };
10051
+ const contextMenuSelectImage = evt => {
10052
+ const target = evt.target;
10053
+ if (isEventOnImageOutsideRange(evt, editor.selection.getRng()) && !evt.isDefaultPrevented()) {
10054
+ editor.selection.select(target);
10055
+ }
10056
+ };
10057
+ const getResizeTargets = elm => {
10058
+ if (dom.hasClass(elm, 'mce-preview-object') && isNonNullable(elm.firstElementChild)) {
10059
+ return [
10060
+ elm,
10061
+ elm.firstElementChild
10062
+ ];
10063
+ } else if (dom.is(elm, 'figure.image')) {
10064
+ return [elm.querySelector('img')];
10065
+ } else {
10066
+ return [elm];
10067
+ }
10068
+ };
10069
+ const isResizable = elm => {
10070
+ const selector = getObjectResizing(editor);
10071
+ if (!selector || editor.mode.isReadOnly()) {
10072
+ return false;
10073
+ }
10074
+ if (elm.getAttribute('data-mce-resize') === 'false') {
10075
+ return false;
10076
+ }
10077
+ if (elm === editor.getBody()) {
10078
+ return false;
10079
+ }
10080
+ if (dom.hasClass(elm, 'mce-preview-object') && isNonNullable(elm.firstElementChild)) {
10081
+ return is$1(SugarElement.fromDom(elm.firstElementChild), selector);
10082
+ } else {
10083
+ return is$1(SugarElement.fromDom(elm), selector);
10084
+ }
10085
+ };
10086
+ const createGhostElement = (dom, elm) => {
10087
+ if (isMedia(elm)) {
10088
+ return dom.create('img', { src: Env.transparentSrc });
10089
+ } else if (isTable$2(elm)) {
10090
+ const isNorth = startsWith(selectedHandle.name, 'n');
10091
+ const rowSelect = isNorth ? head : last$2;
10092
+ const tableElm = elm.cloneNode(true);
10093
+ rowSelect(dom.select('tr', tableElm)).each(tr => {
10094
+ const cells = dom.select('td,th', tr);
10095
+ dom.setStyle(tr, 'height', null);
10096
+ each$e(cells, cell => dom.setStyle(cell, 'height', null));
10097
+ });
10098
+ return tableElm;
10099
+ } else {
10100
+ return elm.cloneNode(true);
10342
10101
  }
10343
- }
10344
- if (collapsed) {
10345
- if (isText$b(container) && offset === 0) {
10346
- findTextNodeRelative(dom, isAfterNode, collapsed, true, container).each(pos => {
10347
- container = pos.container();
10348
- offset = pos.offset();
10349
- normalized = true;
10102
+ };
10103
+ const setSizeProp = (element, name, value) => {
10104
+ if (isNonNullable(value)) {
10105
+ const targets = getResizeTargets(element);
10106
+ each$e(targets, target => {
10107
+ if (target.style[name] || !editor.schema.isValid(target.nodeName.toLowerCase(), name)) {
10108
+ dom.setStyle(target, name, value);
10109
+ } else {
10110
+ dom.setAttrib(target, name, '' + value);
10111
+ }
10350
10112
  });
10351
10113
  }
10352
- if (isElement$6(container)) {
10353
- node = container.childNodes[offset];
10354
- if (!node) {
10355
- node = container.childNodes[offset - 1];
10356
- }
10357
- if (node && isBr$6(node) && !isPrevNode(node, 'A') && !hasBrBeforeAfter(dom, node, false) && !hasBrBeforeAfter(dom, node, true)) {
10358
- findTextNodeRelative(dom, isAfterNode, collapsed, true, node).each(pos => {
10359
- container = pos.container();
10360
- offset = pos.offset();
10361
- normalized = true;
10362
- });
10114
+ };
10115
+ const setGhostElmSize = (ghostElm, width, height) => {
10116
+ setSizeProp(ghostElm, 'width', width);
10117
+ setSizeProp(ghostElm, 'height', height);
10118
+ };
10119
+ const resizeGhostElement = e => {
10120
+ let deltaX, deltaY, proportional;
10121
+ let resizeHelperX, resizeHelperY;
10122
+ deltaX = e.screenX - startX;
10123
+ deltaY = e.screenY - startY;
10124
+ width = deltaX * selectedHandle[2] + startW;
10125
+ height = deltaY * selectedHandle[3] + startH;
10126
+ width = width < 5 ? 5 : width;
10127
+ height = height < 5 ? 5 : height;
10128
+ if ((isImage(selectedElm) || isMedia(selectedElm)) && getResizeImgProportional(editor) !== false) {
10129
+ proportional = !VK.modifierPressed(e);
10130
+ } else {
10131
+ proportional = VK.modifierPressed(e);
10132
+ }
10133
+ if (proportional) {
10134
+ if (abs(deltaX) > abs(deltaY)) {
10135
+ height = round$1(width * ratio);
10136
+ width = round$1(height / ratio);
10137
+ } else {
10138
+ width = round$1(height / ratio);
10139
+ height = round$1(width * ratio);
10363
10140
  }
10364
10141
  }
10365
- }
10366
- if (directionLeft && !collapsed && isText$b(container) && offset === container.data.length) {
10367
- findTextNodeRelative(dom, isAfterNode, collapsed, false, container).each(pos => {
10368
- container = pos.container();
10369
- offset = pos.offset();
10370
- normalized = true;
10142
+ setGhostElmSize(selectedElmGhost, width, height);
10143
+ resizeHelperX = selectedHandle.startPos.x + deltaX;
10144
+ resizeHelperY = selectedHandle.startPos.y + deltaY;
10145
+ resizeHelperX = resizeHelperX > 0 ? resizeHelperX : 0;
10146
+ resizeHelperY = resizeHelperY > 0 ? resizeHelperY : 0;
10147
+ dom.setStyles(resizeHelper, {
10148
+ left: resizeHelperX,
10149
+ top: resizeHelperY,
10150
+ display: 'block'
10371
10151
  });
10372
- }
10373
- return normalized && container ? Optional.some(CaretPosition(container, offset)) : Optional.none();
10374
- };
10375
- const normalize$2 = (dom, rng) => {
10376
- const collapsed = rng.collapsed, normRng = rng.cloneRange();
10377
- const startPos = CaretPosition.fromRangeStart(rng);
10378
- normalizeEndPoint(dom, collapsed, true, normRng).each(pos => {
10379
- if (!collapsed || !CaretPosition.isAbove(startPos, pos)) {
10380
- normRng.setStart(pos.container(), pos.offset());
10152
+ resizeHelper.innerHTML = width + ' &times; ' + height;
10153
+ if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) {
10154
+ dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width));
10381
10155
  }
10382
- });
10383
- if (!collapsed) {
10384
- normalizeEndPoint(dom, collapsed, false, normRng).each(pos => {
10385
- normRng.setEnd(pos.container(), pos.offset());
10386
- });
10387
- }
10388
- if (collapsed) {
10389
- normRng.collapse(true);
10390
- }
10391
- return isEq$4(rng, normRng) ? Optional.none() : Optional.some(normRng);
10392
- };
10393
-
10394
- const splitText = (node, offset) => {
10395
- return node.splitText(offset);
10396
- };
10397
- const split = rng => {
10398
- let startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;
10399
- if (startContainer === endContainer && isText$b(startContainer)) {
10400
- if (startOffset > 0 && startOffset < startContainer.data.length) {
10401
- endContainer = splitText(startContainer, startOffset);
10402
- startContainer = endContainer.previousSibling;
10403
- if (endOffset > startOffset) {
10404
- endOffset = endOffset - startOffset;
10405
- const newContainer = splitText(endContainer, endOffset).previousSibling;
10406
- startContainer = endContainer = newContainer;
10407
- endOffset = newContainer.data.length;
10408
- startOffset = 0;
10409
- } else {
10410
- endOffset = 0;
10411
- }
10156
+ if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) {
10157
+ dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height));
10412
10158
  }
10413
- } else {
10414
- if (isText$b(startContainer) && startOffset > 0 && startOffset < startContainer.data.length) {
10415
- startContainer = splitText(startContainer, startOffset);
10416
- startOffset = 0;
10159
+ deltaX = rootElement.scrollWidth - startScrollWidth;
10160
+ deltaY = rootElement.scrollHeight - startScrollHeight;
10161
+ if (deltaX + deltaY !== 0) {
10162
+ dom.setStyles(resizeHelper, {
10163
+ left: resizeHelperX - deltaX,
10164
+ top: resizeHelperY - deltaY
10165
+ });
10417
10166
  }
10418
- if (isText$b(endContainer) && endOffset > 0 && endOffset < endContainer.data.length) {
10419
- const newContainer = splitText(endContainer, endOffset).previousSibling;
10420
- endContainer = newContainer;
10421
- endOffset = newContainer.data.length;
10167
+ if (!resizeStarted) {
10168
+ fireObjectResizeStart(editor, selectedElm, startW, startH, 'corner-' + selectedHandle.name);
10169
+ resizeStarted = true;
10422
10170
  }
10423
- }
10424
- return {
10425
- startContainer,
10426
- startOffset,
10427
- endContainer,
10428
- endOffset
10429
- };
10430
- };
10431
-
10432
- const RangeUtils = dom => {
10433
- const walk = (rng, callback) => {
10434
- return walk$3(dom, rng, callback);
10435
10171
  };
10436
- const split$1 = split;
10437
- const normalize = rng => {
10438
- return normalize$2(dom, rng).fold(never, normalizedRng => {
10439
- rng.setStart(normalizedRng.startContainer, normalizedRng.startOffset);
10440
- rng.setEnd(normalizedRng.endContainer, normalizedRng.endOffset);
10441
- return true;
10442
- });
10172
+ const endGhostResize = () => {
10173
+ const wasResizeStarted = resizeStarted;
10174
+ resizeStarted = false;
10175
+ if (wasResizeStarted) {
10176
+ setSizeProp(selectedElm, 'width', width);
10177
+ setSizeProp(selectedElm, 'height', height);
10178
+ }
10179
+ dom.unbind(editableDoc, 'mousemove', resizeGhostElement);
10180
+ dom.unbind(editableDoc, 'mouseup', endGhostResize);
10181
+ if (rootDocument !== editableDoc) {
10182
+ dom.unbind(rootDocument, 'mousemove', resizeGhostElement);
10183
+ dom.unbind(rootDocument, 'mouseup', endGhostResize);
10184
+ }
10185
+ dom.remove(selectedElmGhost);
10186
+ dom.remove(resizeHelper);
10187
+ dom.remove(resizeBackdrop);
10188
+ showResizeRect(selectedElm);
10189
+ if (wasResizeStarted) {
10190
+ fireObjectResized(editor, selectedElm, width, height, 'corner-' + selectedHandle.name);
10191
+ dom.setAttrib(selectedElm, 'style', dom.getAttrib(selectedElm, 'style'));
10192
+ }
10193
+ editor.nodeChanged();
10443
10194
  };
10444
- const expand = (rng, options = { type: 'word' }) => {
10445
- if (options.type === 'word') {
10446
- const rangeLike = expandRng(dom, rng, [{ inline: 'span' }]);
10447
- const newRange = dom.createRng();
10448
- newRange.setStart(rangeLike.startContainer, rangeLike.startOffset);
10449
- newRange.setEnd(rangeLike.endContainer, rangeLike.endOffset);
10450
- return newRange;
10195
+ const showResizeRect = targetElm => {
10196
+ unbindResizeHandleEvents();
10197
+ const position = dom.getPos(targetElm, rootElement);
10198
+ const selectedElmX = position.x;
10199
+ const selectedElmY = position.y;
10200
+ const rect = targetElm.getBoundingClientRect();
10201
+ const targetWidth = rect.width || rect.right - rect.left;
10202
+ const targetHeight = rect.height || rect.bottom - rect.top;
10203
+ if (selectedElm !== targetElm) {
10204
+ hideResizeRect();
10205
+ selectedElm = targetElm;
10206
+ width = height = 0;
10207
+ }
10208
+ const e = editor.dispatch('ObjectSelected', { target: targetElm });
10209
+ if (isResizable(targetElm) && !e.isDefaultPrevented()) {
10210
+ each$d(resizeHandles, (handle, name) => {
10211
+ const startDrag = e => {
10212
+ const target = getResizeTargets(selectedElm)[0];
10213
+ startX = e.screenX;
10214
+ startY = e.screenY;
10215
+ startW = target.clientWidth;
10216
+ startH = target.clientHeight;
10217
+ ratio = startH / startW;
10218
+ selectedHandle = handle;
10219
+ selectedHandle.name = name;
10220
+ selectedHandle.startPos = {
10221
+ x: targetWidth * handle[0] + selectedElmX,
10222
+ y: targetHeight * handle[1] + selectedElmY
10223
+ };
10224
+ startScrollWidth = rootElement.scrollWidth;
10225
+ startScrollHeight = rootElement.scrollHeight;
10226
+ resizeBackdrop = dom.add(rootElement, 'div', {
10227
+ 'class': 'mce-resize-backdrop',
10228
+ 'data-mce-bogus': 'all'
10229
+ });
10230
+ dom.setStyles(resizeBackdrop, {
10231
+ position: 'fixed',
10232
+ left: '0',
10233
+ top: '0',
10234
+ width: '100%',
10235
+ height: '100%'
10236
+ });
10237
+ selectedElmGhost = createGhostElement(dom, selectedElm);
10238
+ dom.addClass(selectedElmGhost, 'mce-clonedresizable');
10239
+ dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all');
10240
+ selectedElmGhost.contentEditable = 'false';
10241
+ dom.setStyles(selectedElmGhost, {
10242
+ left: selectedElmX,
10243
+ top: selectedElmY,
10244
+ margin: 0
10245
+ });
10246
+ setGhostElmSize(selectedElmGhost, targetWidth, targetHeight);
10247
+ selectedElmGhost.removeAttribute(elementSelectionAttr);
10248
+ rootElement.appendChild(selectedElmGhost);
10249
+ dom.bind(editableDoc, 'mousemove', resizeGhostElement);
10250
+ dom.bind(editableDoc, 'mouseup', endGhostResize);
10251
+ if (rootDocument !== editableDoc) {
10252
+ dom.bind(rootDocument, 'mousemove', resizeGhostElement);
10253
+ dom.bind(rootDocument, 'mouseup', endGhostResize);
10254
+ }
10255
+ resizeHelper = dom.add(rootElement, 'div', {
10256
+ 'class': 'mce-resize-helper',
10257
+ 'data-mce-bogus': 'all'
10258
+ }, startW + ' &times; ' + startH);
10259
+ };
10260
+ let handleElm = dom.get('mceResizeHandle' + name);
10261
+ if (handleElm) {
10262
+ dom.remove(handleElm);
10263
+ }
10264
+ handleElm = dom.add(rootElement, 'div', {
10265
+ 'id': 'mceResizeHandle' + name,
10266
+ 'data-mce-bogus': 'all',
10267
+ 'class': 'mce-resizehandle',
10268
+ 'unselectable': true,
10269
+ 'style': 'cursor:' + name + '-resize; margin:0; padding:0'
10270
+ });
10271
+ dom.bind(handleElm, 'mousedown', e => {
10272
+ e.stopImmediatePropagation();
10273
+ e.preventDefault();
10274
+ startDrag(e);
10275
+ });
10276
+ handle.elm = handleElm;
10277
+ dom.setStyles(handleElm, {
10278
+ left: targetWidth * handle[0] + selectedElmX - handleElm.offsetWidth / 2,
10279
+ top: targetHeight * handle[1] + selectedElmY - handleElm.offsetHeight / 2
10280
+ });
10281
+ });
10282
+ } else {
10283
+ hideResizeRect(false);
10451
10284
  }
10452
- return rng;
10453
10285
  };
10454
- return {
10455
- walk,
10456
- split: split$1,
10457
- expand,
10458
- normalize
10286
+ const throttledShowResizeRect = first$1(showResizeRect, 0);
10287
+ const hideResizeRect = (removeSelected = true) => {
10288
+ throttledShowResizeRect.cancel();
10289
+ unbindResizeHandleEvents();
10290
+ if (selectedElm && removeSelected) {
10291
+ selectedElm.removeAttribute(elementSelectionAttr);
10292
+ }
10293
+ each$d(resizeHandles, (value, name) => {
10294
+ const handleElm = dom.get('mceResizeHandle' + name);
10295
+ if (handleElm) {
10296
+ dom.unbind(handleElm);
10297
+ dom.remove(handleElm);
10298
+ }
10299
+ });
10459
10300
  };
10460
- };
10461
- RangeUtils.compareRanges = isEq$4;
10462
- RangeUtils.getCaretRangeFromPoint = fromPoint;
10463
- RangeUtils.getSelectedNode = getSelectedNode;
10464
- RangeUtils.getNode = getNode$1;
10465
-
10466
- const Dimension = (name, getOffset) => {
10467
- const set = (element, h) => {
10468
- if (!isNumber(h) && !h.match(/^[0-9]+$/)) {
10469
- throw new Error(name + '.set accepts only positive integer values. Value was ' + h);
10301
+ const isChildOrEqual = (node, parent) => dom.isChildOf(node, parent);
10302
+ const updateResizeRect = e => {
10303
+ if (resizeStarted || editor.removed || editor.composing) {
10304
+ return;
10470
10305
  }
10471
- const dom = element.dom;
10472
- if (isSupported(dom)) {
10473
- dom.style[name] = h + 'px';
10306
+ const targetElm = e.type === 'mousedown' ? e.target : selection.getNode();
10307
+ const controlElm = closest$3(SugarElement.fromDom(targetElm), controlElmSelector).map(e => e.dom).filter(e => dom.isEditable(e.parentElement) || e.nodeName === 'IMG' && dom.isEditable(e)).getOrUndefined();
10308
+ const selectedValue = isNonNullable(controlElm) ? dom.getAttrib(controlElm, elementSelectionAttr, '1') : '1';
10309
+ each$e(dom.select(`img[${ elementSelectionAttr }],hr[${ elementSelectionAttr }]`), img => {
10310
+ img.removeAttribute(elementSelectionAttr);
10311
+ });
10312
+ if (isNonNullable(controlElm) && isChildOrEqual(controlElm, rootElement) && hasEditorOrUiFocus(editor)) {
10313
+ disableGeckoResize();
10314
+ const startElm = selection.getStart(true);
10315
+ if (isChildOrEqual(startElm, controlElm) && isChildOrEqual(selection.getEnd(true), controlElm)) {
10316
+ dom.setAttrib(controlElm, elementSelectionAttr, selectedValue);
10317
+ throttledShowResizeRect.throttle(controlElm);
10318
+ return;
10319
+ }
10474
10320
  }
10321
+ hideResizeRect();
10475
10322
  };
10476
- const get = element => {
10477
- const r = getOffset(element);
10478
- if (r <= 0 || r === null) {
10479
- const css = get$7(element, name);
10480
- return parseFloat(css) || 0;
10323
+ const unbindResizeHandleEvents = () => {
10324
+ each$d(resizeHandles, handle => {
10325
+ if (handle.elm) {
10326
+ dom.unbind(handle.elm);
10327
+ delete handle.elm;
10328
+ }
10329
+ });
10330
+ };
10331
+ const disableGeckoResize = () => {
10332
+ try {
10333
+ editor.getDoc().execCommand('enableObjectResizing', false, 'false');
10334
+ } catch (ex) {
10481
10335
  }
10482
- return r;
10483
10336
  };
10484
- const getOuter = get;
10485
- const aggregate = (element, properties) => foldl(properties, (acc, property) => {
10486
- const val = get$7(element, property);
10487
- const value = val === undefined ? 0 : parseInt(val, 10);
10488
- return isNaN(value) ? acc : acc + value;
10489
- }, 0);
10490
- const max = (element, value, properties) => {
10491
- const cumulativeInclusions = aggregate(element, properties);
10492
- const absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;
10493
- return absoluteMax;
10337
+ editor.on('init', () => {
10338
+ disableGeckoResize();
10339
+ editor.on('NodeChange ResizeEditor ResizeWindow ResizeContent drop', updateResizeRect);
10340
+ editor.on('keyup compositionend', e => {
10341
+ if (selectedElm && selectedElm.nodeName === 'TABLE') {
10342
+ updateResizeRect(e);
10343
+ }
10344
+ });
10345
+ editor.on('hide blur', hideResizeRect);
10346
+ editor.on('contextmenu longpress', contextMenuSelectImage, true);
10347
+ });
10348
+ editor.on('remove', unbindResizeHandleEvents);
10349
+ const destroy = () => {
10350
+ throttledShowResizeRect.cancel();
10351
+ selectedElm = selectedElmGhost = resizeBackdrop = null;
10494
10352
  };
10495
10353
  return {
10496
- set,
10497
- get,
10498
- getOuter,
10499
- aggregate,
10500
- max
10354
+ isResizable,
10355
+ showResizeRect,
10356
+ hideResizeRect,
10357
+ updateResizeRect,
10358
+ destroy
10501
10359
  };
10502
10360
  };
10503
10361
 
10504
- const api = Dimension('height', element => {
10505
- const dom = element.dom;
10506
- return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;
10507
- });
10508
- const get$2 = element => api.get(element);
10509
-
10510
- const getDocument = () => SugarElement.fromDom(document);
10511
-
10512
- const walkUp = (navigation, doc) => {
10513
- const frame = navigation.view(doc);
10514
- return frame.fold(constant([]), f => {
10515
- const parent = navigation.owner(f);
10516
- const rest = walkUp(navigation, parent);
10517
- return [f].concat(rest);
10518
- });
10519
- };
10520
- const pathTo = (element, navigation) => {
10521
- const d = navigation.owner(element);
10522
- return walkUp(navigation, d);
10523
- };
10524
-
10525
- const view = doc => {
10526
- var _a;
10527
- const element = doc.dom === document ? Optional.none() : Optional.from((_a = doc.dom.defaultView) === null || _a === void 0 ? void 0 : _a.frameElement);
10528
- return element.map(SugarElement.fromDom);
10529
- };
10530
- const owner = element => documentOrOwner(element);
10531
-
10532
- var Navigation = /*#__PURE__*/Object.freeze({
10533
- __proto__: null,
10534
- view: view,
10535
- owner: owner
10536
- });
10537
-
10538
- const find = element => {
10539
- const doc = getDocument();
10540
- const scroll = get$5(doc);
10541
- const frames = pathTo(element, Navigation);
10542
- const offset = viewport(element);
10543
- const r = foldr(frames, (b, a) => {
10544
- const loc = viewport(a);
10545
- return {
10546
- left: b.left + loc.left,
10547
- top: b.top + loc.top
10548
- };
10549
- }, {
10550
- left: 0,
10551
- top: 0
10552
- });
10553
- return SugarPosition(r.left + offset.left + scroll.left, r.top + offset.top + scroll.top);
10554
- };
10555
-
10556
- const excludeFromDescend = element => name(element) === 'textarea';
10557
- const fireScrollIntoViewEvent = (editor, data) => {
10558
- const scrollEvent = editor.dispatch('ScrollIntoView', data);
10559
- return scrollEvent.isDefaultPrevented();
10560
- };
10561
- const fireAfterScrollIntoViewEvent = (editor, data) => {
10562
- editor.dispatch('AfterScrollIntoView', data);
10563
- };
10564
- const descend = (element, offset) => {
10565
- const children = children$1(element);
10566
- if (children.length === 0 || excludeFromDescend(element)) {
10567
- return {
10568
- element,
10569
- offset
10570
- };
10571
- } else if (offset < children.length && !excludeFromDescend(children[offset])) {
10572
- return {
10573
- element: children[offset],
10574
- offset: 0
10575
- };
10576
- } else {
10577
- const last = children[children.length - 1];
10578
- if (excludeFromDescend(last)) {
10579
- return {
10580
- element,
10581
- offset
10582
- };
10583
- } else {
10584
- if (name(last) === 'img') {
10585
- return {
10586
- element: last,
10587
- offset: 1
10588
- };
10589
- } else if (isText$c(last)) {
10590
- return {
10591
- element: last,
10592
- offset: get$3(last).length
10593
- };
10594
- } else {
10595
- return {
10596
- element: last,
10597
- offset: children$1(last).length
10598
- };
10599
- }
10600
- }
10601
- }
10602
- };
10603
- const markerInfo = (element, cleanupFun) => {
10604
- const pos = absolute(element);
10605
- const height = get$2(element);
10606
- return {
10607
- element,
10608
- bottom: pos.top + height,
10609
- height,
10610
- pos,
10611
- cleanup: cleanupFun
10612
- };
10613
- };
10614
- const createMarker$1 = (element, offset) => {
10615
- const startPoint = descend(element, offset);
10616
- const span = SugarElement.fromHtml('<span data-mce-bogus="all" style="display: inline-block;">' + ZWSP$1 + '</span>');
10617
- before$3(startPoint.element, span);
10618
- return markerInfo(span, () => remove$4(span));
10619
- };
10620
- const elementMarker = element => markerInfo(SugarElement.fromDom(element), noop);
10621
- const withMarker = (editor, f, rng, alignToTop) => {
10622
- preserveWith(editor, (_s, _e) => applyWithMarker(editor, f, rng, alignToTop), rng);
10623
- };
10624
- const withScrollEvents = (editor, doc, f, marker, alignToTop) => {
10625
- const data = {
10626
- elm: marker.element.dom,
10627
- alignToTop
10628
- };
10629
- if (fireScrollIntoViewEvent(editor, data)) {
10630
- return;
10631
- }
10632
- const scrollTop = get$5(doc).top;
10633
- f(editor, doc, scrollTop, marker, alignToTop);
10634
- fireAfterScrollIntoViewEvent(editor, data);
10362
+ const setStart = (rng, situ) => {
10363
+ situ.fold(e => {
10364
+ rng.setStartBefore(e.dom);
10365
+ }, (e, o) => {
10366
+ rng.setStart(e.dom, o);
10367
+ }, e => {
10368
+ rng.setStartAfter(e.dom);
10369
+ });
10635
10370
  };
10636
- const applyWithMarker = (editor, f, rng, alignToTop) => {
10637
- const body = SugarElement.fromDom(editor.getBody());
10638
- const doc = SugarElement.fromDom(editor.getDoc());
10639
- reflow(body);
10640
- const marker = createMarker$1(SugarElement.fromDom(rng.startContainer), rng.startOffset);
10641
- withScrollEvents(editor, doc, f, marker, alignToTop);
10642
- marker.cleanup();
10371
+ const setFinish = (rng, situ) => {
10372
+ situ.fold(e => {
10373
+ rng.setEndBefore(e.dom);
10374
+ }, (e, o) => {
10375
+ rng.setEnd(e.dom, o);
10376
+ }, e => {
10377
+ rng.setEndAfter(e.dom);
10378
+ });
10643
10379
  };
10644
- const withElement = (editor, element, f, alignToTop) => {
10645
- const doc = SugarElement.fromDom(editor.getDoc());
10646
- withScrollEvents(editor, doc, f, elementMarker(element), alignToTop);
10380
+ const relativeToNative = (win, startSitu, finishSitu) => {
10381
+ const range = win.document.createRange();
10382
+ setStart(range, startSitu);
10383
+ setFinish(range, finishSitu);
10384
+ return range;
10647
10385
  };
10648
- const preserveWith = (editor, f, rng) => {
10649
- const startElement = rng.startContainer;
10650
- const startOffset = rng.startOffset;
10651
- const endElement = rng.endContainer;
10652
- const endOffset = rng.endOffset;
10653
- f(SugarElement.fromDom(startElement), SugarElement.fromDom(endElement));
10654
- const newRng = editor.dom.createRng();
10655
- newRng.setStart(startElement, startOffset);
10656
- newRng.setEnd(endElement, endOffset);
10657
- editor.selection.setRng(rng);
10386
+ const exactToNative = (win, start, soffset, finish, foffset) => {
10387
+ const rng = win.document.createRange();
10388
+ rng.setStart(start.dom, soffset);
10389
+ rng.setEnd(finish.dom, foffset);
10390
+ return rng;
10658
10391
  };
10659
- const scrollToMarker = (editor, marker, viewHeight, alignToTop, doc) => {
10660
- const pos = marker.pos;
10661
- if (alignToTop) {
10662
- to(pos.left, pos.top, doc);
10663
- } else {
10664
- const y = pos.top - viewHeight + marker.height;
10665
- to(-editor.getBody().getBoundingClientRect().left, y, doc);
10392
+
10393
+ const adt$1 = Adt.generate([
10394
+ {
10395
+ ltr: [
10396
+ 'start',
10397
+ 'soffset',
10398
+ 'finish',
10399
+ 'foffset'
10400
+ ]
10401
+ },
10402
+ {
10403
+ rtl: [
10404
+ 'start',
10405
+ 'soffset',
10406
+ 'finish',
10407
+ 'foffset'
10408
+ ]
10666
10409
  }
10667
- };
10668
- const intoWindowIfNeeded = (editor, doc, scrollTop, viewHeight, marker, alignToTop) => {
10669
- const viewportBottom = viewHeight + scrollTop;
10670
- const markerTop = marker.pos.top;
10671
- const markerBottom = marker.bottom;
10672
- const largerThanViewport = markerBottom - markerTop >= viewHeight;
10673
- if (markerTop < scrollTop) {
10674
- scrollToMarker(editor, marker, viewHeight, alignToTop !== false, doc);
10675
- } else if (markerTop > viewportBottom) {
10676
- const align = largerThanViewport ? alignToTop !== false : alignToTop === true;
10677
- scrollToMarker(editor, marker, viewHeight, align, doc);
10678
- } else if (markerBottom > viewportBottom && !largerThanViewport) {
10679
- scrollToMarker(editor, marker, viewHeight, alignToTop === true, doc);
10410
+ ]);
10411
+ const fromRange = (win, type, range) => type(SugarElement.fromDom(range.startContainer), range.startOffset, SugarElement.fromDom(range.endContainer), range.endOffset);
10412
+ const getRanges = (win, selection) => selection.match({
10413
+ domRange: rng => {
10414
+ return {
10415
+ ltr: constant(rng),
10416
+ rtl: Optional.none
10417
+ };
10418
+ },
10419
+ relative: (startSitu, finishSitu) => {
10420
+ return {
10421
+ ltr: cached(() => relativeToNative(win, startSitu, finishSitu)),
10422
+ rtl: cached(() => Optional.some(relativeToNative(win, finishSitu, startSitu)))
10423
+ };
10424
+ },
10425
+ exact: (start, soffset, finish, foffset) => {
10426
+ return {
10427
+ ltr: cached(() => exactToNative(win, start, soffset, finish, foffset)),
10428
+ rtl: cached(() => Optional.some(exactToNative(win, finish, foffset, start, soffset)))
10429
+ };
10680
10430
  }
10681
- };
10682
- const intoWindow = (editor, doc, scrollTop, marker, alignToTop) => {
10683
- const viewHeight = defaultView(doc).dom.innerHeight;
10684
- intoWindowIfNeeded(editor, doc, scrollTop, viewHeight, marker, alignToTop);
10685
- };
10686
- const intoFrame = (editor, doc, scrollTop, marker, alignToTop) => {
10687
- const frameViewHeight = defaultView(doc).dom.innerHeight;
10688
- intoWindowIfNeeded(editor, doc, scrollTop, frameViewHeight, marker, alignToTop);
10689
- const op = find(marker.element);
10690
- const viewportBounds = getBounds(window);
10691
- if (op.top < viewportBounds.y) {
10692
- intoView(marker.element, alignToTop !== false);
10693
- } else if (op.top > viewportBounds.bottom) {
10694
- intoView(marker.element, alignToTop === true);
10431
+ });
10432
+ const doDiagnose = (win, ranges) => {
10433
+ const rng = ranges.ltr();
10434
+ if (rng.collapsed) {
10435
+ const reversed = ranges.rtl().filter(rev => rev.collapsed === false);
10436
+ return reversed.map(rev => adt$1.rtl(SugarElement.fromDom(rev.endContainer), rev.endOffset, SugarElement.fromDom(rev.startContainer), rev.startOffset)).getOrThunk(() => fromRange(win, adt$1.ltr, rng));
10437
+ } else {
10438
+ return fromRange(win, adt$1.ltr, rng);
10695
10439
  }
10696
10440
  };
10697
- const rangeIntoWindow = (editor, rng, alignToTop) => withMarker(editor, intoWindow, rng, alignToTop);
10698
- const elementIntoWindow = (editor, element, alignToTop) => withElement(editor, element, intoWindow, alignToTop);
10699
- const rangeIntoFrame = (editor, rng, alignToTop) => withMarker(editor, intoFrame, rng, alignToTop);
10700
- const elementIntoFrame = (editor, element, alignToTop) => withElement(editor, element, intoFrame, alignToTop);
10701
- const scrollElementIntoView = (editor, element, alignToTop) => {
10702
- const scroller = editor.inline ? elementIntoWindow : elementIntoFrame;
10703
- scroller(editor, element, alignToTop);
10704
- };
10705
- const scrollRangeIntoView = (editor, rng, alignToTop) => {
10706
- const scroller = editor.inline ? rangeIntoWindow : rangeIntoFrame;
10707
- scroller(editor, rng, alignToTop);
10708
- };
10709
-
10710
- const focus$1 = (element, preventScroll = false) => element.dom.focus({ preventScroll });
10711
- const hasFocus$1 = element => {
10712
- const root = getRootNode(element).dom;
10713
- return element.dom === root.activeElement;
10441
+ const diagnose = (win, selection) => {
10442
+ const ranges = getRanges(win, selection);
10443
+ return doDiagnose(win, ranges);
10714
10444
  };
10715
- const active$1 = (root = getDocument()) => Optional.from(root.dom.activeElement).map(SugarElement.fromDom);
10716
- const search = element => active$1(getRootNode(element)).filter(e => element.dom.contains(e.dom));
10445
+ adt$1.ltr;
10446
+ adt$1.rtl;
10717
10447
 
10718
- const clamp$1 = (offset, element) => {
10719
- const max = isText$c(element) ? get$3(element).length : children$1(element).length + 1;
10720
- if (offset > max) {
10721
- return max;
10722
- } else if (offset < 0) {
10723
- return 0;
10724
- }
10725
- return offset;
10726
- };
10727
- const normalizeRng = rng => SimSelection.range(rng.start, clamp$1(rng.soffset, rng.start), rng.finish, clamp$1(rng.foffset, rng.finish));
10728
- const isOrContains = (root, elm) => !isRestrictedNode(elm.dom) && (contains(root, elm) || eq(root, elm));
10729
- const isRngInRoot = root => rng => isOrContains(root, rng.start) && isOrContains(root, rng.finish);
10730
- const shouldStore = editor => editor.inline || Env.browser.isFirefox();
10731
- const nativeRangeToSelectionRange = r => SimSelection.range(SugarElement.fromDom(r.startContainer), r.startOffset, SugarElement.fromDom(r.endContainer), r.endOffset);
10732
- const readRange = win => {
10733
- const selection = win.getSelection();
10734
- const rng = !selection || selection.rangeCount === 0 ? Optional.none() : Optional.from(selection.getRangeAt(0));
10735
- return rng.map(nativeRangeToSelectionRange);
10448
+ const caretPositionFromPoint = (doc, x, y) => {
10449
+ var _a;
10450
+ return Optional.from((_a = doc.caretPositionFromPoint) === null || _a === void 0 ? void 0 : _a.call(doc, x, y)).bind(pos => {
10451
+ if (pos.offsetNode === null) {
10452
+ return Optional.none();
10453
+ }
10454
+ const r = doc.createRange();
10455
+ r.setStart(pos.offsetNode, pos.offset);
10456
+ r.collapse();
10457
+ return Optional.some(r);
10458
+ });
10736
10459
  };
10737
- const getBookmark$1 = root => {
10738
- const win = defaultView(root);
10739
- return readRange(win.dom).filter(isRngInRoot(root));
10460
+ const caretRangeFromPoint = (doc, x, y) => {
10461
+ var _a;
10462
+ return Optional.from((_a = doc.caretRangeFromPoint) === null || _a === void 0 ? void 0 : _a.call(doc, x, y));
10740
10463
  };
10741
- const validate = (root, bookmark) => Optional.from(bookmark).filter(isRngInRoot(root)).map(normalizeRng);
10742
- const bookmarkToNativeRng = bookmark => {
10743
- const rng = document.createRange();
10744
- try {
10745
- rng.setStart(bookmark.start.dom, bookmark.soffset);
10746
- rng.setEnd(bookmark.finish.dom, bookmark.foffset);
10747
- return Optional.some(rng);
10748
- } catch (_) {
10464
+ const availableSearch = (doc, x, y) => {
10465
+ if (doc.caretPositionFromPoint) {
10466
+ return caretPositionFromPoint(doc, x, y);
10467
+ } else if (doc.caretRangeFromPoint) {
10468
+ return caretRangeFromPoint(doc, x, y);
10469
+ } else {
10749
10470
  return Optional.none();
10750
10471
  }
10751
10472
  };
10752
- const store = editor => {
10753
- const newBookmark = shouldStore(editor) ? getBookmark$1(SugarElement.fromDom(editor.getBody())) : Optional.none();
10754
- editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;
10755
- };
10756
- const getRng = editor => {
10757
- const bookmark = editor.bookmark ? editor.bookmark : Optional.none();
10758
- return bookmark.bind(x => validate(SugarElement.fromDom(editor.getBody()), x)).bind(bookmarkToNativeRng);
10759
- };
10760
- const restore = editor => {
10761
- getRng(editor).each(rng => editor.selection.setRng(rng));
10762
- };
10763
-
10764
- const isEditorUIElement$1 = elm => {
10765
- const className = elm.className.toString();
10766
- return className.indexOf('tox-') !== -1 || className.indexOf('mce-') !== -1;
10473
+ const fromPoint$1 = (win, x, y) => {
10474
+ const doc = win.document;
10475
+ return availableSearch(doc, x, y).map(rng => SimRange.create(SugarElement.fromDom(rng.startContainer), rng.startOffset, SugarElement.fromDom(rng.endContainer), rng.endOffset));
10767
10476
  };
10768
- const FocusManager = { isEditorUIElement: isEditorUIElement$1 };
10769
10477
 
10770
- const wrappedSetTimeout = (callback, time) => {
10771
- if (!isNumber(time)) {
10772
- time = 0;
10478
+ const beforeSpecial = (element, offset) => {
10479
+ const name$1 = name(element);
10480
+ if ('input' === name$1) {
10481
+ return Situ.after(element);
10482
+ } else if (!contains$2([
10483
+ 'br',
10484
+ 'img'
10485
+ ], name$1)) {
10486
+ return Situ.on(element, offset);
10487
+ } else {
10488
+ return offset === 0 ? Situ.before(element) : Situ.after(element);
10773
10489
  }
10774
- return setTimeout(callback, time);
10775
10490
  };
10776
- const wrappedSetInterval = (callback, time) => {
10777
- if (!isNumber(time)) {
10778
- time = 0;
10779
- }
10780
- return setInterval(callback, time);
10491
+ const preprocessRelative = (startSitu, finishSitu) => {
10492
+ const start = startSitu.fold(Situ.before, beforeSpecial, Situ.after);
10493
+ const finish = finishSitu.fold(Situ.before, beforeSpecial, Situ.after);
10494
+ return SimSelection.relative(start, finish);
10781
10495
  };
10782
- const Delay = {
10783
- setEditorTimeout: (editor, callback, time) => {
10784
- return wrappedSetTimeout(() => {
10785
- if (!editor.removed) {
10786
- callback();
10787
- }
10788
- }, time);
10789
- },
10790
- setEditorInterval: (editor, callback, time) => {
10791
- const timer = wrappedSetInterval(() => {
10792
- if (!editor.removed) {
10793
- callback();
10794
- } else {
10795
- clearInterval(timer);
10796
- }
10797
- }, time);
10798
- return timer;
10799
- }
10496
+ const preprocessExact = (start, soffset, finish, foffset) => {
10497
+ const startSitu = beforeSpecial(start, soffset);
10498
+ const finishSitu = beforeSpecial(finish, foffset);
10499
+ return SimSelection.relative(startSitu, finishSitu);
10800
10500
  };
10501
+ const preprocess = selection => selection.match({
10502
+ domRange: rng => {
10503
+ const start = SugarElement.fromDom(rng.startContainer);
10504
+ const finish = SugarElement.fromDom(rng.endContainer);
10505
+ return preprocessExact(start, rng.startOffset, finish, rng.endOffset);
10506
+ },
10507
+ relative: preprocessRelative,
10508
+ exact: preprocessExact
10509
+ });
10801
10510
 
10802
- const isManualNodeChange = e => {
10803
- return e.type === 'nodechange' && e.selectionChange;
10804
- };
10805
- const registerPageMouseUp = (editor, throttledStore) => {
10806
- const mouseUpPage = () => {
10807
- throttledStore.throttle();
10808
- };
10809
- DOMUtils.DOM.bind(document, 'mouseup', mouseUpPage);
10810
- editor.on('remove', () => {
10811
- DOMUtils.DOM.unbind(document, 'mouseup', mouseUpPage);
10511
+ const fromElements = (elements, scope) => {
10512
+ const doc = scope || document;
10513
+ const fragment = doc.createDocumentFragment();
10514
+ each$e(elements, element => {
10515
+ fragment.appendChild(element.dom);
10812
10516
  });
10517
+ return SugarElement.fromDom(fragment);
10813
10518
  };
10814
- const registerMouseUp = (editor, throttledStore) => {
10815
- editor.on('mouseup touchend', _e => {
10816
- throttledStore.throttle();
10519
+
10520
+ const toNative = selection => {
10521
+ const win = SimSelection.getWin(selection).dom;
10522
+ const getDomRange = (start, soffset, finish, foffset) => exactToNative(win, start, soffset, finish, foffset);
10523
+ const filtered = preprocess(selection);
10524
+ return diagnose(win, filtered).match({
10525
+ ltr: getDomRange,
10526
+ rtl: getDomRange
10817
10527
  });
10818
10528
  };
10819
- const registerEditorEvents = (editor, throttledStore) => {
10820
- registerMouseUp(editor, throttledStore);
10821
- editor.on('keyup NodeChange AfterSetSelectionRange', e => {
10822
- if (!isManualNodeChange(e)) {
10823
- store(editor);
10824
- }
10825
- });
10529
+ const getAtPoint = (win, x, y) => fromPoint$1(win, x, y);
10530
+
10531
+ const fromPoint = (clientX, clientY, doc) => {
10532
+ const win = defaultView(SugarElement.fromDom(doc));
10533
+ return getAtPoint(win.dom, clientX, clientY).map(simRange => {
10534
+ const rng = doc.createRange();
10535
+ rng.setStart(simRange.start.dom, simRange.soffset);
10536
+ rng.setEnd(simRange.finish.dom, simRange.foffset);
10537
+ return rng;
10538
+ }).getOrUndefined();
10826
10539
  };
10827
- const register$6 = editor => {
10828
- const throttledStore = first$1(() => {
10829
- store(editor);
10830
- }, 0);
10831
- editor.on('init', () => {
10832
- if (editor.inline) {
10833
- registerPageMouseUp(editor, throttledStore);
10834
- }
10835
- registerEditorEvents(editor, throttledStore);
10836
- });
10837
- editor.on('remove', () => {
10838
- throttledStore.cancel();
10839
- });
10540
+
10541
+ const isEq$4 = (rng1, rng2) => {
10542
+ return isNonNullable(rng1) && isNonNullable(rng2) && (rng1.startContainer === rng2.startContainer && rng1.startOffset === rng2.startOffset) && (rng1.endContainer === rng2.endContainer && rng1.endOffset === rng2.endOffset);
10840
10543
  };
10841
10544
 
10842
- let documentFocusInHandler;
10843
- const DOM$9 = DOMUtils.DOM;
10844
- const isEditorUIElement = elm => {
10845
- return isElement$6(elm) && FocusManager.isEditorUIElement(elm);
10545
+ const findParent = (node, rootNode, predicate) => {
10546
+ let currentNode = node;
10547
+ while (currentNode && currentNode !== rootNode) {
10548
+ if (predicate(currentNode)) {
10549
+ return currentNode;
10550
+ }
10551
+ currentNode = currentNode.parentNode;
10552
+ }
10553
+ return null;
10846
10554
  };
10847
- const isEditorContentAreaElement = elm => {
10848
- const classList = elm.classList;
10849
- if (classList !== undefined) {
10850
- return classList.contains('tox-edit-area') || classList.contains('tox-edit-area__iframe') || classList.contains('mce-content-body');
10851
- } else {
10852
- return false;
10555
+ const hasParent$1 = (node, rootNode, predicate) => findParent(node, rootNode, predicate) !== null;
10556
+ const hasParentWithName = (node, rootNode, name) => hasParent$1(node, rootNode, node => node.nodeName === name);
10557
+ const isCeFalseCaretContainer = (node, rootNode) => isCaretContainer$2(node) && !hasParent$1(node, rootNode, isCaretNode);
10558
+ const hasBrBeforeAfter = (dom, node, left) => {
10559
+ const parentNode = node.parentNode;
10560
+ if (parentNode) {
10561
+ const walker = new DomTreeWalker(node, dom.getParent(parentNode, dom.isBlock) || dom.getRoot());
10562
+ let currentNode;
10563
+ while (currentNode = walker[left ? 'prev' : 'next']()) {
10564
+ if (isBr$6(currentNode)) {
10565
+ return true;
10566
+ }
10567
+ }
10853
10568
  }
10569
+ return false;
10854
10570
  };
10855
- const isUIElement = (editor, elm) => {
10856
- const customSelector = getCustomUiSelector(editor);
10857
- const parent = DOM$9.getParent(elm, elm => {
10858
- return isEditorUIElement(elm) || (customSelector ? editor.dom.is(elm, customSelector) : false);
10859
- });
10860
- return parent !== null;
10571
+ const isPrevNode = (node, name) => {
10572
+ var _a;
10573
+ return ((_a = node.previousSibling) === null || _a === void 0 ? void 0 : _a.nodeName) === name;
10861
10574
  };
10862
- const getActiveElement = editor => {
10863
- try {
10864
- const root = getRootNode(SugarElement.fromDom(editor.getElement()));
10865
- return active$1(root).fold(() => document.body, x => x.dom);
10866
- } catch (ex) {
10867
- return document.body;
10575
+ const hasContentEditableFalseParent = (root, node) => {
10576
+ let currentNode = node;
10577
+ while (currentNode && currentNode !== root) {
10578
+ if (isContentEditableFalse$b(currentNode)) {
10579
+ return true;
10580
+ }
10581
+ currentNode = currentNode.parentNode;
10868
10582
  }
10583
+ return false;
10869
10584
  };
10870
- const registerEvents$1 = (editorManager, e) => {
10871
- const editor = e.editor;
10872
- register$6(editor);
10873
- const toggleContentAreaOnFocus = (editor, fn) => {
10874
- if (shouldHighlightOnFocus(editor) && editor.inline !== true) {
10875
- const contentArea = SugarElement.fromDom(editor.getContainer());
10876
- fn(contentArea, 'tox-edit-focus');
10585
+ const findTextNodeRelative = (dom, isAfterNode, collapsed, left, startNode) => {
10586
+ const body = dom.getRoot();
10587
+ const nonEmptyElementsMap = dom.schema.getNonEmptyElements();
10588
+ const parentNode = startNode.parentNode;
10589
+ let lastInlineElement;
10590
+ let node;
10591
+ if (!parentNode) {
10592
+ return Optional.none();
10593
+ }
10594
+ const parentBlockContainer = dom.getParent(parentNode, dom.isBlock) || body;
10595
+ if (left && isBr$6(startNode) && isAfterNode && dom.isEmpty(parentBlockContainer)) {
10596
+ return Optional.some(CaretPosition(parentNode, dom.nodeIndex(startNode)));
10597
+ }
10598
+ const walker = new DomTreeWalker(startNode, parentBlockContainer);
10599
+ while (node = walker[left ? 'prev' : 'next']()) {
10600
+ if (dom.getContentEditableParent(node) === 'false' || isCeFalseCaretContainer(node, body)) {
10601
+ return Optional.none();
10877
10602
  }
10878
- };
10879
- editor.on('focusin', () => {
10880
- const focusedEditor = editorManager.focusedEditor;
10881
- if (isEditorContentAreaElement(getActiveElement(editor))) {
10882
- toggleContentAreaOnFocus(editor, add$2);
10603
+ if (isText$b(node) && node.data.length > 0) {
10604
+ if (!hasParentWithName(node, body, 'A')) {
10605
+ return Optional.some(CaretPosition(node, left ? node.data.length : 0));
10606
+ }
10607
+ return Optional.none();
10883
10608
  }
10884
- if (focusedEditor !== editor) {
10885
- if (focusedEditor) {
10886
- focusedEditor.dispatch('blur', { focusedEditor: editor });
10609
+ if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
10610
+ return Optional.none();
10611
+ }
10612
+ lastInlineElement = node;
10613
+ }
10614
+ if (isComment(lastInlineElement)) {
10615
+ return Optional.none();
10616
+ }
10617
+ if (collapsed && lastInlineElement) {
10618
+ return Optional.some(CaretPosition(lastInlineElement, 0));
10619
+ }
10620
+ return Optional.none();
10621
+ };
10622
+ const normalizeEndPoint = (dom, collapsed, start, rng) => {
10623
+ const body = dom.getRoot();
10624
+ let node;
10625
+ let normalized = false;
10626
+ let container = start ? rng.startContainer : rng.endContainer;
10627
+ let offset = start ? rng.startOffset : rng.endOffset;
10628
+ const isAfterNode = isElement$6(container) && offset === container.childNodes.length;
10629
+ const nonEmptyElementsMap = dom.schema.getNonEmptyElements();
10630
+ let directionLeft = start;
10631
+ if (isCaretContainer$2(container)) {
10632
+ return Optional.none();
10633
+ }
10634
+ if (isElement$6(container) && offset > container.childNodes.length - 1) {
10635
+ directionLeft = false;
10636
+ }
10637
+ if (isDocument$1(container)) {
10638
+ container = body;
10639
+ offset = 0;
10640
+ }
10641
+ if (container === body) {
10642
+ if (directionLeft) {
10643
+ node = container.childNodes[offset > 0 ? offset - 1 : 0];
10644
+ if (node) {
10645
+ if (isCaretContainer$2(node)) {
10646
+ return Optional.none();
10647
+ }
10648
+ if (nonEmptyElementsMap[node.nodeName] || isTable$2(node)) {
10649
+ return Optional.none();
10650
+ }
10887
10651
  }
10888
- editorManager.setActive(editor);
10889
- editorManager.focusedEditor = editor;
10890
- editor.dispatch('focus', { blurredEditor: focusedEditor });
10891
- editor.focus(true);
10892
10652
  }
10893
- });
10894
- editor.on('focusout', () => {
10895
- Delay.setEditorTimeout(editor, () => {
10896
- const focusedEditor = editorManager.focusedEditor;
10897
- if (!isEditorContentAreaElement(getActiveElement(editor)) || focusedEditor !== editor) {
10898
- toggleContentAreaOnFocus(editor, remove$6);
10653
+ if (container.hasChildNodes()) {
10654
+ offset = Math.min(!directionLeft && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1);
10655
+ container = container.childNodes[offset];
10656
+ offset = isText$b(container) && isAfterNode ? container.data.length : 0;
10657
+ if (!collapsed && container === body.lastChild && isTable$2(container)) {
10658
+ return Optional.none();
10899
10659
  }
10900
- if (!isUIElement(editor, getActiveElement(editor)) && focusedEditor === editor) {
10901
- editor.dispatch('blur', { focusedEditor: null });
10902
- editorManager.focusedEditor = null;
10660
+ if (hasContentEditableFalseParent(body, container) || isCaretContainer$2(container)) {
10661
+ return Optional.none();
10903
10662
  }
10904
- });
10905
- });
10906
- if (!documentFocusInHandler) {
10907
- documentFocusInHandler = e => {
10908
- const activeEditor = editorManager.activeEditor;
10909
- if (activeEditor) {
10910
- getOriginalEventTarget(e).each(target => {
10911
- const elem = target;
10912
- if (elem.ownerDocument === document) {
10913
- if (elem !== document.body && !isUIElement(activeEditor, elem) && editorManager.focusedEditor === activeEditor) {
10914
- activeEditor.dispatch('blur', { focusedEditor: null });
10915
- editorManager.focusedEditor = null;
10663
+ if (isDetails(container)) {
10664
+ return Optional.none();
10665
+ }
10666
+ if (container.hasChildNodes() && !isTable$2(container)) {
10667
+ node = container;
10668
+ const walker = new DomTreeWalker(container, body);
10669
+ do {
10670
+ if (isContentEditableFalse$b(node) || isCaretContainer$2(node)) {
10671
+ normalized = false;
10672
+ break;
10673
+ }
10674
+ if (isText$b(node) && node.data.length > 0) {
10675
+ offset = directionLeft ? 0 : node.data.length;
10676
+ container = node;
10677
+ normalized = true;
10678
+ break;
10679
+ }
10680
+ if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCellOrCaption(node)) {
10681
+ offset = dom.nodeIndex(node);
10682
+ container = node.parentNode;
10683
+ if (!directionLeft) {
10684
+ offset++;
10916
10685
  }
10686
+ normalized = true;
10687
+ break;
10917
10688
  }
10689
+ } while (node = directionLeft ? walker.next() : walker.prev());
10690
+ }
10691
+ }
10692
+ }
10693
+ if (collapsed) {
10694
+ if (isText$b(container) && offset === 0) {
10695
+ findTextNodeRelative(dom, isAfterNode, collapsed, true, container).each(pos => {
10696
+ container = pos.container();
10697
+ offset = pos.offset();
10698
+ normalized = true;
10699
+ });
10700
+ }
10701
+ if (isElement$6(container)) {
10702
+ node = container.childNodes[offset];
10703
+ if (!node) {
10704
+ node = container.childNodes[offset - 1];
10705
+ }
10706
+ if (node && isBr$6(node) && !isPrevNode(node, 'A') && !hasBrBeforeAfter(dom, node, false) && !hasBrBeforeAfter(dom, node, true)) {
10707
+ findTextNodeRelative(dom, isAfterNode, collapsed, true, node).each(pos => {
10708
+ container = pos.container();
10709
+ offset = pos.offset();
10710
+ normalized = true;
10918
10711
  });
10919
10712
  }
10920
- };
10921
- DOM$9.bind(document, 'focusin', documentFocusInHandler);
10713
+ }
10714
+ }
10715
+ if (directionLeft && !collapsed && isText$b(container) && offset === container.data.length) {
10716
+ findTextNodeRelative(dom, isAfterNode, collapsed, false, container).each(pos => {
10717
+ container = pos.container();
10718
+ offset = pos.offset();
10719
+ normalized = true;
10720
+ });
10922
10721
  }
10722
+ return normalized && container ? Optional.some(CaretPosition(container, offset)) : Optional.none();
10923
10723
  };
10924
- const unregisterDocumentEvents = (editorManager, e) => {
10925
- if (editorManager.focusedEditor === e.editor) {
10926
- editorManager.focusedEditor = null;
10724
+ const normalize$2 = (dom, rng) => {
10725
+ const collapsed = rng.collapsed, normRng = rng.cloneRange();
10726
+ const startPos = CaretPosition.fromRangeStart(rng);
10727
+ normalizeEndPoint(dom, collapsed, true, normRng).each(pos => {
10728
+ if (!collapsed || !CaretPosition.isAbove(startPos, pos)) {
10729
+ normRng.setStart(pos.container(), pos.offset());
10730
+ }
10731
+ });
10732
+ if (!collapsed) {
10733
+ normalizeEndPoint(dom, collapsed, false, normRng).each(pos => {
10734
+ normRng.setEnd(pos.container(), pos.offset());
10735
+ });
10927
10736
  }
10928
- if (!editorManager.activeEditor && documentFocusInHandler) {
10929
- DOM$9.unbind(document, 'focusin', documentFocusInHandler);
10930
- documentFocusInHandler = null;
10737
+ if (collapsed) {
10738
+ normRng.collapse(true);
10931
10739
  }
10932
- };
10933
- const setup$w = editorManager => {
10934
- editorManager.on('AddEditor', curry(registerEvents$1, editorManager));
10935
- editorManager.on('RemoveEditor', curry(unregisterDocumentEvents, editorManager));
10740
+ return isEq$4(rng, normRng) ? Optional.none() : Optional.some(normRng);
10936
10741
  };
10937
10742
 
10938
- const getContentEditableHost = (editor, node) => editor.dom.getParent(node, node => editor.dom.getContentEditable(node) === 'true');
10939
- const hasContentEditableFalseParent = (editor, node) => editor.dom.getParent(node, node => editor.dom.getContentEditable(node) === 'false') !== null;
10940
- const getCollapsedNode = rng => rng.collapsed ? Optional.from(getNode$1(rng.startContainer, rng.startOffset)).map(SugarElement.fromDom) : Optional.none();
10941
- const getFocusInElement = (root, rng) => getCollapsedNode(rng).bind(node => {
10942
- if (isTableSection(node)) {
10943
- return Optional.some(node);
10944
- } else if (!contains(root, node)) {
10945
- return Optional.some(root);
10743
+ const splitText = (node, offset) => {
10744
+ return node.splitText(offset);
10745
+ };
10746
+ const split = rng => {
10747
+ let startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;
10748
+ if (startContainer === endContainer && isText$b(startContainer)) {
10749
+ if (startOffset > 0 && startOffset < startContainer.data.length) {
10750
+ endContainer = splitText(startContainer, startOffset);
10751
+ startContainer = endContainer.previousSibling;
10752
+ if (endOffset > startOffset) {
10753
+ endOffset = endOffset - startOffset;
10754
+ const newContainer = splitText(endContainer, endOffset).previousSibling;
10755
+ startContainer = endContainer = newContainer;
10756
+ endOffset = newContainer.data.length;
10757
+ startOffset = 0;
10758
+ } else {
10759
+ endOffset = 0;
10760
+ }
10761
+ }
10946
10762
  } else {
10947
- return Optional.none();
10763
+ if (isText$b(startContainer) && startOffset > 0 && startOffset < startContainer.data.length) {
10764
+ startContainer = splitText(startContainer, startOffset);
10765
+ startOffset = 0;
10766
+ }
10767
+ if (isText$b(endContainer) && endOffset > 0 && endOffset < endContainer.data.length) {
10768
+ const newContainer = splitText(endContainer, endOffset).previousSibling;
10769
+ endContainer = newContainer;
10770
+ endOffset = newContainer.data.length;
10771
+ }
10948
10772
  }
10949
- });
10950
- const normalizeSelection = (editor, rng) => {
10951
- getFocusInElement(SugarElement.fromDom(editor.getBody()), rng).bind(elm => {
10952
- return firstPositionIn(elm.dom);
10953
- }).fold(() => {
10954
- editor.selection.normalize();
10955
- }, caretPos => editor.selection.setRng(caretPos.toRange()));
10773
+ return {
10774
+ startContainer,
10775
+ startOffset,
10776
+ endContainer,
10777
+ endOffset
10778
+ };
10956
10779
  };
10957
- const focusBody = body => {
10958
- if (body.setActive) {
10959
- try {
10960
- body.setActive();
10961
- } catch (ex) {
10962
- body.focus();
10780
+
10781
+ const RangeUtils = dom => {
10782
+ const walk = (rng, callback) => {
10783
+ return walk$3(dom, rng, callback);
10784
+ };
10785
+ const split$1 = split;
10786
+ const normalize = rng => {
10787
+ return normalize$2(dom, rng).fold(never, normalizedRng => {
10788
+ rng.setStart(normalizedRng.startContainer, normalizedRng.startOffset);
10789
+ rng.setEnd(normalizedRng.endContainer, normalizedRng.endOffset);
10790
+ return true;
10791
+ });
10792
+ };
10793
+ const expand = (rng, options = { type: 'word' }) => {
10794
+ if (options.type === 'word') {
10795
+ const rangeLike = expandRng(dom, rng, [{ inline: 'span' }]);
10796
+ const newRange = dom.createRng();
10797
+ newRange.setStart(rangeLike.startContainer, rangeLike.startOffset);
10798
+ newRange.setEnd(rangeLike.endContainer, rangeLike.endOffset);
10799
+ return newRange;
10800
+ }
10801
+ return rng;
10802
+ };
10803
+ return {
10804
+ walk,
10805
+ split: split$1,
10806
+ expand,
10807
+ normalize
10808
+ };
10809
+ };
10810
+ RangeUtils.compareRanges = isEq$4;
10811
+ RangeUtils.getCaretRangeFromPoint = fromPoint;
10812
+ RangeUtils.getSelectedNode = getSelectedNode;
10813
+ RangeUtils.getNode = getNode$1;
10814
+
10815
+ const Dimension = (name, getOffset) => {
10816
+ const set = (element, h) => {
10817
+ if (!isNumber(h) && !h.match(/^[0-9]+$/)) {
10818
+ throw new Error(name + '.set accepts only positive integer values. Value was ' + h);
10819
+ }
10820
+ const dom = element.dom;
10821
+ if (isSupported(dom)) {
10822
+ dom.style[name] = h + 'px';
10823
+ }
10824
+ };
10825
+ const get = element => {
10826
+ const r = getOffset(element);
10827
+ if (r <= 0 || r === null) {
10828
+ const css = get$7(element, name);
10829
+ return parseFloat(css) || 0;
10963
10830
  }
10831
+ return r;
10832
+ };
10833
+ const getOuter = get;
10834
+ const aggregate = (element, properties) => foldl(properties, (acc, property) => {
10835
+ const val = get$7(element, property);
10836
+ const value = val === undefined ? 0 : parseInt(val, 10);
10837
+ return isNaN(value) ? acc : acc + value;
10838
+ }, 0);
10839
+ const max = (element, value, properties) => {
10840
+ const cumulativeInclusions = aggregate(element, properties);
10841
+ const absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;
10842
+ return absoluteMax;
10843
+ };
10844
+ return {
10845
+ set,
10846
+ get,
10847
+ getOuter,
10848
+ aggregate,
10849
+ max
10850
+ };
10851
+ };
10852
+
10853
+ const api = Dimension('height', element => {
10854
+ const dom = element.dom;
10855
+ return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;
10856
+ });
10857
+ const get$2 = element => api.get(element);
10858
+
10859
+ const walkUp = (navigation, doc) => {
10860
+ const frame = navigation.view(doc);
10861
+ return frame.fold(constant([]), f => {
10862
+ const parent = navigation.owner(f);
10863
+ const rest = walkUp(navigation, parent);
10864
+ return [f].concat(rest);
10865
+ });
10866
+ };
10867
+ const pathTo = (element, navigation) => {
10868
+ const d = navigation.owner(element);
10869
+ return walkUp(navigation, d);
10870
+ };
10871
+
10872
+ const view = doc => {
10873
+ var _a;
10874
+ const element = doc.dom === document ? Optional.none() : Optional.from((_a = doc.dom.defaultView) === null || _a === void 0 ? void 0 : _a.frameElement);
10875
+ return element.map(SugarElement.fromDom);
10876
+ };
10877
+ const owner = element => documentOrOwner(element);
10878
+
10879
+ var Navigation = /*#__PURE__*/Object.freeze({
10880
+ __proto__: null,
10881
+ view: view,
10882
+ owner: owner
10883
+ });
10884
+
10885
+ const find = element => {
10886
+ const doc = getDocument();
10887
+ const scroll = get$5(doc);
10888
+ const frames = pathTo(element, Navigation);
10889
+ const offset = viewport(element);
10890
+ const r = foldr(frames, (b, a) => {
10891
+ const loc = viewport(a);
10892
+ return {
10893
+ left: b.left + loc.left,
10894
+ top: b.top + loc.top
10895
+ };
10896
+ }, {
10897
+ left: 0,
10898
+ top: 0
10899
+ });
10900
+ return SugarPosition(r.left + offset.left + scroll.left, r.top + offset.top + scroll.top);
10901
+ };
10902
+
10903
+ const excludeFromDescend = element => name(element) === 'textarea';
10904
+ const fireScrollIntoViewEvent = (editor, data) => {
10905
+ const scrollEvent = editor.dispatch('ScrollIntoView', data);
10906
+ return scrollEvent.isDefaultPrevented();
10907
+ };
10908
+ const fireAfterScrollIntoViewEvent = (editor, data) => {
10909
+ editor.dispatch('AfterScrollIntoView', data);
10910
+ };
10911
+ const descend = (element, offset) => {
10912
+ const children = children$1(element);
10913
+ if (children.length === 0 || excludeFromDescend(element)) {
10914
+ return {
10915
+ element,
10916
+ offset
10917
+ };
10918
+ } else if (offset < children.length && !excludeFromDescend(children[offset])) {
10919
+ return {
10920
+ element: children[offset],
10921
+ offset: 0
10922
+ };
10964
10923
  } else {
10965
- body.focus();
10924
+ const last = children[children.length - 1];
10925
+ if (excludeFromDescend(last)) {
10926
+ return {
10927
+ element,
10928
+ offset
10929
+ };
10930
+ } else {
10931
+ if (name(last) === 'img') {
10932
+ return {
10933
+ element: last,
10934
+ offset: 1
10935
+ };
10936
+ } else if (isText$c(last)) {
10937
+ return {
10938
+ element: last,
10939
+ offset: get$3(last).length
10940
+ };
10941
+ } else {
10942
+ return {
10943
+ element: last,
10944
+ offset: children$1(last).length
10945
+ };
10946
+ }
10947
+ }
10966
10948
  }
10967
10949
  };
10968
- const hasElementFocus = elm => hasFocus$1(elm) || search(elm).isSome();
10969
- const hasIframeFocus = editor => isNonNullable(editor.iframeElement) && hasFocus$1(SugarElement.fromDom(editor.iframeElement));
10970
- const hasInlineFocus = editor => {
10971
- const rawBody = editor.getBody();
10972
- return rawBody && hasElementFocus(SugarElement.fromDom(rawBody));
10950
+ const markerInfo = (element, cleanupFun) => {
10951
+ const pos = absolute(element);
10952
+ const height = get$2(element);
10953
+ return {
10954
+ element,
10955
+ bottom: pos.top + height,
10956
+ height,
10957
+ pos,
10958
+ cleanup: cleanupFun
10959
+ };
10973
10960
  };
10974
- const hasUiFocus = editor => {
10975
- const dos = getRootNode(SugarElement.fromDom(editor.getElement()));
10976
- return active$1(dos).filter(elem => !isEditorContentAreaElement(elem.dom) && isUIElement(editor, elem.dom)).isSome();
10961
+ const createMarker$1 = (element, offset) => {
10962
+ const startPoint = descend(element, offset);
10963
+ const span = SugarElement.fromHtml('<span data-mce-bogus="all" style="display: inline-block;">' + ZWSP$1 + '</span>');
10964
+ before$3(startPoint.element, span);
10965
+ return markerInfo(span, () => remove$4(span));
10977
10966
  };
10978
- const hasFocus = editor => editor.inline ? hasInlineFocus(editor) : hasIframeFocus(editor);
10979
- const hasEditorOrUiFocus = editor => hasFocus(editor) || hasUiFocus(editor);
10980
- const focusEditor = editor => {
10981
- const selection = editor.selection;
10982
- const body = editor.getBody();
10983
- let rng = selection.getRng();
10984
- editor.quirks.refreshContentEditable();
10985
- const restoreBookmark = editor => {
10986
- getRng(editor).each(bookmarkRng => {
10987
- editor.selection.setRng(bookmarkRng);
10988
- rng = bookmarkRng;
10989
- });
10967
+ const elementMarker = element => markerInfo(SugarElement.fromDom(element), noop);
10968
+ const withMarker = (editor, f, rng, alignToTop) => {
10969
+ preserveWith(editor, (_s, _e) => applyWithMarker(editor, f, rng, alignToTop), rng);
10970
+ };
10971
+ const withScrollEvents = (editor, doc, f, marker, alignToTop) => {
10972
+ const data = {
10973
+ elm: marker.element.dom,
10974
+ alignToTop
10990
10975
  };
10991
- if (!hasFocus(editor) && editor.hasEditableRoot()) {
10992
- restoreBookmark(editor);
10993
- }
10994
- const contentEditableHost = getContentEditableHost(editor, selection.getNode());
10995
- if (contentEditableHost && editor.dom.isChildOf(contentEditableHost, body)) {
10996
- if (!hasContentEditableFalseParent(editor, contentEditableHost)) {
10997
- focusBody(body);
10998
- }
10999
- focusBody(contentEditableHost);
11000
- if (!editor.hasEditableRoot()) {
11001
- restoreBookmark(editor);
11002
- }
11003
- normalizeSelection(editor, rng);
11004
- activateEditor(editor);
10976
+ if (fireScrollIntoViewEvent(editor, data)) {
11005
10977
  return;
11006
10978
  }
11007
- if (!editor.inline) {
11008
- if (!Env.browser.isOpera()) {
11009
- focusBody(body);
11010
- }
11011
- editor.getWin().focus();
11012
- }
11013
- if (Env.browser.isFirefox() || editor.inline) {
11014
- focusBody(body);
11015
- normalizeSelection(editor, rng);
10979
+ const scrollTop = get$5(doc).top;
10980
+ f(editor, doc, scrollTop, marker, alignToTop);
10981
+ fireAfterScrollIntoViewEvent(editor, data);
10982
+ };
10983
+ const applyWithMarker = (editor, f, rng, alignToTop) => {
10984
+ const body = SugarElement.fromDom(editor.getBody());
10985
+ const doc = SugarElement.fromDom(editor.getDoc());
10986
+ reflow(body);
10987
+ const marker = createMarker$1(SugarElement.fromDom(rng.startContainer), rng.startOffset);
10988
+ withScrollEvents(editor, doc, f, marker, alignToTop);
10989
+ marker.cleanup();
10990
+ };
10991
+ const withElement = (editor, element, f, alignToTop) => {
10992
+ const doc = SugarElement.fromDom(editor.getDoc());
10993
+ withScrollEvents(editor, doc, f, elementMarker(element), alignToTop);
10994
+ };
10995
+ const preserveWith = (editor, f, rng) => {
10996
+ const startElement = rng.startContainer;
10997
+ const startOffset = rng.startOffset;
10998
+ const endElement = rng.endContainer;
10999
+ const endOffset = rng.endOffset;
11000
+ f(SugarElement.fromDom(startElement), SugarElement.fromDom(endElement));
11001
+ const newRng = editor.dom.createRng();
11002
+ newRng.setStart(startElement, startOffset);
11003
+ newRng.setEnd(endElement, endOffset);
11004
+ editor.selection.setRng(rng);
11005
+ };
11006
+ const scrollToMarker = (editor, marker, viewHeight, alignToTop, doc) => {
11007
+ const pos = marker.pos;
11008
+ if (alignToTop) {
11009
+ to(pos.left, pos.top, doc);
11010
+ } else {
11011
+ const y = pos.top - viewHeight + marker.height;
11012
+ to(-editor.getBody().getBoundingClientRect().left, y, doc);
11016
11013
  }
11017
- activateEditor(editor);
11018
11014
  };
11019
- const activateEditor = editor => editor.editorManager.setActive(editor);
11020
- const focus = (editor, skipFocus) => {
11021
- if (editor.removed) {
11022
- return;
11015
+ const intoWindowIfNeeded = (editor, doc, scrollTop, viewHeight, marker, alignToTop) => {
11016
+ const viewportBottom = viewHeight + scrollTop;
11017
+ const markerTop = marker.pos.top;
11018
+ const markerBottom = marker.bottom;
11019
+ const largerThanViewport = markerBottom - markerTop >= viewHeight;
11020
+ if (markerTop < scrollTop) {
11021
+ scrollToMarker(editor, marker, viewHeight, alignToTop !== false, doc);
11022
+ } else if (markerTop > viewportBottom) {
11023
+ const align = largerThanViewport ? alignToTop !== false : alignToTop === true;
11024
+ scrollToMarker(editor, marker, viewHeight, align, doc);
11025
+ } else if (markerBottom > viewportBottom && !largerThanViewport) {
11026
+ scrollToMarker(editor, marker, viewHeight, alignToTop === true, doc);
11023
11027
  }
11024
- if (skipFocus) {
11025
- activateEditor(editor);
11026
- } else {
11027
- focusEditor(editor);
11028
+ };
11029
+ const intoWindow = (editor, doc, scrollTop, marker, alignToTop) => {
11030
+ const viewHeight = defaultView(doc).dom.innerHeight;
11031
+ intoWindowIfNeeded(editor, doc, scrollTop, viewHeight, marker, alignToTop);
11032
+ };
11033
+ const intoFrame = (editor, doc, scrollTop, marker, alignToTop) => {
11034
+ const frameViewHeight = defaultView(doc).dom.innerHeight;
11035
+ intoWindowIfNeeded(editor, doc, scrollTop, frameViewHeight, marker, alignToTop);
11036
+ const op = find(marker.element);
11037
+ const viewportBounds = getBounds(window);
11038
+ if (op.top < viewportBounds.y) {
11039
+ intoView(marker.element, alignToTop !== false);
11040
+ } else if (op.top > viewportBounds.bottom) {
11041
+ intoView(marker.element, alignToTop === true);
11028
11042
  }
11029
11043
  };
11044
+ const rangeIntoWindow = (editor, rng, alignToTop) => withMarker(editor, intoWindow, rng, alignToTop);
11045
+ const elementIntoWindow = (editor, element, alignToTop) => withElement(editor, element, intoWindow, alignToTop);
11046
+ const rangeIntoFrame = (editor, rng, alignToTop) => withMarker(editor, intoFrame, rng, alignToTop);
11047
+ const elementIntoFrame = (editor, element, alignToTop) => withElement(editor, element, intoFrame, alignToTop);
11048
+ const scrollElementIntoView = (editor, element, alignToTop) => {
11049
+ const scroller = editor.inline ? elementIntoWindow : elementIntoFrame;
11050
+ scroller(editor, element, alignToTop);
11051
+ };
11052
+ const scrollRangeIntoView = (editor, rng, alignToTop) => {
11053
+ const scroller = editor.inline ? rangeIntoWindow : rangeIntoFrame;
11054
+ scroller(editor, rng, alignToTop);
11055
+ };
11030
11056
 
11031
11057
  const isEditableRange = (dom, rng) => {
11032
11058
  if (rng.collapsed) {
@@ -11521,7 +11547,7 @@
11521
11547
  const doc = editor.getDoc();
11522
11548
  const dos = getRootNode(SugarElement.fromDom(editor.getBody()));
11523
11549
  const offscreenDiv = SugarElement.fromTag('div', doc);
11524
- set$3(offscreenDiv, 'data-mce-bogus', 'all');
11550
+ set$4(offscreenDiv, 'data-mce-bogus', 'all');
11525
11551
  setAll(offscreenDiv, {
11526
11552
  position: 'fixed',
11527
11553
  left: '-9999999px',
@@ -12466,7 +12492,7 @@
12466
12492
  editor.selection.collapse(true);
12467
12493
  }
12468
12494
  if (selectedCells.length > 1 && exists(selectedCells, cell => eq(cell, selectedNode))) {
12469
- set$3(selectedNode, 'data-mce-selected', '1');
12495
+ set$4(selectedNode, 'data-mce-selected', '1');
12470
12496
  }
12471
12497
  };
12472
12498
  const emptySingleTableCells = (editor, cells, outsideDetails) => Optional.some(() => {
@@ -15001,13 +15027,21 @@
15001
15027
  const matches = /([a-z0-9+\/=\s]+)/i.exec(data);
15002
15028
  return matches ? matches[1] : '';
15003
15029
  };
15030
+ const decodeData = data => {
15031
+ try {
15032
+ return decodeURIComponent(data);
15033
+ } catch (_a) {
15034
+ return data;
15035
+ }
15036
+ };
15004
15037
  const parseDataUri = uri => {
15005
15038
  const [type, ...rest] = uri.split(',');
15006
15039
  const data = rest.join(',');
15007
15040
  const matches = /data:([^/]+\/[^;]+)(;.+)?/.exec(type);
15008
15041
  if (matches) {
15009
15042
  const base64Encoded = matches[2] === ';base64';
15010
- const extractedData = base64Encoded ? extractBase64Data(data) : decodeURIComponent(data);
15043
+ const decodedData = decodeData(data);
15044
+ const extractedData = base64Encoded ? extractBase64Data(decodedData) : decodedData;
15011
15045
  return Optional.some({
15012
15046
  type: matches[1],
15013
15047
  data: extractedData,
@@ -17182,11 +17216,11 @@
17182
17216
  }
17183
17217
  if (validate && rule && !isInternalElement) {
17184
17218
  each$e((_c = rule.attributesForced) !== null && _c !== void 0 ? _c : [], attr => {
17185
- set$3(element, attr.name, attr.value === '{$uid}' ? `mce_${ uid++ }` : attr.value);
17219
+ set$4(element, attr.name, attr.value === '{$uid}' ? `mce_${ uid++ }` : attr.value);
17186
17220
  });
17187
17221
  each$e((_d = rule.attributesDefault) !== null && _d !== void 0 ? _d : [], attr => {
17188
17222
  if (!has$1(element, attr.name)) {
17189
- set$3(element, attr.name, attr.value === '{$uid}' ? `mce_${ uid++ }` : attr.value);
17223
+ set$4(element, attr.name, attr.value === '{$uid}' ? `mce_${ uid++ }` : attr.value);
17190
17224
  }
17191
17225
  });
17192
17226
  if (rule.attributesRequired && !exists(rule.attributesRequired, attr => has$1(element, attr))) {
@@ -19800,41 +19834,182 @@
19800
19834
  fireError(editor, errorType, { message: msg });
19801
19835
  console.error(msg);
19802
19836
  };
19803
- const createLoadError = (type, url, name) => name ? `Failed to load ${ type }: ${ name } from url ${ url }` : `Failed to load ${ type } url: ${ url }`;
19804
- const pluginLoadError = (editor, url, name) => {
19805
- logError(editor, 'PluginLoadError', createLoadError('plugin', url, name));
19837
+ const createLoadError = (type, url, name) => name ? `Failed to load ${ type }: ${ name } from url ${ url }` : `Failed to load ${ type } url: ${ url }`;
19838
+ const pluginLoadError = (editor, url, name) => {
19839
+ logError(editor, 'PluginLoadError', createLoadError('plugin', url, name));
19840
+ };
19841
+ const iconsLoadError = (editor, url, name) => {
19842
+ logError(editor, 'IconsLoadError', createLoadError('icons', url, name));
19843
+ };
19844
+ const languageLoadError = (editor, url, name) => {
19845
+ logError(editor, 'LanguageLoadError', createLoadError('language', url, name));
19846
+ };
19847
+ const themeLoadError = (editor, url, name) => {
19848
+ logError(editor, 'ThemeLoadError', createLoadError('theme', url, name));
19849
+ };
19850
+ const modelLoadError = (editor, url, name) => {
19851
+ logError(editor, 'ModelLoadError', createLoadError('model', url, name));
19852
+ };
19853
+ const pluginInitError = (editor, name, err) => {
19854
+ const message = I18n.translate([
19855
+ 'Failed to initialize plugin: {0}',
19856
+ name
19857
+ ]);
19858
+ fireError(editor, 'PluginLoadError', { message });
19859
+ initError(message, err);
19860
+ displayError(editor, message);
19861
+ };
19862
+ const initError = (message, ...x) => {
19863
+ const console = window.console;
19864
+ if (console) {
19865
+ if (console.error) {
19866
+ console.error(message, ...x);
19867
+ } else {
19868
+ console.log(message, ...x);
19869
+ }
19870
+ }
19871
+ };
19872
+
19873
+ const removeFakeSelection = editor => {
19874
+ Optional.from(editor.selection.getNode()).each(elm => {
19875
+ elm.removeAttribute('data-mce-selected');
19876
+ });
19877
+ };
19878
+ const setEditorCommandState = (editor, cmd, state) => {
19879
+ try {
19880
+ editor.getDoc().execCommand(cmd, false, String(state));
19881
+ } catch (ex) {
19882
+ }
19883
+ };
19884
+ const setCommonEditorCommands = (editor, state) => {
19885
+ setEditorCommandState(editor, 'StyleWithCSS', state);
19886
+ setEditorCommandState(editor, 'enableInlineTableEditing', state);
19887
+ setEditorCommandState(editor, 'enableObjectResizing', state);
19888
+ };
19889
+ const restoreFakeSelection = editor => {
19890
+ editor.selection.setRng(editor.selection.getRng());
19891
+ };
19892
+ const toggleClass = (elm, cls, state) => {
19893
+ if (has(elm, cls) && !state) {
19894
+ remove$6(elm, cls);
19895
+ } else if (state) {
19896
+ add$2(elm, cls);
19897
+ }
19898
+ };
19899
+ const disableEditor = editor => {
19900
+ const body = SugarElement.fromDom(editor.getBody());
19901
+ toggleClass(body, 'mce-content-readonly', true);
19902
+ editor.selection.controlSelection.hideResizeRect();
19903
+ editor._selectionOverrides.hideFakeCaret();
19904
+ removeFakeSelection(editor);
19905
+ };
19906
+ const enableEditor = editor => {
19907
+ const body = SugarElement.fromDom(editor.getBody());
19908
+ toggleClass(body, 'mce-content-readonly', false);
19909
+ if (editor.hasEditableRoot()) {
19910
+ set$3(body, true);
19911
+ }
19912
+ setCommonEditorCommands(editor, false);
19913
+ if (hasEditorOrUiFocus(editor)) {
19914
+ editor.focus();
19915
+ }
19916
+ restoreFakeSelection(editor);
19917
+ editor.nodeChanged();
19918
+ };
19919
+
19920
+ const isDisabled = editor => isDisabled$1(editor);
19921
+ const internalContentEditableAttr = 'data-mce-contenteditable';
19922
+ const switchOffContentEditableTrue = elm => {
19923
+ each$e(descendants(elm, '*[contenteditable="true"]'), elm => {
19924
+ set$4(elm, internalContentEditableAttr, 'true');
19925
+ set$3(elm, false);
19926
+ });
19806
19927
  };
19807
- const iconsLoadError = (editor, url, name) => {
19808
- logError(editor, 'IconsLoadError', createLoadError('icons', url, name));
19928
+ const switchOnContentEditableTrue = elm => {
19929
+ each$e(descendants(elm, `*[${ internalContentEditableAttr }="true"]`), elm => {
19930
+ remove$9(elm, internalContentEditableAttr);
19931
+ set$3(elm, true);
19932
+ });
19809
19933
  };
19810
- const languageLoadError = (editor, url, name) => {
19811
- logError(editor, 'LanguageLoadError', createLoadError('language', url, name));
19934
+ const toggleDisabled = (editor, state) => {
19935
+ const body = SugarElement.fromDom(editor.getBody());
19936
+ if (state) {
19937
+ disableEditor(editor);
19938
+ set$3(body, false);
19939
+ switchOffContentEditableTrue(body);
19940
+ } else {
19941
+ switchOnContentEditableTrue(body);
19942
+ enableEditor(editor);
19943
+ }
19812
19944
  };
19813
- const themeLoadError = (editor, url, name) => {
19814
- logError(editor, 'ThemeLoadError', createLoadError('theme', url, name));
19945
+ const registerDisabledContentFilters = editor => {
19946
+ if (editor.serializer) {
19947
+ registerFilters(editor);
19948
+ } else {
19949
+ editor.on('PreInit', () => {
19950
+ registerFilters(editor);
19951
+ });
19952
+ }
19815
19953
  };
19816
- const modelLoadError = (editor, url, name) => {
19817
- logError(editor, 'ModelLoadError', createLoadError('model', url, name));
19954
+ const registerFilters = editor => {
19955
+ editor.parser.addAttributeFilter('contenteditable', nodes => {
19956
+ if (isDisabled(editor)) {
19957
+ each$e(nodes, node => {
19958
+ node.attr(internalContentEditableAttr, node.attr('contenteditable'));
19959
+ node.attr('contenteditable', 'false');
19960
+ });
19961
+ }
19962
+ });
19963
+ editor.serializer.addAttributeFilter(internalContentEditableAttr, nodes => {
19964
+ if (isDisabled(editor)) {
19965
+ each$e(nodes, node => {
19966
+ node.attr('contenteditable', node.attr(internalContentEditableAttr));
19967
+ });
19968
+ }
19969
+ });
19970
+ editor.serializer.addTempAttr(internalContentEditableAttr);
19818
19971
  };
19819
- const pluginInitError = (editor, name, err) => {
19820
- const message = I18n.translate([
19821
- 'Failed to initialize plugin: {0}',
19822
- name
19823
- ]);
19824
- fireError(editor, 'PluginLoadError', { message });
19825
- initError(message, err);
19826
- displayError(editor, message);
19972
+ const isClickEvent = e => e.type === 'click';
19973
+ const allowedEvents = ['copy'];
19974
+ const isAllowedEventInDisabledMode = e => contains$2(allowedEvents, e.type);
19975
+ const getAnchorHrefOpt = (editor, elm) => {
19976
+ const isRoot = elm => eq(elm, SugarElement.fromDom(editor.getBody()));
19977
+ return closest$3(elm, 'a', isRoot).bind(a => getOpt(a, 'href'));
19827
19978
  };
19828
- const initError = (message, ...x) => {
19829
- const console = window.console;
19830
- if (console) {
19831
- if (console.error) {
19832
- console.error(message, ...x);
19833
- } else {
19834
- console.log(message, ...x);
19835
- }
19979
+ const processDisabledEvents = (editor, e) => {
19980
+ if (isClickEvent(e) && !VK.metaKeyPressed(e)) {
19981
+ const elm = SugarElement.fromDom(e.target);
19982
+ getAnchorHrefOpt(editor, elm).each(href => {
19983
+ e.preventDefault();
19984
+ if (/^#/.test(href)) {
19985
+ const targetEl = editor.dom.select(`${ href },[name="${ removeLeading(href, '#') }"]`);
19986
+ if (targetEl.length) {
19987
+ editor.selection.scrollIntoView(targetEl[0], true);
19988
+ }
19989
+ } else {
19990
+ window.open(href, '_blank', 'rel=noopener noreferrer,menubar=yes,toolbar=yes,location=yes,status=yes,resizable=yes,scrollbars=yes');
19991
+ }
19992
+ });
19993
+ } else if (isAllowedEventInDisabledMode(e)) {
19994
+ editor.dispatch(e.type, e);
19836
19995
  }
19837
19996
  };
19997
+ const registerDisabledModeEventHandlers = editor => {
19998
+ editor.on('ShowCaret ObjectSelected', e => {
19999
+ if (isDisabled(editor)) {
20000
+ e.preventDefault();
20001
+ }
20002
+ });
20003
+ editor.on('DisabledStateChange', e => {
20004
+ if (!e.isDefaultPrevented()) {
20005
+ toggleDisabled(editor, e.state);
20006
+ }
20007
+ });
20008
+ };
20009
+ const registerEventsAndFilters$1 = editor => {
20010
+ registerDisabledContentFilters(editor);
20011
+ registerDisabledModeEventHandlers(editor);
20012
+ };
19838
20013
 
19839
20014
  const isContentCssSkinName = url => /^[a-z0-9\-]+$/i.test(url);
19840
20015
  const toContentSkinResourceName = url => 'content/' + url + '/content.css';
@@ -20431,6 +20606,11 @@
20431
20606
  styles: { float: 'left' },
20432
20607
  preview: 'font-family font-size'
20433
20608
  },
20609
+ {
20610
+ selector: '.mce-placeholder',
20611
+ styles: { float: 'left' },
20612
+ ceFalseOverride: true
20613
+ },
20434
20614
  {
20435
20615
  selector: 'table',
20436
20616
  collapsed: false,
@@ -20473,6 +20653,15 @@
20473
20653
  },
20474
20654
  preview: false
20475
20655
  },
20656
+ {
20657
+ selector: '.mce-placeholder',
20658
+ styles: {
20659
+ display: 'block',
20660
+ marginLeft: 'auto',
20661
+ marginRight: 'auto'
20662
+ },
20663
+ ceFalseOverride: true
20664
+ },
20476
20665
  {
20477
20666
  selector: 'table',
20478
20667
  collapsed: false,
@@ -20522,6 +20711,11 @@
20522
20711
  styles: { float: 'right' },
20523
20712
  preview: 'font-family font-size'
20524
20713
  },
20714
+ {
20715
+ selector: '.mce-placeholder',
20716
+ styles: { float: 'right' },
20717
+ ceFalseOverride: true
20718
+ },
20525
20719
  {
20526
20720
  selector: 'table',
20527
20721
  collapsed: false,
@@ -20680,6 +20874,7 @@
20680
20874
  subscript: { inline: 'sub' },
20681
20875
  superscript: { inline: 'sup' },
20682
20876
  code: { inline: 'code' },
20877
+ samp: { inline: 'samp' },
20683
20878
  link: {
20684
20879
  inline: 'a',
20685
20880
  selector: 'a',
@@ -20739,7 +20934,7 @@
20739
20934
  }
20740
20935
  ]
20741
20936
  };
20742
- Tools.each('p h1 h2 h3 h4 h5 h6 div address pre dt dd samp'.split(/\s/), name => {
20937
+ Tools.each('p h1 h2 h3 h4 h5 h6 div address pre dt dd'.split(/\s/), name => {
20743
20938
  formats[name] = {
20744
20939
  block: name,
20745
20940
  remove: 'all'
@@ -24076,6 +24271,29 @@
24076
24271
  toString
24077
24272
  };
24078
24273
  };
24274
+ const oneOf = (props, rawF) => {
24275
+ const f = rawF !== undefined ? rawF : identity;
24276
+ const extract = (path, val) => {
24277
+ const errors = [];
24278
+ for (const prop of props) {
24279
+ const res = prop.extract(path, val);
24280
+ if (res.stype === SimpleResultType.Value) {
24281
+ return {
24282
+ stype: SimpleResultType.Value,
24283
+ svalue: f(res.svalue)
24284
+ };
24285
+ }
24286
+ errors.push(res);
24287
+ }
24288
+ return ResultCombine.consolidateArr(errors);
24289
+ };
24290
+ const toString = () => 'oneOf(' + map$3(props, prop => prop.toString()).join(', ') + ')';
24291
+ return {
24292
+ extract,
24293
+ toString
24294
+ };
24295
+ };
24296
+ const arrOfObj = compose(arrOf, objOf);
24079
24297
 
24080
24298
  const valueOf = validator => value(v => validator(v).fold(SimpleResult.serror, SimpleResult.svalue));
24081
24299
  const extractValue = (label, prop, obj) => {
@@ -24106,6 +24324,7 @@
24106
24324
  const validateEnum = values => valueOf(value => contains$2(values, value) ? Result.value(value) : Result.error(`Unsupported value: "${ value }", choose one of "${ values.join(', ') }".`));
24107
24325
  const requiredOf = (key, schema) => field(key, key, required(), schema);
24108
24326
  const requiredString = key => requiredOf(key, string);
24327
+ const requiredStringEnum = (key, values) => field(key, key, required(), validateEnum(values));
24109
24328
  const requiredFunction = key => requiredOf(key, functionProcessor);
24110
24329
  const requiredArrayOf = (key, schema) => field(key, key, required(), arrOf(schema));
24111
24330
  const optionOf = (key, schema) => field(key, key, asOption(), schema);
@@ -24173,12 +24392,14 @@
24173
24392
 
24174
24393
  const contextButtonFields = baseToolbarButtonFields.concat([
24175
24394
  defaultedType('contextformbutton'),
24395
+ defaultedString('align', 'end'),
24176
24396
  primary,
24177
24397
  onAction,
24178
24398
  customField('original', identity)
24179
24399
  ]);
24180
24400
  const contextToggleButtonFields = baseToolbarToggleButtonFields.concat([
24181
24401
  defaultedType('contextformbutton'),
24402
+ defaultedString('align', 'end'),
24182
24403
  primary,
24183
24404
  onAction,
24184
24405
  customField('original', identity)
@@ -24189,15 +24410,56 @@
24189
24410
  contextformbutton: contextButtonFields,
24190
24411
  contextformtogglebutton: contextToggleButtonFields
24191
24412
  });
24192
- objOf([
24193
- defaultedType('contextform'),
24194
- defaultedFunction('initValue', constant('')),
24413
+ const baseContextFormFields = [
24195
24414
  optionalLabel,
24196
24415
  requiredArrayOf('commands', toggleOrNormal),
24197
24416
  optionOf('launch', choose('type', {
24198
24417
  contextformbutton: launchButtonFields,
24199
24418
  contextformtogglebutton: launchToggleButtonFields
24419
+ })),
24420
+ defaultedFunction('onInput', noop),
24421
+ defaultedFunction('onSetup', noop)
24422
+ ];
24423
+ const contextFormFields = [
24424
+ ...contextBarFields,
24425
+ ...baseContextFormFields,
24426
+ requiredStringEnum('type', ['contextform']),
24427
+ defaultedFunction('initValue', constant('')),
24428
+ optionString('placeholder')
24429
+ ];
24430
+ const contextSliderFormFields = [
24431
+ ...contextBarFields,
24432
+ ...baseContextFormFields,
24433
+ requiredStringEnum('type', ['contextsliderform']),
24434
+ defaultedFunction('initValue', constant(0)),
24435
+ defaultedFunction('min', constant(0)),
24436
+ defaultedFunction('max', constant(100))
24437
+ ];
24438
+ const contextSizeInputFormFields = [
24439
+ ...contextBarFields,
24440
+ ...baseContextFormFields,
24441
+ requiredStringEnum('type', ['contextsizeinputform']),
24442
+ defaultedFunction('initValue', constant({
24443
+ width: '',
24444
+ height: ''
24200
24445
  }))
24446
+ ];
24447
+ choose('type', {
24448
+ contextform: contextFormFields,
24449
+ contextsliderform: contextSliderFormFields,
24450
+ contextsizeinputform: contextSizeInputFormFields
24451
+ });
24452
+
24453
+ objOf([
24454
+ defaultedType('contexttoolbar'),
24455
+ requiredOf('items', oneOf([
24456
+ string,
24457
+ arrOfObj([
24458
+ optionString('name'),
24459
+ optionString('label'),
24460
+ requiredArrayOf('items', string)
24461
+ ])
24462
+ ]))
24201
24463
  ].concat(contextBarFields));
24202
24464
 
24203
24465
  const register$2 = editor => {
@@ -25930,7 +26192,7 @@
25930
26192
  const editor = this.editor;
25931
26193
  const selection = editor.selection;
25932
26194
  let node;
25933
- if (editor.initialized && selection && !shouldDisableNodeChange(editor)) {
26195
+ if (editor.initialized && selection && !shouldDisableNodeChange(editor) && !isDisabled$1(editor)) {
25934
26196
  const root = editor.getBody();
25935
26197
  node = selection.getStart(true) || root;
25936
26198
  if (node.ownerDocument !== editor.getDoc() || !editor.dom.isChildOf(node, root)) {
@@ -27761,7 +28023,7 @@
27761
28023
  const doc = editor.getDoc();
27762
28024
  const realSelectionContainer = descendant$1(body, '#' + realSelectionId).getOrThunk(() => {
27763
28025
  const newContainer = SugarElement.fromHtml('<div data-mce-bogus="all" class="mce-offscreen-selection"></div>', doc);
27764
- set$3(newContainer, 'id', realSelectionId);
28026
+ set$4(newContainer, 'id', realSelectionId);
27765
28027
  append$1(body, newContainer);
27766
28028
  return newContainer;
27767
28029
  });
@@ -28864,7 +29126,7 @@
28864
29126
  const body = SugarElement.fromDom(editor.getBody());
28865
29127
  const container = getStyleContainer(getRootNode(body));
28866
29128
  const style = SugarElement.fromTag('style');
28867
- set$3(style, 'type', 'text/css');
29129
+ set$4(style, 'type', 'text/css');
28868
29130
  append$1(style, SugarElement.fromText(text));
28869
29131
  append$1(container, style);
28870
29132
  editor.on('remove', () => {
@@ -29038,6 +29300,9 @@
29038
29300
  initInstanceCallback.call(editor, editor);
29039
29301
  }
29040
29302
  autoFocus(editor);
29303
+ if (isDisabled(editor)) {
29304
+ toggleDisabled(editor, true);
29305
+ }
29041
29306
  };
29042
29307
  const getStyleSheetLoader$1 = editor => editor.inline ? editor.ui.styleSheetLoader : editor.dom.styleSheetLoader;
29043
29308
  const makeStylesheetLoadingPromises = (editor, css, framedFonts) => {
@@ -29165,7 +29430,7 @@
29165
29430
  body.disabled = true;
29166
29431
  editor.readonly = isReadOnly$1(editor);
29167
29432
  editor._editableRoot = hasEditableRoot$1(editor);
29168
- if (editor.hasEditableRoot()) {
29433
+ if (!isDisabled$1(editor) && editor.hasEditableRoot()) {
29169
29434
  if (editor.inline && DOM$6.getStyle(body, 'position', true) === 'static') {
29170
29435
  body.style.position = 'relative';
29171
29436
  }
@@ -29242,7 +29507,7 @@
29242
29507
  const DOM$5 = DOMUtils.DOM;
29243
29508
  const createIframeElement = (id, title, customAttrs, tabindex) => {
29244
29509
  const iframe = SugarElement.fromTag('iframe');
29245
- tabindex.each(t => set$3(iframe, 'tabindex', t));
29510
+ tabindex.each(t => set$4(iframe, 'tabindex', t));
29246
29511
  setAll$1(iframe, customAttrs);
29247
29512
  setAll$1(iframe, {
29248
29513
  id: id + '_ifr',
@@ -29424,7 +29689,7 @@
29424
29689
  hide: Optional.from(api.hide).getOr(noop),
29425
29690
  isEnabled: Optional.from(api.isEnabled).getOr(always),
29426
29691
  setEnabled: state => {
29427
- const shouldSkip = state && editor.mode.get() === 'readonly';
29692
+ const shouldSkip = state && (editor.mode.get() === 'readonly' || isDisabled(editor));
29428
29693
  if (!shouldSkip) {
29429
29694
  Optional.from(api.setEnabled).each(f => f(state));
29430
29695
  }
@@ -29638,8 +29903,10 @@
29638
29903
  const setEditableRoot = (editor, state) => {
29639
29904
  if (editor._editableRoot !== state) {
29640
29905
  editor._editableRoot = state;
29641
- editor.getBody().contentEditable = String(editor.hasEditableRoot());
29642
- editor.nodeChanged();
29906
+ if (!isDisabled(editor)) {
29907
+ editor.getBody().contentEditable = String(editor.hasEditableRoot());
29908
+ editor.nodeChanged();
29909
+ }
29643
29910
  fireEditableRootStateChange(editor, state);
29644
29911
  }
29645
29912
  };
@@ -30327,120 +30594,6 @@
30327
30594
  }
30328
30595
  }
30329
30596
 
30330
- const toggleClass = (elm, cls, state) => {
30331
- if (has(elm, cls) && !state) {
30332
- remove$6(elm, cls);
30333
- } else if (state) {
30334
- add$2(elm, cls);
30335
- }
30336
- };
30337
- const setEditorCommandState = (editor, cmd, state) => {
30338
- try {
30339
- editor.getDoc().execCommand(cmd, false, String(state));
30340
- } catch (ex) {
30341
- }
30342
- };
30343
- const setContentEditable = (elm, state) => {
30344
- elm.dom.contentEditable = state ? 'true' : 'false';
30345
- };
30346
- const removeFakeSelection = editor => {
30347
- Optional.from(editor.selection.getNode()).each(elm => {
30348
- elm.removeAttribute('data-mce-selected');
30349
- });
30350
- };
30351
- const restoreFakeSelection = editor => {
30352
- editor.selection.setRng(editor.selection.getRng());
30353
- };
30354
- const setCommonEditorCommands = (editor, state) => {
30355
- setEditorCommandState(editor, 'StyleWithCSS', state);
30356
- setEditorCommandState(editor, 'enableInlineTableEditing', state);
30357
- setEditorCommandState(editor, 'enableObjectResizing', state);
30358
- };
30359
- const setEditorReadonly = editor => {
30360
- editor.readonly = true;
30361
- editor.selection.controlSelection.hideResizeRect();
30362
- editor._selectionOverrides.hideFakeCaret();
30363
- removeFakeSelection(editor);
30364
- };
30365
- const unsetEditorReadonly = (editor, body) => {
30366
- editor.readonly = false;
30367
- if (editor.hasEditableRoot()) {
30368
- setContentEditable(body, true);
30369
- }
30370
- setCommonEditorCommands(editor, false);
30371
- if (hasEditorOrUiFocus(editor)) {
30372
- editor.focus();
30373
- }
30374
- restoreFakeSelection(editor);
30375
- editor.nodeChanged();
30376
- };
30377
- const toggleReadOnly = (editor, state) => {
30378
- const body = SugarElement.fromDom(editor.getBody());
30379
- toggleClass(body, 'mce-content-readonly', state);
30380
- if (state) {
30381
- setEditorReadonly(editor);
30382
- if (editor.hasEditableRoot()) {
30383
- setContentEditable(body, true);
30384
- }
30385
- } else {
30386
- unsetEditorReadonly(editor, body);
30387
- }
30388
- };
30389
- const isReadOnly = editor => editor.readonly;
30390
- const isClickEvent = e => e.type === 'click';
30391
- const allowedEvents = ['copy'];
30392
- const isReadOnlyAllowedEvent = e => contains$2(allowedEvents, e.type);
30393
- const getAnchorHrefOpt = (editor, elm) => {
30394
- const isRoot = elm => eq(elm, SugarElement.fromDom(editor.getBody()));
30395
- return closest$3(elm, 'a', isRoot).bind(a => getOpt(a, 'href'));
30396
- };
30397
- const processReadonlyEvents = (editor, e) => {
30398
- if (isClickEvent(e) && !VK.metaKeyPressed(e)) {
30399
- const elm = SugarElement.fromDom(e.target);
30400
- getAnchorHrefOpt(editor, elm).each(href => {
30401
- e.preventDefault();
30402
- if (/^#/.test(href)) {
30403
- const targetEl = editor.dom.select(`${ href },[name="${ removeLeading(href, '#') }"]`);
30404
- if (targetEl.length) {
30405
- editor.selection.scrollIntoView(targetEl[0], true);
30406
- }
30407
- } else {
30408
- window.open(href, '_blank', 'rel=noopener noreferrer,menubar=yes,toolbar=yes,location=yes,status=yes,resizable=yes,scrollbars=yes');
30409
- }
30410
- });
30411
- } else if (isReadOnlyAllowedEvent(e)) {
30412
- editor.dispatch(e.type, e);
30413
- }
30414
- };
30415
- const registerReadOnlySelectionBlockers = editor => {
30416
- editor.on('beforeinput paste cut dragend dragover draggesture dragdrop drop drag', e => {
30417
- if (isReadOnly(editor)) {
30418
- e.preventDefault();
30419
- }
30420
- });
30421
- editor.on('BeforeExecCommand', e => {
30422
- if ((e.command === 'Undo' || e.command === 'Redo') && isReadOnly(editor)) {
30423
- e.preventDefault();
30424
- }
30425
- });
30426
- editor.on('input', e => {
30427
- if (!e.isComposing && isReadOnly(editor)) {
30428
- const undoLevel = editor.undoManager.add();
30429
- if (isNonNullable(undoLevel)) {
30430
- editor.undoManager.undo();
30431
- }
30432
- }
30433
- });
30434
- editor.on('compositionend', () => {
30435
- if (isReadOnly(editor)) {
30436
- const undoLevel = editor.undoManager.add();
30437
- if (isNonNullable(undoLevel)) {
30438
- editor.undoManager.undo();
30439
- }
30440
- }
30441
- });
30442
- };
30443
-
30444
30597
  const nativeEvents = Tools.makeMap('focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange ' + 'mouseout mouseenter mouseleave wheel keydown keypress keyup input beforeinput contextmenu dragstart dragend dragover ' + 'draggesture dragdrop drop drag submit ' + 'compositionstart compositionend compositionupdate touchstart touchmove touchend touchcancel', ' ');
30445
30598
  class EventDispatcher {
30446
30599
  static isNative(name) {
@@ -30632,12 +30785,12 @@
30632
30785
  }
30633
30786
  return editor.getBody();
30634
30787
  };
30635
- const isListening = editor => !editor.hidden;
30788
+ const isListening = editor => !editor.hidden && !isDisabled(editor);
30636
30789
  const fireEvent = (editor, eventName, e) => {
30637
30790
  if (isListening(editor)) {
30638
30791
  editor.dispatch(eventName, e);
30639
- } else if (isReadOnly(editor)) {
30640
- processReadonlyEvents(editor, e);
30792
+ } else if (isDisabled(editor)) {
30793
+ processDisabledEvents(editor, e);
30641
30794
  }
30642
30795
  };
30643
30796
  const bindEventDelegate = (editor, eventName) => {
@@ -30886,6 +31039,52 @@
30886
31039
  };
30887
31040
  };
30888
31041
 
31042
+ const setContentEditable = (elm, state) => {
31043
+ elm.dom.contentEditable = state ? 'true' : 'false';
31044
+ };
31045
+ const toggleReadOnly = (editor, state) => {
31046
+ const body = SugarElement.fromDom(editor.getBody());
31047
+ if (state) {
31048
+ editor.readonly = true;
31049
+ if (editor.hasEditableRoot()) {
31050
+ setContentEditable(body, true);
31051
+ }
31052
+ disableEditor(editor);
31053
+ } else {
31054
+ editor.readonly = false;
31055
+ enableEditor(editor);
31056
+ }
31057
+ };
31058
+ const isReadOnly = editor => editor.readonly;
31059
+ const registerReadOnlyInputBlockers = editor => {
31060
+ editor.on('beforeinput paste cut dragend dragover draggesture dragdrop drop drag', e => {
31061
+ if (isReadOnly(editor)) {
31062
+ e.preventDefault();
31063
+ }
31064
+ });
31065
+ editor.on('BeforeExecCommand', e => {
31066
+ if ((e.command === 'Undo' || e.command === 'Redo') && isReadOnly(editor)) {
31067
+ e.preventDefault();
31068
+ }
31069
+ });
31070
+ editor.on('input', e => {
31071
+ if (!e.isComposing && isReadOnly(editor)) {
31072
+ const undoLevel = editor.undoManager.add();
31073
+ if (isNonNullable(undoLevel)) {
31074
+ editor.undoManager.undo();
31075
+ }
31076
+ }
31077
+ });
31078
+ editor.on('compositionend', () => {
31079
+ if (isReadOnly(editor)) {
31080
+ const undoLevel = editor.undoManager.add();
31081
+ if (isNonNullable(undoLevel)) {
31082
+ editor.undoManager.undo();
31083
+ }
31084
+ }
31085
+ });
31086
+ };
31087
+
30889
31088
  const defaultModes = [
30890
31089
  'design',
30891
31090
  'readonly'
@@ -30907,7 +31106,7 @@
30907
31106
  fireSwitchMode(editor, mode);
30908
31107
  };
30909
31108
  const setMode = (editor, availableModes, activeMode, mode) => {
30910
- if (mode === activeMode.get()) {
31109
+ if (mode === activeMode.get() || editor.initialized && isDisabled(editor)) {
30911
31110
  return;
30912
31111
  } else if (!has$2(availableModes, mode)) {
30913
31112
  throw new Error(`Editor mode '${ mode }' is invalid`);
@@ -30951,7 +31150,8 @@
30951
31150
  editorReadOnly: true
30952
31151
  }
30953
31152
  });
30954
- registerReadOnlySelectionBlockers(editor);
31153
+ registerReadOnlyInputBlockers(editor);
31154
+ registerEventsAndFilters$1(editor);
30955
31155
  return {
30956
31156
  isReadOnly: () => isReadOnly(editor),
30957
31157
  set: mode => setMode(editor, availableModes.get(), activeMode, mode),
@@ -31135,6 +31335,12 @@
31135
31335
  type
31136
31336
  };
31137
31337
  };
31338
+ const addDefaulted = (collection, type) => (name, spec) => {
31339
+ collection[name.toLowerCase()] = {
31340
+ type,
31341
+ ...spec
31342
+ };
31343
+ };
31138
31344
  const addIcon = (name, svgData) => icons[name.toLowerCase()] = svgData;
31139
31345
  const addContext = (name, pred) => contexts[name.toLowerCase()] = pred;
31140
31346
  return {
@@ -31149,7 +31355,7 @@
31149
31355
  addAutocompleter: add(popups, 'autocompleter'),
31150
31356
  addContextMenu: add(contextMenus, 'contextmenu'),
31151
31357
  addContextToolbar: add(contextToolbars, 'contexttoolbar'),
31152
- addContextForm: add(contextToolbars, 'contextform'),
31358
+ addContextForm: addDefaulted(contextToolbars, 'contextform'),
31153
31359
  addSidebar: add(sidebars, 'sidebar'),
31154
31360
  addView: add(views, 'views'),
31155
31361
  addIcon,
@@ -31623,8 +31829,8 @@
31623
31829
  documentBaseURL: null,
31624
31830
  suffix: null,
31625
31831
  majorVersion: '7',
31626
- minorVersion: '5.1',
31627
- releaseDate: 'TBD',
31832
+ minorVersion: '6.0',
31833
+ releaseDate: '2024-12-11',
31628
31834
  i18n: I18n,
31629
31835
  activeEditor: null,
31630
31836
  focusedEditor: null,