@richscripts/richtexteditor 2.4.1 → 2.4.2
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/package.json +4 -2
- package/richtexteditor/all_plugins.js +24 -0
- package/richtexteditor/all_plugins.min.js +1 -1
- package/richtexteditor/plugins/all_plugins.js +24 -0
- package/richtexteditor/plugins/all_plugins.min.js +1 -1
- package/richtexteditor/plugins/crdt-engine.js +2201 -198
- package/richtexteditor/plugins/crdt-engine.min.js +5 -5
- package/richtexteditor/plugins/sanitizer.js +24 -0
- package/richtexteditor/rte_theme_default.css +22 -1
|
@@ -141,6 +141,17 @@ function RTE_Plugin_Sanitizer() {
|
|
|
141
141
|
var v = String(value == null ? "" : value).replace(/[\u0000-\u0020\u007F-\u00A0]+/g, "").trim();
|
|
142
142
|
if (!v) return false;
|
|
143
143
|
|
|
144
|
+
// <use> resolves its reference by FETCHING it. The only legitimate form
|
|
145
|
+
// in editor content is a same-document fragment (#icon-id) pointing at a
|
|
146
|
+
// <symbol>/<defs> in the same markup — nobody authoring a document means
|
|
147
|
+
// to reference a remote SVG. Left unrestricted it is a beacon that fires
|
|
148
|
+
// in every reader's browser for content one author saved, which is the
|
|
149
|
+
// same class of problem as an embedded remote logo or analytics pixel
|
|
150
|
+
// (see the no-external-calls hardening). Browsers additionally refuse
|
|
151
|
+
// cross-origin <use>, but relying on that is relying on someone else's
|
|
152
|
+
// policy to enforce ours.
|
|
153
|
+
if (tag === "use") return v.charAt(0) === "#";
|
|
154
|
+
|
|
144
155
|
// Fragments, absolute paths and query-only URLs carry no scheme.
|
|
145
156
|
if (/^[#?/]/.test(v)) return true;
|
|
146
157
|
|
|
@@ -243,6 +254,19 @@ function RTE_Plugin_Sanitizer() {
|
|
|
243
254
|
// This is the construct that actually executed downstream.
|
|
244
255
|
if (el.hasAttribute("srcdoc")) { note(report.removedAttributes, "iframe[srcdoc]"); el.removeAttribute("srcdoc"); }
|
|
245
256
|
if (!iframeAllowed(el)) { note(report.removedTags, "iframe"); el.parentNode.removeChild(el); continue; }
|
|
257
|
+
} else if (tag === "title" || tag === "desc") {
|
|
258
|
+
// Legal inside <svg> (they supply its accessible name), which is
|
|
259
|
+
// why they are in ALLOWED_TAGS. But the allowance was
|
|
260
|
+
// unqualified, so a document-level <title> from a pasted or
|
|
261
|
+
// set full HTML document survived into SAVED content while
|
|
262
|
+
// <style>/<meta>/<link> beside it were stripped. Head-level
|
|
263
|
+
// markup has no business in body content; keep these only where
|
|
264
|
+
// they are actually valid.
|
|
265
|
+
if (!el.closest || !el.closest("svg")) {
|
|
266
|
+
note(report.removedTags, tag);
|
|
267
|
+
el.parentNode.removeChild(el);
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
246
270
|
} else if (DROP_WHOLE[tag]) {
|
|
247
271
|
note(report.removedTags, tag);
|
|
248
272
|
el.parentNode.removeChild(el);
|
|
@@ -283,7 +283,13 @@ rte-codebox {
|
|
|
283
283
|
previously hardcoded #d5d5d5 stayed light-gray on the dark surface. */
|
|
284
284
|
border: 1px solid var(--rte-border, #d5d5d5);
|
|
285
285
|
border-radius: 10px;
|
|
286
|
-
overflow:
|
|
286
|
+
/* Deliberately NOT overflow:hidden. Toolbar dropdown panels
|
|
287
|
+
(rte-dropdown-panel) are absolutely positioned children of this element,
|
|
288
|
+
so clipping here cut off any panel anchored near the right edge: Line
|
|
289
|
+
Height rendered only the "1" of "100%", Paragraphs and Document Outline
|
|
290
|
+
lost 91px. Corner rounding does not depend on this clip - the toolbar and
|
|
291
|
+
status bar round their own corners (see the rule below). */
|
|
292
|
+
overflow: visible;
|
|
287
293
|
background-clip: padding-box;
|
|
288
294
|
}
|
|
289
295
|
|
|
@@ -1986,6 +1992,21 @@ rte-menuspliter {
|
|
|
1986
1992
|
margin: 3px 0px 3px 28px;
|
|
1987
1993
|
}
|
|
1988
1994
|
|
|
1995
|
+
/* The panel is shrink-to-fit, so its width is decided by its widest preview —
|
|
1996
|
+
"Headline 1" at 32px — and measured 187px of text inside 187px of space:
|
|
1997
|
+
ZERO tolerance. Whenever the font used at layout time is a hair narrower than
|
|
1998
|
+
the one finally painted (a fallback still in place during a webfont swap, a
|
|
1999
|
+
different platform's metrics), the label overflows and the last character is
|
|
2000
|
+
cut off. Reported from the wild with "Headline 1" clipped.
|
|
2001
|
+
|
|
2002
|
+
A min-width gives the panel slack that does not depend on font metrics
|
|
2003
|
+
matching to the pixel; the previews are nowrap, so slack is the only thing
|
|
2004
|
+
that can absorb the variance. */
|
|
2005
|
+
.rte-dropdown-panel.rte_command_paragraphs,
|
|
2006
|
+
rte-dropdown-panel.rte_command_paragraphs {
|
|
2007
|
+
min-width: 292px;
|
|
2008
|
+
}
|
|
2009
|
+
|
|
1989
2010
|
.rte_command_paragraphs rte-toolbar-dropdown-item div {
|
|
1990
2011
|
font-size: 15px;
|
|
1991
2012
|
margin: 0px;
|