@mulmoclaude/core 4.4.2 → 4.5.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/assets/helps/bug-report-faq.md +13 -0
- package/assets/helps/business.md +4 -0
- package/assets/helps/error-recovery.md +71 -0
- package/assets/helps/gemini.md +1 -1
- package/assets/helps/mulmoscript.md +71 -1
- package/assets/helps/presentation-deck.md +4 -1
- package/assets/helps/storyteller.md +7 -0
- package/dist/collection/core/accentColor.d.ts +23 -0
- package/dist/collection/core/iconGlyph.d.ts +26 -0
- package/dist/collection/core/schema.d.ts +9 -0
- package/dist/collection/core/schemaZ.d.ts +18 -0
- package/dist/collection/core/shortcutInfo.d.ts +14 -0
- package/dist/collection/core/uiTypes.d.ts +6 -0
- package/dist/collection/index.cjs +22 -2
- package/dist/collection/index.cjs.map +1 -1
- package/dist/collection/index.d.ts +3 -0
- package/dist/collection/index.js +17 -3
- package/dist/collection/index.js.map +1 -1
- package/dist/collection/registry/server/index.cjs +3 -3
- package/dist/collection/registry/server/index.js +3 -3
- package/dist/collection/server/index.cjs +5 -4
- package/dist/collection/server/index.js +5 -5
- package/dist/collection/server/paths.d.ts +10 -0
- package/dist/collection-watchers/index.cjs +5 -5
- package/dist/collection-watchers/index.js +5 -5
- package/dist/{discovery-Dl9nRa-m.cjs → discovery-2TvulIz8.cjs} +25 -5
- package/dist/discovery-2TvulIz8.cjs.map +1 -0
- package/dist/{discovery-P64fgtuD.js → discovery-BY-nMCuh.js} +20 -6
- package/dist/discovery-BY-nMCuh.js.map +1 -0
- package/dist/feeds/index.cjs +2 -2
- package/dist/feeds/index.js +2 -2
- package/dist/feeds/server/index.cjs +5 -5
- package/dist/feeds/server/index.js +5 -5
- package/dist/files/atomic.d.ts +4 -0
- package/dist/files/index.cjs +1 -1
- package/dist/files/index.js +1 -1
- package/dist/google/index.cjs +3 -3
- package/dist/google/index.js +3 -3
- package/dist/iconGlyph-D8JeNg7R.js +59 -0
- package/dist/iconGlyph-D8JeNg7R.js.map +1 -0
- package/dist/iconGlyph-fSBp6k4J.cjs +70 -0
- package/dist/iconGlyph-fSBp6k4J.cjs.map +1 -0
- package/dist/{ingestTypes-CaX7_s-K.cjs → ingestTypes-DsVH9BYy.cjs} +2 -2
- package/dist/{ingestTypes-CaX7_s-K.cjs.map → ingestTypes-DsVH9BYy.cjs.map} +1 -1
- package/dist/{ingestTypes-CIy1lHjf.js → ingestTypes-GkG7bJdB.js} +2 -2
- package/dist/{ingestTypes-CIy1lHjf.js.map → ingestTypes-GkG7bJdB.js.map} +1 -1
- package/dist/{itemId-BY2YPBkT.js → itemId-4P9S_ehz.js} +48 -2
- package/dist/itemId-4P9S_ehz.js.map +1 -0
- package/dist/{itemId-CEQdK01z.cjs → itemId-CGT2J7YK.cjs} +65 -1
- package/dist/itemId-CGT2J7YK.cjs.map +1 -0
- package/dist/plugin-vue/IconGlyph.d.ts +27 -0
- package/dist/plugin-vue/index.cjs +117 -201
- package/dist/plugin-vue/index.cjs.map +1 -1
- package/dist/plugin-vue/index.d.ts +1 -0
- package/dist/plugin-vue/index.js +118 -203
- package/dist/plugin-vue/index.js.map +1 -1
- package/dist/{promptSafety-Bp780ezk.js → promptSafety-Bte62OvU.js} +2 -2
- package/dist/{promptSafety-Bp780ezk.js.map → promptSafety-Bte62OvU.js.map} +1 -1
- package/dist/{promptSafety-C0BWDsfT.cjs → promptSafety-Cv-SoTd4.cjs} +2 -2
- package/dist/{promptSafety-C0BWDsfT.cjs.map → promptSafety-Cv-SoTd4.cjs.map} +1 -1
- package/dist/{root-BMroU_mB.js → root-BcS4-Kge.js} +12 -2
- package/dist/root-BcS4-Kge.js.map +1 -0
- package/dist/{root-rPH6FGDT.cjs → root-BvwBUcol.cjs} +12 -2
- package/dist/root-BvwBUcol.cjs.map +1 -0
- package/dist/{server-BvXO49Vj.js → server-BENtFplH.js} +47 -18
- package/dist/{server-BvXO49Vj.js.map → server-BENtFplH.js.map} +1 -1
- package/dist/{server-CF1qllGV.cjs → server-Wz4_ALLl.cjs} +47 -18
- package/dist/{server-CF1qllGV.cjs.map → server-Wz4_ALLl.cjs.map} +1 -1
- package/package.json +8 -8
- package/dist/discovery-Dl9nRa-m.cjs.map +0 -1
- package/dist/discovery-P64fgtuD.js.map +0 -1
- package/dist/itemId-BY2YPBkT.js.map +0 -1
- package/dist/itemId-CEQdK01z.cjs.map +0 -1
- package/dist/root-BMroU_mB.js.map +0 -1
- package/dist/root-rPH6FGDT.cjs.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_iconGlyph = require("../iconGlyph-fSBp6k4J.cjs");
|
|
2
3
|
let _mulmoclaude_markdown_utils_markdown_frontmatter = require("@mulmoclaude/markdown-utils/markdown/frontmatter");
|
|
3
4
|
let vue = require("vue");
|
|
4
5
|
let gui_chat_protocol_vue = require("gui-chat-protocol/vue");
|
|
@@ -87,8 +88,57 @@ function useClipboardCopy(resetMs = DEFAULT_RESET_MS) {
|
|
|
87
88
|
};
|
|
88
89
|
}
|
|
89
90
|
//#endregion
|
|
91
|
+
//#region src/plugin-vue/IconGlyph.ts
|
|
92
|
+
var DEFAULT_SIZE_CLASS = "text-base";
|
|
93
|
+
var DEFAULT_FONT_CLASS = "material-symbols-outlined";
|
|
94
|
+
var SYMBOL_CONTAINMENT = {
|
|
95
|
+
display: "inline-block",
|
|
96
|
+
width: "1em",
|
|
97
|
+
overflow: "hidden"
|
|
98
|
+
};
|
|
99
|
+
var GLYPH_CONTAINMENT = {
|
|
100
|
+
display: "inline-block",
|
|
101
|
+
maxWidth: "1.25em",
|
|
102
|
+
overflow: "hidden",
|
|
103
|
+
lineHeight: "1"
|
|
104
|
+
};
|
|
105
|
+
/** Both branches carry the same semantics, and the icon-font one needs them
|
|
106
|
+
* MORE: its text content is the ligature NAME, so an unlabelled span makes a
|
|
107
|
+
* screen reader announce "podcasts" / "rss_feed" as content. 48 icon spans
|
|
108
|
+
* across this repo already mark themselves `aria-hidden`; these are the same
|
|
109
|
+
* kind of span. */
|
|
110
|
+
function labellingFor(ariaLabel) {
|
|
111
|
+
return ariaLabel ? {
|
|
112
|
+
role: "img",
|
|
113
|
+
"aria-label": ariaLabel
|
|
114
|
+
} : { "aria-hidden": "true" };
|
|
115
|
+
}
|
|
116
|
+
var IconGlyph = (props) => {
|
|
117
|
+
const sizeClass = props.sizeClass ?? DEFAULT_SIZE_CLASS;
|
|
118
|
+
const glyph = require_iconGlyph.resolveIconGlyph(props.icon, props.fallback ?? "dataset");
|
|
119
|
+
const labelling = labellingFor(props.ariaLabel);
|
|
120
|
+
if (glyph.kind === "symbol") return (0, vue.h)("span", {
|
|
121
|
+
class: [props.fontClass ?? DEFAULT_FONT_CLASS, sizeClass],
|
|
122
|
+
style: SYMBOL_CONTAINMENT,
|
|
123
|
+
...labelling
|
|
124
|
+
}, glyph.name);
|
|
125
|
+
return (0, vue.h)("span", {
|
|
126
|
+
class: sizeClass,
|
|
127
|
+
style: GLYPH_CONTAINMENT,
|
|
128
|
+
...labelling
|
|
129
|
+
}, glyph.text);
|
|
130
|
+
};
|
|
131
|
+
IconGlyph.displayName = "IconGlyph";
|
|
132
|
+
IconGlyph.props = {
|
|
133
|
+
icon: String,
|
|
134
|
+
fallback: String,
|
|
135
|
+
sizeClass: String,
|
|
136
|
+
ariaLabel: String,
|
|
137
|
+
fontClass: String
|
|
138
|
+
};
|
|
139
|
+
//#endregion
|
|
90
140
|
//#region ../../node_modules/dompurify/dist/purify.es.mjs
|
|
91
|
-
/*! @license DOMPurify 3.4.
|
|
141
|
+
/*! @license DOMPurify 3.4.13 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.13/LICENSE */
|
|
92
142
|
function _arrayLikeToArray(r, a) {
|
|
93
143
|
(null == a || a > r.length) && (a = r.length);
|
|
94
144
|
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
@@ -817,7 +867,6 @@ var svg = freeze([
|
|
|
817
867
|
"patterncontentunits",
|
|
818
868
|
"patterntransform",
|
|
819
869
|
"patternunits",
|
|
820
|
-
"pointer-events",
|
|
821
870
|
"points",
|
|
822
871
|
"preservealpha",
|
|
823
872
|
"preserveaspectratio",
|
|
@@ -872,7 +921,6 @@ var svg = freeze([
|
|
|
872
921
|
"u2",
|
|
873
922
|
"unicode",
|
|
874
923
|
"values",
|
|
875
|
-
"vector-effect",
|
|
876
924
|
"viewbox",
|
|
877
925
|
"visibility",
|
|
878
926
|
"version",
|
|
@@ -986,24 +1034,6 @@ var NODE_TYPE = {
|
|
|
986
1034
|
documentFragment: 11,
|
|
987
1035
|
notation: 12
|
|
988
1036
|
};
|
|
989
|
-
var LITERAL_TEXT_ELEMENT_NAMES = [
|
|
990
|
-
"style",
|
|
991
|
-
"script",
|
|
992
|
-
"xmp",
|
|
993
|
-
"iframe",
|
|
994
|
-
"noembed",
|
|
995
|
-
"noframes",
|
|
996
|
-
"plaintext",
|
|
997
|
-
"noscript"
|
|
998
|
-
];
|
|
999
|
-
var LITERAL_TEXT_ELEMENTS = freeze(addToSet({}, LITERAL_TEXT_ELEMENT_NAMES));
|
|
1000
|
-
var LITERAL_TEXT_CLOSE = function() {
|
|
1001
|
-
const map = {};
|
|
1002
|
-
arrayForEach(LITERAL_TEXT_ELEMENT_NAMES, (name) => {
|
|
1003
|
-
map[name] = seal(new RegExp("</" + name + "(?=[\\t\\n\\f\\r />])", "i"));
|
|
1004
|
-
});
|
|
1005
|
-
return freeze(map);
|
|
1006
|
-
}();
|
|
1007
1037
|
var getGlobal = function getGlobal() {
|
|
1008
1038
|
return typeof window === "undefined" ? null : window;
|
|
1009
1039
|
};
|
|
@@ -1063,25 +1093,10 @@ var _createHooksMap = function _createHooksMap() {
|
|
|
1063
1093
|
var _resolveSetOption = function _resolveSetOption(cfg, key, fallback, options) {
|
|
1064
1094
|
return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
|
|
1065
1095
|
};
|
|
1066
|
-
/**
|
|
1067
|
-
* Resolve an object-valued configuration option: a prototype-free clone
|
|
1068
|
-
* of cfg[key] when it is an own, truthy object property, else a fresh
|
|
1069
|
-
* fallback built by makeFallback (fresh on every parse, so a previous
|
|
1070
|
-
* parse can never leak state into the next one).
|
|
1071
|
-
*
|
|
1072
|
-
* @param cfg the cloned, prototype-free configuration object
|
|
1073
|
-
* @param key the configuration property to read
|
|
1074
|
-
* @param makeFallback builds the fallback value when the option is absent
|
|
1075
|
-
* @returns the resolved object
|
|
1076
|
-
*/
|
|
1077
|
-
var _resolveObjectOption = function _resolveObjectOption(cfg, key, makeFallback) {
|
|
1078
|
-
const value = objectHasOwnProperty(cfg, key) ? cfg[key] : void 0;
|
|
1079
|
-
return value && typeof value === "object" ? clone(value) : makeFallback();
|
|
1080
|
-
};
|
|
1081
1096
|
function createDOMPurify() {
|
|
1082
1097
|
let window = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
|
|
1083
1098
|
const DOMPurify = (root) => createDOMPurify(root);
|
|
1084
|
-
DOMPurify.version = "3.4.
|
|
1099
|
+
DOMPurify.version = "3.4.13";
|
|
1085
1100
|
DOMPurify.removed = [];
|
|
1086
1101
|
if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
|
|
1087
1102
|
DOMPurify.isSupported = false;
|
|
@@ -1106,12 +1121,6 @@ function createDOMPurify() {
|
|
|
1106
1121
|
const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeType") : null;
|
|
1107
1122
|
const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeName") : null;
|
|
1108
1123
|
const getOwnerDocument = Node && Node.prototype ? lookupGetter(Node.prototype, "ownerDocument") : null;
|
|
1109
|
-
const _readNodeType = function _readNodeType(node) {
|
|
1110
|
-
return getNodeType ? getNodeType(node) : node.nodeType;
|
|
1111
|
-
};
|
|
1112
|
-
const _readNodeName = function _readNodeName(node) {
|
|
1113
|
-
return getNodeName ? getNodeName(node) : node.nodeName;
|
|
1114
|
-
};
|
|
1115
1124
|
if (typeof HTMLTemplateElement === "function") {
|
|
1116
1125
|
const template = document.createElement("template");
|
|
1117
1126
|
if (template.content && template.content.ownerDocument) document = template.content.ownerDocument;
|
|
@@ -1369,9 +1378,9 @@ function createDOMPurify() {
|
|
|
1369
1378
|
IN_PLACE = cfg.IN_PLACE || false;
|
|
1370
1379
|
IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
|
|
1371
1380
|
NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
|
|
1372
|
-
MATHML_TEXT_INTEGRATION_POINTS =
|
|
1373
|
-
HTML_INTEGRATION_POINTS =
|
|
1374
|
-
const customElementHandling =
|
|
1381
|
+
MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
|
|
1382
|
+
HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
|
|
1383
|
+
const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
|
|
1375
1384
|
CUSTOM_ELEMENT_HANDLING = create(null);
|
|
1376
1385
|
if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck;
|
|
1377
1386
|
if (objectHasOwnProperty(customElementHandling, "attributeNameCheck") && isRegexOrFunction(customElementHandling.attributeNameCheck)) CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck;
|
|
@@ -1418,6 +1427,11 @@ function createDOMPurify() {
|
|
|
1418
1427
|
addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
|
|
1419
1428
|
}
|
|
1420
1429
|
}
|
|
1430
|
+
if (objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
|
|
1431
|
+
if (objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS)) {
|
|
1432
|
+
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
1433
|
+
addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
|
|
1434
|
+
}
|
|
1421
1435
|
if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
|
|
1422
1436
|
if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS);
|
|
1423
1437
|
addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
|
|
@@ -1534,32 +1548,6 @@ function createDOMPurify() {
|
|
|
1534
1548
|
}
|
|
1535
1549
|
};
|
|
1536
1550
|
/**
|
|
1537
|
-
* _stripAttributeNode
|
|
1538
|
-
*
|
|
1539
|
-
* Remove a single Attr node case/namespace-exactly on an attribute-teardown
|
|
1540
|
-
* path. Name-based removeAttribute() ASCII-lowercases its lookup key for an
|
|
1541
|
-
* HTML element in an HTML document and so silently misses a case-preserved
|
|
1542
|
-
* handler (e.g. `ONERROR` off an XML/XHTML import) - the same defect
|
|
1543
|
-
* _removeAttribute() was fixed for, which a name-based call would reintroduce
|
|
1544
|
-
* on these IN_PLACE teardown paths. Unlike _removeAttribute this does not
|
|
1545
|
-
* record into DOMPurify.removed: the neutralize passes intentionally do not
|
|
1546
|
-
* book-keep. A clobbered/detached node falls back to best-effort name-based
|
|
1547
|
-
* removal.
|
|
1548
|
-
*
|
|
1549
|
-
* @param element the element to strip the attribute from
|
|
1550
|
-
* @param attribute the Attr node to remove
|
|
1551
|
-
* @param name the attribute's name, for the fallback path
|
|
1552
|
-
*/
|
|
1553
|
-
const _stripAttributeNode = function _stripAttributeNode(element, attribute, name) {
|
|
1554
|
-
try {
|
|
1555
|
-
element.removeAttributeNode(attribute);
|
|
1556
|
-
} catch (_) {
|
|
1557
|
-
try {
|
|
1558
|
-
element.removeAttribute(name);
|
|
1559
|
-
} catch (_) {}
|
|
1560
|
-
}
|
|
1561
|
-
};
|
|
1562
|
-
/**
|
|
1563
1551
|
* _neutralizeRoot
|
|
1564
1552
|
*
|
|
1565
1553
|
* Fail-closed teardown of an in-place root after the sanitize walk aborts
|
|
@@ -1593,45 +1581,30 @@ function createDOMPurify() {
|
|
|
1593
1581
|
if (attributes) for (let i = attributes.length - 1; i >= 0; --i) {
|
|
1594
1582
|
const attribute = attributes[i];
|
|
1595
1583
|
const name = attribute && attribute.name;
|
|
1596
|
-
if (typeof name === "string")
|
|
1584
|
+
if (typeof name === "string") try {
|
|
1585
|
+
root.removeAttribute(name);
|
|
1586
|
+
} catch (_) {}
|
|
1597
1587
|
}
|
|
1598
1588
|
};
|
|
1599
1589
|
/**
|
|
1600
1590
|
* _removeAttribute
|
|
1601
1591
|
*
|
|
1602
|
-
* Name-based getAttributeNode()/removeAttribute() ASCII-lowercase their
|
|
1603
|
-
* lookup key for HTML elements in an HTML document, so they silently miss an
|
|
1604
|
-
* attribute whose stored qualified name still contains uppercase ASCII
|
|
1605
|
-
* letters. That happens when the node came from a case-preserving source
|
|
1606
|
-
* (an XML/XHTML document imported via importNode(), or createAttributeNS()),
|
|
1607
|
-
* where e.g. `ONERROR` survives the walk: the policy check lowercases to
|
|
1608
|
-
* `onerror` and rejects it, but `removeAttribute('ONERROR')` looks up
|
|
1609
|
-
* `onerror` and finds nothing. Remove the exact Attr node instead, which is
|
|
1610
|
-
* case- and namespace-exact, and fall back to name-based removal only when
|
|
1611
|
-
* the caller could not supply the node.
|
|
1612
|
-
*
|
|
1613
1592
|
* @param name an Attribute name
|
|
1614
1593
|
* @param element a DOM node
|
|
1615
|
-
* @param attr the exact Attr node to remove, when the caller has it
|
|
1616
1594
|
*/
|
|
1617
|
-
const _removeAttribute = function _removeAttribute(name, element
|
|
1618
|
-
if (!attr) try {
|
|
1619
|
-
attr = element.getAttributeNode(name);
|
|
1620
|
-
} catch (_) {
|
|
1621
|
-
attr = null;
|
|
1622
|
-
}
|
|
1623
|
-
arrayPush(DOMPurify.removed, {
|
|
1624
|
-
attribute: attr || null,
|
|
1625
|
-
from: element
|
|
1626
|
-
});
|
|
1595
|
+
const _removeAttribute = function _removeAttribute(name, element) {
|
|
1627
1596
|
try {
|
|
1628
|
-
|
|
1629
|
-
|
|
1597
|
+
arrayPush(DOMPurify.removed, {
|
|
1598
|
+
attribute: element.getAttributeNode(name),
|
|
1599
|
+
from: element
|
|
1600
|
+
});
|
|
1630
1601
|
} catch (_) {
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1602
|
+
arrayPush(DOMPurify.removed, {
|
|
1603
|
+
attribute: null,
|
|
1604
|
+
from: element
|
|
1605
|
+
});
|
|
1634
1606
|
}
|
|
1607
|
+
element.removeAttribute(name);
|
|
1635
1608
|
if (name === "is") if (RETURN_DOM || RETURN_DOM_FRAGMENT) try {
|
|
1636
1609
|
_forceRemove(element);
|
|
1637
1610
|
} catch (_) {}
|
|
@@ -1656,7 +1629,9 @@ function createDOMPurify() {
|
|
|
1656
1629
|
const attribute = attributes[i];
|
|
1657
1630
|
const name = attribute && attribute.name;
|
|
1658
1631
|
if (typeof name !== "string" || ALLOWED_ATTR[transformCaseFunc(name)]) continue;
|
|
1659
|
-
|
|
1632
|
+
try {
|
|
1633
|
+
element.removeAttribute(name);
|
|
1634
|
+
} catch (_) {}
|
|
1660
1635
|
}
|
|
1661
1636
|
};
|
|
1662
1637
|
/**
|
|
@@ -1685,7 +1660,7 @@ function createDOMPurify() {
|
|
|
1685
1660
|
const stack = [root];
|
|
1686
1661
|
while (stack.length > 0) {
|
|
1687
1662
|
const node = stack.pop();
|
|
1688
|
-
if (
|
|
1663
|
+
if ((getNodeType ? getNodeType(node) : node.nodeType) === NODE_TYPE.element) _stripDisallowedAttributes(node);
|
|
1689
1664
|
const childNodes = getChildNodes(node);
|
|
1690
1665
|
if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push(childNodes[i]);
|
|
1691
1666
|
}
|
|
@@ -1725,28 +1700,12 @@ function createDOMPurify() {
|
|
|
1725
1700
|
*
|
|
1726
1701
|
* @param root the in-place root to sweep
|
|
1727
1702
|
*/
|
|
1728
|
-
/**
|
|
1729
|
-
* Central policy for declarative-partial-updates patch-linkage attributes,
|
|
1730
|
-
* shared by the _neutralizePatchLinkage pre-pass and _isValidAttribute so
|
|
1731
|
-
* the two sites cannot drift: `patchsrc` always links, `for` links
|
|
1732
|
-
* everywhere except on <label>/<output>, and the whole policy is gated on
|
|
1733
|
-
* SAFE_FOR_XML (see the rationale block in _isValidAttribute).
|
|
1734
|
-
*
|
|
1735
|
-
* @param lcName the transformCaseFunc'd attribute name
|
|
1736
|
-
* @param lcTag the transformCaseFunc'd tag name of the carrying element
|
|
1737
|
-
* @return true if the attribute is patch linkage and must be dropped
|
|
1738
|
-
*/
|
|
1739
|
-
const _isPatchLinkageAttribute = function _isPatchLinkageAttribute(lcName, lcTag) {
|
|
1740
|
-
if (!SAFE_FOR_XML) return false;
|
|
1741
|
-
if (lcName === "patchsrc") return true;
|
|
1742
|
-
return lcName === "for" && lcTag !== "label" && lcTag !== "output";
|
|
1743
|
-
};
|
|
1744
1703
|
const _neutralizePatchLinkage = function _neutralizePatchLinkage(root) {
|
|
1745
1704
|
if (!SAFE_FOR_XML) return;
|
|
1746
1705
|
const stack = [root];
|
|
1747
1706
|
while (stack.length > 0) {
|
|
1748
1707
|
const node = stack.pop();
|
|
1749
|
-
const nodeType =
|
|
1708
|
+
const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
|
|
1750
1709
|
if (nodeType === NODE_TYPE.processingInstruction || nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, node.data)) {
|
|
1751
1710
|
try {
|
|
1752
1711
|
remove(node);
|
|
@@ -1755,10 +1714,10 @@ function createDOMPurify() {
|
|
|
1755
1714
|
}
|
|
1756
1715
|
if (nodeType === NODE_TYPE.element) {
|
|
1757
1716
|
const element = node;
|
|
1758
|
-
const lcTag = transformCaseFunc(
|
|
1717
|
+
const lcTag = transformCaseFunc(getNodeName ? getNodeName(node) : node.nodeName);
|
|
1759
1718
|
try {
|
|
1760
1719
|
if (element.hasAttribute && element.hasAttribute("patchsrc")) element.removeAttribute("patchsrc");
|
|
1761
|
-
if (element.hasAttribute && element.hasAttribute("for") &&
|
|
1720
|
+
if (element.hasAttribute && element.hasAttribute("for") && lcTag !== "label" && lcTag !== "output") element.removeAttribute("for");
|
|
1762
1721
|
} catch (_) {}
|
|
1763
1722
|
}
|
|
1764
1723
|
const childNodes = getChildNodes(node);
|
|
@@ -1927,32 +1886,12 @@ function createDOMPurify() {
|
|
|
1927
1886
|
*/
|
|
1928
1887
|
const _isUnsafeNode = function _isUnsafeNode(currentNode, tagName) {
|
|
1929
1888
|
if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) return true;
|
|
1930
|
-
if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE &&
|
|
1889
|
+
if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) return true;
|
|
1931
1890
|
if (currentNode.nodeType === NODE_TYPE.processingInstruction) return true;
|
|
1932
1891
|
if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) return true;
|
|
1933
1892
|
return false;
|
|
1934
1893
|
};
|
|
1935
1894
|
/**
|
|
1936
|
-
* Evaluate a CUSTOM_ELEMENT_HANDLING check (a RegExp or a predicate
|
|
1937
|
-
* function, per the validation in _parseConfig) against a name.
|
|
1938
|
-
* Additional arguments are forwarded to predicate functions - the
|
|
1939
|
-
* attributeNameCheck predicate receives the tag name as its second
|
|
1940
|
-
* argument. A null/absent check never matches.
|
|
1941
|
-
*
|
|
1942
|
-
* @param check the configured tagNameCheck / attributeNameCheck value
|
|
1943
|
-
* @param name the name to test
|
|
1944
|
-
* @param args extra arguments forwarded to a predicate function
|
|
1945
|
-
* @return true if the check matches the name
|
|
1946
|
-
*/
|
|
1947
|
-
const _matchesNameCheck = function _matchesNameCheck(check, name) {
|
|
1948
|
-
if (check instanceof RegExp) return regExpTest(check, name);
|
|
1949
|
-
if (check instanceof Function) {
|
|
1950
|
-
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) args[_key - 2] = arguments[_key];
|
|
1951
|
-
return Boolean(check(name, ...args));
|
|
1952
|
-
}
|
|
1953
|
-
return false;
|
|
1954
|
-
};
|
|
1955
|
-
/**
|
|
1956
1895
|
* Handle a node whose tag is forbidden or not allowlisted: keep
|
|
1957
1896
|
* allowed custom elements (false return exits _sanitizeElements
|
|
1958
1897
|
* early - the namespace and fallback-tag removal checks are
|
|
@@ -1970,7 +1909,10 @@ function createDOMPurify() {
|
|
|
1970
1909
|
* @return true if the node was removed, false if kept
|
|
1971
1910
|
*/
|
|
1972
1911
|
const _sanitizeDisallowedNode = function _sanitizeDisallowedNode(currentNode, tagName, root) {
|
|
1973
|
-
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)
|
|
1912
|
+
if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
|
|
1913
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
|
|
1914
|
+
if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;
|
|
1915
|
+
}
|
|
1974
1916
|
if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
|
|
1975
1917
|
const parentNode = getParentNode(currentNode);
|
|
1976
1918
|
const childNodes = getChildNodes(currentNode);
|
|
@@ -2004,42 +1946,6 @@ function createDOMPurify() {
|
|
|
2004
1946
|
return set === defaultSet || set === setConfigSet ? clone(set) : set;
|
|
2005
1947
|
};
|
|
2006
1948
|
/**
|
|
2007
|
-
* Shared guard for a node that a hook has detached from the walk tree,
|
|
2008
|
-
* used after each element-hook site in _sanitizeElements. Detaching is a
|
|
2009
|
-
* long-standing user pattern (issue #469; draw.io-style foreignObject
|
|
2010
|
-
* filtering). Per the cached, unclobberable parentNode getter the node is
|
|
2011
|
-
* genuinely out of the tree, so it can reach neither the serialized
|
|
2012
|
-
* output nor an IN_PLACE live tree; treat it as removed and stop
|
|
2013
|
-
* processing it. Without this guard, the unsafe-node / namespace checks
|
|
2014
|
-
* would call _forceRemove on a parentless node and hit the REPORT-3
|
|
2015
|
-
* fail-closed throw — which exists for nodes DOMPurify wants gone but
|
|
2016
|
-
* *cannot* detach (clobbered / parentless roots), the opposite of a node
|
|
2017
|
-
* that is already safely gone. The walk root is exempt: a detached
|
|
2018
|
-
* IN_PLACE root is legitimate input and must still be fully sanitized,
|
|
2019
|
-
* and a kill-decision on it must keep hitting the REPORT-3 throw.
|
|
2020
|
-
*
|
|
2021
|
-
* Nodes detached by hooks stay the hook's responsibility for placement:
|
|
2022
|
-
* they are not recorded in DOMPurify.removed, so the post-walk IN_PLACE
|
|
2023
|
-
* pass (which iterates DOMPurify.removed) does not reach them. But a
|
|
2024
|
-
* hook-detached subtree can still hold a queued resource-event handler -
|
|
2025
|
-
* e.g. an <img onload> that began loading when the caller built the live
|
|
2026
|
-
* tree - which fires in page scope after sanitize returns even though the
|
|
2027
|
-
* handler never reached the returned tree. That is the audit-5 F1 hazard,
|
|
2028
|
-
* and the documented node.remove() hook pattern walks straight into it.
|
|
2029
|
-
* So on the IN_PLACE path we neutralize the detached subtree inline,
|
|
2030
|
-
* stripping its non-allow-listed attributes before returning, exactly as
|
|
2031
|
-
* the post-walk pass does for _forceRemove'd subtrees.
|
|
2032
|
-
*
|
|
2033
|
-
* @param currentNode the node a hook may have detached
|
|
2034
|
-
* @param root the current walk root
|
|
2035
|
-
* @return true if the node is detached and now handled, false otherwise
|
|
2036
|
-
*/
|
|
2037
|
-
const _handleHookDetachedNode = function _handleHookDetachedNode(currentNode, root) {
|
|
2038
|
-
if (currentNode === root || getParentNode(currentNode) !== null) return false;
|
|
2039
|
-
if (IN_PLACE) _neutralizeSubtree(currentNode);
|
|
2040
|
-
return true;
|
|
2041
|
-
};
|
|
2042
|
-
/**
|
|
2043
1949
|
* _sanitizeElements
|
|
2044
1950
|
*
|
|
2045
1951
|
* @protect nodeName
|
|
@@ -2050,18 +1956,24 @@ function createDOMPurify() {
|
|
|
2050
1956
|
*/
|
|
2051
1957
|
const _sanitizeElements = function _sanitizeElements(currentNode, root) {
|
|
2052
1958
|
_executeHooks(hooks.beforeSanitizeElements, currentNode, null);
|
|
2053
|
-
if (
|
|
1959
|
+
if (currentNode !== root && getParentNode(currentNode) === null) {
|
|
1960
|
+
if (IN_PLACE) _neutralizeSubtree(currentNode);
|
|
1961
|
+
return true;
|
|
1962
|
+
}
|
|
2054
1963
|
if (_isClobbered(currentNode)) {
|
|
2055
1964
|
_forceRemove(currentNode);
|
|
2056
1965
|
return true;
|
|
2057
1966
|
}
|
|
2058
|
-
const tagName = transformCaseFunc(
|
|
1967
|
+
const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
|
|
2059
1968
|
ALLOWED_TAGS = _forkSharedAllowlist(hooks.uponSanitizeElement, ALLOWED_TAGS, DEFAULT_ALLOWED_TAGS, SET_CONFIG_ALLOWED_TAGS);
|
|
2060
1969
|
_executeHooks(hooks.uponSanitizeElement, currentNode, {
|
|
2061
1970
|
tagName,
|
|
2062
1971
|
allowedTags: ALLOWED_TAGS
|
|
2063
1972
|
});
|
|
2064
|
-
if (
|
|
1973
|
+
if (currentNode !== root && getParentNode(currentNode) === null) {
|
|
1974
|
+
if (IN_PLACE) _neutralizeSubtree(currentNode);
|
|
1975
|
+
return true;
|
|
1976
|
+
}
|
|
2065
1977
|
if (_isUnsafeNode(currentNode, tagName)) {
|
|
2066
1978
|
_forceRemove(currentNode);
|
|
2067
1979
|
return true;
|
|
@@ -2071,7 +1983,7 @@ function createDOMPurify() {
|
|
|
2071
1983
|
if (removed === false) _executeHooks(hooks.afterSanitizeElements, currentNode, null);
|
|
2072
1984
|
return removed;
|
|
2073
1985
|
}
|
|
2074
|
-
if (
|
|
1986
|
+
if ((getNodeType ? getNodeType(currentNode) : currentNode.nodeType) === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
|
|
2075
1987
|
_forceRemove(currentNode);
|
|
2076
1988
|
return true;
|
|
2077
1989
|
}
|
|
@@ -2099,17 +2011,20 @@ function createDOMPurify() {
|
|
|
2099
2011
|
*/
|
|
2100
2012
|
const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
|
|
2101
2013
|
if (FORBID_ATTR[lcName]) return false;
|
|
2102
|
-
if (
|
|
2014
|
+
if (SAFE_FOR_XML && lcName === "patchsrc") return false;
|
|
2015
|
+
if (SAFE_FOR_XML && lcName === "for" && lcTag !== "label" && lcTag !== "output") return false;
|
|
2103
2016
|
if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document || value in formElement)) return false;
|
|
2104
2017
|
const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
|
|
2105
|
-
if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName))
|
|
2106
|
-
if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName))
|
|
2107
|
-
if (!nameIsPermitted)
|
|
2108
|
-
|
|
2109
|
-
if (
|
|
2110
|
-
if ((
|
|
2111
|
-
if (
|
|
2112
|
-
|
|
2018
|
+
if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName));
|
|
2019
|
+
else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName));
|
|
2020
|
+
else if (!nameIsPermitted) if (_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) || lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value)));
|
|
2021
|
+
else return false;
|
|
2022
|
+
else if (URI_SAFE_ATTRIBUTES[lcName]);
|
|
2023
|
+
else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, "")));
|
|
2024
|
+
else if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]);
|
|
2025
|
+
else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, "")));
|
|
2026
|
+
else if (value) return false;
|
|
2027
|
+
return true;
|
|
2113
2028
|
};
|
|
2114
2029
|
const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, [
|
|
2115
2030
|
"annotation-xml",
|
|
@@ -2211,29 +2126,29 @@ function createDOMPurify() {
|
|
|
2211
2126
|
_executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
|
|
2212
2127
|
value = hookEvent.attrValue;
|
|
2213
2128
|
if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
|
|
2214
|
-
_removeAttribute(name, currentNode
|
|
2129
|
+
_removeAttribute(name, currentNode);
|
|
2215
2130
|
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
|
2216
2131
|
}
|
|
2217
2132
|
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
|
|
2218
|
-
_removeAttribute(name, currentNode
|
|
2133
|
+
_removeAttribute(name, currentNode);
|
|
2219
2134
|
continue;
|
|
2220
2135
|
}
|
|
2221
2136
|
if (lcName === "attributename" && stringMatch(value, "href")) {
|
|
2222
|
-
_removeAttribute(name, currentNode
|
|
2137
|
+
_removeAttribute(name, currentNode);
|
|
2223
2138
|
continue;
|
|
2224
2139
|
}
|
|
2225
2140
|
if (hookEvent.forceKeepAttr) continue;
|
|
2226
2141
|
if (!hookEvent.keepAttr) {
|
|
2227
|
-
_removeAttribute(name, currentNode
|
|
2142
|
+
_removeAttribute(name, currentNode);
|
|
2228
2143
|
continue;
|
|
2229
2144
|
}
|
|
2230
2145
|
if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
|
|
2231
|
-
_removeAttribute(name, currentNode
|
|
2146
|
+
_removeAttribute(name, currentNode);
|
|
2232
2147
|
continue;
|
|
2233
2148
|
}
|
|
2234
2149
|
if (SAFE_FOR_TEMPLATES) value = _stripTemplateExpressions(value);
|
|
2235
2150
|
if (!_isValidAttribute(lcTag, lcName, value)) {
|
|
2236
|
-
_removeAttribute(name, currentNode
|
|
2151
|
+
_removeAttribute(name, currentNode);
|
|
2237
2152
|
continue;
|
|
2238
2153
|
}
|
|
2239
2154
|
value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
|
|
@@ -2255,7 +2170,7 @@ function createDOMPurify() {
|
|
|
2255
2170
|
_sanitizeElements(shadowNode, fragment);
|
|
2256
2171
|
_sanitizeAttributes(shadowNode);
|
|
2257
2172
|
if (_isDocumentFragment(shadowNode.content)) _sanitizeShadowDOM2(shadowNode.content);
|
|
2258
|
-
if (
|
|
2173
|
+
if ((getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType) === NODE_TYPE.element) {
|
|
2259
2174
|
const innerSr = getShadowRoot(shadowNode);
|
|
2260
2175
|
if (_isDocumentFragment(innerSr)) {
|
|
2261
2176
|
_sanitizeAttachedShadowRoots(innerSr);
|
|
@@ -2296,7 +2211,7 @@ function createDOMPurify() {
|
|
|
2296
2211
|
continue;
|
|
2297
2212
|
}
|
|
2298
2213
|
const node = item.node;
|
|
2299
|
-
const isElement =
|
|
2214
|
+
const isElement = (getNodeType ? getNodeType(node) : node.nodeType) === NODE_TYPE.element;
|
|
2300
2215
|
const childNodes = getChildNodes(node);
|
|
2301
2216
|
if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push({
|
|
2302
2217
|
node: childNodes[i],
|
|
@@ -2347,7 +2262,7 @@ function createDOMPurify() {
|
|
|
2347
2262
|
const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
|
|
2348
2263
|
if (inPlace) {
|
|
2349
2264
|
_neutralizePatchLinkage(dirty);
|
|
2350
|
-
const nn =
|
|
2265
|
+
const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
|
|
2351
2266
|
if (typeof nn === "string") {
|
|
2352
2267
|
const tagName = transformCaseFunc(nn);
|
|
2353
2268
|
if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
|
|
@@ -2498,6 +2413,7 @@ function _resetSanitizeForTests() {
|
|
|
2498
2413
|
hookInstalled = false;
|
|
2499
2414
|
}
|
|
2500
2415
|
//#endregion
|
|
2416
|
+
exports.IconGlyph = IconGlyph;
|
|
2501
2417
|
exports._resetSanitizeForTests = _resetSanitizeForTests;
|
|
2502
2418
|
exports.buildMarkdownDocView = buildMarkdownDocView;
|
|
2503
2419
|
exports.formatScalarField = formatScalarField;
|