tinymce-rails 7.3.0 → 7.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/app/assets/source/tinymce/tinymce.js +168 -116
  4. data/lib/tinymce/rails/version.rb +2 -2
  5. data/vendor/assets/javascripts/tinymce/icons/default/icons.js +1 -1
  6. data/vendor/assets/javascripts/tinymce/models/dom/model.js +2 -2
  7. data/vendor/assets/javascripts/tinymce/plugins/accordion/plugin.js +2 -2
  8. data/vendor/assets/javascripts/tinymce/plugins/advlist/plugin.js +2 -2
  9. data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.js +1 -1
  10. data/vendor/assets/javascripts/tinymce/plugins/autolink/plugin.js +2 -2
  11. data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.js +1 -1
  12. data/vendor/assets/javascripts/tinymce/plugins/autosave/plugin.js +2 -2
  13. data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.js +1 -1
  14. data/vendor/assets/javascripts/tinymce/plugins/code/plugin.js +1 -1
  15. data/vendor/assets/javascripts/tinymce/plugins/codesample/plugin.js +1 -1
  16. data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.js +1 -1
  17. data/vendor/assets/javascripts/tinymce/plugins/emoticons/plugin.js +1 -1
  18. data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.js +2 -2
  19. data/vendor/assets/javascripts/tinymce/plugins/help/plugin.js +2 -2
  20. data/vendor/assets/javascripts/tinymce/plugins/image/plugin.js +2 -2
  21. data/vendor/assets/javascripts/tinymce/plugins/importcss/plugin.js +1 -1
  22. data/vendor/assets/javascripts/tinymce/plugins/insertdatetime/plugin.js +2 -2
  23. data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +2 -2
  24. data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +2 -2
  25. data/vendor/assets/javascripts/tinymce/plugins/media/plugin.js +1 -1
  26. data/vendor/assets/javascripts/tinymce/plugins/nonbreaking/plugin.js +1 -1
  27. data/vendor/assets/javascripts/tinymce/plugins/pagebreak/plugin.js +1 -1
  28. data/vendor/assets/javascripts/tinymce/plugins/preview/plugin.js +2 -2
  29. data/vendor/assets/javascripts/tinymce/plugins/quickbars/plugin.js +1 -1
  30. data/vendor/assets/javascripts/tinymce/plugins/save/plugin.js +1 -1
  31. data/vendor/assets/javascripts/tinymce/plugins/searchreplace/plugin.js +1 -1
  32. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +1 -1
  33. data/vendor/assets/javascripts/tinymce/plugins/visualblocks/plugin.js +2 -2
  34. data/vendor/assets/javascripts/tinymce/plugins/visualchars/plugin.js +2 -2
  35. data/vendor/assets/javascripts/tinymce/plugins/wordcount/plugin.js +2 -2
  36. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.css +1 -1
  37. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.css +1 -1
  38. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.js +1 -1
  39. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.min.css +1 -1
  40. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.js +1 -1
  41. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.min.css +1 -1
  42. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.css +1 -1
  43. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.js +1 -1
  44. data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.min.css +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/tinymce-5/content.css +1 -1
  55. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.css +1 -1
  56. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.js +1 -1
  57. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.min.css +1 -1
  58. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.js +1 -1
  59. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.min.css +1 -1
  60. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.css +1 -1
  61. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.js +1 -1
  62. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.min.css +1 -1
  63. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.css +1 -1
  64. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.css +1 -1
  65. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.js +1 -1
  66. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.min.css +1 -1
  67. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.js +1 -1
  68. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.min.css +1 -1
  69. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.css +1 -1
  70. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.js +1 -1
  71. data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.min.css +1 -1
  72. data/vendor/assets/javascripts/tinymce/themes/silver/theme.js +2 -2
  73. data/vendor/assets/javascripts/tinymce/tinymce.d.ts +23 -0
  74. data/vendor/assets/javascripts/tinymce/tinymce.js +2 -2
  75. metadata +6 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f2cff298fe1ce0fd108d0ebe03fe0dfd4952d2aaa0762649b29be1a1d4df3f9
4
- data.tar.gz: a592e9e5d1d70c0ba1b0c06d02611236ec6120599991e4126409facc4cb410dc
3
+ metadata.gz: a66f1198e46acd5dfd476f6ffe9759d8dc75ee76048293f613207dbf9e21c04c
4
+ data.tar.gz: da1acf90b1e5f7500cff7c378b6c0be2aded36636440018909f87ca9bcc80732
5
5
  SHA512:
6
- metadata.gz: 4f0e2323551e3fd6d8dbf152121bda436bac579e380a079114ce6efa7192b30e71b6583a6995b355a5adc9744fbb4470b8ba8a93201b6568722d02f29e3a5981
7
- data.tar.gz: 5e219df2c3e9014062ba1f1d464302010da46bd385a018fde27ba9b53750576c0fe98eeb5bf51cea5b820dd812e580e27857b0a2addf6baf9d291416b73ed9f3
6
+ metadata.gz: cdc19cef2ea9075c7a46559850807c8bac0db219662d845bffc8443652c3fb01d6e058f43e3e06588619e643ce3f0b4635d55d6acd75bdcb9862289d24a61365
7
+ data.tar.gz: 1e1268da77e3b9feb50f06945749b7a8d6463071c151cfc4e79acf79fd230fe9894ff6e63b6b0d5207a6c2294fb9c5feb144137a76be368202727a083c17bfa1
data/README.md CHANGED
@@ -11,6 +11,8 @@ Please see alternate branches for [TinyMCE 6](https://github.com/spohlenz/tinymc
11
11
  > [!IMPORTANT]
12
12
  > Please note that as of version 7, TinyMCE (and therefore this project) is now licensed under the GPL.
13
13
 
14
+ [![Latest Gem Version](https://img.shields.io/gem/v/tinymce-rails)](https://rubygems.org/gems/tinymce-rails)
15
+ [![Upstream Version](https://img.shields.io/npm/v/tinymce?label=upstream&color=%23335dff)](https://www.tiny.cloud/docs/tinymce/latest/release-notes/)
14
16
  [![Build Status](https://img.shields.io/github/actions/workflow/status/spohlenz/tinymce-rails/rspec.yml)](https://github.com/spohlenz/tinymce-rails/actions)
15
17
 
16
18
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * TinyMCE version 7.3.0 (2024-08-07)
2
+ * TinyMCE version 7.4.0 (2024-10-09)
3
3
  */
4
4
 
5
5
  (function () {
@@ -7290,6 +7290,19 @@
7290
7290
  processor: 'boolean',
7291
7291
  default: false
7292
7292
  });
7293
+ registerOption('allow_mathml_annotation_encodings', {
7294
+ processor: value => {
7295
+ const valid = isArrayOf(value, isString);
7296
+ return valid ? {
7297
+ value,
7298
+ valid
7299
+ } : {
7300
+ valid: false,
7301
+ message: 'Must be an array of strings.'
7302
+ };
7303
+ },
7304
+ default: []
7305
+ });
7293
7306
  registerOption('convert_fonts_to_spans', {
7294
7307
  processor: 'boolean',
7295
7308
  default: true,
@@ -7948,7 +7961,7 @@
7948
7961
  const isContentEditableTrue$1 = isContentEditableTrue$3;
7949
7962
  const isContentEditableFalse$7 = isContentEditableFalse$b;
7950
7963
  const isMedia = isMedia$2;
7951
- const isBlockLike = matchStyleValues('display', 'block table table-cell table-caption list-item');
7964
+ const isBlockLike = matchStyleValues('display', 'block table table-cell table-row table-caption list-item');
7952
7965
  const isCaretContainer = isCaretContainer$2;
7953
7966
  const isCaretContainerBlock = isCaretContainerBlock$1;
7954
7967
  const isElement$2 = isElement$6;
@@ -9635,7 +9648,7 @@
9635
9648
  };
9636
9649
  const isResizable = elm => {
9637
9650
  const selector = getObjectResizing(editor);
9638
- if (!selector) {
9651
+ if (!selector || editor.mode.isReadOnly()) {
9639
9652
  return false;
9640
9653
  }
9641
9654
  if (elm.getAttribute('data-mce-resize') === 'false') {
@@ -13243,6 +13256,9 @@
13243
13256
  if (node && node.attr('id') === 'mce_marker') {
13244
13257
  const marker = node;
13245
13258
  for (node = node.prev; node; node = node.walk(true)) {
13259
+ if (node.name === 'table') {
13260
+ break;
13261
+ }
13246
13262
  if (node.type === 3 || !dom.isBlock(node.name)) {
13247
13263
  if (node.parent && editor.schema.isValidChild(node.parent.name, 'span')) {
13248
13264
  node.parent.insert(marker, node, node.name === 'br');
@@ -17230,37 +17246,55 @@
17230
17246
  }
17231
17247
  return config;
17232
17248
  };
17233
- const sanitizeNamespaceElement = ele => {
17249
+ const sanitizeSvgElement = ele => {
17250
+ const xlinkAttrs = [
17251
+ 'type',
17252
+ 'href',
17253
+ 'role',
17254
+ 'arcrole',
17255
+ 'title',
17256
+ 'show',
17257
+ 'actuate',
17258
+ 'label',
17259
+ 'from',
17260
+ 'to'
17261
+ ].map(name => `xlink:${ name }`);
17262
+ const config = {
17263
+ IN_PLACE: true,
17264
+ USE_PROFILES: {
17265
+ html: true,
17266
+ svg: true,
17267
+ svgFilters: true
17268
+ },
17269
+ ALLOWED_ATTR: xlinkAttrs
17270
+ };
17271
+ purify().sanitize(ele, config);
17272
+ };
17273
+ const sanitizeMathmlElement = (node, settings) => {
17274
+ const config = {
17275
+ IN_PLACE: true,
17276
+ USE_PROFILES: { mathMl: true }
17277
+ };
17278
+ const purify$1 = purify();
17279
+ purify$1.addHook('uponSanitizeElement', (node, evt) => {
17280
+ var _a;
17281
+ const lcTagName = (_a = evt.tagName) !== null && _a !== void 0 ? _a : node.nodeName.toLowerCase();
17282
+ const allowedEncodings = settings.allow_mathml_annotation_encodings;
17283
+ if (lcTagName === 'annotation' && isArray$1(allowedEncodings) && allowedEncodings.length > 0) {
17284
+ const encoding = node.getAttribute('encoding');
17285
+ if (isString(encoding) && contains$2(allowedEncodings, encoding)) {
17286
+ evt.allowedTags[lcTagName] = true;
17287
+ }
17288
+ }
17289
+ });
17290
+ purify$1.sanitize(node, config);
17291
+ };
17292
+ const mkSanitizeNamespaceElement = settings => ele => {
17234
17293
  const namespaceType = toScopeType(ele);
17235
17294
  if (namespaceType === 'svg') {
17236
- const xlinkAttrs = [
17237
- 'type',
17238
- 'href',
17239
- 'role',
17240
- 'arcrole',
17241
- 'title',
17242
- 'show',
17243
- 'actuate',
17244
- 'label',
17245
- 'from',
17246
- 'to'
17247
- ].map(name => `xlink:${ name }`);
17248
- const config = {
17249
- IN_PLACE: true,
17250
- USE_PROFILES: {
17251
- html: true,
17252
- svg: true,
17253
- svgFilters: true
17254
- },
17255
- ALLOWED_ATTR: xlinkAttrs
17256
- };
17257
- purify().sanitize(ele, config);
17295
+ sanitizeSvgElement(ele);
17258
17296
  } else if (namespaceType === 'math') {
17259
- const config = {
17260
- IN_PLACE: true,
17261
- USE_PROFILES: { mathMl: true }
17262
- };
17263
- purify().sanitize(ele, config);
17297
+ sanitizeMathmlElement(ele, settings);
17264
17298
  } else {
17265
17299
  throw new Error('Not a namespace element');
17266
17300
  }
@@ -17276,7 +17310,7 @@
17276
17310
  };
17277
17311
  return {
17278
17312
  sanitizeHtmlElement,
17279
- sanitizeNamespaceElement
17313
+ sanitizeNamespaceElement: mkSanitizeNamespaceElement(settings)
17280
17314
  };
17281
17315
  } else {
17282
17316
  const sanitizeHtmlElement = (body, _mimeType) => {
@@ -18743,6 +18777,9 @@
18743
18777
  return !sel || rng.collapsed;
18744
18778
  };
18745
18779
  const isEditable = () => {
18780
+ if (editor.mode.isReadOnly()) {
18781
+ return false;
18782
+ }
18746
18783
  const rng = getRng$1();
18747
18784
  const fakeSelectedElements = editor.getBody().querySelectorAll('[data-mce-selected="1"]');
18748
18785
  if (fakeSelectedElements.length > 0) {
@@ -22659,6 +22696,9 @@
22659
22696
  const getBlocksToIndent = editor => filter$5(fromDom$1(editor.selection.getSelectedBlocks()), el => !isListComponent(el) && !parentIsListComponent(el) && isEditable(el));
22660
22697
  const handle = (editor, command) => {
22661
22698
  var _a, _b;
22699
+ if (editor.mode.isReadOnly()) {
22700
+ return;
22701
+ }
22662
22702
  const {dom} = editor;
22663
22703
  const indentation = getIndentation(editor);
22664
22704
  const indentUnit = (_b = (_a = /[a-z%]+$/i.exec(indentation)) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : 'px';
@@ -23398,6 +23438,9 @@
23398
23438
  return getCellFirstCursorPosition(cell);
23399
23439
  });
23400
23440
  }, current => {
23441
+ if (editor.mode.isReadOnly()) {
23442
+ return Optional.none();
23443
+ }
23401
23444
  editor.execCommand('mceTableInsertRowAfter');
23402
23445
  return tabForward(editor, isRoot, current);
23403
23446
  });
@@ -24078,7 +24121,8 @@
24078
24121
  optionalTooltip,
24079
24122
  optionalIcon,
24080
24123
  optionalText,
24081
- onSetup
24124
+ onSetup,
24125
+ defaultedString('context', 'mode:design')
24082
24126
  ];
24083
24127
 
24084
24128
  const baseToolbarToggleButtonFields = [active].concat(baseToolbarButtonFields);
@@ -24941,9 +24985,12 @@
24941
24985
  const isEmptyAnchor = (dom, elm) => {
24942
24986
  return elm && elm.nodeName === 'A' && dom.isEmpty(elm);
24943
24987
  };
24944
- const containerAndSiblingName = (container, nodeName) => {
24988
+ const containerAndPreviousSiblingName = (container, nodeName) => {
24945
24989
  return container.nodeName === nodeName || container.previousSibling && container.previousSibling.nodeName === nodeName;
24946
24990
  };
24991
+ const containerAndNextSiblingName = (container, nodeName) => {
24992
+ return container.nodeName === nodeName || container.nextSibling && container.nextSibling.nodeName === nodeName;
24993
+ };
24947
24994
  const canSplitBlock = (dom, node) => {
24948
24995
  return isNonNullable(node) && dom.isBlock(node) && !/^(TD|TH|CAPTION|FORM)$/.test(node.nodeName) && !/^(fixed|absolute)/i.test(node.style.position) && dom.isEditable(node.parentNode) && dom.getContentEditable(node) !== 'false';
24949
24996
  };
@@ -25085,7 +25132,10 @@
25085
25132
  if (start && isElement$6(container) && container === parentBlock.firstChild) {
25086
25133
  return true;
25087
25134
  }
25088
- if (containerAndSiblingName(container, 'TABLE') || containerAndSiblingName(container, 'HR')) {
25135
+ if (containerAndPreviousSiblingName(container, 'TABLE') || containerAndPreviousSiblingName(container, 'HR')) {
25136
+ if (containerAndNextSiblingName(container, 'BR')) {
25137
+ return !start;
25138
+ }
25089
25139
  return isAfterLastNodeInContainer && !start || !isAfterLastNodeInContainer && start;
25090
25140
  }
25091
25141
  const walker = new DomTreeWalker(container, parentBlock);
@@ -25203,7 +25253,7 @@
25203
25253
  const afterBr = isAfterBr(parentBlockSugar, caretPos, editor.schema);
25204
25254
  const prevBrOpt = afterBr ? findPreviousBr(parentBlockSugar, caretPos, editor.schema).bind(pos => Optional.from(pos.getNode())) : Optional.none();
25205
25255
  newBlock = parentBlockParent.insertBefore(createNewBlock$1(), parentBlock);
25206
- const root = containerAndSiblingName(parentBlock, 'HR') || afterTable ? newBlock : prevBrOpt.getOr(parentBlock);
25256
+ const root = containerAndPreviousSiblingName(parentBlock, 'HR') || afterTable ? newBlock : prevBrOpt.getOr(parentBlock);
25207
25257
  moveToCaretPosition(editor, root);
25208
25258
  } else {
25209
25259
  const tmpRng = includeZwspInRange(rng).cloneRange();
@@ -25463,6 +25513,9 @@
25463
25513
  };
25464
25514
 
25465
25515
  const insertBreak = (breakType, editor, evt) => {
25516
+ if (editor.mode.isReadOnly()) {
25517
+ return;
25518
+ }
25466
25519
  if (!editor.selection.isCollapsed()) {
25467
25520
  execEditorDeleteCommand(editor);
25468
25521
  }
@@ -25478,6 +25531,9 @@
25478
25531
  }
25479
25532
  };
25480
25533
  const insert$1 = (editor, evt) => {
25534
+ if (editor.mode.isReadOnly()) {
25535
+ return;
25536
+ }
25481
25537
  const br = () => insertBreak(linebreak, editor, evt);
25482
25538
  const block = () => insertBreak(blockbreak, editor, evt);
25483
25539
  const logicalAction = getAction(editor, evt);
@@ -25840,16 +25896,17 @@
25840
25896
  });
25841
25897
  }
25842
25898
  nodeChanged(args = {}) {
25843
- const selection = this.editor.selection;
25899
+ const editor = this.editor;
25900
+ const selection = editor.selection;
25844
25901
  let node;
25845
- if (this.editor.initialized && selection && !shouldDisableNodeChange(this.editor) && !this.editor.mode.isReadOnly()) {
25846
- const root = this.editor.getBody();
25902
+ if (editor.initialized && selection && !shouldDisableNodeChange(editor)) {
25903
+ const root = editor.getBody();
25847
25904
  node = selection.getStart(true) || root;
25848
- if (node.ownerDocument !== this.editor.getDoc() || !this.editor.dom.isChildOf(node, root)) {
25905
+ if (node.ownerDocument !== editor.getDoc() || !editor.dom.isChildOf(node, root)) {
25849
25906
  node = root;
25850
25907
  }
25851
25908
  const parents = [];
25852
- this.editor.dom.getParent(node, node => {
25909
+ editor.dom.getParent(node, node => {
25853
25910
  if (node === root) {
25854
25911
  return true;
25855
25912
  } else {
@@ -25857,7 +25914,7 @@
25857
25914
  return false;
25858
25915
  }
25859
25916
  });
25860
- this.editor.dispatch('NodeChange', {
25917
+ editor.dispatch('NodeChange', {
25861
25918
  ...args,
25862
25919
  element: node,
25863
25920
  parents
@@ -28328,7 +28385,7 @@
28328
28385
  }), getTextPatternsLookup(editor));
28329
28386
  const hasDynamicPatterns = () => hasTextPatternsLookup(editor);
28330
28387
  editor.on('keydown', e => {
28331
- if (e.keyCode === 13 && !VK.modifierPressed(e) && editor.selection.isCollapsed()) {
28388
+ if (e.keyCode === 13 && !VK.modifierPressed(e) && editor.selection.isCollapsed() && editor.selection.isEditable()) {
28332
28389
  const patternSet = filterByTrigger(getPatternSet(), 'enter');
28333
28390
  const hasPatterns = patternSet.inlinePatterns.length > 0 || patternSet.blockPatterns.length > 0 || hasDynamicPatterns();
28334
28391
  if (hasPatterns && handleEnter(editor, patternSet)) {
@@ -28337,7 +28394,7 @@
28337
28394
  }
28338
28395
  }, true);
28339
28396
  editor.on('keydown', e => {
28340
- if (e.keyCode === 32 && editor.selection.isCollapsed()) {
28397
+ if (e.keyCode === 32 && editor.selection.isCollapsed() && editor.selection.isEditable()) {
28341
28398
  const patternSet = filterByTrigger(getPatternSet(), 'space');
28342
28399
  const hasPatterns = patternSet.blockPatterns.length > 0 || hasDynamicPatterns();
28343
28400
  if (hasPatterns && handleBlockPatternOnSpace(editor, patternSet)) {
@@ -28346,7 +28403,7 @@
28346
28403
  }
28347
28404
  }, true);
28348
28405
  const handleInlineTrigger = () => {
28349
- if (editor.selection.isCollapsed()) {
28406
+ if (editor.selection.isCollapsed() && editor.selection.isEditable()) {
28350
28407
  const patternSet = filterByTrigger(getPatternSet(), 'space');
28351
28408
  const hasPatterns = patternSet.inlinePatterns.length > 0 || hasDynamicPatterns();
28352
28409
  if (hasPatterns) {
@@ -28794,6 +28851,7 @@
28794
28851
  allow_svg_data_urls: getOption('allow_svg_data_urls'),
28795
28852
  allow_html_in_named_anchor: getOption('allow_html_in_named_anchor'),
28796
28853
  allow_script_urls: getOption('allow_script_urls'),
28854
+ allow_mathml_annotation_encodings: getOption('allow_mathml_annotation_encodings'),
28797
28855
  allow_unsafe_link_target: getOption('allow_unsafe_link_target'),
28798
28856
  convert_unsafe_embeds: getOption('convert_unsafe_embeds'),
28799
28857
  convert_fonts_to_spans: getOption('convert_fonts_to_spans'),
@@ -29076,7 +29134,7 @@
29076
29134
  body.disabled = true;
29077
29135
  editor.readonly = isReadOnly$1(editor);
29078
29136
  editor._editableRoot = hasEditableRoot$1(editor);
29079
- if (!editor.readonly && editor.hasEditableRoot()) {
29137
+ if (editor.hasEditableRoot()) {
29080
29138
  if (editor.inline && DOM$6.getStyle(body, 'position', true) === 'static') {
29081
29139
  body.style.position = 'relative';
29082
29140
  }
@@ -29335,7 +29393,8 @@
29335
29393
  hide: Optional.from(api.hide).getOr(noop),
29336
29394
  isEnabled: Optional.from(api.isEnabled).getOr(always),
29337
29395
  setEnabled: state => {
29338
- if (!editor.mode.isReadOnly()) {
29396
+ const shouldSkip = state && editor.mode.get() === 'readonly';
29397
+ if (!shouldSkip) {
29339
29398
  Optional.from(api.setEnabled).each(f => f(state));
29340
29399
  }
29341
29400
  }
@@ -29548,10 +29607,8 @@
29548
29607
  const setEditableRoot = (editor, state) => {
29549
29608
  if (editor._editableRoot !== state) {
29550
29609
  editor._editableRoot = state;
29551
- if (!editor.readonly) {
29552
- editor.getBody().contentEditable = String(editor.hasEditableRoot());
29553
- editor.nodeChanged();
29554
- }
29610
+ editor.getBody().contentEditable = String(editor.hasEditableRoot());
29611
+ editor.nodeChanged();
29555
29612
  fireEditableRootStateChange(editor, state);
29556
29613
  }
29557
29614
  };
@@ -29992,6 +30049,9 @@
29992
30049
 
29993
30050
  const registerCommands$4 = editor => {
29994
30051
  const applyLinkToSelection = (_command, _ui, value) => {
30052
+ if (editor.mode.isReadOnly()) {
30053
+ return;
30054
+ }
29995
30055
  const linkDetails = isString(value) ? { href: value } : value;
29996
30056
  const anchor = editor.dom.getParent(editor.selection.getNode(), 'a');
29997
30057
  if (isObject(linkDetails) && isString(linkDetails.href)) {
@@ -30029,6 +30089,9 @@
30029
30089
  return Optional.from(topParentBlock).map(SugarElement.fromDom);
30030
30090
  };
30031
30091
  const insert = (editor, before) => {
30092
+ if (editor.mode.isReadOnly()) {
30093
+ return;
30094
+ }
30032
30095
  const dom = editor.dom;
30033
30096
  const rng = editor.selection.getRng();
30034
30097
  const node = before ? editor.selection.getStart() : editor.selection.getEnd();
@@ -30233,7 +30296,6 @@
30233
30296
  }
30234
30297
  }
30235
30298
 
30236
- const internalContentEditableAttr = 'data-mce-contenteditable';
30237
30299
  const toggleClass = (elm, cls, state) => {
30238
30300
  if (has(elm, cls) && !state) {
30239
30301
  remove$6(elm, cls);
@@ -30250,18 +30312,6 @@
30250
30312
  const setContentEditable = (elm, state) => {
30251
30313
  elm.dom.contentEditable = state ? 'true' : 'false';
30252
30314
  };
30253
- const switchOffContentEditableTrue = elm => {
30254
- each$e(descendants(elm, '*[contenteditable="true"]'), elm => {
30255
- set$3(elm, internalContentEditableAttr, 'true');
30256
- setContentEditable(elm, false);
30257
- });
30258
- };
30259
- const switchOnContentEditableTrue = elm => {
30260
- each$e(descendants(elm, `*[${ internalContentEditableAttr }="true"]`), elm => {
30261
- remove$9(elm, internalContentEditableAttr);
30262
- setContentEditable(elm, true);
30263
- });
30264
- };
30265
30315
  const removeFakeSelection = editor => {
30266
30316
  Optional.from(editor.selection.getNode()).each(elm => {
30267
30317
  elm.removeAttribute('data-mce-selected');
@@ -30270,60 +30320,42 @@
30270
30320
  const restoreFakeSelection = editor => {
30271
30321
  editor.selection.setRng(editor.selection.getRng());
30272
30322
  };
30323
+ const setCommonEditorCommands = (editor, state) => {
30324
+ setEditorCommandState(editor, 'StyleWithCSS', state);
30325
+ setEditorCommandState(editor, 'enableInlineTableEditing', state);
30326
+ setEditorCommandState(editor, 'enableObjectResizing', state);
30327
+ };
30328
+ const setEditorReadonly = editor => {
30329
+ editor.readonly = true;
30330
+ editor.selection.controlSelection.hideResizeRect();
30331
+ editor._selectionOverrides.hideFakeCaret();
30332
+ removeFakeSelection(editor);
30333
+ };
30334
+ const unsetEditorReadonly = (editor, body) => {
30335
+ editor.readonly = false;
30336
+ if (editor.hasEditableRoot()) {
30337
+ setContentEditable(body, true);
30338
+ }
30339
+ setCommonEditorCommands(editor, false);
30340
+ if (hasEditorOrUiFocus(editor)) {
30341
+ editor.focus();
30342
+ }
30343
+ restoreFakeSelection(editor);
30344
+ editor.nodeChanged();
30345
+ };
30273
30346
  const toggleReadOnly = (editor, state) => {
30274
30347
  const body = SugarElement.fromDom(editor.getBody());
30275
30348
  toggleClass(body, 'mce-content-readonly', state);
30276
30349
  if (state) {
30277
- editor.selection.controlSelection.hideResizeRect();
30278
- editor._selectionOverrides.hideFakeCaret();
30279
- removeFakeSelection(editor);
30280
- editor.readonly = true;
30281
- setContentEditable(body, false);
30282
- switchOffContentEditableTrue(body);
30283
- } else {
30284
- editor.readonly = false;
30350
+ setEditorReadonly(editor);
30285
30351
  if (editor.hasEditableRoot()) {
30286
30352
  setContentEditable(body, true);
30287
30353
  }
30288
- switchOnContentEditableTrue(body);
30289
- setEditorCommandState(editor, 'StyleWithCSS', false);
30290
- setEditorCommandState(editor, 'enableInlineTableEditing', false);
30291
- setEditorCommandState(editor, 'enableObjectResizing', false);
30292
- if (hasEditorOrUiFocus(editor)) {
30293
- editor.focus();
30294
- }
30295
- restoreFakeSelection(editor);
30296
- editor.nodeChanged();
30297
- }
30298
- };
30299
- const isReadOnly = editor => editor.readonly;
30300
- const registerFilters = editor => {
30301
- editor.parser.addAttributeFilter('contenteditable', nodes => {
30302
- if (isReadOnly(editor)) {
30303
- each$e(nodes, node => {
30304
- node.attr(internalContentEditableAttr, node.attr('contenteditable'));
30305
- node.attr('contenteditable', 'false');
30306
- });
30307
- }
30308
- });
30309
- editor.serializer.addAttributeFilter(internalContentEditableAttr, nodes => {
30310
- if (isReadOnly(editor)) {
30311
- each$e(nodes, node => {
30312
- node.attr('contenteditable', node.attr(internalContentEditableAttr));
30313
- });
30314
- }
30315
- });
30316
- editor.serializer.addTempAttr(internalContentEditableAttr);
30317
- };
30318
- const registerReadOnlyContentFilters = editor => {
30319
- if (editor.serializer) {
30320
- registerFilters(editor);
30321
30354
  } else {
30322
- editor.on('PreInit', () => {
30323
- registerFilters(editor);
30324
- });
30355
+ unsetEditorReadonly(editor, body);
30325
30356
  }
30326
30357
  };
30358
+ const isReadOnly = editor => editor.readonly;
30327
30359
  const isClickEvent = e => e.type === 'click';
30328
30360
  const allowedEvents = ['copy'];
30329
30361
  const isReadOnlyAllowedEvent = e => contains$2(allowedEvents, e.type);
@@ -30350,16 +30382,32 @@
30350
30382
  }
30351
30383
  };
30352
30384
  const registerReadOnlySelectionBlockers = editor => {
30353
- editor.on('ShowCaret', e => {
30385
+ editor.on('beforeinput paste cut dragend dragover draggesture dragdrop drop drag', e => {
30354
30386
  if (isReadOnly(editor)) {
30355
30387
  e.preventDefault();
30356
30388
  }
30357
30389
  });
30358
- editor.on('ObjectSelected', e => {
30359
- if (isReadOnly(editor)) {
30390
+ editor.on('BeforeExecCommand', e => {
30391
+ if ((e.command === 'Undo' || e.command === 'Redo') && isReadOnly(editor)) {
30360
30392
  e.preventDefault();
30361
30393
  }
30362
30394
  });
30395
+ editor.on('input', e => {
30396
+ if (!e.isComposing && isReadOnly(editor)) {
30397
+ const undoLevel = editor.undoManager.add();
30398
+ if (isNonNullable(undoLevel)) {
30399
+ editor.undoManager.undo();
30400
+ }
30401
+ }
30402
+ });
30403
+ editor.on('compositionend', () => {
30404
+ if (isReadOnly(editor)) {
30405
+ const undoLevel = editor.undoManager.add();
30406
+ if (isNonNullable(undoLevel)) {
30407
+ editor.undoManager.undo();
30408
+ }
30409
+ }
30410
+ });
30363
30411
  };
30364
30412
 
30365
30413
  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', ' ');
@@ -30553,7 +30601,7 @@
30553
30601
  }
30554
30602
  return editor.getBody();
30555
30603
  };
30556
- const isListening = editor => !editor.hidden && !isReadOnly(editor);
30604
+ const isListening = editor => !editor.hidden;
30557
30605
  const fireEvent = (editor, eventName, e) => {
30558
30606
  if (isListening(editor)) {
30559
30607
  editor.dispatch(eventName, e);
@@ -30872,7 +30920,6 @@
30872
30920
  editorReadOnly: true
30873
30921
  }
30874
30922
  });
30875
- registerReadOnlyContentFilters(editor);
30876
30923
  registerReadOnlySelectionBlockers(editor);
30877
30924
  return {
30878
30925
  isReadOnly: () => isReadOnly(editor),
@@ -31048,6 +31095,7 @@
31048
31095
  const icons = {};
31049
31096
  const contextMenus = {};
31050
31097
  const contextToolbars = {};
31098
+ const contexts = {};
31051
31099
  const sidebars = {};
31052
31100
  const views = {};
31053
31101
  const add = (collection, type) => (name, spec) => {
@@ -31057,6 +31105,7 @@
31057
31105
  };
31058
31106
  };
31059
31107
  const addIcon = (name, svgData) => icons[name.toLowerCase()] = svgData;
31108
+ const addContext = (name, pred) => contexts[name.toLowerCase()] = pred;
31060
31109
  return {
31061
31110
  addButton: add(buttons, 'button'),
31062
31111
  addGroupToolbarButton: add(buttons, 'grouptoolbarbutton'),
@@ -31073,6 +31122,7 @@
31073
31122
  addSidebar: add(sidebars, 'sidebar'),
31074
31123
  addView: add(views, 'views'),
31075
31124
  addIcon,
31125
+ addContext,
31076
31126
  getAll: () => ({
31077
31127
  buttons,
31078
31128
  menuItems,
@@ -31081,7 +31131,8 @@
31081
31131
  contextMenus,
31082
31132
  contextToolbars,
31083
31133
  sidebars,
31084
- views
31134
+ views,
31135
+ contexts
31085
31136
  })
31086
31137
  };
31087
31138
  };
@@ -31104,6 +31155,7 @@
31104
31155
  addGroupToolbarButton: bridge.addGroupToolbarButton,
31105
31156
  addToggleMenuItem: bridge.addToggleMenuItem,
31106
31157
  addView: bridge.addView,
31158
+ addContext: bridge.addContext,
31107
31159
  getAll: bridge.getAll
31108
31160
  };
31109
31161
  };
@@ -31540,8 +31592,8 @@
31540
31592
  documentBaseURL: null,
31541
31593
  suffix: null,
31542
31594
  majorVersion: '7',
31543
- minorVersion: '3.0',
31544
- releaseDate: '2024-08-07',
31595
+ minorVersion: '4.0',
31596
+ releaseDate: '2024-10-09',
31545
31597
  i18n: I18n,
31546
31598
  activeEditor: null,
31547
31599
  focusedEditor: null,
@@ -1,6 +1,6 @@
1
1
  module TinyMCE
2
2
  module Rails
3
- VERSION = "7.3.0"
4
- TINYMCE_VERSION = "7.3.0"
3
+ VERSION = "7.4.0"
4
+ TINYMCE_VERSION = "7.4.0"
5
5
  end
6
6
  end