@doenet/v06-to-v07 0.7.26-dev.571 → 0.7.26-dev.573
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/apply-assign-name-renames.d.ts +14 -0
- package/apply-assign-name-renames.d.ts.map +1 -0
- package/assign-names/apply-renames.d.ts +21 -0
- package/assign-names/apply-renames.d.ts.map +1 -0
- package/assign-names/break-into-pieces.d.ts +34 -0
- package/assign-names/break-into-pieces.d.ts.map +1 -0
- package/assign-names/composite-info.d.ts +61 -0
- package/assign-names/composite-info.d.ts.map +1 -0
- package/assign-names/context.d.ts +103 -0
- package/assign-names/context.d.ts.map +1 -0
- package/assign-names/prop-access-parts.d.ts +14 -0
- package/assign-names/prop-access-parts.d.ts.map +1 -0
- package/assign-names/register-assign-names.d.ts +38 -0
- package/assign-names/register-assign-names.d.ts.map +1 -0
- package/assign-names/register-composite.d.ts +26 -0
- package/assign-names/register-composite.d.ts.map +1 -0
- package/assign-names/rename-registry.d.ts +90 -0
- package/assign-names/rename-registry.d.ts.map +1 -0
- package/assign-names/visit-all.d.ts +35 -0
- package/assign-names/visit-all.d.ts.map +1 -0
- package/core-info/core.d.ts +1 -0
- package/core-info/core.d.ts.map +1 -1
- package/core-info/determine-prop-type.d.ts +9 -0
- package/core-info/determine-prop-type.d.ts.map +1 -1
- package/{index-Cxf3BQNw.js → index-4M4L_2sg.js} +2286 -318
- package/{index-Cxf3BQNw.js.map → index-4M4L_2sg.js.map} +1 -1
- package/index.d.ts.map +1 -1
- package/index.js +1 -1
- package/normalize-capitalization.d.ts.map +1 -1
- package/package.json +1 -1
- package/{sha256-8sXzDnE0-hQwEEL17-DD-3Noo4.js → sha256-8sXzDnE0-BtProggv-BVCPcIg2.js} +2 -2
- package/{sha256-8sXzDnE0-hQwEEL17-DD-3Noo4.js.map → sha256-8sXzDnE0-BtProggv-BVCPcIg2.js.map} +1 -1
- package/slash-to-dot.d.ts.map +1 -1
- package/upgrade-assign-names.d.ts +32 -0
- package/upgrade-assign-names.d.ts.map +1 -0
- package/upgrade-attribute-syntax.d.ts +4 -1
- package/upgrade-attribute-syntax.d.ts.map +1 -1
- package/upgrade-collect-element.d.ts +4 -1
- package/upgrade-collect-element.d.ts.map +1 -1
- package/upgrade-copy-elements.d.ts +45 -0
- package/upgrade-copy-elements.d.ts.map +1 -0
- package/upgrade-copy-syntax.d.ts.map +1 -1
- package/upgrade-deprecated-attributes.d.ts +12 -0
- package/upgrade-deprecated-attributes.d.ts.map +1 -0
- package/upgrade-list-props.d.ts +4 -0
- package/upgrade-list-props.d.ts.map +1 -0
- package/upgrade-map-element.d.ts +4 -1
- package/upgrade-map-element.d.ts.map +1 -1
- package/upgrade-module-element.d.ts.map +1 -1
- package/utils.d.ts +34 -2
- package/utils.d.ts.map +1 -1
|
@@ -1849,16 +1849,16 @@ function findNodesWithPositionInfo(nodes) {
|
|
|
1849
1849
|
}
|
|
1850
1850
|
return ret;
|
|
1851
1851
|
}
|
|
1852
|
-
function macroToString(node) {
|
|
1852
|
+
function macroToString(node, forceParens = false) {
|
|
1853
1853
|
if (Array.isArray(node)) {
|
|
1854
|
-
return node
|
|
1854
|
+
return arrayToString(node);
|
|
1855
1855
|
}
|
|
1856
1856
|
switch (node.type) {
|
|
1857
1857
|
case "macro": {
|
|
1858
1858
|
const macro = unwrappedMacroToString$1(node);
|
|
1859
1859
|
let start = "$";
|
|
1860
1860
|
let end = "";
|
|
1861
|
-
if (macroNeedsParens$1(node)) {
|
|
1861
|
+
if (macroNeedsParens$1(node) || forceParens) {
|
|
1862
1862
|
start += "(";
|
|
1863
1863
|
end += ")";
|
|
1864
1864
|
}
|
|
@@ -1868,11 +1868,11 @@ function macroToString(node) {
|
|
|
1868
1868
|
const macro = unwrappedMacroToString$1(node.macro);
|
|
1869
1869
|
let start = "$$";
|
|
1870
1870
|
let end = "";
|
|
1871
|
-
if (macroNeedsParens$1(node)) {
|
|
1871
|
+
if (macroNeedsParens$1(node) || forceParens) {
|
|
1872
1872
|
start += "(";
|
|
1873
1873
|
end += ")";
|
|
1874
1874
|
}
|
|
1875
|
-
const args = node.input ? `(${node.input.map(macroToString).join(", ")})` : "";
|
|
1875
|
+
const args = node.input ? `(${node.input.map((arg) => macroToString(arg)).join(", ")})` : "";
|
|
1876
1876
|
return start + macro + end + args;
|
|
1877
1877
|
}
|
|
1878
1878
|
case "text":
|
|
@@ -1898,12 +1898,29 @@ function macroPathToString$1(path) {
|
|
|
1898
1898
|
function macroPathPartToString$1(pathPart) {
|
|
1899
1899
|
return pathPart.name + pathPart.index.map((part) => `[${macroToString(part.value)}]`).join("");
|
|
1900
1900
|
}
|
|
1901
|
+
function arrayToString(nodes) {
|
|
1902
|
+
const parts = nodes.map((n2) => macroToString(n2));
|
|
1903
|
+
let nextChar = "";
|
|
1904
|
+
for (let i2 = parts.length - 1; i2 >= 0; i2--) {
|
|
1905
|
+
const child = nodes[i2];
|
|
1906
|
+
if ((child.type === "macro" || child.type === "function") && isNameChar$1(nextChar) && isNameChar$1(parts[i2].slice(-1))) {
|
|
1907
|
+
parts[i2] = macroToString(child, true);
|
|
1908
|
+
}
|
|
1909
|
+
if (parts[i2]) {
|
|
1910
|
+
nextChar = parts[i2][0];
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
return parts.join("");
|
|
1914
|
+
}
|
|
1915
|
+
function isNameChar$1(char) {
|
|
1916
|
+
return /^[a-zA-Z0-9_]$/.test(char);
|
|
1917
|
+
}
|
|
1901
1918
|
function attrToString$1(attr) {
|
|
1902
1919
|
const name2 = attr.name;
|
|
1903
1920
|
if (attr.children.length === 0) {
|
|
1904
1921
|
return name2;
|
|
1905
1922
|
}
|
|
1906
|
-
const value = attr.children
|
|
1923
|
+
const value = arrayToString(attr.children);
|
|
1907
1924
|
return `${name2}=${quote(value)}`;
|
|
1908
1925
|
}
|
|
1909
1926
|
function macroNeedsParens$1(macro) {
|
|
@@ -1923,10 +1940,22 @@ function toXml(tree, options) {
|
|
|
1923
1940
|
const node = Array.isArray(tree) ? { type: "root", children: tree } : tree;
|
|
1924
1941
|
return nodesToXml(node, options);
|
|
1925
1942
|
}
|
|
1926
|
-
function nodesToXml(node, options) {
|
|
1943
|
+
function nodesToXml(node, options, forceParens = false) {
|
|
1927
1944
|
if (Array.isArray(node)) {
|
|
1928
1945
|
if (!node.some((n2) => n2.type === "pathPart")) {
|
|
1929
|
-
|
|
1946
|
+
const children = mergeAdjacentTextInArray(node);
|
|
1947
|
+
const parts = children.map((child) => nodesToXml(child, options));
|
|
1948
|
+
let nextChar = "";
|
|
1949
|
+
for (let i2 = parts.length - 1; i2 >= 0; i2--) {
|
|
1950
|
+
const child = children[i2];
|
|
1951
|
+
if ((child.type === "macro" || child.type === "function") && isNameChar(nextChar) && isNameChar(parts[i2].slice(-1))) {
|
|
1952
|
+
parts[i2] = nodesToXml(child, options, true);
|
|
1953
|
+
}
|
|
1954
|
+
if (parts[i2]) {
|
|
1955
|
+
nextChar = parts[i2][0];
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
return parts.join("");
|
|
1930
1959
|
} else {
|
|
1931
1960
|
return node.map((part) => nodesToXml(part, options)).join(".");
|
|
1932
1961
|
}
|
|
@@ -2011,12 +2040,12 @@ function nodesToXml(node, options) {
|
|
|
2011
2040
|
}
|
|
2012
2041
|
case "macro": {
|
|
2013
2042
|
if (node.version === "0.6") {
|
|
2014
|
-
return macroToString(node);
|
|
2043
|
+
return macroToString(node, forceParens);
|
|
2015
2044
|
}
|
|
2016
2045
|
const macro = unwrappedMacroToString(node, options);
|
|
2017
2046
|
let start = "$";
|
|
2018
2047
|
let end = "";
|
|
2019
|
-
if (macroNeedsParens(node)) {
|
|
2048
|
+
if (macroNeedsParens(node) || forceParens) {
|
|
2020
2049
|
start += "(";
|
|
2021
2050
|
end += ")";
|
|
2022
2051
|
}
|
|
@@ -2024,12 +2053,12 @@ function nodesToXml(node, options) {
|
|
|
2024
2053
|
}
|
|
2025
2054
|
case "function": {
|
|
2026
2055
|
if (node.version === "0.6") {
|
|
2027
|
-
return macroToString(node);
|
|
2056
|
+
return macroToString(node, forceParens);
|
|
2028
2057
|
}
|
|
2029
2058
|
const macro = unwrappedMacroToString(node, options);
|
|
2030
2059
|
let start = "$$";
|
|
2031
2060
|
let end = "";
|
|
2032
|
-
if (macroNeedsParens(node)) {
|
|
2061
|
+
if (macroNeedsParens(node) || forceParens) {
|
|
2033
2062
|
start += "(";
|
|
2034
2063
|
end += ")";
|
|
2035
2064
|
}
|
|
@@ -2082,6 +2111,9 @@ function attrToString(attr, options) {
|
|
|
2082
2111
|
function macroNeedsParens(macro) {
|
|
2083
2112
|
return macro.path.some((part) => part.name.includes("-"));
|
|
2084
2113
|
}
|
|
2114
|
+
function isNameChar(char) {
|
|
2115
|
+
return /^[a-zA-Z0-9_]$/.test(char);
|
|
2116
|
+
}
|
|
2085
2117
|
const StartTag = 1, StartCloseTag = 2, MissingCloseTag = 3, mismatchedStartCloseTag = 4, incompleteStartCloseTag = 5, commentContent$1 = 36, piContent$1 = 37, cdataContent$1 = 38, Text$1 = 7, Element = 12, EndTag = 13, OpenTag = 14, TagName = 15, Attribute = 16, AttributeValue = 19, CloseTag = 20, SelfCloseEndTag = 21, SelfClosingTag = 22, MismatchedCloseTag = 25;
|
|
2086
2118
|
const DefaultBufferLength = 1024;
|
|
2087
2119
|
let nextPropID = 0;
|
|
@@ -31765,7 +31797,7 @@ var init_before = __esmMin((() => {
|
|
|
31765
31797
|
})), once_default, init_once = __esmMin((() => {
|
|
31766
31798
|
init_partial(), init_before(), once_default = partial(before, 2);
|
|
31767
31799
|
}));
|
|
31768
|
-
function findKey(t4, n2, r2) {
|
|
31800
|
+
function findKey$2(t4, n2, r2) {
|
|
31769
31801
|
n2 = cb(n2, r2);
|
|
31770
31802
|
for (var i2 = keys$1(t4), a2, o2 = 0, s2 = i2.length; o2 < s2; o2++) if (a2 = i2[o2], n2(t4[a2], a2, t4)) return a2;
|
|
31771
31803
|
}
|
|
@@ -31815,7 +31847,7 @@ var init__createIndexFinder = __esmMin((() => {
|
|
|
31815
31847
|
init_findLastIndex(), init__createIndexFinder(), lastIndexOf_default = createIndexFinder(-1, findLastIndex_default);
|
|
31816
31848
|
}));
|
|
31817
31849
|
function find$1(t4, n2, r2) {
|
|
31818
|
-
var i2 = (_isArrayLike_default(t4) ? findIndex_default : findKey)(t4, n2, r2);
|
|
31850
|
+
var i2 = (_isArrayLike_default(t4) ? findIndex_default : findKey$2)(t4, n2, r2);
|
|
31819
31851
|
if (i2 !== void 0 && i2 !== -1) return t4[i2];
|
|
31820
31852
|
}
|
|
31821
31853
|
var init_find = __esmMin((() => {
|
|
@@ -32199,11 +32231,11 @@ var init_mixin = __esmMin((() => {
|
|
|
32199
32231
|
return t5 != null && (t5 = n2.apply(t5, arguments)), chainResult(this, t5);
|
|
32200
32232
|
};
|
|
32201
32233
|
}), underscore_array_methods_default = _$1$1;
|
|
32202
|
-
})), modules_exports = __exportAll({ VERSION: () => VERSION, after: () => after, all: () => every$1, allKeys: () => allKeys, any: () => some$1, assign: () => extendOwn_default, before: () => before, bind: () => bind_default, bindAll: () => bindAll_default, chain: () => chain, chunk: () => chunk, clone: () => clone, collect: () => map$2, compact: () => compact$1, compose: () => compose, constant: () => constant, contains: () => contains$1, countBy: () => countBy_default, create: () => create, debounce: () => debounce, default: () => underscore_array_methods_default, defaults: () => defaults_default, defer: () => defer_default, delay: () => delay_default, detect: () => find$1, difference: () => difference_default, drop: () => rest, each: () => each, escape: () => escape_default, every: () => every$1, extend: () => extend_default, extendOwn: () => extendOwn_default, filter: () => filter$2, find: () => find$1, findIndex: () => findIndex_default, findKey: () => findKey, findLastIndex: () => findLastIndex_default, findWhere: () => findWhere, first: () => first$2, flatten: () => flatten$2, foldl: () => reduce_default, foldr: () => reduceRight_default, forEach: () => each, functions: () => functions$1, get: () => get, groupBy: () => groupBy_default, has: () => has$2, head: () => first$2, identity: () => identity, include: () => contains$1, includes: () => contains$1, indexBy: () => indexBy_default, indexOf: () => indexOf_default, initial: () => initial, inject: () => reduce_default, intersection: () => intersection, invert: () => invert, invoke: () => invoke_default, isArguments: () => isArguments_default, isArray: () => isArray_default, isArrayBuffer: () => isArrayBuffer_default, isBoolean: () => isBoolean$2, isDataView: () => isDataView_default, isDate: () => isDate_default, isElement: () => isElement, isEmpty: () => isEmpty$1, isEqual: () => isEqual, isError: () => isError_default, isFinite: () => isFinite$1, isFunction: () => isFunction_default, isMap: () => isMap_default, isMatch: () => isMatch, isNaN: () => isNaN$1, isNull: () => isNull, isNumber: () => isNumber_default, isObject: () => isObject$2, isRegExp: () => isRegExp_default, isSet: () => isSet_default, isString: () => isString_default, isSymbol: () => isSymbol_default, isTypedArray: () => isTypedArray_default, isUndefined: () => isUndefined$2, isWeakMap: () => isWeakMap_default, isWeakSet: () => isWeakSet_default, iteratee: () => iteratee, keys: () => keys$1, last: () => last$1, lastIndexOf: () => lastIndexOf_default, map: () => map$2, mapObject: () => mapObject, matcher: () => matcher, matches: () => matcher, max: () => max$2, memoize: () => memoize$2, methods: () => functions$1, min: () => min$2, mixin: () => mixin, negate: () => negate, noop: () => noop, now: () => now_default, object: () => object, omit: () => omit_default, once: () => once_default, pairs: () => pairs, partial: () => partial, partition: () => partition_default, pick: () => pick_default, pluck: () => pluck, property: () => property, propertyOf: () => propertyOf, random: () => random, range: () => range, reduce: () => reduce_default, reduceRight: () => reduceRight_default, reject: () => reject$1, rest: () => rest, restArguments: () => restArguments, result: () => result, sample: () => sample, select: () => filter$2, shuffle: () => shuffle, size: () => size, some: () => some$1, sortBy: () => sortBy, sortedIndex: () => sortedIndex, tail: () => rest, take: () => first$2, tap: () => tap, template: () => template, templateSettings: () => templateSettings_default, throttle: () => throttle, times: () => times, toArray: () => toArray, toPath: () => toPath$1, transpose: () => unzip, unescape: () => unescape_default, union: () => union_default, uniq: () => uniq$1, unique: () => uniq$1, uniqueId: () => uniqueId, unzip: () => unzip, values: () => values$2, where: () => where, without: () => without_default, wrap: () => wrap, zip: () => zip_default }), init_modules = __esmMin((() => {
|
|
32234
|
+
})), modules_exports = __exportAll({ VERSION: () => VERSION, after: () => after, all: () => every$1, allKeys: () => allKeys, any: () => some$1, assign: () => extendOwn_default, before: () => before, bind: () => bind_default, bindAll: () => bindAll_default, chain: () => chain, chunk: () => chunk, clone: () => clone, collect: () => map$2, compact: () => compact$1, compose: () => compose, constant: () => constant, contains: () => contains$1, countBy: () => countBy_default, create: () => create, debounce: () => debounce, default: () => underscore_array_methods_default, defaults: () => defaults_default, defer: () => defer_default, delay: () => delay_default, detect: () => find$1, difference: () => difference_default, drop: () => rest, each: () => each, escape: () => escape_default, every: () => every$1, extend: () => extend_default, extendOwn: () => extendOwn_default, filter: () => filter$2, find: () => find$1, findIndex: () => findIndex_default, findKey: () => findKey$2, findLastIndex: () => findLastIndex_default, findWhere: () => findWhere, first: () => first$2, flatten: () => flatten$2, foldl: () => reduce_default, foldr: () => reduceRight_default, forEach: () => each, functions: () => functions$1, get: () => get, groupBy: () => groupBy_default, has: () => has$2, head: () => first$2, identity: () => identity, include: () => contains$1, includes: () => contains$1, indexBy: () => indexBy_default, indexOf: () => indexOf_default, initial: () => initial, inject: () => reduce_default, intersection: () => intersection, invert: () => invert, invoke: () => invoke_default, isArguments: () => isArguments_default, isArray: () => isArray_default, isArrayBuffer: () => isArrayBuffer_default, isBoolean: () => isBoolean$2, isDataView: () => isDataView_default, isDate: () => isDate_default, isElement: () => isElement, isEmpty: () => isEmpty$1, isEqual: () => isEqual, isError: () => isError_default, isFinite: () => isFinite$1, isFunction: () => isFunction_default, isMap: () => isMap_default, isMatch: () => isMatch, isNaN: () => isNaN$1, isNull: () => isNull, isNumber: () => isNumber_default, isObject: () => isObject$2, isRegExp: () => isRegExp_default, isSet: () => isSet_default, isString: () => isString_default, isSymbol: () => isSymbol_default, isTypedArray: () => isTypedArray_default, isUndefined: () => isUndefined$2, isWeakMap: () => isWeakMap_default, isWeakSet: () => isWeakSet_default, iteratee: () => iteratee, keys: () => keys$1, last: () => last$1, lastIndexOf: () => lastIndexOf_default, map: () => map$2, mapObject: () => mapObject, matcher: () => matcher, matches: () => matcher, max: () => max$2, memoize: () => memoize$2, methods: () => functions$1, min: () => min$2, mixin: () => mixin, negate: () => negate, noop: () => noop, now: () => now_default, object: () => object, omit: () => omit_default, once: () => once_default, pairs: () => pairs, partial: () => partial, partition: () => partition_default, pick: () => pick_default, pluck: () => pluck, property: () => property, propertyOf: () => propertyOf, random: () => random, range: () => range, reduce: () => reduce_default, reduceRight: () => reduceRight_default, reject: () => reject$1, rest: () => rest, restArguments: () => restArguments, result: () => result, sample: () => sample, select: () => filter$2, shuffle: () => shuffle, size: () => size, some: () => some$1, sortBy: () => sortBy, sortedIndex: () => sortedIndex, tail: () => rest, take: () => first$2, tap: () => tap, template: () => template, templateSettings: () => templateSettings_default, throttle: () => throttle, times: () => times, toArray: () => toArray, toPath: () => toPath$1, transpose: () => unzip, unescape: () => unescape_default, union: () => union_default, uniq: () => uniq$1, unique: () => uniq$1, uniqueId: () => uniqueId, unzip: () => unzip, values: () => values$2, where: () => where, without: () => without_default, wrap: () => wrap, zip: () => zip_default }), init_modules = __esmMin((() => {
|
|
32203
32235
|
init__setup(), init_restArguments(), init_isObject(), init_isNull(), init_isUndefined(), init_isBoolean(), init_isElement(), init_isString(), init_isNumber(), init_isDate(), init_isRegExp(), init_isError(), init_isSymbol(), init_isArrayBuffer(), init_isDataView(), init_isArray(), init_isFunction(), init_isArguments(), init_isFinite(), init_isNaN(), init_isTypedArray(), init_isEmpty(), init_isMatch(), init_isEqual(), init_isMap(), init_isWeakMap(), init_isSet(), init_isWeakSet(), init_keys(), init_allKeys(), init_values(), init_pairs(), init_invert(), init_functions(), init_extend(), init_extendOwn(), init_defaults(), init_create(), init_clone(), init_tap(), init_get(), init_has(), init_mapObject(), init_identity(), init_constant(), init_noop(), init_toPath(), init_property(), init_propertyOf(), init_matcher(), init_times(), init_random(), init_now(), init_escape(), init_unescape(), init_templateSettings(), init_template(), init_result(), init_uniqueId(), init_chain(), init_iteratee(), init_partial(), init_bind(), init_bindAll(), init_memoize(), init_delay(), init_defer(), init_throttle(), init_debounce(), init_wrap(), init_negate(), init_compose(), init_after(), init_before(), init_once(), init_findKey(), init_findIndex(), init_findLastIndex(), init_sortedIndex(), init_indexOf(), init_lastIndexOf(), init_find(), init_findWhere(), init_each(), init_map(), init_reduce(), init_reduceRight(), init_filter(), init_reject(), init_every(), init_some(), init_contains(), init_invoke(), init_pluck(), init_where(), init_max(), init_min(), init_shuffle(), init_sample(), init_sortBy(), init_groupBy(), init_indexBy(), init_countBy(), init_partition(), init_toArray(), init_size(), init_pick(), init_omit(), init_first(), init_initial(), init_last(), init_rest(), init_compact(), init_flatten(), init_without(), init_uniq(), init_union(), init_intersection(), init_difference(), init_unzip(), init_zip(), init_object(), init_range(), init_chunk(), init_mixin(), init_underscore_array_methods();
|
|
32204
32236
|
})), _$2, init_index_default = __esmMin((() => {
|
|
32205
32237
|
init_modules(), _$2 = mixin(modules_exports), _$2._ = _$2;
|
|
32206
|
-
})), index_all_exports = __exportAll({ VERSION: () => VERSION, after: () => after, all: () => every$1, allKeys: () => allKeys, any: () => some$1, assign: () => extendOwn_default, before: () => before, bind: () => bind_default, bindAll: () => bindAll_default, chain: () => chain, chunk: () => chunk, clone: () => clone, collect: () => map$2, compact: () => compact$1, compose: () => compose, constant: () => constant, contains: () => contains$1, countBy: () => countBy_default, create: () => create, debounce: () => debounce, default: () => _$2, defaults: () => defaults_default, defer: () => defer_default, delay: () => delay_default, detect: () => find$1, difference: () => difference_default, drop: () => rest, each: () => each, escape: () => escape_default, every: () => every$1, extend: () => extend_default, extendOwn: () => extendOwn_default, filter: () => filter$2, find: () => find$1, findIndex: () => findIndex_default, findKey: () => findKey, findLastIndex: () => findLastIndex_default, findWhere: () => findWhere, first: () => first$2, flatten: () => flatten$2, foldl: () => reduce_default, foldr: () => reduceRight_default, forEach: () => each, functions: () => functions$1, get: () => get, groupBy: () => groupBy_default, has: () => has$2, head: () => first$2, identity: () => identity, include: () => contains$1, includes: () => contains$1, indexBy: () => indexBy_default, indexOf: () => indexOf_default, initial: () => initial, inject: () => reduce_default, intersection: () => intersection, invert: () => invert, invoke: () => invoke_default, isArguments: () => isArguments_default, isArray: () => isArray_default, isArrayBuffer: () => isArrayBuffer_default, isBoolean: () => isBoolean$2, isDataView: () => isDataView_default, isDate: () => isDate_default, isElement: () => isElement, isEmpty: () => isEmpty$1, isEqual: () => isEqual, isError: () => isError_default, isFinite: () => isFinite$1, isFunction: () => isFunction_default, isMap: () => isMap_default, isMatch: () => isMatch, isNaN: () => isNaN$1, isNull: () => isNull, isNumber: () => isNumber_default, isObject: () => isObject$2, isRegExp: () => isRegExp_default, isSet: () => isSet_default, isString: () => isString_default, isSymbol: () => isSymbol_default, isTypedArray: () => isTypedArray_default, isUndefined: () => isUndefined$2, isWeakMap: () => isWeakMap_default, isWeakSet: () => isWeakSet_default, iteratee: () => iteratee, keys: () => keys$1, last: () => last$1, lastIndexOf: () => lastIndexOf_default, map: () => map$2, mapObject: () => mapObject, matcher: () => matcher, matches: () => matcher, max: () => max$2, memoize: () => memoize$2, methods: () => functions$1, min: () => min$2, mixin: () => mixin, negate: () => negate, noop: () => noop, now: () => now_default, object: () => object, omit: () => omit_default, once: () => once_default, pairs: () => pairs, partial: () => partial, partition: () => partition_default, pick: () => pick_default, pluck: () => pluck, property: () => property, propertyOf: () => propertyOf, random: () => random, range: () => range, reduce: () => reduce_default, reduceRight: () => reduceRight_default, reject: () => reject$1, rest: () => rest, restArguments: () => restArguments, result: () => result, sample: () => sample, select: () => filter$2, shuffle: () => shuffle, size: () => size, some: () => some$1, sortBy: () => sortBy, sortedIndex: () => sortedIndex, tail: () => rest, take: () => first$2, tap: () => tap, template: () => template, templateSettings: () => templateSettings_default, throttle: () => throttle, times: () => times, toArray: () => toArray, toPath: () => toPath$1, transpose: () => unzip, unescape: () => unescape_default, union: () => union_default, uniq: () => uniq$1, unique: () => uniq$1, uniqueId: () => uniqueId, unzip: () => unzip, values: () => values$2, where: () => where, without: () => without_default, wrap: () => wrap, zip: () => zip_default }), init_index_all = __esmMin((() => {
|
|
32238
|
+
})), index_all_exports = __exportAll({ VERSION: () => VERSION, after: () => after, all: () => every$1, allKeys: () => allKeys, any: () => some$1, assign: () => extendOwn_default, before: () => before, bind: () => bind_default, bindAll: () => bindAll_default, chain: () => chain, chunk: () => chunk, clone: () => clone, collect: () => map$2, compact: () => compact$1, compose: () => compose, constant: () => constant, contains: () => contains$1, countBy: () => countBy_default, create: () => create, debounce: () => debounce, default: () => _$2, defaults: () => defaults_default, defer: () => defer_default, delay: () => delay_default, detect: () => find$1, difference: () => difference_default, drop: () => rest, each: () => each, escape: () => escape_default, every: () => every$1, extend: () => extend_default, extendOwn: () => extendOwn_default, filter: () => filter$2, find: () => find$1, findIndex: () => findIndex_default, findKey: () => findKey$2, findLastIndex: () => findLastIndex_default, findWhere: () => findWhere, first: () => first$2, flatten: () => flatten$2, foldl: () => reduce_default, foldr: () => reduceRight_default, forEach: () => each, functions: () => functions$1, get: () => get, groupBy: () => groupBy_default, has: () => has$2, head: () => first$2, identity: () => identity, include: () => contains$1, includes: () => contains$1, indexBy: () => indexBy_default, indexOf: () => indexOf_default, initial: () => initial, inject: () => reduce_default, intersection: () => intersection, invert: () => invert, invoke: () => invoke_default, isArguments: () => isArguments_default, isArray: () => isArray_default, isArrayBuffer: () => isArrayBuffer_default, isBoolean: () => isBoolean$2, isDataView: () => isDataView_default, isDate: () => isDate_default, isElement: () => isElement, isEmpty: () => isEmpty$1, isEqual: () => isEqual, isError: () => isError_default, isFinite: () => isFinite$1, isFunction: () => isFunction_default, isMap: () => isMap_default, isMatch: () => isMatch, isNaN: () => isNaN$1, isNull: () => isNull, isNumber: () => isNumber_default, isObject: () => isObject$2, isRegExp: () => isRegExp_default, isSet: () => isSet_default, isString: () => isString_default, isSymbol: () => isSymbol_default, isTypedArray: () => isTypedArray_default, isUndefined: () => isUndefined$2, isWeakMap: () => isWeakMap_default, isWeakSet: () => isWeakSet_default, iteratee: () => iteratee, keys: () => keys$1, last: () => last$1, lastIndexOf: () => lastIndexOf_default, map: () => map$2, mapObject: () => mapObject, matcher: () => matcher, matches: () => matcher, max: () => max$2, memoize: () => memoize$2, methods: () => functions$1, min: () => min$2, mixin: () => mixin, negate: () => negate, noop: () => noop, now: () => now_default, object: () => object, omit: () => omit_default, once: () => once_default, pairs: () => pairs, partial: () => partial, partition: () => partition_default, pick: () => pick_default, pluck: () => pluck, property: () => property, propertyOf: () => propertyOf, random: () => random, range: () => range, reduce: () => reduce_default, reduceRight: () => reduceRight_default, reject: () => reject$1, rest: () => rest, restArguments: () => restArguments, result: () => result, sample: () => sample, select: () => filter$2, shuffle: () => shuffle, size: () => size, some: () => some$1, sortBy: () => sortBy, sortedIndex: () => sortedIndex, tail: () => rest, take: () => first$2, tap: () => tap, template: () => template, templateSettings: () => templateSettings_default, throttle: () => throttle, times: () => times, toArray: () => toArray, toPath: () => toPath$1, transpose: () => unzip, unescape: () => unescape_default, union: () => union_default, uniq: () => uniq$1, unique: () => uniq$1, uniqueId: () => uniqueId, unzip: () => unzip, values: () => values$2, where: () => where, without: () => without_default, wrap: () => wrap, zip: () => zip_default }), init_index_all = __esmMin((() => {
|
|
32207
32239
|
init_index_default(), init_modules();
|
|
32208
32240
|
}));
|
|
32209
32241
|
init_index_all();
|
|
@@ -47324,7 +47356,7 @@ async function cidFromArrayBuffer(data) {
|
|
|
47324
47356
|
await crypto.subtle.digest("SHA-256", new Uint8Array());
|
|
47325
47357
|
digest = (data2) => crypto.subtle.digest("SHA-256", data2);
|
|
47326
47358
|
} catch (e22) {
|
|
47327
|
-
const sha256 = (await import("./sha256-8sXzDnE0-
|
|
47359
|
+
const sha256 = (await import("./sha256-8sXzDnE0-BtProggv-BVCPcIg2.js").then((n2) => n2.s)).default;
|
|
47328
47360
|
digest = (data2) => sha256(data2, {
|
|
47329
47361
|
asBytes: true
|
|
47330
47362
|
});
|
|
@@ -83761,6 +83793,97 @@ function aggregateCreditOverScoredDescendants(dependencyValues, variableName, cr
|
|
|
83761
83793
|
}
|
|
83762
83794
|
return totalWeight > 0 ? creditSum / totalWeight : creditWhenNothingScored;
|
|
83763
83795
|
}
|
|
83796
|
+
function aggregateCreditForCheckWork(dependencyValues) {
|
|
83797
|
+
const descendants = dependencyValues.scoredDescendants;
|
|
83798
|
+
const totalWeight = descendants.reduce(
|
|
83799
|
+
(sum2, descendant) => sum2 + descendant.stateValues.weight,
|
|
83800
|
+
0
|
|
83801
|
+
);
|
|
83802
|
+
const useUnitWeights = !(totalWeight > 0);
|
|
83803
|
+
const weightSum = useUnitWeights ? descendants.length : totalWeight;
|
|
83804
|
+
let creditSum = 0;
|
|
83805
|
+
for (const [ind, descendant] of descendants.entries()) {
|
|
83806
|
+
const { stateValues } = dependencyValues["creditForCheckWork" + ind];
|
|
83807
|
+
const credit = stateValues.creditAchievedForCheckWork ?? stateValues.creditAchieved;
|
|
83808
|
+
creditSum += credit * (useUnitWeights ? 1 : descendant.stateValues.weight);
|
|
83809
|
+
}
|
|
83810
|
+
return creditSum / weightSum;
|
|
83811
|
+
}
|
|
83812
|
+
function checkWorkCreditNeedsAggregating(stateValues, alwaysAggregate) {
|
|
83813
|
+
if (!stateValues.suppressAnswerSubmitButtons) {
|
|
83814
|
+
return false;
|
|
83815
|
+
}
|
|
83816
|
+
if (!alwaysAggregate && !stateValues.aggregateScores) {
|
|
83817
|
+
return false;
|
|
83818
|
+
}
|
|
83819
|
+
const descendants = stateValues.scoredDescendants;
|
|
83820
|
+
if (descendants.length === 0) {
|
|
83821
|
+
return false;
|
|
83822
|
+
}
|
|
83823
|
+
const anyPositiveWeight = descendants.some(
|
|
83824
|
+
(descendant) => descendant.stateValues.weight > 0
|
|
83825
|
+
);
|
|
83826
|
+
const anyAggregatingDescendant = descendants.some(
|
|
83827
|
+
// The same test `scoredDescendants` uses to tell a container it keeps
|
|
83828
|
+
// from a leaf it cannot look inside.
|
|
83829
|
+
(descendant) => descendant.stateValues.scoredDescendants !== void 0
|
|
83830
|
+
);
|
|
83831
|
+
return !anyPositiveWeight || anyAggregatingDescendant;
|
|
83832
|
+
}
|
|
83833
|
+
function returnCheckWorkCreditStateVariableDefinition({
|
|
83834
|
+
alwaysAggregate = false
|
|
83835
|
+
} = {}) {
|
|
83836
|
+
const stateVariablesDeterminingDependencies = [
|
|
83837
|
+
"suppressAnswerSubmitButtons",
|
|
83838
|
+
"scoredDescendants"
|
|
83839
|
+
];
|
|
83840
|
+
if (!alwaysAggregate) {
|
|
83841
|
+
stateVariablesDeterminingDependencies.push("aggregateScores");
|
|
83842
|
+
}
|
|
83843
|
+
return {
|
|
83844
|
+
forRenderer: true,
|
|
83845
|
+
defaultValue: null,
|
|
83846
|
+
stateVariablesDeterminingDependencies,
|
|
83847
|
+
returnDependencies({ stateValues }) {
|
|
83848
|
+
if (!checkWorkCreditNeedsAggregating(stateValues, alwaysAggregate)) {
|
|
83849
|
+
return {};
|
|
83850
|
+
}
|
|
83851
|
+
const dependencies2 = {
|
|
83852
|
+
scoredDescendants: {
|
|
83853
|
+
dependencyType: "stateVariable",
|
|
83854
|
+
variableName: "scoredDescendants"
|
|
83855
|
+
}
|
|
83856
|
+
};
|
|
83857
|
+
for (const [
|
|
83858
|
+
ind,
|
|
83859
|
+
descendant
|
|
83860
|
+
] of stateValues.scoredDescendants.entries()) {
|
|
83861
|
+
dependencies2["creditForCheckWork" + ind] = {
|
|
83862
|
+
dependencyType: "multipleStateVariables",
|
|
83863
|
+
componentIdx: descendant.componentIdx,
|
|
83864
|
+
variableNames: [
|
|
83865
|
+
"creditAchievedForCheckWork",
|
|
83866
|
+
"creditAchieved"
|
|
83867
|
+
],
|
|
83868
|
+
// An `<answer>` has only the latter, which is what its
|
|
83869
|
+
// check-work credit would be anyway.
|
|
83870
|
+
variablesOptional: true
|
|
83871
|
+
};
|
|
83872
|
+
}
|
|
83873
|
+
return dependencies2;
|
|
83874
|
+
},
|
|
83875
|
+
definition({ dependencyValues }) {
|
|
83876
|
+
if (dependencyValues.scoredDescendants === void 0) {
|
|
83877
|
+
return { setValue: { creditAchievedForCheckWork: null } };
|
|
83878
|
+
}
|
|
83879
|
+
return {
|
|
83880
|
+
setValue: {
|
|
83881
|
+
creditAchievedForCheckWork: aggregateCreditForCheckWork(dependencyValues)
|
|
83882
|
+
}
|
|
83883
|
+
};
|
|
83884
|
+
}
|
|
83885
|
+
};
|
|
83886
|
+
}
|
|
83764
83887
|
function returnScoredSectionAttributes() {
|
|
83765
83888
|
return {
|
|
83766
83889
|
aggregateScores: {
|
|
@@ -84215,6 +84338,7 @@ function returnScoredSectionStateVariableDefinition() {
|
|
|
84215
84338
|
};
|
|
84216
84339
|
}
|
|
84217
84340
|
};
|
|
84341
|
+
stateVariableDefinitions.creditAchievedForCheckWork = returnCheckWorkCreditStateVariableDefinition();
|
|
84218
84342
|
stateVariableDefinitions.creditAchievedIfSubmit = {
|
|
84219
84343
|
defaultValue: 0,
|
|
84220
84344
|
stateVariablesDeterminingDependencies: [
|
|
@@ -127352,6 +127476,11 @@ class Input extends InlineComponent {
|
|
|
127352
127476
|
componentIdx: stateValues.sectionDeterminingColorCorrectness,
|
|
127353
127477
|
variableNames: [
|
|
127354
127478
|
"justSubmitted",
|
|
127479
|
+
// The section colors its inputs by the same credit
|
|
127480
|
+
// its button reports, so the two can never disagree;
|
|
127481
|
+
// it is `null` wherever the score already says it,
|
|
127482
|
+
// hence the fallback below.
|
|
127483
|
+
"creditAchievedForCheckWork",
|
|
127355
127484
|
"creditAchieved",
|
|
127356
127485
|
"showCorrectness",
|
|
127357
127486
|
"colorCorrectness"
|
|
@@ -127494,7 +127623,7 @@ class Input extends InlineComponent {
|
|
|
127494
127623
|
let creditAchieved = 0;
|
|
127495
127624
|
const comp = dependencyValues.componentDeterminingDisplayedCorrectness;
|
|
127496
127625
|
if (comp) {
|
|
127497
|
-
const overallCredit = comp.stateValues.creditAchieved ?? 0;
|
|
127626
|
+
const overallCredit = comp.stateValues.creditAchievedForCheckWork ?? comp.stateValues.creditAchieved ?? 0;
|
|
127498
127627
|
const creditAchievedPerInput = dependencyValues.answerCreditAchievedPerInput?.stateValues.creditAchievedPerInput ?? (dependencyValues.answerColoringState?.stateValues?.colorInputsSeparately ? dependencyValues.answerColoringState.stateValues.creditAchievedPerInput : void 0);
|
|
127499
127628
|
if (comp.stateValues.colorInputsSeparately && creditAchievedPerInput) {
|
|
127500
127629
|
const key = `${componentIdx}/${variableForImplicitProp}`;
|
|
@@ -133101,6 +133230,9 @@ class Document extends BaseComponent {
|
|
|
133101
133230
|
return { setValue: { creditAchieved, percentCreditAchieved } };
|
|
133102
133231
|
}
|
|
133103
133232
|
};
|
|
133233
|
+
stateVariableDefinitions.creditAchievedForCheckWork = returnCheckWorkCreditStateVariableDefinition({
|
|
133234
|
+
alwaysAggregate: true
|
|
133235
|
+
});
|
|
133104
133236
|
stateVariableDefinitions.creditAchievedIfSubmit = {
|
|
133105
133237
|
defaultValue: 0,
|
|
133106
133238
|
stateVariablesDeterminingDependencies: ["scoredDescendants"],
|
|
@@ -244029,6 +244161,17 @@ const correctAttributeCapitalization = () => {
|
|
|
244029
244161
|
});
|
|
244030
244162
|
};
|
|
244031
244163
|
};
|
|
244164
|
+
const LEGACY_V06_ELEMENT_NAMES = [
|
|
244165
|
+
"copy",
|
|
244166
|
+
"map",
|
|
244167
|
+
"template",
|
|
244168
|
+
"sources",
|
|
244169
|
+
"extract",
|
|
244170
|
+
"customAttribute",
|
|
244171
|
+
"constraints",
|
|
244172
|
+
"styleDefinitions",
|
|
244173
|
+
"feedbackDefinitions"
|
|
244174
|
+
];
|
|
244032
244175
|
const correctElementCapitalization = () => {
|
|
244033
244176
|
const componentInfoObjects2 = createComponentInfoObjects();
|
|
244034
244177
|
const correctCapitalization = Object.keys(
|
|
@@ -244037,6 +244180,9 @@ const correctElementCapitalization = () => {
|
|
|
244037
244180
|
const correctCapitalizationMap = Object.fromEntries(
|
|
244038
244181
|
correctCapitalization.map((name2) => [name2.toLowerCase(), name2])
|
|
244039
244182
|
);
|
|
244183
|
+
for (const name2 of LEGACY_V06_ELEMENT_NAMES) {
|
|
244184
|
+
correctCapitalizationMap[name2.toLowerCase()] ??= name2;
|
|
244185
|
+
}
|
|
244040
244186
|
return (tree) => {
|
|
244041
244187
|
visit(tree, (node) => {
|
|
244042
244188
|
if (!isDastElement(node)) {
|
|
@@ -244097,34 +244243,6 @@ function renameAttrInPlace(elm, oldName, newName) {
|
|
|
244097
244243
|
);
|
|
244098
244244
|
elm.attributes = newAttrs;
|
|
244099
244245
|
}
|
|
244100
|
-
function getUniqueName(tree, baseName) {
|
|
244101
|
-
const allNames = /* @__PURE__ */ new Set();
|
|
244102
|
-
visit(tree, (node) => {
|
|
244103
|
-
if (!isDastElement(node)) {
|
|
244104
|
-
return;
|
|
244105
|
-
}
|
|
244106
|
-
if (node.attributes["name"]) {
|
|
244107
|
-
allNames.add(toXml(node.attributes["name"].children).trim());
|
|
244108
|
-
}
|
|
244109
|
-
if (node.attributes["assignNames"]) {
|
|
244110
|
-
const assignNames = toXml(
|
|
244111
|
-
node.attributes["assignNames"].children
|
|
244112
|
-
).trim();
|
|
244113
|
-
if (assignNames) {
|
|
244114
|
-
for (const name22 of assignNames.split(/\s+/)) {
|
|
244115
|
-
allNames.add(name22);
|
|
244116
|
-
}
|
|
244117
|
-
}
|
|
244118
|
-
}
|
|
244119
|
-
});
|
|
244120
|
-
let name2 = baseName;
|
|
244121
|
-
let i2 = 1;
|
|
244122
|
-
while (allNames.has(name2)) {
|
|
244123
|
-
name2 = `${baseName}${i2}`;
|
|
244124
|
-
i2++;
|
|
244125
|
-
}
|
|
244126
|
-
return name2;
|
|
244127
|
-
}
|
|
244128
244246
|
const componentInfoObjects = createComponentInfoObjects();
|
|
244129
244247
|
function determinePropType(componentType, propName, nIndices = 0) {
|
|
244130
244248
|
const publicStateVariableInfo = componentInfoObjects.publicStateVariableInfo[componentType];
|
|
@@ -244207,10 +244325,889 @@ function componentTypeFromWrapping(wrappingComponents, nDimensions, nIndices) {
|
|
|
244207
244325
|
}
|
|
244208
244326
|
return { foundComponentType: false };
|
|
244209
244327
|
}
|
|
244210
|
-
|
|
244328
|
+
function isModuleComponentType(componentType) {
|
|
244329
|
+
return componentInfoObjects.isInheritedComponentType({
|
|
244330
|
+
inheritedComponentType: componentType,
|
|
244331
|
+
baseComponentType: "module"
|
|
244332
|
+
});
|
|
244333
|
+
}
|
|
244334
|
+
function breakStringInPiecesBySpacesOrParens(string) {
|
|
244335
|
+
if (typeof string !== "string") {
|
|
244336
|
+
return { success: false };
|
|
244337
|
+
}
|
|
244338
|
+
let numParens = 0;
|
|
244339
|
+
const pieces = [];
|
|
244340
|
+
string = string.trim();
|
|
244341
|
+
let beginInd = 0;
|
|
244342
|
+
for (let ind = 0; ind < string.length; ind++) {
|
|
244343
|
+
const char = string[ind];
|
|
244344
|
+
if (char === "(") {
|
|
244345
|
+
if (numParens === 0) {
|
|
244346
|
+
const newPiece2 = string.substring(beginInd, ind).trim();
|
|
244347
|
+
if (newPiece2.length > 0) {
|
|
244348
|
+
pieces.push(newPiece2);
|
|
244349
|
+
}
|
|
244350
|
+
beginInd = ind;
|
|
244351
|
+
}
|
|
244352
|
+
numParens++;
|
|
244353
|
+
} else if (char === ")") {
|
|
244354
|
+
if (numParens === 0) {
|
|
244355
|
+
return { success: false };
|
|
244356
|
+
}
|
|
244357
|
+
if (numParens === 1) {
|
|
244358
|
+
const newPiece2 = string.substring(beginInd + 1, ind).trim();
|
|
244359
|
+
if (newPiece2.length > 0) {
|
|
244360
|
+
const result2 = breakStringInPiecesBySpacesOrParens(newPiece2);
|
|
244361
|
+
if (result2.success === true) {
|
|
244362
|
+
pieces.push(result2.pieces);
|
|
244363
|
+
} else {
|
|
244364
|
+
pieces.push(newPiece2);
|
|
244365
|
+
}
|
|
244366
|
+
}
|
|
244367
|
+
beginInd = ind + 1;
|
|
244368
|
+
}
|
|
244369
|
+
numParens--;
|
|
244370
|
+
} else if (numParens === 0 && char.match(/\s/)) {
|
|
244371
|
+
const newPiece2 = string.substring(beginInd, ind).trim();
|
|
244372
|
+
if (newPiece2.length > 0) {
|
|
244373
|
+
pieces.push(newPiece2);
|
|
244374
|
+
}
|
|
244375
|
+
beginInd = ind;
|
|
244376
|
+
}
|
|
244377
|
+
}
|
|
244378
|
+
if (numParens !== 0) {
|
|
244379
|
+
return { success: false };
|
|
244380
|
+
}
|
|
244381
|
+
const newPiece = string.substring(beginInd, string.length).trim();
|
|
244382
|
+
if (newPiece.length > 0) {
|
|
244383
|
+
pieces.push(newPiece);
|
|
244384
|
+
}
|
|
244385
|
+
return { success: true, pieces };
|
|
244386
|
+
}
|
|
244387
|
+
function firstLeafName(pieces) {
|
|
244388
|
+
for (const piece of pieces) {
|
|
244389
|
+
if (typeof piece === "string") {
|
|
244390
|
+
return piece;
|
|
244391
|
+
}
|
|
244392
|
+
const nested = firstLeafName(piece);
|
|
244393
|
+
if (nested !== void 0) {
|
|
244394
|
+
return nested;
|
|
244395
|
+
}
|
|
244396
|
+
}
|
|
244397
|
+
return void 0;
|
|
244398
|
+
}
|
|
244399
|
+
const VALID_REFERENCEABLE_NAME = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
|
|
244400
|
+
function isValidReferenceableName(name2) {
|
|
244401
|
+
return VALID_REFERENCEABLE_NAME.test(name2);
|
|
244402
|
+
}
|
|
244403
|
+
function makeIndexedPathPart(name2, indices) {
|
|
244404
|
+
return {
|
|
244405
|
+
type: "pathPart",
|
|
244406
|
+
name: name2,
|
|
244407
|
+
index: indices.map((i2) => ({
|
|
244408
|
+
type: "index",
|
|
244409
|
+
value: [{ type: "text", value: `${i2}` }]
|
|
244410
|
+
}))
|
|
244411
|
+
};
|
|
244412
|
+
}
|
|
244413
|
+
class RenameRegistry {
|
|
244414
|
+
constructor(existingNames = /* @__PURE__ */ new Set()) {
|
|
244415
|
+
this._renames = /* @__PURE__ */ new Map();
|
|
244416
|
+
this._matched = /* @__PURE__ */ new Set();
|
|
244417
|
+
this._existingNames = existingNames;
|
|
244418
|
+
}
|
|
244419
|
+
/**
|
|
244420
|
+
* Register that `oldName` should be replaced by `replacement` wherever it appears in
|
|
244421
|
+
* a macro path. The first registration of a name wins; a later one warns.
|
|
244422
|
+
*
|
|
244423
|
+
* Pass `undefined` for `replacement` to claim the name without rewriting anything,
|
|
244424
|
+
* which is what a composite that simply took the assigned name as its own `name`
|
|
244425
|
+
* needs: references already resolve, but a later composite assigning the same name
|
|
244426
|
+
* must not silently redirect them.
|
|
244427
|
+
*/
|
|
244428
|
+
register(oldName, replacement, origin, file) {
|
|
244429
|
+
if (!oldName) {
|
|
244430
|
+
return;
|
|
244431
|
+
}
|
|
244432
|
+
const existing = this._renames.get(oldName) ?? [];
|
|
244433
|
+
const scope = origin.ancestorNames ?? [];
|
|
244434
|
+
const sameScope = existing.find(
|
|
244435
|
+
(target) => sameScopeAs(target.origin.ancestorNames ?? [], scope)
|
|
244436
|
+
);
|
|
244437
|
+
if (sameScope) {
|
|
244438
|
+
file.message(
|
|
244439
|
+
`The name "${oldName}" is assigned by both <${sameScope.origin.elementName}> and <${origin.elementName}> in the same place; references to it were converted as if they referred to the first.`,
|
|
244440
|
+
{
|
|
244441
|
+
place: origin.position,
|
|
244442
|
+
ruleId: "assign-names/duplicate-name",
|
|
244443
|
+
source: "v06-to-v07"
|
|
244444
|
+
}
|
|
244445
|
+
);
|
|
244446
|
+
return;
|
|
244447
|
+
}
|
|
244448
|
+
if (existing.length === 0 && this._existingNames.has(oldName)) {
|
|
244449
|
+
file.message(
|
|
244450
|
+
`The name "${oldName}" assigned by <${origin.elementName}> is also used as the "name" of another component; all references to "${oldName}" were converted to point at the <${origin.elementName}> replacement.`,
|
|
244451
|
+
{
|
|
244452
|
+
place: origin.position,
|
|
244453
|
+
ruleId: "assign-names/shadows-existing-name",
|
|
244454
|
+
source: "v06-to-v07"
|
|
244455
|
+
}
|
|
244456
|
+
);
|
|
244457
|
+
}
|
|
244458
|
+
existing.push({ replacement, origin });
|
|
244459
|
+
this._renames.set(oldName, existing);
|
|
244460
|
+
}
|
|
244461
|
+
/**
|
|
244462
|
+
* The rename for `name`, chosen by which of them the reference is reaching into.
|
|
244463
|
+
*
|
|
244464
|
+
* `precedingNames` are the path parts written before it, so `$g2.a` looks up `a` with
|
|
244465
|
+
* `["g2"]`. The registration whose enclosing names are the longest match at the end of
|
|
244466
|
+
* that wins; one recorded with no enclosing names matches anything, which is what
|
|
244467
|
+
* keeps an unscoped document behaving exactly as before.
|
|
244468
|
+
*/
|
|
244469
|
+
get(name2, precedingNames = [], writtenOn) {
|
|
244470
|
+
const targets = this._renames.get(name2);
|
|
244471
|
+
if (!targets || targets.length === 0) {
|
|
244472
|
+
return void 0;
|
|
244473
|
+
}
|
|
244474
|
+
let best;
|
|
244475
|
+
let bestScore = -1;
|
|
244476
|
+
for (const target of targets) {
|
|
244477
|
+
if (writtenOn && target.origin.element === writtenOn) {
|
|
244478
|
+
continue;
|
|
244479
|
+
}
|
|
244480
|
+
const scope = target.origin.ancestorNames ?? [];
|
|
244481
|
+
if (!isSuffixOf(scope, precedingNames)) {
|
|
244482
|
+
continue;
|
|
244483
|
+
}
|
|
244484
|
+
if (scope.length > bestScore) {
|
|
244485
|
+
best = target;
|
|
244486
|
+
bestScore = scope.length;
|
|
244487
|
+
}
|
|
244488
|
+
}
|
|
244489
|
+
if (best) {
|
|
244490
|
+
this._matched.add(name2);
|
|
244491
|
+
}
|
|
244492
|
+
return best;
|
|
244493
|
+
}
|
|
244494
|
+
/** Whether `name` is registered *and* some registration rewrites references to it. */
|
|
244495
|
+
hasReplacement(name2) {
|
|
244496
|
+
return (this._renames.get(name2) ?? []).some(
|
|
244497
|
+
(target) => target.replacement !== void 0
|
|
244498
|
+
);
|
|
244499
|
+
}
|
|
244500
|
+
get size() {
|
|
244501
|
+
return this._renames.size;
|
|
244502
|
+
}
|
|
244503
|
+
/** Registered names that were never referenced anywhere in the document. */
|
|
244504
|
+
unused() {
|
|
244505
|
+
return [...this._renames.keys()].filter((n2) => !this._matched.has(n2));
|
|
244506
|
+
}
|
|
244507
|
+
}
|
|
244508
|
+
function sameScopeAs(a2, b2) {
|
|
244509
|
+
return a2.length === b2.length && a2.every((name2, i2) => name2 === b2[i2]);
|
|
244510
|
+
}
|
|
244511
|
+
function isSuffixOf(scope, path) {
|
|
244512
|
+
if (scope.length > path.length) {
|
|
244513
|
+
return false;
|
|
244514
|
+
}
|
|
244515
|
+
const offset = path.length - scope.length;
|
|
244516
|
+
return scope.every((name2, i2) => name2 === path[offset + i2]);
|
|
244517
|
+
}
|
|
244518
|
+
function collectExistingNames(tree) {
|
|
244519
|
+
const names = /* @__PURE__ */ new Set();
|
|
244520
|
+
visit(tree, (node) => {
|
|
244521
|
+
if (!isDastElement(node)) {
|
|
244522
|
+
return;
|
|
244523
|
+
}
|
|
244524
|
+
const nameAttr = Object.entries(node.attributes).find(
|
|
244525
|
+
([name2]) => name2.toLowerCase() === "name"
|
|
244526
|
+
)?.[1];
|
|
244527
|
+
if (nameAttr) {
|
|
244528
|
+
const name2 = toXml(nameAttr.children).trim();
|
|
244529
|
+
if (name2) {
|
|
244530
|
+
names.add(name2);
|
|
244531
|
+
}
|
|
244532
|
+
}
|
|
244533
|
+
});
|
|
244534
|
+
return names;
|
|
244535
|
+
}
|
|
244536
|
+
function collectAllNames(tree) {
|
|
244537
|
+
const names = collectExistingNames(tree);
|
|
244538
|
+
visit(tree, (node) => {
|
|
244539
|
+
if (!isDastElement(node)) {
|
|
244540
|
+
return;
|
|
244541
|
+
}
|
|
244542
|
+
const assignNamesAttr = Object.entries(node.attributes).find(
|
|
244543
|
+
([name2]) => name2.toLowerCase() === "assignnames"
|
|
244544
|
+
)?.[1];
|
|
244545
|
+
if (!assignNamesAttr) {
|
|
244546
|
+
return;
|
|
244547
|
+
}
|
|
244548
|
+
const assignNames = toXml(assignNamesAttr.children).trim();
|
|
244549
|
+
for (const name2 of assignNames.split(/[\s()]+/)) {
|
|
244550
|
+
if (name2) {
|
|
244551
|
+
names.add(name2);
|
|
244552
|
+
}
|
|
244553
|
+
}
|
|
244554
|
+
});
|
|
244555
|
+
return names;
|
|
244556
|
+
}
|
|
244557
|
+
function createUniqueNameFactory(tree) {
|
|
244558
|
+
const used = collectAllNames(tree);
|
|
244559
|
+
return (baseName) => {
|
|
244560
|
+
let name2 = baseName;
|
|
244561
|
+
let i2 = 1;
|
|
244562
|
+
while (used.has(name2)) {
|
|
244563
|
+
name2 = `${baseName}${i2}`;
|
|
244564
|
+
i2++;
|
|
244565
|
+
}
|
|
244566
|
+
used.add(name2);
|
|
244567
|
+
return name2;
|
|
244568
|
+
};
|
|
244569
|
+
}
|
|
244570
|
+
function isV06True(attr) {
|
|
244571
|
+
if (!attr) {
|
|
244572
|
+
return false;
|
|
244573
|
+
}
|
|
244574
|
+
const value = toXml(attr.children).trim().toLowerCase();
|
|
244575
|
+
return value === "" || value === "true";
|
|
244576
|
+
}
|
|
244577
|
+
const COMPOSITES = {
|
|
244578
|
+
select: {
|
|
244579
|
+
name: "select",
|
|
244580
|
+
count: { kind: "attr", attr: "numToSelect" },
|
|
244581
|
+
grouping: { childName: "option" }
|
|
244582
|
+
},
|
|
244583
|
+
selectfromsequence: {
|
|
244584
|
+
name: "selectFromSequence",
|
|
244585
|
+
count: { kind: "attr", attr: "numToSelect" }
|
|
244586
|
+
},
|
|
244587
|
+
selectrandomnumbers: {
|
|
244588
|
+
name: "selectRandomNumbers",
|
|
244589
|
+
count: { kind: "attr", attr: "numToSelect" }
|
|
244590
|
+
},
|
|
244591
|
+
samplerandomnumbers: {
|
|
244592
|
+
name: "sampleRandomNumbers",
|
|
244593
|
+
count: { kind: "attr", attr: "numSamples" }
|
|
244594
|
+
},
|
|
244595
|
+
selectprimenumbers: {
|
|
244596
|
+
name: "selectPrimeNumbers",
|
|
244597
|
+
count: { kind: "attr", attr: "numToSelect" }
|
|
244598
|
+
},
|
|
244599
|
+
sampleprimenumbers: {
|
|
244600
|
+
name: "samplePrimeNumbers",
|
|
244601
|
+
count: { kind: "attr", attr: "numSamples" }
|
|
244602
|
+
},
|
|
244603
|
+
conditionalcontent: {
|
|
244604
|
+
name: "conditionalContent",
|
|
244605
|
+
count: { kind: "always-one" },
|
|
244606
|
+
grouping: { childName: "case", alsoMatch: ["else"] }
|
|
244607
|
+
},
|
|
244608
|
+
lorem: { name: "lorem", count: { kind: "unknown" } },
|
|
244609
|
+
sort: { name: "sort", count: { kind: "unknown" } },
|
|
244610
|
+
shuffle: { name: "shuffle", count: { kind: "unknown" } },
|
|
244611
|
+
group: { name: "group", count: { kind: "unknown" } },
|
|
244612
|
+
sequence: { name: "sequence", count: { kind: "unknown" } },
|
|
244613
|
+
substitute: { name: "substitute", count: { kind: "unknown" } },
|
|
244614
|
+
split: { name: "split", count: { kind: "unknown" } },
|
|
244615
|
+
intersection: { name: "intersection", count: { kind: "unknown" } },
|
|
244616
|
+
extract: {
|
|
244617
|
+
name: "extract",
|
|
244618
|
+
count: { kind: "unknown" },
|
|
244619
|
+
noV07Equivalent: true
|
|
244620
|
+
}
|
|
244621
|
+
};
|
|
244622
|
+
function lookupComposite(node) {
|
|
244623
|
+
return COMPOSITES[node.name.toLowerCase()];
|
|
244624
|
+
}
|
|
244625
|
+
function producesSingleReplacement(node, spec) {
|
|
244626
|
+
if (spec.count.kind === "always-one") {
|
|
244627
|
+
return true;
|
|
244628
|
+
}
|
|
244629
|
+
if (spec.count.kind === "unknown") {
|
|
244630
|
+
return false;
|
|
244631
|
+
}
|
|
244632
|
+
const attr = findAttribute(node, spec.count.attr);
|
|
244633
|
+
if (!attr) {
|
|
244634
|
+
return true;
|
|
244635
|
+
}
|
|
244636
|
+
const raw = toXml(attr.children).trim();
|
|
244637
|
+
return raw === "" || raw === "1";
|
|
244638
|
+
}
|
|
244639
|
+
function findAttribute(node, attrName) {
|
|
244640
|
+
return Object.entries(node.attributes).find(
|
|
244641
|
+
([name2]) => name2.toLowerCase() === attrName.toLowerCase()
|
|
244642
|
+
)?.[1];
|
|
244643
|
+
}
|
|
244644
|
+
function makePositionMap(node, spec, file) {
|
|
244645
|
+
if (!spec.grouping) {
|
|
244646
|
+
return void 0;
|
|
244647
|
+
}
|
|
244648
|
+
const names = [
|
|
244649
|
+
spec.grouping.childName,
|
|
244650
|
+
...spec.grouping.alsoMatch || []
|
|
244651
|
+
].map((n2) => n2.toLowerCase());
|
|
244652
|
+
const branches = node.children.filter(
|
|
244653
|
+
(child) => isDastElement(child) && names.includes(child.name.toLowerCase())
|
|
244654
|
+
);
|
|
244655
|
+
if (branches.length === 0) {
|
|
244656
|
+
return void 0;
|
|
244657
|
+
}
|
|
244658
|
+
return positionMapForBranches(
|
|
244659
|
+
branches.map((branch) => branch.children),
|
|
244660
|
+
node,
|
|
244661
|
+
file
|
|
244662
|
+
);
|
|
244663
|
+
}
|
|
244664
|
+
function makeTemplatePositionMap(template2, node, file) {
|
|
244665
|
+
return positionMapForBranches([template2.children], node, file);
|
|
244666
|
+
}
|
|
244667
|
+
function positionMapForBranches(branches, node, file) {
|
|
244668
|
+
const maps = branches.map((children) => branchPositionMap(children));
|
|
244669
|
+
const first2 = maps[0];
|
|
244670
|
+
if (maps.every((m2) => isIdentity(m2))) {
|
|
244671
|
+
return void 0;
|
|
244672
|
+
}
|
|
244673
|
+
if (!maps.every((m2) => sameMap(m2, first2))) {
|
|
244674
|
+
file.message(
|
|
244675
|
+
`The branches of <${node.name}> mix plain text with components differently, so the positions that assignNames referred to cannot be determined; the first branch was used.`,
|
|
244676
|
+
{
|
|
244677
|
+
place: node.position,
|
|
244678
|
+
ruleId: "assign-names/branch-index-skew",
|
|
244679
|
+
source: "v06-to-v07"
|
|
244680
|
+
}
|
|
244681
|
+
);
|
|
244682
|
+
}
|
|
244683
|
+
file.message(
|
|
244684
|
+
`<${node.name}> has a branch that mixes plain text with components. v0.6 skipped the text when assigning names but v0.7 counts it, so the converted indices are a best guess and should be checked.`,
|
|
244685
|
+
{
|
|
244686
|
+
place: node.position,
|
|
244687
|
+
ruleId: "assign-names/primitive-skew",
|
|
244688
|
+
source: "v06-to-v07"
|
|
244689
|
+
}
|
|
244690
|
+
);
|
|
244691
|
+
const insideGroupingDepth = 2;
|
|
244692
|
+
return (depth, ordinal) => {
|
|
244693
|
+
if (depth !== insideGroupingDepth) {
|
|
244694
|
+
return ordinal;
|
|
244695
|
+
}
|
|
244696
|
+
return first2[ordinal - 1];
|
|
244697
|
+
};
|
|
244698
|
+
}
|
|
244699
|
+
function branchPositionMap(children) {
|
|
244700
|
+
const result2 = [];
|
|
244701
|
+
let position2 = 0;
|
|
244702
|
+
for (const child of children) {
|
|
244703
|
+
if (child.type === "text") {
|
|
244704
|
+
if (child.value.trim() === "") {
|
|
244705
|
+
continue;
|
|
244706
|
+
}
|
|
244707
|
+
position2++;
|
|
244708
|
+
continue;
|
|
244709
|
+
}
|
|
244710
|
+
if (child.type === "comment" || child.type === "instruction") {
|
|
244711
|
+
continue;
|
|
244712
|
+
}
|
|
244713
|
+
position2++;
|
|
244714
|
+
result2.push(position2);
|
|
244715
|
+
}
|
|
244716
|
+
return result2;
|
|
244717
|
+
}
|
|
244718
|
+
function isIdentity(map2) {
|
|
244719
|
+
return map2.every((v2, i2) => v2 === i2 + 1);
|
|
244720
|
+
}
|
|
244721
|
+
function sameMap(a2, b2) {
|
|
244722
|
+
return a2.length === b2.length && a2.every((v2, i2) => v2 === b2[i2]);
|
|
244723
|
+
}
|
|
244724
|
+
function createAssignNamesContext(tree) {
|
|
244725
|
+
const existingNames = collectExistingNames(tree);
|
|
244726
|
+
const namespaceElements = /* @__PURE__ */ new WeakMap();
|
|
244727
|
+
let unnamedCount = 0;
|
|
244728
|
+
visit(tree, (node) => {
|
|
244729
|
+
if (!isDastElement(node)) {
|
|
244730
|
+
return;
|
|
244731
|
+
}
|
|
244732
|
+
const newNamespaceKey = Object.keys(node.attributes).find(
|
|
244733
|
+
(key) => key.toLowerCase() === "newnamespace"
|
|
244734
|
+
);
|
|
244735
|
+
if (newNamespaceKey === void 0) {
|
|
244736
|
+
return;
|
|
244737
|
+
}
|
|
244738
|
+
const newNamespaceValue = toXml(
|
|
244739
|
+
node.attributes[newNamespaceKey].children
|
|
244740
|
+
).trim().toLowerCase();
|
|
244741
|
+
if (newNamespaceValue !== "" && newNamespaceValue !== "true") {
|
|
244742
|
+
return;
|
|
244743
|
+
}
|
|
244744
|
+
const nameAttr = findAttribute(node, "name");
|
|
244745
|
+
const name2 = nameAttr ? toXml(nameAttr.children).trim() : "";
|
|
244746
|
+
namespaceElements.set(node, name2 || `\0ns${++unnamedCount}`);
|
|
244747
|
+
});
|
|
244748
|
+
const context = {
|
|
244749
|
+
registry: new RenameRegistry(existingNames),
|
|
244750
|
+
uniqueName: createUniqueNameFactory(tree),
|
|
244751
|
+
existingNames,
|
|
244752
|
+
claimedNames: /* @__PURE__ */ new Set(),
|
|
244753
|
+
namespaceElements,
|
|
244754
|
+
existingNameScopes: /* @__PURE__ */ new Map()
|
|
244755
|
+
};
|
|
244756
|
+
visit(tree, (node, info) => {
|
|
244757
|
+
if (!isDastElement(node)) {
|
|
244758
|
+
return;
|
|
244759
|
+
}
|
|
244760
|
+
const nameAttr = findAttribute(node, "name");
|
|
244761
|
+
const name2 = nameAttr ? toXml(nameAttr.children).trim() : "";
|
|
244762
|
+
if (!name2) {
|
|
244763
|
+
return;
|
|
244764
|
+
}
|
|
244765
|
+
const scopes = context.existingNameScopes.get(name2) ?? [];
|
|
244766
|
+
scopes.push(namespaceChainOf(info.parents, context));
|
|
244767
|
+
context.existingNameScopes.set(name2, scopes);
|
|
244768
|
+
});
|
|
244769
|
+
return context;
|
|
244770
|
+
}
|
|
244771
|
+
function nameTakenInScope(context, name2, ancestorNames) {
|
|
244772
|
+
const scopes = context.existingNameScopes.get(name2);
|
|
244773
|
+
if (!scopes) {
|
|
244774
|
+
return false;
|
|
244775
|
+
}
|
|
244776
|
+
const here = ancestorNames ?? [];
|
|
244777
|
+
return scopes.some(
|
|
244778
|
+
(scope) => scope.length === here.length && scope.every((segment, i2) => segment === here[i2])
|
|
244779
|
+
);
|
|
244780
|
+
}
|
|
244781
|
+
function chooseCompositeName(node, pieces, fallbackBase, context, file) {
|
|
244782
|
+
const nameAttr = findAttribute(node, "name");
|
|
244783
|
+
const existingName = nameAttr ? toXml(nameAttr.children).trim() : "";
|
|
244784
|
+
if (existingName && isValidReferenceableName(existingName)) {
|
|
244785
|
+
return existingName;
|
|
244786
|
+
}
|
|
244787
|
+
if (existingName) {
|
|
244788
|
+
file?.message(
|
|
244789
|
+
`<${node.name}> is called "${existingName}", which v0.7 cannot use as a name — it must start with a letter and hold only letters, digits, underscores and hyphens. A different name was used instead.`,
|
|
244790
|
+
{
|
|
244791
|
+
place: node.position,
|
|
244792
|
+
ruleId: "assign-names/invalid-name",
|
|
244793
|
+
source: "v06-to-v07"
|
|
244794
|
+
}
|
|
244795
|
+
);
|
|
244796
|
+
}
|
|
244797
|
+
const firstName = firstLeafName(pieces);
|
|
244798
|
+
if (firstName && isValidReferenceableName(firstName) && !context.existingNames.has(firstName) && !context.claimedNames.has(firstName)) {
|
|
244799
|
+
context.claimedNames.add(firstName);
|
|
244800
|
+
return firstName;
|
|
244801
|
+
}
|
|
244802
|
+
return context.uniqueName(fallbackBase);
|
|
244803
|
+
}
|
|
244804
|
+
function setCompositeName(node, name2) {
|
|
244805
|
+
const nameAttr = findAttribute(node, "name");
|
|
244806
|
+
const oldKey = assignNamesKey(node);
|
|
244807
|
+
if (nameAttr) {
|
|
244808
|
+
if (toXml(nameAttr.children) !== name2) {
|
|
244809
|
+
nameAttr.children = [{ type: "text", value: name2 }];
|
|
244810
|
+
}
|
|
244811
|
+
deleteAssignNames(node);
|
|
244812
|
+
return;
|
|
244813
|
+
}
|
|
244814
|
+
if (oldKey !== void 0) {
|
|
244815
|
+
renameAttrInPlace(node, oldKey, "name");
|
|
244816
|
+
node.attributes["name"].children = [{ type: "text", value: name2 }];
|
|
244817
|
+
return;
|
|
244818
|
+
}
|
|
244819
|
+
node.attributes["name"] = {
|
|
244820
|
+
type: "attribute",
|
|
244821
|
+
name: "name",
|
|
244822
|
+
children: [{ type: "text", value: name2 }]
|
|
244823
|
+
};
|
|
244824
|
+
}
|
|
244825
|
+
function readAssignNames(node) {
|
|
244826
|
+
const key = assignNamesKey(node);
|
|
244827
|
+
if (key === void 0) {
|
|
244828
|
+
return void 0;
|
|
244829
|
+
}
|
|
244830
|
+
return toXml(node.attributes[key].children).trim();
|
|
244831
|
+
}
|
|
244832
|
+
function deleteAssignNames(node) {
|
|
244833
|
+
const key = assignNamesKey(node);
|
|
244834
|
+
if (key !== void 0) {
|
|
244835
|
+
delete node.attributes[key];
|
|
244836
|
+
}
|
|
244837
|
+
}
|
|
244838
|
+
function assignNamesKey(node) {
|
|
244839
|
+
return Object.keys(node.attributes).find(
|
|
244840
|
+
(k2) => k2.toLowerCase() === "assignnames"
|
|
244841
|
+
);
|
|
244842
|
+
}
|
|
244843
|
+
function namespaceChainOf(parents, context) {
|
|
244844
|
+
const chain2 = [];
|
|
244845
|
+
for (const parent of parents) {
|
|
244846
|
+
const segment = context.namespaceElements.get(parent);
|
|
244847
|
+
if (segment !== void 0) {
|
|
244848
|
+
chain2.push(segment);
|
|
244849
|
+
}
|
|
244850
|
+
}
|
|
244851
|
+
return chain2.reverse();
|
|
244852
|
+
}
|
|
244853
|
+
function inheritNamespace(from, to2, context) {
|
|
244854
|
+
const segment = context.namespaceElements.get(from);
|
|
244855
|
+
if (segment !== void 0) {
|
|
244856
|
+
context.namespaceElements.set(to2, segment);
|
|
244857
|
+
}
|
|
244858
|
+
}
|
|
244859
|
+
const identityPositionMap = (_depth, ordinal) => ordinal;
|
|
244860
|
+
function registerAssignNames({
|
|
244861
|
+
assignNamesValue,
|
|
244862
|
+
compositeName,
|
|
244863
|
+
registry,
|
|
244864
|
+
origin,
|
|
244865
|
+
file,
|
|
244866
|
+
positionMap = identityPositionMap
|
|
244867
|
+
}) {
|
|
244868
|
+
const result2 = breakStringInPiecesBySpacesOrParens(assignNamesValue);
|
|
244869
|
+
if (!result2.success) {
|
|
244870
|
+
file.message(
|
|
244871
|
+
`Could not parse assignNames="${assignNamesValue}" on <${origin.elementName}> because its parentheses are unbalanced; references to those names were not converted.`,
|
|
244872
|
+
{
|
|
244873
|
+
place: origin.position,
|
|
244874
|
+
ruleId: "assign-names/unbalanced-parens",
|
|
244875
|
+
source: "v06-to-v07"
|
|
244876
|
+
}
|
|
244877
|
+
);
|
|
244878
|
+
return false;
|
|
244879
|
+
}
|
|
244880
|
+
registerPieces(result2.pieces, []);
|
|
244881
|
+
return true;
|
|
244882
|
+
function registerPieces(pieces, indexPath) {
|
|
244883
|
+
pieces.forEach((piece, i2) => {
|
|
244884
|
+
const depth = indexPath.length + 1;
|
|
244885
|
+
const position2 = positionMap(depth, i2 + 1);
|
|
244886
|
+
if (position2 === void 0) {
|
|
244887
|
+
reportNamesNothing(piece);
|
|
244888
|
+
return;
|
|
244889
|
+
}
|
|
244890
|
+
const indices = [...indexPath, position2];
|
|
244891
|
+
if (typeof piece === "string") {
|
|
244892
|
+
if (!isValidReferenceableName(piece)) {
|
|
244893
|
+
file.message(
|
|
244894
|
+
`The assignNames token "${piece}" on <${origin.elementName}> is not a valid v0.7 name, so references to it were not converted.`,
|
|
244895
|
+
{
|
|
244896
|
+
place: origin.position,
|
|
244897
|
+
ruleId: "assign-names/invalid-name",
|
|
244898
|
+
source: "v06-to-v07"
|
|
244899
|
+
}
|
|
244900
|
+
);
|
|
244901
|
+
return;
|
|
244902
|
+
}
|
|
244903
|
+
registry.register(
|
|
244904
|
+
piece,
|
|
244905
|
+
[makeIndexedPathPart(compositeName, indices)],
|
|
244906
|
+
origin,
|
|
244907
|
+
file
|
|
244908
|
+
);
|
|
244909
|
+
} else {
|
|
244910
|
+
registerPieces(piece, indices);
|
|
244911
|
+
}
|
|
244912
|
+
});
|
|
244913
|
+
}
|
|
244914
|
+
function reportNamesNothing(piece) {
|
|
244915
|
+
if (typeof piece !== "string") {
|
|
244916
|
+
piece.forEach(reportNamesNothing);
|
|
244917
|
+
return;
|
|
244918
|
+
}
|
|
244919
|
+
file.message(
|
|
244920
|
+
`The assignNames token "${piece}" on <${origin.elementName}> named nothing in v0.6 — the position it was given holds no component — so references to it were not converted.`,
|
|
244921
|
+
{
|
|
244922
|
+
place: origin.position,
|
|
244923
|
+
ruleId: "assign-names/names-nothing",
|
|
244924
|
+
source: "v06-to-v07"
|
|
244925
|
+
}
|
|
244926
|
+
);
|
|
244927
|
+
}
|
|
244928
|
+
}
|
|
244929
|
+
function registerCompositeAssignNames({
|
|
244930
|
+
node,
|
|
244931
|
+
assignNamesValue,
|
|
244932
|
+
fallbackBase,
|
|
244933
|
+
ancestorNames,
|
|
244934
|
+
context,
|
|
244935
|
+
file,
|
|
244936
|
+
positionMap
|
|
244937
|
+
}) {
|
|
244938
|
+
const origin = {
|
|
244939
|
+
elementName: node.name,
|
|
244940
|
+
position: node.position,
|
|
244941
|
+
ancestorNames,
|
|
244942
|
+
element: node
|
|
244943
|
+
};
|
|
244944
|
+
const parsed = breakStringInPiecesBySpacesOrParens(assignNamesValue);
|
|
244945
|
+
if (!parsed.success) {
|
|
244946
|
+
registerAssignNames({
|
|
244947
|
+
assignNamesValue,
|
|
244948
|
+
compositeName: "",
|
|
244949
|
+
registry: context.registry,
|
|
244950
|
+
origin,
|
|
244951
|
+
file
|
|
244952
|
+
});
|
|
244953
|
+
return void 0;
|
|
244954
|
+
}
|
|
244955
|
+
if (firstLeafName(parsed.pieces) === void 0) {
|
|
244956
|
+
return void 0;
|
|
244957
|
+
}
|
|
244958
|
+
const compositeName = chooseCompositeName(
|
|
244959
|
+
node,
|
|
244960
|
+
parsed.pieces,
|
|
244961
|
+
fallbackBase,
|
|
244962
|
+
context,
|
|
244963
|
+
file
|
|
244964
|
+
);
|
|
244965
|
+
registerAssignNames({
|
|
244966
|
+
assignNamesValue,
|
|
244967
|
+
compositeName,
|
|
244968
|
+
registry: context.registry,
|
|
244969
|
+
origin,
|
|
244970
|
+
file,
|
|
244971
|
+
positionMap
|
|
244972
|
+
});
|
|
244973
|
+
return compositeName;
|
|
244974
|
+
}
|
|
244975
|
+
function visitAll(tree, visitor) {
|
|
244976
|
+
walk(tree, [], void 0);
|
|
244977
|
+
function walk(node, parents, attributeOwner) {
|
|
244978
|
+
const isMacro = node.type === "macro" || node.type === "function";
|
|
244979
|
+
if (!isMacro) {
|
|
244980
|
+
visitor(node, parents, attributeOwner);
|
|
244981
|
+
}
|
|
244982
|
+
const innerParents = isDastElement(node) ? [node, ...parents] : parents;
|
|
244983
|
+
if (isDastElement(node)) {
|
|
244984
|
+
for (const attr of Object.values(node.attributes)) {
|
|
244985
|
+
walkArray(attr.children, innerParents, node);
|
|
244986
|
+
}
|
|
244987
|
+
}
|
|
244988
|
+
if (node.type === "macro") {
|
|
244989
|
+
walkMacroAttributes(node, innerParents, attributeOwner);
|
|
244990
|
+
walkMacroPath(node, innerParents, attributeOwner);
|
|
244991
|
+
const accessedProp = node.accessedProp;
|
|
244992
|
+
if (accessedProp) {
|
|
244993
|
+
walk(accessedProp, innerParents, attributeOwner);
|
|
244994
|
+
}
|
|
244995
|
+
}
|
|
244996
|
+
if (node.type === "function") {
|
|
244997
|
+
const inner = node.macro;
|
|
244998
|
+
if (inner) {
|
|
244999
|
+
walk(inner, innerParents, attributeOwner);
|
|
245000
|
+
}
|
|
245001
|
+
walkMacroPath(node, innerParents, attributeOwner);
|
|
245002
|
+
for (const inputPart of node.input || []) {
|
|
245003
|
+
walkArray(
|
|
245004
|
+
inputPart,
|
|
245005
|
+
innerParents,
|
|
245006
|
+
attributeOwner
|
|
245007
|
+
);
|
|
245008
|
+
}
|
|
245009
|
+
}
|
|
245010
|
+
if ("children" in node && Array.isArray(node.children)) {
|
|
245011
|
+
walkArray(
|
|
245012
|
+
node.children,
|
|
245013
|
+
innerParents,
|
|
245014
|
+
isDastElement(node) ? void 0 : attributeOwner
|
|
245015
|
+
);
|
|
245016
|
+
}
|
|
245017
|
+
if (isMacro) {
|
|
245018
|
+
visitor(node, parents, attributeOwner);
|
|
245019
|
+
}
|
|
245020
|
+
}
|
|
245021
|
+
function walkMacroAttributes(node, parents, attributeOwner) {
|
|
245022
|
+
const attrs = Array.isArray(node.attributes) ? node.attributes : Object.values(node.attributes);
|
|
245023
|
+
for (const attr of attrs) {
|
|
245024
|
+
walkArray(attr.children, parents, attributeOwner);
|
|
245025
|
+
}
|
|
245026
|
+
}
|
|
245027
|
+
function walkMacroPath(node, parents, attributeOwner) {
|
|
245028
|
+
for (const part of node.path || []) {
|
|
245029
|
+
for (const index2 of part.index) {
|
|
245030
|
+
walkArray(index2.value, parents, attributeOwner);
|
|
245031
|
+
}
|
|
245032
|
+
}
|
|
245033
|
+
}
|
|
245034
|
+
function walkArray(nodes, parents, attributeOwner) {
|
|
245035
|
+
for (let i2 = 0; i2 < nodes.length; i2++) {
|
|
245036
|
+
walk(nodes[i2], parents, attributeOwner);
|
|
245037
|
+
}
|
|
245038
|
+
}
|
|
245039
|
+
}
|
|
245040
|
+
function visitAllMacros(tree, visitor) {
|
|
245041
|
+
visitAll(tree, (node, parents, attributeOwner) => {
|
|
245042
|
+
if (node.type !== "macro" && node.type !== "function") {
|
|
245043
|
+
return;
|
|
245044
|
+
}
|
|
245045
|
+
if (!Array.isArray(node.path)) {
|
|
245046
|
+
return;
|
|
245047
|
+
}
|
|
245048
|
+
visitor(node, parents, attributeOwner);
|
|
245049
|
+
});
|
|
245050
|
+
}
|
|
245051
|
+
const propAccessParts = /* @__PURE__ */ new WeakSet();
|
|
245052
|
+
function markAsPropAccess(part) {
|
|
245053
|
+
propAccessParts.add(part);
|
|
245054
|
+
}
|
|
245055
|
+
function isPropAccess(part) {
|
|
245056
|
+
return propAccessParts.has(part);
|
|
245057
|
+
}
|
|
245058
|
+
const rawPropPositions = /* @__PURE__ */ new WeakMap();
|
|
245059
|
+
function markRawPropPositions(node, attrName, positions) {
|
|
245060
|
+
let byAttr = rawPropPositions.get(node);
|
|
245061
|
+
if (!byAttr) {
|
|
245062
|
+
byAttr = /* @__PURE__ */ new Map();
|
|
245063
|
+
rawPropPositions.set(node, byAttr);
|
|
245064
|
+
}
|
|
245065
|
+
byAttr.set(attrName.toLowerCase(), positions);
|
|
245066
|
+
}
|
|
245067
|
+
function restoreRawPropPositions(node, attrName, path) {
|
|
245068
|
+
const positions = rawPropPositions.get(node)?.get(attrName.toLowerCase());
|
|
245069
|
+
if (!positions) {
|
|
245070
|
+
return;
|
|
245071
|
+
}
|
|
245072
|
+
for (const position2 of positions) {
|
|
245073
|
+
const part = path[position2];
|
|
245074
|
+
if (part) {
|
|
245075
|
+
markAsPropAccess(part);
|
|
245076
|
+
}
|
|
245077
|
+
}
|
|
245078
|
+
}
|
|
245079
|
+
const RAW_REFERENCE_ATTRS = {
|
|
245080
|
+
copy: ["source"],
|
|
245081
|
+
extract: ["source"]
|
|
245082
|
+
};
|
|
245083
|
+
function applyRefRenames(tree, registry, file, context) {
|
|
245084
|
+
if (registry.size === 0) {
|
|
245085
|
+
return;
|
|
245086
|
+
}
|
|
245087
|
+
visitAllMacros(tree, (node, parents, attributeOwner) => {
|
|
245088
|
+
node.path = renamePath(
|
|
245089
|
+
node.path,
|
|
245090
|
+
registry,
|
|
245091
|
+
file,
|
|
245092
|
+
node.position,
|
|
245093
|
+
namespaceChainOf(parents, context),
|
|
245094
|
+
// A reference written on an element cannot mean the name that element is
|
|
245095
|
+
// about to take: `<copy source="$x0" assignNames="x0">` reaches elsewhere
|
|
245096
|
+
// for the thing it copies. References among its *children* are a different
|
|
245097
|
+
// matter and keep their ownership clear, so `visitAll` reports none for them.
|
|
245098
|
+
attributeOwner
|
|
245099
|
+
);
|
|
245100
|
+
});
|
|
245101
|
+
visitAll(tree, (node, parents) => {
|
|
245102
|
+
if (!isDastElement(node)) {
|
|
245103
|
+
return;
|
|
245104
|
+
}
|
|
245105
|
+
const attrNames = RAW_REFERENCE_ATTRS[node.name.toLowerCase()];
|
|
245106
|
+
if (!attrNames) {
|
|
245107
|
+
return;
|
|
245108
|
+
}
|
|
245109
|
+
const enclosing = namespaceChainOf(parents, context);
|
|
245110
|
+
for (const attrName of attrNames) {
|
|
245111
|
+
renameRawReferenceAttribute(
|
|
245112
|
+
node,
|
|
245113
|
+
attrName,
|
|
245114
|
+
registry,
|
|
245115
|
+
file,
|
|
245116
|
+
enclosing
|
|
245117
|
+
);
|
|
245118
|
+
}
|
|
245119
|
+
});
|
|
245120
|
+
}
|
|
245121
|
+
function renameRawReferenceAttribute(node, attrName, registry, file, enclosingNames) {
|
|
245122
|
+
const attr = Object.entries(node.attributes).find(
|
|
245123
|
+
([name2]) => name2.toLowerCase() === attrName.toLowerCase()
|
|
245124
|
+
)?.[1];
|
|
245125
|
+
if (!attr || attr.children.length !== 1) {
|
|
245126
|
+
return;
|
|
245127
|
+
}
|
|
245128
|
+
const child = attr.children[0];
|
|
245129
|
+
if (child.type !== "text") {
|
|
245130
|
+
return;
|
|
245131
|
+
}
|
|
245132
|
+
const value = child.value.trim();
|
|
245133
|
+
if (!value) {
|
|
245134
|
+
return;
|
|
245135
|
+
}
|
|
245136
|
+
if (!value.split(/[^A-Za-z0-9_-]+/).some((piece) => registry.hasReplacement(piece))) {
|
|
245137
|
+
return;
|
|
245138
|
+
}
|
|
245139
|
+
let path;
|
|
245140
|
+
try {
|
|
245141
|
+
path = parseReferencePath(value);
|
|
245142
|
+
} catch (e4) {
|
|
245143
|
+
file.message(
|
|
245144
|
+
`Could not convert a reference to an assignNames name in ${attrName}="${value}".`,
|
|
245145
|
+
{
|
|
245146
|
+
place: node.position,
|
|
245147
|
+
ruleId: "assign-names/unparsable-reference-attribute",
|
|
245148
|
+
source: "v06-to-v07"
|
|
245149
|
+
}
|
|
245150
|
+
);
|
|
245151
|
+
return;
|
|
245152
|
+
}
|
|
245153
|
+
restoreRawPropPositions(node, attrName, path);
|
|
245154
|
+
const asMacro = { type: "macro", path, attributes: {} };
|
|
245155
|
+
visitAllMacros(asMacro, (macro) => {
|
|
245156
|
+
macro.path = renamePath(
|
|
245157
|
+
macro.path,
|
|
245158
|
+
registry,
|
|
245159
|
+
file,
|
|
245160
|
+
node.position,
|
|
245161
|
+
enclosingNames,
|
|
245162
|
+
// A copy's `source` says what it copies, which is never the copy itself:
|
|
245163
|
+
// `<copy source="../x0" assignNames="x0">` names its result `x0` while
|
|
245164
|
+
// reaching out of the namespace for the `x0` it copies.
|
|
245165
|
+
node
|
|
245166
|
+
);
|
|
245167
|
+
});
|
|
245168
|
+
child.value = toXml(asMacro.path);
|
|
245169
|
+
}
|
|
245170
|
+
function renamePath(path, registry, file, place, enclosingNames = [], writtenOn) {
|
|
245171
|
+
if (!path.some((part) => registry.hasReplacement(part.name))) {
|
|
245172
|
+
return path;
|
|
245173
|
+
}
|
|
245174
|
+
return path.flatMap((part, partIndex) => {
|
|
245175
|
+
const target = registry.get(
|
|
245176
|
+
part.name,
|
|
245177
|
+
[...enclosingNames, ...path.slice(0, partIndex).map((p2) => p2.name)],
|
|
245178
|
+
writtenOn
|
|
245179
|
+
);
|
|
245180
|
+
if (!target?.replacement) {
|
|
245181
|
+
return [part];
|
|
245182
|
+
}
|
|
245183
|
+
if (partIndex > 0 && isPropAccess(part)) {
|
|
245184
|
+
return [part];
|
|
245185
|
+
}
|
|
245186
|
+
const replacement = structuredClone(
|
|
245187
|
+
target.replacement
|
|
245188
|
+
);
|
|
245189
|
+
const last2 = replacement[replacement.length - 1];
|
|
245190
|
+
last2.index = [...last2.index, ...part.index];
|
|
245191
|
+
return replacement;
|
|
245192
|
+
});
|
|
245193
|
+
}
|
|
245194
|
+
function parseReferencePath(value) {
|
|
245195
|
+
for (const candidate of [`$${value}`, `$(${value})`]) {
|
|
245196
|
+
let reparsed;
|
|
245197
|
+
try {
|
|
245198
|
+
reparsed = reparseAttribute(candidate);
|
|
245199
|
+
} catch (e4) {
|
|
245200
|
+
continue;
|
|
245201
|
+
}
|
|
245202
|
+
if (reparsed.length === 1 && reparsed[0].type === "macro") {
|
|
245203
|
+
return reparsed[0].path;
|
|
245204
|
+
}
|
|
245205
|
+
}
|
|
245206
|
+
throw new Error(`Could not parse "${value}" as a reference`);
|
|
245207
|
+
}
|
|
245208
|
+
const upgradeCollectElement = (context) => {
|
|
244211
245209
|
return (tree, file) => {
|
|
244212
|
-
|
|
244213
|
-
visit(tree, (node) => {
|
|
245210
|
+
visit(tree, (node, info) => {
|
|
244214
245211
|
if (!isDastElement(node)) {
|
|
244215
245212
|
return;
|
|
244216
245213
|
}
|
|
@@ -244220,50 +245217,45 @@ const upgradeCollectElement = () => {
|
|
|
244220
245217
|
if (node.attributes["componentTypes"]) {
|
|
244221
245218
|
renameAttrInPlace(node, "componentTypes", "componentType");
|
|
244222
245219
|
}
|
|
244223
|
-
|
|
244224
|
-
|
|
244225
|
-
|
|
244226
|
-
if (!fromValue.startsWith("$")) {
|
|
244227
|
-
node.attributes["from"].children = reparseAttribute(
|
|
244228
|
-
`$${fromValue}`
|
|
244229
|
-
);
|
|
244230
|
-
}
|
|
244231
|
-
} else if (node.attributes["target"]) {
|
|
244232
|
-
renameAttrInPlace(node, "target", "from");
|
|
244233
|
-
const fromValue = toXml(node.attributes["from"].children);
|
|
244234
|
-
if (!fromValue.startsWith("$")) {
|
|
244235
|
-
node.attributes["from"].children = reparseAttribute(
|
|
244236
|
-
`$${fromValue}`
|
|
244237
|
-
);
|
|
245220
|
+
for (const oldKey of ["source", "target"]) {
|
|
245221
|
+
if (!node.attributes[oldKey]) {
|
|
245222
|
+
continue;
|
|
244238
245223
|
}
|
|
245224
|
+
renameAttrInPlace(node, oldKey, "from");
|
|
245225
|
+
makeFromAReference(node, file);
|
|
245226
|
+
break;
|
|
244239
245227
|
}
|
|
244240
|
-
const
|
|
244241
|
-
if (!
|
|
245228
|
+
const assignNamesValue = readAssignNames(node);
|
|
245229
|
+
if (!assignNamesValue) {
|
|
245230
|
+
deleteAssignNames(node);
|
|
244242
245231
|
return;
|
|
244243
245232
|
}
|
|
244244
|
-
|
|
244245
|
-
|
|
244246
|
-
|
|
244247
|
-
|
|
244248
|
-
|
|
244249
|
-
|
|
244250
|
-
|
|
244251
|
-
`Expected attribute to be a single macro, got: ${JSON.stringify(attr)}`
|
|
244252
|
-
);
|
|
244253
|
-
}
|
|
244254
|
-
refsToRename[name2] = attr.path;
|
|
245233
|
+
const compositeName = registerCompositeAssignNames({
|
|
245234
|
+
node,
|
|
245235
|
+
assignNamesValue,
|
|
245236
|
+
fallbackBase: "collect",
|
|
245237
|
+
ancestorNames: namespaceChainOf(info.parents, context),
|
|
245238
|
+
context,
|
|
245239
|
+
file
|
|
244255
245240
|
});
|
|
245241
|
+
if (compositeName === void 0) {
|
|
245242
|
+
deleteAssignNames(node);
|
|
245243
|
+
return;
|
|
245244
|
+
}
|
|
245245
|
+
setCompositeName(node, compositeName);
|
|
244256
245246
|
});
|
|
244257
245247
|
replaceNode(tree, (node) => {
|
|
244258
245248
|
if (!isDastElement(node) || node.name !== "collect") {
|
|
244259
245249
|
return;
|
|
244260
245250
|
}
|
|
244261
|
-
const
|
|
244262
|
-
|
|
245251
|
+
const propKey = Object.keys(node.attributes).find(
|
|
245252
|
+
(key) => key.toLowerCase() === "prop"
|
|
245253
|
+
);
|
|
245254
|
+
const propName = propKey ? toXml(node.attributes[propKey].children).trim() : "";
|
|
244263
245255
|
if (!propName) {
|
|
244264
245256
|
return;
|
|
244265
245257
|
}
|
|
244266
|
-
delete node.attributes[
|
|
245258
|
+
delete node.attributes[propKey];
|
|
244267
245259
|
const setup = {
|
|
244268
245260
|
type: "element",
|
|
244269
245261
|
name: "setup",
|
|
@@ -244273,8 +245265,9 @@ const upgradeCollectElement = () => {
|
|
|
244273
245265
|
const componentType = toXml(
|
|
244274
245266
|
node.attributes["componentType"]?.children
|
|
244275
245267
|
).trim();
|
|
244276
|
-
const
|
|
244277
|
-
const
|
|
245268
|
+
const authoredListName = node.attributes["name"] ? toXml(node.attributes["name"].children).trim() : "";
|
|
245269
|
+
const listName = authoredListName && isValidReferenceableName(authoredListName) ? authoredListName : context.uniqueName("list");
|
|
245270
|
+
const collectName = context.uniqueName(`collect_${listName}`);
|
|
244278
245271
|
node.attributes["name"] = {
|
|
244279
245272
|
type: "attribute",
|
|
244280
245273
|
name: "name",
|
|
@@ -244284,7 +245277,11 @@ const upgradeCollectElement = () => {
|
|
|
244284
245277
|
if (!listType) {
|
|
244285
245278
|
file.message(
|
|
244286
245279
|
`Could not determine type for prop "${propName}" of component type "${componentType}". Using "math" as default.`,
|
|
244287
|
-
{
|
|
245280
|
+
{
|
|
245281
|
+
place: node.position,
|
|
245282
|
+
ruleId: "collect/unknown-prop-type",
|
|
245283
|
+
source: "v06-to-v07"
|
|
245284
|
+
}
|
|
244288
245285
|
);
|
|
244289
245286
|
listType = "math";
|
|
244290
245287
|
}
|
|
@@ -244302,30 +245299,81 @@ const upgradeCollectElement = () => {
|
|
|
244302
245299
|
extend: {
|
|
244303
245300
|
type: "attribute",
|
|
244304
245301
|
name: "extend",
|
|
244305
|
-
children:
|
|
244306
|
-
|
|
244307
|
-
|
|
245302
|
+
children: [
|
|
245303
|
+
{
|
|
245304
|
+
type: "macro",
|
|
245305
|
+
path: [
|
|
245306
|
+
...parseReferencePath(collectName),
|
|
245307
|
+
...propPathParts(propName, node, file)
|
|
245308
|
+
],
|
|
245309
|
+
attributes: {}
|
|
245310
|
+
}
|
|
245311
|
+
]
|
|
244308
245312
|
}
|
|
244309
245313
|
},
|
|
244310
245314
|
children: []
|
|
244311
245315
|
};
|
|
244312
245316
|
return [setup, list];
|
|
244313
245317
|
});
|
|
244314
|
-
visit(tree, (node) => {
|
|
244315
|
-
if (node.type !== "macro") {
|
|
244316
|
-
return;
|
|
244317
|
-
}
|
|
244318
|
-
if (!node.path.some((part) => refsToRename[part.name])) {
|
|
244319
|
-
return;
|
|
244320
|
-
}
|
|
244321
|
-
node.path = node.path.flatMap((part) => {
|
|
244322
|
-
return refsToRename[part.name] || [part];
|
|
244323
|
-
});
|
|
244324
|
-
});
|
|
244325
245318
|
};
|
|
244326
245319
|
};
|
|
245320
|
+
function makeFromAReference(node, file) {
|
|
245321
|
+
const attr = node.attributes["from"];
|
|
245322
|
+
const value = toXml(attr.children).trim();
|
|
245323
|
+
if (!value || value.startsWith("$")) {
|
|
245324
|
+
return;
|
|
245325
|
+
}
|
|
245326
|
+
try {
|
|
245327
|
+
attr.children = [
|
|
245328
|
+
{
|
|
245329
|
+
type: "macro",
|
|
245330
|
+
path: parseReferencePath(value),
|
|
245331
|
+
attributes: {}
|
|
245332
|
+
}
|
|
245333
|
+
];
|
|
245334
|
+
} catch {
|
|
245335
|
+
file.message(
|
|
245336
|
+
`Could not read "${value}" as the name of what <collect> collects from.`,
|
|
245337
|
+
{
|
|
245338
|
+
place: node.position,
|
|
245339
|
+
ruleId: "collect/unparsable-from",
|
|
245340
|
+
source: "v06-to-v07"
|
|
245341
|
+
}
|
|
245342
|
+
);
|
|
245343
|
+
}
|
|
245344
|
+
}
|
|
245345
|
+
function propPathParts(propName, node, file) {
|
|
245346
|
+
let parts;
|
|
245347
|
+
try {
|
|
245348
|
+
parts = parseReferencePath(propName);
|
|
245349
|
+
} catch {
|
|
245350
|
+
file.message(
|
|
245351
|
+
`<collect prop="${propName}"> could not be turned into a reference, so the generated list extends a path that needs fixing by hand.`,
|
|
245352
|
+
{
|
|
245353
|
+
place: node.position,
|
|
245354
|
+
ruleId: "collect/unparsable-prop",
|
|
245355
|
+
source: "v06-to-v07"
|
|
245356
|
+
}
|
|
245357
|
+
);
|
|
245358
|
+
return [{ type: "pathPart", name: propName, index: [] }];
|
|
245359
|
+
}
|
|
245360
|
+
parts.forEach(markAsPropAccess);
|
|
245361
|
+
return parts;
|
|
245362
|
+
}
|
|
244327
245363
|
const upgradePathSlashesToDots = () => {
|
|
244328
245364
|
return (tree, file) => {
|
|
245365
|
+
const warnParentPath = (original) => {
|
|
245366
|
+
file.message(
|
|
245367
|
+
`There is no equivalent to the $(../x) syntax; a best-guess was made when converting ${macroToString(
|
|
245368
|
+
original
|
|
245369
|
+
)}`,
|
|
245370
|
+
{
|
|
245371
|
+
place: original.position,
|
|
245372
|
+
ruleId: "no-v07-equivalent/parent-path",
|
|
245373
|
+
source: "v06-to-v07"
|
|
245374
|
+
}
|
|
245375
|
+
);
|
|
245376
|
+
};
|
|
244329
245377
|
visit(
|
|
244330
245378
|
tree,
|
|
244331
245379
|
// @ts-ignore
|
|
@@ -244336,44 +245384,17 @@ const upgradePathSlashesToDots = () => {
|
|
|
244336
245384
|
}
|
|
244337
245385
|
if (isDastElement(node)) {
|
|
244338
245386
|
for (const attr of Object.values(node.attributes)) {
|
|
244339
|
-
|
|
244340
|
-
if (isV06MacroOrFunctionMacro(child)) {
|
|
244341
|
-
macros.push(child);
|
|
244342
|
-
}
|
|
244343
|
-
}
|
|
245387
|
+
collectV06Macros(attr.children, macros);
|
|
244344
245388
|
}
|
|
244345
245389
|
}
|
|
244346
245390
|
for (const node2 of macros) {
|
|
244347
|
-
const macro = node2.type === "macro" ? v06MacroToV07Macro(node2) : v06FunctionMacroToV07FunctionMacro(
|
|
245391
|
+
const macro = node2.type === "macro" ? v06MacroToV07Macro(node2, warnParentPath) : v06FunctionMacroToV07FunctionMacro(
|
|
245392
|
+
node2,
|
|
245393
|
+
warnParentPath
|
|
245394
|
+
);
|
|
244348
245395
|
Object.keys(node2).forEach((key) => {
|
|
244349
245396
|
delete node2[key];
|
|
244350
245397
|
});
|
|
244351
|
-
if (macro.path.some((p2) => p2.name === "..")) {
|
|
244352
|
-
const newPath = [];
|
|
244353
|
-
let errorMessageWritten = false;
|
|
244354
|
-
for (const part of macro.path) {
|
|
244355
|
-
if (part.name === "..") {
|
|
244356
|
-
if (newPath.length > 0) {
|
|
244357
|
-
newPath.pop();
|
|
244358
|
-
if (!errorMessageWritten) {
|
|
244359
|
-
errorMessageWritten = true;
|
|
244360
|
-
file.message(
|
|
244361
|
-
`There is no equivalent to the $(../x) syntax; a best-guess was made when converting ${macroToString(
|
|
244362
|
-
macro
|
|
244363
|
-
)}`,
|
|
244364
|
-
{
|
|
244365
|
-
start: node2.position?.start,
|
|
244366
|
-
end: node2.position?.end
|
|
244367
|
-
}
|
|
244368
|
-
);
|
|
244369
|
-
}
|
|
244370
|
-
}
|
|
244371
|
-
continue;
|
|
244372
|
-
}
|
|
244373
|
-
newPath.push(part);
|
|
244374
|
-
}
|
|
244375
|
-
macro.path = newPath;
|
|
244376
|
-
}
|
|
244377
245398
|
Object.assign(node2, macro);
|
|
244378
245399
|
}
|
|
244379
245400
|
}
|
|
@@ -244382,24 +245403,54 @@ const upgradePathSlashesToDots = () => {
|
|
|
244382
245403
|
if (!isDastElement(node)) {
|
|
244383
245404
|
return;
|
|
244384
245405
|
}
|
|
245406
|
+
if (!ELEMENTS_WITH_REFERENCE_SOURCE.has(node.name.toLowerCase())) {
|
|
245407
|
+
return;
|
|
245408
|
+
}
|
|
244385
245409
|
const sourceAttr = node.attributes["source"];
|
|
244386
245410
|
if (!sourceAttr) {
|
|
244387
245411
|
return;
|
|
244388
245412
|
}
|
|
244389
245413
|
const sourceName = toXml(sourceAttr.children).trim();
|
|
244390
|
-
|
|
245414
|
+
const hasSlash = sourceName.includes("/");
|
|
245415
|
+
if (!hasSlash && !sourceName.includes(".")) {
|
|
244391
245416
|
return;
|
|
244392
245417
|
}
|
|
244393
245418
|
const reparsedSource = parseMacrosV06(`$(${sourceName})`);
|
|
244394
245419
|
if (reparsedSource.length !== 1 || reparsedSource[0].type !== "macro") {
|
|
244395
|
-
|
|
244396
|
-
|
|
244397
|
-
|
|
244398
|
-
|
|
245420
|
+
if (hasSlash) {
|
|
245421
|
+
file.message(
|
|
245422
|
+
`Could not reparse "source" attribute that contains a slash: "${sourceName}".`,
|
|
245423
|
+
{
|
|
245424
|
+
place: node.position,
|
|
245425
|
+
ruleId: "copy/unparsable-source",
|
|
245426
|
+
source: "v06-to-v07"
|
|
245427
|
+
}
|
|
245428
|
+
);
|
|
245429
|
+
}
|
|
244399
245430
|
return;
|
|
244400
245431
|
}
|
|
244401
|
-
const upgradedSource = v06MacroToV07Macro(
|
|
245432
|
+
const upgradedSource = v06MacroToV07Macro(
|
|
245433
|
+
reparsedSource[0],
|
|
245434
|
+
() => file.message(
|
|
245435
|
+
`There is no equivalent to the ../x syntax; a best-guess was made when converting source="${sourceName}"`,
|
|
245436
|
+
{
|
|
245437
|
+
place: node.position,
|
|
245438
|
+
ruleId: "no-v07-equivalent/parent-path",
|
|
245439
|
+
source: "v06-to-v07"
|
|
245440
|
+
}
|
|
245441
|
+
)
|
|
245442
|
+
);
|
|
245443
|
+
markRawPropPositions(
|
|
245444
|
+
node,
|
|
245445
|
+
"source",
|
|
245446
|
+
upgradedSource.path.flatMap(
|
|
245447
|
+
(part, index2) => isPropAccess(part) ? [index2] : []
|
|
245448
|
+
)
|
|
245449
|
+
);
|
|
244402
245450
|
const newSourceName = toXml(upgradedSource.path);
|
|
245451
|
+
if (newSourceName === sourceName) {
|
|
245452
|
+
return;
|
|
245453
|
+
}
|
|
244403
245454
|
sourceAttr.children = [
|
|
244404
245455
|
{
|
|
244405
245456
|
type: "text",
|
|
@@ -244410,12 +245461,44 @@ const upgradePathSlashesToDots = () => {
|
|
|
244410
245461
|
});
|
|
244411
245462
|
};
|
|
244412
245463
|
};
|
|
244413
|
-
function
|
|
244414
|
-
const
|
|
245464
|
+
function collectV06Macros(nodes, macros) {
|
|
245465
|
+
for (const node of nodes) {
|
|
245466
|
+
if (isV06MacroOrFunctionMacro(node)) {
|
|
245467
|
+
macros.push(node);
|
|
245468
|
+
}
|
|
245469
|
+
}
|
|
245470
|
+
}
|
|
245471
|
+
const ELEMENTS_WITH_REFERENCE_SOURCE = /* @__PURE__ */ new Set(["copy", "collect", "extract"]);
|
|
245472
|
+
function collapseParentPathParts(path, warn) {
|
|
245473
|
+
if (!path.some((part) => part.name === "..")) {
|
|
245474
|
+
return path;
|
|
245475
|
+
}
|
|
245476
|
+
const newPath = [];
|
|
245477
|
+
let warned = false;
|
|
245478
|
+
for (const part of path) {
|
|
245479
|
+
if (part.name === "..") {
|
|
245480
|
+
if (newPath.length > 0) {
|
|
245481
|
+
newPath.pop();
|
|
245482
|
+
}
|
|
245483
|
+
if (!warned) {
|
|
245484
|
+
warned = true;
|
|
245485
|
+
warn();
|
|
245486
|
+
}
|
|
245487
|
+
continue;
|
|
245488
|
+
}
|
|
245489
|
+
newPath.push(part);
|
|
245490
|
+
}
|
|
245491
|
+
return newPath;
|
|
245492
|
+
}
|
|
245493
|
+
function v06MacroToV07Macro(macro, warn, reportAs = macro) {
|
|
245494
|
+
const path = collapseParentPathParts(
|
|
245495
|
+
flattenedAccessedProps(macro, warn),
|
|
245496
|
+
() => warn(reportAs)
|
|
245497
|
+
);
|
|
244415
245498
|
const { accessedProp, version: version2, attributes, ...rest2 } = macro;
|
|
244416
245499
|
return {
|
|
244417
245500
|
...rest2,
|
|
244418
|
-
attributes: v06AttributeToV07Attribute(mergeAttributes(macro)),
|
|
245501
|
+
attributes: v06AttributeToV07Attribute(mergeAttributes(macro), warn),
|
|
244419
245502
|
path
|
|
244420
245503
|
};
|
|
244421
245504
|
}
|
|
@@ -244433,35 +245516,56 @@ function mergeAttributes(macro) {
|
|
|
244433
245516
|
}
|
|
244434
245517
|
return ret;
|
|
244435
245518
|
}
|
|
244436
|
-
function v06FunctionMacroToV07FunctionMacro(funcMacro) {
|
|
244437
|
-
const macro = v06MacroToV07Macro(funcMacro.macro);
|
|
245519
|
+
function v06FunctionMacroToV07FunctionMacro(funcMacro, warn) {
|
|
245520
|
+
const macro = v06MacroToV07Macro(funcMacro.macro, warn, funcMacro);
|
|
244438
245521
|
return {
|
|
244439
245522
|
type: "function",
|
|
244440
245523
|
path: macro.path,
|
|
244441
|
-
|
|
244442
|
-
// the syntax of function arguments.
|
|
244443
|
-
input: funcMacro.input,
|
|
245524
|
+
input: convertArguments(funcMacro.input, warn),
|
|
244444
245525
|
position: funcMacro.position
|
|
244445
245526
|
};
|
|
244446
245527
|
}
|
|
244447
|
-
function
|
|
245528
|
+
function convertArguments(input, warn) {
|
|
245529
|
+
if (!input) {
|
|
245530
|
+
return null;
|
|
245531
|
+
}
|
|
245532
|
+
return input.map(
|
|
245533
|
+
(argument) => argument.map((node) => {
|
|
245534
|
+
if (isV06MacroOrFunctionMacro(node)) {
|
|
245535
|
+
return node.type === "macro" ? v06MacroToV07Macro(node, warn) : v06FunctionMacroToV07FunctionMacro(node, warn);
|
|
245536
|
+
}
|
|
245537
|
+
return node;
|
|
245538
|
+
})
|
|
245539
|
+
);
|
|
245540
|
+
}
|
|
245541
|
+
function v06IndexToV07Index(index2, warn) {
|
|
244448
245542
|
return index2.map((ind) => ({
|
|
244449
245543
|
...ind,
|
|
244450
|
-
value
|
|
244451
|
-
|
|
244452
|
-
)
|
|
245544
|
+
// @ts-ignore -- see the note on `value` below
|
|
245545
|
+
// The DAST types say an index holds only text and plain macros, but the v0.6
|
|
245546
|
+
// parser does put a function macro in one (`$list[$$(g/h)(2)]`), so both have
|
|
245547
|
+
// to be converted here — this is the only pass that reaches them.
|
|
245548
|
+
value: ind.value.map((v2) => {
|
|
245549
|
+
if (v2.type === "macro") {
|
|
245550
|
+
return v06MacroToV07Macro(v2, warn);
|
|
245551
|
+
}
|
|
245552
|
+
if (v2.type === "function") {
|
|
245553
|
+
return v06FunctionMacroToV07FunctionMacro(v2, warn);
|
|
245554
|
+
}
|
|
245555
|
+
return v2;
|
|
245556
|
+
})
|
|
244453
245557
|
}));
|
|
244454
245558
|
}
|
|
244455
|
-
function v06AttributeToV07Attribute(attrs) {
|
|
245559
|
+
function v06AttributeToV07Attribute(attrs, warn) {
|
|
244456
245560
|
const ret = {};
|
|
244457
245561
|
attrs = Array.isArray(attrs) ? attrs : Object.values(attrs);
|
|
244458
245562
|
for (const attr of attrs) {
|
|
244459
245563
|
const children = attr.children.map((c2) => {
|
|
244460
245564
|
if (c2.type === "macro") {
|
|
244461
|
-
return v06MacroToV07Macro(c2);
|
|
245565
|
+
return v06MacroToV07Macro(c2, warn);
|
|
244462
245566
|
}
|
|
244463
245567
|
if (c2.type === "function") {
|
|
244464
|
-
return v06FunctionMacroToV07FunctionMacro(c2);
|
|
245568
|
+
return v06FunctionMacroToV07FunctionMacro(c2, warn);
|
|
244465
245569
|
}
|
|
244466
245570
|
return c2;
|
|
244467
245571
|
});
|
|
@@ -244472,15 +245576,17 @@ function v06AttributeToV07Attribute(attrs) {
|
|
|
244472
245576
|
}
|
|
244473
245577
|
return ret;
|
|
244474
245578
|
}
|
|
244475
|
-
function flattenedAccessedProps(macro) {
|
|
245579
|
+
function flattenedAccessedProps(macro, warn) {
|
|
244476
245580
|
const path = macro.path.map((p2) => {
|
|
244477
245581
|
return {
|
|
244478
245582
|
...p2,
|
|
244479
|
-
index: v06IndexToV07Index(p2.index)
|
|
245583
|
+
index: v06IndexToV07Index(p2.index, warn)
|
|
244480
245584
|
};
|
|
244481
245585
|
});
|
|
244482
245586
|
if (macro.accessedProp) {
|
|
244483
|
-
|
|
245587
|
+
const propParts = flattenedAccessedProps(macro.accessedProp, warn);
|
|
245588
|
+
propParts.forEach(markAsPropAccess);
|
|
245589
|
+
return [...path, ...propParts];
|
|
244484
245590
|
}
|
|
244485
245591
|
return path;
|
|
244486
245592
|
}
|
|
@@ -245235,9 +246341,26 @@ async function createCoreForLookup({ dast }) {
|
|
|
245235
246341
|
const wasmBuffer = (await import("./lib_doenetml_worker_bg-BJtDoC-f.js")).default;
|
|
245236
246342
|
await __wbg_init({ module_or_path: wasmBuffer });
|
|
245237
246343
|
const rustCore = PublicDoenetMLCore.new();
|
|
245238
|
-
|
|
245239
|
-
|
|
245240
|
-
|
|
246344
|
+
let core2;
|
|
246345
|
+
async function releaseCores() {
|
|
246346
|
+
try {
|
|
246347
|
+
await core2?.terminate();
|
|
246348
|
+
} catch (e4) {
|
|
246349
|
+
}
|
|
246350
|
+
try {
|
|
246351
|
+
rustCore.free();
|
|
246352
|
+
} catch (e4) {
|
|
246353
|
+
}
|
|
246354
|
+
}
|
|
246355
|
+
let normalizedRoot;
|
|
246356
|
+
try {
|
|
246357
|
+
dast = normalizeDocumentDast(structuredClone(dast), true);
|
|
246358
|
+
rustCore.set_source(dast, toXml(dast));
|
|
246359
|
+
normalizedRoot = rustCore.return_normalized_dast_root();
|
|
246360
|
+
} catch (e4) {
|
|
246361
|
+
await releaseCores();
|
|
246362
|
+
throw e4;
|
|
246363
|
+
}
|
|
245241
246364
|
function resolvePath(path, origin, skip_parent_search) {
|
|
245242
246365
|
return rustCore.resolve_path(path, origin, skip_parent_search);
|
|
245243
246366
|
}
|
|
@@ -245248,44 +246371,62 @@ async function createCoreForLookup({ dast }) {
|
|
|
245248
246371
|
rustCore.delete_nodes_from_resolver(node_list);
|
|
245249
246372
|
}
|
|
245250
246373
|
const flags = { ...defaultFlags };
|
|
245251
|
-
|
|
245252
|
-
|
|
245253
|
-
|
|
245254
|
-
|
|
245255
|
-
|
|
245256
|
-
|
|
245257
|
-
|
|
245258
|
-
|
|
245259
|
-
|
|
245260
|
-
|
|
245261
|
-
|
|
245262
|
-
|
|
245263
|
-
|
|
245264
|
-
|
|
245265
|
-
|
|
245266
|
-
|
|
245267
|
-
|
|
245268
|
-
|
|
245269
|
-
|
|
245270
|
-
|
|
245271
|
-
|
|
245272
|
-
|
|
245273
|
-
|
|
245274
|
-
|
|
245275
|
-
|
|
245276
|
-
|
|
245277
|
-
|
|
245278
|
-
|
|
245279
|
-
|
|
245280
|
-
|
|
246374
|
+
try {
|
|
246375
|
+
core2 = new PublicDoenetMLCore$1();
|
|
246376
|
+
core2.setSource(toXml(dast));
|
|
246377
|
+
core2.setFlags(flags);
|
|
246378
|
+
await core2.initializeWorker({
|
|
246379
|
+
activityId: "",
|
|
246380
|
+
docId: "1",
|
|
246381
|
+
requestedVariantIndex: 1,
|
|
246382
|
+
attemptNumber: 1,
|
|
246383
|
+
normalizedRoot,
|
|
246384
|
+
addNodesToResolver,
|
|
246385
|
+
deleteNodesFromResolver,
|
|
246386
|
+
resolvePath
|
|
246387
|
+
});
|
|
246388
|
+
const dastResult = await core2.createCoreGenerateDast(
|
|
246389
|
+
{
|
|
246390
|
+
coreId: "",
|
|
246391
|
+
cid: "",
|
|
246392
|
+
initializeCounters: {},
|
|
246393
|
+
theme: "light"
|
|
246394
|
+
},
|
|
246395
|
+
() => null,
|
|
246396
|
+
() => null,
|
|
246397
|
+
() => null,
|
|
246398
|
+
() => null,
|
|
246399
|
+
() => null,
|
|
246400
|
+
() => null,
|
|
246401
|
+
async () => ({ allowView: true })
|
|
246402
|
+
);
|
|
246403
|
+
if (!dastResult.success) {
|
|
246404
|
+
throw Error(dastResult.errMsg);
|
|
246405
|
+
}
|
|
246406
|
+
} catch (e4) {
|
|
246407
|
+
await releaseCores();
|
|
246408
|
+
throw e4;
|
|
246409
|
+
}
|
|
246410
|
+
const readyCore = core2;
|
|
246411
|
+
if (!readyCore) {
|
|
246412
|
+
await releaseCores();
|
|
246413
|
+
throw Error("The DoenetML core was not initialized.");
|
|
245281
246414
|
}
|
|
245282
246415
|
function resolvePathToNodeIdx(name2, origin = 0) {
|
|
245283
246416
|
if (name2.startsWith("$")) {
|
|
245284
246417
|
name2 = name2.slice(1);
|
|
245285
246418
|
}
|
|
245286
|
-
return resolvePathImmediatelyToNodeIdx(
|
|
246419
|
+
return resolvePathImmediatelyToNodeIdx(
|
|
246420
|
+
name2,
|
|
246421
|
+
rustCore,
|
|
246422
|
+
readyCore,
|
|
246423
|
+
origin
|
|
246424
|
+
);
|
|
245287
246425
|
}
|
|
245288
|
-
|
|
246426
|
+
async function dispose() {
|
|
246427
|
+
await releaseCores();
|
|
246428
|
+
}
|
|
246429
|
+
return { core: readyCore, rustCore, resolvePathToNodeIdx, dispose };
|
|
245289
246430
|
}
|
|
245290
246431
|
const upgradeCopySyntax = () => {
|
|
245291
246432
|
return async (tree, file) => {
|
|
@@ -245302,91 +246443,128 @@ const upgradeCopySyntax = () => {
|
|
|
245302
246443
|
if (skip) {
|
|
245303
246444
|
return;
|
|
245304
246445
|
}
|
|
245305
|
-
|
|
245306
|
-
|
|
245307
|
-
|
|
245308
|
-
|
|
245309
|
-
|
|
245310
|
-
|
|
245311
|
-
|
|
245312
|
-
|
|
245313
|
-
|
|
245314
|
-
}
|
|
245315
|
-
if (node.attributes["prop"]) {
|
|
245316
|
-
const propName = toXml(node.attributes["prop"].children).trim();
|
|
245317
|
-
if (propName) {
|
|
245318
|
-
referentName += `.${propName}`;
|
|
245319
|
-
}
|
|
245320
|
-
delete node.attributes["prop"];
|
|
245321
|
-
}
|
|
245322
|
-
if (node.attributes["assignNames"]) {
|
|
245323
|
-
if (node.attributes["name"]) {
|
|
245324
|
-
file.message(
|
|
245325
|
-
`The <copy> tag with source="${referentName}" has both "name" and "assignNames" attributes. "name" will be ignored.`,
|
|
245326
|
-
node.position?.start
|
|
245327
|
-
);
|
|
245328
|
-
delete node.attributes["name"];
|
|
246446
|
+
let core2;
|
|
246447
|
+
try {
|
|
246448
|
+
core2 = await createCoreForLookup({ dast: tree });
|
|
246449
|
+
} catch (e4) {
|
|
246450
|
+
file.message(
|
|
246451
|
+
`Could not load the document to work out what the <copy> tags refer to, so they were left as they are: ${e4}`,
|
|
246452
|
+
{
|
|
246453
|
+
ruleId: "copy/could-not-load-document",
|
|
246454
|
+
source: "v06-to-v07"
|
|
245329
246455
|
}
|
|
245330
|
-
|
|
246456
|
+
);
|
|
246457
|
+
return;
|
|
246458
|
+
}
|
|
246459
|
+
try {
|
|
246460
|
+
await resolveCopyTags(core2, tree, file);
|
|
246461
|
+
} finally {
|
|
246462
|
+
await core2.dispose();
|
|
246463
|
+
}
|
|
246464
|
+
};
|
|
246465
|
+
};
|
|
246466
|
+
async function resolveCopyTags(core2, tree, file) {
|
|
246467
|
+
const referenced = [];
|
|
246468
|
+
visit(tree, (node) => {
|
|
246469
|
+
if (!isDastElement(node) || node.name !== "copy") {
|
|
246470
|
+
return;
|
|
246471
|
+
}
|
|
246472
|
+
if (Object.keys(node.attributes).some(
|
|
246473
|
+
(key) => key.toLowerCase() === "uri"
|
|
246474
|
+
)) {
|
|
246475
|
+
return;
|
|
246476
|
+
}
|
|
246477
|
+
let referentName = toXml(node.attributes["source"]?.children).trim();
|
|
246478
|
+
if (!referentName) {
|
|
246479
|
+
return;
|
|
246480
|
+
}
|
|
246481
|
+
const propKey = Object.keys(node.attributes).find(
|
|
246482
|
+
(key) => key.toLowerCase() === "prop"
|
|
246483
|
+
);
|
|
246484
|
+
if (propKey) {
|
|
246485
|
+
const propName = toXml(node.attributes[propKey].children).trim();
|
|
246486
|
+
if (propName) {
|
|
246487
|
+
referentName += `.${propName}`;
|
|
245331
246488
|
}
|
|
245332
|
-
|
|
245333
|
-
|
|
245334
|
-
referentType: findReferentType(core2, referentName),
|
|
245335
|
-
referentName
|
|
245336
|
-
});
|
|
245337
|
-
});
|
|
245338
|
-
for (let {
|
|
246489
|
+
}
|
|
246490
|
+
referenced.push({
|
|
245339
246491
|
node,
|
|
245340
|
-
referentType:
|
|
245341
|
-
referentName
|
|
245342
|
-
|
|
245343
|
-
|
|
245344
|
-
|
|
245345
|
-
|
|
245346
|
-
|
|
245347
|
-
|
|
245348
|
-
|
|
245349
|
-
|
|
245350
|
-
|
|
245351
|
-
|
|
245352
|
-
|
|
245353
|
-
|
|
245354
|
-
|
|
245355
|
-
|
|
245356
|
-
|
|
245357
|
-
|
|
245358
|
-
|
|
245359
|
-
|
|
245360
|
-
|
|
245361
|
-
|
|
245362
|
-
continue;
|
|
246492
|
+
referentType: findReferentType(core2, referentName),
|
|
246493
|
+
referentName,
|
|
246494
|
+
propKey
|
|
246495
|
+
});
|
|
246496
|
+
});
|
|
246497
|
+
for (let {
|
|
246498
|
+
node,
|
|
246499
|
+
referentType: referentPromise,
|
|
246500
|
+
referentName,
|
|
246501
|
+
propKey
|
|
246502
|
+
} of referenced) {
|
|
246503
|
+
try {
|
|
246504
|
+
const referentType = await referentPromise;
|
|
246505
|
+
if (propKey) {
|
|
246506
|
+
delete node.attributes[propKey];
|
|
246507
|
+
}
|
|
246508
|
+
const linkKey = Object.keys(node.attributes).find(
|
|
246509
|
+
(key) => key.toLowerCase() === "link"
|
|
246510
|
+
);
|
|
246511
|
+
const targetTag = linkKey ? isV06True(node.attributes[linkKey]) ? "extend" : "copy" : isModuleComponentType(referentType) ? "copy" : "extend";
|
|
246512
|
+
if (linkKey) {
|
|
246513
|
+
delete node.attributes[linkKey];
|
|
245363
246514
|
}
|
|
246515
|
+
renameAttrInPlace(node, "source", targetTag);
|
|
246516
|
+
const bareName = referentName.startsWith("$") ? referentName.slice(1) : referentName;
|
|
246517
|
+
node.attributes[targetTag].children = [
|
|
246518
|
+
{
|
|
246519
|
+
type: "macro",
|
|
246520
|
+
path: parseReferencePath(bareName),
|
|
246521
|
+
attributes: {}
|
|
246522
|
+
}
|
|
246523
|
+
];
|
|
246524
|
+
node.name = referentType;
|
|
246525
|
+
} catch (e4) {
|
|
246526
|
+
file.message(
|
|
246527
|
+
`Could not resolve referent type for <copy> tag with source="${referentName}": ${e4}`,
|
|
246528
|
+
{
|
|
246529
|
+
place: node.position,
|
|
246530
|
+
ruleId: "copy/unresolved-referent",
|
|
246531
|
+
source: "v06-to-v07"
|
|
246532
|
+
}
|
|
246533
|
+
);
|
|
246534
|
+
continue;
|
|
245364
246535
|
}
|
|
245365
|
-
};
|
|
245366
|
-
};
|
|
245367
|
-
async function findReferentType(core2, referentName) {
|
|
245368
|
-
if (!referentName.startsWith("$")) {
|
|
245369
|
-
referentName = `$${referentName}`;
|
|
245370
246536
|
}
|
|
245371
|
-
|
|
245372
|
-
|
|
245373
|
-
|
|
246537
|
+
}
|
|
246538
|
+
async function findReferentType(core2, referentName) {
|
|
246539
|
+
const bare = referentName.startsWith("$") ? referentName.slice(1) : referentName;
|
|
246540
|
+
let path;
|
|
246541
|
+
try {
|
|
246542
|
+
path = parseReferencePath(bare);
|
|
246543
|
+
} catch (e4) {
|
|
245374
246544
|
throw new Error(`Could not parse referent name "${referentName}"`);
|
|
245375
246545
|
}
|
|
245376
246546
|
let unresolvedIndex = [];
|
|
245377
246547
|
let unresolvedProps = [];
|
|
245378
246548
|
let referentType = void 0;
|
|
245379
|
-
for (let i2 = path.length; i2 > 0; i2--) {
|
|
246549
|
+
search: for (let i2 = path.length; i2 > 0; i2--) {
|
|
245380
246550
|
const pathParts = path.slice(0, i2);
|
|
245381
|
-
const
|
|
245382
|
-
|
|
245383
|
-
|
|
245384
|
-
|
|
245385
|
-
|
|
245386
|
-
|
|
245387
|
-
|
|
245388
|
-
|
|
246551
|
+
for (const keepIndices of [true, false]) {
|
|
246552
|
+
if (keepIndices && !hasOnlyLiteralIndices(pathParts)) {
|
|
246553
|
+
continue;
|
|
246554
|
+
}
|
|
246555
|
+
const pathStr = keepIndices ? printPath(pathParts) : printPathWithoutIndices(pathParts);
|
|
246556
|
+
const referentIdx = await core2.resolvePathToNodeIdx(pathStr);
|
|
246557
|
+
if (referentIdx === -1) {
|
|
246558
|
+
continue;
|
|
245389
246559
|
}
|
|
246560
|
+
const foundType = core2.core.core?.components?.[referentIdx]?.componentType;
|
|
246561
|
+
if (!foundType || foundType.startsWith("_")) {
|
|
246562
|
+
continue;
|
|
246563
|
+
}
|
|
246564
|
+
referentType = foundType;
|
|
246565
|
+
unresolvedIndex = keepIndices ? [] : pathParts.flatMap((part) => part.index);
|
|
246566
|
+
unresolvedProps = path.slice(i2);
|
|
246567
|
+
break search;
|
|
245390
246568
|
}
|
|
245391
246569
|
}
|
|
245392
246570
|
if (unresolvedIndex.length !== 0) {
|
|
@@ -245408,14 +246586,287 @@ async function findReferentType(core2, referentName) {
|
|
|
245408
246586
|
}
|
|
245409
246587
|
throw new Error(`Could not find referent type for "${referentName}"`);
|
|
245410
246588
|
}
|
|
246589
|
+
function hasOnlyLiteralIndices(pathParts) {
|
|
246590
|
+
return pathParts.every(
|
|
246591
|
+
(part) => part.index.every(
|
|
246592
|
+
(index2) => index2.value.length === 1 && index2.value[0].type === "text" && /^\d+$/.test(index2.value[0].value.trim())
|
|
246593
|
+
)
|
|
246594
|
+
);
|
|
246595
|
+
}
|
|
246596
|
+
function printPath(pathParts) {
|
|
246597
|
+
return pathParts.map(
|
|
246598
|
+
(part) => part.name + part.index.map((index2) => `[${toXml(index2.value).trim()}]`).join("")
|
|
246599
|
+
).join(".");
|
|
246600
|
+
}
|
|
245411
246601
|
function printPathWithoutIndices(pathParts) {
|
|
245412
246602
|
return pathParts.map((part) => {
|
|
245413
246603
|
return part.name;
|
|
245414
246604
|
}).join(".");
|
|
245415
246605
|
}
|
|
245416
|
-
const
|
|
246606
|
+
const upgradeCopyElements = (context) => {
|
|
246607
|
+
return (tree, file) => {
|
|
246608
|
+
visit(tree, (node, info) => {
|
|
246609
|
+
if (!isDastElement(node)) {
|
|
246610
|
+
return;
|
|
246611
|
+
}
|
|
246612
|
+
if (node.name.toLowerCase() === "ref") {
|
|
246613
|
+
warnAboutExternalRef(node, file);
|
|
246614
|
+
return;
|
|
246615
|
+
}
|
|
246616
|
+
if (node.name.toLowerCase() !== "copy") {
|
|
246617
|
+
return;
|
|
246618
|
+
}
|
|
246619
|
+
convertAssignNames(
|
|
246620
|
+
node,
|
|
246621
|
+
namespaceChainOf(info.parents, context),
|
|
246622
|
+
context,
|
|
246623
|
+
file
|
|
246624
|
+
);
|
|
246625
|
+
const uriKey = findKey$1(node, "uri");
|
|
246626
|
+
if (!uriKey) {
|
|
246627
|
+
return;
|
|
246628
|
+
}
|
|
246629
|
+
const uri = toXml(node.attributes[uriKey].children).trim();
|
|
246630
|
+
if (!uri.toLowerCase().startsWith("doenet:")) {
|
|
246631
|
+
return;
|
|
246632
|
+
}
|
|
246633
|
+
const passedAttributes = Object.keys(node.attributes).filter(
|
|
246634
|
+
(key) => !COPY_OWN_ATTRIBUTES.has(key.toLowerCase())
|
|
246635
|
+
);
|
|
246636
|
+
if (passedAttributes.length === 0) {
|
|
246637
|
+
file.message(
|
|
246638
|
+
`<copy uri="${uri}"> could not be converted: v0.7 loads external content with a "copy" attribute on an element of the same component type as the external document, and this copy passes no attributes to indicate what that type is. Replace it with, for example, <problem copy="doenet:<contentId>" /> once the target has been converted.`,
|
|
246639
|
+
{
|
|
246640
|
+
place: node.position,
|
|
246641
|
+
ruleId: "external-copy/unknown-component-type",
|
|
246642
|
+
source: "v06-to-v07"
|
|
246643
|
+
}
|
|
246644
|
+
);
|
|
246645
|
+
return;
|
|
246646
|
+
}
|
|
246647
|
+
const narrowing = Object.keys(node.attributes).filter(
|
|
246648
|
+
(key) => COPY_NARROWING_ATTRIBUTES.has(key.toLowerCase())
|
|
246649
|
+
);
|
|
246650
|
+
if (narrowing.length > 0) {
|
|
246651
|
+
file.message(
|
|
246652
|
+
`<copy uri="${uri}"> could not be converted because it also sets ${narrowing.join(
|
|
246653
|
+
", "
|
|
246654
|
+
)}, which changes what it copies; v0.7 has no way to say that on the element that loads an external document. Convert it by hand.`,
|
|
246655
|
+
{
|
|
246656
|
+
place: node.position,
|
|
246657
|
+
ruleId: "external-copy/narrowed",
|
|
246658
|
+
source: "v06-to-v07"
|
|
246659
|
+
}
|
|
246660
|
+
);
|
|
246661
|
+
return;
|
|
246662
|
+
}
|
|
246663
|
+
const dropped = Object.keys(node.attributes).filter(
|
|
246664
|
+
(key) => COPY_CONTROL_ATTRIBUTES.has(key.toLowerCase())
|
|
246665
|
+
);
|
|
246666
|
+
for (const key of dropped) {
|
|
246667
|
+
delete node.attributes[key];
|
|
246668
|
+
}
|
|
246669
|
+
const linkKey = findKey$1(node, "link");
|
|
246670
|
+
const targetTag = linkKey && isV06True(node.attributes[linkKey]) ? "extend" : "copy";
|
|
246671
|
+
if (linkKey) {
|
|
246672
|
+
delete node.attributes[linkKey];
|
|
246673
|
+
}
|
|
246674
|
+
node.name = "module";
|
|
246675
|
+
renameAttrInPlace(node, uriKey, targetTag);
|
|
246676
|
+
if (dropped.length > 0) {
|
|
246677
|
+
file.message(
|
|
246678
|
+
`Dropped ${dropped.join(
|
|
246679
|
+
", "
|
|
246680
|
+
)} from <copy uri="${uri}">: they controlled how v0.6 copied, and a <module ${targetTag}="doenet:..."> has no equivalent.`,
|
|
246681
|
+
{
|
|
246682
|
+
place: node.position,
|
|
246683
|
+
ruleId: "external-copy/dropped-copy-controls",
|
|
246684
|
+
source: "v06-to-v07"
|
|
246685
|
+
}
|
|
246686
|
+
);
|
|
246687
|
+
}
|
|
246688
|
+
file.message(
|
|
246689
|
+
`Converted <copy uri="${uri}"> to <module ${targetTag}="${uri}">, passing ${passedAttributes.join(", ")}. The identifier in the URI is a v0.6 one; replace it with the v0.7 content id of the converted module, and check that the target really is a <module>.`,
|
|
246690
|
+
{
|
|
246691
|
+
place: node.position,
|
|
246692
|
+
ruleId: "external-copy/needs-new-content-id",
|
|
246693
|
+
source: "v06-to-v07"
|
|
246694
|
+
}
|
|
246695
|
+
);
|
|
246696
|
+
});
|
|
246697
|
+
};
|
|
246698
|
+
};
|
|
246699
|
+
const COPY_NARROWING_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
246700
|
+
"componentindex",
|
|
246701
|
+
"createcomponentoftype",
|
|
246702
|
+
"numcomponents",
|
|
246703
|
+
"obtainpropfromcomposite",
|
|
246704
|
+
"prop",
|
|
246705
|
+
"propindex",
|
|
246706
|
+
"removeemptyarrayentries",
|
|
246707
|
+
"source",
|
|
246708
|
+
"sourceindex",
|
|
246709
|
+
"sourcesubnames",
|
|
246710
|
+
"sourcesubnamescomponentindex",
|
|
246711
|
+
"target",
|
|
246712
|
+
"tname"
|
|
246713
|
+
]);
|
|
246714
|
+
const COPY_CONTROL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
246715
|
+
"assignnamesskip",
|
|
246716
|
+
"assignnewnamespaces",
|
|
246717
|
+
"sourceattributestoignore"
|
|
246718
|
+
]);
|
|
246719
|
+
const COPY_OWN_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
246720
|
+
"assignnames",
|
|
246721
|
+
"assignnamesskip",
|
|
246722
|
+
"assignnewnamespaces",
|
|
246723
|
+
"componentindex",
|
|
246724
|
+
"createcomponentoftype",
|
|
246725
|
+
"link",
|
|
246726
|
+
"name",
|
|
246727
|
+
"newnamespace",
|
|
246728
|
+
"numcomponents",
|
|
246729
|
+
"obtainpropfromcomposite",
|
|
246730
|
+
"prop",
|
|
246731
|
+
"propindex",
|
|
246732
|
+
"removeemptyarrayentries",
|
|
246733
|
+
"source",
|
|
246734
|
+
"sourceattributestoignore",
|
|
246735
|
+
"sourceindex",
|
|
246736
|
+
"sourcesubnames",
|
|
246737
|
+
"sourcesubnamescomponentindex",
|
|
246738
|
+
"target",
|
|
246739
|
+
"tname",
|
|
246740
|
+
"uri"
|
|
246741
|
+
]);
|
|
246742
|
+
function convertAssignNames(node, ancestorNames, context, file) {
|
|
246743
|
+
const assignNamesValue = readAssignNames(node);
|
|
246744
|
+
if (!assignNamesValue) {
|
|
246745
|
+
deleteAssignNames(node);
|
|
246746
|
+
return;
|
|
246747
|
+
}
|
|
246748
|
+
const origin = {
|
|
246749
|
+
elementName: node.name,
|
|
246750
|
+
position: node.position,
|
|
246751
|
+
ancestorNames,
|
|
246752
|
+
element: node
|
|
246753
|
+
};
|
|
246754
|
+
const parsed = breakStringInPiecesBySpacesOrParens(assignNamesValue);
|
|
246755
|
+
const names = parsed.success && parsed.pieces.every((p2) => typeof p2 === "string") ? parsed.pieces : void 0;
|
|
246756
|
+
if (!names || names.length !== 1) {
|
|
246757
|
+
file.message(
|
|
246758
|
+
`assignNames="${assignNamesValue}" on <${node.name}> could not be converted: the names refer to the replacements of the copied component, and this converter cannot tell how many of those there are. References to those names need fixing by hand.`,
|
|
246759
|
+
{
|
|
246760
|
+
place: node.position,
|
|
246761
|
+
ruleId: "copy/unmapped-assign-names",
|
|
246762
|
+
source: "v06-to-v07"
|
|
246763
|
+
}
|
|
246764
|
+
);
|
|
246765
|
+
deleteAssignNames(node);
|
|
246766
|
+
return;
|
|
246767
|
+
}
|
|
246768
|
+
const [assignedName] = names;
|
|
246769
|
+
const existingName = toXml(
|
|
246770
|
+
node.attributes[findKey$1(node, "name") ?? ""]?.children ?? []
|
|
246771
|
+
).trim();
|
|
246772
|
+
const nameIsUnusable = !isValidReferenceableName(assignedName);
|
|
246773
|
+
const nameBelongsToAnother = nameIsUnusable || nameTakenInScope(context, assignedName, ancestorNames);
|
|
246774
|
+
const nameIsTaken = nameBelongsToAnother || context.existingNames.has(assignedName) || context.claimedNames.has(assignedName);
|
|
246775
|
+
if (existingName && !isValidReferenceableName(existingName)) {
|
|
246776
|
+
file.message(
|
|
246777
|
+
`<${node.name}> is called "${existingName}", which v0.7 cannot use as a name — it must start with a letter and hold only letters, digits, underscores and hyphens. A generated name was used instead and references to "${assignedName}" were left alone.`,
|
|
246778
|
+
{
|
|
246779
|
+
place: node.position,
|
|
246780
|
+
ruleId: "assign-names/invalid-name",
|
|
246781
|
+
source: "v06-to-v07"
|
|
246782
|
+
}
|
|
246783
|
+
);
|
|
246784
|
+
deleteAssignNames(node);
|
|
246785
|
+
setCompositeName(node, context.uniqueName("copy"));
|
|
246786
|
+
return;
|
|
246787
|
+
}
|
|
246788
|
+
if (existingName) {
|
|
246789
|
+
if (existingName !== assignedName && !nameBelongsToAnother) {
|
|
246790
|
+
context.registry.register(
|
|
246791
|
+
assignedName,
|
|
246792
|
+
[makeIndexedPathPart(existingName, [])],
|
|
246793
|
+
origin,
|
|
246794
|
+
file
|
|
246795
|
+
);
|
|
246796
|
+
} else if (existingName !== assignedName) {
|
|
246797
|
+
reportUnusableName(node, assignedName, nameIsUnusable, file);
|
|
246798
|
+
}
|
|
246799
|
+
deleteAssignNames(node);
|
|
246800
|
+
setCompositeName(node, existingName);
|
|
246801
|
+
return;
|
|
246802
|
+
}
|
|
246803
|
+
if (nameIsTaken) {
|
|
246804
|
+
const generated = context.uniqueName("copy");
|
|
246805
|
+
if (nameBelongsToAnother) {
|
|
246806
|
+
reportUnusableName(node, assignedName, nameIsUnusable, file);
|
|
246807
|
+
} else {
|
|
246808
|
+
context.registry.register(
|
|
246809
|
+
assignedName,
|
|
246810
|
+
[makeIndexedPathPart(generated, [])],
|
|
246811
|
+
origin,
|
|
246812
|
+
file
|
|
246813
|
+
);
|
|
246814
|
+
}
|
|
246815
|
+
deleteAssignNames(node);
|
|
246816
|
+
setCompositeName(node, generated);
|
|
246817
|
+
return;
|
|
246818
|
+
}
|
|
246819
|
+
context.claimedNames.add(assignedName);
|
|
246820
|
+
context.registry.register(assignedName, void 0, origin, file);
|
|
246821
|
+
setCompositeName(node, assignedName);
|
|
246822
|
+
}
|
|
246823
|
+
function warnAboutExternalRef(node, file) {
|
|
246824
|
+
const toKey = findKey$1(node, "to");
|
|
246825
|
+
if (!toKey) {
|
|
246826
|
+
return;
|
|
246827
|
+
}
|
|
246828
|
+
const target = toXml(node.attributes[toKey].children).trim();
|
|
246829
|
+
if (!/^doenet:.*(activityId|doenetId|cid|pageId)=/i.test(target)) {
|
|
246830
|
+
return;
|
|
246831
|
+
}
|
|
246832
|
+
file.message(
|
|
246833
|
+
`<ref to="${target}"> points at a v0.6 activity; replace the identifier with the v0.7 content id (or a doenet.org URL) of the converted document.`,
|
|
246834
|
+
{
|
|
246835
|
+
place: node.position,
|
|
246836
|
+
ruleId: "external-ref/needs-new-content-id",
|
|
246837
|
+
source: "v06-to-v07"
|
|
246838
|
+
}
|
|
246839
|
+
);
|
|
246840
|
+
}
|
|
246841
|
+
function reportUnusableName(node, assignedName, nameIsUnusable, file) {
|
|
246842
|
+
if (nameIsUnusable) {
|
|
246843
|
+
file.message(
|
|
246844
|
+
`<${node.name}> assigns the name "${assignedName}", which v0.7 cannot use as a name — it must start with a letter and hold only letters, digits, underscores and hyphens. A generated name was used instead and references to "${assignedName}" were left alone.`,
|
|
246845
|
+
{
|
|
246846
|
+
place: node.position,
|
|
246847
|
+
ruleId: "assign-names/invalid-name",
|
|
246848
|
+
source: "v06-to-v07"
|
|
246849
|
+
}
|
|
246850
|
+
);
|
|
246851
|
+
return;
|
|
246852
|
+
}
|
|
246853
|
+
file.message(
|
|
246854
|
+
`<${node.name}> assigns the name "${assignedName}", but something else in the document is already called that. References to "${assignedName}" were left pointing where they already pointed.`,
|
|
246855
|
+
{
|
|
246856
|
+
place: node.position,
|
|
246857
|
+
ruleId: "copy/name-already-taken",
|
|
246858
|
+
source: "v06-to-v07"
|
|
246859
|
+
}
|
|
246860
|
+
);
|
|
246861
|
+
}
|
|
246862
|
+
function findKey$1(node, attrName) {
|
|
246863
|
+
return Object.keys(node.attributes).find(
|
|
246864
|
+
(key) => key.toLowerCase() === attrName.toLowerCase()
|
|
246865
|
+
);
|
|
246866
|
+
}
|
|
246867
|
+
const upgradeAttributeSyntax = (context) => {
|
|
245417
246868
|
return async (tree, file) => {
|
|
245418
|
-
visit(tree, (node) => {
|
|
246869
|
+
visit(tree, (node, info) => {
|
|
245419
246870
|
if (node.type !== "macro") {
|
|
245420
246871
|
return;
|
|
245421
246872
|
}
|
|
@@ -245441,6 +246892,18 @@ const upgradeAttributeSyntax = () => {
|
|
|
245441
246892
|
}
|
|
245442
246893
|
});
|
|
245443
246894
|
Object.assign(node, copy2);
|
|
246895
|
+
const assigned = readAssignNames(node);
|
|
246896
|
+
convertAssignNames(
|
|
246897
|
+
node,
|
|
246898
|
+
namespaceChainOf(info.parents, context),
|
|
246899
|
+
context,
|
|
246900
|
+
file
|
|
246901
|
+
);
|
|
246902
|
+
warnIfNameCouldNotBeKept(
|
|
246903
|
+
node,
|
|
246904
|
+
assigned,
|
|
246905
|
+
file
|
|
246906
|
+
);
|
|
245444
246907
|
});
|
|
245445
246908
|
const macrosInAttributes = [];
|
|
245446
246909
|
visit(tree, (node, info) => {
|
|
@@ -245534,39 +246997,34 @@ const upgradeAttributeSyntax = () => {
|
|
|
245534
246997
|
documentElement.children.unshift(setupTag);
|
|
245535
246998
|
};
|
|
245536
246999
|
};
|
|
245537
|
-
|
|
247000
|
+
function warnIfNameCouldNotBeKept(node, assigned, file) {
|
|
247001
|
+
if (!assigned) {
|
|
247002
|
+
return;
|
|
247003
|
+
}
|
|
247004
|
+
const name2 = toXml(node.attributes["name"]?.children ?? []).trim();
|
|
247005
|
+
if (name2 === assigned.trim()) {
|
|
247006
|
+
return;
|
|
247007
|
+
}
|
|
247008
|
+
file.message(
|
|
247009
|
+
`A reference wrote assignNames="${assigned}" in its attributes, and that name could not be kept${name2 ? ` (the element is now named "${name2}")` : ""}. References to "${assigned}" need fixing by hand.`,
|
|
247010
|
+
{
|
|
247011
|
+
place: node.position,
|
|
247012
|
+
ruleId: "assign-names/late-attribute-assignment",
|
|
247013
|
+
source: "v06-to-v07"
|
|
247014
|
+
}
|
|
247015
|
+
);
|
|
247016
|
+
}
|
|
247017
|
+
const upgradeMapElement = (context) => {
|
|
245538
247018
|
return (tree, file) => {
|
|
245539
|
-
|
|
245540
|
-
replaceNode(tree, (node) => {
|
|
247019
|
+
replaceNode(tree, (node, info) => {
|
|
245541
247020
|
if (!isDastElement(node)) {
|
|
245542
247021
|
return;
|
|
245543
247022
|
}
|
|
245544
|
-
if (node.name !== "map") {
|
|
247023
|
+
if (node.name.toLowerCase() !== "map") {
|
|
245545
247024
|
return;
|
|
245546
247025
|
}
|
|
245547
|
-
|
|
245548
|
-
const
|
|
245549
|
-
if (name2 && assignNames.length > 0) {
|
|
245550
|
-
assignNames.forEach((assignName, index2) => {
|
|
245551
|
-
refsToRename[assignName] = [
|
|
245552
|
-
{
|
|
245553
|
-
type: "pathPart",
|
|
245554
|
-
name: name2,
|
|
245555
|
-
index: [
|
|
245556
|
-
{
|
|
245557
|
-
type: "index",
|
|
245558
|
-
value: [
|
|
245559
|
-
{
|
|
245560
|
-
type: "text",
|
|
245561
|
-
value: `${index2 + 1}`
|
|
245562
|
-
}
|
|
245563
|
-
]
|
|
245564
|
-
}
|
|
245565
|
-
]
|
|
245566
|
-
}
|
|
245567
|
-
];
|
|
245568
|
-
});
|
|
245569
|
-
}
|
|
247026
|
+
let name2 = toXml(node.attributes["name"]?.children).trim();
|
|
247027
|
+
const assignNamesValue = readAssignNames(node);
|
|
245570
247028
|
const templateNode = node.children.find(
|
|
245571
247029
|
(child) => isDastElement(child) && child.name === "template"
|
|
245572
247030
|
);
|
|
@@ -245576,10 +247034,32 @@ const upgradeMapElement = () => {
|
|
|
245576
247034
|
if (!templateNode || !isDastElement(templateNode) || !sourcesNode || !isDastElement(sourcesNode)) {
|
|
245577
247035
|
file.message(
|
|
245578
247036
|
`Map element must have both a template and sources children to be converted`,
|
|
245579
|
-
{
|
|
247037
|
+
{
|
|
247038
|
+
place: node.position,
|
|
247039
|
+
ruleId: "map/missing-template-or-sources",
|
|
247040
|
+
source: "v06-to-v07"
|
|
247041
|
+
}
|
|
245580
247042
|
);
|
|
245581
247043
|
return;
|
|
245582
247044
|
}
|
|
247045
|
+
if (assignNamesValue) {
|
|
247046
|
+
name2 = registerCompositeAssignNames({
|
|
247047
|
+
node,
|
|
247048
|
+
assignNamesValue,
|
|
247049
|
+
fallbackBase: "repeat",
|
|
247050
|
+
ancestorNames: namespaceChainOf(info.parents, context),
|
|
247051
|
+
context,
|
|
247052
|
+
file,
|
|
247053
|
+
// A nested name such as `assignNames="(a b)"` counts positions
|
|
247054
|
+
// inside one iteration, which are the template's children — and
|
|
247055
|
+
// v0.6 skipped bare text there while v0.7 counts it.
|
|
247056
|
+
positionMap: makeTemplatePositionMap(
|
|
247057
|
+
templateNode,
|
|
247058
|
+
node,
|
|
247059
|
+
file
|
|
247060
|
+
)
|
|
247061
|
+
}) ?? name2;
|
|
247062
|
+
}
|
|
245583
247063
|
const valueName = toXml(
|
|
245584
247064
|
sourcesNode.attributes["alias"]?.children
|
|
245585
247065
|
).trim();
|
|
@@ -245591,6 +247071,7 @@ const upgradeMapElement = () => {
|
|
|
245591
247071
|
(child) => isDastElement(child) && child.name === "sequence"
|
|
245592
247072
|
)) {
|
|
245593
247073
|
if (name2) {
|
|
247074
|
+
warnIfNameLost(sequenceNode, name2, file);
|
|
245594
247075
|
sequenceNode.attributes["name"] = {
|
|
245595
247076
|
type: "attribute",
|
|
245596
247077
|
name: "name",
|
|
@@ -245598,6 +247079,7 @@ const upgradeMapElement = () => {
|
|
|
245598
247079
|
};
|
|
245599
247080
|
}
|
|
245600
247081
|
sequenceNode.name = "repeatForSequence";
|
|
247082
|
+
inheritNamespace(templateNode, sequenceNode, context);
|
|
245601
247083
|
if (valueName) {
|
|
245602
247084
|
sequenceNode.attributes["valueName"] = {
|
|
245603
247085
|
type: "attribute",
|
|
@@ -245627,12 +247109,15 @@ const upgradeMapElement = () => {
|
|
|
245627
247109
|
attributes: {},
|
|
245628
247110
|
children: [groupTag]
|
|
245629
247111
|
};
|
|
245630
|
-
const groupName =
|
|
247112
|
+
const groupName = context.uniqueName("group");
|
|
245631
247113
|
groupTag.attributes["name"] = {
|
|
245632
247114
|
type: "attribute",
|
|
245633
247115
|
name: "name",
|
|
245634
247116
|
children: reparseAttribute(groupName)
|
|
245635
247117
|
};
|
|
247118
|
+
if (name2) {
|
|
247119
|
+
warnIfNameLost(templateNode, name2, file);
|
|
247120
|
+
}
|
|
245636
247121
|
templateNode.name = "repeat";
|
|
245637
247122
|
templateNode.attributes["for"] = {
|
|
245638
247123
|
type: "attribute",
|
|
@@ -245663,19 +247148,22 @@ const upgradeMapElement = () => {
|
|
|
245663
247148
|
return [setupTag, templateNode];
|
|
245664
247149
|
}
|
|
245665
247150
|
});
|
|
245666
|
-
visit(tree, (node) => {
|
|
245667
|
-
if (node.type !== "macro") {
|
|
245668
|
-
return;
|
|
245669
|
-
}
|
|
245670
|
-
if (!node.path.some((part) => refsToRename[part.name])) {
|
|
245671
|
-
return;
|
|
245672
|
-
}
|
|
245673
|
-
node.path = node.path.flatMap((part) => {
|
|
245674
|
-
return refsToRename[part.name] || [part];
|
|
245675
|
-
});
|
|
245676
|
-
});
|
|
245677
247151
|
};
|
|
245678
247152
|
};
|
|
247153
|
+
function warnIfNameLost(node, newName, file) {
|
|
247154
|
+
const existing = toXml(node.attributes["name"]?.children).trim();
|
|
247155
|
+
if (!existing || existing === newName) {
|
|
247156
|
+
return;
|
|
247157
|
+
}
|
|
247158
|
+
file.message(
|
|
247159
|
+
`<${node.name} name="${existing}"> becomes the <repeat> that takes the name "${newName}", so "${existing}" is gone; references to it need fixing by hand.`,
|
|
247160
|
+
{
|
|
247161
|
+
place: node.position,
|
|
247162
|
+
ruleId: "map/name-overwritten",
|
|
247163
|
+
source: "v06-to-v07"
|
|
247164
|
+
}
|
|
247165
|
+
);
|
|
247166
|
+
}
|
|
245679
247167
|
const upgradeModuleElement = () => {
|
|
245680
247168
|
return (tree, file) => {
|
|
245681
247169
|
visit(tree, (node) => {
|
|
@@ -245691,14 +247179,30 @@ const upgradeModuleElement = () => {
|
|
|
245691
247179
|
if (!setupNode) {
|
|
245692
247180
|
return;
|
|
245693
247181
|
}
|
|
245694
|
-
|
|
245695
|
-
(child) => !isDastElement(child) || child.name !== "setup"
|
|
245696
|
-
);
|
|
247182
|
+
const isCustomAttribute = (child) => isDastElement(child) && child.name === "customAttribute";
|
|
245697
247183
|
const customAttributeNodes = setupNode.children.filter(
|
|
245698
|
-
(child) =>
|
|
247184
|
+
(child) => isCustomAttribute(child)
|
|
247185
|
+
);
|
|
247186
|
+
const otherSetupChildren = setupNode.children.filter(
|
|
247187
|
+
(child) => !isCustomAttribute(child)
|
|
245699
247188
|
);
|
|
245700
247189
|
setupNode.children = [];
|
|
245701
247190
|
setupNode.name = "moduleAttributes";
|
|
247191
|
+
if (otherSetupChildren.some(
|
|
247192
|
+
(child) => child.type !== "text" || child.value.trim() !== ""
|
|
247193
|
+
)) {
|
|
247194
|
+
const newSetup = {
|
|
247195
|
+
type: "element",
|
|
247196
|
+
name: "setup",
|
|
247197
|
+
attributes: {},
|
|
247198
|
+
children: otherSetupChildren
|
|
247199
|
+
};
|
|
247200
|
+
node.children.splice(
|
|
247201
|
+
node.children.indexOf(setupNode) + 1,
|
|
247202
|
+
0,
|
|
247203
|
+
newSetup
|
|
247204
|
+
);
|
|
247205
|
+
}
|
|
245702
247206
|
for (const customAttributeNode of customAttributeNodes) {
|
|
245703
247207
|
const name2 = toXml(
|
|
245704
247208
|
customAttributeNode.attributes["assignNames"]?.children
|
|
@@ -245710,7 +247214,9 @@ const upgradeModuleElement = () => {
|
|
|
245710
247214
|
file.message(
|
|
245711
247215
|
`Module "customAttribute" is missing a "componentType"; the syntax cannot be upgraded with a "componentType".`,
|
|
245712
247216
|
{
|
|
245713
|
-
place: customAttributeNode.position
|
|
247217
|
+
place: customAttributeNode.position,
|
|
247218
|
+
ruleId: "module/custom-attribute-without-type",
|
|
247219
|
+
source: "v06-to-v07"
|
|
245714
247220
|
}
|
|
245715
247221
|
);
|
|
245716
247222
|
continue;
|
|
@@ -245773,10 +247279,459 @@ const removeDefinitionsElement = () => {
|
|
|
245773
247279
|
});
|
|
245774
247280
|
};
|
|
245775
247281
|
};
|
|
247282
|
+
const GLOBAL_RULES = {
|
|
247283
|
+
// v0.6 renamed `targets*` to `sources*`; v0.7 renamed them again to `references*`.
|
|
247284
|
+
sourcesareresponses: {
|
|
247285
|
+
kind: "renameToReferenceList",
|
|
247286
|
+
to: "referencesAreResponses"
|
|
247287
|
+
},
|
|
247288
|
+
targetsareresponses: {
|
|
247289
|
+
kind: "renameToReferenceList",
|
|
247290
|
+
to: "referencesAreResponses"
|
|
247291
|
+
},
|
|
247292
|
+
sourcesarefunctionsymbols: {
|
|
247293
|
+
kind: "renameToReferenceList",
|
|
247294
|
+
to: "referencesAreFunctionSymbols"
|
|
247295
|
+
},
|
|
247296
|
+
targetsarefunctionsymbols: {
|
|
247297
|
+
kind: "renameToReferenceList",
|
|
247298
|
+
to: "referencesAreFunctionSymbols"
|
|
247299
|
+
},
|
|
247300
|
+
triggerwithtargets: { kind: "renameToReferenceList", to: "triggerWith" },
|
|
247301
|
+
triggerwithtnames: { kind: "renameToReferenceList", to: "triggerWith" },
|
|
247302
|
+
updatewithtname: { kind: "rename", to: "updateWith" },
|
|
247303
|
+
updatewithtarget: { kind: "rename", to: "updateWith" },
|
|
247304
|
+
// `tname` was the pre-v0.6 spelling of the attribute naming what to act on. On
|
|
247305
|
+
// components that *copy*, it became `source`; everywhere else it became `target`.
|
|
247306
|
+
// The element-specific tables below override this for the copying components.
|
|
247307
|
+
tname: { kind: "rename", to: "target" }
|
|
247308
|
+
};
|
|
247309
|
+
const ELEMENT_RULES = {
|
|
247310
|
+
copy: { tname: { kind: "rename", to: "source" } },
|
|
247311
|
+
collect: {
|
|
247312
|
+
tname: { kind: "rename", to: "source" },
|
|
247313
|
+
draggable: {
|
|
247314
|
+
kind: "remove",
|
|
247315
|
+
because: "<collect> does not take `draggable` in v0.7"
|
|
247316
|
+
}
|
|
247317
|
+
},
|
|
247318
|
+
extract: { tname: { kind: "rename", to: "source" } },
|
|
247319
|
+
updatevalue: {
|
|
247320
|
+
// `<updateValue target="x" prop="y">` is a single path in v0.7.
|
|
247321
|
+
prop: { kind: "mergeInto", target: "target" }
|
|
247322
|
+
},
|
|
247323
|
+
animatefromsequence: { prop: { kind: "mergeInto", target: "target" } },
|
|
247324
|
+
ref: {
|
|
247325
|
+
page: {
|
|
247326
|
+
kind: "remove",
|
|
247327
|
+
because: "v0.7 documents are not paginated, so <ref> has no `page`; link to the individual document instead",
|
|
247328
|
+
ruleId: "deprecated/ref-page"
|
|
247329
|
+
}
|
|
247330
|
+
},
|
|
247331
|
+
variantcontrol: { nvariants: { kind: "rename", to: "numVariants" } },
|
|
247332
|
+
option: {
|
|
247333
|
+
selectforvariantnames: { kind: "rename", to: "selectForVariants" }
|
|
247334
|
+
},
|
|
247335
|
+
graph: {
|
|
247336
|
+
xlabel: { kind: "toChildElement", elementName: "xLabel" },
|
|
247337
|
+
ylabel: { kind: "toChildElement", elementName: "yLabel" },
|
|
247338
|
+
height: {
|
|
247339
|
+
kind: "remove",
|
|
247340
|
+
because: "v0.7 graphs are sized with `size`, `width` and `aspectRatio`"
|
|
247341
|
+
}
|
|
247342
|
+
},
|
|
247343
|
+
image: {
|
|
247344
|
+
// v0.6 rendered `description` as the image's `alt` text. v0.7 carries that in a
|
|
247345
|
+
// `<shortDescription>` child, which the reference pages describe as required for
|
|
247346
|
+
// accessibility, so this must be converted rather than dropped.
|
|
247347
|
+
description: {
|
|
247348
|
+
kind: "toChildElement",
|
|
247349
|
+
elementName: "shortDescription"
|
|
247350
|
+
}
|
|
247351
|
+
},
|
|
247352
|
+
conditionalcontent: {
|
|
247353
|
+
maximumnumbertoshow: {
|
|
247354
|
+
kind: "remove",
|
|
247355
|
+
because: "v0.7 <conditionalContent> always shows one case"
|
|
247356
|
+
}
|
|
247357
|
+
},
|
|
247358
|
+
embed: {
|
|
247359
|
+
encodedgeogebracontent: {
|
|
247360
|
+
kind: "unsupported",
|
|
247361
|
+
because: "v0.7 has no <embed> element and no GeoGebra support; this content must be replaced by hand",
|
|
247362
|
+
ruleId: "no-v07-equivalent/embed-geogebra"
|
|
247363
|
+
}
|
|
247364
|
+
},
|
|
247365
|
+
point: {
|
|
247366
|
+
link: {
|
|
247367
|
+
kind: "remove",
|
|
247368
|
+
because: "`link` only means something alongside `copySource`",
|
|
247369
|
+
// `copySourceToExtendOrCopy` needs `link` when there is a `copySource`.
|
|
247370
|
+
when: (_value, node) => !findAttrKey(node, "copySource") && !findAttrKey(node, "source")
|
|
247371
|
+
}
|
|
247372
|
+
},
|
|
247373
|
+
tabular: removeSides(),
|
|
247374
|
+
row: removeSides(),
|
|
247375
|
+
cell: removeSides()
|
|
247376
|
+
};
|
|
247377
|
+
function removeSides() {
|
|
247378
|
+
const rule = {
|
|
247379
|
+
kind: "remove",
|
|
247380
|
+
because: "v0.7 tables do not take per-side border attributes"
|
|
247381
|
+
};
|
|
247382
|
+
return { top: rule, bottom: rule, left: rule, right: rule };
|
|
247383
|
+
}
|
|
247384
|
+
const upgradeDeprecatedAttributes = () => {
|
|
247385
|
+
return (tree, file) => {
|
|
247386
|
+
visit(tree, (node) => {
|
|
247387
|
+
if (!isDastElement(node)) {
|
|
247388
|
+
return;
|
|
247389
|
+
}
|
|
247390
|
+
const elm = node;
|
|
247391
|
+
const rules = {
|
|
247392
|
+
...GLOBAL_RULES,
|
|
247393
|
+
...ELEMENT_RULES[elm.name.toLowerCase()] || {}
|
|
247394
|
+
};
|
|
247395
|
+
const keys2 = Object.keys(elm.attributes);
|
|
247396
|
+
const isMerge = (key) => rules[key.toLowerCase()]?.kind === "mergeInto";
|
|
247397
|
+
for (const key of [
|
|
247398
|
+
...keys2.filter((k2) => !isMerge(k2)),
|
|
247399
|
+
...keys2.filter(isMerge)
|
|
247400
|
+
]) {
|
|
247401
|
+
const rule = rules[key.toLowerCase()];
|
|
247402
|
+
if (!rule) {
|
|
247403
|
+
continue;
|
|
247404
|
+
}
|
|
247405
|
+
const attr = elm.attributes[key];
|
|
247406
|
+
if (!attr) {
|
|
247407
|
+
continue;
|
|
247408
|
+
}
|
|
247409
|
+
const value = toXml(attr.children).trim();
|
|
247410
|
+
if (rule.when && !rule.when(value, elm)) {
|
|
247411
|
+
continue;
|
|
247412
|
+
}
|
|
247413
|
+
applyRule(elm, key, attr, value, rule, file);
|
|
247414
|
+
}
|
|
247415
|
+
});
|
|
247416
|
+
};
|
|
247417
|
+
};
|
|
247418
|
+
const prependedChildCount = /* @__PURE__ */ new WeakMap();
|
|
247419
|
+
function applyRule(elm, key, attr, value, rule, file) {
|
|
247420
|
+
switch (rule.kind) {
|
|
247421
|
+
case "rename": {
|
|
247422
|
+
renameAttrInPlace(elm, key, rule.to);
|
|
247423
|
+
return;
|
|
247424
|
+
}
|
|
247425
|
+
case "renameToReferenceList": {
|
|
247426
|
+
renameAttrInPlace(elm, key, rule.to);
|
|
247427
|
+
const dollared = value.split(/\s+/).filter((t4) => t4).map(referenceTo).join(" ");
|
|
247428
|
+
elm.attributes[rule.to].children = reparseAttributeV6(dollared);
|
|
247429
|
+
return;
|
|
247430
|
+
}
|
|
247431
|
+
case "mergeInto": {
|
|
247432
|
+
const targetKey = findAttrKey(elm, rule.target);
|
|
247433
|
+
if (!targetKey || !value) {
|
|
247434
|
+
return;
|
|
247435
|
+
}
|
|
247436
|
+
const targetValue = toXml(
|
|
247437
|
+
elm.attributes[targetKey].children
|
|
247438
|
+
).trim();
|
|
247439
|
+
elm.attributes[targetKey].children = reparseAttributeV6(
|
|
247440
|
+
`${targetValue}.${value}`
|
|
247441
|
+
);
|
|
247442
|
+
delete elm.attributes[key];
|
|
247443
|
+
return;
|
|
247444
|
+
}
|
|
247445
|
+
case "toChildElement": {
|
|
247446
|
+
if (!value) {
|
|
247447
|
+
delete elm.attributes[key];
|
|
247448
|
+
return;
|
|
247449
|
+
}
|
|
247450
|
+
const child = {
|
|
247451
|
+
type: "element",
|
|
247452
|
+
name: rule.elementName,
|
|
247453
|
+
attributes: {},
|
|
247454
|
+
children: attr.children,
|
|
247455
|
+
position: attr.position
|
|
247456
|
+
};
|
|
247457
|
+
const alreadyPrepended = prependedChildCount.get(elm) || 0;
|
|
247458
|
+
elm.children.splice(alreadyPrepended, 0, child);
|
|
247459
|
+
prependedChildCount.set(elm, alreadyPrepended + 1);
|
|
247460
|
+
delete elm.attributes[key];
|
|
247461
|
+
return;
|
|
247462
|
+
}
|
|
247463
|
+
case "remove": {
|
|
247464
|
+
delete elm.attributes[key];
|
|
247465
|
+
file.message(
|
|
247466
|
+
`Removed ${key}="${value}" from <${elm.name}>: ${rule.because}.`,
|
|
247467
|
+
{
|
|
247468
|
+
place: elm.position,
|
|
247469
|
+
ruleId: rule.ruleId || `deprecated/${key.toLowerCase()}`,
|
|
247470
|
+
source: "v06-to-v07"
|
|
247471
|
+
}
|
|
247472
|
+
);
|
|
247473
|
+
return;
|
|
247474
|
+
}
|
|
247475
|
+
case "unsupported": {
|
|
247476
|
+
file.message(
|
|
247477
|
+
`<${elm.name} ${key}="..."> was left unchanged: ${rule.because}.`,
|
|
247478
|
+
{
|
|
247479
|
+
place: elm.position,
|
|
247480
|
+
ruleId: rule.ruleId || `no-v07-equivalent/${key.toLowerCase()}`,
|
|
247481
|
+
source: "v06-to-v07"
|
|
247482
|
+
}
|
|
247483
|
+
);
|
|
247484
|
+
return;
|
|
247485
|
+
}
|
|
247486
|
+
}
|
|
247487
|
+
}
|
|
247488
|
+
function findAttrKey(elm, attrName) {
|
|
247489
|
+
return Object.keys(elm.attributes).find(
|
|
247490
|
+
(key) => key.toLowerCase() === attrName.toLowerCase()
|
|
247491
|
+
);
|
|
247492
|
+
}
|
|
247493
|
+
function referenceTo(token) {
|
|
247494
|
+
if (token.startsWith("$(")) {
|
|
247495
|
+
return token;
|
|
247496
|
+
}
|
|
247497
|
+
const name2 = token.startsWith("$") ? token.slice(1) : token;
|
|
247498
|
+
return /^[a-zA-Z0-9_]+$/.test(name2) ? `$${name2}` : `$(${name2})`;
|
|
247499
|
+
}
|
|
247500
|
+
const ALL_ITEMS_PROPS = /* @__PURE__ */ new Set(["maths", "texts", "numbers", "booleans"]);
|
|
247501
|
+
const NUMBERED_ITEM_PROP = /^(math|text|number|boolean)(\d+)$/;
|
|
247502
|
+
const ELEMENTS_WITH_PROP = /* @__PURE__ */ new Set(["copy", "extract"]);
|
|
247503
|
+
const upgradeListProps = () => {
|
|
247504
|
+
return (tree, file) => {
|
|
247505
|
+
visitAllMacros(tree, (node) => {
|
|
247506
|
+
node.path = rewritePath(node.path);
|
|
247507
|
+
});
|
|
247508
|
+
visitAll(tree, (node) => {
|
|
247509
|
+
if (!isDastElement(node) || !ELEMENTS_WITH_PROP.has(node.name.toLowerCase())) {
|
|
247510
|
+
return;
|
|
247511
|
+
}
|
|
247512
|
+
rewritePropAttribute(node, file);
|
|
247513
|
+
rewriteRawSourceAttribute(node);
|
|
247514
|
+
});
|
|
247515
|
+
};
|
|
247516
|
+
};
|
|
247517
|
+
const ELEMENTS_WITH_RAW_SOURCE = /* @__PURE__ */ new Set(["copy", "extract"]);
|
|
247518
|
+
function rewriteRawSourceAttribute(node) {
|
|
247519
|
+
if (!ELEMENTS_WITH_RAW_SOURCE.has(node.name.toLowerCase())) {
|
|
247520
|
+
return;
|
|
247521
|
+
}
|
|
247522
|
+
const sourceKey = findKey(node, "source");
|
|
247523
|
+
if (!sourceKey) {
|
|
247524
|
+
return;
|
|
247525
|
+
}
|
|
247526
|
+
const attr = node.attributes[sourceKey];
|
|
247527
|
+
if (attr.children.length !== 1 || attr.children[0].type !== "text") {
|
|
247528
|
+
return;
|
|
247529
|
+
}
|
|
247530
|
+
const child = attr.children[0];
|
|
247531
|
+
const value = child.value.trim();
|
|
247532
|
+
if (!value || value.startsWith("$") || !value.includes(".")) {
|
|
247533
|
+
return;
|
|
247534
|
+
}
|
|
247535
|
+
let path;
|
|
247536
|
+
try {
|
|
247537
|
+
path = parseReferencePath(value);
|
|
247538
|
+
} catch {
|
|
247539
|
+
return;
|
|
247540
|
+
}
|
|
247541
|
+
restoreRawPropPositions(node, sourceKey, path);
|
|
247542
|
+
const rewritten = rewritePath(path);
|
|
247543
|
+
if (rewritten === path) {
|
|
247544
|
+
return;
|
|
247545
|
+
}
|
|
247546
|
+
child.value = toXml(rewritten);
|
|
247547
|
+
}
|
|
247548
|
+
function rewritePath(path) {
|
|
247549
|
+
if (path.length < 2) {
|
|
247550
|
+
return path;
|
|
247551
|
+
}
|
|
247552
|
+
const result2 = [path[0]];
|
|
247553
|
+
for (const part of path.slice(1)) {
|
|
247554
|
+
const previous = result2[result2.length - 1];
|
|
247555
|
+
if (!isPropAccess(part)) {
|
|
247556
|
+
result2.push(part);
|
|
247557
|
+
continue;
|
|
247558
|
+
}
|
|
247559
|
+
if (ALL_ITEMS_PROPS.has(part.name)) {
|
|
247560
|
+
previous.index = [...previous.index, ...part.index];
|
|
247561
|
+
continue;
|
|
247562
|
+
}
|
|
247563
|
+
const numbered = NUMBERED_ITEM_PROP.exec(part.name);
|
|
247564
|
+
if (numbered) {
|
|
247565
|
+
previous.index = [
|
|
247566
|
+
...previous.index,
|
|
247567
|
+
{
|
|
247568
|
+
type: "index",
|
|
247569
|
+
value: [{ type: "text", value: numbered[2] }]
|
|
247570
|
+
},
|
|
247571
|
+
...part.index
|
|
247572
|
+
];
|
|
247573
|
+
continue;
|
|
247574
|
+
}
|
|
247575
|
+
result2.push(part);
|
|
247576
|
+
}
|
|
247577
|
+
return result2;
|
|
247578
|
+
}
|
|
247579
|
+
function rewritePropAttribute(node, file) {
|
|
247580
|
+
const propKey = findKey(node, "prop");
|
|
247581
|
+
if (!propKey) {
|
|
247582
|
+
return;
|
|
247583
|
+
}
|
|
247584
|
+
const prop = toXml(node.attributes[propKey].children).trim();
|
|
247585
|
+
const numbered = NUMBERED_ITEM_PROP.exec(prop);
|
|
247586
|
+
if (!ALL_ITEMS_PROPS.has(prop) && !numbered) {
|
|
247587
|
+
return;
|
|
247588
|
+
}
|
|
247589
|
+
const sourceKey = findKey(node, "source");
|
|
247590
|
+
if (!sourceKey) {
|
|
247591
|
+
return;
|
|
247592
|
+
}
|
|
247593
|
+
const sourceAttr = node.attributes[sourceKey];
|
|
247594
|
+
const source = toXml(sourceAttr.children).trim();
|
|
247595
|
+
if (!source) {
|
|
247596
|
+
return;
|
|
247597
|
+
}
|
|
247598
|
+
if (!numbered) {
|
|
247599
|
+
if (node.name.toLowerCase() === "extract") {
|
|
247600
|
+
file.message(
|
|
247601
|
+
`<extract prop="${prop}"> has no v0.7 equivalent and was left as it is; the prop names the whole list, which v0.7 reaches as $${source}.`,
|
|
247602
|
+
{
|
|
247603
|
+
place: node.position,
|
|
247604
|
+
ruleId: "no-v07-equivalent/extract",
|
|
247605
|
+
source: "v06-to-v07"
|
|
247606
|
+
}
|
|
247607
|
+
);
|
|
247608
|
+
return;
|
|
247609
|
+
}
|
|
247610
|
+
delete node.attributes[propKey];
|
|
247611
|
+
return;
|
|
247612
|
+
}
|
|
247613
|
+
const hadDollar = source.startsWith("$");
|
|
247614
|
+
let path;
|
|
247615
|
+
try {
|
|
247616
|
+
path = parseReferencePath(hadDollar ? source.slice(1) : source);
|
|
247617
|
+
} catch (e4) {
|
|
247618
|
+
return;
|
|
247619
|
+
}
|
|
247620
|
+
const last2 = path[path.length - 1];
|
|
247621
|
+
last2.index = [
|
|
247622
|
+
...last2.index,
|
|
247623
|
+
{ type: "index", value: [{ type: "text", value: numbered[2] }] }
|
|
247624
|
+
];
|
|
247625
|
+
sourceAttr.children = hadDollar ? [{ type: "macro", path, attributes: {} }] : [{ type: "text", value: toXml(path) }];
|
|
247626
|
+
delete node.attributes[propKey];
|
|
247627
|
+
}
|
|
247628
|
+
function findKey(node, attrName) {
|
|
247629
|
+
return Object.keys(node.attributes).find(
|
|
247630
|
+
(key) => key.toLowerCase() === attrName.toLowerCase()
|
|
247631
|
+
);
|
|
247632
|
+
}
|
|
247633
|
+
const upgradeAssignNames = (context) => {
|
|
247634
|
+
return (tree, file) => {
|
|
247635
|
+
visitAll(tree, (node, parents) => {
|
|
247636
|
+
if (!isDastElement(node)) {
|
|
247637
|
+
return;
|
|
247638
|
+
}
|
|
247639
|
+
const spec = lookupComposite(node);
|
|
247640
|
+
if (!spec) {
|
|
247641
|
+
return;
|
|
247642
|
+
}
|
|
247643
|
+
const assignNamesValue = readAssignNames(node);
|
|
247644
|
+
if (assignNamesValue === void 0) {
|
|
247645
|
+
return;
|
|
247646
|
+
}
|
|
247647
|
+
if (spec.noV07Equivalent) {
|
|
247648
|
+
file.message(
|
|
247649
|
+
`<${node.name}> has no v0.7 equivalent and must be rewritten by hand; its references were converted as if it behaved like a v0.6 composite.`,
|
|
247650
|
+
{
|
|
247651
|
+
place: node.position,
|
|
247652
|
+
ruleId: `no-v07-equivalent/${spec.name.toLowerCase()}`,
|
|
247653
|
+
source: "v06-to-v07"
|
|
247654
|
+
}
|
|
247655
|
+
);
|
|
247656
|
+
}
|
|
247657
|
+
if (!assignNamesValue) {
|
|
247658
|
+
deleteAssignNames(node);
|
|
247659
|
+
return;
|
|
247660
|
+
}
|
|
247661
|
+
const parsed = breakStringInPiecesBySpacesOrParens(assignNamesValue);
|
|
247662
|
+
if (parsed.success && firstLeafName(parsed.pieces) === void 0) {
|
|
247663
|
+
deleteAssignNames(node);
|
|
247664
|
+
return;
|
|
247665
|
+
}
|
|
247666
|
+
const onlyPiece = parsed.success && parsed.pieces.length === 1 && typeof parsed.pieces[0] === "string" ? parsed.pieces[0] : void 0;
|
|
247667
|
+
if (onlyPiece !== void 0 && isValidReferenceableName(onlyPiece) && !findAttribute(node, "name") && !context.existingNames.has(onlyPiece) && !context.claimedNames.has(onlyPiece) && producesSingleReplacement(node, spec)) {
|
|
247668
|
+
context.claimedNames.add(onlyPiece);
|
|
247669
|
+
context.registry.register(
|
|
247670
|
+
onlyPiece,
|
|
247671
|
+
void 0,
|
|
247672
|
+
{
|
|
247673
|
+
elementName: node.name,
|
|
247674
|
+
position: node.position,
|
|
247675
|
+
ancestorNames: namespaceChainOf(parents, context),
|
|
247676
|
+
element: node
|
|
247677
|
+
},
|
|
247678
|
+
file
|
|
247679
|
+
);
|
|
247680
|
+
warnIfSelfReferential(node, onlyPiece, file);
|
|
247681
|
+
setCompositeName(node, onlyPiece);
|
|
247682
|
+
return;
|
|
247683
|
+
}
|
|
247684
|
+
const compositeName = registerCompositeAssignNames({
|
|
247685
|
+
node,
|
|
247686
|
+
assignNamesValue,
|
|
247687
|
+
fallbackBase: spec.name,
|
|
247688
|
+
ancestorNames: namespaceChainOf(parents, context),
|
|
247689
|
+
context,
|
|
247690
|
+
file,
|
|
247691
|
+
positionMap: makePositionMap(node, spec, file)
|
|
247692
|
+
});
|
|
247693
|
+
if (compositeName === void 0) {
|
|
247694
|
+
deleteAssignNames(node);
|
|
247695
|
+
return;
|
|
247696
|
+
}
|
|
247697
|
+
warnIfSelfReferential(node, compositeName, file);
|
|
247698
|
+
setCompositeName(node, compositeName);
|
|
247699
|
+
});
|
|
247700
|
+
};
|
|
247701
|
+
};
|
|
247702
|
+
function warnIfSelfReferential(node, compositeName, file) {
|
|
247703
|
+
let referencesSelf = false;
|
|
247704
|
+
for (const attr of Object.values(node.attributes)) {
|
|
247705
|
+
for (const child of attr.children) {
|
|
247706
|
+
visitAllMacros(child, (macro) => {
|
|
247707
|
+
if (macro.path[0]?.name === compositeName) {
|
|
247708
|
+
referencesSelf = true;
|
|
247709
|
+
}
|
|
247710
|
+
});
|
|
247711
|
+
}
|
|
247712
|
+
}
|
|
247713
|
+
if (!referencesSelf) {
|
|
247714
|
+
return;
|
|
247715
|
+
}
|
|
247716
|
+
file.message(
|
|
247717
|
+
`<${node.name}> is being named "${compositeName}", but one of its own attributes already refers to $${compositeName}. That reference resolved to nothing in v0.6; in v0.7 it is a circular reference and the document will not load.`,
|
|
247718
|
+
{
|
|
247719
|
+
place: node.position,
|
|
247720
|
+
ruleId: "assign-names/self-reference",
|
|
247721
|
+
source: "v06-to-v07"
|
|
247722
|
+
}
|
|
247723
|
+
);
|
|
247724
|
+
}
|
|
247725
|
+
const applyAssignNameRenames = (context) => {
|
|
247726
|
+
return (tree, file) => {
|
|
247727
|
+
applyRefRenames(tree, context.registry, file, context);
|
|
247728
|
+
};
|
|
247729
|
+
};
|
|
245776
247730
|
async function updateSyntaxFromV06toV07_root(dast, options) {
|
|
245777
|
-
|
|
247731
|
+
const assignNamesContext = createAssignNamesContext(dast);
|
|
247732
|
+
let processor = unified$1().use(correctElementCapitalization).use(correctAttributeCapitalization).use(correctComponentTypesAttributeCapitalization).use(upgradeDeprecatedAttributes).use(ensureDollarBeforeNamesOnSpecificAttributes).use(upgradePathSlashesToDots).use(removeNewNamespaceAttribute).use(upgradeRefElement).use(copySourceToExtendOrCopy, assignNamesContext).use(upgradeCollectElement, assignNamesContext).use(upgradeMapElement, assignNamesContext).use(upgradeAssignNames, assignNamesContext).use(upgradeCopyElements, assignNamesContext).use(applyAssignNameRenames, assignNamesContext).use(upgradeListProps).use(upgradeModuleElement).use(removeConstraintsElement).use(removeDefinitionsElement);
|
|
245778
247733
|
if (!options.doNotUpgradeAttributeSyntax) {
|
|
245779
|
-
processor = processor.use(upgradeAttributeSyntax);
|
|
247734
|
+
processor = processor.use(upgradeAttributeSyntax, assignNamesContext);
|
|
245780
247735
|
}
|
|
245781
247736
|
if (!options.doNotUpgradeCopyTags) {
|
|
245782
247737
|
processor = processor.use(upgradeCopySyntax);
|
|
@@ -245817,31 +247772,44 @@ const ensureDollarBeforeNamesOnSpecificAttributes = () => {
|
|
|
245817
247772
|
});
|
|
245818
247773
|
};
|
|
245819
247774
|
};
|
|
245820
|
-
const copySourceToExtendOrCopy = () => {
|
|
245821
|
-
return (tree) => {
|
|
245822
|
-
visit(tree, (node) => {
|
|
247775
|
+
const copySourceToExtendOrCopy = (context) => {
|
|
247776
|
+
return (tree, file) => {
|
|
247777
|
+
visit(tree, (node, info) => {
|
|
245823
247778
|
if (!isDastElement(node)) {
|
|
245824
247779
|
return;
|
|
245825
247780
|
}
|
|
245826
247781
|
const copySourceAttr = node.attributes["copySource"];
|
|
245827
247782
|
const linkAttr = node.attributes["link"];
|
|
245828
|
-
const assignNamesAttr = node.attributes["assignNames"];
|
|
245829
247783
|
const copyPropAttr = node.attributes["copyProp"];
|
|
245830
247784
|
if (!copySourceAttr) {
|
|
245831
247785
|
return;
|
|
245832
247786
|
}
|
|
245833
|
-
const targetTag =
|
|
247787
|
+
const targetTag = linkAttr ? isV06True(linkAttr) ? "extend" : "copy" : isModuleComponentType(node.name) ? "copy" : "extend";
|
|
245834
247788
|
const baseValue = toXml(copySourceAttr.children).trim();
|
|
245835
247789
|
let extendValue = baseValue.startsWith("$") ? baseValue : `$${baseValue}`;
|
|
245836
247790
|
copySourceAttr.name = targetTag;
|
|
247791
|
+
let appendedPropName;
|
|
245837
247792
|
if (copyPropAttr) {
|
|
245838
|
-
|
|
247793
|
+
appendedPropName = toXml(copyPropAttr.children).trim();
|
|
247794
|
+
extendValue += `.${appendedPropName}`;
|
|
245839
247795
|
delete node.attributes["copyProp"];
|
|
245840
247796
|
}
|
|
245841
247797
|
copySourceAttr.children = reparseAttribute(extendValue);
|
|
245842
|
-
if (
|
|
245843
|
-
|
|
247798
|
+
if (appendedPropName) {
|
|
247799
|
+
const macro = copySourceAttr.children[0];
|
|
247800
|
+
if (macro?.type === "macro") {
|
|
247801
|
+
const last2 = macro.path[macro.path.length - 1];
|
|
247802
|
+
if (last2) {
|
|
247803
|
+
markAsPropAccess(last2);
|
|
247804
|
+
}
|
|
247805
|
+
}
|
|
245844
247806
|
}
|
|
247807
|
+
convertAssignNames(
|
|
247808
|
+
node,
|
|
247809
|
+
namespaceChainOf(info.parents, context),
|
|
247810
|
+
context,
|
|
247811
|
+
file
|
|
247812
|
+
);
|
|
245845
247813
|
if (linkAttr) {
|
|
245846
247814
|
delete node.attributes["link"];
|
|
245847
247815
|
}
|
|
@@ -245876,4 +247844,4 @@ export {
|
|
|
245876
247844
|
getDefaultExportFromCjs$1 as g,
|
|
245877
247845
|
updateSyntaxFromV06toV07 as u
|
|
245878
247846
|
};
|
|
245879
|
-
//# sourceMappingURL=index-
|
|
247847
|
+
//# sourceMappingURL=index-4M4L_2sg.js.map
|