reffy 6.2.0 → 6.2.1
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/LICENSE +21 -21
- package/README.md +158 -158
- package/index.js +11 -11
- package/package.json +53 -53
- package/reffy.js +248 -248
- package/src/browserlib/canonicalize-url.mjs +50 -50
- package/src/browserlib/create-outline.mjs +352 -352
- package/src/browserlib/extract-cssdfn.mjs +319 -319
- package/src/browserlib/extract-dfns.mjs +686 -686
- package/src/browserlib/extract-elements.mjs +205 -205
- package/src/browserlib/extract-headings.mjs +48 -48
- package/src/browserlib/extract-ids.mjs +28 -28
- package/src/browserlib/extract-links.mjs +28 -28
- package/src/browserlib/extract-references.mjs +203 -203
- package/src/browserlib/extract-webidl.mjs +134 -134
- package/src/browserlib/get-absolute-url.mjs +21 -21
- package/src/browserlib/get-generator.mjs +26 -26
- package/src/browserlib/get-lastmodified-date.mjs +13 -13
- package/src/browserlib/get-title.mjs +11 -11
- package/src/browserlib/informative-selector.mjs +16 -16
- package/src/browserlib/map-ids-to-headings.mjs +136 -136
- package/src/browserlib/reffy.json +53 -53
- package/src/cli/check-missing-dfns.js +609 -609
- package/src/cli/generate-idlnames.js +430 -430
- package/src/cli/generate-idlparsed.js +139 -139
- package/src/cli/merge-crawl-results.js +128 -128
- package/src/cli/parse-webidl.js +430 -430
- package/src/lib/css-grammar-parse-tree.schema.json +109 -109
- package/src/lib/css-grammar-parser.js +440 -440
- package/src/lib/fetch.js +55 -55
- package/src/lib/nock-server.js +119 -119
- package/src/lib/specs-crawler.js +605 -603
- package/src/lib/util.js +898 -898
- package/src/specs/missing-css-rules.json +197 -197
- package/src/specs/spec-equivalents.json +149 -149
- package/src/browserlib/extract-editors.mjs~ +0 -14
- package/src/browserlib/generate-es-dfn-report.sh~ +0 -4
- package/src/cli/csstree-grammar-check.js +0 -28
- package/src/cli/csstree-grammar-check.js~ +0 -10
- package/src/cli/csstree-grammar-parser.js +0 -11
- package/src/cli/csstree-grammar-parser.js~ +0 -1
- package/src/cli/extract-editors.js~ +0 -38
- package/src/cli/process-specs.js~ +0 -28
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Gets the absolute URL with fragment to the given node
|
|
3
|
-
*
|
|
4
|
-
* @function
|
|
5
|
-
* @public
|
|
6
|
-
* @param {Element} node DOM node to look at. Must have an ID.
|
|
7
|
-
* @param {Object} options "singlePage" asserts whether the spec is single page
|
|
8
|
-
* or whether that's unknown. Default is false for "unknown".
|
|
9
|
-
* "attribute" tells function to use value of given attribute name instead of
|
|
10
|
-
* the node's ID. Default is "id".
|
|
11
|
-
* @return {String} Absolute URL ending with fragment ref
|
|
12
|
-
*/
|
|
13
|
-
export default function (node, { singlePage, attribute } =
|
|
14
|
-
{ singlePage: false, attribute: 'id' }) {
|
|
15
|
-
attribute = attribute ?? 'id';
|
|
16
|
-
const page = singlePage ? null :
|
|
17
|
-
node.closest('[data-reffy-page]')?.getAttribute('data-reffy-page');
|
|
18
|
-
const url = new URL(page ?? window.location.href);
|
|
19
|
-
url.hash = '#' + node.getAttribute(attribute);
|
|
20
|
-
return url.toString();
|
|
21
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Gets the absolute URL with fragment to the given node
|
|
3
|
+
*
|
|
4
|
+
* @function
|
|
5
|
+
* @public
|
|
6
|
+
* @param {Element} node DOM node to look at. Must have an ID.
|
|
7
|
+
* @param {Object} options "singlePage" asserts whether the spec is single page
|
|
8
|
+
* or whether that's unknown. Default is false for "unknown".
|
|
9
|
+
* "attribute" tells function to use value of given attribute name instead of
|
|
10
|
+
* the node's ID. Default is "id".
|
|
11
|
+
* @return {String} Absolute URL ending with fragment ref
|
|
12
|
+
*/
|
|
13
|
+
export default function (node, { singlePage, attribute } =
|
|
14
|
+
{ singlePage: false, attribute: 'id' }) {
|
|
15
|
+
attribute = attribute ?? 'id';
|
|
16
|
+
const page = singlePage ? null :
|
|
17
|
+
node.closest('[data-reffy-page]')?.getAttribute('data-reffy-page');
|
|
18
|
+
const url = new URL(page ?? window.location.href);
|
|
19
|
+
url.hash = '#' + node.getAttribute(attribute);
|
|
20
|
+
return url.toString();
|
|
21
|
+
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Return the name of a well-known generator that was used to generate the
|
|
3
|
-
* spec, if known.
|
|
4
|
-
*
|
|
5
|
-
* This function expects to run within a browser context.
|
|
6
|
-
*
|
|
7
|
-
* @function
|
|
8
|
-
* @public
|
|
9
|
-
* @param {Window} window
|
|
10
|
-
* @return {Promise} The promise to get a document ready for extraction and
|
|
11
|
-
* the name of the generator (or null if generator is unknown).
|
|
12
|
-
*/
|
|
13
|
-
export default function () {
|
|
14
|
-
const generator = window.document.querySelector('meta[name="generator"]');
|
|
15
|
-
if (generator && generator.content.match(/bikeshed/i)) {
|
|
16
|
-
return 'bikeshed';
|
|
17
|
-
}
|
|
18
|
-
else if ((generator && generator.content.match(/respec/i)) ||
|
|
19
|
-
(document.body.id === 'respecDocument') ||
|
|
20
|
-
window.respecConfig ||
|
|
21
|
-
window.eval('typeof respecConfig !== "undefined"')) {
|
|
22
|
-
return 'respec';
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Return the name of a well-known generator that was used to generate the
|
|
3
|
+
* spec, if known.
|
|
4
|
+
*
|
|
5
|
+
* This function expects to run within a browser context.
|
|
6
|
+
*
|
|
7
|
+
* @function
|
|
8
|
+
* @public
|
|
9
|
+
* @param {Window} window
|
|
10
|
+
* @return {Promise} The promise to get a document ready for extraction and
|
|
11
|
+
* the name of the generator (or null if generator is unknown).
|
|
12
|
+
*/
|
|
13
|
+
export default function () {
|
|
14
|
+
const generator = window.document.querySelector('meta[name="generator"]');
|
|
15
|
+
if (generator && generator.content.match(/bikeshed/i)) {
|
|
16
|
+
return 'bikeshed';
|
|
17
|
+
}
|
|
18
|
+
else if ((generator && generator.content.match(/respec/i)) ||
|
|
19
|
+
(document.body.id === 'respecDocument') ||
|
|
20
|
+
window.respecConfig ||
|
|
21
|
+
window.eval('typeof respecConfig !== "undefined"')) {
|
|
22
|
+
return 'respec';
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
27
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
export default function () {
|
|
2
|
-
const dateEl = document.querySelector('.head time');
|
|
3
|
-
const statusAndDate = [...document.querySelectorAll('.head h2')]
|
|
4
|
-
.map(el => el.textContent).join(' ').trim();
|
|
5
|
-
const lastModified = new Date(Date.parse(document.lastModified));
|
|
6
|
-
const date = dateEl ? dateEl.textContent.trim() :
|
|
7
|
-
(statusAndDate ? statusAndDate.split(/\s+/).slice(-3).join(' ') :
|
|
8
|
-
[
|
|
9
|
-
lastModified.toLocaleDateString('en-US', { day: 'numeric' }),
|
|
10
|
-
lastModified.toLocaleDateString('en-US', { month: 'long' }),
|
|
11
|
-
lastModified.toLocaleDateString('en-US', { year: 'numeric' })
|
|
12
|
-
].join(' '));
|
|
13
|
-
return date;
|
|
1
|
+
export default function () {
|
|
2
|
+
const dateEl = document.querySelector('.head time');
|
|
3
|
+
const statusAndDate = [...document.querySelectorAll('.head h2')]
|
|
4
|
+
.map(el => el.textContent).join(' ').trim();
|
|
5
|
+
const lastModified = new Date(Date.parse(document.lastModified));
|
|
6
|
+
const date = dateEl ? dateEl.textContent.trim() :
|
|
7
|
+
(statusAndDate ? statusAndDate.split(/\s+/).slice(-3).join(' ') :
|
|
8
|
+
[
|
|
9
|
+
lastModified.toLocaleDateString('en-US', { day: 'numeric' }),
|
|
10
|
+
lastModified.toLocaleDateString('en-US', { month: 'long' }),
|
|
11
|
+
lastModified.toLocaleDateString('en-US', { year: 'numeric' })
|
|
12
|
+
].join(' '));
|
|
13
|
+
return date;
|
|
14
14
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Gets the title of the document
|
|
3
|
-
*/
|
|
4
|
-
export default function () {
|
|
5
|
-
const title = window.document.querySelector('title');
|
|
6
|
-
if (title) {
|
|
7
|
-
return title.textContent.replace(/\s+/g, ' ').trim();
|
|
8
|
-
}
|
|
9
|
-
else {
|
|
10
|
-
return '[No title found for ' + window.location.href + ']';
|
|
11
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Gets the title of the document
|
|
3
|
+
*/
|
|
4
|
+
export default function () {
|
|
5
|
+
const title = window.document.querySelector('title');
|
|
6
|
+
if (title) {
|
|
7
|
+
return title.textContent.replace(/\s+/g, ' ').trim();
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
return '[No title found for ' + window.location.href + ']';
|
|
11
|
+
}
|
|
12
12
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query selector that matches informative sections
|
|
3
|
-
*
|
|
4
|
-
* Based on:
|
|
5
|
-
* https://github.com/w3c/respec/blob/develop/src/core/utils.js#L45
|
|
6
|
-
* https://tabatkins.github.io/bikeshed/#metadata-informative-classes
|
|
7
|
-
*/
|
|
8
|
-
export default [
|
|
9
|
-
'.informative',
|
|
10
|
-
'.note',
|
|
11
|
-
'.issue',
|
|
12
|
-
'.example',
|
|
13
|
-
'.ednote',
|
|
14
|
-
'.practice',
|
|
15
|
-
'.introductory',
|
|
16
|
-
'.non-normative'
|
|
1
|
+
/**
|
|
2
|
+
* Query selector that matches informative sections
|
|
3
|
+
*
|
|
4
|
+
* Based on:
|
|
5
|
+
* https://github.com/w3c/respec/blob/develop/src/core/utils.js#L45
|
|
6
|
+
* https://tabatkins.github.io/bikeshed/#metadata-informative-classes
|
|
7
|
+
*/
|
|
8
|
+
export default [
|
|
9
|
+
'.informative',
|
|
10
|
+
'.note',
|
|
11
|
+
'.issue',
|
|
12
|
+
'.example',
|
|
13
|
+
'.ednote',
|
|
14
|
+
'.practice',
|
|
15
|
+
'.introductory',
|
|
16
|
+
'.non-normative'
|
|
17
17
|
].join(',');
|
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
import createOutline from './create-outline.mjs';
|
|
2
|
-
import getAbsoluteUrl from './get-absolute-url.mjs';
|
|
3
|
-
|
|
4
|
-
// Regular expression to capture the numbering of a heading. The expression
|
|
5
|
-
// extracts numbers such as "1.", "A.", "A.3", "13.3.4.". Note: a top-level
|
|
6
|
-
// number always ends with a ".", but there may be no final "." in sublevels
|
|
7
|
-
// (Bikeshed adds one, ReSpec does not).
|
|
8
|
-
const reNumber = /^([A-Z0-9]\.|[A-Z](\.[0-9]+)+\.?|[0-9]+(\.[0-9]+)+\.?)\s/;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Generate a mapping between elements that have an ID and the closest heading
|
|
12
|
-
* (that also has an ID) under which these elements appear in the DOM tree.
|
|
13
|
-
*
|
|
14
|
-
* The main difficulty is that the structure of a DOM tree does not necessarily
|
|
15
|
-
* follow the structure of the outline of the document, which means that there
|
|
16
|
-
* is no direct way to tell the conceptual section where an element is defined
|
|
17
|
-
* just by looking at its list of ancestors in the DOM tree.
|
|
18
|
-
*
|
|
19
|
-
* In practice, the outline of the document needs to be prepared accordingly to
|
|
20
|
-
* the HTML spec before the mapping can be done.
|
|
21
|
-
*
|
|
22
|
-
* @function
|
|
23
|
-
* @public
|
|
24
|
-
* @return {Object} A mapping table, where keys are IDs of all elements in the
|
|
25
|
-
* document, and values are IDs of the heading elements under which these
|
|
26
|
-
* elements are defined. The table only contains IDs for which there exists
|
|
27
|
-
* such a heading.
|
|
28
|
-
*/
|
|
29
|
-
export default function () {
|
|
30
|
-
// Special-casing ecmascript specs which use special markup for sections
|
|
31
|
-
// <emu-clause>
|
|
32
|
-
if (document.querySelector("emu-clause")) {
|
|
33
|
-
return esMapIdToHeadings();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
// Get a flat list of all conceptual sections
|
|
38
|
-
function flattenSections(outline) {
|
|
39
|
-
return outline
|
|
40
|
-
.concat(outline.flatMap(section => flattenSections(section.subSections)))
|
|
41
|
-
.concat(outline.flatMap(section => flattenSections(section.subRoots)));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const { outline, nodeToSection } = createOutline(document.body);
|
|
45
|
-
const sections = flattenSections(outline);
|
|
46
|
-
|
|
47
|
-
// Compute once whether we created a single page version out of multiple pages
|
|
48
|
-
const singlePage = !document.querySelector('[data-reffy-page]');
|
|
49
|
-
|
|
50
|
-
const mappingTable = {};
|
|
51
|
-
[...document.querySelectorAll('[id]')].forEach(node => {
|
|
52
|
-
let parentSection = nodeToSection.get(node);
|
|
53
|
-
while (parentSection) {
|
|
54
|
-
if (parentSection.heading !== '__implied') {
|
|
55
|
-
break;
|
|
56
|
-
}
|
|
57
|
-
parentSection = sections.find(section =>
|
|
58
|
-
section.subSections.includes(parentSection) ||
|
|
59
|
-
section.subRoots.includes(parentSection));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Compute the absolute URL with fragment
|
|
63
|
-
// (Note the crawler merges pages of a multi-page spec in the first page
|
|
64
|
-
// to ease parsing logic, and we want to get back to the URL of the page)
|
|
65
|
-
const nodeid = getAbsoluteUrl(node, { singlePage });
|
|
66
|
-
let href = nodeid;
|
|
67
|
-
|
|
68
|
-
if (parentSection) {
|
|
69
|
-
const heading = parentSection.heading;
|
|
70
|
-
let id = heading.id;
|
|
71
|
-
href = getAbsoluteUrl(heading, { singlePage });
|
|
72
|
-
|
|
73
|
-
if (parentSection.root && parentSection.root.hasAttribute('id')) {
|
|
74
|
-
id = parentSection.root.id;
|
|
75
|
-
href = getAbsoluteUrl(parentSection.root, { singlePage });
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const trimmedText = heading.textContent.trim();
|
|
79
|
-
const match = trimmedText.match(reNumber);
|
|
80
|
-
const number = match ? match[1] : null;
|
|
81
|
-
|
|
82
|
-
mappingTable[nodeid] = {
|
|
83
|
-
id,
|
|
84
|
-
href,
|
|
85
|
-
title: trimmedText.replace(reNumber, '').trim().replace(/\s+/g, ' ')
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
if (number) {
|
|
89
|
-
// Store the number without the final "."
|
|
90
|
-
mappingTable[nodeid].number = number.replace(/\.$/, '');
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
return mappingTable;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function esMapIdToHeadings() {
|
|
99
|
-
// Based on https://tc39.es/ecmarkup/
|
|
100
|
-
// and actual emu-* tags used in the ecmascript spec with ids
|
|
101
|
-
const ignoreTags = ["emu-xref"];
|
|
102
|
-
const sectionTags = ["emu-intro", "emu-clause", "emu-annex"];
|
|
103
|
-
|
|
104
|
-
// Compute once whether we created a single page version out of multiple pages
|
|
105
|
-
const singlePage = !document.querySelector('[data-reffy-page]');
|
|
106
|
-
|
|
107
|
-
let mappingTable = {};
|
|
108
|
-
[...document.querySelectorAll(`[id]:not(${ignoreTags.join(',')}`)]
|
|
109
|
-
.forEach(el => {
|
|
110
|
-
const section = el.closest(`${sectionTags.map(t => `${t}[id]`).join(',')}`);
|
|
111
|
-
|
|
112
|
-
// These are spec UI-related ids, so not a loss
|
|
113
|
-
if (!section) return;
|
|
114
|
-
|
|
115
|
-
const heading = section.querySelector("h1");
|
|
116
|
-
const trimmedText = heading.textContent.trim();
|
|
117
|
-
const nodeid = getAbsoluteUrl(el, { singlePage });
|
|
118
|
-
const href = getAbsoluteUrl(section, { singlePage });
|
|
119
|
-
|
|
120
|
-
const match = trimmedText.match(reNumber);
|
|
121
|
-
const number = match ? match[1] : null;
|
|
122
|
-
|
|
123
|
-
mappingTable[nodeid] = {
|
|
124
|
-
id: section.id,
|
|
125
|
-
href,
|
|
126
|
-
title: trimmedText.replace(reNumber, '').trim().replace(/\s+/g, ' ')
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
if (number) {
|
|
130
|
-
// Store the number without the final "."
|
|
131
|
-
mappingTable[nodeid].number = number.replace(/\.$/, '');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
});
|
|
135
|
-
return mappingTable;
|
|
136
|
-
}
|
|
1
|
+
import createOutline from './create-outline.mjs';
|
|
2
|
+
import getAbsoluteUrl from './get-absolute-url.mjs';
|
|
3
|
+
|
|
4
|
+
// Regular expression to capture the numbering of a heading. The expression
|
|
5
|
+
// extracts numbers such as "1.", "A.", "A.3", "13.3.4.". Note: a top-level
|
|
6
|
+
// number always ends with a ".", but there may be no final "." in sublevels
|
|
7
|
+
// (Bikeshed adds one, ReSpec does not).
|
|
8
|
+
const reNumber = /^([A-Z0-9]\.|[A-Z](\.[0-9]+)+\.?|[0-9]+(\.[0-9]+)+\.?)\s/;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Generate a mapping between elements that have an ID and the closest heading
|
|
12
|
+
* (that also has an ID) under which these elements appear in the DOM tree.
|
|
13
|
+
*
|
|
14
|
+
* The main difficulty is that the structure of a DOM tree does not necessarily
|
|
15
|
+
* follow the structure of the outline of the document, which means that there
|
|
16
|
+
* is no direct way to tell the conceptual section where an element is defined
|
|
17
|
+
* just by looking at its list of ancestors in the DOM tree.
|
|
18
|
+
*
|
|
19
|
+
* In practice, the outline of the document needs to be prepared accordingly to
|
|
20
|
+
* the HTML spec before the mapping can be done.
|
|
21
|
+
*
|
|
22
|
+
* @function
|
|
23
|
+
* @public
|
|
24
|
+
* @return {Object} A mapping table, where keys are IDs of all elements in the
|
|
25
|
+
* document, and values are IDs of the heading elements under which these
|
|
26
|
+
* elements are defined. The table only contains IDs for which there exists
|
|
27
|
+
* such a heading.
|
|
28
|
+
*/
|
|
29
|
+
export default function () {
|
|
30
|
+
// Special-casing ecmascript specs which use special markup for sections
|
|
31
|
+
// <emu-clause>
|
|
32
|
+
if (document.querySelector("emu-clause")) {
|
|
33
|
+
return esMapIdToHeadings();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
// Get a flat list of all conceptual sections
|
|
38
|
+
function flattenSections(outline) {
|
|
39
|
+
return outline
|
|
40
|
+
.concat(outline.flatMap(section => flattenSections(section.subSections)))
|
|
41
|
+
.concat(outline.flatMap(section => flattenSections(section.subRoots)));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const { outline, nodeToSection } = createOutline(document.body);
|
|
45
|
+
const sections = flattenSections(outline);
|
|
46
|
+
|
|
47
|
+
// Compute once whether we created a single page version out of multiple pages
|
|
48
|
+
const singlePage = !document.querySelector('[data-reffy-page]');
|
|
49
|
+
|
|
50
|
+
const mappingTable = {};
|
|
51
|
+
[...document.querySelectorAll('[id]')].forEach(node => {
|
|
52
|
+
let parentSection = nodeToSection.get(node);
|
|
53
|
+
while (parentSection) {
|
|
54
|
+
if (parentSection.heading !== '__implied') {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
parentSection = sections.find(section =>
|
|
58
|
+
section.subSections.includes(parentSection) ||
|
|
59
|
+
section.subRoots.includes(parentSection));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Compute the absolute URL with fragment
|
|
63
|
+
// (Note the crawler merges pages of a multi-page spec in the first page
|
|
64
|
+
// to ease parsing logic, and we want to get back to the URL of the page)
|
|
65
|
+
const nodeid = getAbsoluteUrl(node, { singlePage });
|
|
66
|
+
let href = nodeid;
|
|
67
|
+
|
|
68
|
+
if (parentSection) {
|
|
69
|
+
const heading = parentSection.heading;
|
|
70
|
+
let id = heading.id;
|
|
71
|
+
href = getAbsoluteUrl(heading, { singlePage });
|
|
72
|
+
|
|
73
|
+
if (parentSection.root && parentSection.root.hasAttribute('id')) {
|
|
74
|
+
id = parentSection.root.id;
|
|
75
|
+
href = getAbsoluteUrl(parentSection.root, { singlePage });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const trimmedText = heading.textContent.trim();
|
|
79
|
+
const match = trimmedText.match(reNumber);
|
|
80
|
+
const number = match ? match[1] : null;
|
|
81
|
+
|
|
82
|
+
mappingTable[nodeid] = {
|
|
83
|
+
id,
|
|
84
|
+
href,
|
|
85
|
+
title: trimmedText.replace(reNumber, '').trim().replace(/\s+/g, ' ')
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
if (number) {
|
|
89
|
+
// Store the number without the final "."
|
|
90
|
+
mappingTable[nodeid].number = number.replace(/\.$/, '');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return mappingTable;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function esMapIdToHeadings() {
|
|
99
|
+
// Based on https://tc39.es/ecmarkup/
|
|
100
|
+
// and actual emu-* tags used in the ecmascript spec with ids
|
|
101
|
+
const ignoreTags = ["emu-xref"];
|
|
102
|
+
const sectionTags = ["emu-intro", "emu-clause", "emu-annex"];
|
|
103
|
+
|
|
104
|
+
// Compute once whether we created a single page version out of multiple pages
|
|
105
|
+
const singlePage = !document.querySelector('[data-reffy-page]');
|
|
106
|
+
|
|
107
|
+
let mappingTable = {};
|
|
108
|
+
[...document.querySelectorAll(`[id]:not(${ignoreTags.join(',')}`)]
|
|
109
|
+
.forEach(el => {
|
|
110
|
+
const section = el.closest(`${sectionTags.map(t => `${t}[id]`).join(',')}`);
|
|
111
|
+
|
|
112
|
+
// These are spec UI-related ids, so not a loss
|
|
113
|
+
if (!section) return;
|
|
114
|
+
|
|
115
|
+
const heading = section.querySelector("h1");
|
|
116
|
+
const trimmedText = heading.textContent.trim();
|
|
117
|
+
const nodeid = getAbsoluteUrl(el, { singlePage });
|
|
118
|
+
const href = getAbsoluteUrl(section, { singlePage });
|
|
119
|
+
|
|
120
|
+
const match = trimmedText.match(reNumber);
|
|
121
|
+
const number = match ? match[1] : null;
|
|
122
|
+
|
|
123
|
+
mappingTable[nodeid] = {
|
|
124
|
+
id: section.id,
|
|
125
|
+
href,
|
|
126
|
+
title: trimmedText.replace(reNumber, '').trim().replace(/\s+/g, ' ')
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
if (number) {
|
|
130
|
+
// Store the number without the final "."
|
|
131
|
+
mappingTable[nodeid].number = number.replace(/\.$/, '');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
});
|
|
135
|
+
return mappingTable;
|
|
136
|
+
}
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"href": "./get-title.mjs",
|
|
4
|
-
"property": "title",
|
|
5
|
-
"metadata": true
|
|
6
|
-
},
|
|
7
|
-
{
|
|
8
|
-
"href": "./get-generator.mjs",
|
|
9
|
-
"property": "generator",
|
|
10
|
-
"metadata": true
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"href": "./get-lastmodified-date.mjs",
|
|
14
|
-
"property": "date",
|
|
15
|
-
"metadata": true
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"href": "./extract-links.mjs",
|
|
19
|
-
"property": "links"
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
"href": "./extract-references.mjs",
|
|
23
|
-
"property": "refs"
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"href": "./extract-webidl.mjs",
|
|
27
|
-
"property": "idl",
|
|
28
|
-
"extractsPerSeries": true
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"href": "./extract-cssdfn.mjs",
|
|
32
|
-
"property": "css",
|
|
33
|
-
"extractsPerSeries": true
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"href": "./extract-dfns.mjs",
|
|
37
|
-
"property": "dfns",
|
|
38
|
-
"needsIdToHeadingMap": true
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"href": "./extract-elements.mjs",
|
|
42
|
-
"property": "elements"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"href": "./extract-headings.mjs",
|
|
46
|
-
"property": "headings"
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"href": "./extract-ids.mjs",
|
|
50
|
-
"property": "ids",
|
|
51
|
-
"needsIdToHeadingMap": true
|
|
52
|
-
}
|
|
53
|
-
]
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"href": "./get-title.mjs",
|
|
4
|
+
"property": "title",
|
|
5
|
+
"metadata": true
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"href": "./get-generator.mjs",
|
|
9
|
+
"property": "generator",
|
|
10
|
+
"metadata": true
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"href": "./get-lastmodified-date.mjs",
|
|
14
|
+
"property": "date",
|
|
15
|
+
"metadata": true
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"href": "./extract-links.mjs",
|
|
19
|
+
"property": "links"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"href": "./extract-references.mjs",
|
|
23
|
+
"property": "refs"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"href": "./extract-webidl.mjs",
|
|
27
|
+
"property": "idl",
|
|
28
|
+
"extractsPerSeries": true
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"href": "./extract-cssdfn.mjs",
|
|
32
|
+
"property": "css",
|
|
33
|
+
"extractsPerSeries": true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"href": "./extract-dfns.mjs",
|
|
37
|
+
"property": "dfns",
|
|
38
|
+
"needsIdToHeadingMap": true
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"href": "./extract-elements.mjs",
|
|
42
|
+
"property": "elements"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"href": "./extract-headings.mjs",
|
|
46
|
+
"property": "headings"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"href": "./extract-ids.mjs",
|
|
50
|
+
"property": "ids",
|
|
51
|
+
"needsIdToHeadingMap": true
|
|
52
|
+
}
|
|
53
|
+
]
|