tinymce-rails 7.2.0 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +8 -4
- data/app/assets/source/tinymce/tinymce.js +84 -35
- data/lib/tinymce/rails/asset_installer/copy_no_preserve.rb +1 -1
- data/lib/tinymce/rails/asset_installer.rb +4 -4
- data/lib/tinymce/rails/asset_manifest/json_manifest.rb +62 -0
- data/lib/tinymce/rails/asset_manifest/null_manifest.rb +12 -0
- data/lib/tinymce/rails/asset_manifest/propshaft_manifest.rb +43 -0
- data/lib/tinymce/rails/asset_manifest/yaml_manifest.rb +43 -0
- data/lib/tinymce/rails/asset_manifest.rb +6 -108
- data/lib/tinymce/rails/engine.rb +15 -2
- data/lib/tinymce/rails/helper.rb +19 -5
- data/lib/tinymce/rails/propshaft/asset.rb +11 -0
- data/lib/tinymce/rails/version.rb +2 -2
- data/lib/tinymce/rails.rb +2 -2
- data/vendor/assets/javascripts/tinymce/icons/default/icons.js +1 -1
- data/vendor/assets/javascripts/tinymce/models/dom/model.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/accordion/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/advlist/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autolink/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autosave/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/code/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/codesample/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/emoticons/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/help/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/image/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/importcss/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/insertdatetime/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/media/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/nonbreaking/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/pagebreak/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/preview/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/quickbars/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/save/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/searchreplace/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/visualblocks/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/visualchars/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/wordcount/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/content/dark/content.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/content/default/content.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/content/document/content.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/content/tinymce-5/content.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/content/tinymce-5-dark/content.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/content/writer/content.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.inline.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/content.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide/skin.shadowdom.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.inline.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/content.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/oxide-dark/skin.shadowdom.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.inline.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/content.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5/skin.shadowdom.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.inline.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/content.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.js +1 -2
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/ui/tinymce-5-dark/skin.shadowdom.js +1 -2
- data/vendor/assets/javascripts/tinymce/themes/silver/theme.js +2 -2
- data/vendor/assets/javascripts/tinymce/tinymce.js +2 -2
- metadata +9 -4
- /data/app/assets/{javascripts → sprockets}/tinymce/preinit.js.erb +0 -0
- /data/app/assets/{javascripts → sprockets}/tinymce.js +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3f2cff298fe1ce0fd108d0ebe03fe0dfd4952d2aaa0762649b29be1a1d4df3f9
|
|
4
|
+
data.tar.gz: a592e9e5d1d70c0ba1b0c06d02611236ec6120599991e4126409facc4cb410dc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4f0e2323551e3fd6d8dbf152121bda436bac579e380a079114ce6efa7192b30e71b6583a6995b355a5adc9744fbb4470b8ba8a93201b6568722d02f29e3a5981
|
|
7
|
+
data.tar.gz: 5e219df2c3e9014062ba1f1d464302010da46bd385a018fde27ba9b53750576c0fe98eeb5bf51cea5b820dd812e580e27857b0a2addf6baf9d291416b73ed9f3
|
data/README.md
CHANGED
|
@@ -3,7 +3,7 @@ Rails Integration for TinyMCE
|
|
|
3
3
|
|
|
4
4
|
The `tinymce-rails` gem integrates the [TinyMCE](https://www.tiny.cloud/) editor with the Rails asset pipeline.
|
|
5
5
|
|
|
6
|
-
This gem is compatible with Rails 5.
|
|
6
|
+
This gem is compatible with Rails 5.1 and higher.
|
|
7
7
|
|
|
8
8
|
This is the branch for **TinyMCE 7**.<br />
|
|
9
9
|
Please see alternate branches for [TinyMCE 6](https://github.com/spohlenz/tinymce-rails/tree/tinymce-6), [TinyMCE 5](https://github.com/spohlenz/tinymce-rails/tree/tinymce-5), [TinyMCE 4](https://github.com/spohlenz/tinymce-rails/tree/tinymce-4) & [TinyMCE 3.5.x](https://github.com/spohlenz/tinymce-rails/tree/tinymce-3).
|
|
@@ -61,7 +61,7 @@ See the [TinyMCE 7 Documentation](https://www.tiny.cloud/docs/tinymce/7/) for a
|
|
|
61
61
|
|
|
62
62
|
Use *one* of the following options to include TinyMCE assets.
|
|
63
63
|
|
|
64
|
-
(1) Add to your application.js:
|
|
64
|
+
(1) Add to your application.js (Sprockets only):
|
|
65
65
|
|
|
66
66
|
```js
|
|
67
67
|
//= require tinymce
|
|
@@ -70,10 +70,14 @@ Use *one* of the following options to include TinyMCE assets.
|
|
|
70
70
|
or (2) add the script tag to your layout using the `tinymce_assets` helper:
|
|
71
71
|
|
|
72
72
|
```erb
|
|
73
|
-
<%= tinymce_assets %>
|
|
74
|
-
#=> <script type="text/javascript" src="/assets/tinymce.js">
|
|
73
|
+
<%= tinymce_assets data: { turbo_track: "reload" } %>
|
|
74
|
+
#=> <script type="text/javascript" src="/assets/tinymce.js" data-turbo-track="reload">
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
+
When using Propshaft, the `tinymce_assets` helper adds multiple script tags including the pre-init code (available via the `tinymce_preinit` helper), as well as `tinymce/tinymce.js` and `tinymce/rails.js`. You may prefer to selectively include these manually depending on your requirements.
|
|
78
|
+
|
|
79
|
+
For Sprockets, these are bundled together into one script tag.
|
|
80
|
+
|
|
77
81
|
|
|
78
82
|
**4. Initialize TinyMCE**
|
|
79
83
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* TinyMCE version 7.
|
|
2
|
+
* TinyMCE version 7.3.0 (2024-08-07)
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
(function () {
|
|
@@ -955,10 +955,10 @@
|
|
|
955
955
|
const PlatformDetection = { detect: detect$2 };
|
|
956
956
|
|
|
957
957
|
const mediaMatch = query => window.matchMedia(query).matches;
|
|
958
|
-
let platform$4 = cached(() => PlatformDetection.detect(navigator.userAgent, Optional.from(navigator.userAgentData), mediaMatch));
|
|
958
|
+
let platform$4 = cached(() => PlatformDetection.detect(window.navigator.userAgent, Optional.from(window.navigator.userAgentData), mediaMatch));
|
|
959
959
|
const detect$1 = () => platform$4();
|
|
960
960
|
|
|
961
|
-
const userAgent = navigator.userAgent;
|
|
961
|
+
const userAgent = window.navigator.userAgent;
|
|
962
962
|
const platform$3 = detect$1();
|
|
963
963
|
const browser$3 = platform$3.browser;
|
|
964
964
|
const os$1 = platform$3.os;
|
|
@@ -1402,9 +1402,7 @@
|
|
|
1402
1402
|
};
|
|
1403
1403
|
|
|
1404
1404
|
const isShadowRoot = dos => isDocumentFragment$1(dos) && isNonNullable(dos.dom.host);
|
|
1405
|
-
const
|
|
1406
|
-
const isSupported$1 = constant(supported);
|
|
1407
|
-
const getRootNode = supported ? e => SugarElement.fromDom(e.dom.getRootNode()) : documentOrOwner;
|
|
1405
|
+
const getRootNode = e => SugarElement.fromDom(e.dom.getRootNode());
|
|
1408
1406
|
const getStyleContainer = dos => isShadowRoot(dos) ? dos : getHead(documentOrOwner(dos));
|
|
1409
1407
|
const getContentContainer = dos => isShadowRoot(dos) ? dos : SugarElement.fromDom(documentOrOwner(dos).dom.body);
|
|
1410
1408
|
const getShadowRoot = e => {
|
|
@@ -1413,7 +1411,7 @@
|
|
|
1413
1411
|
};
|
|
1414
1412
|
const getShadowHost = e => SugarElement.fromDom(e.dom.host);
|
|
1415
1413
|
const getOriginalEventTarget = event => {
|
|
1416
|
-
if (
|
|
1414
|
+
if (isNonNullable(event.target)) {
|
|
1417
1415
|
const el = SugarElement.fromDom(event.target);
|
|
1418
1416
|
if (isElement$7(el) && isOpenShadowHost(el)) {
|
|
1419
1417
|
if (event.composed && event.composedPath) {
|
|
@@ -5455,13 +5453,16 @@
|
|
|
5455
5453
|
};
|
|
5456
5454
|
};
|
|
5457
5455
|
|
|
5456
|
+
const clamp$2 = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
5457
|
+
const random = () => window.crypto.getRandomValues(new Uint32Array(1))[0] / 4294967295;
|
|
5458
|
+
|
|
5458
5459
|
let unique = 0;
|
|
5459
5460
|
const generate$1 = prefix => {
|
|
5460
5461
|
const date = new Date();
|
|
5461
5462
|
const time = date.getTime();
|
|
5462
|
-
const random = Math.floor(
|
|
5463
|
+
const random$1 = Math.floor(random() * 1000000000);
|
|
5463
5464
|
unique++;
|
|
5464
|
-
return prefix + '_' + random + unique + String(time);
|
|
5465
|
+
return prefix + '_' + random$1 + unique + String(time);
|
|
5465
5466
|
};
|
|
5466
5467
|
|
|
5467
5468
|
const add = (element, classes) => {
|
|
@@ -5858,8 +5859,6 @@
|
|
|
5858
5859
|
};
|
|
5859
5860
|
const overlapY = (r1, r2) => Math.max(0, Math.min(r1.bottom, r2.bottom) - Math.max(r1.top, r2.top));
|
|
5860
5861
|
|
|
5861
|
-
const clamp$2 = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
5862
|
-
|
|
5863
5862
|
const getSelectedNode = range => {
|
|
5864
5863
|
const startContainer = range.startContainer, startOffset = range.startOffset;
|
|
5865
5864
|
if (startContainer === range.endContainer && startContainer.hasChildNodes() && range.endOffset === startOffset + 1) {
|
|
@@ -10022,32 +10021,32 @@
|
|
|
10022
10021
|
const SimRange = { create: create$9 };
|
|
10023
10022
|
|
|
10024
10023
|
const caretPositionFromPoint = (doc, x, y) => {
|
|
10025
|
-
var _a
|
|
10026
|
-
return Optional.from((
|
|
10024
|
+
var _a;
|
|
10025
|
+
return Optional.from((_a = doc.caretPositionFromPoint) === null || _a === void 0 ? void 0 : _a.call(doc, x, y)).bind(pos => {
|
|
10027
10026
|
if (pos.offsetNode === null) {
|
|
10028
10027
|
return Optional.none();
|
|
10029
10028
|
}
|
|
10030
|
-
const r = doc.
|
|
10029
|
+
const r = doc.createRange();
|
|
10031
10030
|
r.setStart(pos.offsetNode, pos.offset);
|
|
10032
10031
|
r.collapse();
|
|
10033
10032
|
return Optional.some(r);
|
|
10034
10033
|
});
|
|
10035
10034
|
};
|
|
10036
10035
|
const caretRangeFromPoint = (doc, x, y) => {
|
|
10037
|
-
var _a
|
|
10038
|
-
return Optional.from((
|
|
10036
|
+
var _a;
|
|
10037
|
+
return Optional.from((_a = doc.caretRangeFromPoint) === null || _a === void 0 ? void 0 : _a.call(doc, x, y));
|
|
10039
10038
|
};
|
|
10040
|
-
const availableSearch = (
|
|
10041
|
-
if (
|
|
10042
|
-
return caretPositionFromPoint;
|
|
10043
|
-
} else if (
|
|
10044
|
-
return caretRangeFromPoint;
|
|
10039
|
+
const availableSearch = (doc, x, y) => {
|
|
10040
|
+
if (doc.caretPositionFromPoint) {
|
|
10041
|
+
return caretPositionFromPoint(doc, x, y);
|
|
10042
|
+
} else if (doc.caretRangeFromPoint) {
|
|
10043
|
+
return caretRangeFromPoint(doc, x, y);
|
|
10045
10044
|
} else {
|
|
10046
|
-
return Optional.none;
|
|
10045
|
+
return Optional.none();
|
|
10047
10046
|
}
|
|
10048
|
-
}
|
|
10047
|
+
};
|
|
10049
10048
|
const fromPoint$1 = (win, x, y) => {
|
|
10050
|
-
const doc =
|
|
10049
|
+
const doc = win.document;
|
|
10051
10050
|
return availableSearch(doc, x, y).map(rng => SimRange.create(SugarElement.fromDom(rng.startContainer), rng.startOffset, SugarElement.fromDom(rng.endContainer), rng.endOffset));
|
|
10052
10051
|
};
|
|
10053
10052
|
|
|
@@ -10211,7 +10210,7 @@
|
|
|
10211
10210
|
var _a;
|
|
10212
10211
|
return ((_a = node.previousSibling) === null || _a === void 0 ? void 0 : _a.nodeName) === name;
|
|
10213
10212
|
};
|
|
10214
|
-
const hasContentEditableFalseParent = (root, node) => {
|
|
10213
|
+
const hasContentEditableFalseParent$1 = (root, node) => {
|
|
10215
10214
|
let currentNode = node;
|
|
10216
10215
|
while (currentNode && currentNode !== root) {
|
|
10217
10216
|
if (isContentEditableFalse$b(currentNode)) {
|
|
@@ -10296,7 +10295,7 @@
|
|
|
10296
10295
|
if (!collapsed && container === body.lastChild && isTable$2(container)) {
|
|
10297
10296
|
return Optional.none();
|
|
10298
10297
|
}
|
|
10299
|
-
if (hasContentEditableFalseParent(body, container) || isCaretContainer$2(container)) {
|
|
10298
|
+
if (hasContentEditableFalseParent$1(body, container) || isCaretContainer$2(container)) {
|
|
10300
10299
|
return Optional.none();
|
|
10301
10300
|
}
|
|
10302
10301
|
if (isDetails(container)) {
|
|
@@ -10924,6 +10923,7 @@
|
|
|
10924
10923
|
};
|
|
10925
10924
|
|
|
10926
10925
|
const getContentEditableHost = (editor, node) => editor.dom.getParent(node, node => editor.dom.getContentEditable(node) === 'true');
|
|
10926
|
+
const hasContentEditableFalseParent = (editor, node) => editor.dom.getParent(node, node => editor.dom.getContentEditable(node) === 'false') !== null;
|
|
10927
10927
|
const getCollapsedNode = rng => rng.collapsed ? Optional.from(getNode$1(rng.startContainer, rng.startOffset)).map(SugarElement.fromDom) : Optional.none();
|
|
10928
10928
|
const getFocusInElement = (root, rng) => getCollapsedNode(rng).bind(node => {
|
|
10929
10929
|
if (isTableSection(node)) {
|
|
@@ -10980,6 +10980,9 @@
|
|
|
10980
10980
|
}
|
|
10981
10981
|
const contentEditableHost = getContentEditableHost(editor, selection.getNode());
|
|
10982
10982
|
if (contentEditableHost && editor.dom.isChildOf(contentEditableHost, body)) {
|
|
10983
|
+
if (!hasContentEditableFalseParent(editor, contentEditableHost)) {
|
|
10984
|
+
focusBody(body);
|
|
10985
|
+
}
|
|
10983
10986
|
focusBody(contentEditableHost);
|
|
10984
10987
|
if (!editor.hasEditableRoot()) {
|
|
10985
10988
|
restoreBookmark(editor);
|
|
@@ -11997,7 +12000,7 @@
|
|
|
11997
12000
|
return false;
|
|
11998
12001
|
}
|
|
11999
12002
|
};
|
|
12000
|
-
const normalizeNbsps = (root, pos, schema) => {
|
|
12003
|
+
const normalizeNbsps$1 = (root, pos, schema) => {
|
|
12001
12004
|
const container = pos.container();
|
|
12002
12005
|
if (!isText$b(container)) {
|
|
12003
12006
|
return Optional.none();
|
|
@@ -12015,7 +12018,7 @@
|
|
|
12015
12018
|
const normalizeNbspsInEditor = editor => {
|
|
12016
12019
|
const root = SugarElement.fromDom(editor.getBody());
|
|
12017
12020
|
if (editor.selection.isCollapsed()) {
|
|
12018
|
-
normalizeNbsps(root, CaretPosition.fromRangeStart(editor.selection.getRng()), editor.schema).each(pos => {
|
|
12021
|
+
normalizeNbsps$1(root, CaretPosition.fromRangeStart(editor.selection.getRng()), editor.schema).each(pos => {
|
|
12019
12022
|
editor.selection.setRng(pos.toRange());
|
|
12020
12023
|
});
|
|
12021
12024
|
}
|
|
@@ -13663,6 +13666,35 @@
|
|
|
13663
13666
|
return Optional.none();
|
|
13664
13667
|
}
|
|
13665
13668
|
};
|
|
13669
|
+
const normalizeNbsps = node => set(node, get$3(node).replace(new RegExp(`${ nbsp }$`), ' '));
|
|
13670
|
+
const normalizeNbspsBetween = (editor, caretContainer) => {
|
|
13671
|
+
const handler = () => {
|
|
13672
|
+
if (caretContainer !== null && !editor.dom.isEmpty(caretContainer)) {
|
|
13673
|
+
prevSibling(SugarElement.fromDom(caretContainer)).each(node => {
|
|
13674
|
+
if (isText$c(node)) {
|
|
13675
|
+
normalizeNbsps(node);
|
|
13676
|
+
} else {
|
|
13677
|
+
descendant$2(node, e => isText$c(e)).each(textNode => {
|
|
13678
|
+
if (isText$c(textNode)) {
|
|
13679
|
+
normalizeNbsps(textNode);
|
|
13680
|
+
}
|
|
13681
|
+
});
|
|
13682
|
+
}
|
|
13683
|
+
});
|
|
13684
|
+
}
|
|
13685
|
+
};
|
|
13686
|
+
editor.once('input', e => {
|
|
13687
|
+
if (e.data && !isWhiteSpace(e.data)) {
|
|
13688
|
+
if (!e.isComposing) {
|
|
13689
|
+
handler();
|
|
13690
|
+
} else {
|
|
13691
|
+
editor.once('compositionend', () => {
|
|
13692
|
+
handler();
|
|
13693
|
+
});
|
|
13694
|
+
}
|
|
13695
|
+
}
|
|
13696
|
+
});
|
|
13697
|
+
};
|
|
13666
13698
|
const applyCaretFormat = (editor, name, vars) => {
|
|
13667
13699
|
let caretContainer;
|
|
13668
13700
|
const selection = editor.selection;
|
|
@@ -13690,6 +13722,7 @@
|
|
|
13690
13722
|
textNode = caretContainer.firstChild;
|
|
13691
13723
|
selectionRng.insertNode(caretContainer);
|
|
13692
13724
|
offset = 1;
|
|
13725
|
+
normalizeNbspsBetween(editor, caretContainer);
|
|
13693
13726
|
editor.formatter.apply(name, vars, caretContainer);
|
|
13694
13727
|
} else {
|
|
13695
13728
|
editor.formatter.apply(name, vars, caretContainer);
|
|
@@ -13753,6 +13786,7 @@
|
|
|
13753
13786
|
removeCaretContainerNode(editor, caretContainer, isNonNullable(caretContainer));
|
|
13754
13787
|
}
|
|
13755
13788
|
selection.setCursorLocation(caretTextNode, 1);
|
|
13789
|
+
normalizeNbspsBetween(editor, newCaretContainer);
|
|
13756
13790
|
if (dom.isEmpty(formatNode)) {
|
|
13757
13791
|
dom.remove(formatNode);
|
|
13758
13792
|
}
|
|
@@ -17363,6 +17397,8 @@
|
|
|
17363
17397
|
}
|
|
17364
17398
|
if (text.length === 0) {
|
|
17365
17399
|
node.remove();
|
|
17400
|
+
} else if (text === ' ' && node.prev && node.prev.type === COMMENT && node.next && node.next.type === COMMENT) {
|
|
17401
|
+
node.remove();
|
|
17366
17402
|
} else {
|
|
17367
17403
|
node.value = text;
|
|
17368
17404
|
}
|
|
@@ -17432,8 +17468,16 @@
|
|
|
17432
17468
|
const mimeType = format === 'xhtml' ? 'application/xhtml+xml' : 'text/html';
|
|
17433
17469
|
const isSpecialRoot = has$2(schema.getSpecialElements(), rootName.toLowerCase());
|
|
17434
17470
|
const content = isSpecialRoot ? `<${ rootName }>${ html }</${ rootName }>` : html;
|
|
17435
|
-
const
|
|
17436
|
-
|
|
17471
|
+
const makeWrap = () => {
|
|
17472
|
+
if (format === 'xhtml') {
|
|
17473
|
+
return `<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>${ content }</body></html>`;
|
|
17474
|
+
} else if (/^[\s]*<head/i.test(html) || /^[\s]*<html/i.test(html) || /^[\s]*<!DOCTYPE/i.test(html)) {
|
|
17475
|
+
return `<html>${ content }</html>`;
|
|
17476
|
+
} else {
|
|
17477
|
+
return `<body>${ content }</body>`;
|
|
17478
|
+
}
|
|
17479
|
+
};
|
|
17480
|
+
const body = parser.parseFromString(makeWrap(), mimeType).body;
|
|
17437
17481
|
sanitizer.sanitizeHtmlElement(body, mimeType);
|
|
17438
17482
|
return isSpecialRoot ? body.firstChild : body;
|
|
17439
17483
|
};
|
|
@@ -19553,7 +19597,7 @@
|
|
|
19553
19597
|
}
|
|
19554
19598
|
reposition();
|
|
19555
19599
|
});
|
|
19556
|
-
editor.on('show ResizeEditor NodeChange', () => {
|
|
19600
|
+
editor.on('show ResizeEditor ResizeWindow NodeChange ToggleView FullscreenStateChanged', () => {
|
|
19557
19601
|
requestAnimationFrame(reposition);
|
|
19558
19602
|
});
|
|
19559
19603
|
editor.on('remove', () => {
|
|
@@ -19858,7 +19902,7 @@
|
|
|
19858
19902
|
let count = 0;
|
|
19859
19903
|
const seed = () => {
|
|
19860
19904
|
const rnd = () => {
|
|
19861
|
-
return Math.round(
|
|
19905
|
+
return Math.round(random() * 4294967295).toString(36);
|
|
19862
19906
|
};
|
|
19863
19907
|
const now = new Date().getTime();
|
|
19864
19908
|
return 's' + now.toString(36) + rnd() + rnd() + rnd();
|
|
@@ -28276,7 +28320,12 @@
|
|
|
28276
28320
|
'?'
|
|
28277
28321
|
];
|
|
28278
28322
|
const keyCodes = [32];
|
|
28279
|
-
const getPatternSet = () => createPatternSet(getTextPatterns(editor)
|
|
28323
|
+
const getPatternSet = () => createPatternSet(getTextPatterns(editor).filter(pattern => {
|
|
28324
|
+
if (pattern.type === 'inline-command' || pattern.type === 'block-command') {
|
|
28325
|
+
return editor.queryCommandSupported(pattern.cmd);
|
|
28326
|
+
}
|
|
28327
|
+
return true;
|
|
28328
|
+
}), getTextPatternsLookup(editor));
|
|
28280
28329
|
const hasDynamicPatterns = () => hasTextPatternsLookup(editor);
|
|
28281
28330
|
editor.on('keydown', e => {
|
|
28282
28331
|
if (e.keyCode === 13 && !VK.modifierPressed(e) && editor.selection.isCollapsed()) {
|
|
@@ -31491,8 +31540,8 @@
|
|
|
31491
31540
|
documentBaseURL: null,
|
|
31492
31541
|
suffix: null,
|
|
31493
31542
|
majorVersion: '7',
|
|
31494
|
-
minorVersion: '
|
|
31495
|
-
releaseDate: '2024-
|
|
31543
|
+
minorVersion: '3.0',
|
|
31544
|
+
releaseDate: '2024-08-07',
|
|
31496
31545
|
i18n: I18n,
|
|
31497
31546
|
activeEditor: null,
|
|
31498
31547
|
focusedEditor: null,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "asset_manifest"
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
require_relative "asset_installer/copy"
|
|
4
|
+
require_relative "asset_installer/copy_no_preserve"
|
|
5
|
+
require_relative "asset_installer/compile"
|
|
6
6
|
|
|
7
7
|
module TinyMCE
|
|
8
8
|
module Rails
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module TinyMCE
|
|
2
|
+
module Rails
|
|
3
|
+
class JsonManifest < AssetManifest
|
|
4
|
+
def self.try(manifest_path, pattern=nil)
|
|
5
|
+
if pattern
|
|
6
|
+
paths = Dir[File.join(manifest_path, pattern)]
|
|
7
|
+
new(paths.first) if paths.any?
|
|
8
|
+
elsif File.file?(manifest_path)
|
|
9
|
+
new(manifest_path)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(file)
|
|
14
|
+
@file = file
|
|
15
|
+
@manifest = JSON.parse(File.read(file))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def append(logical_path, file)
|
|
19
|
+
stat = File.stat(file)
|
|
20
|
+
|
|
21
|
+
assets[logical_path] = logical_path
|
|
22
|
+
files[logical_path] = {
|
|
23
|
+
"logical_path" => logical_path,
|
|
24
|
+
"mtime" => stat.mtime.iso8601,
|
|
25
|
+
"size" => stat.size,
|
|
26
|
+
"digest" => nil
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def remove(logical_path)
|
|
31
|
+
if digested = assets.delete(logical_path)
|
|
32
|
+
files.delete(digested)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def remove_digest(logical_path)
|
|
37
|
+
asset_path(logical_path) do |digested, logical_path|
|
|
38
|
+
assets[logical_path] = logical_path
|
|
39
|
+
files[logical_path] = files.delete(digested).tap { |f| f["digest"] = nil }
|
|
40
|
+
|
|
41
|
+
yield digested, logical_path if block_given?
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def assets
|
|
46
|
+
@manifest["assets"]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def files
|
|
50
|
+
@manifest["files"]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def dump
|
|
54
|
+
JSON.generate(@manifest)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def write
|
|
58
|
+
File.open(@file, "wb") { |f| f.write(dump) }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module TinyMCE
|
|
2
|
+
module Rails
|
|
3
|
+
class PropshaftManifest < AssetManifest
|
|
4
|
+
def self.try(manifest_path)
|
|
5
|
+
json_file = File.join(manifest_path, ".manifest.json")
|
|
6
|
+
new(json_file) if File.exist?(json_file)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def initialize(file)
|
|
10
|
+
@file = file
|
|
11
|
+
@manifest = JSON.parse(File.read(file))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def append(logical_path, file)
|
|
15
|
+
assets[logical_path] = logical_path
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def remove(logical_path)
|
|
19
|
+
assets.delete(logical_path)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def remove_digest(logical_path)
|
|
23
|
+
asset_path(logical_path) do |digested, logical_path|
|
|
24
|
+
assets[logical_path] = logical_path
|
|
25
|
+
|
|
26
|
+
yield digested, logical_path if block_given?
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def assets
|
|
31
|
+
@manifest
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def dump
|
|
35
|
+
JSON.generate(@manifest)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def write
|
|
39
|
+
File.open(@file, "wb") { |f| f.write(dump) }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module TinyMCE
|
|
2
|
+
module Rails
|
|
3
|
+
class YamlManifest < AssetManifest
|
|
4
|
+
def self.try(manifest_path)
|
|
5
|
+
yaml_file = File.join(manifest_path, "manifest.yml")
|
|
6
|
+
new(yaml_file) if File.exist?(yaml_file)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def initialize(file)
|
|
10
|
+
@file = file
|
|
11
|
+
@manifest = YAML.load_file(file)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def append(logical_path, file)
|
|
15
|
+
assets[logical_path] = logical_path
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def remove(logical_path)
|
|
19
|
+
assets.delete(logical_path)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def remove_digest(logical_path)
|
|
23
|
+
asset_path(logical_path) do |digested, logical_path|
|
|
24
|
+
assets[logical_path] = logical_path
|
|
25
|
+
|
|
26
|
+
yield digested, logical_path if block_given?
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def assets
|
|
31
|
+
@manifest
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def dump(io=nil)
|
|
35
|
+
YAML.dump(@manifest, io)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def write
|
|
39
|
+
File.open(@file, "wb") { |f| dump(f) }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -4,7 +4,8 @@ module TinyMCE
|
|
|
4
4
|
attr_reader :file
|
|
5
5
|
|
|
6
6
|
def self.load(manifest_path)
|
|
7
|
-
|
|
7
|
+
PropshaftManifest.try(manifest_path) ||
|
|
8
|
+
JsonManifest.try(manifest_path, ".sprockets-manifest*.json") ||
|
|
8
9
|
JsonManifest.try(manifest_path, "manifest*.json") ||
|
|
9
10
|
JsonManifest.try(manifest_path) ||
|
|
10
11
|
YamlManifest.try(manifest_path) ||
|
|
@@ -35,112 +36,9 @@ module TinyMCE
|
|
|
35
36
|
end
|
|
36
37
|
end
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def initialize(file)
|
|
45
|
-
@file = file
|
|
46
|
-
@manifest = YAML.load_file(file)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def append(logical_path, file)
|
|
50
|
-
assets[logical_path] = logical_path
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def remove(logical_path)
|
|
54
|
-
assets.delete(logical_path)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def remove_digest(logical_path)
|
|
58
|
-
asset_path(logical_path) do |digested, logical_path|
|
|
59
|
-
assets[logical_path] = logical_path
|
|
60
|
-
|
|
61
|
-
yield digested, logical_path if block_given?
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def assets
|
|
66
|
-
@manifest
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def dump(io=nil)
|
|
70
|
-
YAML.dump(@manifest, io)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def write
|
|
74
|
-
File.open(@file, "wb") { |f| dump(f) }
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
class JsonManifest < AssetManifest
|
|
79
|
-
def self.try(manifest_path, pattern=nil)
|
|
80
|
-
if pattern
|
|
81
|
-
paths = Dir[File.join(manifest_path, pattern)]
|
|
82
|
-
new(paths.first) if paths.any?
|
|
83
|
-
elsif File.file?(manifest_path)
|
|
84
|
-
new(manifest_path)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def initialize(file)
|
|
89
|
-
@file = file
|
|
90
|
-
@manifest = JSON.parse(File.read(file))
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def append(logical_path, file)
|
|
94
|
-
stat = File.stat(file)
|
|
95
|
-
|
|
96
|
-
assets[logical_path] = logical_path
|
|
97
|
-
files[logical_path] = {
|
|
98
|
-
"logical_path" => logical_path,
|
|
99
|
-
"mtime" => stat.mtime.iso8601,
|
|
100
|
-
"size" => stat.size,
|
|
101
|
-
"digest" => nil
|
|
102
|
-
}
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def remove(logical_path)
|
|
106
|
-
if digested = assets.delete(logical_path)
|
|
107
|
-
files.delete(digested)
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def remove_digest(logical_path)
|
|
112
|
-
asset_path(logical_path) do |digested, logical_path|
|
|
113
|
-
assets[logical_path] = logical_path
|
|
114
|
-
files[logical_path] = files.delete(digested).tap { |f| f["digest"] = nil }
|
|
115
|
-
|
|
116
|
-
yield digested, logical_path if block_given?
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def assets
|
|
121
|
-
@manifest["assets"]
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def files
|
|
125
|
-
@manifest["files"]
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def dump
|
|
129
|
-
JSON.generate(@manifest)
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def write
|
|
133
|
-
File.open(@file, "wb") { |f| f.write(dump) }
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
class NullManifest < AssetManifest
|
|
138
|
-
def append(*); end
|
|
139
|
-
def remove(*); end
|
|
140
|
-
def remove_digest(*); end
|
|
141
|
-
def assets; {}; end
|
|
142
|
-
def each(*); end
|
|
143
|
-
def write; end
|
|
144
|
-
end
|
|
39
|
+
require_relative "asset_manifest/json_manifest"
|
|
40
|
+
require_relative "asset_manifest/null_manifest"
|
|
41
|
+
require_relative "asset_manifest/propshaft_manifest"
|
|
42
|
+
require_relative "asset_manifest/yaml_manifest"
|
|
145
43
|
end
|
|
146
44
|
end
|
data/lib/tinymce/rails/engine.rb
CHANGED
|
@@ -13,14 +13,27 @@ module TinyMCE::Rails
|
|
|
13
13
|
# :copy - copies across the TinyMCE assets statically
|
|
14
14
|
config.tinymce.install = :compile
|
|
15
15
|
|
|
16
|
+
# Set default attributes for script source tags (defaults to data-turbolinks-track="reload" for backwards compatibility)
|
|
17
|
+
config.tinymce.default_script_attributes = { "data-turbolinks-track" => "reload" }
|
|
18
|
+
|
|
16
19
|
initializer "precompile", :group => :all do |app|
|
|
17
20
|
if config.tinymce.install == :compile
|
|
18
21
|
app.config.assets.precompile << "tinymce-rails.manifest.js" # Sprockets 4 manifest
|
|
19
22
|
app.config.assets.precompile << "tinymce/*" # Sprockets 3
|
|
20
23
|
end
|
|
21
24
|
|
|
22
|
-
app.config.assets.precompile << "tinymce.js"
|
|
23
|
-
end
|
|
25
|
+
app.config.assets.precompile << "tinymce.js" << "tinymce-jquery.js"
|
|
26
|
+
end if defined?(Sprockets)
|
|
27
|
+
|
|
28
|
+
initializer "propshaft" do |app|
|
|
29
|
+
config.assets.excluded_paths << root.join("app/assets/sprockets")
|
|
30
|
+
|
|
31
|
+
if config.assets.server
|
|
32
|
+
# Monkey-patch Propshaft::Asset to enable access
|
|
33
|
+
# of TinyMCE assets without a hash digest.
|
|
34
|
+
require_relative "propshaft/asset"
|
|
35
|
+
end
|
|
36
|
+
end if defined?(Propshaft)
|
|
24
37
|
|
|
25
38
|
initializer "helper" do |app|
|
|
26
39
|
ActiveSupport.on_load(:action_view) do
|