Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // @ts-nocheck
  2. 'use strict';
  3. const _ = require('lodash');
  4. const declarationValueIndex = require('../../utils/declarationValueIndex');
  5. const getDeclarationValue = require('../../utils/getDeclarationValue');
  6. const getUnitFromValueNode = require('../../utils/getUnitFromValueNode');
  7. const isCounterIncrementCustomIdentValue = require('../../utils/isCounterIncrementCustomIdentValue');
  8. const isCounterResetCustomIdentValue = require('../../utils/isCounterResetCustomIdentValue');
  9. const isStandardSyntaxValue = require('../../utils/isStandardSyntaxValue');
  10. const keywordSets = require('../../reference/keywordSets');
  11. const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp');
  12. const report = require('../../utils/report');
  13. const ruleMessages = require('../../utils/ruleMessages');
  14. const validateOptions = require('../../utils/validateOptions');
  15. const valueParser = require('postcss-value-parser');
  16. const ruleName = 'value-keyword-case';
  17. const messages = ruleMessages(ruleName, {
  18. expected: (actual, expected) => `Expected "${actual}" to be "${expected}"`,
  19. });
  20. // Operators are interpreted as "words" by the value parser, so we want to make sure to ignore them.
  21. const ignoredCharacters = new Set(['+', '-', '/', '*', '%']);
  22. const gridRowProps = new Set(['grid-row', 'grid-row-start', 'grid-row-end']);
  23. const gridColumnProps = new Set(['grid-column', 'grid-column-start', 'grid-column-end']);
  24. const mapLowercaseKeywordsToCamelCase = new Map();
  25. keywordSets.camelCaseKeywords.forEach((func) => {
  26. mapLowercaseKeywordsToCamelCase.set(func.toLowerCase(), func);
  27. });
  28. function rule(expectation, options, context) {
  29. return (root, result) => {
  30. const validOptions = validateOptions(
  31. result,
  32. ruleName,
  33. {
  34. actual: expectation,
  35. possible: ['lower', 'upper'],
  36. },
  37. {
  38. actual: options,
  39. possible: {
  40. ignoreProperties: [_.isString, _.isRegExp],
  41. ignoreKeywords: [_.isString, _.isRegExp],
  42. ignoreFunctions: [_.isString, _.isRegExp],
  43. },
  44. optional: true,
  45. },
  46. );
  47. if (!validOptions) {
  48. return;
  49. }
  50. root.walkDecls((decl) => {
  51. const prop = decl.prop;
  52. const propLowerCase = decl.prop.toLowerCase();
  53. const value = decl.value;
  54. const parsed = valueParser(getDeclarationValue(decl));
  55. let needFix = false;
  56. parsed.walk((node) => {
  57. const valueLowerCase = node.value.toLowerCase();
  58. // Ignore system colors
  59. if (keywordSets.systemColors.has(valueLowerCase)) {
  60. return;
  61. }
  62. // Ignore keywords within `url` and `var` function
  63. if (
  64. node.type === 'function' &&
  65. (valueLowerCase === 'url' ||
  66. valueLowerCase === 'var' ||
  67. valueLowerCase === 'counter' ||
  68. valueLowerCase === 'counters' ||
  69. valueLowerCase === 'attr')
  70. ) {
  71. return false;
  72. }
  73. // ignore keywords within ignoreFunctions functions
  74. const ignoreFunctions = (options && options.ignoreFunctions) || [];
  75. if (
  76. node.type === 'function' &&
  77. ignoreFunctions.length > 0 &&
  78. matchesStringOrRegExp(valueLowerCase, ignoreFunctions)
  79. ) {
  80. return false;
  81. }
  82. const keyword = node.value;
  83. // Ignore css variables, and hex values, and math operators, and sass interpolation
  84. if (
  85. node.type !== 'word' ||
  86. !isStandardSyntaxValue(node.value) ||
  87. value.includes('#') ||
  88. ignoredCharacters.has(keyword) ||
  89. getUnitFromValueNode(node)
  90. ) {
  91. return;
  92. }
  93. if (
  94. propLowerCase === 'animation' &&
  95. !keywordSets.animationShorthandKeywords.has(valueLowerCase) &&
  96. !keywordSets.animationNameKeywords.has(valueLowerCase)
  97. ) {
  98. return;
  99. }
  100. if (
  101. propLowerCase === 'animation-name' &&
  102. !keywordSets.animationNameKeywords.has(valueLowerCase)
  103. ) {
  104. return;
  105. }
  106. if (
  107. propLowerCase === 'font' &&
  108. !keywordSets.fontShorthandKeywords.has(valueLowerCase) &&
  109. !keywordSets.fontFamilyKeywords.has(valueLowerCase)
  110. ) {
  111. return;
  112. }
  113. if (
  114. propLowerCase === 'font-family' &&
  115. !keywordSets.fontFamilyKeywords.has(valueLowerCase)
  116. ) {
  117. return;
  118. }
  119. if (
  120. propLowerCase === 'counter-increment' &&
  121. isCounterIncrementCustomIdentValue(valueLowerCase)
  122. ) {
  123. return;
  124. }
  125. if (propLowerCase === 'counter-reset' && isCounterResetCustomIdentValue(valueLowerCase)) {
  126. return;
  127. }
  128. if (gridRowProps.has(propLowerCase) && !keywordSets.gridRowKeywords.has(valueLowerCase)) {
  129. return;
  130. }
  131. if (
  132. gridColumnProps.has(propLowerCase) &&
  133. !keywordSets.gridColumnKeywords.has(valueLowerCase)
  134. ) {
  135. return;
  136. }
  137. if (propLowerCase === 'grid-area' && !keywordSets.gridAreaKeywords.has(valueLowerCase)) {
  138. return;
  139. }
  140. if (
  141. propLowerCase === 'list-style' &&
  142. !keywordSets.listStyleShorthandKeywords.has(valueLowerCase) &&
  143. !keywordSets.listStyleTypeKeywords.has(valueLowerCase)
  144. ) {
  145. return;
  146. }
  147. if (
  148. propLowerCase === 'list-style-type' &&
  149. !keywordSets.listStyleTypeKeywords.has(valueLowerCase)
  150. ) {
  151. return;
  152. }
  153. const ignoreKeywords = (options && options.ignoreKeywords) || [];
  154. const ignoreProperties = (options && options.ignoreProperties) || [];
  155. if (ignoreKeywords.length > 0 && matchesStringOrRegExp(keyword, ignoreKeywords)) {
  156. return;
  157. }
  158. if (ignoreProperties.length > 0 && matchesStringOrRegExp(prop, ignoreProperties)) {
  159. return;
  160. }
  161. const keywordLowerCase = keyword.toLocaleLowerCase();
  162. let expectedKeyword = null;
  163. if (expectation === 'lower' && mapLowercaseKeywordsToCamelCase.has(keywordLowerCase)) {
  164. expectedKeyword = mapLowercaseKeywordsToCamelCase.get(keywordLowerCase);
  165. } else if (expectation === 'lower') {
  166. expectedKeyword = keyword.toLowerCase();
  167. } else {
  168. expectedKeyword = keyword.toUpperCase();
  169. }
  170. if (keyword === expectedKeyword) {
  171. return;
  172. }
  173. if (context.fix) {
  174. needFix = true;
  175. node.value = expectedKeyword;
  176. return;
  177. }
  178. report({
  179. message: messages.expected(keyword, expectedKeyword),
  180. node: decl,
  181. index: declarationValueIndex(decl) + node.sourceIndex,
  182. result,
  183. ruleName,
  184. });
  185. });
  186. if (context.fix && needFix) {
  187. decl.value = parsed.toString();
  188. }
  189. });
  190. };
  191. }
  192. rule.ruleName = ruleName;
  193. rule.messages = messages;
  194. module.exports = rule;