xslt-processor 4.8.0 → 4.8.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/index.d.mts +117 -0
- package/index.d.ts +117 -0
- package/index.js +842 -52
- package/index.js.map +1 -1
- package/index.mjs +842 -52
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/umd/xslt-processor.global.js +5 -5
- package/umd/xslt-processor.global.js.map +1 -1
package/index.js
CHANGED
|
@@ -5759,7 +5759,7 @@ function getBuiltInFunction(name) {
|
|
|
5759
5759
|
function getBuiltInFunctionArity(name) {
|
|
5760
5760
|
return FUNCTION_ARITY[name];
|
|
5761
5761
|
}
|
|
5762
|
-
var BUILT_IN_FUNCTIONS, FUNCTION_ARITY, XPathFunctionCall;
|
|
5762
|
+
var toStringValue, BUILT_IN_FUNCTIONS, FUNCTION_ARITY, XPathFunctionCall;
|
|
5763
5763
|
var init_function_call_expression = __esm({
|
|
5764
5764
|
"src/xpath/lib/src/expressions/function-call-expression.ts"() {
|
|
5765
5765
|
init_expression();
|
|
@@ -5778,10 +5778,30 @@ var init_function_call_expression = __esm({
|
|
|
5778
5778
|
init_qname_functions();
|
|
5779
5779
|
init_uri_functions();
|
|
5780
5780
|
init_node_functions();
|
|
5781
|
+
toStringValue = (arg) => {
|
|
5782
|
+
var _a;
|
|
5783
|
+
if (arg && typeof arg === "object") {
|
|
5784
|
+
if (typeof arg.stringValue === "function") {
|
|
5785
|
+
return arg.stringValue();
|
|
5786
|
+
}
|
|
5787
|
+
if (Array.isArray(arg)) {
|
|
5788
|
+
if (arg.length === 0) return "";
|
|
5789
|
+
const firstNode = arg[0];
|
|
5790
|
+
return (_a = firstNode == null ? void 0 : firstNode.textContent) != null ? _a : String(firstNode);
|
|
5791
|
+
}
|
|
5792
|
+
if (typeof arg.textContent === "string") {
|
|
5793
|
+
return arg.textContent;
|
|
5794
|
+
}
|
|
5795
|
+
if (arg.nodeValue !== void 0 && arg.nodeValue !== null) {
|
|
5796
|
+
return String(arg.nodeValue);
|
|
5797
|
+
}
|
|
5798
|
+
}
|
|
5799
|
+
return String(arg != null ? arg : "");
|
|
5800
|
+
};
|
|
5781
5801
|
BUILT_IN_FUNCTIONS = {
|
|
5782
5802
|
// String functions
|
|
5783
|
-
"upper-case": (_ctx, arg) =>
|
|
5784
|
-
"lower-case": (_ctx, arg) =>
|
|
5803
|
+
"upper-case": (_ctx, arg) => toStringValue(arg).toUpperCase(),
|
|
5804
|
+
"lower-case": (_ctx, arg) => toStringValue(arg).toLowerCase(),
|
|
5785
5805
|
concat: (_ctx, ...args) => args.map((a) => String(a)).join(""),
|
|
5786
5806
|
"string-join": (_ctx, seq, sep = "") => {
|
|
5787
5807
|
if (Array.isArray(seq)) {
|
|
@@ -6372,6 +6392,10 @@ var init_function_call_expression = __esm({
|
|
|
6372
6392
|
return context.functions[this.name](context, ...evaluatedArgs);
|
|
6373
6393
|
}
|
|
6374
6394
|
let builtInFunc = BUILT_IN_FUNCTIONS[this.name];
|
|
6395
|
+
if (!builtInFunc && this.name.startsWith("fn:")) {
|
|
6396
|
+
const localName = this.name.substring(3);
|
|
6397
|
+
builtInFunc = BUILT_IN_FUNCTIONS[localName];
|
|
6398
|
+
}
|
|
6375
6399
|
if (!builtInFunc && this.name.startsWith("Q{")) {
|
|
6376
6400
|
const { namespace, localName } = this.parseEQName(this.name);
|
|
6377
6401
|
builtInFunc = BUILT_IN_FUNCTIONS[localName];
|
|
@@ -12667,11 +12691,24 @@ function makeComponentKey(component) {
|
|
|
12667
12691
|
return `unknown:${component.type}`;
|
|
12668
12692
|
}
|
|
12669
12693
|
}
|
|
12694
|
+
function isComponentVisible(component, fromPackage) {
|
|
12695
|
+
if (component.visibility === "private") {
|
|
12696
|
+
return fromPackage;
|
|
12697
|
+
}
|
|
12698
|
+
return true;
|
|
12699
|
+
}
|
|
12700
|
+
function canOverrideComponent(component) {
|
|
12701
|
+
if (component.visibility === "final") {
|
|
12702
|
+
return false;
|
|
12703
|
+
}
|
|
12704
|
+
return component.overridable;
|
|
12705
|
+
}
|
|
12670
12706
|
|
|
12671
12707
|
// src/xslt/package-system/package-registry.ts
|
|
12672
12708
|
var PackageRegistry = class {
|
|
12673
12709
|
constructor() {
|
|
12674
12710
|
this.packages = /* @__PURE__ */ new Map();
|
|
12711
|
+
this.loading = /* @__PURE__ */ new Set();
|
|
12675
12712
|
}
|
|
12676
12713
|
/**
|
|
12677
12714
|
* Register a package in the registry.
|
|
@@ -12682,10 +12719,97 @@ var PackageRegistry = class {
|
|
|
12682
12719
|
}
|
|
12683
12720
|
/**
|
|
12684
12721
|
* Retrieve a package from the registry.
|
|
12722
|
+
* Supports version constraints: exact, wildcards (1.*), ranges (>=1.0), and combined (>=1.0,<2.0).
|
|
12685
12723
|
*/
|
|
12686
12724
|
get(name, version) {
|
|
12687
|
-
|
|
12688
|
-
|
|
12725
|
+
if (!version) {
|
|
12726
|
+
return this.packages.get(name);
|
|
12727
|
+
}
|
|
12728
|
+
const exactKey = this.makePackageKey(name, version);
|
|
12729
|
+
const exactMatch = this.packages.get(exactKey);
|
|
12730
|
+
if (exactMatch) {
|
|
12731
|
+
return exactMatch;
|
|
12732
|
+
}
|
|
12733
|
+
const hasConstraint = /[*<>=,]/.test(version);
|
|
12734
|
+
if (!hasConstraint) {
|
|
12735
|
+
return void 0;
|
|
12736
|
+
}
|
|
12737
|
+
const matchingPackages = [];
|
|
12738
|
+
this.packages.forEach((pkg, key) => {
|
|
12739
|
+
if (pkg.name === name && pkg.version && this.satisfiesVersion(pkg.version, version)) {
|
|
12740
|
+
matchingPackages.push(pkg);
|
|
12741
|
+
}
|
|
12742
|
+
});
|
|
12743
|
+
if (matchingPackages.length === 0) {
|
|
12744
|
+
return void 0;
|
|
12745
|
+
}
|
|
12746
|
+
matchingPackages.sort((a, b) => this.compareVersions(b.version, a.version));
|
|
12747
|
+
return matchingPackages[0];
|
|
12748
|
+
}
|
|
12749
|
+
/**
|
|
12750
|
+
* Check if a package version satisfies a version constraint.
|
|
12751
|
+
*/
|
|
12752
|
+
satisfiesVersion(packageVersion, constraint) {
|
|
12753
|
+
if (constraint.includes(",")) {
|
|
12754
|
+
const constraints = constraint.split(",").map((c) => c.trim());
|
|
12755
|
+
return constraints.every((c) => this.satisfiesSingleConstraint(packageVersion, c));
|
|
12756
|
+
}
|
|
12757
|
+
return this.satisfiesSingleConstraint(packageVersion, constraint);
|
|
12758
|
+
}
|
|
12759
|
+
/**
|
|
12760
|
+
* Evaluate a single version constraint.
|
|
12761
|
+
*/
|
|
12762
|
+
satisfiesSingleConstraint(packageVersion, constraint) {
|
|
12763
|
+
if (constraint.includes("*")) {
|
|
12764
|
+
const prefix = constraint.replace(/\*$/, "").replace(/\.$/, "");
|
|
12765
|
+
if (!prefix) {
|
|
12766
|
+
return true;
|
|
12767
|
+
}
|
|
12768
|
+
const pkgParts = packageVersion.split(".");
|
|
12769
|
+
const prefixParts = prefix.split(".");
|
|
12770
|
+
for (let i = 0; i < prefixParts.length; i++) {
|
|
12771
|
+
if (pkgParts[i] !== prefixParts[i]) {
|
|
12772
|
+
return false;
|
|
12773
|
+
}
|
|
12774
|
+
}
|
|
12775
|
+
return true;
|
|
12776
|
+
}
|
|
12777
|
+
const operatorMatch = constraint.match(/^(>=|<=|>|<|=)?(.+)$/);
|
|
12778
|
+
if (!operatorMatch) {
|
|
12779
|
+
return false;
|
|
12780
|
+
}
|
|
12781
|
+
const operator = operatorMatch[1] || "=";
|
|
12782
|
+
const targetVersion = operatorMatch[2].trim();
|
|
12783
|
+
const comparison = this.compareVersions(packageVersion, targetVersion);
|
|
12784
|
+
switch (operator) {
|
|
12785
|
+
case ">=":
|
|
12786
|
+
return comparison >= 0;
|
|
12787
|
+
case ">":
|
|
12788
|
+
return comparison > 0;
|
|
12789
|
+
case "<=":
|
|
12790
|
+
return comparison <= 0;
|
|
12791
|
+
case "<":
|
|
12792
|
+
return comparison < 0;
|
|
12793
|
+
case "=":
|
|
12794
|
+
default:
|
|
12795
|
+
return comparison === 0;
|
|
12796
|
+
}
|
|
12797
|
+
}
|
|
12798
|
+
/**
|
|
12799
|
+
* Compare two semantic versions.
|
|
12800
|
+
* @returns -1 if a < b, 0 if a === b, 1 if a > b
|
|
12801
|
+
*/
|
|
12802
|
+
compareVersions(a, b) {
|
|
12803
|
+
const aParts = a.split(".").map((p) => parseInt(p, 10) || 0);
|
|
12804
|
+
const bParts = b.split(".").map((p) => parseInt(p, 10) || 0);
|
|
12805
|
+
const maxLength = Math.max(aParts.length, bParts.length);
|
|
12806
|
+
for (let i = 0; i < maxLength; i++) {
|
|
12807
|
+
const aPart = aParts[i] || 0;
|
|
12808
|
+
const bPart = bParts[i] || 0;
|
|
12809
|
+
if (aPart < bPart) return -1;
|
|
12810
|
+
if (aPart > bPart) return 1;
|
|
12811
|
+
}
|
|
12812
|
+
return 0;
|
|
12689
12813
|
}
|
|
12690
12814
|
/**
|
|
12691
12815
|
* Check if a package exists in the registry.
|
|
@@ -12694,6 +12818,31 @@ var PackageRegistry = class {
|
|
|
12694
12818
|
const key = this.makePackageKey(name, version);
|
|
12695
12819
|
return this.packages.has(key);
|
|
12696
12820
|
}
|
|
12821
|
+
/**
|
|
12822
|
+
* Mark a package as currently being loaded.
|
|
12823
|
+
* Used to detect circular dependencies.
|
|
12824
|
+
* @returns true if the package can be loaded, false if it's already being loaded (circular dependency)
|
|
12825
|
+
*/
|
|
12826
|
+
beginLoading(packageKey) {
|
|
12827
|
+
if (this.loading.has(packageKey)) {
|
|
12828
|
+
return false;
|
|
12829
|
+
}
|
|
12830
|
+
this.loading.add(packageKey);
|
|
12831
|
+
return true;
|
|
12832
|
+
}
|
|
12833
|
+
/**
|
|
12834
|
+
* Mark a package as finished loading.
|
|
12835
|
+
*/
|
|
12836
|
+
endLoading(packageKey) {
|
|
12837
|
+
this.loading.delete(packageKey);
|
|
12838
|
+
}
|
|
12839
|
+
/**
|
|
12840
|
+
* Check if a package is currently being loaded.
|
|
12841
|
+
* Used to detect circular dependencies when a package tries to use another package that is still loading.
|
|
12842
|
+
*/
|
|
12843
|
+
isLoading(packageKey) {
|
|
12844
|
+
return this.loading.has(packageKey);
|
|
12845
|
+
}
|
|
12697
12846
|
/**
|
|
12698
12847
|
* Create a unique key for a package based on name and version.
|
|
12699
12848
|
*/
|
|
@@ -12705,6 +12854,7 @@ var PackageRegistry = class {
|
|
|
12705
12854
|
*/
|
|
12706
12855
|
clear() {
|
|
12707
12856
|
this.packages.clear();
|
|
12857
|
+
this.loading.clear();
|
|
12708
12858
|
}
|
|
12709
12859
|
};
|
|
12710
12860
|
|
|
@@ -13603,7 +13753,8 @@ function selectBestTemplate(templates, context, matchResolver, xPath, warningsCa
|
|
|
13603
13753
|
return {
|
|
13604
13754
|
selectedTemplate: winner.template,
|
|
13605
13755
|
hasConflict: conflicts.length > 1,
|
|
13606
|
-
conflictingTemplates: conflicts.length > 1 ? conflicts : []
|
|
13756
|
+
conflictingTemplates: conflicts.length > 1 ? conflicts : [],
|
|
13757
|
+
originalComponent: winner.originalComponent
|
|
13607
13758
|
};
|
|
13608
13759
|
}
|
|
13609
13760
|
function emitConflictWarning(result, node, warningsCallback) {
|
|
@@ -13704,6 +13855,11 @@ var Xslt = class {
|
|
|
13704
13855
|
* null if processing a non-package stylesheet.
|
|
13705
13856
|
*/
|
|
13706
13857
|
this.currentPackage = null;
|
|
13858
|
+
/**
|
|
13859
|
+
* Current override context (for XSLT 3.0 xsl:original).
|
|
13860
|
+
* Tracks the original component when executing an override.
|
|
13861
|
+
*/
|
|
13862
|
+
this.currentOverrideContext = null;
|
|
13707
13863
|
/**
|
|
13708
13864
|
* Accumulator registry for XSLT 3.0 accumulators.
|
|
13709
13865
|
* Stores accumulator definitions and current state during processing.
|
|
@@ -13945,6 +14101,12 @@ var Xslt = class {
|
|
|
13945
14101
|
case "accept":
|
|
13946
14102
|
this.xsltAccept(context, template);
|
|
13947
14103
|
break;
|
|
14104
|
+
case "override":
|
|
14105
|
+
yield this.xsltOverride(context, template, output);
|
|
14106
|
+
break;
|
|
14107
|
+
case "original":
|
|
14108
|
+
yield this.xsltOriginal(context, template, output);
|
|
14109
|
+
break;
|
|
13948
14110
|
case "param":
|
|
13949
14111
|
yield this.xsltVariable(context, template, false);
|
|
13950
14112
|
break;
|
|
@@ -13982,6 +14144,11 @@ var Xslt = class {
|
|
|
13982
14144
|
case "merge":
|
|
13983
14145
|
yield this.xsltMerge(context, template, output);
|
|
13984
14146
|
break;
|
|
14147
|
+
case "mode":
|
|
14148
|
+
if (this.currentPackage) {
|
|
14149
|
+
this.xsltMode(context, template);
|
|
14150
|
+
}
|
|
14151
|
+
break;
|
|
13985
14152
|
case "template":
|
|
13986
14153
|
yield this.xsltTemplate(context, template, output);
|
|
13987
14154
|
break;
|
|
@@ -14063,8 +14230,10 @@ var Xslt = class {
|
|
|
14063
14230
|
return;
|
|
14064
14231
|
}
|
|
14065
14232
|
const mode = xmlGetAttribute(template, "mode");
|
|
14233
|
+
const effectiveMode = mode || null;
|
|
14066
14234
|
const top = template.ownerDocument.documentElement;
|
|
14067
|
-
|
|
14235
|
+
let expandedTemplates = collectAndExpandTemplates(top, effectiveMode, this.xPath, this.templateSourceMap);
|
|
14236
|
+
expandedTemplates = expandedTemplates.concat(this.collectAcceptedTemplates(effectiveMode));
|
|
14068
14237
|
const paramContext = context.clone();
|
|
14069
14238
|
yield this.xsltWithParam(paramContext, template);
|
|
14070
14239
|
const modifiedContext = paramContext.clone(nodes);
|
|
@@ -14090,13 +14259,19 @@ var Xslt = class {
|
|
|
14090
14259
|
this.currentTemplateStack.push({
|
|
14091
14260
|
template: textSelection.selectedTemplate,
|
|
14092
14261
|
stylesheetDepth: (_a = metadata == null ? void 0 : metadata.importDepth) != null ? _a : 0,
|
|
14093
|
-
mode: modeAttr ||
|
|
14262
|
+
mode: modeAttr || effectiveMode,
|
|
14094
14263
|
match: matchPattern
|
|
14095
14264
|
});
|
|
14265
|
+
const previousOverrideContext = this.currentOverrideContext;
|
|
14266
|
+
const overrideContext = textSelection.originalComponent || textSelection.selectedTemplate.__originalComponent;
|
|
14267
|
+
if (overrideContext) {
|
|
14268
|
+
this.currentOverrideContext = overrideContext;
|
|
14269
|
+
}
|
|
14096
14270
|
try {
|
|
14097
14271
|
yield this.xsltChildNodes(textNodeContext, textSelection.selectedTemplate, output);
|
|
14098
14272
|
} finally {
|
|
14099
14273
|
this.currentTemplateStack.pop();
|
|
14274
|
+
this.currentOverrideContext = previousOverrideContext;
|
|
14100
14275
|
}
|
|
14101
14276
|
} else {
|
|
14102
14277
|
const oldTextNodeContext = context.clone([currentNode], 0);
|
|
@@ -14125,13 +14300,19 @@ var Xslt = class {
|
|
|
14125
14300
|
this.currentTemplateStack.push({
|
|
14126
14301
|
template: selection.selectedTemplate,
|
|
14127
14302
|
stylesheetDepth: (_b = metadata == null ? void 0 : metadata.importDepth) != null ? _b : 0,
|
|
14128
|
-
mode: modeAttr ||
|
|
14303
|
+
mode: modeAttr || effectiveMode,
|
|
14129
14304
|
match: matchPattern
|
|
14130
14305
|
});
|
|
14306
|
+
const previousOverrideContext = this.currentOverrideContext;
|
|
14307
|
+
const overrideContext = selection.originalComponent || selection.selectedTemplate.__originalComponent;
|
|
14308
|
+
if (overrideContext) {
|
|
14309
|
+
this.currentOverrideContext = overrideContext;
|
|
14310
|
+
}
|
|
14131
14311
|
try {
|
|
14132
14312
|
yield this.xsltChildNodes(clonedContext, selection.selectedTemplate, output);
|
|
14133
14313
|
} finally {
|
|
14134
14314
|
this.currentTemplateStack.pop();
|
|
14315
|
+
this.currentOverrideContext = previousOverrideContext;
|
|
14135
14316
|
}
|
|
14136
14317
|
} else {
|
|
14137
14318
|
if (currentNode.nodeType === DOM_ELEMENT_NODE && currentNode.childNodes && currentNode.childNodes.length > 0) {
|
|
@@ -14172,7 +14353,7 @@ var Xslt = class {
|
|
|
14172
14353
|
this.currentTemplateStack.push({
|
|
14173
14354
|
template: childSelection.selectedTemplate,
|
|
14174
14355
|
stylesheetDepth: (_c = childMetadata == null ? void 0 : childMetadata.importDepth) != null ? _c : 0,
|
|
14175
|
-
mode: childModeAttr ||
|
|
14356
|
+
mode: childModeAttr || effectiveMode,
|
|
14176
14357
|
match: childMatchPattern
|
|
14177
14358
|
});
|
|
14178
14359
|
try {
|
|
@@ -14181,7 +14362,7 @@ var Xslt = class {
|
|
|
14181
14362
|
this.currentTemplateStack.pop();
|
|
14182
14363
|
}
|
|
14183
14364
|
} else if (childNode.nodeType === DOM_ELEMENT_NODE) {
|
|
14184
|
-
yield this.applyBuiltInTemplate(childNode, expandedTemplates,
|
|
14365
|
+
yield this.applyBuiltInTemplate(childNode, expandedTemplates, effectiveMode, paramContext, output);
|
|
14185
14366
|
}
|
|
14186
14367
|
}
|
|
14187
14368
|
}
|
|
@@ -14218,7 +14399,16 @@ var Xslt = class {
|
|
|
14218
14399
|
this.warningsCallback
|
|
14219
14400
|
);
|
|
14220
14401
|
if (textSelection.selectedTemplate) {
|
|
14221
|
-
|
|
14402
|
+
const previousOverrideContext = this.currentOverrideContext;
|
|
14403
|
+
const overrideContext = textSelection.originalComponent || textSelection.selectedTemplate.__originalComponent;
|
|
14404
|
+
if (overrideContext) {
|
|
14405
|
+
this.currentOverrideContext = overrideContext;
|
|
14406
|
+
}
|
|
14407
|
+
try {
|
|
14408
|
+
yield this.xsltChildNodes(textContext, textSelection.selectedTemplate, output);
|
|
14409
|
+
} finally {
|
|
14410
|
+
this.currentOverrideContext = previousOverrideContext;
|
|
14411
|
+
}
|
|
14222
14412
|
} else {
|
|
14223
14413
|
this.commonLogicTextNode(textContext, childNode, output);
|
|
14224
14414
|
}
|
|
@@ -14242,10 +14432,16 @@ var Xslt = class {
|
|
|
14242
14432
|
mode: childModeAttr || mode,
|
|
14243
14433
|
match: childMatchPattern
|
|
14244
14434
|
});
|
|
14435
|
+
const previousOverrideContext = this.currentOverrideContext;
|
|
14436
|
+
const overrideContext = childSelection.originalComponent || childSelection.selectedTemplate.__originalComponent;
|
|
14437
|
+
if (overrideContext) {
|
|
14438
|
+
this.currentOverrideContext = overrideContext;
|
|
14439
|
+
}
|
|
14245
14440
|
try {
|
|
14246
14441
|
yield this.xsltChildNodes(childContext, childSelection.selectedTemplate, output);
|
|
14247
14442
|
} finally {
|
|
14248
14443
|
this.currentTemplateStack.pop();
|
|
14444
|
+
this.currentOverrideContext = previousOverrideContext;
|
|
14249
14445
|
}
|
|
14250
14446
|
} else if (childNode.nodeType === DOM_ELEMENT_NODE) {
|
|
14251
14447
|
yield this.applyBuiltInTemplate(childNode, expandedTemplates, mode, paramContext, output);
|
|
@@ -14284,23 +14480,39 @@ var Xslt = class {
|
|
|
14284
14480
|
return;
|
|
14285
14481
|
}
|
|
14286
14482
|
const nodeContext = context.clone([currentNode], 0);
|
|
14287
|
-
const selection = selectBestTemplate(
|
|
14483
|
+
const selection = selectBestTemplate(
|
|
14484
|
+
importedTemplates,
|
|
14485
|
+
nodeContext,
|
|
14486
|
+
this.matchResolver,
|
|
14487
|
+
this.xPath,
|
|
14488
|
+
this.warningsCallback
|
|
14489
|
+
);
|
|
14288
14490
|
if (!selection.selectedTemplate) {
|
|
14289
14491
|
return;
|
|
14290
14492
|
}
|
|
14291
14493
|
const importedContext = context.clone();
|
|
14292
|
-
|
|
14494
|
+
yield this.xsltWithParam(importedContext, template);
|
|
14293
14495
|
const metadata = this.templateSourceMap.get(selection.selectedTemplate);
|
|
14294
14496
|
if (metadata) {
|
|
14295
14497
|
const matchPattern = xmlGetAttribute(selection.selectedTemplate, "match");
|
|
14498
|
+
const modeAttr = xmlGetAttribute(selection.selectedTemplate, "mode");
|
|
14296
14499
|
this.currentTemplateStack.push({
|
|
14297
14500
|
template: selection.selectedTemplate,
|
|
14298
14501
|
stylesheetDepth: metadata.importDepth,
|
|
14299
|
-
mode: currentMode,
|
|
14502
|
+
mode: modeAttr || currentMode,
|
|
14300
14503
|
match: matchPattern
|
|
14301
14504
|
});
|
|
14302
|
-
|
|
14303
|
-
|
|
14505
|
+
const previousOverrideContext = this.currentOverrideContext;
|
|
14506
|
+
const overrideContext = selection.originalComponent || selection.selectedTemplate.__originalComponent;
|
|
14507
|
+
if (overrideContext) {
|
|
14508
|
+
this.currentOverrideContext = overrideContext;
|
|
14509
|
+
}
|
|
14510
|
+
try {
|
|
14511
|
+
yield this.xsltChildNodes(importedContext, selection.selectedTemplate, output);
|
|
14512
|
+
} finally {
|
|
14513
|
+
this.currentTemplateStack.pop();
|
|
14514
|
+
this.currentOverrideContext = previousOverrideContext;
|
|
14515
|
+
}
|
|
14304
14516
|
}
|
|
14305
14517
|
});
|
|
14306
14518
|
}
|
|
@@ -14335,6 +14547,21 @@ var Xslt = class {
|
|
|
14335
14547
|
const top = template.ownerDocument.documentElement;
|
|
14336
14548
|
const paramContext = context.clone();
|
|
14337
14549
|
yield this.xsltWithParam(paramContext, template);
|
|
14550
|
+
let foundTemplate = null;
|
|
14551
|
+
if (this.currentPackage) {
|
|
14552
|
+
this.currentPackage.usedPackages.forEach((usedPkg) => {
|
|
14553
|
+
usedPkg.acceptedComponents.forEach((component) => {
|
|
14554
|
+
if (component.type === "template" && component.name === name && component.isAccepted) {
|
|
14555
|
+
const effectiveComponent = this.getEffectiveComponent(component);
|
|
14556
|
+
foundTemplate = effectiveComponent.node;
|
|
14557
|
+
}
|
|
14558
|
+
});
|
|
14559
|
+
});
|
|
14560
|
+
}
|
|
14561
|
+
if (foundTemplate) {
|
|
14562
|
+
yield this.xsltChildNodes(paramContext, foundTemplate, output);
|
|
14563
|
+
return;
|
|
14564
|
+
}
|
|
14338
14565
|
for (let i = 0; i < top.childNodes.length; ++i) {
|
|
14339
14566
|
let childNode = top.childNodes[i];
|
|
14340
14567
|
if (childNode.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(childNode, "template") && domGetAttributeValue(childNode, "name") === name) {
|
|
@@ -15146,16 +15373,27 @@ var Xslt = class {
|
|
|
15146
15373
|
}
|
|
15147
15374
|
const name = xmlGetAttribute(template, "name");
|
|
15148
15375
|
const packageVersion = xmlGetAttribute(template, "package-version");
|
|
15376
|
+
const declaredModes = xmlGetAttribute(template, "declared-modes") || "yes";
|
|
15377
|
+
const inputTypeAnnotations = xmlGetAttribute(template, "input-type-annotations") || "unspecified";
|
|
15149
15378
|
if (!name) {
|
|
15150
15379
|
throw new Error('<xsl:package> requires a "name" attribute.');
|
|
15151
15380
|
}
|
|
15381
|
+
const packageKey = packageVersion ? `${name}@${packageVersion}` : name;
|
|
15382
|
+
const wasAlreadyLoading = this.packageRegistry.isLoading(packageKey);
|
|
15383
|
+
if (!wasAlreadyLoading) {
|
|
15384
|
+
this.packageRegistry.beginLoading(packageKey);
|
|
15385
|
+
}
|
|
15152
15386
|
const pkg = {
|
|
15153
15387
|
name,
|
|
15154
15388
|
version: packageVersion,
|
|
15155
15389
|
root: template,
|
|
15156
15390
|
components: /* @__PURE__ */ new Map(),
|
|
15157
15391
|
usedPackages: /* @__PURE__ */ new Map(),
|
|
15158
|
-
isTopLevel: this.currentPackage === null
|
|
15392
|
+
isTopLevel: this.currentPackage === null,
|
|
15393
|
+
overrides: /* @__PURE__ */ new Map(),
|
|
15394
|
+
modes: /* @__PURE__ */ new Map(),
|
|
15395
|
+
declaredModes,
|
|
15396
|
+
inputTypeAnnotations
|
|
15159
15397
|
};
|
|
15160
15398
|
const previousPackage = this.currentPackage;
|
|
15161
15399
|
this.currentPackage = pkg;
|
|
@@ -15163,10 +15401,54 @@ var Xslt = class {
|
|
|
15163
15401
|
this.packageRegistry.register(pkg);
|
|
15164
15402
|
yield this.xsltTransformOrStylesheet(context, template, output);
|
|
15165
15403
|
} finally {
|
|
15404
|
+
if (!wasAlreadyLoading) {
|
|
15405
|
+
this.packageRegistry.endLoading(packageKey);
|
|
15406
|
+
}
|
|
15166
15407
|
this.currentPackage = previousPackage;
|
|
15167
15408
|
}
|
|
15168
15409
|
});
|
|
15169
15410
|
}
|
|
15411
|
+
/**
|
|
15412
|
+
* Loads and registers an external package.
|
|
15413
|
+
* Creates a temporary context and processes the package document.
|
|
15414
|
+
*
|
|
15415
|
+
* @param name The package name/URI.
|
|
15416
|
+
* @param packageDoc The parsed package document.
|
|
15417
|
+
* @param version Optional semantic version string.
|
|
15418
|
+
*/
|
|
15419
|
+
loadAndRegisterPackage(name, packageDoc, version) {
|
|
15420
|
+
return __async(this, null, function* () {
|
|
15421
|
+
const packageKey = version ? `${name}@${version}` : name;
|
|
15422
|
+
if (!this.packageRegistry.beginLoading(packageKey)) {
|
|
15423
|
+
throw new Error(`Circular package dependency detected: "${packageKey}".`);
|
|
15424
|
+
}
|
|
15425
|
+
try {
|
|
15426
|
+
let packageRoot = packageDoc;
|
|
15427
|
+
if (packageDoc.nodeType === DOM_DOCUMENT_NODE) {
|
|
15428
|
+
for (const child of packageDoc.childNodes) {
|
|
15429
|
+
if (child.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(child, "package")) {
|
|
15430
|
+
packageRoot = child;
|
|
15431
|
+
break;
|
|
15432
|
+
}
|
|
15433
|
+
}
|
|
15434
|
+
}
|
|
15435
|
+
if (packageRoot && this.isXsltElement(packageRoot, "package")) {
|
|
15436
|
+
if (name && !xmlGetAttribute(packageRoot, "name")) {
|
|
15437
|
+
domSetAttribute(packageRoot, "name", name);
|
|
15438
|
+
}
|
|
15439
|
+
if (version && !xmlGetAttribute(packageRoot, "package-version")) {
|
|
15440
|
+
domSetAttribute(packageRoot, "package-version", version);
|
|
15441
|
+
}
|
|
15442
|
+
const tempContext = new ExprContext([packageRoot]);
|
|
15443
|
+
yield this.xsltPackage(tempContext, packageRoot);
|
|
15444
|
+
} else {
|
|
15445
|
+
throw new Error("Package document does not contain an xsl:package root element.");
|
|
15446
|
+
}
|
|
15447
|
+
} finally {
|
|
15448
|
+
this.packageRegistry.endLoading(packageKey);
|
|
15449
|
+
}
|
|
15450
|
+
});
|
|
15451
|
+
}
|
|
15170
15452
|
/**
|
|
15171
15453
|
* Implements `<xsl:use-package>` (XSLT 3.0 Section 3.7).
|
|
15172
15454
|
* Imports another package and makes its public components available.
|
|
@@ -15184,10 +15466,27 @@ var Xslt = class {
|
|
|
15184
15466
|
if (!name) {
|
|
15185
15467
|
throw new Error('<xsl:use-package> requires a "name" attribute.');
|
|
15186
15468
|
}
|
|
15187
|
-
const
|
|
15469
|
+
const packageKey = packageVersion ? `${name}@${packageVersion}` : name;
|
|
15470
|
+
if (this.packageRegistry.isLoading(packageKey)) {
|
|
15471
|
+
throw new Error(`Circular package dependency detected: "${packageKey}".`);
|
|
15472
|
+
}
|
|
15473
|
+
let usedPackage = this.packageRegistry.get(name, packageVersion);
|
|
15474
|
+
if (!usedPackage && this.packageLoader) {
|
|
15475
|
+
try {
|
|
15476
|
+
const packageDoc = yield this.packageLoader(name, packageVersion);
|
|
15477
|
+
if (packageDoc) {
|
|
15478
|
+
yield this.loadAndRegisterPackage(name, packageDoc, packageVersion);
|
|
15479
|
+
usedPackage = this.packageRegistry.get(name, packageVersion);
|
|
15480
|
+
}
|
|
15481
|
+
} catch (error) {
|
|
15482
|
+
if (error instanceof Error && error.message.includes("Circular package dependency")) {
|
|
15483
|
+
throw error;
|
|
15484
|
+
}
|
|
15485
|
+
}
|
|
15486
|
+
}
|
|
15188
15487
|
if (!usedPackage) {
|
|
15189
15488
|
throw new Error(
|
|
15190
|
-
`Package "${name}"${packageVersion ? `@${packageVersion}` : ""} not found. Packages must be loaded before they can be used
|
|
15489
|
+
`Package "${name}"${packageVersion ? `@${packageVersion}` : ""} not found. ` + (this.packageLoader ? "Package loader failed to load the package." : "Packages must be loaded before they can be used.")
|
|
15191
15490
|
);
|
|
15192
15491
|
}
|
|
15193
15492
|
const usedPkg = {
|
|
@@ -15199,8 +15498,22 @@ var Xslt = class {
|
|
|
15199
15498
|
for (const child of template.childNodes) {
|
|
15200
15499
|
if (this.isXsltElement(child, "accept")) {
|
|
15201
15500
|
this.xsltAccept(context, child);
|
|
15501
|
+
} else if (this.isXsltElement(child, "override")) {
|
|
15502
|
+
yield this.xsltOverride(context, child, output);
|
|
15202
15503
|
}
|
|
15203
15504
|
}
|
|
15505
|
+
yield this.registerAcceptedVariables(context);
|
|
15506
|
+
this.registerUserDefinedFunctionsInContext(context);
|
|
15507
|
+
usedPackage.components.forEach((component, key2) => {
|
|
15508
|
+
if (component.visibility === "abstract") {
|
|
15509
|
+
const hasOverride = this.currentPackage.overrides.has(key2);
|
|
15510
|
+
if (!hasOverride) {
|
|
15511
|
+
throw new Error(
|
|
15512
|
+
`Abstract component "${component.name || component.match || key2}" from package "${name}" must be overridden.`
|
|
15513
|
+
);
|
|
15514
|
+
}
|
|
15515
|
+
}
|
|
15516
|
+
});
|
|
15204
15517
|
});
|
|
15205
15518
|
}
|
|
15206
15519
|
/**
|
|
@@ -15224,16 +15537,69 @@ var Xslt = class {
|
|
|
15224
15537
|
throw new Error('<xsl:expose> requires a "names" attribute.');
|
|
15225
15538
|
}
|
|
15226
15539
|
for (const name of nameList) {
|
|
15227
|
-
const
|
|
15228
|
-
|
|
15229
|
-
|
|
15230
|
-
|
|
15231
|
-
|
|
15232
|
-
|
|
15233
|
-
|
|
15234
|
-
|
|
15235
|
-
|
|
15540
|
+
const actualComponent = this.findComponentInPackageRoot(
|
|
15541
|
+
this.currentPackage.root,
|
|
15542
|
+
componentType,
|
|
15543
|
+
name === "*" ? null : name
|
|
15544
|
+
);
|
|
15545
|
+
if (actualComponent) {
|
|
15546
|
+
const component = {
|
|
15547
|
+
type: componentType,
|
|
15548
|
+
name: actualComponent.name || (name !== "*" ? name : void 0),
|
|
15549
|
+
match: actualComponent.match,
|
|
15550
|
+
mode: actualComponent.mode,
|
|
15551
|
+
visibility,
|
|
15552
|
+
overridable: visibility !== "final",
|
|
15553
|
+
node: actualComponent.node,
|
|
15554
|
+
priority: actualComponent.priority
|
|
15555
|
+
};
|
|
15556
|
+
const key = makeComponentKey(component);
|
|
15557
|
+
this.currentPackage.components.set(key, component);
|
|
15558
|
+
} else if (name !== "*") {
|
|
15559
|
+
}
|
|
15560
|
+
}
|
|
15561
|
+
}
|
|
15562
|
+
/**
|
|
15563
|
+
* Find a component definition in the package root.
|
|
15564
|
+
* @param packageRoot The package root element
|
|
15565
|
+
* @param type The component type to find
|
|
15566
|
+
* @param name The component name (null for all matching type)
|
|
15567
|
+
* @returns Component information or null if not found
|
|
15568
|
+
*/
|
|
15569
|
+
findComponentInPackageRoot(packageRoot, type, name) {
|
|
15570
|
+
for (const child of packageRoot.childNodes) {
|
|
15571
|
+
if (child.nodeType !== DOM_ELEMENT_NODE) {
|
|
15572
|
+
continue;
|
|
15573
|
+
}
|
|
15574
|
+
if (type === "template" && this.isXsltElement(child, "template")) {
|
|
15575
|
+
const templateName = xmlGetAttribute(child, "name");
|
|
15576
|
+
const match = xmlGetAttribute(child, "match");
|
|
15577
|
+
const mode = xmlGetAttribute(child, "mode");
|
|
15578
|
+
if (name) {
|
|
15579
|
+
if (templateName === name) {
|
|
15580
|
+
return { node: child, name: templateName, match, mode };
|
|
15581
|
+
}
|
|
15582
|
+
} else {
|
|
15583
|
+
return { node: child, name: templateName, match, mode };
|
|
15584
|
+
}
|
|
15585
|
+
} else if (type === "function" && this.isXsltElement(child, "function")) {
|
|
15586
|
+
const functionName2 = xmlGetAttribute(child, "name");
|
|
15587
|
+
if (!name || functionName2 === name) {
|
|
15588
|
+
return { node: child, name: functionName2 };
|
|
15589
|
+
}
|
|
15590
|
+
} else if (type === "variable" && this.isXsltElement(child, "variable")) {
|
|
15591
|
+
const varName = xmlGetAttribute(child, "name");
|
|
15592
|
+
if (!name || varName === name) {
|
|
15593
|
+
return { node: child, name: varName };
|
|
15594
|
+
}
|
|
15595
|
+
} else if (type === "attribute-set" && this.isXsltElement(child, "attribute-set")) {
|
|
15596
|
+
const setName = xmlGetAttribute(child, "name");
|
|
15597
|
+
if (!name || setName === name) {
|
|
15598
|
+
return { node: child, name: setName };
|
|
15599
|
+
}
|
|
15600
|
+
}
|
|
15236
15601
|
}
|
|
15602
|
+
return null;
|
|
15237
15603
|
}
|
|
15238
15604
|
/**
|
|
15239
15605
|
* Implements `<xsl:accept>` (XSLT 3.0 Section 3.9).
|
|
@@ -15247,6 +15613,7 @@ var Xslt = class {
|
|
|
15247
15613
|
}
|
|
15248
15614
|
const componentType = xmlGetAttribute(template, "component");
|
|
15249
15615
|
const names = xmlGetAttribute(template, "names");
|
|
15616
|
+
const visibilityOverride = xmlGetAttribute(template, "visibility");
|
|
15250
15617
|
if (!componentType) {
|
|
15251
15618
|
throw new Error('<xsl:accept> requires a "component" attribute.');
|
|
15252
15619
|
}
|
|
@@ -15265,17 +15632,325 @@ var Xslt = class {
|
|
|
15265
15632
|
if (!usedPkg) {
|
|
15266
15633
|
throw new Error(`Internal error: used package "${key}" not found.`);
|
|
15267
15634
|
}
|
|
15268
|
-
|
|
15269
|
-
|
|
15270
|
-
|
|
15271
|
-
|
|
15272
|
-
|
|
15273
|
-
|
|
15635
|
+
const componentsToAccept = this.findComponentsInPackage(
|
|
15636
|
+
usedPkg.package,
|
|
15637
|
+
componentType,
|
|
15638
|
+
nameList
|
|
15639
|
+
);
|
|
15640
|
+
for (const component of componentsToAccept) {
|
|
15641
|
+
if (!isComponentVisible(component, false)) {
|
|
15642
|
+
const componentName = component.name || component.match || "unnamed";
|
|
15643
|
+
throw new Error(
|
|
15644
|
+
`Cannot accept private component "${componentName}" of type "${componentType}" from package "${usedPkg.package.name}".`
|
|
15645
|
+
);
|
|
15646
|
+
}
|
|
15647
|
+
const acceptedComponent = __spreadProps(__spreadValues({}, component), {
|
|
15648
|
+
sourcePackage: usedPkg.package.name,
|
|
15649
|
+
isAccepted: true,
|
|
15650
|
+
effectiveVisibility: visibilityOverride || component.visibility
|
|
15651
|
+
});
|
|
15652
|
+
const componentKey = makeComponentKey(acceptedComponent);
|
|
15653
|
+
usedPkg.acceptedComponents.set(componentKey, acceptedComponent);
|
|
15654
|
+
}
|
|
15655
|
+
}
|
|
15656
|
+
/**
|
|
15657
|
+
* Implements <xsl:override> (XSLT 3.0 Section 3.7.2).
|
|
15658
|
+
* Overrides components from a used package.
|
|
15659
|
+
*/
|
|
15660
|
+
xsltOverride(context, template, output) {
|
|
15661
|
+
return __async(this, null, function* () {
|
|
15662
|
+
if (!this.currentPackage) {
|
|
15663
|
+
throw new Error("<xsl:override> can only appear as a child of <xsl:use-package>.");
|
|
15664
|
+
}
|
|
15665
|
+
const parentUsePackage = template.parentNode;
|
|
15666
|
+
if (!parentUsePackage || !this.isXsltElement(parentUsePackage, "use-package")) {
|
|
15667
|
+
throw new Error("<xsl:override> must be a child of <xsl:use-package>.");
|
|
15668
|
+
}
|
|
15669
|
+
const packageName = xmlGetAttribute(parentUsePackage, "name");
|
|
15670
|
+
const packageVersion = xmlGetAttribute(parentUsePackage, "package-version");
|
|
15671
|
+
const key = packageVersion ? `${packageName}@${packageVersion}` : packageName;
|
|
15672
|
+
const usedPkg = this.currentPackage.usedPackages.get(key);
|
|
15673
|
+
if (!usedPkg) {
|
|
15674
|
+
throw new Error(`Internal error: used package "${key}" not found.`);
|
|
15675
|
+
}
|
|
15676
|
+
for (let i = 0; i < template.childNodes.length; i++) {
|
|
15677
|
+
const child = template.childNodes[i];
|
|
15678
|
+
if (child.nodeType !== DOM_ELEMENT_NODE) {
|
|
15679
|
+
continue;
|
|
15680
|
+
}
|
|
15681
|
+
const localName = child.localName;
|
|
15682
|
+
let componentType = null;
|
|
15683
|
+
let componentName = null;
|
|
15684
|
+
let componentMatch = null;
|
|
15685
|
+
switch (localName) {
|
|
15686
|
+
case "template":
|
|
15687
|
+
componentType = "template";
|
|
15688
|
+
componentName = xmlGetAttribute(child, "name");
|
|
15689
|
+
componentMatch = xmlGetAttribute(child, "match");
|
|
15690
|
+
break;
|
|
15691
|
+
case "function":
|
|
15692
|
+
componentType = "function";
|
|
15693
|
+
componentName = xmlGetAttribute(child, "name");
|
|
15694
|
+
break;
|
|
15695
|
+
case "variable":
|
|
15696
|
+
componentType = "variable";
|
|
15697
|
+
componentName = xmlGetAttribute(child, "name");
|
|
15698
|
+
break;
|
|
15699
|
+
case "attribute-set":
|
|
15700
|
+
componentType = "attribute-set";
|
|
15701
|
+
componentName = xmlGetAttribute(child, "name");
|
|
15702
|
+
break;
|
|
15703
|
+
default:
|
|
15704
|
+
throw new Error(`<xsl:override> does not support <xsl:${localName}> elements.`);
|
|
15705
|
+
}
|
|
15706
|
+
if (!componentType) {
|
|
15707
|
+
continue;
|
|
15708
|
+
}
|
|
15709
|
+
let originalComponent;
|
|
15710
|
+
usedPkg.acceptedComponents.forEach((component) => {
|
|
15711
|
+
if (component.type !== componentType) {
|
|
15712
|
+
return;
|
|
15713
|
+
}
|
|
15714
|
+
if (componentName && component.name === componentName) {
|
|
15715
|
+
originalComponent = component;
|
|
15716
|
+
} else if (componentMatch && component.match === componentMatch) {
|
|
15717
|
+
originalComponent = component;
|
|
15718
|
+
}
|
|
15719
|
+
});
|
|
15720
|
+
if (!originalComponent) {
|
|
15721
|
+
usedPkg.package.components.forEach((component) => {
|
|
15722
|
+
if (component.type !== componentType) {
|
|
15723
|
+
return;
|
|
15724
|
+
}
|
|
15725
|
+
if (componentName && component.name === componentName) {
|
|
15726
|
+
originalComponent = component;
|
|
15727
|
+
} else if (componentMatch && component.match === componentMatch) {
|
|
15728
|
+
originalComponent = component;
|
|
15729
|
+
}
|
|
15730
|
+
});
|
|
15731
|
+
}
|
|
15732
|
+
if (!originalComponent) {
|
|
15733
|
+
const identifier = componentName || componentMatch || "unnamed";
|
|
15734
|
+
throw new Error(
|
|
15735
|
+
`Cannot override component "${identifier}" of type "${componentType}": component not found in package "${usedPkg.package.name}".`
|
|
15736
|
+
);
|
|
15737
|
+
}
|
|
15738
|
+
if (!canOverrideComponent(originalComponent)) {
|
|
15739
|
+
const identifier = componentName || componentMatch || "unnamed";
|
|
15740
|
+
throw new Error(
|
|
15741
|
+
`Cannot override component "${identifier}" of type "${componentType}": component is marked as "final" in package "${usedPkg.package.name}".`
|
|
15742
|
+
);
|
|
15743
|
+
}
|
|
15744
|
+
const overridingComponent = {
|
|
15745
|
+
type: componentType,
|
|
15746
|
+
name: componentName || void 0,
|
|
15747
|
+
match: componentMatch || void 0,
|
|
15748
|
+
mode: xmlGetAttribute(child, "mode") || void 0,
|
|
15749
|
+
visibility: originalComponent.visibility,
|
|
15750
|
+
// Inherit visibility from original
|
|
15751
|
+
overridable: false,
|
|
15752
|
+
// Overrides cannot themselves be overridden (unless explicitly marked)
|
|
15753
|
+
node: child,
|
|
15754
|
+
sourcePackage: this.currentPackage.name,
|
|
15755
|
+
isAccepted: false,
|
|
15756
|
+
effectiveVisibility: originalComponent.visibility
|
|
15757
|
+
};
|
|
15758
|
+
overridingComponent.originalComponent = originalComponent;
|
|
15759
|
+
overridingComponent.node.__originalComponent = originalComponent;
|
|
15760
|
+
const componentKey = makeComponentKey(originalComponent);
|
|
15761
|
+
this.currentPackage.overrides.set(componentKey, overridingComponent);
|
|
15762
|
+
if (componentType === "function") {
|
|
15763
|
+
this.xsltFunction(context, child);
|
|
15764
|
+
}
|
|
15765
|
+
}
|
|
15766
|
+
});
|
|
15767
|
+
}
|
|
15768
|
+
/**
|
|
15769
|
+
* Find components in a package matching the given criteria.
|
|
15770
|
+
* Used by xsl:accept to locate components from used packages.
|
|
15771
|
+
*
|
|
15772
|
+
* @param pkg The package to search in
|
|
15773
|
+
* @param componentType The type of component to find
|
|
15774
|
+
* @param namePatterns Array of name patterns ('*' for all, or specific names)
|
|
15775
|
+
* @returns Array of matching components
|
|
15776
|
+
*/
|
|
15777
|
+
findComponentsInPackage(pkg, componentType, namePatterns) {
|
|
15778
|
+
const results = [];
|
|
15779
|
+
const isWildcard = namePatterns.includes("*");
|
|
15780
|
+
pkg.components.forEach((component, key) => {
|
|
15781
|
+
if (component.type !== componentType) {
|
|
15782
|
+
return;
|
|
15783
|
+
}
|
|
15784
|
+
if (isWildcard) {
|
|
15785
|
+
results.push(component);
|
|
15786
|
+
return;
|
|
15787
|
+
}
|
|
15788
|
+
const componentName = this.getComponentNameForMatching(component);
|
|
15789
|
+
if (componentName && namePatterns.includes(componentName)) {
|
|
15790
|
+
results.push(component);
|
|
15791
|
+
}
|
|
15792
|
+
});
|
|
15793
|
+
return results;
|
|
15794
|
+
}
|
|
15795
|
+
/**
|
|
15796
|
+
* Get the name to use when matching components.
|
|
15797
|
+
* For named components (functions, variables, attribute-sets), returns the name.
|
|
15798
|
+
* For templates, returns the name if present, otherwise returns null (match-based templates).
|
|
15799
|
+
*
|
|
15800
|
+
* @param component The component to get the name from
|
|
15801
|
+
* @returns The component name for matching, or null if unnamed
|
|
15802
|
+
*/
|
|
15803
|
+
getComponentNameForMatching(component) {
|
|
15804
|
+
switch (component.type) {
|
|
15805
|
+
case "function":
|
|
15806
|
+
case "variable":
|
|
15807
|
+
case "attribute-set":
|
|
15808
|
+
case "mode":
|
|
15809
|
+
return component.name || null;
|
|
15810
|
+
case "template":
|
|
15811
|
+
return component.name || null;
|
|
15812
|
+
default:
|
|
15813
|
+
return null;
|
|
15814
|
+
}
|
|
15815
|
+
}
|
|
15816
|
+
/**
|
|
15817
|
+
* Implements <xsl:original> (XSLT 3.0 Section 3.7.2).
|
|
15818
|
+
* Calls the original component from within an override.
|
|
15819
|
+
*/
|
|
15820
|
+
xsltOriginal(context, template, output) {
|
|
15821
|
+
return __async(this, null, function* () {
|
|
15822
|
+
if (!this.currentOverrideContext && this.currentTemplateStack.length > 0) {
|
|
15823
|
+
const currentTemplate = this.currentTemplateStack[this.currentTemplateStack.length - 1].template;
|
|
15824
|
+
const templateOverrideContext = currentTemplate.__originalComponent;
|
|
15825
|
+
if (templateOverrideContext) {
|
|
15826
|
+
this.currentOverrideContext = templateOverrideContext;
|
|
15827
|
+
}
|
|
15828
|
+
}
|
|
15829
|
+
if (!this.currentOverrideContext) {
|
|
15830
|
+
throw new Error("<xsl:original> can only be used within an overriding component.");
|
|
15831
|
+
}
|
|
15832
|
+
const originalComponent = this.currentOverrideContext;
|
|
15833
|
+
const originalNode = originalComponent.node;
|
|
15834
|
+
switch (originalComponent.type) {
|
|
15835
|
+
case "template":
|
|
15836
|
+
yield this.xsltChildNodes(context, originalNode, output);
|
|
15837
|
+
break;
|
|
15838
|
+
case "function":
|
|
15839
|
+
throw new Error("<xsl:original> for functions should be called as a function, not as an element.");
|
|
15840
|
+
case "variable":
|
|
15841
|
+
yield this.xsltVariable(context, originalNode, true);
|
|
15842
|
+
break;
|
|
15843
|
+
case "attribute-set":
|
|
15844
|
+
if (originalComponent.name && output) {
|
|
15845
|
+
yield this.applyAttributeSets(context, output, originalComponent.name);
|
|
15846
|
+
}
|
|
15847
|
+
break;
|
|
15848
|
+
default:
|
|
15849
|
+
throw new Error(`<xsl:original> does not support component type "${originalComponent.type}".`);
|
|
15850
|
+
}
|
|
15851
|
+
});
|
|
15852
|
+
}
|
|
15853
|
+
/**
|
|
15854
|
+
* Implements `<xsl:mode>` (XSLT 3.0 Section 3.5).
|
|
15855
|
+
* Declares a mode with visibility and other properties.
|
|
15856
|
+
* Only valid within an xsl:package.
|
|
15857
|
+
*/
|
|
15858
|
+
xsltMode(context, template) {
|
|
15859
|
+
if (!this.currentPackage) {
|
|
15860
|
+
throw new Error("<xsl:mode> can only appear as a child of <xsl:package>.");
|
|
15861
|
+
}
|
|
15862
|
+
const name = xmlGetAttribute(template, "name");
|
|
15863
|
+
if (!name) {
|
|
15864
|
+
throw new Error('<xsl:mode> requires a "name" attribute.');
|
|
15865
|
+
}
|
|
15866
|
+
const visibility = xmlGetAttribute(template, "visibility") || "public";
|
|
15867
|
+
const streamableAttr = xmlGetAttribute(template, "streamable");
|
|
15868
|
+
const onNoMatch = xmlGetAttribute(template, "on-no-match");
|
|
15869
|
+
const onMultipleMatch = xmlGetAttribute(template, "on-multiple-match");
|
|
15870
|
+
const streamable = streamableAttr === "yes";
|
|
15871
|
+
if (!this.currentPackage.modes) {
|
|
15872
|
+
this.currentPackage.modes = /* @__PURE__ */ new Map();
|
|
15873
|
+
}
|
|
15874
|
+
const modeProperties = {
|
|
15875
|
+
name,
|
|
15876
|
+
visibility,
|
|
15877
|
+
streamable,
|
|
15878
|
+
onNoMatch,
|
|
15879
|
+
onMultipleMatch
|
|
15880
|
+
};
|
|
15881
|
+
this.currentPackage.modes.set(name, modeProperties);
|
|
15882
|
+
const componentKey = makeComponentKey({ type: "mode", name, visibility });
|
|
15883
|
+
if (!this.currentPackage.components.has(componentKey)) {
|
|
15884
|
+
this.currentPackage.components.set(componentKey, {
|
|
15885
|
+
type: "mode",
|
|
15886
|
+
name,
|
|
15887
|
+
visibility,
|
|
15888
|
+
overridable: false,
|
|
15274
15889
|
node: template
|
|
15275
|
-
};
|
|
15276
|
-
|
|
15277
|
-
|
|
15890
|
+
});
|
|
15891
|
+
}
|
|
15892
|
+
}
|
|
15893
|
+
/**
|
|
15894
|
+
* Get the effective component, checking for overrides first.
|
|
15895
|
+
* If the component has been overridden in the current package, returns the override.
|
|
15896
|
+
* Otherwise, returns the original component.
|
|
15897
|
+
* @param component The original component
|
|
15898
|
+
* @returns The effective component (override or original)
|
|
15899
|
+
*/
|
|
15900
|
+
getEffectiveComponent(component) {
|
|
15901
|
+
if (!this.currentPackage) {
|
|
15902
|
+
return component;
|
|
15278
15903
|
}
|
|
15904
|
+
const componentKey = makeComponentKey(component);
|
|
15905
|
+
const override = this.currentPackage.overrides.get(componentKey);
|
|
15906
|
+
return override || component;
|
|
15907
|
+
}
|
|
15908
|
+
/**
|
|
15909
|
+
* Collect templates from accepted components in used packages.
|
|
15910
|
+
* @param mode The mode to match (null for default mode)
|
|
15911
|
+
* @returns Array of template priority interfaces
|
|
15912
|
+
*/
|
|
15913
|
+
collectAcceptedTemplates(mode) {
|
|
15914
|
+
const templates = [];
|
|
15915
|
+
if (!this.currentPackage) {
|
|
15916
|
+
return templates;
|
|
15917
|
+
}
|
|
15918
|
+
this.currentPackage.usedPackages.forEach((usedPkg, packageKey) => {
|
|
15919
|
+
usedPkg.acceptedComponents.forEach((component, componentKey) => {
|
|
15920
|
+
if (component.type === "template" && component.isAccepted) {
|
|
15921
|
+
const effectiveComponent = this.getEffectiveComponent(component);
|
|
15922
|
+
const templateNode = effectiveComponent.node;
|
|
15923
|
+
const isOverride = effectiveComponent !== component;
|
|
15924
|
+
const originalForContext = isOverride ? component : void 0;
|
|
15925
|
+
const templateMode = xmlGetAttribute(templateNode, "mode") || null;
|
|
15926
|
+
const effectiveMode = mode || null;
|
|
15927
|
+
if (effectiveMode !== templateMode) {
|
|
15928
|
+
return;
|
|
15929
|
+
}
|
|
15930
|
+
const match = xmlGetAttribute(templateNode, "match");
|
|
15931
|
+
if (!match) {
|
|
15932
|
+
return;
|
|
15933
|
+
}
|
|
15934
|
+
const priorityAttr = xmlGetAttribute(templateNode, "priority");
|
|
15935
|
+
const explicitPriority = priorityAttr ? parseFloat(priorityAttr) : null;
|
|
15936
|
+
const defaultPriority = component.priority || 0;
|
|
15937
|
+
const effectivePriority = explicitPriority !== null && !isNaN(explicitPriority) ? explicitPriority : defaultPriority;
|
|
15938
|
+
templates.push({
|
|
15939
|
+
template: templateNode,
|
|
15940
|
+
explicitPriority: explicitPriority !== null && !isNaN(explicitPriority) ? explicitPriority : null,
|
|
15941
|
+
defaultPriority,
|
|
15942
|
+
effectivePriority,
|
|
15943
|
+
importPrecedence: 0,
|
|
15944
|
+
// Accepted templates have neutral precedence
|
|
15945
|
+
documentOrder: 0,
|
|
15946
|
+
matchPattern: match,
|
|
15947
|
+
originalComponent: originalForContext
|
|
15948
|
+
// Store original for xsl:original support
|
|
15949
|
+
});
|
|
15950
|
+
}
|
|
15951
|
+
});
|
|
15952
|
+
});
|
|
15953
|
+
return templates;
|
|
15279
15954
|
}
|
|
15280
15955
|
/**
|
|
15281
15956
|
* Implements `<xsl:stream>` (XSLT 3.0 Section 16).
|
|
@@ -16364,6 +17039,30 @@ var Xslt = class {
|
|
|
16364
17039
|
}
|
|
16365
17040
|
this.userDefinedFunctions.set(name, template);
|
|
16366
17041
|
}
|
|
17042
|
+
/**
|
|
17043
|
+
* Coerce a NodeValue to a specific type based on the 'as' attribute.
|
|
17044
|
+
*
|
|
17045
|
+
* @param value The value to coerce.
|
|
17046
|
+
* @param type The target type (e.g., "xs:integer", "xs:string", "xs:boolean").
|
|
17047
|
+
* @returns The coerced value.
|
|
17048
|
+
*/
|
|
17049
|
+
coerceToType(value, type) {
|
|
17050
|
+
const normalizedType = type.replace(/^xs:/, "").toLowerCase();
|
|
17051
|
+
switch (normalizedType) {
|
|
17052
|
+
case "integer":
|
|
17053
|
+
case "int":
|
|
17054
|
+
case "double":
|
|
17055
|
+
case "decimal":
|
|
17056
|
+
case "number":
|
|
17057
|
+
return new NumberValue(value.numberValue());
|
|
17058
|
+
case "string":
|
|
17059
|
+
return new StringValue(value.stringValue());
|
|
17060
|
+
case "boolean":
|
|
17061
|
+
return new BooleanValue(value.booleanValue());
|
|
17062
|
+
default:
|
|
17063
|
+
return value;
|
|
17064
|
+
}
|
|
17065
|
+
}
|
|
16367
17066
|
/**
|
|
16368
17067
|
* Execute a user-defined xsl:function.
|
|
16369
17068
|
* Called when a function from userDefinedFunctions is invoked from XPath.
|
|
@@ -16401,18 +17100,32 @@ var Xslt = class {
|
|
|
16401
17100
|
const paramName = xmlGetAttribute(params[i], "name");
|
|
16402
17101
|
if (paramName) {
|
|
16403
17102
|
if (i < args.length) {
|
|
16404
|
-
|
|
17103
|
+
let argValue = args[i];
|
|
17104
|
+
const paramType = xmlGetAttribute(params[i], "as");
|
|
17105
|
+
let paramValue;
|
|
16405
17106
|
if (argValue && typeof argValue === "object" && "stringValue" in argValue) {
|
|
16406
|
-
|
|
17107
|
+
paramValue = argValue;
|
|
17108
|
+
if (paramType) {
|
|
17109
|
+
paramValue = this.coerceToType(paramValue, paramType);
|
|
17110
|
+
}
|
|
17111
|
+
} else if (argValue && typeof argValue === "object" && "nodeType" in argValue) {
|
|
17112
|
+
paramValue = new NodeSetValue([argValue]);
|
|
17113
|
+
if (paramType) {
|
|
17114
|
+
paramValue = this.coerceToType(paramValue, paramType);
|
|
17115
|
+
}
|
|
16407
17116
|
} else if (Array.isArray(argValue)) {
|
|
16408
|
-
|
|
17117
|
+
paramValue = new NodeSetValue(argValue);
|
|
17118
|
+
if (paramType) {
|
|
17119
|
+
paramValue = this.coerceToType(paramValue, paramType);
|
|
17120
|
+
}
|
|
16409
17121
|
} else if (typeof argValue === "number") {
|
|
16410
|
-
|
|
17122
|
+
paramValue = new NumberValue(argValue);
|
|
16411
17123
|
} else if (typeof argValue === "boolean") {
|
|
16412
|
-
|
|
17124
|
+
paramValue = new BooleanValue(argValue);
|
|
16413
17125
|
} else {
|
|
16414
|
-
|
|
17126
|
+
paramValue = new StringValue(String(argValue != null ? argValue : ""));
|
|
16415
17127
|
}
|
|
17128
|
+
functionContext.setVariable(paramName, paramValue);
|
|
16416
17129
|
} else {
|
|
16417
17130
|
const selectExpr = xmlGetAttribute(params[i], "select");
|
|
16418
17131
|
if (selectExpr) {
|
|
@@ -16491,6 +17204,30 @@ var Xslt = class {
|
|
|
16491
17204
|
getResultDocuments() {
|
|
16492
17205
|
return this.resultDocuments;
|
|
16493
17206
|
}
|
|
17207
|
+
/**
|
|
17208
|
+
* Sets the package loader callback.
|
|
17209
|
+
* The callback is called when a package is referenced via xsl:use-package
|
|
17210
|
+
* but is not found in the registry.
|
|
17211
|
+
*
|
|
17212
|
+
* @param loader A function that loads package documents by URI and optional version.
|
|
17213
|
+
* Returns the parsed package document, or null if not found.
|
|
17214
|
+
*/
|
|
17215
|
+
setPackageLoader(loader) {
|
|
17216
|
+
this.packageLoader = loader;
|
|
17217
|
+
}
|
|
17218
|
+
/**
|
|
17219
|
+
* Pre-registers a package for use in transformations.
|
|
17220
|
+
* The package is parsed and stored in the internal registry.
|
|
17221
|
+
*
|
|
17222
|
+
* @param name The package name/URI.
|
|
17223
|
+
* @param packageDoc The parsed package document.
|
|
17224
|
+
* @param version Optional semantic version string.
|
|
17225
|
+
*/
|
|
17226
|
+
registerPackage(name, packageDoc, version) {
|
|
17227
|
+
return __async(this, null, function* () {
|
|
17228
|
+
yield this.loadAndRegisterPackage(name, packageDoc, version);
|
|
17229
|
+
});
|
|
17230
|
+
}
|
|
16494
17231
|
/**
|
|
16495
17232
|
* Implements `xsl:perform-sort` (XSLT 2.0).
|
|
16496
17233
|
*
|
|
@@ -16605,6 +17342,25 @@ var Xslt = class {
|
|
|
16605
17342
|
}
|
|
16606
17343
|
});
|
|
16607
17344
|
}
|
|
17345
|
+
/**
|
|
17346
|
+
* Register accepted variables from used packages into the context.
|
|
17347
|
+
* Called after processing package use-package declarations.
|
|
17348
|
+
* @param context The expression context.
|
|
17349
|
+
*/
|
|
17350
|
+
registerAcceptedVariables(context) {
|
|
17351
|
+
return __async(this, null, function* () {
|
|
17352
|
+
if (!this.currentPackage) {
|
|
17353
|
+
return;
|
|
17354
|
+
}
|
|
17355
|
+
this.currentPackage.usedPackages.forEach((usedPkg, packageKey) => {
|
|
17356
|
+
usedPkg.acceptedComponents.forEach((component, componentKey) => {
|
|
17357
|
+
if (component.type === "variable" && component.name && component.isAccepted) {
|
|
17358
|
+
this.xsltVariable(context, component.node, false);
|
|
17359
|
+
}
|
|
17360
|
+
});
|
|
17361
|
+
});
|
|
17362
|
+
});
|
|
17363
|
+
}
|
|
16608
17364
|
/**
|
|
16609
17365
|
* Traverses the template node tree. Calls the main processing
|
|
16610
17366
|
* function with the current input context for every child node of the
|
|
@@ -16699,13 +17455,7 @@ var Xslt = class {
|
|
|
16699
17455
|
node = context.nodeList[context.position];
|
|
16700
17456
|
let newNode;
|
|
16701
17457
|
newNode = domCreateElement(this.outputDocument, template.nodeName);
|
|
16702
|
-
|
|
16703
|
-
newNode.siblingPosition = node.siblingPosition;
|
|
16704
|
-
} else if (node === void 0 && context.nodeList.length === 0) {
|
|
16705
|
-
newNode.siblingPosition = (output || this.outputDocument).childNodes.length;
|
|
16706
|
-
} else {
|
|
16707
|
-
newNode.siblingPosition = 0;
|
|
16708
|
-
}
|
|
17458
|
+
newNode.siblingPosition = (output || this.outputDocument).childNodes.length;
|
|
16709
17459
|
domAppendChild(output || this.outputDocument, newNode);
|
|
16710
17460
|
const useAttributeSetsAttr = template.childNodes.find(
|
|
16711
17461
|
(a) => (a == null ? void 0 : a.nodeType) === DOM_ATTRIBUTE_NODE && a.nodeName === "use-attribute-sets"
|
|
@@ -16944,7 +17694,7 @@ var Xslt = class {
|
|
|
16944
17694
|
* @param context The expression context.
|
|
16945
17695
|
*/
|
|
16946
17696
|
registerUserDefinedFunctionsInContext(context) {
|
|
16947
|
-
if (this.userDefinedFunctions.size === 0) {
|
|
17697
|
+
if (this.userDefinedFunctions.size === 0 && !this.hasAcceptedFunctions()) {
|
|
16948
17698
|
return;
|
|
16949
17699
|
}
|
|
16950
17700
|
const functionsMap = /* @__PURE__ */ new Map();
|
|
@@ -16956,8 +17706,48 @@ var Xslt = class {
|
|
|
16956
17706
|
}
|
|
16957
17707
|
});
|
|
16958
17708
|
});
|
|
17709
|
+
this.registerAcceptedFunctions(functionsMap);
|
|
16959
17710
|
context.userDefinedFunctions = functionsMap;
|
|
16960
17711
|
}
|
|
17712
|
+
/**
|
|
17713
|
+
* Check if there are any accepted functions in used packages.
|
|
17714
|
+
*/
|
|
17715
|
+
hasAcceptedFunctions() {
|
|
17716
|
+
if (!this.currentPackage) {
|
|
17717
|
+
return false;
|
|
17718
|
+
}
|
|
17719
|
+
let hasAccepted = false;
|
|
17720
|
+
this.currentPackage.usedPackages.forEach((usedPkg) => {
|
|
17721
|
+
usedPkg.acceptedComponents.forEach((component) => {
|
|
17722
|
+
if (component.type === "function" && component.isAccepted) {
|
|
17723
|
+
hasAccepted = true;
|
|
17724
|
+
}
|
|
17725
|
+
});
|
|
17726
|
+
});
|
|
17727
|
+
return hasAccepted;
|
|
17728
|
+
}
|
|
17729
|
+
/**
|
|
17730
|
+
* Register accepted functions from used packages.
|
|
17731
|
+
* @param functionsMap The map to register functions into.
|
|
17732
|
+
*/
|
|
17733
|
+
registerAcceptedFunctions(functionsMap) {
|
|
17734
|
+
if (!this.currentPackage) {
|
|
17735
|
+
return;
|
|
17736
|
+
}
|
|
17737
|
+
this.currentPackage.usedPackages.forEach((usedPkg, packageKey) => {
|
|
17738
|
+
usedPkg.acceptedComponents.forEach((component, componentKey) => {
|
|
17739
|
+
if (component.type === "function" && component.name && component.isAccepted) {
|
|
17740
|
+
const effectiveComponent = this.getEffectiveComponent(component);
|
|
17741
|
+
functionsMap.set(component.name, {
|
|
17742
|
+
functionDef: effectiveComponent.node,
|
|
17743
|
+
executor: (ctx, funcDef, args) => {
|
|
17744
|
+
return this.executeUserDefinedFunctionSync(ctx, funcDef, args);
|
|
17745
|
+
}
|
|
17746
|
+
});
|
|
17747
|
+
}
|
|
17748
|
+
});
|
|
17749
|
+
});
|
|
17750
|
+
}
|
|
16961
17751
|
/**
|
|
16962
17752
|
* Apply one or more attribute sets to an element.
|
|
16963
17753
|
* Parses space-separated attribute set names and applies them.
|