Skip to content

Commit 3bada57

Browse files
committed
Handle rules defined in multiple specs
1 parent a5094d9 commit 3bada57

1 file changed

Lines changed: 32 additions & 16 deletions

File tree

scripts/extract.js

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ const excluded = {
647647

648648
const descriptors = Object.keys(initial.descriptors).map(rule => [rule, Object.entries(initial.descriptors[rule])])
649649
const properties = Object.entries(initial.properties)
650+
const rules = []
650651
const types = [...Object.entries(initial.types), ...Object.entries(replaced.types)]
651652

652653
// TODO: periodically review this list to remove errors that no longer occur
@@ -752,21 +753,22 @@ function reportMissingPseudoSelectors(selectors, key) {
752753
}
753754

754755
/**
755-
* @param {string} name
756-
* @param {string} value
757-
* @param {object} rule
758-
* @returns {boolean}
756+
* @param {*[][]} rules
759757
*/
760-
function isUpdatedRule(name, value, { prelude, value: block }) {
761-
let definition = name
762-
if (prelude) {
763-
definition += ` ${prelude}`
764-
}
765-
definition += block ? ` { ${block.name} }` : ' ;'
766-
value = value
767-
.replace(/[([] | [)\],]/g, match => match.trim())
768-
.replace('};', '}')
769-
return value !== definition
758+
function reportRuleUpdates(rules) {
759+
rules.forEach(([name, value, { prelude, value: block }, key]) => {
760+
let definition = name
761+
if (prelude) {
762+
definition += ` ${prelude}`
763+
}
764+
definition += block ? ` { ${block.name} }` : ' ;'
765+
value = value
766+
.replace(/[([] | [)\],]/g, match => match.trim())
767+
.replace('};', '}')
768+
if (value !== definition) {
769+
reportError(key, name, `${name} has a new definition`)
770+
}
771+
})
770772
}
771773

772774
/**
@@ -1065,8 +1067,20 @@ function addRules(definitions = [], key) {
10651067

10661068
const rule = findRule(name)
10671069
if (rule) {
1068-
if (value && isUpdatedRule(name, value, rule)) {
1069-
reportError(key, name, `${name} has a new definition`)
1070+
if (value) {
1071+
const entry = rules.find(([rule]) => rule === name)
1072+
if (entry) {
1073+
const prevKey = entry.at(-1)
1074+
const [base1, v1 = 1] = prevKey.split(/-(\d)$/)
1075+
const [base2, v2 = 1] = key.split(/-(\d)$/)
1076+
if (base1 !== base2) {
1077+
throw Error(`Unhandled duplicate definitions of the rule "${name}"`)
1078+
} else if (v1 < v2) {
1079+
entry.splice(1, 2, value, key)
1080+
}
1081+
} else {
1082+
rules.push([name, value, rule, key])
1083+
}
10701084
}
10711085
addDescriptors(definitions, name, key)
10721086
addTypes(values, key)
@@ -1092,6 +1106,8 @@ function build(specifications) {
10921106
reportMissingPseudoSelectors(selectors, key)
10931107
})
10941108

1109+
reportRuleUpdates(rules)
1110+
10951111
return Promise.all([
10961112
fs.writeFile(
10971113
path.join(import.meta.dirname, '..', 'lib', 'descriptors', 'definitions.js'),

0 commit comments

Comments
 (0)