reffy 8.0.2 → 8.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": "8.0.2",
3
+ "version": "8.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",
@@ -34,7 +34,7 @@
34
34
  "abortcontroller-polyfill": "1.7.3",
35
35
  "commander": "9.4.0",
36
36
  "fetch-filecache-for-crawling": "4.1.0",
37
- "puppeteer": "15.4.0",
37
+ "puppeteer": "15.4.1",
38
38
  "semver": "^7.3.5",
39
39
  "web-specs": "2.17.0",
40
40
  "webidl2": "24.2.2"
@@ -43,7 +43,7 @@
43
43
  "chai": "4.3.6",
44
44
  "mocha": "10.0.0",
45
45
  "nock": "13.2.9",
46
- "respec": "32.1.10",
46
+ "respec": "32.2.0",
47
47
  "respec-hljs": "2.1.1",
48
48
  "rollup": "2.77.0"
49
49
  },
package/reffy.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  /**
3
3
  * The spec crawler takes a list of spec URLs as input, gathers some knowledge
4
4
  * about these specs (published versions, URL of the Editor's Draft, etc.),
package/src/lib/util.js CHANGED
@@ -946,9 +946,13 @@ async function createFolderIfNeeded(folder) {
946
946
  * the tree.
947
947
  */
948
948
  const trees = {
949
- // DOM tree:
949
+ // The DOM tree is defined through "get the parent" algorithms:
950
950
  // https://dom.spec.whatwg.org/#node-trees
951
- 'dom': ['Window', 'Document', 'Element', 'Node'],
951
+ // https://dom.spec.whatwg.org/#get-the-parent
952
+ // - Node -> Node
953
+ // - Document -> Window
954
+ // - ShadowRoot -> Element (both derive from Node, so covered by Node -> Node)
955
+ 'dom': ['Window', 'Document', 'Node'],
952
956
 
953
957
  // IndexedDB tree (defined through "get the parent" algorithms)
954
958
  // https://www.w3.org/TR/IndexedDB/#ref-for-get-the-parent%E2%91%A0
@@ -46,7 +46,6 @@ module.exports = {
46
46
  for (const event of events) {
47
47
  expandMixinTargets(event, mixins);
48
48
  setBubblingPerTarget(event, parsedInterfaces);
49
- cleanTargetInTrees(event, parsedInterfaces);
50
49
  }
51
50
 
52
51
  // Consolidate events extended in other specs
@@ -69,6 +68,7 @@ module.exports = {
69
68
  return events
70
69
  .filter(event => !eventsToDrop.includes(event))
71
70
  .map(event => {
71
+ cleanTargetInterfaces(event, parsedInterfaces);
72
72
  delete event.spec;
73
73
  return event;
74
74
  });
@@ -135,41 +135,57 @@ function setBubblingPerTarget(event, parsedInterfaces) {
135
135
  }
136
136
 
137
137
 
138
- function cleanTargetInTrees(event, parsedInterfaces) {
139
- // When several targets are attached to an event that bubbles
140
- // keep only the "deepest" target
141
- if (event.bubbles && event.targets?.length > 1) {
142
- const filteredTargets = deepestInterfaceInTree(event.targets, parsedInterfaces);
143
- if (filteredTargets.length !== event.targets.length) {
144
- event.targets = filteredTargets;
145
- return true;
138
+ /**
139
+ * Filter the list of target interfaces to remove those that don't need to
140
+ * appear explicitly because they are de facto already covered by another entry
141
+ * in the list.
142
+ *
143
+ * Two reasons to drop a target interface t from the list:
144
+ * 1. There exists another target interface o with similar bubbling properties
145
+ * for the event and t inherits from o. If event fires at o, it can de facto
146
+ * fire at t.
147
+ * 2. There exists another target interface o such that t and o belong to the
148
+ * same bubbling tree, o is at a deeper level than t in the bubbling tree, and
149
+ * event bubbles when it fires at o. Event will de facto fire at t through
150
+ * bubbling when that happens.
151
+ */
152
+ function cleanTargetInterfaces(event, parsedInterfaces) {
153
+ // Helper function that returns true if the iface interface inherits from the
154
+ // base interface
155
+ function inheritsFrom(iface, base) {
156
+ while (iface) {
157
+ if (iface === base) {
158
+ return true;
159
+ }
160
+ iface = parsedInterfaces.find(i => i.name === iface)?.inheritance;
146
161
  }
162
+ return false;
147
163
  }
148
- return false;
149
- }
150
-
151
164
 
152
- function deepestInterfaceInTree(targets, parsedInterfaces) {
153
- let deepestInTrees = {};
154
- let filteredTargets = [];
155
- for (let {target, bubbles} of targets) {
156
- const treeInfo = getInterfaceTreeInfo(target, parsedInterfaces);
157
- if (!treeInfo) { // Not in a tree, we keep it in
158
- filteredTargets.push({target});
159
- continue;
160
- }
161
- const { tree, depth } = treeInfo;
162
- const currentDeepest = deepestInTrees[tree]?.target;
163
- if (currentDeepest) {
164
- const { depth: currentDeepestDepth } = getInterfaceTreeInfo(currentDeepest, parsedInterfaces);
165
- if (depth > currentDeepestDepth) {
166
- deepestInTrees[tree] = {target, bubbles};
167
- }
168
- } else {
169
- deepestInTrees[tree] = {target, bubbles};
170
- }
165
+ if (!event.targets) {
166
+ return;
171
167
  }
172
- return filteredTargets.concat(Object.values(deepestInTrees));
168
+
169
+ event.targets = event.targets
170
+ .filter(({ target, bubbles }) =>
171
+ // Drop if an ancestor in the inheritance chain is already there
172
+ !event.targets.find(({ target: other, bubbles: otherBubbles}) =>
173
+ target !== other &&
174
+ bubbles === otherBubbles &&
175
+ inheritsFrom(target, other)))
176
+ .filter(({ target, bubbles }) => {
177
+ // Drop if a deeper bubbling target interface in the tree is already there
178
+ const targetTreeInfo = getInterfaceTreeInfo(target, parsedInterfaces);
179
+ return !targetTreeInfo ||
180
+ !event.targets.find(({ target: other, bubbles: otherBubbles }) => {
181
+ if (other === target) {
182
+ return false;
183
+ }
184
+ const otherTreeInfo = getInterfaceTreeInfo(other, parsedInterfaces);
185
+ return otherTreeInfo?.tree === targetTreeInfo.tree &&
186
+ otherBubbles && otherTreeInfo.depth > targetTreeInfo.depth;
187
+ });
188
+ });
173
189
  }
174
190
 
175
191