tinymce-rails 7.2.0 → 7.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|