@richscripts/richtexteditor 2.14.1 → 2.16.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 +182 -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 +40 -52
- 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 +68 -22
- package/package.json +25 -3
- package/react/index.js +118 -37
- package/react/index.mjs +29 -0
- package/richtexteditor/all_plugins.js +8816 -2373
- package/richtexteditor/all_plugins.min.js +77 -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 +1050 -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 +1056 -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 +1056 -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 +1056 -2
- package/richtexteditor/lang/rte-lang-ja.js +1056 -2
- package/richtexteditor/lang/rte-lang-kn.js +1 -0
- package/richtexteditor/lang/rte-lang-ko.js +1056 -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 +1056 -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 +1056 -2
- package/richtexteditor/lang/rte-lang-pt.js +1056 -2
- package/richtexteditor/lang/rte-lang-ro.js +1 -0
- package/richtexteditor/lang/rte-lang-ru.js +1056 -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 +1050 -2
- package/richtexteditor/lang/rte-lang-zh-Hant.js +1050 -2
- package/richtexteditor/plugins/a11yenhance.js +4 -1
- package/richtexteditor/plugins/a11yenhance.min.js +1 -1
- package/richtexteditor/plugins/accessibilitychecker.js +256 -64
- package/richtexteditor/plugins/accessibilitychecker.min.js +1 -1
- package/richtexteditor/plugins/aitoolkit.js +1057 -386
- package/richtexteditor/plugins/aitoolkit.min.js +7 -7
- package/richtexteditor/plugins/all_plugins.js +8816 -2373
- package/richtexteditor/plugins/all_plugins.min.js +77 -59
- package/richtexteditor/plugins/autocorrect.js +66 -31
- package/richtexteditor/plugins/autocorrect.min.js +1 -1
- package/richtexteditor/plugins/autoembed.js +18 -1
- 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 +460 -61
- package/richtexteditor/plugins/comments.min.js +4 -3
- package/richtexteditor/plugins/contentminimap.js +28 -9
- package/richtexteditor/plugins/contentminimap.min.js +1 -1
- package/richtexteditor/plugins/crdt-engine.js +27 -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 +250 -59
- package/richtexteditor/plugins/documentimport.min.js +4 -4
- package/richtexteditor/plugins/documentoutline.js +47 -8
- package/richtexteditor/plugins/documentoutline.min.js +1 -1
- package/richtexteditor/plugins/docxexport.js +233 -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 +111 -57
- 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 +6 -6
- 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 +8 -8
- package/richtexteditor/plugins/html2pdf.min.js +1 -1
- package/richtexteditor/plugins/imageeditor.js +31 -12
- 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 +29 -11
- package/richtexteditor/plugins/insertcode.min.js +6 -6
- package/richtexteditor/plugins/insertemoji.js +113 -16
- package/richtexteditor/plugins/insertemoji.min.js +1 -1
- package/richtexteditor/plugins/insertgallery.js +46 -40
- package/richtexteditor/plugins/insertgallery.min.js +1 -1
- package/richtexteditor/plugins/inserttemplate.js +43 -19
- 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 +90 -27
- package/richtexteditor/plugins/mentionplugin.min.js +1 -1
- package/richtexteditor/plugins/mermaiddiagram.js +14 -8
- 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/nodetypes.js +1 -1
- package/richtexteditor/plugins/nodetypes.min.js +1 -1
- package/richtexteditor/plugins/pagination.js +2 -2
- package/richtexteditor/plugins/pagination.min.js +1 -1
- package/richtexteditor/plugins/pdfexport.js +1752 -1167
- package/richtexteditor/plugins/pdfexport.min.js +28 -13
- 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 +30 -16
- 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 +173 -41
- package/richtexteditor/plugins/revisionhistory.min.js +3 -3
- package/richtexteditor/plugins/rubyannotation.js +21 -11
- package/richtexteditor/plugins/rubyannotation.min.js +1 -1
- package/richtexteditor/plugins/sanitizer.js +119 -7
- package/richtexteditor/plugins/sanitizer.min.js +1 -1
- package/richtexteditor/plugins/slashcommand.js +32 -18
- package/richtexteditor/plugins/slashcommand.min.js +2 -2
- package/richtexteditor/plugins/smartchips.js +39 -25
- package/richtexteditor/plugins/smartchips.min.js +2 -2
- package/richtexteditor/plugins/spellcheck.js +20 -11
- package/richtexteditor/plugins/spellcheck.min.js +2 -2
- package/richtexteditor/plugins/stateinspector.js +21 -11
- package/richtexteditor/plugins/stateinspector.min.js +2 -2
- package/richtexteditor/plugins/structured-content-bridge.js +90 -32
- package/richtexteditor/plugins/structured-content-bridge.min.js +8 -8
- 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 +19 -6
- 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 +11 -6
- 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 +144 -86
- package/richtexteditor/rte-headless.js +19 -4
- package/richtexteditor/rte-watchdog.js +3 -1
- package/richtexteditor/rte-webcomponent.js +91 -16
- package/richtexteditor/rte.js +146 -88
- package/richtexteditor/runtime/colorpicker_more_ns.htm +3 -1
- 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
|
@@ -226,7 +226,7 @@ RTE_DefaultConfig.insertCellTag = "<td><br/></td>"; // Default cell attributes w
|
|
|
226
226
|
|
|
227
227
|
|
|
228
228
|
|
|
229
|
-
RTE_DefaultConfig.insertOrderedListItems = [["decimal", "1,2,3,4,5"], ["lower-alpha", "a,b,c,d,e"], ["upper-alpha", "A,B,C,D,E"], ["lower-roman", "
|
|
229
|
+
RTE_DefaultConfig.insertOrderedListItems = [["decimal", "1,2,3,4,5"], ["lower-alpha", "a,b,c,d,e"], ["upper-alpha", "A,B,C,D,E"], ["lower-roman", "\u2170,\u2171,\u2172,\u2173,\u2174"], ["upper-roman", "\u2160,\u2161,\u2162,\u2163,\u2164"]];
|
|
230
230
|
|
|
231
231
|
RTE_DefaultConfig.insertUnorderedListItems = [["disc", "Disc"], ["circle", "Circle"], ["square", "Square"]];
|
|
232
232
|
|
|
@@ -258,42 +258,20 @@ RTE_DefaultConfig.backColorItems = ["#000000", "#993300", "#333300", "#003300",
|
|
|
258
258
|
"#ff00ff", "#ffcc00", "#ffff00", "#00ff00", "#00ffff", "#00ccff", "#993366", "#c0c0c0",
|
|
259
259
|
"#ff99cc", "#ffcc99", "#ffff99", "#ccffcc", "#ccffff", "#99ccff", "#cc99ff", "#ffffff"];
|
|
260
260
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
"https://richtexteditor.com/uploads/2.jpg",
|
|
276
|
-
"https://richtexteditor.com/uploads/3.jpg",
|
|
277
|
-
"https://richtexteditor.com/uploads/4.jpg",
|
|
278
|
-
"https://richtexteditor.com/uploads/5.jpg",
|
|
279
|
-
"https://richtexteditor.com/uploads/6.jpg"
|
|
280
|
-
] // For insert image by URL
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
RTE_DefaultConfig.galleryImages = [
|
|
284
|
-
"https://richtexteditor.com/uploads/1.jpg",
|
|
285
|
-
"https://richtexteditor.com/uploads/2.jpg",
|
|
286
|
-
"https://richtexteditor.com/uploads/3.jpg",
|
|
287
|
-
"https://richtexteditor.com/uploads/4.jpg",
|
|
288
|
-
"https://richtexteditor.com/uploads/5.jpg",
|
|
289
|
-
"https://richtexteditor.com/uploads/6.jpg"
|
|
290
|
-
]; // Default images for gallery Images dialog.
|
|
291
|
-
|
|
292
|
-
RTE_DefaultConfig.htmlTemplates = [
|
|
293
|
-
["My Doc 1", "<h2>MyTitleMyTitleMyTitleMyTitleMyTitleMyTitleMyTitle</h2><p>Paragraph 1 </p><p>Paragraph 2 </p><p>Paragraph 3 </p><p>Paragraph 4 </p><p>Paragraph 5 </p>"]
|
|
294
|
-
,
|
|
295
|
-
["My Doc 1", "<h2>MyTitleMyTitleMyTitle</h2><p>Paragraph 1 </p><p>Paragraph 2 </p><p>Paragraph 3 </p><p>Paragraph 4 </p><p>Paragraph 5 </p>"]
|
|
296
|
-
];// Default html Templates for html Templates dialog.
|
|
261
|
+
// 2026-10-26 these three shipped DEMO data: every customer's link dialog suggested five big-company sites, and
|
|
262
|
+
// opening the gallery fetched six images from the vendor's server, on a product that makes no outbound calls.
|
|
263
|
+
// They are empty now; set your own, e.g. linkItems = ["/about", "/contact"], galleryImages = ["/img/a.jpg"].
|
|
264
|
+
// An empty list hides the URL field's suggestion arrow. tools/security/no-default-outbound.mjs
|
|
265
|
+
RTE_DefaultConfig.linkItems = [] // Addresses the Insert Link dialog suggests.
|
|
266
|
+
|
|
267
|
+
RTE_DefaultConfig.imageItems = [] // Addresses the Insert Image (by URL) dialog suggests.
|
|
268
|
+
|
|
269
|
+
RTE_DefaultConfig.galleryImages = []; // Preset images for the gallery dialog: "url", [url, text] or { url, name, alt }.
|
|
270
|
+
|
|
271
|
+
// 2026-10-26 shipped two demo templates, both named "My Doc 1" ("MyTitleMyTitle..."), in every Insert Template
|
|
272
|
+
// dialog. Empty now; set your own: htmlTemplates = [["Letter", "<p>Dear ...</p>"]] or { title, html, description }.
|
|
273
|
+
// tools/templates/template-defaults.mjs
|
|
274
|
+
RTE_DefaultConfig.htmlTemplates = [];// Templates the Insert Template dialog offers.
|
|
297
275
|
|
|
298
276
|
// Slash command menu — type "/" at the start of a line or after whitespace to open an inline command picker.
|
|
299
277
|
// Set slashCommandEnabled to false to disable. Set slashCommandIncludeAi to false to hide AI actions from the menu.
|
|
@@ -377,7 +355,7 @@ RTE_DefaultConfig.stylesMerge = false; // true: the Quick Styles lists below are
|
|
|
377
355
|
// { title: "Callouts", items: [ ... ] } a labelled GROUP; items are indented under a heading
|
|
378
356
|
// Groups render as a heading plus indented items, not as a flyout submenu.
|
|
379
357
|
RTE_DefaultConfig.inlineStyles = [["Red", "color:red", "color:red"], ["Bold", "font-weight:bold", "font-weight:bold"], ["Mark", "my-cls-mark"], ["Warning", "my-cls-warning"]]; // Default CSS styles for inline styles dropdown.
|
|
380
|
-
RTE_DefaultConfig.paragraphStyles = [["Red", "color:red", "color:red"], ["Bold", "font-weight:bold", "font-weight:bold"], ["Quote", "my-cls-quote"], ["
|
|
358
|
+
RTE_DefaultConfig.paragraphStyles = [["Red", "color:red", "color:red"], ["Bold", "font-weight:bold", "font-weight:bold"], ["Quote", "my-cls-quote"], ["Large Center", "my-cls-largecenter"]]; // Default CSS styles for paragraph styles dropdown.
|
|
381
359
|
RTE_DefaultConfig.imageStyles = [["Border", "border: 1px solid #ddd; border-radius: 4px; padding: 5px;"], ["grayscale", "filter: grayscale(100%);"], ["Shadow", "box-shadow:0 0 8px gray"], ["Margin10", "margin:10px"], ["Padding:10", "padding:10px"]
|
|
382
360
|
, ["Rounded Corners", "border-radius: 10px;"], ["Rounded Images", "border-radius: 50%;"], ["Thumbnail Image", "border: 1px solid #ddd; border-radius: 4px; padding: 5px;width:150px"]// Default CSS styles for image Styles dropdown.
|
|
383
361
|
];
|
|
@@ -420,13 +398,15 @@ RTE_DefaultConfig.subtoolbar_more_full = "{strike,ucase,lcase,titlecase,insertho
|
|
|
420
398
|
RTE_DefaultConfig.subtoolbar_more_mobile = "{save} #{newdoc,help}"; // A set of buttons that appears in the subtoolbar of mobile toolbar set.
|
|
421
399
|
RTE_DefaultConfig.subtoolbar_paste = "pasteauto,pastetext,pasteword"; // A set of buttons that appears in the rich text editor's paste subtoolbar.
|
|
422
400
|
RTE_DefaultConfig.subtoolbar_paragraphop = "{justifyleft,justifycenter,justifyright,insertorderedlist,insertunorderedlist,indent,outdent,insertblockquote}" // A set of buttons that appears in the rich text editor's paragraph subtoolbar.
|
|
423
|
-
RTE_DefaultConfig.subtoolbar_table = "controlsizeauto,controlsize100,controlsize75,controlsize50,tabledistributecolumns,tabledistributerows,tableproperties,tabledelete"; // A set of buttons that appears in the table subtoolbar.
|
|
401
|
+
RTE_DefaultConfig.subtoolbar_table = "controlsizeauto,controlsize100,controlsize75,controlsize50,tabledistributecolumns,tabledistributerows,tablecaption,tableproperties,tabledelete"; // A set of buttons that appears in the table subtoolbar.
|
|
424
402
|
RTE_DefaultConfig.subtoolbar_tablerow = "tablerowinsertabove,tablerowinsertbelow,tablerowdelete"; // A set of buttons that appears in the tablerow subtoolbar.
|
|
425
403
|
RTE_DefaultConfig.subtoolbar_tablecell = "tablecellmerge,tablecellsplitver,tablecellsplithor,tablecellforecolor,tablecellbackcolor,tablecelltype,tablecellproperties"; // A set of buttons that appears in the tablecell subtoolbar.
|
|
426
404
|
|
|
427
405
|
// Icons + tooltips for the table/cell commands added 2026-06-18 (Lucide-style line icons).
|
|
428
406
|
RTE_DefaultConfig.text_tablecellproperties = "Cell Properties";
|
|
429
407
|
RTE_DefaultConfig.text_tableproperties = "Table Properties";
|
|
408
|
+
RTE_DefaultConfig.text_tablecaption = "Table Caption";
|
|
409
|
+
RTE_DefaultConfig.svgCode_tablecaption = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="4" x2="18" y2="4"/><rect x="3" y="8" width="18" height="13" rx="1"/><line x1="3" y1="14.5" x2="21" y2="14.5"/><line x1="12" y1="8" x2="12" y2="21"/></svg>';
|
|
430
410
|
RTE_DefaultConfig.text_tablecelltype = "Toggle Header Cell";
|
|
431
411
|
RTE_DefaultConfig.text_tabledistributecolumns = "Distribute Columns";
|
|
432
412
|
RTE_DefaultConfig.text_tabledistributerows = "Distribute Rows";
|
|
@@ -649,22 +629,22 @@ RTE_DefaultConfig.text_ok = "OK";
|
|
|
649
629
|
RTE_DefaultConfig.text_cancel = "Cancel";
|
|
650
630
|
|
|
651
631
|
RTE_DefaultConfig.text_normal = "Normal"
|
|
652
|
-
RTE_DefaultConfig.text_h1 = "
|
|
653
|
-
RTE_DefaultConfig.text_h2 = "
|
|
654
|
-
RTE_DefaultConfig.text_h3 = "
|
|
655
|
-
RTE_DefaultConfig.text_h4 = "
|
|
656
|
-
RTE_DefaultConfig.text_h5 = "
|
|
657
|
-
RTE_DefaultConfig.text_h6 = "
|
|
658
|
-
RTE_DefaultConfig.text_h7 = "
|
|
632
|
+
RTE_DefaultConfig.text_h1 = "Heading 1"
|
|
633
|
+
RTE_DefaultConfig.text_h2 = "Heading 2"
|
|
634
|
+
RTE_DefaultConfig.text_h3 = "Heading 3"
|
|
635
|
+
RTE_DefaultConfig.text_h4 = "Heading 4"
|
|
636
|
+
RTE_DefaultConfig.text_h5 = "Heading 5"
|
|
637
|
+
RTE_DefaultConfig.text_h6 = "Heading 6"
|
|
638
|
+
RTE_DefaultConfig.text_h7 = "Heading 7"
|
|
659
639
|
|
|
660
640
|
RTE_DefaultConfig.text_close = "Close";
|
|
661
641
|
|
|
662
642
|
RTE_DefaultConfig.text_bold = "Bold";
|
|
663
643
|
RTE_DefaultConfig.text_italic = "Italic";
|
|
664
644
|
RTE_DefaultConfig.text_underline = "Underline";
|
|
665
|
-
RTE_DefaultConfig.text_strike = "
|
|
645
|
+
RTE_DefaultConfig.text_strike = "Strikethrough";
|
|
666
646
|
RTE_DefaultConfig.text_superscript = "Superscript";
|
|
667
|
-
RTE_DefaultConfig.text_subscript = "
|
|
647
|
+
RTE_DefaultConfig.text_subscript = "Subscript";
|
|
668
648
|
RTE_DefaultConfig.text_ucase = "Upper Case";
|
|
669
649
|
RTE_DefaultConfig.text_lcase = "Lower Case";
|
|
670
650
|
RTE_DefaultConfig.text_titlecase = "Title Case";
|
|
@@ -675,17 +655,17 @@ RTE_DefaultConfig.text_titlecase = "Title Case";
|
|
|
675
655
|
// translate without forking the plugin source.
|
|
676
656
|
RTE_DefaultConfig.svgCode_documentoutline = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="6" x2="20" y2="6"/><line x1="9" y1="11" x2="20" y2="11"/><line x1="12" y1="16" x2="20" y2="16"/><line x1="3" y1="6" x2="3.5" y2="6"/><line x1="6" y1="11" x2="6.5" y2="11"/><line x1="9" y1="16" x2="9.5" y2="16"/></svg>';
|
|
677
657
|
RTE_DefaultConfig.text_documentoutline = "Document outline";
|
|
678
|
-
RTE_DefaultConfig.text_documentoutlinehint = "Live table of contents
|
|
658
|
+
RTE_DefaultConfig.text_documentoutlinehint = "Live table of contents \u2014 click any heading to jump to it.";
|
|
679
659
|
|
|
680
660
|
RTE_DefaultConfig.svgCode_contentminimap = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="6" y1="7" x2="14" y2="7"/><line x1="6" y1="11" x2="18" y2="11"/><line x1="6" y1="15" x2="12" y2="15"/><line x1="6" y1="19" x2="16" y2="19"/></svg>';
|
|
681
661
|
RTE_DefaultConfig.text_contentminimap = "Content minimap";
|
|
682
|
-
RTE_DefaultConfig.text_contentminimaphint = "Bird's-eye view of the document
|
|
662
|
+
RTE_DefaultConfig.text_contentminimaphint = "Bird's-eye view of the document \u2014 drag the highlight box to scroll.";
|
|
683
663
|
|
|
684
664
|
RTE_DefaultConfig.svgCode_accessibilitychecker = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="7" r="1.4" fill="currentColor"/><path d="M9 11.5h6"/><path d="M12 11.5v8"/><path d="M9 19.5l3-4 3 4"/></svg>';
|
|
685
665
|
RTE_DefaultConfig.text_accessibilitychecker = "Accessibility checker";
|
|
686
666
|
RTE_DefaultConfig.text_accessibilitycheckerhint = "Scan the document for missing alt text, empty headings, low contrast, and other a11y issues.";
|
|
687
667
|
|
|
688
|
-
RTE_DefaultConfig.text_removeformat = "
|
|
668
|
+
RTE_DefaultConfig.text_removeformat = "Clear Formatting";
|
|
689
669
|
|
|
690
670
|
RTE_DefaultConfig.text_insertlink = "Insert Link";
|
|
691
671
|
RTE_DefaultConfig.text_openlink = "Open Link";
|
|
@@ -704,8 +684,8 @@ RTE_DefaultConfig.text_outdent = "Outdent";
|
|
|
704
684
|
|
|
705
685
|
RTE_DefaultConfig.text_insertblockquote = "Block Quote";
|
|
706
686
|
|
|
707
|
-
RTE_DefaultConfig.text_insertorderedlist = "
|
|
708
|
-
RTE_DefaultConfig.text_insertunorderedlist = "
|
|
687
|
+
RTE_DefaultConfig.text_insertorderedlist = "Numbered List";
|
|
688
|
+
RTE_DefaultConfig.text_insertunorderedlist = "Bulleted List";
|
|
709
689
|
|
|
710
690
|
RTE_DefaultConfig.text_inserthorizontalrule = "Insert Horizontal Rule";
|
|
711
691
|
RTE_DefaultConfig.text_insertdate = "Insert Date";
|
|
@@ -745,13 +725,13 @@ RTE_DefaultConfig.text_inlinestyles = "Text styles";// Quick Styles applied to t
|
|
|
745
725
|
RTE_DefaultConfig.text_fontname = "Font";
|
|
746
726
|
RTE_DefaultConfig.text_fontsize = "Size";
|
|
747
727
|
RTE_DefaultConfig.text_forecolor = "Text Color";
|
|
748
|
-
RTE_DefaultConfig.text_backcolor = "
|
|
728
|
+
RTE_DefaultConfig.text_backcolor = "Background Color";
|
|
749
729
|
|
|
750
730
|
RTE_DefaultConfig.text_justify = "Justify"
|
|
751
|
-
RTE_DefaultConfig.text_justifyleft = "
|
|
752
|
-
RTE_DefaultConfig.text_justifyright = "
|
|
753
|
-
RTE_DefaultConfig.text_justifycenter = "
|
|
754
|
-
RTE_DefaultConfig.text_justifyfull = "Justify
|
|
731
|
+
RTE_DefaultConfig.text_justifyleft = "Align Left"
|
|
732
|
+
RTE_DefaultConfig.text_justifyright = "Align Right"
|
|
733
|
+
RTE_DefaultConfig.text_justifycenter = "Align Center"
|
|
734
|
+
RTE_DefaultConfig.text_justifyfull = "Justify"
|
|
755
735
|
RTE_DefaultConfig.text_justifynone = "Justify None"
|
|
756
736
|
|
|
757
737
|
RTE_DefaultConfig.text_delete = "Delete";
|
|
@@ -764,11 +744,11 @@ RTE_DefaultConfig.text_preview = "Preview";
|
|
|
764
744
|
RTE_DefaultConfig.text_print = "Print";
|
|
765
745
|
RTE_DefaultConfig.text_undo = "Undo";
|
|
766
746
|
RTE_DefaultConfig.text_redo = "Redo";
|
|
767
|
-
RTE_DefaultConfig.text_more = "More
|
|
747
|
+
RTE_DefaultConfig.text_more = "More\u2026";
|
|
768
748
|
RTE_DefaultConfig.text_newdoc = "New Doc";
|
|
769
749
|
RTE_DefaultConfig.text_help = "Help";
|
|
770
750
|
|
|
771
|
-
RTE_DefaultConfig.text_fullscreenenter = "
|
|
751
|
+
RTE_DefaultConfig.text_fullscreenenter = "Full Screen";
|
|
772
752
|
RTE_DefaultConfig.text_fullscreenexit = "Exit Full Screen";
|
|
773
753
|
RTE_DefaultConfig.text_fullscreen = "@text_fullscreenenter";
|
|
774
754
|
|
|
@@ -782,9 +762,9 @@ RTE_DefaultConfig.text_paragraphstyle = "Paragraph Styles";
|
|
|
782
762
|
RTE_DefaultConfig.text_linkstyle = "Link Styles";
|
|
783
763
|
RTE_DefaultConfig.text_link = "Link";
|
|
784
764
|
RTE_DefaultConfig.text_style = "Styles";
|
|
785
|
-
RTE_DefaultConfig.text_cssclass = "
|
|
786
|
-
RTE_DefaultConfig.text_url = "
|
|
787
|
-
RTE_DefaultConfig.text_byurl = "By
|
|
765
|
+
RTE_DefaultConfig.text_cssclass = "CSS Classes";
|
|
766
|
+
RTE_DefaultConfig.text_url = "URL";
|
|
767
|
+
RTE_DefaultConfig.text_byurl = "By URL";
|
|
788
768
|
RTE_DefaultConfig.text_upload = "Upload";
|
|
789
769
|
RTE_DefaultConfig.text_size = "Size";
|
|
790
770
|
|
|
@@ -795,7 +775,7 @@ RTE_DefaultConfig.text_opennewwin = "Open in new tab";
|
|
|
795
775
|
RTE_DefaultConfig.text_insert = "Insert";
|
|
796
776
|
RTE_DefaultConfig.text_update = "Update";
|
|
797
777
|
|
|
798
|
-
RTE_DefaultConfig.text_find = "Find
|
|
778
|
+
RTE_DefaultConfig.text_find = "Find and Replace";
|
|
799
779
|
RTE_DefaultConfig.text_findwhat = "Find";
|
|
800
780
|
RTE_DefaultConfig.text_replacewith = "Replace";
|
|
801
781
|
|
|
@@ -854,9 +834,9 @@ RTE_DefaultConfig.text_pmoveup = "Move Up";
|
|
|
854
834
|
RTE_DefaultConfig.text_pmovedown = "Move Down";
|
|
855
835
|
RTE_DefaultConfig.text_pduplicate = "Duplicate";
|
|
856
836
|
RTE_DefaultConfig.text_pdelete = "Delete";
|
|
857
|
-
RTE_DefaultConfig.text_pmore = "More
|
|
837
|
+
RTE_DefaultConfig.text_pmore = "More\u2026";
|
|
858
838
|
|
|
859
|
-
RTE_DefaultConfig.text_togglemore = "More
|
|
839
|
+
RTE_DefaultConfig.text_togglemore = "More\u2026";
|
|
860
840
|
RTE_DefaultConfig.text_toggleborder = "Toggle Border";
|
|
861
841
|
|
|
862
842
|
RTE_DefaultConfig.text_cut = "Cut";
|
|
@@ -877,7 +857,7 @@ RTE_DefaultConfig.text_insertbookmarktitle = "Insert bookmark";
|
|
|
877
857
|
RTE_DefaultConfig.text_insertbookmarklabel = "Link URL";
|
|
878
858
|
RTE_DefaultConfig.text_spellcheck = "Spell Check";
|
|
879
859
|
RTE_DefaultConfig.text_spellchecktitle = "Spelling";
|
|
880
|
-
RTE_DefaultConfig.text_spellchecknative = "Browser spell-check is on
|
|
860
|
+
RTE_DefaultConfig.text_spellchecknative = "Browser spell-check is on \u2014 misspellings are underlined as you type.";
|
|
881
861
|
RTE_DefaultConfig.text_spellcheckclean = "No spelling issues found.";
|
|
882
862
|
RTE_DefaultConfig.text_insertdatechip = "Date Chip";
|
|
883
863
|
RTE_DefaultConfig.text_insertchip = "Smart Chip";
|
|
@@ -954,14 +934,80 @@ RTE_DefaultConfig.translation = RTE_DefaultConfig.translation || {
|
|
|
954
934
|
RTE_DefaultConfig.plugin_insertcomment = function () {
|
|
955
935
|
var obj = this;
|
|
956
936
|
obj.PluginName = "InsertComment";
|
|
937
|
+
// Wraps each block's part of range in its own make() element, and returns them. The selection is
|
|
938
|
+
// cut into runs of text that share a block; a run starting or ending at the edge of an inline
|
|
939
|
+
// element (<b>) takes the whole element, so no empty <b></b> is left behind; text inside a
|
|
940
|
+
// non-editable element (a chip) moves with its run; a whitespace-only run (the line break between
|
|
941
|
+
// two blocks) gets nothing.
|
|
942
|
+
function markEachBlock(doc, range, make) {
|
|
943
|
+
var BLOCK = /^(P|DIV|LI|UL|OL|DL|DT|DD|TABLE|TBODY|THEAD|TFOOT|TR|TD|TH|CAPTION|H[1-6]|PRE|BLOCKQUOTE|ADDRESS|FIGURE|FIGCAPTION|SECTION|ARTICLE|ASIDE|HEADER|FOOTER|NAV|MAIN|DETAILS|SUMMARY|FORM|FIELDSET|LEGEND|HR|BODY)$/;
|
|
944
|
+
function blockOf(node) {
|
|
945
|
+
for (var n = node; n; n = n.parentNode)
|
|
946
|
+
if (n.nodeType === 1 && BLOCK.test(n.nodeName)) return n;
|
|
947
|
+
return null;
|
|
948
|
+
}
|
|
949
|
+
var root = range.commonAncestorContainer;
|
|
950
|
+
if (root.nodeType !== 1) root = root.parentNode;
|
|
951
|
+
var runs = [], cur = null;
|
|
952
|
+
var w = doc.createTreeWalker(root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, {
|
|
953
|
+
acceptNode: function (n) { return n.nodeType === 1 && n.getAttribute("contenteditable") === "false" ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT; }
|
|
954
|
+
});
|
|
955
|
+
for (var n = w.nextNode(); n; n = w.nextNode()) {
|
|
956
|
+
if (n.nodeType === 1) {
|
|
957
|
+
if (BLOCK.test(n.nodeName)) cur = null;
|
|
958
|
+
continue;
|
|
959
|
+
}
|
|
960
|
+
if (!range.intersectsNode(n)) continue;
|
|
961
|
+
var a = n === range.startContainer ? range.startOffset : 0, b = n === range.endContainer ? range.endOffset : n.data.length;
|
|
962
|
+
if (b <= a) continue;
|
|
963
|
+
var blk = blockOf(n);
|
|
964
|
+
if (!cur || cur.block !== blk) {
|
|
965
|
+
cur = { block: blk, sn: n, so: a, text: "" };
|
|
966
|
+
runs.push(cur);
|
|
967
|
+
}
|
|
968
|
+
cur.en = n;
|
|
969
|
+
cur.eo = b;
|
|
970
|
+
cur.text += n.data.substring(a, b);
|
|
971
|
+
}
|
|
972
|
+
var out = [];
|
|
973
|
+
// from the last run back: wrapping one never moves the text of a run still to come
|
|
974
|
+
for (var i = runs.length - 1; i >= 0; i--) {
|
|
975
|
+
var run = runs[i];
|
|
976
|
+
if (!/\S/.test(run.text)) continue;
|
|
977
|
+
var sub = doc.createRange();
|
|
978
|
+
sub.setStart(run.sn, run.so);
|
|
979
|
+
sub.setEnd(run.en, run.eo);
|
|
980
|
+
var x = sub.startContainer;
|
|
981
|
+
if (x.nodeType === 3 && sub.startOffset === 0) {
|
|
982
|
+
while (x.parentNode && x.parentNode !== run.block && !x.previousSibling && !BLOCK.test(x.parentNode.nodeName)) x = x.parentNode;
|
|
983
|
+
sub.setStartBefore(x);
|
|
984
|
+
}
|
|
985
|
+
x = sub.endContainer;
|
|
986
|
+
if (x.nodeType === 3 && sub.endOffset === x.data.length) {
|
|
987
|
+
while (x.parentNode && x.parentNode !== run.block && !x.nextSibling && !BLOCK.test(x.parentNode.nodeName)) x = x.parentNode;
|
|
988
|
+
sub.setEndAfter(x);
|
|
989
|
+
}
|
|
990
|
+
var el = make();
|
|
991
|
+
el.appendChild(sub.extractContents());
|
|
992
|
+
sub.insertNode(el);
|
|
993
|
+
out.unshift(el);
|
|
994
|
+
}
|
|
995
|
+
return out;
|
|
996
|
+
}
|
|
957
997
|
obj.InitConfig = function () {};
|
|
958
998
|
obj.InitEditor = function (editor) {
|
|
959
999
|
editor.attachEvent("exec_command_insertcomment", function (state) {
|
|
960
1000
|
var edDoc = editor.document;
|
|
961
1001
|
var sel = edDoc.defaultView.getSelection();
|
|
962
1002
|
var selectedText = sel && !sel.isCollapsed ? sel.toString() : "";
|
|
963
|
-
|
|
964
|
-
|
|
1003
|
+
// 2026-10-02 The range is kept from the moment the dialog opens: read on submit, after
|
|
1004
|
+
// focus had moved into the dialog, it could be collapsed (an EMPTY mark landed at the
|
|
1005
|
+
// start of the document in Firefox). tools/comments/comment-dialog.mjs
|
|
1006
|
+
var savedRange = selectedText ? sel.getRangeAt(0).cloneRange() : null;
|
|
1007
|
+
|
|
1008
|
+
// 2026-10-18 the dialog's words read config.text_ keys (English as the fallback).
|
|
1009
|
+
// tools/i18n/core-dialogs-language.mjs
|
|
1010
|
+
var dialoginner = editor.createDialog((editor.config || {}).text_commentapply || "Add Comment", "rte-dialog-insertcomment");
|
|
965
1011
|
dialoginner.style.padding = "14px";
|
|
966
1012
|
if (selectedText) {
|
|
967
1013
|
var preview = document.createElement("div");
|
|
@@ -970,30 +1016,39 @@ RTE_DefaultConfig.plugin_insertcomment = function () {
|
|
|
970
1016
|
dialoginner.appendChild(preview);
|
|
971
1017
|
}
|
|
972
1018
|
var label = document.createElement("label");
|
|
973
|
-
label.innerText = "Comment:";
|
|
1019
|
+
label.innerText = (editor.config || {}).text_dlg_commentlabel || "Comment:";
|
|
974
1020
|
label.className = "rte-comment-dialog-label";
|
|
975
1021
|
dialoginner.appendChild(label);
|
|
976
1022
|
var textarea = document.createElement("textarea");
|
|
977
1023
|
textarea.id = "rte-comment-input-" + new Date().getTime();
|
|
978
1024
|
label.htmlFor = textarea.id;
|
|
979
|
-
textarea.placeholder = "Type your comment...";
|
|
1025
|
+
textarea.placeholder = (editor.config || {}).text_commentplaceholder || "Type your comment...";
|
|
980
1026
|
textarea.className = "rte-comment-dialog-input";
|
|
981
1027
|
dialoginner.appendChild(textarea);
|
|
982
1028
|
var btnRow = document.createElement("div");
|
|
983
1029
|
btnRow.className = "rte-comment-dialog-actions";
|
|
984
1030
|
var insertBtn = document.createElement("button");
|
|
985
|
-
insertBtn.innerText = "Add Comment";
|
|
1031
|
+
insertBtn.innerText = (editor.config || {}).text_commentapply || "Add Comment";
|
|
986
1032
|
insertBtn.type = "button";
|
|
987
1033
|
insertBtn.className = "rte-comment-dialog-submit";
|
|
1034
|
+
// 2026-10-15 unstyled, the buttons were 21px tall: WCAG 2.5.8 asks for 24px targets. tools/a11y/dialog-axe.mjs
|
|
1035
|
+
insertBtn.style.cssText = "min-height:28px;padding:4px 14px;margin-right:6px;cursor:pointer;";
|
|
988
1036
|
insertBtn.onclick = function () {
|
|
989
1037
|
var comment = textarea.value.replace(/^\s+|\s+$/g, "");
|
|
990
|
-
if (comment &&
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
mark
|
|
995
|
-
|
|
996
|
-
|
|
1038
|
+
if (comment && savedRange) {
|
|
1039
|
+
// 2026-10-02 range.surroundContents THREW whenever the selection crossed an
|
|
1040
|
+
// element edge - starting inside a bold word, two paragraphs, two list items - and
|
|
1041
|
+
// the throw was swallowed: the dialog closed and the typed comment was gone. Each
|
|
1042
|
+
// block's part of the selection now gets its own mark (a mark around blocks would
|
|
1043
|
+
// split them, as links and the comments plugin did).
|
|
1044
|
+
if (editor.commitBookmark) editor.commitBookmark();
|
|
1045
|
+
markEachBlock(edDoc, savedRange, function () {
|
|
1046
|
+
var mark = edDoc.createElement("mark");
|
|
1047
|
+
mark.style.cssText = "background:#fff9c4;border-bottom:2px solid #f9a825;cursor:pointer;position:relative;";
|
|
1048
|
+
mark.setAttribute("title", comment);
|
|
1049
|
+
mark.setAttribute("data-comment", comment);
|
|
1050
|
+
return mark;
|
|
1051
|
+
});
|
|
997
1052
|
} else if (comment) {
|
|
998
1053
|
var safeComment = comment.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
999
1054
|
editor.insertHTML('<span class="rte-comment-marker" contenteditable="false" style="background:#fff9c4;border:1px solid #f9a825;border-radius:3px;padding:1px 6px;font-size:11px;color:#f57f17;cursor:pointer;" title="' + safeComment + '">💬 Comment</span>');
|
|
@@ -1002,9 +1057,10 @@ RTE_DefaultConfig.plugin_insertcomment = function () {
|
|
|
1002
1057
|
editor.focus();
|
|
1003
1058
|
};
|
|
1004
1059
|
var cancelBtn = document.createElement("button");
|
|
1005
|
-
cancelBtn.innerText = "Cancel";
|
|
1060
|
+
cancelBtn.innerText = (editor.config || {}).text_cancel || "Cancel";
|
|
1006
1061
|
cancelBtn.type = "button";
|
|
1007
1062
|
cancelBtn.className = "rte-comment-dialog-cancel";
|
|
1063
|
+
cancelBtn.style.cssText = "min-height:28px;padding:4px 14px;cursor:pointer;";
|
|
1008
1064
|
cancelBtn.onclick = function () {
|
|
1009
1065
|
dialoginner.close();
|
|
1010
1066
|
editor.focus();
|
|
@@ -1030,16 +1086,18 @@ RTE_DefaultConfig.plugin_insertcomment = function () {
|
|
|
1030
1086
|
};
|
|
1031
1087
|
};
|
|
1032
1088
|
|
|
1033
|
-
// ===
|
|
1089
|
+
// === Keyboard shortcut hints for the toolbar tooltips (config.keyboardShortcutHints). ===
|
|
1034
1090
|
(function () {
|
|
1035
1091
|
if (!RTE_DefaultConfig.showKeyboardShortcutsInTooltips) return;
|
|
1036
1092
|
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad|iPod/i.test(navigator.platform || navigator.userAgent || "");
|
|
1037
|
-
var mod = isMac ? "
|
|
1038
|
-
var shift = isMac ? "
|
|
1093
|
+
var mod = isMac ? "\u2318" : "Ctrl";
|
|
1094
|
+
var shift = isMac ? "\u21e7" : "Shift";
|
|
1095
|
+
// 2026-10-18 a map read by rte.js for the toolbar TOOLTIPS; the label strings are no longer rewritten, so a
|
|
1096
|
+
// dialog title or a button's accessible name never carries " (Ctrl+K)" and a language pack keeps the hints.
|
|
1097
|
+
// tools/i18n/shortcut-hints.mjs
|
|
1098
|
+
var hints = RTE_DefaultConfig.keyboardShortcutHints = RTE_DefaultConfig.keyboardShortcutHints || {};
|
|
1039
1099
|
function add(cmd, key) {
|
|
1040
|
-
|
|
1041
|
-
if (!base || / \(.+\)$/.test(base)) return;
|
|
1042
|
-
RTE_DefaultConfig["text_" + cmd] = base + " (" + key + ")";
|
|
1100
|
+
if (!hints[cmd]) hints[cmd] = key;
|
|
1043
1101
|
}
|
|
1044
1102
|
add("bold", mod + "+B");
|
|
1045
1103
|
add("italic", mod + "+I");
|
|
@@ -116,15 +116,18 @@
|
|
|
116
116
|
}, 16);
|
|
117
117
|
}
|
|
118
118
|
this._emitUpdate = emitUpdate;
|
|
119
|
+
this._editorListeners = [];
|
|
119
120
|
|
|
120
121
|
["selectionchange", "change", "focus", "blur"].forEach(function (evt) {
|
|
121
122
|
try {
|
|
122
|
-
|
|
123
|
+
var listener = function (a, b) {
|
|
123
124
|
self._emit(evt, a, b);
|
|
124
125
|
if (evt === "selectionchange" || evt === "change") {
|
|
125
126
|
emitUpdate();
|
|
126
127
|
}
|
|
127
|
-
}
|
|
128
|
+
};
|
|
129
|
+
self.editor.attachEvent(evt, listener);
|
|
130
|
+
self._editorListeners.push([evt, listener]);
|
|
128
131
|
} catch (e) { /* event surface differs by build; ignore */ }
|
|
129
132
|
});
|
|
130
133
|
|
|
@@ -150,6 +153,7 @@
|
|
|
150
153
|
};
|
|
151
154
|
|
|
152
155
|
HeadlessController.prototype.on = function (name, cb) {
|
|
156
|
+
if (this._destroyed) return this;
|
|
153
157
|
if (typeof cb === "function") {
|
|
154
158
|
(this._handlers[name] = this._handlers[name] || []).push(cb);
|
|
155
159
|
}
|
|
@@ -165,12 +169,13 @@
|
|
|
165
169
|
};
|
|
166
170
|
|
|
167
171
|
HeadlessController.prototype._emit = function (name) {
|
|
172
|
+
if (this._destroyed) return;
|
|
168
173
|
var list = this._handlers[name];
|
|
169
174
|
if (!list || !list.length) {
|
|
170
175
|
return;
|
|
171
176
|
}
|
|
172
177
|
var args = Array.prototype.slice.call(arguments, 1);
|
|
173
|
-
for (var i = 0; i < list.length; i++) {
|
|
178
|
+
for (var i = 0; i < list.length && !this._destroyed; i++) {
|
|
174
179
|
try {
|
|
175
180
|
list[i].apply(this, args);
|
|
176
181
|
} catch (e) {
|
|
@@ -303,8 +308,15 @@
|
|
|
303
308
|
};
|
|
304
309
|
|
|
305
310
|
HeadlessController.prototype.destroy = function () {
|
|
311
|
+
if (this._destroyed) return this;
|
|
306
312
|
this._destroyed = true;
|
|
307
313
|
this._handlers = {};
|
|
314
|
+
if (this._editorListeners) {
|
|
315
|
+
for (var ei = 0; ei < this._editorListeners.length; ei++) {
|
|
316
|
+
try { this.editor.detachEvent(this._editorListeners[ei][0], this._editorListeners[ei][1]); } catch (e) {}
|
|
317
|
+
}
|
|
318
|
+
this._editorListeners = null;
|
|
319
|
+
}
|
|
308
320
|
// Drop format subscriptions here too: _destroyed alone only silences the
|
|
309
321
|
// callback, it does not stop the core from evaluating the commands on
|
|
310
322
|
// every toolbar refresh for a controller nobody is using any more.
|
|
@@ -321,7 +333,10 @@
|
|
|
321
333
|
}
|
|
322
334
|
this._docListeners = null;
|
|
323
335
|
this._boundDoc = null;
|
|
324
|
-
try {
|
|
336
|
+
try {
|
|
337
|
+
if (typeof this.editor.destroy === "function") this.editor.destroy();
|
|
338
|
+
else if (typeof this.editor.prepareDestroy === "function") this.editor.prepareDestroy();
|
|
339
|
+
} catch (e) { /* ignore */ }
|
|
325
340
|
return this;
|
|
326
341
|
};
|
|
327
342
|
|
|
@@ -279,7 +279,9 @@
|
|
|
279
279
|
|
|
280
280
|
// The old instance leaves its chrome in the host element; a fresh editor
|
|
281
281
|
// built on top of that would stack two toolbars.
|
|
282
|
-
|
|
282
|
+
// textContent, not innerHTML: under Trusted Types even innerHTML = "" is refused (a CSP violation the catch
|
|
283
|
+
// hid, so the host was never cleared here). tools/csp/trusted-types-companions.mjs
|
|
284
|
+
try { if (this._host) this._host.textContent = ""; } catch (e) {}
|
|
283
285
|
|
|
284
286
|
try {
|
|
285
287
|
this._start();
|