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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // @ts-nocheck
  2. 'use strict';
  3. const isCustomPropertySet = require('../../utils/isCustomPropertySet');
  4. const isStandardSyntaxAtRule = require('../../utils/isStandardSyntaxAtRule');
  5. const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule');
  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 = 'no-extra-semicolons';
  11. const messages = ruleMessages(ruleName, {
  12. rejected: 'Unexpected extra semicolon',
  13. });
  14. function getOffsetByNode(node) {
  15. if (node.parent && node.parent.document) {
  16. return 0;
  17. }
  18. const string = node.root().source.input.css;
  19. const nodeColumn = node.source.start.column;
  20. const nodeLine = node.source.start.line;
  21. let line = 1;
  22. let column = 1;
  23. let index = 0;
  24. for (let i = 0; i < string.length; i++) {
  25. if (column === nodeColumn && nodeLine === line) {
  26. index = i;
  27. break;
  28. }
  29. if (string[i] === '\n') {
  30. column = 1;
  31. line += 1;
  32. } else {
  33. column += 1;
  34. }
  35. }
  36. return index;
  37. }
  38. function rule(actual, options, context) {
  39. return (root, result) => {
  40. const validOptions = validateOptions(result, ruleName, { actual });
  41. if (!validOptions) {
  42. return;
  43. }
  44. const rawAfterRoot = root.raws.after;
  45. if (rawAfterRoot && rawAfterRoot.trim().length !== 0) {
  46. const fixSemiIndices = [];
  47. styleSearch({ source: rawAfterRoot, target: ';' }, (match) => {
  48. if (context.fix) {
  49. fixSemiIndices.push(match.startIndex);
  50. return;
  51. }
  52. complain(root.source.input.css.length - rawAfterRoot.length + match.startIndex);
  53. });
  54. // fix
  55. if (fixSemiIndices.length) {
  56. root.raws.after = removeIndices(rawAfterRoot, fixSemiIndices);
  57. }
  58. }
  59. root.walk((node) => {
  60. if (node.type === 'atrule' && !isStandardSyntaxAtRule(node)) {
  61. return;
  62. }
  63. if (node.type === 'rule' && !isCustomPropertySet(node) && !isStandardSyntaxRule(node)) {
  64. return;
  65. }
  66. let rawBeforeNode = node.raws.before;
  67. if (rawBeforeNode && rawBeforeNode.trim().length !== 0) {
  68. let allowedSemi = 0;
  69. const next = node.next();
  70. // Ignore semicolon before comment if next node is custom properties sets or comment
  71. if (
  72. node.type === 'comment' &&
  73. next &&
  74. isCustomPropertySet(next) &&
  75. node.parent.index(next) > 0
  76. ) {
  77. allowedSemi = 1;
  78. }
  79. const prev = node.prev();
  80. let rawBeforeIndexStart = 0;
  81. // Adding previous node string to custom properties set if previous node is comment
  82. if (
  83. isCustomPropertySet(node) &&
  84. node.parent.index(node) > 0 &&
  85. prev &&
  86. prev.type === 'comment'
  87. ) {
  88. rawBeforeNode = prev.toString() + rawBeforeNode;
  89. allowedSemi = 0;
  90. rawBeforeIndexStart = prev.toString().length;
  91. }
  92. const fixSemiIndices = [];
  93. styleSearch({ source: rawBeforeNode, target: ';' }, (match, count) => {
  94. if (count === allowedSemi) {
  95. return;
  96. }
  97. if (context.fix) {
  98. fixSemiIndices.push(match.startIndex - rawBeforeIndexStart);
  99. return;
  100. }
  101. complain(getOffsetByNode(node) - rawBeforeNode.length + match.startIndex);
  102. });
  103. // fix
  104. if (fixSemiIndices.length) {
  105. node.raws.before = removeIndices(node.raws.before, fixSemiIndices);
  106. }
  107. }
  108. const rawAfterNode = node.raws.after;
  109. if (rawAfterNode && rawAfterNode.trim().length !== 0) {
  110. /**
  111. * If the last child is a Less mixin followed by more than one semicolon,
  112. * node.raws.after will be populated with that semicolon.
  113. * Since we ignore Less mixins, exit here
  114. */
  115. if (
  116. node.last &&
  117. node.last.type === 'atrule' &&
  118. !isCustomPropertySet(node.last) &&
  119. !isStandardSyntaxAtRule(node.last)
  120. ) {
  121. return;
  122. }
  123. const fixSemiIndices = [];
  124. styleSearch({ source: rawAfterNode, target: ';' }, (match) => {
  125. if (context.fix) {
  126. fixSemiIndices.push(match.startIndex);
  127. return;
  128. }
  129. const index =
  130. getOffsetByNode(node) +
  131. node.toString().length -
  132. 1 -
  133. rawAfterNode.length +
  134. match.startIndex;
  135. complain(index);
  136. });
  137. // fix
  138. if (fixSemiIndices.length) {
  139. node.raws.after = removeIndices(rawAfterNode, fixSemiIndices);
  140. }
  141. }
  142. const rawOwnSemicolon = node.raws.ownSemicolon;
  143. if (rawOwnSemicolon) {
  144. let allowedSemi = 0;
  145. if (isCustomPropertySet(node)) {
  146. allowedSemi = 1;
  147. }
  148. const fixSemiIndices = [];
  149. styleSearch({ source: rawOwnSemicolon, target: ';' }, (match, count) => {
  150. if (count === allowedSemi) {
  151. return;
  152. }
  153. if (context.fix) {
  154. fixSemiIndices.push(match.startIndex);
  155. return;
  156. }
  157. const index =
  158. getOffsetByNode(node) +
  159. node.toString().length -
  160. rawOwnSemicolon.length +
  161. match.startIndex;
  162. complain(index);
  163. });
  164. // fix
  165. if (fixSemiIndices.length) {
  166. node.raws.ownSemicolon = removeIndices(rawOwnSemicolon, fixSemiIndices);
  167. }
  168. }
  169. });
  170. function complain(index) {
  171. report({
  172. message: messages.rejected,
  173. node: root,
  174. index,
  175. result,
  176. ruleName,
  177. });
  178. }
  179. function removeIndices(str, indices) {
  180. indices.reverse().forEach((index) => {
  181. str = str.slice(0, index) + str.slice(index + 1);
  182. });
  183. return str;
  184. }
  185. };
  186. }
  187. rule.ruleName = ruleName;
  188. rule.messages = messages;
  189. module.exports = rule;