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.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // @ts-nocheck
  2. 'use strict';
  3. const isOnlyWhitespace = require('../../utils/isOnlyWhitespace');
  4. const optionsMatches = require('../../utils/optionsMatches');
  5. const report = require('../../utils/report');
  6. const ruleMessages = require('../../utils/ruleMessages');
  7. const styleSearch = require('style-search');
  8. const validateOptions = require('../../utils/validateOptions');
  9. const ruleName = 'no-eol-whitespace';
  10. const messages = ruleMessages(ruleName, {
  11. rejected: 'Unexpected whitespace at end of line',
  12. });
  13. const whitespacesToReject = new Set([' ', '\t']);
  14. function fixString(str) {
  15. return str.replace(/[ \t]+$/, '');
  16. }
  17. function findErrorStartIndex(
  18. lastEOLIndex,
  19. string,
  20. { ignoreEmptyLines, isRootFirst } = {
  21. ignoreEmptyLines: false,
  22. isRootFirst: false,
  23. },
  24. ) {
  25. const eolWhitespaceIndex = lastEOLIndex - 1;
  26. // If the character before newline is not whitespace, ignore
  27. if (!whitespacesToReject.has(string[eolWhitespaceIndex])) {
  28. return -1;
  29. }
  30. if (ignoreEmptyLines) {
  31. // If there is only whitespace between the previous newline and
  32. // this newline, ignore
  33. const beforeNewlineIndex = string.lastIndexOf('\n', eolWhitespaceIndex);
  34. if (beforeNewlineIndex >= 0 || isRootFirst) {
  35. const line = string.substring(beforeNewlineIndex, eolWhitespaceIndex);
  36. if (isOnlyWhitespace(line)) {
  37. return -1;
  38. }
  39. }
  40. }
  41. return eolWhitespaceIndex;
  42. }
  43. function rule(on, options, context) {
  44. return (root, result) => {
  45. const validOptions = validateOptions(
  46. result,
  47. ruleName,
  48. {
  49. actual: on,
  50. },
  51. {
  52. optional: true,
  53. actual: options,
  54. possible: {
  55. ignore: ['empty-lines'],
  56. },
  57. },
  58. );
  59. if (!validOptions) {
  60. return;
  61. }
  62. const ignoreEmptyLines = optionsMatches(options, 'ignore', 'empty-lines');
  63. if (context.fix) {
  64. fix(root);
  65. }
  66. const rootString = context.fix ? root.toString() : root.source.input.css;
  67. const reportFromIndex = (index) => {
  68. report({
  69. message: messages.rejected,
  70. node: root,
  71. index,
  72. result,
  73. ruleName,
  74. });
  75. };
  76. eachEolWhitespace(rootString, reportFromIndex, true);
  77. const errorIndex = findErrorStartIndex(rootString.length, rootString, {
  78. ignoreEmptyLines,
  79. isRootFirst: true,
  80. });
  81. if (errorIndex > -1) {
  82. reportFromIndex(errorIndex);
  83. }
  84. /**
  85. * Iterate each whitespace at the end of each line of the given string.
  86. * @param {string} string the source code string
  87. * @param {Function} callback callback the whitespace index at the end of each line.
  88. * @param {boolean} isRootFirst set `true` if the given string is the first token of the root.
  89. * @returns {void}
  90. */
  91. function eachEolWhitespace(string, callback, isRootFirst) {
  92. styleSearch(
  93. {
  94. source: string,
  95. target: ['\n', '\r'],
  96. comments: 'check',
  97. },
  98. (match) => {
  99. const index = findErrorStartIndex(match.startIndex, string, {
  100. ignoreEmptyLines,
  101. isRootFirst,
  102. });
  103. if (index > -1) {
  104. callback(index);
  105. }
  106. },
  107. );
  108. }
  109. function fix(rootNode) {
  110. let isRootFirst = true;
  111. rootNode.walk((node) => {
  112. fixText(
  113. node.raws.before,
  114. (fixed) => {
  115. node.raws.before = fixed;
  116. },
  117. isRootFirst,
  118. );
  119. isRootFirst = false;
  120. // AtRule
  121. fixText(node.raws.afterName, (fixed) => {
  122. node.raws.afterName = fixed;
  123. });
  124. if (node.raws.params) {
  125. fixText(node.raws.params.raw, (fixed) => {
  126. node.raws.params.raw = fixed;
  127. });
  128. } else {
  129. fixText(node.params, (fixed) => {
  130. node.params = fixed;
  131. });
  132. }
  133. // Rule
  134. if (node.raws.selector) {
  135. fixText(node.raws.selector.raw, (fixed) => {
  136. node.raws.selector.raw = fixed;
  137. });
  138. } else {
  139. fixText(node.selector, (fixed) => {
  140. node.selector = fixed;
  141. });
  142. }
  143. // AtRule or Rule or Decl
  144. fixText(node.raws.between, (fixed) => {
  145. node.raws.between = fixed;
  146. });
  147. // Decl
  148. if (node.raws.value) {
  149. fixText(node.raws.value.raw, (fixed) => {
  150. node.raws.value.raw = fixed;
  151. });
  152. } else {
  153. fixText(node.value, (fixed) => {
  154. node.value = fixed;
  155. });
  156. }
  157. // Comment
  158. fixText(node.raws.left, (fixed) => {
  159. node.raws.left = fixed;
  160. });
  161. if (node.raws.inline) {
  162. node.raws.right = fixString(node.raws.right);
  163. } else {
  164. fixText(node.raws.right, (fixed) => {
  165. node.raws.right = fixed;
  166. });
  167. }
  168. fixText(node.text, (fixed) => {
  169. node.text = fixed;
  170. });
  171. fixText(node.raws.after, (fixed) => {
  172. node.raws.after = fixed;
  173. });
  174. });
  175. fixText(
  176. rootNode.raws.after,
  177. (fixed) => {
  178. rootNode.raws.after = fixed;
  179. },
  180. isRootFirst,
  181. );
  182. if (typeof rootNode.raws.after === 'string') {
  183. const lastEOL = Math.max(
  184. rootNode.raws.after.lastIndexOf('\n'),
  185. rootNode.raws.after.lastIndexOf('\r'),
  186. );
  187. if (lastEOL !== rootNode.raws.after.length - 1) {
  188. rootNode.raws.after =
  189. rootNode.raws.after.slice(0, lastEOL + 1) +
  190. fixString(rootNode.raws.after.slice(lastEOL + 1));
  191. }
  192. }
  193. }
  194. function fixText(value, fixFn, isRootFirst) {
  195. if (!value) {
  196. return;
  197. }
  198. let fixed = '';
  199. let lastIndex = 0;
  200. eachEolWhitespace(
  201. value,
  202. (index) => {
  203. const newlineIndex = index + 1;
  204. fixed += fixString(value.slice(lastIndex, newlineIndex));
  205. lastIndex = newlineIndex;
  206. },
  207. isRootFirst,
  208. );
  209. if (lastIndex) {
  210. fixed += value.slice(lastIndex);
  211. fixFn(fixed);
  212. }
  213. }
  214. };
  215. }
  216. rule.ruleName = ruleName;
  217. rule.messages = messages;
  218. module.exports = rule;