reffy 7.2.7 → 7.2.10
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": "7.2.
|
|
3
|
+
"version": "7.2.10",
|
|
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",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"abortcontroller-polyfill": "1.7.3",
|
|
35
35
|
"commander": "9.3.0",
|
|
36
36
|
"fetch-filecache-for-crawling": "4.1.0",
|
|
37
|
-
"puppeteer": "15.
|
|
37
|
+
"puppeteer": "15.4.0",
|
|
38
38
|
"semver": "^7.3.5",
|
|
39
|
-
"web-specs": "2.
|
|
39
|
+
"web-specs": "2.17.0",
|
|
40
40
|
"webidl2": "24.2.2"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
@@ -225,6 +225,12 @@ const extractValueSpaces = doc => {
|
|
|
225
225
|
}
|
|
226
226
|
};
|
|
227
227
|
|
|
228
|
+
// Regular expression to use to split production rules:
|
|
229
|
+
// Split on the space that precedes a term immediately before an equal sign
|
|
230
|
+
// that is not wrapped in quotes (an equal sign wrapped in quotes is part of
|
|
231
|
+
// actual value syntax)
|
|
232
|
+
const reSplitRules = /\s(?=[^\s]+?\s*?=[^'])/;
|
|
233
|
+
|
|
228
234
|
// Extract all dfns with data-dfn-type="type" or data-dfn-type="function"
|
|
229
235
|
// but ignore definitions in <pre> as they do not always use dfns, as in
|
|
230
236
|
// https://drafts.csswg.org/css-values-4/#calc-syntax
|
|
@@ -246,7 +252,15 @@ const extractValueSpaces = doc => {
|
|
|
246
252
|
const text = parent.textContent.trim();
|
|
247
253
|
if (text.match(/\s?=\s/)) {
|
|
248
254
|
// Definition appears in a "prod = foo" text, that's all good
|
|
249
|
-
|
|
255
|
+
// ... except in css-easing-2 draft where text also contains another
|
|
256
|
+
// production rule as a child of the first one:
|
|
257
|
+
// https://drafts.csswg.org/css-easing-2/#typedef-step-easing-function
|
|
258
|
+
const prod = text.split(reSplitRules)
|
|
259
|
+
.find(p => p.trim().startsWith(dfn.textContent.trim()));
|
|
260
|
+
if (!prod) {
|
|
261
|
+
throw new Error(`Production rule for ${dfn.textContent.trim()} found has unexpected format`);
|
|
262
|
+
}
|
|
263
|
+
parseProductionRule(prod, { pureSyntax: true });
|
|
250
264
|
}
|
|
251
265
|
else if (dfn.textContent.trim().match(/^[a-zA-Z_][a-zA-Z0-9_\-]+\([^\)]+\)$/)) {
|
|
252
266
|
// Definition is "prod(foo bar)", create a "prod() = prod(foo bar)" entry
|
|
@@ -323,7 +337,7 @@ const extractValueSpaces = doc => {
|
|
|
323
337
|
})
|
|
324
338
|
.map(el => el.textContent)
|
|
325
339
|
.map(val => val.replace(/\/\*[^]*?\*\//gm, '')) // Drop comments
|
|
326
|
-
.map(val => val.split(
|
|
340
|
+
.map(val => val.split(reSplitRules)) // Separate definitions
|
|
327
341
|
.flat()
|
|
328
342
|
.filter(text => text.match(/\s?=\s/))
|
|
329
343
|
.map(text => parseProductionRule(text, { pureSyntax: true }));
|
|
@@ -41,14 +41,11 @@ export default function (spec) {
|
|
|
41
41
|
function fromEventElementToTargetInterfaces(eventEl) {
|
|
42
42
|
if (!eventEl) return;
|
|
43
43
|
|
|
44
|
-
console.log(`[reffy] ${eventEl.textContent}`);
|
|
45
|
-
|
|
46
44
|
if (eventEl.dataset?.dfnFor || eventEl.dataset?.linkFor) {
|
|
47
45
|
return (eventEl.dataset.dfnFor || eventEl.dataset.linkFor).split(",").map(t => t.trim());
|
|
48
46
|
} else if (eventEl.getAttribute("href")?.startsWith("#")) {
|
|
49
47
|
const dfn = document.getElementById(eventEl.getAttribute("href").slice(1));
|
|
50
48
|
if (dfn && dfn.dataset?.dfnFor) {
|
|
51
|
-
console.log(`[reffy] ${eventEl.textContent} dfnFor ${dfn.dataset.dfnFor.split(",").map(t => t.trim())}`);
|
|
52
49
|
return dfn.dataset.dfnFor.split(",").map(t => t.trim());
|
|
53
50
|
}
|
|
54
51
|
} else if (handledEventNames[eventEl.textContent]?.length) {
|
|
@@ -56,7 +53,6 @@ export default function (spec) {
|
|
|
56
53
|
const matchingInterfaces = handledEventNames[eventEl.textContent];
|
|
57
54
|
if (matchingInterfaces.length === 1) {
|
|
58
55
|
// only one such handler, we assume it's a match
|
|
59
|
-
console.log(`[reffy] ${eventEl.textContent} found ${matchingInterfaces}`);
|
|
60
56
|
return matchingInterfaces;
|
|
61
57
|
} else {
|
|
62
58
|
console.error(`[reffy] Multiple event handler named ${eventEl.textContent}, cannot associate reliably to an interface in ${spec.title}`);
|
|
@@ -106,12 +102,12 @@ export default function (spec) {
|
|
|
106
102
|
if (el.tagName === "DFN" && el.id) {
|
|
107
103
|
event.href = href(el);
|
|
108
104
|
} else if (el.tagName === "A") {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
105
|
+
if (!el.getAttribute("href").startsWith("https://")) {
|
|
106
|
+
const url = new URL(el.href);
|
|
107
|
+
event.href = href(document.getElementById(url.hash.slice(1)));
|
|
108
|
+
} else {
|
|
109
|
+
event.href = el.href;
|
|
110
|
+
}
|
|
115
111
|
}
|
|
116
112
|
event.src = { format: "summary table", href: href(el.closest('*[id]')) };
|
|
117
113
|
event.type = eventEl.textContent.trim();
|
|
@@ -124,9 +120,9 @@ export default function (spec) {
|
|
|
124
120
|
tr.querySelector(`td:nth-child(${interfaceColumn + 1}) a`)?.textContent ??
|
|
125
121
|
tr.querySelector(`td:nth-child(${interfaceColumn + 1}) code`)?.textContent;
|
|
126
122
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
123
|
+
if (targetsColumn >= 0 && !event.targets) {
|
|
124
|
+
event.targets = tr.querySelector(`td:nth-child(${targetsColumn + 1})`)?.textContent?.split(',').map(t => t.trim());
|
|
125
|
+
}
|
|
130
126
|
events.push(event);
|
|
131
127
|
eventEl.replaceWith(origEventEl);
|
|
132
128
|
});
|
|
@@ -209,8 +205,8 @@ export default function (spec) {
|
|
|
209
205
|
} else {
|
|
210
206
|
event.type = name;
|
|
211
207
|
// looking at the element following the link
|
|
212
|
-
|
|
213
|
-
|
|
208
|
+
// if its content match the name of the event
|
|
209
|
+
const eventEl = a.nextElementSibling?.textContent?.trim() === event.type ? a.nextElementSibling.querySelector("a,dfn") || a.nextElementSibling : null;
|
|
214
210
|
if (eventEl) {
|
|
215
211
|
if (eventEl.tagName === "A" && eventEl.getAttribute("href")) {
|
|
216
212
|
// use the target of the link as our href
|
|
@@ -231,7 +227,7 @@ export default function (spec) {
|
|
|
231
227
|
while ((curEl = curEl.nextElementSibling)) {
|
|
232
228
|
if (curEl.textContent.match(/^([A-Z]+[a-z0-9]*)+Event$/)) {
|
|
233
229
|
iface = curEl.textContent.trim();
|
|
234
|
-
|
|
230
|
+
break;
|
|
235
231
|
}
|
|
236
232
|
}
|
|
237
233
|
if (iface) {
|
|
@@ -326,20 +322,20 @@ export default function (spec) {
|
|
|
326
322
|
// of the section where the definitions are located
|
|
327
323
|
let currentEl = container.parentNode;
|
|
328
324
|
while(currentEl) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
325
|
+
if (currentEl.tagName.match(/^H[1-6]$/)) {
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
currentEl = currentEl.previousElementSibling;
|
|
333
329
|
}
|
|
334
330
|
const interfaceEl = currentEl?.querySelector("code");
|
|
335
331
|
if (interfaceEl?.textContent?.match(/^[A-Z][a-z]+Event$/)) {
|
|
336
|
-
|
|
332
|
+
iface = interfaceEl.textContent;
|
|
337
333
|
}
|
|
338
334
|
}
|
|
339
335
|
const ev = events.find(e => isSameEvent(event, e));
|
|
340
336
|
if (!ev) {
|
|
341
337
|
if (iface) {
|
|
342
|
-
|
|
338
|
+
event.interface = iface;
|
|
343
339
|
}
|
|
344
340
|
event.bubbles = bubbles;
|
|
345
341
|
events.push(event);
|
|
@@ -351,7 +347,7 @@ export default function (spec) {
|
|
|
351
347
|
ev.interface = iface;
|
|
352
348
|
}
|
|
353
349
|
if (!ev.href && event.href) {
|
|
354
|
-
|
|
350
|
+
ev.href = event.href;
|
|
355
351
|
}
|
|
356
352
|
if (bubbles !== undefined) {
|
|
357
353
|
ev.bubbles = bubbles;
|
package/src/lib/util.js
CHANGED
|
@@ -605,7 +605,7 @@ async function processSpecification(spec, processFunction, args, options) {
|
|
|
605
605
|
window.document.head.querySelector("script[src*='respec']");
|
|
606
606
|
|
|
607
607
|
function sleep(ms) {
|
|
608
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
608
|
+
return new Promise(resolve => setTimeout(resolve, ms, 'slept'));
|
|
609
609
|
}
|
|
610
610
|
|
|
611
611
|
async function isReady(counter) {
|
|
@@ -614,7 +614,10 @@ async function processSpecification(spec, processFunction, args, options) {
|
|
|
614
614
|
throw new Error('Respec generation took too long');
|
|
615
615
|
}
|
|
616
616
|
if (window.document.respec?.ready) {
|
|
617
|
-
await window.document.respec.ready;
|
|
617
|
+
const res = await Promise.race([window.document.respec.ready, sleep(60000)]);
|
|
618
|
+
if (res === 'slept') {
|
|
619
|
+
throw new Error('Respec generation took too long');
|
|
620
|
+
}
|
|
618
621
|
}
|
|
619
622
|
else if (usesRespec) {
|
|
620
623
|
await sleep(1000);
|