@richscripts/richtexteditor 2.4.0 → 2.4.1
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/migration/README.md +100 -0
- package/migration/cli.js +294 -0
- package/migration/index.d.ts +18 -0
- package/migration/index.js +242 -0
- package/migration/report-schema-v2.json +127 -0
- package/package.json +11 -1
- package/richtexteditor/CHANGELOG.md +326 -1
- package/richtexteditor/all_plugins.js +14959 -4832
- package/richtexteditor/all_plugins.min.js +62 -42
- package/richtexteditor/plugins/accessibilitychecker.js +8 -7
- package/richtexteditor/plugins/aitoolkit.css +17 -8
- package/richtexteditor/plugins/aitoolkit.js +8 -8
- package/richtexteditor/plugins/all_plugins.js +14959 -4832
- package/richtexteditor/plugins/all_plugins.min.js +62 -42
- package/richtexteditor/plugins/autocorrect.js +353 -0
- package/richtexteditor/plugins/bookmarkcard.js +12 -1
- package/richtexteditor/plugins/changecase.js +238 -0
- package/richtexteditor/plugins/comments.js +15 -28
- package/richtexteditor/plugins/contentminimap.js +6 -5
- package/richtexteditor/plugins/crossreference.js +408 -0
- package/richtexteditor/plugins/documentimport.js +915 -21
- package/richtexteditor/plugins/documentoutline.js +5 -4
- package/richtexteditor/plugins/docxexport.js +960 -0
- package/richtexteditor/plugins/draghandle.js +309 -0
- package/richtexteditor/plugins/footnotes.js +398 -0
- package/richtexteditor/plugins/formatpainter.js +298 -0
- package/richtexteditor/plugins/formattingmarks.js +246 -0
- package/richtexteditor/plugins/html2pdf.js +108 -4
- package/richtexteditor/plugins/imageeditor.js +37 -7
- package/richtexteditor/plugins/insertgallery.js +553 -170
- package/richtexteditor/plugins/keyboarda11y.js +316 -0
- package/richtexteditor/plugins/linenumbers.js +352 -0
- package/richtexteditor/plugins/linkchecker.js +396 -0
- package/richtexteditor/plugins/mentionplugin.js +4 -3
- package/richtexteditor/plugins/mergefields.js +328 -0
- package/richtexteditor/plugins/multilevellist.js +137 -0
- package/richtexteditor/plugins/pagination.js +505 -0
- package/richtexteditor/plugins/pdfexport.js +1137 -0
- package/richtexteditor/plugins/permanentpen.js +211 -0
- package/richtexteditor/plugins/revisionhistory.js +47 -34
- package/richtexteditor/plugins/rtlui.js +150 -0
- package/richtexteditor/plugins/sanitizer.js +486 -0
- package/richtexteditor/plugins/slashcommand.js +142 -17
- package/richtexteditor/plugins/spellcheck.js +6 -3
- package/richtexteditor/plugins/tableofcontents.js +353 -0
- package/richtexteditor/plugins/tabletools.js +342 -0
- package/richtexteditor/plugins/textdirection.js +313 -0
- package/richtexteditor/plugins/trackedchanges.js +37 -6
- package/richtexteditor/plugins/tui.image-editor/tui-code-snippet.min.js +1 -1
- package/richtexteditor/plugins/tui.image-editor/tui-color-picker.min.js +1 -1
- package/richtexteditor/plugins/tui.image-editor/tui-image-editor.min.js +1 -1
- package/richtexteditor/plugins/vendor/html2pdf.bundle.min.js +3 -0
- package/richtexteditor/plugins/watermark.js +214 -0
- package/richtexteditor/plugins/wordexport.js +0 -0
- package/richtexteditor/plugins/yjscollab.js +49 -11
- package/richtexteditor/rte-config.js +44 -44
- package/richtexteditor/rte.js +91 -63
- package/richtexteditor/rte_theme_default.css +462 -384
|
@@ -6,9 +6,53 @@ if (!RTE_DefaultConfig.svgCode_html2pdf) {
|
|
|
6
6
|
|
|
7
7
|
RTE_DefaultConfig.plugin_html2pdf = RTE_Plugin_Html2PDF;
|
|
8
8
|
|
|
9
|
+
// Where to load the html2pdf renderer from. Leave null to use the pinned copy
|
|
10
|
+
// shipped in <url_base>/plugins/vendor/. Set it to serve the bundle from your own
|
|
11
|
+
// CDN, a versioned asset path, or a different build.
|
|
12
|
+
if (typeof RTE_DefaultConfig.html2pdfScriptUrl === "undefined") RTE_DefaultConfig.html2pdfScriptUrl = null;
|
|
13
|
+
|
|
9
14
|
function RTE_Plugin_Html2PDF() {
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
// The html2pdf renderer (jsPDF + html2canvas) is ~900 KB, so it is loaded on
|
|
17
|
+
// demand rather than bundled — but it is served from YOUR OWN assets by
|
|
18
|
+
// default, alongside the rest of the editor.
|
|
19
|
+
//
|
|
20
|
+
// It used to be pulled from a GitHub raw-CDN URL that tracked a branch rather
|
|
21
|
+
// than a release. That meant PDF export required a public network round-trip
|
|
22
|
+
// (so it failed offline / air-gapped), demanded a third-party `script-src`
|
|
23
|
+
// entry in any Content-Security-Policy, and could change underneath the
|
|
24
|
+
// product with no version pin. The bundled copy is pinned at html2pdf.js
|
|
25
|
+
// 0.14.0.
|
|
26
|
+
//
|
|
27
|
+
// Resolution order:
|
|
28
|
+
// 1. config.html2pdfScriptUrl — explicit override (absolute or relative)
|
|
29
|
+
// 2. <url_base>/plugins/vendor/... — the copy shipped with the editor
|
|
30
|
+
// 3. a pinned CDN URL — last resort if url_base is unknown
|
|
31
|
+
var VENDOR_PATH = "/plugins/vendor/html2pdf.bundle.min.js";
|
|
32
|
+
// 2026-07-31 There is deliberately NO built-in CDN fallback any more.
|
|
33
|
+
//
|
|
34
|
+
// A fallback that silently reaches a third-party CDN when url_base happens to
|
|
35
|
+
// be unset is the worst of both worlds: it hides a misconfiguration, and it
|
|
36
|
+
// puts a public URL in a file that security-scanned deployments must ship.
|
|
37
|
+
// Failing loudly is better -- the host either serves the vendored copy or
|
|
38
|
+
// points html2pdfScriptUrl wherever it wants, including its own CDN.
|
|
39
|
+
|
|
40
|
+
// The script tag is written into a generated iframe whose base URL is not the
|
|
41
|
+
// host page, so the URL has to be absolute by the time it is injected.
|
|
42
|
+
function absoluteUrl(url) {
|
|
43
|
+
try { return new URL(url, document.baseURI || location.href).href; }
|
|
44
|
+
catch (e) { return url; }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function resolveScriptUrl() {
|
|
48
|
+
if (config && config.html2pdfScriptUrl) return absoluteUrl(config.html2pdfScriptUrl);
|
|
49
|
+
var base = config && config.url_base ? String(config.url_base).replace(/\/+$/, "") : "";
|
|
50
|
+
if (base) return absoluteUrl(base + VENDOR_PATH);
|
|
51
|
+
// No url_base and no explicit override: resolve against the page instead
|
|
52
|
+
// of reaching outside. If that 404s the failure is visible and local,
|
|
53
|
+
// which is what a misconfigured deployment should look like.
|
|
54
|
+
return absoluteUrl("." + VENDOR_PATH);
|
|
55
|
+
}
|
|
12
56
|
|
|
13
57
|
var obj = this;
|
|
14
58
|
|
|
@@ -36,6 +80,59 @@ function RTE_Plugin_Html2PDF() {
|
|
|
36
80
|
|
|
37
81
|
}
|
|
38
82
|
|
|
83
|
+
// Paper size / orientation / margins for the exported PDF, taken from the
|
|
84
|
+
// document's page setup when it has one. Returns the historical
|
|
85
|
+
// letter/portrait/0.5in defaults otherwise, so documents without a page
|
|
86
|
+
// setup export exactly as they always have.
|
|
87
|
+
obj.GetPdfPageOptions = function () {
|
|
88
|
+
var fallback = { format: 'letter', orientation: 'portrait', margin: 0.5 };
|
|
89
|
+
|
|
90
|
+
var setup = null;
|
|
91
|
+
try {
|
|
92
|
+
if (editor && typeof editor.getDocumentPageSetup === "function") setup = editor.getDocumentPageSetup();
|
|
93
|
+
} catch (e) { setup = null; }
|
|
94
|
+
if (!setup || typeof setup !== "object") return fallback;
|
|
95
|
+
|
|
96
|
+
// jsPDF understands these page-format names.
|
|
97
|
+
var SUPPORTED = { a3: 1, a4: 1, a5: 1, letter: 1, legal: 1, tabloid: 1 };
|
|
98
|
+
var fmt = String(setup.format || "").toLowerCase();
|
|
99
|
+
var orientation = String(setup.orientation || "").toLowerCase() === "landscape" ? "landscape" : fallback.orientation;
|
|
100
|
+
|
|
101
|
+
var result = {
|
|
102
|
+
format: SUPPORTED[fmt] ? fmt : fallback.format,
|
|
103
|
+
orientation: orientation,
|
|
104
|
+
margin: fallback.margin
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Margins are emitted in inches, matching jsPDF's unit: 'in'.
|
|
108
|
+
var m = setup.margins;
|
|
109
|
+
if (m && typeof m === "object") {
|
|
110
|
+
var top = __ToInches(m.top), right = __ToInches(m.right);
|
|
111
|
+
var bottom = __ToInches(m.bottom), left = __ToInches(m.left);
|
|
112
|
+
if (top !== null && right !== null && bottom !== null && left !== null) {
|
|
113
|
+
result.margin = [top, right, bottom, left];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// Accepts a bare number (already inches) or a CSS length string.
|
|
120
|
+
function __ToInches(v) {
|
|
121
|
+
if (typeof v === "number" && isFinite(v)) return v;
|
|
122
|
+
if (typeof v !== "string") return null;
|
|
123
|
+
var m = /^\s*(-?[\d.]+)\s*(mm|cm|in|px|pt)?\s*$/.exec(v);
|
|
124
|
+
if (!m) return null;
|
|
125
|
+
var n = parseFloat(m[1]);
|
|
126
|
+
if (!isFinite(n)) return null;
|
|
127
|
+
switch (m[2]) {
|
|
128
|
+
case "mm": return n / 25.4;
|
|
129
|
+
case "cm": return n / 2.54;
|
|
130
|
+
case "pt": return n / 72;
|
|
131
|
+
case "px": return n / 96;
|
|
132
|
+
default: return n; // bare number or explicit "in"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
39
136
|
function __Append(parent, tagname, csstext, cssclass) {
|
|
40
137
|
var tag = parent.ownerDocument.createElement(tagname);
|
|
41
138
|
if (csstext) tag.style.cssText = csstext;
|
|
@@ -76,12 +173,19 @@ function RTE_Plugin_Html2PDF() {
|
|
|
76
173
|
|
|
77
174
|
div2.innerHTML = "Exporting...";
|
|
78
175
|
|
|
176
|
+
// Honor the document's own page setup (paper size, orientation and
|
|
177
|
+
// margins) so the exported PDF matches the paginated page view and the
|
|
178
|
+
// Word export instead of always emitting US Letter. Falls back to the
|
|
179
|
+
// previous fixed letter/portrait/0.5in defaults when the document
|
|
180
|
+
// carries no page setup, so existing integrations are unaffected.
|
|
181
|
+
var page = obj.GetPdfPageOptions();
|
|
182
|
+
|
|
79
183
|
var opt = {
|
|
80
|
-
margin:
|
|
184
|
+
margin: page.margin,
|
|
81
185
|
filename: 'myfile.pdf',
|
|
82
186
|
image: { type: 'jpeg', quality: 0.98 },
|
|
83
187
|
html2canvas: { scale: 2 },
|
|
84
|
-
jsPDF: { unit: 'in', format:
|
|
188
|
+
jsPDF: { unit: 'in', format: page.format, orientation: page.orientation }
|
|
85
189
|
};
|
|
86
190
|
|
|
87
191
|
var promimg = win.html2pdf().set(opt).from(win.document.body).outputImg();
|
|
@@ -145,7 +249,7 @@ function RTE_Plugin_Html2PDF() {
|
|
|
145
249
|
iframe = __Append(div1, "iframe", "align-self:center;flex:99;width:100%;height:0px;border:0px;", "rte-editable");
|
|
146
250
|
iframe.contentDocument.open("text/html");
|
|
147
251
|
iframe.contentDocument.write("<html><head><link id='url-css-preview' rel='stylesheet' href='" + editor.htmlEncode(config.previewCssUrl) + "'/>"
|
|
148
|
-
+ "<script src='" + editor.htmlEncode(
|
|
252
|
+
+ "<script src='" + editor.htmlEncode(resolveScriptUrl()) + "'></script></head><body style='padding:10px;margin:0px'>"
|
|
149
253
|
+ editor.getHTMLCode() + "</body>"
|
|
150
254
|
+ "<script>window.onload=function(){setTimeout(function(){parent.html2pdf_callback(window)},100)}</script></html>")
|
|
151
255
|
iframe.contentDocument.close();
|
|
@@ -70,14 +70,40 @@ function RTE_Plugin_ImageEditor() {
|
|
|
70
70
|
var scriptbase = config.url_base + "/plugins/tui.image-editor/";
|
|
71
71
|
|
|
72
72
|
window.rte_image_editor_callback = function (win) {
|
|
73
|
+
// 2026-07-31 No outbound calls from the image editor, at any layer.
|
|
74
|
+
//
|
|
75
|
+
// Upstream Toast UI ships a "usage statistics" beacon (in
|
|
76
|
+
// tui-code-snippet and tui-color-picker) that reports the host's own
|
|
77
|
+
// hostname to a third-party analytics endpoint, and its default theme
|
|
78
|
+
// loads a branding logo from the vendor's CDN. Both endpoint strings
|
|
79
|
+
// have been removed from the vendored copies in
|
|
80
|
+
// plugins/tui.image-editor/ -- deliberately from the FILES, not just
|
|
81
|
+
// disabled at runtime, because static scanners (Fortify CWE-297) flag
|
|
82
|
+
// the literal URL and a runtime flag does not satisfy them.
|
|
83
|
+
//
|
|
84
|
+
// Do NOT write those hostnames into this file either: it is
|
|
85
|
+
// concatenated into all_plugins.js, which is what customers scan.
|
|
86
|
+
//
|
|
87
|
+
// The settings below are the belt to that braces -- they switch the
|
|
88
|
+
// beacon off through the library's own supported option, so a future
|
|
89
|
+
// vendor upgrade that reintroduces the endpoint still does not phone
|
|
90
|
+
// home until someone re-applies the patch.
|
|
91
|
+
try { win.tui = win.tui || {}; win.tui.usageStatistics = false; } catch (e) {}
|
|
92
|
+
|
|
73
93
|
var options = {
|
|
94
|
+
usageStatistics: false,
|
|
74
95
|
includeUI: {
|
|
75
96
|
loadImage: {
|
|
76
97
|
path: img.src,
|
|
77
98
|
name: 'RteImage'
|
|
78
99
|
},
|
|
100
|
+
usageStatistics: false,
|
|
79
101
|
//locale: locale_ru_RU,
|
|
80
102
|
theme: {
|
|
103
|
+
// Blank rather than Toast's CDN-hosted logo.
|
|
104
|
+
'common.bi.image': '',
|
|
105
|
+
'common.bisize.width': '0',
|
|
106
|
+
'common.bisize.height': '0',
|
|
81
107
|
// main icons
|
|
82
108
|
'menu.normalIcon.path': scriptbase + 'svg/icon-d.svg',
|
|
83
109
|
'menu.activeIcon.path': scriptbase + 'svg/icon-b.svg',
|
|
@@ -106,7 +132,13 @@ function RTE_Plugin_ImageEditor() {
|
|
|
106
132
|
btns.innerHTML = '';
|
|
107
133
|
var savebtn = __Append(btns, "button", "");
|
|
108
134
|
savebtn.innerText = "Save";
|
|
135
|
+
var status = __Append(btns, "div", "margin-left:10px;font-size:12px;color:#b42318;", "rte-imageeditor-upload-status");
|
|
136
|
+
status.setAttribute("role", "status");
|
|
137
|
+
status.setAttribute("aria-live", "polite");
|
|
109
138
|
savebtn.onclick = function () {
|
|
139
|
+
status.innerText = "";
|
|
140
|
+
savebtn.disabled = true;
|
|
141
|
+
savebtn.innerText = "Saving...";
|
|
110
142
|
|
|
111
143
|
var dataurl = imgeditor.toDataURL();
|
|
112
144
|
if (!config.file_upload_handler) {
|
|
@@ -125,13 +157,11 @@ function RTE_Plugin_ImageEditor() {
|
|
|
125
157
|
dialoginner.close();
|
|
126
158
|
return;
|
|
127
159
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
alert("Developer warning : ");
|
|
134
|
-
}
|
|
160
|
+
savebtn.disabled = false;
|
|
161
|
+
savebtn.innerText = "Save";
|
|
162
|
+
status.innerText = error
|
|
163
|
+
? "Upload failed. Check your connection and try again."
|
|
164
|
+
: "The upload did not return a file URL. Please try again.";
|
|
135
165
|
});
|
|
136
166
|
|
|
137
167
|
|