reffy 11.0.1 → 11.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reffy",
|
|
3
|
-
"version": "11.0.
|
|
3
|
+
"version": "11.0.3",
|
|
4
4
|
"description": "W3C/WHATWG spec dependencies exploration companion. Features a short set of tools to study spec references as well as WebIDL term definitions and references found in W3C specifications.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"chai": "4.3.7",
|
|
47
47
|
"mocha": "10.1.0",
|
|
48
48
|
"nock": "13.2.9",
|
|
49
|
-
"respec": "32.
|
|
49
|
+
"respec": "32.4.0",
|
|
50
50
|
"respec-hljs": "2.1.1",
|
|
51
51
|
"rollup": "3.5.0"
|
|
52
52
|
},
|
package/schemas/common.json
CHANGED
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"type": "array",
|
|
44
44
|
"items": {
|
|
45
45
|
"type": "object",
|
|
46
|
-
"required": ["name", "type"
|
|
46
|
+
"required": ["name", "type"],
|
|
47
47
|
"additionalProperties": false,
|
|
48
48
|
"properties": {
|
|
49
49
|
"name": { "$ref": "#/$defs/cssValue" },
|
|
50
|
-
"type": { "type": "string", "enum": ["type", "function", "value"] },
|
|
50
|
+
"type": { "type": "string", "enum": ["type", "function", "value", "selector"] },
|
|
51
51
|
"prose": { "type": "string" },
|
|
52
52
|
"value": { "$ref": "#/$defs/cssValue" },
|
|
53
53
|
"legacyValue": { "$ref": "#/$defs/cssValue" },
|
|
@@ -36,7 +36,9 @@ export default function () {
|
|
|
36
36
|
warnings
|
|
37
37
|
}),
|
|
38
38
|
selectors: extractDfns({
|
|
39
|
-
selector: 'dfn[data-dfn-type=selector][data-export]',
|
|
39
|
+
selector: ['dfn[data-dfn-type=selector][data-export]:not([data-dfn-for])',
|
|
40
|
+
'dfn[data-dfn-type=selector][data-export][data-dfn-for=""]'
|
|
41
|
+
].join(','),
|
|
40
42
|
extractor: extractTypedDfn,
|
|
41
43
|
duplicates: 'reject',
|
|
42
44
|
warnings
|
|
@@ -125,7 +127,8 @@ export default function () {
|
|
|
125
127
|
const values = extractDfns({
|
|
126
128
|
selector: ['dfn[data-dfn-type=value][data-dfn-for]:not([data-dfn-for=""])',
|
|
127
129
|
'dfn[data-dfn-type=function][data-dfn-for]:not([data-dfn-for=""])',
|
|
128
|
-
'dfn[data-dfn-type=type][data-dfn-for]:not([data-dfn-for=""])'
|
|
130
|
+
'dfn[data-dfn-type=type][data-dfn-for]:not([data-dfn-for=""])',
|
|
131
|
+
'dfn[data-dfn-type=selector][data-dfn-for]:not([data-dfn-for=""])'
|
|
129
132
|
].join(','),
|
|
130
133
|
extractor: extractTypedDfn,
|
|
131
134
|
duplicates: 'push',
|
|
@@ -541,6 +544,39 @@ const parseProductionRule = (rule, { res = [], pureSyntax = false }) => {
|
|
|
541
544
|
};
|
|
542
545
|
|
|
543
546
|
|
|
547
|
+
/**
|
|
548
|
+
* Extract the definition name. If multiple linking texts are possible, the
|
|
549
|
+
* function will select the one that is a "syntax" definition. For instance, it
|
|
550
|
+
* will pick up "<identifier>" for "identifiers|<identifier>" in CSS 2:
|
|
551
|
+
* https://drafts.csswg.org/css2/#value-def-identifier
|
|
552
|
+
*
|
|
553
|
+
* The function throws if it cannot extract an obvious name from the definition.
|
|
554
|
+
* We may want to be smarter about that in the future, but this should really
|
|
555
|
+
* never happen in practice (the above "identifiers" example is the only one
|
|
556
|
+
* CSS value definition so far to have multiple linking texts)
|
|
557
|
+
*/
|
|
558
|
+
const getDfnName = dfn => {
|
|
559
|
+
if (dfn.getAttribute('data-lt')) {
|
|
560
|
+
const names = dfn.getAttribute('data-lt').split('|').map(normalize);
|
|
561
|
+
let name = names.find(n =>
|
|
562
|
+
n.startsWith('<') || // Looks like a "type"
|
|
563
|
+
n.startsWith('@') || // Looks like an "at-rule"
|
|
564
|
+
n.startsWith(':') || // Looks like a "descriptor"
|
|
565
|
+
n.endsWith('()')); // Looks like a "function"
|
|
566
|
+
if (!name) {
|
|
567
|
+
if (names.length > 1) {
|
|
568
|
+
throw new Error(`Found multiple linking texts for dfn without any obvious one: ${names.join(', ')}`);
|
|
569
|
+
}
|
|
570
|
+
name = names[0];
|
|
571
|
+
}
|
|
572
|
+
return name;
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
return dfn.textContent.trim();
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
|
|
544
580
|
/**
|
|
545
581
|
* Extract the given dfn
|
|
546
582
|
*/
|
|
@@ -550,6 +586,7 @@ const extractTypedDfn = dfn => {
|
|
|
550
586
|
const dfnType = dfn.getAttribute('data-dfn-type');
|
|
551
587
|
const dfnFor = dfn.getAttribute('data-dfn-for');
|
|
552
588
|
const parent = dfn.parentNode.cloneNode(true);
|
|
589
|
+
const fnRegExp = /^([a-zA-Z_][a-zA-Z0-9_\-]+)\([^\)]+\)$/;
|
|
553
590
|
|
|
554
591
|
// Remove note references as in:
|
|
555
592
|
// https://drafts.csswg.org/css-syntax-3/#the-anb-type
|
|
@@ -571,8 +608,17 @@ const extractTypedDfn = dfn => {
|
|
|
571
608
|
// Don't attempt to parse pre tags at this stage, they are tricky to
|
|
572
609
|
// split, we'll parse them as text and map them to the right definitions
|
|
573
610
|
// afterwards.
|
|
574
|
-
|
|
575
|
-
|
|
611
|
+
// That said, we may be looking at a function definition on the right hand
|
|
612
|
+
// side of a production rule, as in the definition of "linear()" in
|
|
613
|
+
// css-easing-2: https://drafts.csswg.org/css-easing-2/#funcdef-linear
|
|
614
|
+
// In such a case, we still want to extract the function parameters
|
|
615
|
+
if (dfn.textContent.trim().match(fnRegExp)) {
|
|
616
|
+
const fn = dfn.textContent.trim().match(fnRegExp)[1];
|
|
617
|
+
res = parseProductionRule(`${fn}() = ${dfn.textContent.trim()}`, { pureSyntax: false });
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
res = { name: getDfnName(dfn) };
|
|
621
|
+
}
|
|
576
622
|
}
|
|
577
623
|
else if (prod) {
|
|
578
624
|
res = parseProductionRule(prod, { pureSyntax: true });
|
|
@@ -582,13 +628,12 @@ const extractTypedDfn = dfn => {
|
|
|
582
628
|
// https://drafts.csswg.org/css-speech-1/#typedef-voice-volume-decibel
|
|
583
629
|
// It may be worth checking but not an error per se.
|
|
584
630
|
console.warn('[reffy]', `Found "=" next to definition of ${dfn.textContent.trim()} but no production rule. Did I miss something?`);
|
|
585
|
-
|
|
586
|
-
res = { name, prose: text.replace(/\s+/g, ' ') };
|
|
631
|
+
res = { name: getDfnName(dfn), prose: text.replace(/\s+/g, ' ') };
|
|
587
632
|
}
|
|
588
633
|
}
|
|
589
|
-
else if (dfn.textContent.trim().match(
|
|
634
|
+
else if (dfn.textContent.trim().match(fnRegExp)) {
|
|
590
635
|
// Definition is "prod(foo bar)", create a "prod() = prod(foo bar)" entry
|
|
591
|
-
const fn = dfn.textContent.trim().match(
|
|
636
|
+
const fn = dfn.textContent.trim().match(fnRegExp)[1];
|
|
592
637
|
res = parseProductionRule(`${fn}() = ${dfn.textContent.trim()}`, { pureSyntax: false });
|
|
593
638
|
}
|
|
594
639
|
else if (parent.nodeName === 'DT') {
|
|
@@ -622,20 +667,23 @@ const extractTypedDfn = dfn => {
|
|
|
622
667
|
}
|
|
623
668
|
});
|
|
624
669
|
|
|
625
|
-
|
|
626
|
-
|
|
670
|
+
res = {
|
|
671
|
+
name: getDfnName(dfn),
|
|
672
|
+
prose: dd.textContent.trim().replace(/\s+/g, ' ')
|
|
673
|
+
};
|
|
627
674
|
}
|
|
628
675
|
}
|
|
629
676
|
else if (parent.nodeName === 'P') {
|
|
630
677
|
// Definition is in regular prose, extract value from prose.
|
|
631
|
-
|
|
632
|
-
|
|
678
|
+
res = {
|
|
679
|
+
name: getDfnName(dfn),
|
|
680
|
+
prose: parent.textContent.trim().replace(/\s+/g, ' ')
|
|
681
|
+
};
|
|
633
682
|
}
|
|
634
683
|
else {
|
|
635
684
|
// Definition is in a heading or a more complex structure, just list the
|
|
636
685
|
// name for now.
|
|
637
|
-
|
|
638
|
-
res = { name };
|
|
686
|
+
res = { name: getDfnName(dfn) };
|
|
639
687
|
}
|
|
640
688
|
|
|
641
689
|
res.type = dfnType;
|
|
@@ -106,17 +106,18 @@ function hasValidType(el) {
|
|
|
106
106
|
return isValid;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// Return true when definition is not already defined in the list,
|
|
109
|
+
// Return true when exported definition is not already defined in the list,
|
|
110
110
|
// Return false and issue a warning when it is already defined.
|
|
111
|
-
function
|
|
111
|
+
function isNotAlreadyExported(dfn, idx, list) {
|
|
112
112
|
const first = list.find(d => d === dfn ||
|
|
113
|
-
(d.
|
|
113
|
+
(d.access === 'public' && dfn.access === 'public' &&
|
|
114
|
+
d.type === dfn.type &&
|
|
114
115
|
d.linkingText.length === dfn.linkingText.length &&
|
|
115
116
|
d.linkingText.every(lt => dfn.linkingText.find(t => t == lt)) &&
|
|
116
117
|
d.for.length === dfn.for.length &&
|
|
117
118
|
d.for.every(lt => dfn.for.find(t => t === lt))));
|
|
118
119
|
if (first !== dfn) {
|
|
119
|
-
console.warn('[reffy]', `Duplicate dfn found for "${dfn.linkingText[0]}", type="${dfn.type}", for="${dfn.for[0]}"`);
|
|
120
|
+
console.warn('[reffy]', `Duplicate dfn found for "${dfn.linkingText[0]}", type="${dfn.type}", for="${dfn.for[0]}", dupl=${dfn.href}, first=${first.href}`);
|
|
120
121
|
}
|
|
121
122
|
return first === dfn;
|
|
122
123
|
}
|
|
@@ -267,7 +268,7 @@ export default function (spec, idToHeading = {}) {
|
|
|
267
268
|
return !link || (node.textContent.trim() !== link.textContent.trim());
|
|
268
269
|
})
|
|
269
270
|
.map(node => definitionMapper(node, idToHeading, usesDfnDataModel))
|
|
270
|
-
.filter(
|
|
271
|
+
.filter(isNotAlreadyExported);
|
|
271
272
|
}
|
|
272
273
|
|
|
273
274
|
function preProcessEcmascript() {
|