fork from https://github.com/mozilla/pdf.js.git
This commit is contained in:
108
external/stylelint/no-unused-custom-properties.mjs
vendored
Normal file
108
external/stylelint/no-unused-custom-properties.mjs
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/* Copyright 2025 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { parse, registerWalkers, Root } from "postcss-values-parser";
|
||||
import { isString } from "stylelint/lib/utils/validateTypes.mjs";
|
||||
import stylelint from "stylelint";
|
||||
|
||||
const {
|
||||
createPlugin,
|
||||
utils: { report, validateOptions },
|
||||
} = stylelint;
|
||||
|
||||
registerWalkers(Root);
|
||||
|
||||
const ruleName = "pdfjs/no-unused-custom-properties";
|
||||
|
||||
// It's a very basic linter: we don't take into account scopes.
|
||||
// But it should be enough for our use case.
|
||||
|
||||
/** @type {import('stylelint').Plugin} */
|
||||
const ruleFunction =
|
||||
(enabled, { ignoreList = [] } = {}, context = {}) =>
|
||||
(root, result) => {
|
||||
const validOptions = validateOptions(
|
||||
result,
|
||||
ruleName,
|
||||
{
|
||||
actual: enabled,
|
||||
possible: [true],
|
||||
},
|
||||
{
|
||||
actual: ignoreList,
|
||||
possible: [isString],
|
||||
optional: true,
|
||||
}
|
||||
);
|
||||
|
||||
if (!validOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
ignoreList = ignoreList.map(s => (s.startsWith("--") ? s : `--${s}`));
|
||||
|
||||
const usedCustomProperties = new Set(ignoreList);
|
||||
const definedCustomProperties = new Set();
|
||||
const usedBy = new Map();
|
||||
root.walkDecls(decl => {
|
||||
let definingProperty = null;
|
||||
if (decl.prop.startsWith("--")) {
|
||||
// This is a custom property definition.
|
||||
definingProperty = decl.prop;
|
||||
definedCustomProperties.add(definingProperty);
|
||||
}
|
||||
// Parse the declaration value to find var() usages.
|
||||
const parsedValue = parse(decl.value);
|
||||
parsedValue.walkFuncs(node => {
|
||||
if (!node.isVar || node.nodes.length === 0) {
|
||||
return;
|
||||
}
|
||||
// This is a var() function; get the custom property name.
|
||||
const property = node.nodes[0].value;
|
||||
if (!definingProperty) {
|
||||
// This is a usage of a custom property but not in a definition.
|
||||
// width: var(--foo);
|
||||
usedCustomProperties.add(property);
|
||||
return;
|
||||
}
|
||||
let usages = usedBy.get(property);
|
||||
if (!usages) {
|
||||
usages = [];
|
||||
usedBy.set(property, usages);
|
||||
}
|
||||
// Record that this custom property is used by the defining property.
|
||||
// --foo: var(--bar);
|
||||
// bar is really used only if foo is.
|
||||
usages.push(definingProperty);
|
||||
});
|
||||
});
|
||||
const isUsed = p =>
|
||||
usedCustomProperties.has(p) || (usedBy.get(p) || []).some(isUsed);
|
||||
for (const customProperty of definedCustomProperties) {
|
||||
if (isUsed(customProperty)) {
|
||||
continue;
|
||||
}
|
||||
report({
|
||||
message: `Custom property "${customProperty}" is defined but never used.`,
|
||||
node: root,
|
||||
result,
|
||||
ruleName,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ruleFunction.ruleName = ruleName;
|
||||
|
||||
export default createPlugin(ruleName, ruleFunction);
|
||||
Reference in New Issue
Block a user