@richscripts/richtexteditor 2.14.0 → 2.15.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.
- package/README.md +173 -10
- package/angular/build-manifest.json +23 -0
- package/angular/index.d.ts +71 -76
- package/angular/index.mjs +2 -0
- package/angular/package.json +4 -0
- package/headless/index.d.ts +3 -1
- package/headless/index.js +72 -16
- package/index.d.ts +33 -54
- package/integrations/initialization-scope.js +27 -0
- package/integrations/native-mount.js +30 -0
- package/integrations/shared.d.ts +23 -1
- package/integrations/shared.js +58 -22
- package/package.json +25 -3
- package/react/index.js +118 -37
- package/react/index.mjs +29 -0
- package/richtexteditor/all_plugins.js +7113 -1111
- package/richtexteditor/all_plugins.min.js +62 -59
- package/richtexteditor/lang/emoji/LICENSE-CLDR.txt +41 -0
- package/richtexteditor/lang/emoji/rte-emoji-de.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-es.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-fr.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-it.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-ja.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-ko.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-nl.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-pt-pt.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-pt.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-ru.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-zh-Hans.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-zh-Hant.js +3 -0
- package/richtexteditor/lang/rte-lang-af.js +1 -0
- package/richtexteditor/lang/rte-lang-ar.js +1 -0
- package/richtexteditor/lang/rte-lang-bg.js +1 -0
- package/richtexteditor/lang/rte-lang-bn.js +1 -0
- package/richtexteditor/lang/rte-lang-bs.js +1 -0
- package/richtexteditor/lang/rte-lang-ca.js +1 -0
- package/richtexteditor/lang/rte-lang-cs.js +1 -0
- package/richtexteditor/lang/rte-lang-cy.js +1 -0
- package/richtexteditor/lang/rte-lang-da.js +1 -0
- package/richtexteditor/lang/rte-lang-de.js +1017 -2
- package/richtexteditor/lang/rte-lang-el.js +1 -0
- package/richtexteditor/lang/rte-lang-en.js +1 -0
- package/richtexteditor/lang/rte-lang-es.js +1023 -2
- package/richtexteditor/lang/rte-lang-et.js +1 -0
- package/richtexteditor/lang/rte-lang-fa.js +1 -0
- package/richtexteditor/lang/rte-lang-fi.js +1 -0
- package/richtexteditor/lang/rte-lang-fil.js +1 -0
- package/richtexteditor/lang/rte-lang-fj.js +1 -0
- package/richtexteditor/lang/rte-lang-fr.js +1023 -2
- package/richtexteditor/lang/rte-lang-ga.js +1 -0
- package/richtexteditor/lang/rte-lang-gu.js +1 -0
- package/richtexteditor/lang/rte-lang-he.js +1 -0
- package/richtexteditor/lang/rte-lang-hi.js +1 -0
- package/richtexteditor/lang/rte-lang-hr.js +1 -0
- package/richtexteditor/lang/rte-lang-ht.js +1 -0
- package/richtexteditor/lang/rte-lang-hu.js +1 -0
- package/richtexteditor/lang/rte-lang-id.js +1 -0
- package/richtexteditor/lang/rte-lang-is.js +1 -0
- package/richtexteditor/lang/rte-lang-it.js +1023 -2
- package/richtexteditor/lang/rte-lang-ja.js +1023 -2
- package/richtexteditor/lang/rte-lang-kn.js +1 -0
- package/richtexteditor/lang/rte-lang-ko.js +1023 -2
- package/richtexteditor/lang/rte-lang-lt.js +1 -0
- package/richtexteditor/lang/rte-lang-lv.js +1 -0
- package/richtexteditor/lang/rte-lang-mg.js +1 -0
- package/richtexteditor/lang/rte-lang-mi.js +1 -0
- package/richtexteditor/lang/rte-lang-ml.js +1 -0
- package/richtexteditor/lang/rte-lang-mr.js +1 -0
- package/richtexteditor/lang/rte-lang-ms.js +1 -0
- package/richtexteditor/lang/rte-lang-mt.js +1 -0
- package/richtexteditor/lang/rte-lang-mww.js +1 -0
- package/richtexteditor/lang/rte-lang-nb.js +1 -0
- package/richtexteditor/lang/rte-lang-nl.js +1023 -2
- package/richtexteditor/lang/rte-lang-otq.js +1 -0
- package/richtexteditor/lang/rte-lang-pa.js +1 -0
- package/richtexteditor/lang/rte-lang-pl.js +1 -0
- package/richtexteditor/lang/rte-lang-pt-pt.js +1023 -2
- package/richtexteditor/lang/rte-lang-pt.js +1023 -2
- package/richtexteditor/lang/rte-lang-ro.js +1 -0
- package/richtexteditor/lang/rte-lang-ru.js +1023 -2
- package/richtexteditor/lang/rte-lang-sk.js +1 -0
- package/richtexteditor/lang/rte-lang-sl.js +1 -0
- package/richtexteditor/lang/rte-lang-sm.js +1 -0
- package/richtexteditor/lang/rte-lang-sr-Cyrl.js +1 -0
- package/richtexteditor/lang/rte-lang-sr-Latn.js +1 -0
- package/richtexteditor/lang/rte-lang-sv.js +1 -0
- package/richtexteditor/lang/rte-lang-sw.js +1 -0
- package/richtexteditor/lang/rte-lang-ta.js +1 -0
- package/richtexteditor/lang/rte-lang-te.js +1 -0
- package/richtexteditor/lang/rte-lang-th.js +1 -0
- package/richtexteditor/lang/rte-lang-tlh-Latn.js +1 -0
- package/richtexteditor/lang/rte-lang-tlh-Piqd.js +1 -0
- package/richtexteditor/lang/rte-lang-to.js +1 -0
- package/richtexteditor/lang/rte-lang-tr.js +1 -0
- package/richtexteditor/lang/rte-lang-ty.js +1 -0
- package/richtexteditor/lang/rte-lang-uk.js +1 -0
- package/richtexteditor/lang/rte-lang-ur.js +1 -0
- package/richtexteditor/lang/rte-lang-vi.js +1 -0
- package/richtexteditor/lang/rte-lang-yua.js +1 -0
- package/richtexteditor/lang/rte-lang-zh-Hans.js +1017 -2
- package/richtexteditor/lang/rte-lang-zh-Hant.js +1017 -2
- package/richtexteditor/plugins/a11yenhance.js +2 -1
- package/richtexteditor/plugins/a11yenhance.min.js +1 -1
- package/richtexteditor/plugins/accessibilitychecker.js +252 -60
- package/richtexteditor/plugins/accessibilitychecker.min.js +1 -1
- package/richtexteditor/plugins/aitoolkit.js +966 -303
- package/richtexteditor/plugins/aitoolkit.min.js +7 -7
- package/richtexteditor/plugins/all_plugins.js +7113 -1111
- package/richtexteditor/plugins/all_plugins.min.js +62 -59
- package/richtexteditor/plugins/autocorrect.js +66 -31
- package/richtexteditor/plugins/autocorrect.min.js +1 -1
- package/richtexteditor/plugins/autoembed.js +17 -0
- package/richtexteditor/plugins/autoembed.min.js +1 -1
- package/richtexteditor/plugins/blocktypes.js +18 -9
- package/richtexteditor/plugins/blocktypes.min.js +1 -1
- package/richtexteditor/plugins/bookmarkcard.js +12 -5
- package/richtexteditor/plugins/bookmarkcard.min.js +2 -2
- package/richtexteditor/plugins/changecase.js +72 -19
- package/richtexteditor/plugins/changecase.min.js +1 -1
- package/richtexteditor/plugins/charlimit.js +62 -2
- package/richtexteditor/plugins/charlimit.min.js +2 -2
- package/richtexteditor/plugins/comments.js +458 -59
- package/richtexteditor/plugins/comments.min.js +4 -3
- package/richtexteditor/plugins/contentminimap.js +25 -6
- package/richtexteditor/plugins/contentminimap.min.js +1 -1
- package/richtexteditor/plugins/crossreference.js +1 -1
- package/richtexteditor/plugins/crossreference.min.js +1 -1
- package/richtexteditor/plugins/dialoga11y.js +26 -4
- package/richtexteditor/plugins/dialoga11y.min.js +1 -1
- package/richtexteditor/plugins/dictation.js +1 -1
- package/richtexteditor/plugins/documentimport.js +220 -51
- package/richtexteditor/plugins/documentimport.min.js +4 -4
- package/richtexteditor/plugins/documentoutline.js +88 -38
- package/richtexteditor/plugins/documentoutline.min.js +1 -1
- package/richtexteditor/plugins/docxexport.js +204 -32
- package/richtexteditor/plugins/docxexport.min.js +2 -2
- package/richtexteditor/plugins/draghandle.js +267 -3
- package/richtexteditor/plugins/draghandle.min.js +1 -1
- package/richtexteditor/plugins/emailtoolkit.js +28 -14
- package/richtexteditor/plugins/emailtoolkit.min.js +1 -1
- package/richtexteditor/plugins/emojiautocomplete.js +110 -56
- package/richtexteditor/plugins/emojiautocomplete.min.js +1 -1
- package/richtexteditor/plugins/footnotes.js +65 -11
- package/richtexteditor/plugins/footnotes.min.js +1 -1
- package/richtexteditor/plugins/formatpainter.js +10 -0
- package/richtexteditor/plugins/formatpainter.min.js +1 -1
- package/richtexteditor/plugins/formattingmarks.js +53 -8
- package/richtexteditor/plugins/formattingmarks.min.js +1 -1
- package/richtexteditor/plugins/gapcursor.js +60 -0
- package/richtexteditor/plugins/gapcursor.min.js +1 -1
- package/richtexteditor/plugins/ghostcomplete.js +1 -1
- package/richtexteditor/plugins/html2pdf.js +1 -1
- package/richtexteditor/plugins/html2pdf.min.js +1 -1
- package/richtexteditor/plugins/imageeditor.js +12 -6
- package/richtexteditor/plugins/imageeditor.min.js +1 -1
- package/richtexteditor/plugins/importstyles.js +1 -1
- package/richtexteditor/plugins/inlinecode.js +25 -0
- package/richtexteditor/plugins/inlinecode.min.js +1 -1
- package/richtexteditor/plugins/insertcode.js +21 -3
- package/richtexteditor/plugins/insertcode.min.js +4 -4
- package/richtexteditor/plugins/insertemoji.js +112 -15
- package/richtexteditor/plugins/insertemoji.min.js +1 -1
- package/richtexteditor/plugins/insertgallery.js +42 -36
- package/richtexteditor/plugins/insertgallery.min.js +1 -1
- package/richtexteditor/plugins/inserttemplate.js +33 -17
- package/richtexteditor/plugins/inserttemplate.min.js +1 -1
- package/richtexteditor/plugins/keyboarda11y.js +66 -3
- package/richtexteditor/plugins/keyboarda11y.min.js +1 -1
- package/richtexteditor/plugins/layouttable.js +20 -0
- package/richtexteditor/plugins/layouttable.min.js +1 -1
- package/richtexteditor/plugins/linkchecker.js +29 -9
- package/richtexteditor/plugins/linkchecker.min.js +1 -1
- package/richtexteditor/plugins/localdraft.js +51 -7
- package/richtexteditor/plugins/localdraft.min.js +1 -1
- package/richtexteditor/plugins/markdownexport.js +159 -0
- package/richtexteditor/plugins/markdownexport.min.js +2 -2
- package/richtexteditor/plugins/mathdialog.js +11 -5
- package/richtexteditor/plugins/mathdialog.min.js +1 -1
- package/richtexteditor/plugins/mentionplugin.js +88 -25
- package/richtexteditor/plugins/mentionplugin.min.js +1 -1
- package/richtexteditor/plugins/mermaiddiagram.js +9 -3
- package/richtexteditor/plugins/mermaiddiagram.min.js +2 -2
- package/richtexteditor/plugins/multilevellist.js +4 -0
- package/richtexteditor/plugins/multilevellist.min.js +1 -1
- package/richtexteditor/plugins/pdfexport.js +235 -35
- package/richtexteditor/plugins/pdfexport.min.js +12 -12
- package/richtexteditor/plugins/permanentpen.js +3 -3
- package/richtexteditor/plugins/permanentpen.min.js +1 -1
- package/richtexteditor/plugins/readabilitystats.js +25 -11
- package/richtexteditor/plugins/readabilitystats.min.js +1 -1
- package/richtexteditor/plugins/readaloud.js +29 -15
- package/richtexteditor/plugins/readaloud.min.js +1 -1
- package/richtexteditor/plugins/restrictedediting.js +166 -0
- package/richtexteditor/plugins/restrictedediting.min.js +2 -2
- package/richtexteditor/plugins/revisionhistory.js +169 -37
- package/richtexteditor/plugins/revisionhistory.min.js +3 -3
- package/richtexteditor/plugins/rubyannotation.js +19 -9
- package/richtexteditor/plugins/rubyannotation.min.js +1 -1
- package/richtexteditor/plugins/sanitizer.js +86 -4
- package/richtexteditor/plugins/sanitizer.min.js +1 -1
- package/richtexteditor/plugins/slashcommand.js +30 -16
- package/richtexteditor/plugins/slashcommand.min.js +2 -2
- package/richtexteditor/plugins/smartchips.js +36 -22
- package/richtexteditor/plugins/smartchips.min.js +2 -2
- package/richtexteditor/plugins/spellcheck.js +17 -8
- package/richtexteditor/plugins/spellcheck.min.js +2 -2
- package/richtexteditor/plugins/stateinspector.js +19 -9
- package/richtexteditor/plugins/stateinspector.min.js +2 -2
- package/richtexteditor/plugins/structured-content-bridge.js +56 -24
- package/richtexteditor/plugins/structured-content-bridge.min.js +7 -7
- package/richtexteditor/plugins/tableofcontents.js +5 -2
- package/richtexteditor/plugins/tableofcontents.min.js +1 -1
- package/richtexteditor/plugins/tabletools.js +388 -3
- package/richtexteditor/plugins/tabletools.min.js +1 -1
- package/richtexteditor/plugins/textdirection.js +18 -5
- package/richtexteditor/plugins/textdirection.min.js +1 -1
- package/richtexteditor/plugins/textpartlanguage.js +161 -32
- package/richtexteditor/plugins/textpartlanguage.min.js +1 -1
- package/richtexteditor/plugins/todolist.js +90 -6
- package/richtexteditor/plugins/todolist.min.js +1 -1
- package/richtexteditor/plugins/trackedchanges.js +1812 -25
- package/richtexteditor/plugins/trackedchanges.min.js +5 -3
- package/richtexteditor/plugins/wordexport.js +2 -2
- package/richtexteditor/plugins/yjscollab.js +9 -4
- package/richtexteditor/plugins/yjscollab.min.js +1 -1
- package/richtexteditor/plugins/zz_richtextbox_dialog_style.js +22 -13
- package/richtexteditor/plugins/zz_richtextbox_dialog_style.min.js +1 -1
- package/richtexteditor/rte-config.js +131 -50
- package/richtexteditor/rte-headless.js +19 -4
- package/richtexteditor/rte-webcomponent.js +89 -16
- package/richtexteditor/rte.js +133 -52
- package/richtexteditor/runtime/colorpicker_more_ns.htm +93 -16
- package/scripts/build-angular.mjs +97 -0
- package/svelte/index.d.ts +2 -1
- package/svelte/index.js +80 -9
- package/vue/index.js +130 -34
- package/angular/component.ts +0 -297
- package/angular/index.ts +0 -24
|
@@ -31,7 +31,31 @@ function RTE_Plugin_TableTools() {
|
|
|
31
31
|
|
|
32
32
|
obj.PluginName = "TableTools";
|
|
33
33
|
|
|
34
|
-
obj.InitConfig = function (argconfig) {
|
|
34
|
+
obj.InitConfig = function (argconfig) {
|
|
35
|
+
config = argconfig;
|
|
36
|
+
// 2026-10-15 Move Row Up/Down and Move Column Left/Right in the table menus: the single-pointer way to do what
|
|
37
|
+
// the row and column grips do by dragging (WCAG 2.2 SC 2.5.7, Dragging Movements). tools/tables/table-move-buttons.mjs
|
|
38
|
+
appendMenuItems("subtoolbar_tablerow", ["tablerowmoveup", "tablerowmovedown"]);
|
|
39
|
+
appendMenuItems("subtoolbar_tablecolumn", ["tablecolumnmoveleft", "tablecolumnmoveright"]);
|
|
40
|
+
var labels = { tablerowmoveup: "Move Row Up", tablerowmovedown: "Move Row Down", tablecolumnmoveleft: "Move Column Left", tablecolumnmoveright: "Move Column Right" };
|
|
41
|
+
var arrows = { tablerowmoveup: "M12 19V5M6 11l6-6 6 6", tablerowmovedown: "M12 5v14M6 13l6 6 6-6", tablecolumnmoveleft: "M19 12H5M11 6l-6 6 6 6", tablecolumnmoveright: "M5 12h14M13 6l6 6-6 6" };
|
|
42
|
+
for (var k in labels) {
|
|
43
|
+
if (config["text_" + k] == null) config["text_" + k] = labels[k];
|
|
44
|
+
if (config["svgCode_" + k] == null) config["svgCode_" + k] = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="' + arrows[k] + '"/></svg>';
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// subtoolbar_* lists are comma-separated, sometimes inside braces
|
|
49
|
+
function appendMenuItems(name, items) {
|
|
50
|
+
var val = config[name];
|
|
51
|
+
if (typeof val !== "string" || !val) return;
|
|
52
|
+
for (var i = 0; i < items.length; i++) {
|
|
53
|
+
if (val.indexOf(items[i]) !== -1) continue;
|
|
54
|
+
var at = val.lastIndexOf("}");
|
|
55
|
+
val = at === -1 ? val + "," + items[i] : val.substring(0, at) + "," + items[i] + val.substring(at);
|
|
56
|
+
}
|
|
57
|
+
config[name] = val;
|
|
58
|
+
}
|
|
35
59
|
|
|
36
60
|
obj.InitEditor = function (argeditor) {
|
|
37
61
|
editor = argeditor;
|
|
@@ -51,6 +75,22 @@ function RTE_Plugin_TableTools() {
|
|
|
51
75
|
editor.canSortTable = function () { return canSort(tableAtCaret()); };
|
|
52
76
|
editor.addTableRowNumbers = function (opts) { return obj.AddRowNumbers(opts); };
|
|
53
77
|
editor.removeTableRowNumbers = function () { return obj.RemoveRowNumbers(); };
|
|
78
|
+
["tablerowmoveup", "tablerowmovedown", "tablecolumnmoveleft", "tablecolumnmoveright"].forEach(function (cmd) {
|
|
79
|
+
editor.toolbarFactoryMap = editor.toolbarFactoryMap || {};
|
|
80
|
+
if (!editor.toolbarFactoryMap[cmd]) editor.toolbarFactoryMap[cmd] = function (c) { return editor.createToolbarButton(c); };
|
|
81
|
+
editor.attachEvent("exec_command_" + cmd, function (state) {
|
|
82
|
+
state.returnValue = true;
|
|
83
|
+
state.stopBubble = true;
|
|
84
|
+
if (cmd === "tablerowmoveup") moveRowBy(-1);
|
|
85
|
+
else if (cmd === "tablerowmovedown") moveRowBy(1);
|
|
86
|
+
else if (cmd === "tablecolumnmoveleft") moveColumnBy(-1);
|
|
87
|
+
else moveColumnBy(1);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
editor.moveTableRow = function (dir) { return moveRowBy(dir < 0 ? -1 : 1); };
|
|
91
|
+
editor.moveTableColumn = function (dir) { return moveColumnBy(dir < 0 ? -1 : 1); };
|
|
92
|
+
if (config.tableRowDrag !== false) initRowDrag();
|
|
93
|
+
if (config.tableColumnDrag !== false) initColumnDrag();
|
|
54
94
|
editor.hasTableRowNumbers = function () {
|
|
55
95
|
var t = tableAtCaret();
|
|
56
96
|
return !!(t && t.querySelector("[data-rte-rownum]"));
|
|
@@ -142,7 +182,7 @@ function RTE_Plugin_TableTools() {
|
|
|
142
182
|
if (/\d/.test(t)) {
|
|
143
183
|
// Strip currency, spaces, thousands separators; (500) is accounting
|
|
144
184
|
// notation for negative.
|
|
145
|
-
var num = t.replace(/[\s
|
|
185
|
+
var num = t.replace(/[\s\xa0,]/g, "").replace(/^\(([^)]*)\)$/, "-$1").replace(/[^0-9.eE+-]/g, "");
|
|
146
186
|
if (num && /^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/.test(num)) {
|
|
147
187
|
return { type: "number", v: parseFloat(num) };
|
|
148
188
|
}
|
|
@@ -179,6 +219,11 @@ function RTE_Plugin_TableTools() {
|
|
|
179
219
|
obj.Sort = function (table, index, dir) {
|
|
180
220
|
var check = canSort(table);
|
|
181
221
|
if (!check.ok) return check;
|
|
222
|
+
// 2026-10-14 Suggesting mode: a sort reorders rows and is not tracked yet, so the track hook refuses it.
|
|
223
|
+
// tools/tables/table-row-move.mjs
|
|
224
|
+
if (editor.__trackHook && editor.__trackHook("move", { direction: 0 }) === true) {
|
|
225
|
+
return { ok: false, reason: "Suggesting is on, so the table was not sorted. Turn suggesting off to sort it." };
|
|
226
|
+
}
|
|
182
227
|
var descending = String(dir).toLowerCase() === "desc";
|
|
183
228
|
var rows = bodyRows(table);
|
|
184
229
|
var type = columnType(rows, index);
|
|
@@ -230,6 +275,337 @@ function RTE_Plugin_TableTools() {
|
|
|
230
275
|
return { ok: true, reason: "", sortedBy: index, direction: descending ? "desc" : "asc", detectedType: type };
|
|
231
276
|
};
|
|
232
277
|
|
|
278
|
+
// 2026-10-14 Row drag: a grip beside a body row drags that row to another place in its table. It is the same move
|
|
279
|
+
// as Alt+ArrowUp / Alt+ArrowDown, with the same limits: the header rows stay put, a table with merged cells is left
|
|
280
|
+
// alone, and suggesting mode refuses the move because a move is not tracked yet. config.tableRowDrag = false turns
|
|
281
|
+
// the grip off. Escape cancels a drag. tools/tables/table-row-drag.mjs
|
|
282
|
+
// 2026-10-15 grips and drop lines use z-index 99998, under the floating table toolbar (99999), so they never cover
|
|
283
|
+
// its menu buttons. tools/tables/table-move-buttons.mjs
|
|
284
|
+
function initRowDrag() {
|
|
285
|
+
var frame = editor.iframe;
|
|
286
|
+
if (!frame || !frame.ownerDocument) return;
|
|
287
|
+
var host = frame.ownerDocument;
|
|
288
|
+
var edoc = editor.getDocument();
|
|
289
|
+
var grip = host.createElement("div");
|
|
290
|
+
grip.className = "rte-row-grip";
|
|
291
|
+
grip.setAttribute("aria-hidden", "true");
|
|
292
|
+
// 2026-10-15 this was the quoted text "String.fromCharCode(0x283f)", shown as code in the grip. tools/tables/table-column-drag.mjs
|
|
293
|
+
grip.textContent = "\u283f";
|
|
294
|
+
var gs = grip.style;
|
|
295
|
+
gs.position = "fixed"; gs.display = "none"; gs.zIndex = "99998"; gs.width = "12px"; gs.height = "22px";
|
|
296
|
+
gs.lineHeight = "22px"; gs.textAlign = "center"; gs.fontSize = "14px"; gs.color = "#64748b"; gs.cursor = "grab";
|
|
297
|
+
gs.userSelect = "none"; gs.borderRadius = "3px"; gs.background = "rgba(15,23,42,.06)";
|
|
298
|
+
var line = host.createElement("div");
|
|
299
|
+
line.className = "rte-row-drop";
|
|
300
|
+
var ls = line.style;
|
|
301
|
+
ls.position = "fixed"; ls.display = "none"; ls.zIndex = "99998"; ls.height = "2px";
|
|
302
|
+
ls.background = "#2563eb"; ls.pointerEvents = "none";
|
|
303
|
+
host.body.appendChild(grip);
|
|
304
|
+
host.body.appendChild(line);
|
|
305
|
+
|
|
306
|
+
var hoverRow = null, hideTid = 0, drag = null;
|
|
307
|
+
|
|
308
|
+
function frameRect() { return frame.getBoundingClientRect(); }
|
|
309
|
+
function inEditable(node) { try { return !!editor.getEditable() && editor.getEditable().contains(node); } catch (e) { return false; } }
|
|
310
|
+
// The row under a node, if it is a body row that may move.
|
|
311
|
+
function movableRowAt(node) {
|
|
312
|
+
var el = node && node.nodeType === 1 ? node : (node && node.parentNode);
|
|
313
|
+
while (el && el.nodeName !== "TR") el = el.parentNode;
|
|
314
|
+
if (!el || !inEditable(el)) return null;
|
|
315
|
+
var sec = el.parentNode && el.parentNode.nodeName;
|
|
316
|
+
if (sec === "THEAD" || sec === "TFOOT") return null;
|
|
317
|
+
var table = el.closest ? el.closest("table") : null;
|
|
318
|
+
if (!table || bodyRows(table).indexOf(el) < 0) return null;
|
|
319
|
+
return el;
|
|
320
|
+
}
|
|
321
|
+
function placeGrip(row) {
|
|
322
|
+
var fr = frameRect(), tr = row.getBoundingClientRect(), table = row.closest("table");
|
|
323
|
+
var left = table.getBoundingClientRect().left - 14;
|
|
324
|
+
// no room in the gutter: no grip, so it never covers the first cell (the keyboard still moves rows)
|
|
325
|
+
if (left < fr.left) { gs.display = "none"; return; }
|
|
326
|
+
gs.left = Math.round(left) + "px";
|
|
327
|
+
gs.top = Math.round(fr.top + tr.top + tr.height / 2 - 11) + "px";
|
|
328
|
+
gs.display = "block";
|
|
329
|
+
}
|
|
330
|
+
function hideGripSoon() {
|
|
331
|
+
clearTimeout(hideTid);
|
|
332
|
+
hideTid = setTimeout(function () { if (!drag) { gs.display = "none"; hoverRow = null; } }, 350);
|
|
333
|
+
}
|
|
334
|
+
// a pointer event from the editing frame has its y in the frame; the grip lives in the host page
|
|
335
|
+
function hostY(e) { return e.view === frame.contentWindow ? frameRect().top + e.clientY : e.clientY; }
|
|
336
|
+
function hasMergedCells(table) {
|
|
337
|
+
var rows = bodyRows(table);
|
|
338
|
+
for (var i = 0; i < rows.length; i++) for (var c = 0; c < rows[i].cells.length; c++) {
|
|
339
|
+
var cell = rows[i].cells[c];
|
|
340
|
+
if ((cell.rowSpan || 1) > 1 || (cell.colSpan || 1) > 1) return true;
|
|
341
|
+
}
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
function say(text) { try { if (typeof editor.announce === "function") editor.announce(text); } catch (e) { /* ignore */ } }
|
|
345
|
+
|
|
346
|
+
edoc.addEventListener("mousemove", function (e) {
|
|
347
|
+
if (drag) return;
|
|
348
|
+
var row = movableRowAt(e.target);
|
|
349
|
+
if (row) { clearTimeout(hideTid); hoverRow = row; placeGrip(row); } else { hideGripSoon(); }
|
|
350
|
+
});
|
|
351
|
+
grip.addEventListener("mouseenter", function () { clearTimeout(hideTid); });
|
|
352
|
+
grip.addEventListener("mouseleave", hideGripSoon);
|
|
353
|
+
|
|
354
|
+
function endDrag() {
|
|
355
|
+
drag = null;
|
|
356
|
+
host.removeEventListener("mousemove", onDragMove, true);
|
|
357
|
+
edoc.removeEventListener("mousemove", onDragMove, true);
|
|
358
|
+
host.removeEventListener("mouseup", onDragEnd, true);
|
|
359
|
+
edoc.removeEventListener("mouseup", onDragEnd, true);
|
|
360
|
+
host.removeEventListener("keydown", onDragKey, true);
|
|
361
|
+
edoc.removeEventListener("keydown", onDragKey, true);
|
|
362
|
+
ls.display = "none"; gs.display = "none"; gs.cursor = "grab";
|
|
363
|
+
}
|
|
364
|
+
function onDragMove(e) {
|
|
365
|
+
if (!drag) return;
|
|
366
|
+
var y = hostY(e), fr = frameRect(), rows = drag.rows, drop = rows.length;
|
|
367
|
+
for (var i = 0; i < rows.length; i++) {
|
|
368
|
+
var rr = rows[i].getBoundingClientRect();
|
|
369
|
+
if (y < fr.top + rr.top + rr.height / 2) { drop = i; break; }
|
|
370
|
+
}
|
|
371
|
+
drag.drop = drop;
|
|
372
|
+
// dropping the row where it already is, or just below itself, changes nothing
|
|
373
|
+
var noop = drop === drag.from || drop === drag.from + 1;
|
|
374
|
+
drag.noop = noop;
|
|
375
|
+
var at = drop < rows.length ? fr.top + rows[drop].getBoundingClientRect().top
|
|
376
|
+
: fr.top + rows[rows.length - 1].getBoundingClientRect().bottom;
|
|
377
|
+
var tb = drag.table.getBoundingClientRect();
|
|
378
|
+
ls.left = Math.round(fr.left + tb.left) + "px";
|
|
379
|
+
ls.width = Math.round(tb.width) + "px";
|
|
380
|
+
ls.top = Math.round(at - 1) + "px";
|
|
381
|
+
ls.display = noop ? "none" : "block";
|
|
382
|
+
}
|
|
383
|
+
function moveRow(d) {
|
|
384
|
+
// 2026-10-14 Read-only (designMode off) or comments-only: a move changes the document, so it does nothing. tools/review/readonly-audit.mjs
|
|
385
|
+
try { if (String(editor.getDocument().designMode).toLowerCase() === "off" || (editor.getCommentsOnly && editor.getCommentsOnly())) return false; } catch (e) { /* ignore */ }
|
|
386
|
+
if (hasMergedCells(d.table)) { say("This table has merged cells, so the row was not moved."); return false; }
|
|
387
|
+
// a move is not tracked yet: suggesting mode refuses it (the track hook answers "move")
|
|
388
|
+
if (editor.__trackHook && editor.__trackHook("move", { direction: 0 }) === true) return false;
|
|
389
|
+
var ref = d.drop < d.rows.length ? d.rows[d.drop] : null;
|
|
390
|
+
if (typeof editor.recordUndo === "function") editor.recordUndo();
|
|
391
|
+
d.row.parentNode.insertBefore(d.row, ref);
|
|
392
|
+
renumber(d.table);
|
|
393
|
+
// the caret goes into the moved row and the editor takes focus, so Ctrl+Z reaches the editor (as after Alt+Arrow)
|
|
394
|
+
try { restoreCaret(d.row.cells[0]); if (typeof editor.focus === "function") editor.focus(); } catch (e) { /* ignore */ }
|
|
395
|
+
fireChange();
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
function onDragEnd(e) {
|
|
399
|
+
if (!drag) return;
|
|
400
|
+
var d = drag;
|
|
401
|
+
endDrag();
|
|
402
|
+
if (d.drop < 0 || d.noop) return;
|
|
403
|
+
moveRow(d);
|
|
404
|
+
}
|
|
405
|
+
function onDragKey(e) {
|
|
406
|
+
if (e.key === "Escape") { endDrag(); }
|
|
407
|
+
}
|
|
408
|
+
grip.addEventListener("mousedown", function (e) {
|
|
409
|
+
if (!hoverRow || e.button !== 0) return;
|
|
410
|
+
e.preventDefault();
|
|
411
|
+
var table = hoverRow.closest("table");
|
|
412
|
+
var rows = bodyRows(table).filter(function (r) { return r.parentNode === hoverRow.parentNode; });
|
|
413
|
+
drag = { row: hoverRow, table: table, rows: rows, from: rows.indexOf(hoverRow), drop: -1, noop: true };
|
|
414
|
+
gs.cursor = "grabbing";
|
|
415
|
+
host.addEventListener("mousemove", onDragMove, true);
|
|
416
|
+
edoc.addEventListener("mousemove", onDragMove, true);
|
|
417
|
+
host.addEventListener("mouseup", onDragEnd, true);
|
|
418
|
+
edoc.addEventListener("mouseup", onDragEnd, true);
|
|
419
|
+
host.addEventListener("keydown", onDragKey, true);
|
|
420
|
+
edoc.addEventListener("keydown", onDragKey, true);
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// 2026-10-15 Column drag: a grip above a column drags it to another place in its table (Tiptap, CKEditor and
|
|
425
|
+
// BlockNote move columns). Every row moves the cell, header rows too, and the column's <col> width goes with it.
|
|
426
|
+
// Same limits as the row grip: merged cells or ragged rows leave the table alone, suggesting mode refuses (a move
|
|
427
|
+
// is not tracked), read-only does nothing, and the row-number column stays first. config.tableColumnDrag = false
|
|
428
|
+
// turns it off; Escape cancels. tools/tables/table-column-drag.mjs
|
|
429
|
+
function say(text) { try { if (typeof editor.announce === "function") editor.announce(text); } catch (e) { /* ignore */ } }
|
|
430
|
+
// read-only and comments-only change nothing; suggesting mode refuses a move, which is not tracked yet
|
|
431
|
+
function moveRefused() {
|
|
432
|
+
try { if (String(editor.getDocument().designMode).toLowerCase() === "off" || (editor.getCommentsOnly && editor.getCommentsOnly())) return true; } catch (e) { /* ignore */ }
|
|
433
|
+
return !!(editor.__trackHook && editor.__trackHook("move", { direction: 0 }) === true);
|
|
434
|
+
}
|
|
435
|
+
// a rectangular table: every row has the same number of cells and none spans
|
|
436
|
+
function isRectangular(table) {
|
|
437
|
+
var rows = table.rows, n = rows.length ? rows[0].cells.length : 0;
|
|
438
|
+
for (var i = 0; i < rows.length; i++) {
|
|
439
|
+
if (rows[i].cells.length !== n) return false;
|
|
440
|
+
for (var c = 0; c < n; c++) if ((rows[i].cells[c].rowSpan || 1) > 1 || (rows[i].cells[c].colSpan || 1) > 1) return false;
|
|
441
|
+
}
|
|
442
|
+
return n > 1;
|
|
443
|
+
}
|
|
444
|
+
// the first column that may move: the row-number column stays put
|
|
445
|
+
function firstMovableColumn(table) { return table.querySelector("[data-rte-rownum]") ? 1 : 0; }
|
|
446
|
+
// Move column `from` so it sits before column `drop` (drop = column count: to the end). caretCell, when given,
|
|
447
|
+
// keeps the caret; otherwise it goes into the moved column's first body cell.
|
|
448
|
+
function moveColumnTo(table, from, drop, caretCell) {
|
|
449
|
+
if (moveRefused()) return false;
|
|
450
|
+
if (!isRectangular(table)) { say("This table has merged cells, so the column was not moved."); return false; }
|
|
451
|
+
var rows = table.rows, n = rows[0].cells.length;
|
|
452
|
+
if (from < 0 || from >= n || drop < 0 || drop > n || drop === from || drop === from + 1) return false;
|
|
453
|
+
if (typeof editor.recordUndo === "function") editor.recordUndo();
|
|
454
|
+
for (var i = 0; i < rows.length; i++) {
|
|
455
|
+
var cells = rows[i].cells;
|
|
456
|
+
rows[i].insertBefore(cells[from], drop < n ? cells[drop] : null);
|
|
457
|
+
}
|
|
458
|
+
// the <col> widths follow, when the colgroup describes these columns (it may leave out the number column)
|
|
459
|
+
var cols = [];
|
|
460
|
+
for (var k = 0; k < table.children.length; k++) {
|
|
461
|
+
var g = table.children[k];
|
|
462
|
+
if (g.nodeName === "COLGROUP") for (var m = 0; m < g.children.length; m++) if (g.children[m].nodeName === "COL") cols.push(g.children[m]);
|
|
463
|
+
}
|
|
464
|
+
var off = n - cols.length, spans = false;
|
|
465
|
+
for (var s = 0; s < cols.length; s++) if ((parseInt(cols[s].getAttribute("span"), 10) || 1) > 1) spans = true;
|
|
466
|
+
if (cols.length && !spans && (off === 0 || off === firstMovableColumn(table)) && from >= off) {
|
|
467
|
+
var col = cols[from - off], ref = drop < n ? cols[drop - off] : null;
|
|
468
|
+
if (col && col !== ref) (ref ? ref.parentNode : col.parentNode).insertBefore(col, ref);
|
|
469
|
+
}
|
|
470
|
+
var at = drop > from ? drop - 1 : drop;
|
|
471
|
+
try { restoreCaret(caretCell || rows[rows.length > 1 ? 1 : 0].cells[at]); if (typeof editor.focus === "function") editor.focus(); } catch (e) { /* ignore */ }
|
|
472
|
+
fireChange();
|
|
473
|
+
return true;
|
|
474
|
+
}
|
|
475
|
+
function moveColumnBy(dir) {
|
|
476
|
+
var cell = cellAtCaret();
|
|
477
|
+
if (!cell || cell.hasAttribute("data-rte-rownum")) return false;
|
|
478
|
+
var table = cell.closest("table");
|
|
479
|
+
if (!table || !table.rows.length) return false;
|
|
480
|
+
var from = cell.cellIndex, n = table.rows[0].cells.length;
|
|
481
|
+
if (dir < 0 ? from - 1 < firstMovableColumn(table) : from + 1 >= n) return false;
|
|
482
|
+
return moveColumnTo(table, from, dir < 0 ? from - 1 : from + 2, cell);
|
|
483
|
+
}
|
|
484
|
+
// a body row moves one place within its section; header rows stay put, as for the grip and Alt+Arrow
|
|
485
|
+
function moveRowBy(dir) {
|
|
486
|
+
var cell = cellAtCaret();
|
|
487
|
+
if (!cell) return false;
|
|
488
|
+
var row = cell.parentNode, table = cell.closest("table");
|
|
489
|
+
var rows = bodyRows(table).filter(function (r) { return r.parentNode === row.parentNode; });
|
|
490
|
+
var i = rows.indexOf(row), j = i + (dir < 0 ? -1 : 1);
|
|
491
|
+
if (i < 0 || j < 0 || j >= rows.length) return false;
|
|
492
|
+
if (moveRefused()) return false;
|
|
493
|
+
for (var r = 0; r < rows.length; r++) for (var c = 0; c < rows[r].cells.length; c++) {
|
|
494
|
+
if ((rows[r].cells[c].rowSpan || 1) > 1 || (rows[r].cells[c].colSpan || 1) > 1) { say("This table has merged cells, so the row was not moved."); return false; }
|
|
495
|
+
}
|
|
496
|
+
if (typeof editor.recordUndo === "function") editor.recordUndo();
|
|
497
|
+
row.parentNode.insertBefore(row, dir < 0 ? rows[j] : rows[j].nextSibling);
|
|
498
|
+
renumber(table);
|
|
499
|
+
try { restoreCaret(cell); if (typeof editor.focus === "function") editor.focus(); } catch (e) { /* ignore */ }
|
|
500
|
+
fireChange();
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function initColumnDrag() {
|
|
505
|
+
var frame = editor.iframe;
|
|
506
|
+
if (!frame || !frame.ownerDocument) return;
|
|
507
|
+
var host = frame.ownerDocument;
|
|
508
|
+
var edoc = editor.getDocument();
|
|
509
|
+
var grip = host.createElement("div");
|
|
510
|
+
grip.className = "rte-col-grip";
|
|
511
|
+
grip.setAttribute("aria-hidden", "true");
|
|
512
|
+
grip.textContent = "\u283f";
|
|
513
|
+
var gs = grip.style;
|
|
514
|
+
gs.position = "fixed"; gs.display = "none"; gs.zIndex = "99998"; gs.width = "22px"; gs.height = "12px";
|
|
515
|
+
gs.lineHeight = "12px"; gs.textAlign = "center"; gs.fontSize = "12px"; gs.color = "#64748b"; gs.cursor = "grab";
|
|
516
|
+
gs.userSelect = "none"; gs.borderRadius = "3px"; gs.background = "rgba(15,23,42,.06)"; gs.overflow = "hidden";
|
|
517
|
+
var line = host.createElement("div");
|
|
518
|
+
line.className = "rte-col-drop";
|
|
519
|
+
var ls = line.style;
|
|
520
|
+
ls.position = "fixed"; ls.display = "none"; ls.zIndex = "99998"; ls.width = "2px";
|
|
521
|
+
ls.background = "#2563eb"; ls.pointerEvents = "none";
|
|
522
|
+
host.body.appendChild(grip);
|
|
523
|
+
host.body.appendChild(line);
|
|
524
|
+
|
|
525
|
+
var hoverCell = null, hideTid = 0, drag = null;
|
|
526
|
+
function frameRect() { return frame.getBoundingClientRect(); }
|
|
527
|
+
function inEditable(node) { try { return !!editor.getEditable() && editor.getEditable().contains(node); } catch (e) { return false; } }
|
|
528
|
+
function cellAt(node) {
|
|
529
|
+
var el = node && node.nodeType === 1 ? node : (node && node.parentNode);
|
|
530
|
+
while (el && el.nodeName !== "TD" && el.nodeName !== "TH") el = el.parentNode;
|
|
531
|
+
if (!el || !inEditable(el) || el.hasAttribute("data-rte-rownum")) return null;
|
|
532
|
+
return el.closest && el.closest("table") ? el : null;
|
|
533
|
+
}
|
|
534
|
+
function placeGrip(cell) {
|
|
535
|
+
var fr = frameRect(), cr = cell.getBoundingClientRect(), tb = cell.closest("table").getBoundingClientRect();
|
|
536
|
+
var top = fr.top + tb.top - 14;
|
|
537
|
+
// no room above the table: no grip, so it never covers the first row
|
|
538
|
+
if (top < fr.top) { gs.display = "none"; return; }
|
|
539
|
+
gs.left = Math.round(fr.left + cr.left + cr.width / 2 - 11) + "px";
|
|
540
|
+
gs.top = Math.round(top) + "px";
|
|
541
|
+
gs.display = "block";
|
|
542
|
+
}
|
|
543
|
+
function hideGripSoon() {
|
|
544
|
+
clearTimeout(hideTid);
|
|
545
|
+
hideTid = setTimeout(function () { if (!drag) { gs.display = "none"; hoverCell = null; } }, 350);
|
|
546
|
+
}
|
|
547
|
+
function hostX(e) { return e.view === frame.contentWindow ? frameRect().left + e.clientX : e.clientX; }
|
|
548
|
+
|
|
549
|
+
edoc.addEventListener("mousemove", function (e) {
|
|
550
|
+
if (drag) return;
|
|
551
|
+
var cell = cellAt(e.target);
|
|
552
|
+
if (cell) { clearTimeout(hideTid); hoverCell = cell; placeGrip(cell); } else { hideGripSoon(); }
|
|
553
|
+
});
|
|
554
|
+
grip.addEventListener("mouseenter", function () { clearTimeout(hideTid); });
|
|
555
|
+
grip.addEventListener("mouseleave", hideGripSoon);
|
|
556
|
+
|
|
557
|
+
function endDrag() {
|
|
558
|
+
drag = null;
|
|
559
|
+
host.removeEventListener("mousemove", onDragMove, true);
|
|
560
|
+
edoc.removeEventListener("mousemove", onDragMove, true);
|
|
561
|
+
host.removeEventListener("mouseup", onDragEnd, true);
|
|
562
|
+
edoc.removeEventListener("mouseup", onDragEnd, true);
|
|
563
|
+
host.removeEventListener("keydown", onDragKey, true);
|
|
564
|
+
edoc.removeEventListener("keydown", onDragKey, true);
|
|
565
|
+
ls.display = "none"; gs.display = "none"; gs.cursor = "grab";
|
|
566
|
+
}
|
|
567
|
+
function onDragMove(e) {
|
|
568
|
+
if (!drag) return;
|
|
569
|
+
var x = hostX(e), fr = frameRect(), cells = drag.table.rows[0].cells, n = cells.length, drop = n;
|
|
570
|
+
for (var i = drag.min; i < n; i++) {
|
|
571
|
+
var cr = cells[i].getBoundingClientRect();
|
|
572
|
+
if (x < fr.left + cr.left + cr.width / 2) { drop = i; break; }
|
|
573
|
+
}
|
|
574
|
+
drag.drop = drop;
|
|
575
|
+
// dropping the column where it already is, or just after itself, changes nothing
|
|
576
|
+
drag.noop = drop === drag.from || drop === drag.from + 1;
|
|
577
|
+
var at = drop < n ? fr.left + cells[drop].getBoundingClientRect().left : fr.left + cells[n - 1].getBoundingClientRect().right;
|
|
578
|
+
var tb = drag.table.getBoundingClientRect();
|
|
579
|
+
ls.left = Math.round(at - 1) + "px";
|
|
580
|
+
ls.top = Math.round(fr.top + tb.top) + "px";
|
|
581
|
+
ls.height = Math.round(tb.height) + "px";
|
|
582
|
+
ls.display = drag.noop ? "none" : "block";
|
|
583
|
+
}
|
|
584
|
+
function moveColumn(d) { return moveColumnTo(d.table, d.from, d.drop); }
|
|
585
|
+
function onDragEnd() {
|
|
586
|
+
if (!drag) return;
|
|
587
|
+
var d = drag;
|
|
588
|
+
endDrag();
|
|
589
|
+
if (d.drop < 0 || d.noop) return;
|
|
590
|
+
moveColumn(d);
|
|
591
|
+
}
|
|
592
|
+
function onDragKey(e) { if (e.key === "Escape") endDrag(); }
|
|
593
|
+
grip.addEventListener("mousedown", function (e) {
|
|
594
|
+
if (!hoverCell || e.button !== 0) return;
|
|
595
|
+
e.preventDefault();
|
|
596
|
+
var table = hoverCell.closest("table");
|
|
597
|
+
if (!table.rows.length) return;
|
|
598
|
+
drag = { table: table, from: hoverCell.cellIndex, min: firstMovableColumn(table), drop: -1, noop: true };
|
|
599
|
+
gs.cursor = "grabbing";
|
|
600
|
+
host.addEventListener("mousemove", onDragMove, true);
|
|
601
|
+
edoc.addEventListener("mousemove", onDragMove, true);
|
|
602
|
+
host.addEventListener("mouseup", onDragEnd, true);
|
|
603
|
+
edoc.addEventListener("mouseup", onDragEnd, true);
|
|
604
|
+
host.addEventListener("keydown", onDragKey, true);
|
|
605
|
+
edoc.addEventListener("keydown", onDragKey, true);
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
|
|
233
609
|
// ---- row numbering ----------------------------------------------------
|
|
234
610
|
|
|
235
611
|
function seriesLabel(n, series) {
|
|
@@ -259,7 +635,13 @@ function RTE_Plugin_TableTools() {
|
|
|
259
635
|
obj.AddRowNumbers = function (opts) {
|
|
260
636
|
var table = tableAtCaret();
|
|
261
637
|
if (!table) return false;
|
|
262
|
-
if (
|
|
638
|
+
if (editor.commitBookmark) editor.commitBookmark();
|
|
639
|
+
if (table.querySelector("[data-rte-rownum]")) {
|
|
640
|
+
renumber(table);
|
|
641
|
+
fireChange();
|
|
642
|
+
if (editor.recordUndo) editor.recordUndo();
|
|
643
|
+
return true;
|
|
644
|
+
}
|
|
263
645
|
opts = opts || {};
|
|
264
646
|
var series = opts.series || config.tableNumberSeries;
|
|
265
647
|
var doc = table.ownerDocument;
|
|
@@ -281,6 +663,7 @@ function RTE_Plugin_TableTools() {
|
|
|
281
663
|
table.setAttribute("data-rte-rownum-series", series);
|
|
282
664
|
renumber(table);
|
|
283
665
|
fireChange();
|
|
666
|
+
if (editor.recordUndo) editor.recordUndo();
|
|
284
667
|
return true;
|
|
285
668
|
};
|
|
286
669
|
|
|
@@ -296,9 +679,11 @@ function RTE_Plugin_TableTools() {
|
|
|
296
679
|
if (!table) return false;
|
|
297
680
|
var cells = table.querySelectorAll("[data-rte-rownum]");
|
|
298
681
|
if (!cells.length) return false;
|
|
682
|
+
if (editor.commitBookmark) editor.commitBookmark();
|
|
299
683
|
for (var i = 0; i < cells.length; i++) if (cells[i].parentNode) cells[i].parentNode.removeChild(cells[i]);
|
|
300
684
|
table.removeAttribute("data-rte-rownum-series");
|
|
301
685
|
fireChange();
|
|
686
|
+
if (editor.recordUndo) editor.recordUndo();
|
|
302
687
|
return true;
|
|
303
688
|
};
|
|
304
689
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.RTE_DefaultConfig||(window.RTE_DefaultConfig={}),RTE_DefaultConfig.plugin_tabletools=RTE_Plugin_TableTools,typeof RTE_DefaultConfig.tableNumberSeries>"u"&&(RTE_DefaultConfig.tableNumberSeries="numeric"),typeof RTE_DefaultConfig.tableNumberHeader>"u"&&(RTE_DefaultConfig.tableNumberHeader="#");function RTE_Plugin_TableTools(){var o=this,g,u;o.PluginName="TableTools",o.InitConfig=function(r){g=r},o.InitEditor=function(r){u=r,u.attachEvent("exec_command_sorttable",function(e){e.returnValue=!0,o.SortAtCaret(e&&e.value==="desc"?"desc":"asc")}),u.attachEvent("exec_command_tablerownumbers",function(e){e.returnValue=!0,o.ToggleRowNumbers()}),u.sortTableByColumn=function(e,t){return o.Sort(c(),e,t)},u.sortTableAtCaret=function(e){return o.SortAtCaret(e)},u.canSortTable=function(){return A(c())},u.addTableRowNumbers=function(e){return o.AddRowNumbers(e)},u.removeTableRowNumbers=function(){return o.RemoveRowNumbers()},u.hasTableRowNumbers=function(){var e=c();return!!(e&&e.querySelector("[data-rte-rownum]"))}};function R(){try{return u.getEditable()}catch{return null}}function c(){try{var r=u.getSelection();if(!r||r.rangeCount===0)return null;var e=r.getRangeAt(0).startContainer;e&&e.nodeType===3&&(e=e.parentNode);for(var t=R();e&&e!==t;){if(e.nodeName==="TABLE")return e;e=e.parentNode}return null}catch{return null}}function _(){try{var r=u.getSelection();if(!r||r.rangeCount===0)return null;var e=r.getRangeAt(0).startContainer;e&&e.nodeType===3&&(e=e.parentNode);for(var t=R();e&&e!==t;){if(e.nodeName==="TD"||e.nodeName==="TH")return e;e=e.parentNode}return null}catch{return null}}function y(r){if(!r)return[];for(var e=Array.prototype.slice.call(r.rows||[]),t=[],a=0;a<e.length;a++){var n=e[a],l=n.parentNode?n.parentNode.nodeName:"";l==="THEAD"||l==="TFOOT"||t.length===0&&a===0&&n.cells.length&&L(n)||t.push(n)}return t}function L(r){for(var e=0;e<r.cells.length;e++)if(r.cells[e].nodeName!=="TH")return!1;return!0}function A(r){if(!r)return{ok:!1,reason:"The caret is not inside a table."};var e=y(r);if(e.length<2)return{ok:!1,reason:"The table has fewer than two sortable rows."};for(var t=0;t<e.length;t++)for(var a=0;a<e[t].cells.length;a++){var n=e[t].cells[a];if((n.rowSpan||1)>1||(n.colSpan||1)>1)return{ok:!1,reason:"This table has merged cells. Sorting would move rows out from under a rowspan and break the table, so it has been left alone."}}return{ok:!0,reason:""}}function E(r){var e=String(r??"").trim();if(!e)return{type:"empty",v:""};if(/\d/.test(e)){var t=e.replace(/[\s ,]/g,"").replace(/^\(([^)]*)\)$/,"-$1").replace(/[^0-9.eE+-]/g,"");if(t&&/^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/.test(t))return{type:"number",v:parseFloat(t)};var a=Date.parse(e);if(!isNaN(a))return{type:"date",v:a}}return{type:"text",v:e.toLowerCase()}}function V(r,e){for(var t={number:0,date:0,text:0},a=0;a<r.length;a++){var n=r[a].cells[e];if(n){var l=E(n.textContent);l.type!=="empty"&&t[l.type]++}}return t.number>=t.date&&t.number>=t.text&&t.number>0?"number":t.date>=t.text&&t.date>0?"date":"text"}o.SortAtCaret=function(r){var e=c(),t=_();return!e||!t?!1:o.Sort(e,t.cellIndex,r)},o.Sort=function(r,e,t){var a=A(r);if(!a.ok)return a;for(var n=String(t).toLowerCase()==="desc",l=y(r),s=V(l,e),i=[],f=0;f<l.length;f++){var m=l[f].cells[e];i.push({row:l[f],order:f,val:E(m?m.textContent:"")})}i.sort(function(v,d){if(v.val.type==="empty"&&d.val.type==="empty")return v.order-d.order;if(v.val.type==="empty")return 1;if(d.val.type==="empty")return-1;var h;if(s==="number"||s==="date"){var x=v.val.type===s?v.val.v:Number.POSITIVE_INFINITY,H=d.val.type===s?d.val.v:Number.POSITIVE_INFINITY;h=x<H?-1:x>H?1:0}else{var w=String(v.val.v),S=String(d.val.v);h=w.localeCompare?w.localeCompare(S,void 0,{numeric:!0,sensitivity:"base"}):w<S?-1:w>S?1:0}return h===0?v.order-d.order:n?-h:h});var p=i.length?i[0].row.parentNode:null;if(!p)return{ok:!1,reason:"The table has no sortable rows."};for(var b=_(),T=0;T<i.length;T++)p.appendChild(i[T].row);return K(b),C(r),N(),{ok:!0,reason:"",sortedBy:e,direction:n?"desc":"asc",detectedType:s}};function q(r,e){switch(String(e)){case"upper-alpha":return I(r).toUpperCase();case"lower-alpha":return I(r);case"upper-roman":return D(r);case"lower-roman":return D(r).toLowerCase();default:return String(r)}}function I(r){for(var e="";r>0;){var t=(r-1)%26;e=String.fromCharCode(97+t)+e,r=Math.floor((r-1)/26)}return e||"a"}function D(r){for(var e=[[1e3,"M"],[900,"CM"],[500,"D"],[400,"CD"],[100,"C"],[90,"XC"],[50,"L"],[40,"XL"],[10,"X"],[9,"IX"],[5,"V"],[4,"IV"],[1,"I"]],t="",a=0;a<e.length;a++)for(;r>=e[a][0];)t+=e[a][1],r-=e[a][0];return t||"I"}o.AddRowNumbers=function(r){var e=c();if(!e)return!1;if(e.querySelector("[data-rte-rownum]"))return C(e),!0;r=r||{};for(var t=r.series||g.tableNumberSeries,a=e.ownerDocument,n=Array.prototype.slice.call(e.rows||[]),l=y(e),s={},i=0;i<l.length;i++)s[k(l[i])]=!0;for(var f=0;f<n.length;f++){var m=n[f],p=s[k(m)],b=a.createElement(p?"td":"th");b.setAttribute("data-rte-rownum",p?"value":"header"),p||(b.textContent=String(g.tableNumberHeader==null?"#":g.tableNumberHeader)),m.insertBefore(b,m.firstChild)}return e.setAttribute("data-rte-rownum-series",t),C(e),N(),!0};var F=0;function k(r){return r.__rteKey||(r.__rteKey="r"+F++),r.__rteKey}o.RemoveRowNumbers=function(){var r=c();if(!r)return!1;var e=r.querySelectorAll("[data-rte-rownum]");if(!e.length)return!1;for(var t=0;t<e.length;t++)e[t].parentNode&&e[t].parentNode.removeChild(e[t]);return r.removeAttribute("data-rte-rownum-series"),N(),!0},o.ToggleRowNumbers=function(){var r=c();return r?r.querySelector("[data-rte-rownum]")?o.RemoveRowNumbers():o.AddRowNumbers():!1};function C(r){if(r)for(var e=r.getAttribute("data-rte-rownum-series")||g.tableNumberSeries,t=y(r),a=1,n=0;n<t.length;n++){var l=t[n].querySelector("[data-rte-rownum='value']");l&&(l.textContent=q(a++,e))}}function K(r){if(!(!r||!r.parentNode))try{var e=r.ownerDocument,t=e.createRange();t.selectNodeContents(r),t.collapse(!0);var a=u.getSelection();a.removeAllRanges(),a.addRange(t)}catch{}}function N(){try{typeof u.updateDesign=="function"&&u.updateDesign()}catch{}try{typeof u.fireChange=="function"&&u.fireChange()}catch{}}}
|
|
1
|
+
window.RTE_DefaultConfig||(window.RTE_DefaultConfig={}),RTE_DefaultConfig.plugin_tabletools=RTE_Plugin_TableTools,typeof RTE_DefaultConfig.tableNumberSeries>"u"&&(RTE_DefaultConfig.tableNumberSeries="numeric"),typeof RTE_DefaultConfig.tableNumberHeader>"u"&&(RTE_DefaultConfig.tableNumberHeader="#");function RTE_Plugin_TableTools(){var b=this,T,a;b.PluginName="TableTools",b.InitConfig=function(r){T=r,z("subtoolbar_tablerow",["tablerowmoveup","tablerowmovedown"]),z("subtoolbar_tablecolumn",["tablecolumnmoveleft","tablecolumnmoveright"]);var e={tablerowmoveup:"Move Row Up",tablerowmovedown:"Move Row Down",tablecolumnmoveleft:"Move Column Left",tablecolumnmoveright:"Move Column Right"},t={tablerowmoveup:"M12 19V5M6 11l6-6 6 6",tablerowmovedown:"M12 5v14M6 13l6 6 6-6",tablecolumnmoveleft:"M19 12H5M11 6l-6 6 6 6",tablecolumnmoveright:"M5 12h14M13 6l6 6-6 6"};for(var o in e)T["text_"+o]==null&&(T["text_"+o]=e[o]),T["svgCode_"+o]==null&&(T["svgCode_"+o]='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="'+t[o]+'"/></svg>')};function z(r,e){var t=T[r];if(!(typeof t!="string"||!t)){for(var o=0;o<e.length;o++)if(t.indexOf(e[o])===-1){var n=t.lastIndexOf("}");t=n===-1?t+","+e[o]:t.substring(0,n)+","+e[o]+t.substring(n)}T[r]=t}}b.InitEditor=function(r){a=r,a.attachEvent("exec_command_sorttable",function(e){e.returnValue=!0,b.SortAtCaret(e&&e.value==="desc"?"desc":"asc")}),a.attachEvent("exec_command_tablerownumbers",function(e){e.returnValue=!0,b.ToggleRowNumbers()}),a.sortTableByColumn=function(e,t){return b.Sort(D(),e,t)},a.sortTableAtCaret=function(e){return b.SortAtCaret(e)},a.canSortTable=function(){return G(D())},a.addTableRowNumbers=function(e){return b.AddRowNumbers(e)},a.removeTableRowNumbers=function(){return b.RemoveRowNumbers()},["tablerowmoveup","tablerowmovedown","tablecolumnmoveleft","tablecolumnmoveright"].forEach(function(e){a.toolbarFactoryMap=a.toolbarFactoryMap||{},a.toolbarFactoryMap[e]||(a.toolbarFactoryMap[e]=function(t){return a.createToolbarButton(t)}),a.attachEvent("exec_command_"+e,function(t){t.returnValue=!0,t.stopBubble=!0,e==="tablerowmoveup"?X(-1):e==="tablerowmovedown"?X(1):q(e==="tablecolumnmoveleft"?-1:1)})}),a.moveTableRow=function(e){return X(e<0?-1:1)},a.moveTableColumn=function(e){return q(e<0?-1:1)},T.tableRowDrag!==!1&&re(),T.tableColumnDrag!==!1&&oe(),a.hasTableRowNumbers=function(){var e=D();return!!(e&&e.querySelector("[data-rte-rownum]"))}};function K(){try{return a.getEditable()}catch{return null}}function D(){try{var r=a.getSelection();if(!r||r.rangeCount===0)return null;var e=r.getRangeAt(0).startContainer;e&&e.nodeType===3&&(e=e.parentNode);for(var t=K();e&&e!==t;){if(e.nodeName==="TABLE")return e;e=e.parentNode}return null}catch{return null}}function O(){try{var r=a.getSelection();if(!r||r.rangeCount===0)return null;var e=r.getRangeAt(0).startContainer;e&&e.nodeType===3&&(e=e.parentNode);for(var t=K();e&&e!==t;){if(e.nodeName==="TD"||e.nodeName==="TH")return e;e=e.parentNode}return null}catch{return null}}function _(r){if(!r)return[];for(var e=Array.prototype.slice.call(r.rows||[]),t=[],o=0;o<e.length;o++){var n=e[o],c=n.parentNode?n.parentNode.nodeName:"";c==="THEAD"||c==="TFOOT"||t.length===0&&o===0&&n.cells.length&&ee(n)||t.push(n)}return t}function ee(r){for(var e=0;e<r.cells.length;e++)if(r.cells[e].nodeName!=="TH")return!1;return!0}function G(r){if(!r)return{ok:!1,reason:"The caret is not inside a table."};var e=_(r);if(e.length<2)return{ok:!1,reason:"The table has fewer than two sortable rows."};for(var t=0;t<e.length;t++)for(var o=0;o<e[t].cells.length;o++){var n=e[t].cells[o];if((n.rowSpan||1)>1||(n.colSpan||1)>1)return{ok:!1,reason:"This table has merged cells. Sorting would move rows out from under a rowspan and break the table, so it has been left alone."}}return{ok:!0,reason:""}}function P(r){var e=String(r??"").trim();if(!e)return{type:"empty",v:""};if(/\d/.test(e)){var t=e.replace(/[\s\xa0,]/g,"").replace(/^\(([^)]*)\)$/,"-$1").replace(/[^0-9.eE+-]/g,"");if(t&&/^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/.test(t))return{type:"number",v:parseFloat(t)};var o=Date.parse(e);if(!isNaN(o))return{type:"date",v:o}}return{type:"text",v:e.toLowerCase()}}function te(r,e){for(var t={number:0,date:0,text:0},o=0;o<r.length;o++){var n=r[o].cells[e];if(n){var c=P(n.textContent);c.type!=="empty"&&t[c.type]++}}return t.number>=t.date&&t.number>=t.text&&t.number>0?"number":t.date>=t.text&&t.date>0?"date":"text"}b.SortAtCaret=function(r){var e=D(),t=O();return!e||!t?!1:b.Sort(e,t.cellIndex,r)},b.Sort=function(r,e,t){var o=G(r);if(!o.ok)return o;if(a.__trackHook&&a.__trackHook("move",{direction:0})===!0)return{ok:!1,reason:"Suggesting is on, so the table was not sorted. Turn suggesting off to sort it."};for(var n=String(t).toLowerCase()==="desc",c=_(r),f=te(c,e),d=[],v=0;v<c.length;v++){var u=c[v].cells[e];d.push({row:c[v],order:v,val:P(u?u.textContent:"")})}d.sort(function(E,w){if(E.val.type==="empty"&&w.val.type==="empty")return E.order-w.order;if(E.val.type==="empty")return 1;if(w.val.type==="empty")return-1;var N;if(f==="number"||f==="date"){var S=E.val.type===f?E.val.v:Number.POSITIVE_INFINITY,k=w.val.type===f?w.val.v:Number.POSITIVE_INFINITY;N=S<k?-1:S>k?1:0}else{var L=String(E.val.v),x=String(w.val.v);N=L.localeCompare?L.localeCompare(x,void 0,{numeric:!0,sensitivity:"base"}):L<x?-1:L>x?1:0}return N===0?E.order-w.order:n?-N:N});var h=d.length?d[0].row.parentNode:null;if(!h)return{ok:!1,reason:"The table has no sortable rows."};for(var C=O(),R=0;R<d.length;R++)h.appendChild(d[R].row);return U(C),I(r),M(),{ok:!0,reason:"",sortedBy:e,direction:n?"desc":"asc",detectedType:f}};function re(){var r=a.iframe;if(!r||!r.ownerDocument)return;var e=r.ownerDocument,t=a.getDocument(),o=e.createElement("div");o.className="rte-row-grip",o.setAttribute("aria-hidden","true"),o.textContent="\u283F";var n=o.style;n.position="fixed",n.display="none",n.zIndex="99998",n.width="12px",n.height="22px",n.lineHeight="22px",n.textAlign="center",n.fontSize="14px",n.color="#64748b",n.cursor="grab",n.userSelect="none",n.borderRadius="3px",n.background="rgba(15,23,42,.06)";var c=e.createElement("div");c.className="rte-row-drop";var f=c.style;f.position="fixed",f.display="none",f.zIndex="99998",f.height="2px",f.background="#2563eb",f.pointerEvents="none",e.body.appendChild(o),e.body.appendChild(c);var d=null,v=0,u=null;function h(){return r.getBoundingClientRect()}function C(l){try{return!!a.getEditable()&&a.getEditable().contains(l)}catch{return!1}}function R(l){for(var i=l&&l.nodeType===1?l:l&&l.parentNode;i&&i.nodeName!=="TR";)i=i.parentNode;if(!i||!C(i))return null;var p=i.parentNode&&i.parentNode.nodeName;if(p==="THEAD"||p==="TFOOT")return null;var g=i.closest?i.closest("table"):null;return!g||_(g).indexOf(i)<0?null:i}function E(l){var i=h(),p=l.getBoundingClientRect(),g=l.closest("table"),y=g.getBoundingClientRect().left-14;if(y<i.left){n.display="none";return}n.left=Math.round(y)+"px",n.top=Math.round(i.top+p.top+p.height/2-11)+"px",n.display="block"}function w(){clearTimeout(v),v=setTimeout(function(){u||(n.display="none",d=null)},350)}function N(l){return l.view===r.contentWindow?h().top+l.clientY:l.clientY}function S(l){for(var i=_(l),p=0;p<i.length;p++)for(var g=0;g<i[p].cells.length;g++){var y=i[p].cells[g];if((y.rowSpan||1)>1||(y.colSpan||1)>1)return!0}return!1}function k(l){try{typeof a.announce=="function"&&a.announce(l)}catch{}}t.addEventListener("mousemove",function(l){if(!u){var i=R(l.target);i?(clearTimeout(v),d=i,E(i)):w()}}),o.addEventListener("mouseenter",function(){clearTimeout(v)}),o.addEventListener("mouseleave",w);function L(){u=null,e.removeEventListener("mousemove",x,!0),t.removeEventListener("mousemove",x,!0),e.removeEventListener("mouseup",s,!0),t.removeEventListener("mouseup",s,!0),e.removeEventListener("keydown",m,!0),t.removeEventListener("keydown",m,!0),f.display="none",n.display="none",n.cursor="grab"}function x(l){if(u){for(var i=N(l),p=h(),g=u.rows,y=g.length,A=0;A<g.length;A++){var F=g[A].getBoundingClientRect();if(i<p.top+F.top+F.height/2){y=A;break}}u.drop=y;var H=y===u.from||y===u.from+1;u.noop=H;var ue=y<g.length?p.top+g[y].getBoundingClientRect().top:p.top+g[g.length-1].getBoundingClientRect().bottom,Z=u.table.getBoundingClientRect();f.left=Math.round(p.left+Z.left)+"px",f.width=Math.round(Z.width)+"px",f.top=Math.round(ue-1)+"px",f.display=H?"none":"block"}}function B(l){try{if(String(a.getDocument().designMode).toLowerCase()==="off"||a.getCommentsOnly&&a.getCommentsOnly())return!1}catch{}if(S(l.table))return k("This table has merged cells, so the row was not moved."),!1;if(a.__trackHook&&a.__trackHook("move",{direction:0})===!0)return!1;var i=l.drop<l.rows.length?l.rows[l.drop]:null;typeof a.recordUndo=="function"&&a.recordUndo(),l.row.parentNode.insertBefore(l.row,i),I(l.table);try{U(l.row.cells[0]),typeof a.focus=="function"&&a.focus()}catch{}return M(),!0}function s(l){if(u){var i=u;L(),!(i.drop<0||i.noop)&&B(i)}}function m(l){l.key==="Escape"&&L()}o.addEventListener("mousedown",function(l){if(!(!d||l.button!==0)){l.preventDefault();var i=d.closest("table"),p=_(i).filter(function(g){return g.parentNode===d.parentNode});u={row:d,table:i,rows:p,from:p.indexOf(d),drop:-1,noop:!0},n.cursor="grabbing",e.addEventListener("mousemove",x,!0),t.addEventListener("mousemove",x,!0),e.addEventListener("mouseup",s,!0),t.addEventListener("mouseup",s,!0),e.addEventListener("keydown",m,!0),t.addEventListener("keydown",m,!0)}})}function Y(r){try{typeof a.announce=="function"&&a.announce(r)}catch{}}function $(){try{if(String(a.getDocument().designMode).toLowerCase()==="off"||a.getCommentsOnly&&a.getCommentsOnly())return!0}catch{}return!!(a.__trackHook&&a.__trackHook("move",{direction:0})===!0)}function ne(r){for(var e=r.rows,t=e.length?e[0].cells.length:0,o=0;o<e.length;o++){if(e[o].cells.length!==t)return!1;for(var n=0;n<t;n++)if((e[o].cells[n].rowSpan||1)>1||(e[o].cells[n].colSpan||1)>1)return!1}return t>1}function V(r){return r.querySelector("[data-rte-rownum]")?1:0}function W(r,e,t,o){if($())return!1;if(!ne(r))return Y("This table has merged cells, so the column was not moved."),!1;var n=r.rows,c=n[0].cells.length;if(e<0||e>=c||t<0||t>c||t===e||t===e+1)return!1;typeof a.recordUndo=="function"&&a.recordUndo();for(var f=0;f<n.length;f++){var d=n[f].cells;n[f].insertBefore(d[e],t<c?d[t]:null)}for(var v=[],u=0;u<r.children.length;u++){var h=r.children[u];if(h.nodeName==="COLGROUP")for(var C=0;C<h.children.length;C++)h.children[C].nodeName==="COL"&&v.push(h.children[C])}for(var R=c-v.length,E=!1,w=0;w<v.length;w++)(parseInt(v[w].getAttribute("span"),10)||1)>1&&(E=!0);if(v.length&&!E&&(R===0||R===V(r))&&e>=R){var N=v[e-R],S=t<c?v[t-R]:null;N&&N!==S&&(S?S.parentNode:N.parentNode).insertBefore(N,S)}var k=t>e?t-1:t;try{U(o||n[n.length>1?1:0].cells[k]),typeof a.focus=="function"&&a.focus()}catch{}return M(),!0}function q(r){var e=O();if(!e||e.hasAttribute("data-rte-rownum"))return!1;var t=e.closest("table");if(!t||!t.rows.length)return!1;var o=e.cellIndex,n=t.rows[0].cells.length;return(r<0?o-1<V(t):o+1>=n)?!1:W(t,o,r<0?o-1:o+2,e)}function X(r){var e=O();if(!e)return!1;var t=e.parentNode,o=e.closest("table"),n=_(o).filter(function(u){return u.parentNode===t.parentNode}),c=n.indexOf(t),f=c+(r<0?-1:1);if(c<0||f<0||f>=n.length||$())return!1;for(var d=0;d<n.length;d++)for(var v=0;v<n[d].cells.length;v++)if((n[d].cells[v].rowSpan||1)>1||(n[d].cells[v].colSpan||1)>1)return Y("This table has merged cells, so the row was not moved."),!1;typeof a.recordUndo=="function"&&a.recordUndo(),t.parentNode.insertBefore(t,r<0?n[f]:n[f].nextSibling),I(o);try{U(e),typeof a.focus=="function"&&a.focus()}catch{}return M(),!0}function oe(){var r=a.iframe;if(!r||!r.ownerDocument)return;var e=r.ownerDocument,t=a.getDocument(),o=e.createElement("div");o.className="rte-col-grip",o.setAttribute("aria-hidden","true"),o.textContent="\u283F";var n=o.style;n.position="fixed",n.display="none",n.zIndex="99998",n.width="22px",n.height="12px",n.lineHeight="12px",n.textAlign="center",n.fontSize="12px",n.color="#64748b",n.cursor="grab",n.userSelect="none",n.borderRadius="3px",n.background="rgba(15,23,42,.06)",n.overflow="hidden";var c=e.createElement("div");c.className="rte-col-drop";var f=c.style;f.position="fixed",f.display="none",f.zIndex="99998",f.width="2px",f.background="#2563eb",f.pointerEvents="none",e.body.appendChild(o),e.body.appendChild(c);var d=null,v=0,u=null;function h(){return r.getBoundingClientRect()}function C(s){try{return!!a.getEditable()&&a.getEditable().contains(s)}catch{return!1}}function R(s){for(var m=s&&s.nodeType===1?s:s&&s.parentNode;m&&m.nodeName!=="TD"&&m.nodeName!=="TH";)m=m.parentNode;return!m||!C(m)||m.hasAttribute("data-rte-rownum")?null:m.closest&&m.closest("table")?m:null}function E(s){var m=h(),l=s.getBoundingClientRect(),i=s.closest("table").getBoundingClientRect(),p=m.top+i.top-14;if(p<m.top){n.display="none";return}n.left=Math.round(m.left+l.left+l.width/2-11)+"px",n.top=Math.round(p)+"px",n.display="block"}function w(){clearTimeout(v),v=setTimeout(function(){u||(n.display="none",d=null)},350)}function N(s){return s.view===r.contentWindow?h().left+s.clientX:s.clientX}t.addEventListener("mousemove",function(s){if(!u){var m=R(s.target);m?(clearTimeout(v),d=m,E(m)):w()}}),o.addEventListener("mouseenter",function(){clearTimeout(v)}),o.addEventListener("mouseleave",w);function S(){u=null,e.removeEventListener("mousemove",k,!0),t.removeEventListener("mousemove",k,!0),e.removeEventListener("mouseup",x,!0),t.removeEventListener("mouseup",x,!0),e.removeEventListener("keydown",B,!0),t.removeEventListener("keydown",B,!0),f.display="none",n.display="none",n.cursor="grab"}function k(s){if(u){for(var m=N(s),l=h(),i=u.table.rows[0].cells,p=i.length,g=p,y=u.min;y<p;y++){var A=i[y].getBoundingClientRect();if(m<l.left+A.left+A.width/2){g=y;break}}u.drop=g,u.noop=g===u.from||g===u.from+1;var F=g<p?l.left+i[g].getBoundingClientRect().left:l.left+i[p-1].getBoundingClientRect().right,H=u.table.getBoundingClientRect();f.left=Math.round(F-1)+"px",f.top=Math.round(l.top+H.top)+"px",f.height=Math.round(H.height)+"px",f.display=u.noop?"none":"block"}}function L(s){return W(s.table,s.from,s.drop)}function x(){if(u){var s=u;S(),!(s.drop<0||s.noop)&&L(s)}}function B(s){s.key==="Escape"&&S()}o.addEventListener("mousedown",function(s){if(!(!d||s.button!==0)){s.preventDefault();var m=d.closest("table");m.rows.length&&(u={table:m,from:d.cellIndex,min:V(m),drop:-1,noop:!0},n.cursor="grabbing",e.addEventListener("mousemove",k,!0),t.addEventListener("mousemove",k,!0),e.addEventListener("mouseup",x,!0),t.addEventListener("mouseup",x,!0),e.addEventListener("keydown",B,!0),t.addEventListener("keydown",B,!0))}})}function ae(r,e){switch(String(e)){case"upper-alpha":return j(r).toUpperCase();case"lower-alpha":return j(r);case"upper-roman":return J(r);case"lower-roman":return J(r).toLowerCase();default:return String(r)}}function j(r){for(var e="";r>0;){var t=(r-1)%26;e=String.fromCharCode(97+t)+e,r=Math.floor((r-1)/26)}return e||"a"}function J(r){for(var e=[[1e3,"M"],[900,"CM"],[500,"D"],[400,"CD"],[100,"C"],[90,"XC"],[50,"L"],[40,"XL"],[10,"X"],[9,"IX"],[5,"V"],[4,"IV"],[1,"I"]],t="",o=0;o<e.length;o++)for(;r>=e[o][0];)t+=e[o][1],r-=e[o][0];return t||"I"}b.AddRowNumbers=function(r){var e=D();if(!e)return!1;if(a.commitBookmark&&a.commitBookmark(),e.querySelector("[data-rte-rownum]"))return I(e),M(),a.recordUndo&&a.recordUndo(),!0;r=r||{};for(var t=r.series||T.tableNumberSeries,o=e.ownerDocument,n=Array.prototype.slice.call(e.rows||[]),c=_(e),f={},d=0;d<c.length;d++)f[Q(c[d])]=!0;for(var v=0;v<n.length;v++){var u=n[v],h=f[Q(u)],C=o.createElement(h?"td":"th");C.setAttribute("data-rte-rownum",h?"value":"header"),h||(C.textContent=String(T.tableNumberHeader==null?"#":T.tableNumberHeader)),u.insertBefore(C,u.firstChild)}return e.setAttribute("data-rte-rownum-series",t),I(e),M(),a.recordUndo&&a.recordUndo(),!0};var le=0;function Q(r){return r.__rteKey||(r.__rteKey="r"+le++),r.__rteKey}b.RemoveRowNumbers=function(){var r=D();if(!r)return!1;var e=r.querySelectorAll("[data-rte-rownum]");if(!e.length)return!1;a.commitBookmark&&a.commitBookmark();for(var t=0;t<e.length;t++)e[t].parentNode&&e[t].parentNode.removeChild(e[t]);return r.removeAttribute("data-rte-rownum-series"),M(),a.recordUndo&&a.recordUndo(),!0},b.ToggleRowNumbers=function(){var r=D();return r?r.querySelector("[data-rte-rownum]")?b.RemoveRowNumbers():b.AddRowNumbers():!1};function I(r){if(r)for(var e=r.getAttribute("data-rte-rownum-series")||T.tableNumberSeries,t=_(r),o=1,n=0;n<t.length;n++){var c=t[n].querySelector("[data-rte-rownum='value']");c&&(c.textContent=ae(o++,e))}}function U(r){if(!(!r||!r.parentNode))try{var e=r.ownerDocument,t=e.createRange();t.selectNodeContents(r),t.collapse(!0);var o=a.getSelection();o.removeAllRanges(),o.addRange(t)}catch{}}function M(){try{typeof a.updateDesign=="function"&&a.updateDesign()}catch{}try{typeof a.fireChange=="function"&&a.fireChange()}catch{}}}
|
|
@@ -43,15 +43,23 @@ function RTE_Plugin_TextDirection() {
|
|
|
43
43
|
|
|
44
44
|
// Strongly right-to-left ranges: Hebrew, Arabic (+ supplement, extended),
|
|
45
45
|
// Syriac, Thaana, NKo, Samaritan, Mandaic, and the Arabic presentation forms.
|
|
46
|
-
var RTL_RE = /[
|
|
46
|
+
var RTL_RE = /[\u0590-\u05ff\u0600-\u06ff\u0700-\u074f\u0750-\u077f\u0780-\u07bf\u07c0-\u07ff\u0800-\u083f\u0840-\u085f\u08a0-\u08ff\ufb1d-\ufdff\ufe70-\ufeff]/;
|
|
47
47
|
// Strongly left-to-right: Latin, Greek, Cyrillic, Armenian, and CJK/Kana
|
|
48
48
|
// (which are LTR for bidi purposes).
|
|
49
|
-
var LTR_RE = /[A-Za-z
|
|
49
|
+
var LTR_RE = /[A-Za-z\xc0-\u02af\u0370-\u058f\u0900-\u109f\u1e00-\u1fff\u2c00-\u2dff\u2e80-\ua4cf\uac00-\ud7af]/;
|
|
50
50
|
|
|
51
51
|
obj.PluginName = "TextDirection";
|
|
52
52
|
|
|
53
53
|
obj.InitConfig = function (argconfig) { config = argconfig; };
|
|
54
54
|
|
|
55
|
+
// record the change as its own undo step: seal the step before, run, save the snapshot, seal it
|
|
56
|
+
function undoStep(run) {
|
|
57
|
+
try { if (editor.commitBookmark) editor.commitBookmark(); } catch (er) { /* ignore */ }
|
|
58
|
+
var result = run();
|
|
59
|
+
try { if (editor.recordUndo) editor.recordUndo(); else if (editor.notifySelectionChange) editor.notifySelectionChange(); if (editor.commitBookmark) editor.commitBookmark(); } catch (er) { /* ignore */ }
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
|
|
55
63
|
obj.InitEditor = function (argeditor) {
|
|
56
64
|
editor = argeditor;
|
|
57
65
|
|
|
@@ -68,10 +76,12 @@ function RTE_Plugin_TextDirection() {
|
|
|
68
76
|
setTimeout(function () { setup(); afterLoad(); }, 0);
|
|
69
77
|
|
|
70
78
|
// Public API.
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
// 2026-10-04 one undo step when called directly (execCommand does this for the button; a direct
|
|
80
|
+
// call could not be undone). tools/api/plugin-api-undo.mjs
|
|
81
|
+
editor.setTextDirection = function (dir) { return undoStep(function () { return obj.Apply(dir); }); };
|
|
82
|
+
editor.toggleTextDirection = function () { return undoStep(function () { return obj.Toggle(); }); };
|
|
73
83
|
editor.getTextDirection = function () { return obj.Current(); };
|
|
74
|
-
editor.setBaseDirection = function (dir) { return obj.Base(dir); };
|
|
84
|
+
editor.setBaseDirection = function (dir) { return undoStep(function () { return obj.Base(dir); }); };
|
|
75
85
|
editor.getBaseDirection = function () {
|
|
76
86
|
var ed = getEditable();
|
|
77
87
|
return ed ? (ed.getAttribute("dir") || "ltr") : "ltr";
|
|
@@ -183,6 +193,9 @@ function RTE_Plugin_TextDirection() {
|
|
|
183
193
|
dir = (dir === "rtl") ? "rtl" : (dir === "auto" ? "auto" : "ltr");
|
|
184
194
|
var blocks = blocksInSelection();
|
|
185
195
|
if (!blocks.length) return false;
|
|
196
|
+
// 2026-10-14 Suggesting mode: a direction change is not tracked yet, so the track hook refuses it.
|
|
197
|
+
// tools/review/suggesting-structure-audit.mjs
|
|
198
|
+
if (editor.__trackHook && editor.__trackHook("refuse", { message: "Suggesting is on, so the direction was not changed. Turn suggesting off to change it." }) === true) return false;
|
|
186
199
|
for (var i = 0; i < blocks.length; i++) {
|
|
187
200
|
var b = blocks[i];
|
|
188
201
|
var was = b.getAttribute("dir") || "ltr";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.RTE_DefaultConfig||(window.RTE_DefaultConfig={}),RTE_DefaultConfig.plugin_textdirection=RTE_Plugin_TextDirection,typeof RTE_DefaultConfig.defaultTextDirection>"u"&&(RTE_DefaultConfig.defaultTextDirection=null),typeof RTE_DefaultConfig.textDirectionAutoDetect>"u"&&(RTE_DefaultConfig.textDirectionAutoDetect=!1),typeof RTE_DefaultConfig.textDirectionSwapAlign>"u"&&(RTE_DefaultConfig.textDirectionSwapAlign=!0);function RTE_Plugin_TextDirection(){var u=this,
|
|
1
|
+
window.RTE_DefaultConfig||(window.RTE_DefaultConfig={}),RTE_DefaultConfig.plugin_textdirection=RTE_Plugin_TextDirection,typeof RTE_DefaultConfig.defaultTextDirection>"u"&&(RTE_DefaultConfig.defaultTextDirection=null),typeof RTE_DefaultConfig.textDirectionAutoDetect>"u"&&(RTE_DefaultConfig.textDirectionAutoDetect=!1),typeof RTE_DefaultConfig.textDirectionSwapAlign>"u"&&(RTE_DefaultConfig.textDirectionSwapAlign=!0);function RTE_Plugin_TextDirection(){var u=this,f,n,y=null,d={P:1,DIV:1,LI:1,H1:1,H2:1,H3:1,H4:1,H5:1,H6:1,BLOCKQUOTE:1,TD:1,TH:1,PRE:1,UL:1,OL:1,TABLE:1,SECTION:1,ARTICLE:1},S=/[\u0590-\u05ff\u0600-\u06ff\u0700-\u074f\u0750-\u077f\u0780-\u07bf\u07c0-\u07ff\u0800-\u083f\u0840-\u085f\u08a0-\u08ff\ufb1d-\ufdff\ufe70-\ufeff]/,R=/[A-Za-z\xc0-\u02af\u0370-\u058f\u0900-\u109f\u1e00-\u1fff\u2c00-\u2dff\u2e80-\ua4cf\uac00-\ud7af]/;u.PluginName="TextDirection",u.InitConfig=function(t){f=t};function h(t){try{n.commitBookmark&&n.commitBookmark()}catch{}var e=t();try{n.recordUndo?n.recordUndo():n.notifySelectionChange&&n.notifySelectionChange(),n.commitBookmark&&n.commitBookmark()}catch{}return e}u.InitEditor=function(t){n=t,n.attachEvent("exec_command_textdirection",function(e){e.returnValue=!0;var r=e&&e.value;r==="rtl"||r==="ltr"?u.Apply(r):u.Toggle()}),s();try{n.attachEvent("ready",s)}catch{}try{n.attachEvent("aftersethtml",function(){s(),T()})}catch{}setTimeout(function(){s(),T()},0),n.setTextDirection=function(e){return h(function(){return u.Apply(e)})},n.toggleTextDirection=function(){return h(function(){return u.Toggle()})},n.getTextDirection=function(){return u.Current()},n.setBaseDirection=function(e){return h(function(){return u.Base(e)})},n.getBaseDirection=function(){var e=l();return e&&e.getAttribute("dir")||"ltr"},n.detectTextDirection=function(e){return m(String(e??""))},n.autoDetectTextDirection=function(){return u.AutoDetect()},n.isolateBidi=function(e,r){return u.Isolate(e,r)},n.insertIsolated=function(e,r){return u.InsertIsolated(e,r)},n.getTextDirectionCss=function(){return b()}};function s(){var t=p();!t||t===y||(y=t,k(t))}function T(){var t=l();t&&((f.defaultTextDirection==="rtl"||f.defaultTextDirection==="ltr")&&(t.getAttribute("dir")||u.Base(f.defaultTextDirection)),f.textDirectionAutoDetect&&u.AutoDetect())}function p(){try{return n.getDocument()}catch{return null}}function l(){try{return n.getEditable()}catch{return null}}function m(t){for(var e=0;e<t.length;e++){var r=t.charAt(e);if(S.test(r))return"rtl";if(R.test(r))return"ltr"}return"neutral"}function A(){var t=l(),e=[];try{var r=n.getSelection();if(!r||r.rangeCount===0)return e;var i=r.getRangeAt(0),o=x(i.startContainer),a=x(i.endContainer);if(!o)return e;if(o===a||i.collapsed)return[o];for(var v=t.querySelectorAll("*"),E=!1,D=0;D<v.length;D++){var g=v[D];if(d[g.nodeName]&&(g===o&&(E=!0),E&&!C(g)&&e.push(g),g===a))break}e.length||e.push(o)}catch{}return e}function C(t){for(var e=0;e<t.children.length;e++)if(d[t.children[e].nodeName])return!0;return!1}function x(t){for(var e=l(),r=t&&t.nodeType===3?t.parentNode:t;r&&r!==e;){if(r.nodeType===1&&d[r.nodeName])return r;r=r.parentNode}return e&&e.firstElementChild?e.firstElementChild:null}u.Current=function(){var t=A()[0];if(!t)return n.getBaseDirection?n.getBaseDirection():"ltr";var e=t.getAttribute("dir");if(e)return e;try{var r=p(),i=r&&(r.defaultView||r.parentWindow);if(i)return i.getComputedStyle(t).direction||"ltr"}catch{}return"ltr"},u.Apply=function(t){t=t==="rtl"?"rtl":t==="auto"?"auto":"ltr";var e=A();if(!e.length||n.__trackHook&&n.__trackHook("refuse",{message:"Suggesting is on, so the direction was not changed. Turn suggesting off to change it."})===!0)return!1;for(var r=0;r<e.length;r++){var i=e[r],o=i.getAttribute("dir")||"ltr";i.setAttribute("dir",t),f.textDirectionSwapAlign!==!1&&t!=="auto"&&o!==t&&_(i,t)}return c(),t},u.Toggle=function(){return u.Apply(u.Current()==="rtl"?"ltr":"rtl")};function _(t,e){var r=t.style&&t.style.textAlign||t.getAttribute("align")||"";if(r){var i=null;if(r==="left"?i="right":r==="right"&&(i="left"),!!i){var o=e==="rtl"?"right":"left";t.style&&(t.style.textAlign=i===o?"":i),t.getAttribute("align")&&t.removeAttribute("align")}}}u.Base=function(t){var e=l();return e?(t=t==="rtl"?"rtl":t==="auto"?"auto":"ltr",e.setAttribute("dir",t),c(),t):!1},u.AutoDetect=function(){var t=l();if(!t)return[];for(var e=[],r=t.querySelectorAll("*"),i=0;i<r.length;i++){var o=r[i];if(!(!d[o.nodeName]||C(o))){var a=m(o.textContent||"");a!=="neutral"&&o.getAttribute("dir")!==a&&(o.setAttribute("dir",a),e.push({tag:o.nodeName,dir:a}))}}return e.length&&c(),e},u.Isolate=function(t,e){var r=e==="rtl"||e==="ltr"?e:"auto";return'<bdi dir="'+r+'">'+String(t??"")+"</bdi>"},u.InsertIsolated=function(t,e){var r=p();if(!r)return!1;var i=r.createElement("bdi");i.setAttribute("dir",e==="rtl"||e==="ltr"?e:"auto"),i.innerHTML=String(t??"");try{if(typeof n.insertElement=="function")return n.insertElement(i),c(),!0}catch{}try{var o=n.getSelection();if(o&&o.rangeCount){var a=o.getRangeAt(0);return a.collapse(!1),a.insertNode(i),a.setStartAfter(i),a.collapse(!0),o.removeAllRanges(),o.addRange(a),c(),!0}}catch{}return!1};function c(){try{typeof n.updateDesign=="function"&&n.updateDesign()}catch{}try{typeof n.fireChange=="function"&&n.fireChange()}catch{}}function b(){return"[dir='rtl'] ul,[dir='rtl'] ol{padding-right:1.6em;padding-left:0;}[dir='rtl'] blockquote{border-right:3px solid #ddd;border-left:0;padding-right:.9em;padding-left:0;margin-right:0;}[dir='rtl'] table{direction:rtl;}bdi{unicode-bidi:isolate;}"}function k(t){if(t){var e=t.getElementById("rte-textdirection-styles"),r=b();if(e){if(e.getAttribute("data-css")===r)return;e.parentNode&&e.parentNode.removeChild(e)}var i=t.createElement("style");i.id="rte-textdirection-styles",i.setAttribute("data-css",r),i.appendChild(t.createTextNode(r)),(t.head||t.getElementsByTagName("head")[0]||t.documentElement).appendChild(i),n&&typeof n.ensureStyleSheetLive=="function"&&n.ensureStyleSheetLive(t,i,"rte-textdirection-styles",i.textContent)}}}
|