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 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // @ts-nocheck
  2. 'use strict';
  3. const _ = require('lodash');
  4. const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule');
  5. const parseSelector = require('../../utils/parseSelector');
  6. const report = require('../../utils/report');
  7. const ruleMessages = require('../../utils/ruleMessages');
  8. const styleSearch = require('style-search');
  9. const validateOptions = require('../../utils/validateOptions');
  10. const ruleName = 'selector-attribute-brackets-space-inside';
  11. const messages = ruleMessages(ruleName, {
  12. expectedOpening: 'Expected single space after "["',
  13. rejectedOpening: 'Unexpected whitespace after "["',
  14. expectedClosing: 'Expected single space before "]"',
  15. rejectedClosing: 'Unexpected whitespace before "]"',
  16. });
  17. function rule(expectation, options, context) {
  18. return (root, result) => {
  19. const validOptions = validateOptions(result, ruleName, {
  20. actual: expectation,
  21. possible: ['always', 'never'],
  22. });
  23. if (!validOptions) {
  24. return;
  25. }
  26. root.walkRules((ruleNode) => {
  27. if (!isStandardSyntaxRule(ruleNode)) {
  28. return;
  29. }
  30. if (!ruleNode.selector.includes('[')) {
  31. return;
  32. }
  33. const selector = ruleNode.raws.selector ? ruleNode.raws.selector.raw : ruleNode.selector;
  34. let hasFixed;
  35. const fixedSelector = parseSelector(selector, result, ruleNode, (selectorTree) => {
  36. selectorTree.walkAttributes((attributeNode) => {
  37. const attributeSelectorString = attributeNode.toString();
  38. styleSearch({ source: attributeSelectorString, target: '[' }, (match) => {
  39. const nextCharIsSpace = attributeSelectorString[match.startIndex + 1] === ' ';
  40. const index = attributeNode.sourceIndex + match.startIndex + 1;
  41. if (nextCharIsSpace && expectation === 'never') {
  42. if (context.fix) {
  43. hasFixed = true;
  44. fixBefore(attributeNode);
  45. return;
  46. }
  47. complain(messages.rejectedOpening, index);
  48. }
  49. if (!nextCharIsSpace && expectation === 'always') {
  50. if (context.fix) {
  51. hasFixed = true;
  52. fixBefore(attributeNode);
  53. return;
  54. }
  55. complain(messages.expectedOpening, index);
  56. }
  57. });
  58. styleSearch({ source: attributeSelectorString, target: ']' }, (match) => {
  59. const prevCharIsSpace = attributeSelectorString[match.startIndex - 1] === ' ';
  60. const index = attributeNode.sourceIndex + match.startIndex - 1;
  61. if (prevCharIsSpace && expectation === 'never') {
  62. if (context.fix) {
  63. hasFixed = true;
  64. fixAfter(attributeNode);
  65. return;
  66. }
  67. complain(messages.rejectedClosing, index);
  68. }
  69. if (!prevCharIsSpace && expectation === 'always') {
  70. if (context.fix) {
  71. hasFixed = true;
  72. fixAfter(attributeNode);
  73. return;
  74. }
  75. complain(messages.expectedClosing, index);
  76. }
  77. });
  78. });
  79. });
  80. if (hasFixed) {
  81. if (!ruleNode.raws.selector) {
  82. ruleNode.selector = fixedSelector;
  83. } else {
  84. ruleNode.raws.selector.raw = fixedSelector;
  85. }
  86. }
  87. function complain(message, index) {
  88. report({
  89. message,
  90. index,
  91. result,
  92. ruleName,
  93. node: ruleNode,
  94. });
  95. }
  96. });
  97. };
  98. function fixBefore(attributeNode) {
  99. const rawAttrBefore = _.get(attributeNode, 'raws.spaces.attribute.before');
  100. const { attrBefore, setAttrBefore } = rawAttrBefore
  101. ? {
  102. attrBefore: rawAttrBefore,
  103. setAttrBefore(fixed) {
  104. attributeNode.raws.spaces.attribute.before = fixed;
  105. },
  106. }
  107. : {
  108. attrBefore: _.get(attributeNode, 'spaces.attribute.before', ''),
  109. setAttrBefore(fixed) {
  110. _.set(attributeNode, 'spaces.attribute.before', fixed);
  111. },
  112. };
  113. if (expectation === 'always') {
  114. setAttrBefore(attrBefore.replace(/^\s*/, ' '));
  115. } else if (expectation === 'never') {
  116. setAttrBefore(attrBefore.replace(/^\s*/, ''));
  117. }
  118. }
  119. function fixAfter(attributeNode) {
  120. let key;
  121. if (attributeNode.operator) {
  122. key = attributeNode.insensitive ? 'insensitive' : 'value';
  123. } else {
  124. key = 'attribute';
  125. }
  126. const rawAfter = _.get(attributeNode, `raws.spaces.${key}.after`);
  127. const { after, setAfter } = rawAfter
  128. ? {
  129. after: rawAfter,
  130. setAfter(fixed) {
  131. attributeNode.raws.spaces[key].after = fixed;
  132. },
  133. }
  134. : {
  135. after: _.get(attributeNode, `spaces.${key}.after`, ''),
  136. setAfter(fixed) {
  137. _.set(attributeNode, `spaces.${key}.after`, fixed);
  138. },
  139. };
  140. if (expectation === 'always') {
  141. setAfter(after.replace(/\s*$/, ' '));
  142. } else if (expectation === 'never') {
  143. setAfter(after.replace(/\s*$/, ''));
  144. }
  145. }
  146. }
  147. rule.ruleName = ruleName;
  148. rule.messages = messages;
  149. module.exports = rule;