123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // @ts-nocheck
-
- 'use strict';
-
- const declarationValueIndex = require('../../utils/declarationValueIndex');
- const isNumbery = require('../../utils/isNumbery');
- const isStandardSyntaxValue = require('../../utils/isStandardSyntaxValue');
- const isVariable = require('../../utils/isVariable');
- const keywordSets = require('../../reference/keywordSets');
- const optionsMatches = require('../../utils/optionsMatches');
- const postcss = require('postcss');
- const report = require('../../utils/report');
- const ruleMessages = require('../../utils/ruleMessages');
- const validateOptions = require('../../utils/validateOptions');
-
- const ruleName = 'font-weight-notation';
-
- const messages = ruleMessages(ruleName, {
- expected: (type) => `Expected ${type} font-weight notation`,
- invalidNamed: (name) => `Unexpected invalid font-weight name "${name}"`,
- });
-
- const INHERIT_KEYWORD = 'inherit';
- const INITIAL_KEYWORD = 'initial';
- const NORMAL_KEYWORD = 'normal';
- const WEIGHTS_WITH_KEYWORD_EQUIVALENTS = new Set(['400', '700']);
-
- function rule(expectation, options) {
- return (root, result) => {
- const validOptions = validateOptions(
- result,
- ruleName,
- {
- actual: expectation,
- possible: ['numeric', 'named-where-possible'],
- },
- {
- actual: options,
- possible: {
- ignore: ['relative'],
- },
- optional: true,
- },
- );
-
- if (!validOptions) {
- return;
- }
-
- root.walkDecls((decl) => {
- if (decl.prop.toLowerCase() === 'font-weight') {
- checkWeight(decl.value, decl);
- }
-
- if (decl.prop.toLowerCase() === 'font') {
- checkFont(decl);
- }
- });
-
- function checkFont(decl) {
- const valueList = postcss.list.space(decl.value);
- // We do not need to more carefully distinguish font-weight
- // numbers from unitless line-heights because line-heights in
- // `font` values need to be part of a font-size/line-height pair
- const hasNumericFontWeight = valueList.some(isNumbery);
-
- for (const value of postcss.list.space(decl.value)) {
- if (
- (value.toLowerCase() === NORMAL_KEYWORD && !hasNumericFontWeight) ||
- isNumbery(value) ||
- (value.toLowerCase() !== NORMAL_KEYWORD &&
- keywordSets.fontWeightKeywords.has(value.toLowerCase()))
- ) {
- checkWeight(value, decl);
-
- return;
- }
- }
- }
-
- function checkWeight(weightValue, decl) {
- if (!isStandardSyntaxValue(weightValue)) {
- return;
- }
-
- if (isVariable(weightValue)) {
- return;
- }
-
- if (
- weightValue.toLowerCase() === INHERIT_KEYWORD ||
- weightValue.toLowerCase() === INITIAL_KEYWORD
- ) {
- return;
- }
-
- if (
- optionsMatches(options, 'ignore', 'relative') &&
- keywordSets.fontWeightRelativeKeywords.has(weightValue.toLowerCase())
- ) {
- return;
- }
-
- const weightValueOffset = decl.value.indexOf(weightValue);
-
- if (expectation === 'numeric') {
- if (decl.parent.type === 'atrule' && decl.parent.name.toLowerCase() === 'font-face') {
- const weightValueNumbers = postcss.list.space(weightValue);
-
- if (!weightValueNumbers.every(isNumbery)) {
- return complain(messages.expected('numeric'));
- }
-
- return;
- }
-
- if (!isNumbery(weightValue)) {
- return complain(messages.expected('numeric'));
- }
- }
-
- if (expectation === 'named-where-possible') {
- if (isNumbery(weightValue)) {
- if (WEIGHTS_WITH_KEYWORD_EQUIVALENTS.has(weightValue)) {
- complain(messages.expected('named'));
- }
-
- return;
- }
-
- if (
- !keywordSets.fontWeightKeywords.has(weightValue.toLowerCase()) &&
- weightValue.toLowerCase() !== NORMAL_KEYWORD
- ) {
- return complain(messages.invalidNamed(weightValue));
- }
- }
-
- function complain(message) {
- report({
- ruleName,
- result,
- message,
- node: decl,
- index: declarationValueIndex(decl) + weightValueOffset,
- });
- }
- }
- };
- }
-
- rule.ruleName = ruleName;
- rule.messages = messages;
- module.exports = rule;
|