safe-parser.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. let tokenizer = require('postcss/lib/tokenize')
  2. let Comment = require('postcss/lib/comment')
  3. let Parser = require('postcss/lib/parser')
  4. class SafeParser extends Parser {
  5. createTokenizer() {
  6. this.tokenizer = tokenizer(this.input, { ignoreErrors: true })
  7. }
  8. comment(token) {
  9. let node = new Comment()
  10. this.init(node, token[2])
  11. let pos =
  12. this.input.fromOffset(token[3]) ||
  13. this.input.fromOffset(this.input.css.length - 1)
  14. node.source.end = {
  15. offset: token[3],
  16. line: pos.line,
  17. column: pos.col
  18. }
  19. let text = token[1].slice(2)
  20. if (text.slice(-2) === '*/') text = text.slice(0, -2)
  21. if (/^\s*$/.test(text)) {
  22. node.text = ''
  23. node.raws.left = text
  24. node.raws.right = ''
  25. } else {
  26. let match = text.match(/^(\s*)([^]*\S)(\s*)$/)
  27. node.text = match[2]
  28. node.raws.left = match[1]
  29. node.raws.right = match[3]
  30. }
  31. }
  32. decl(tokens) {
  33. if (tokens.length > 1 && tokens.some(i => i[0] === 'word')) {
  34. super.decl(tokens)
  35. }
  36. }
  37. unclosedBracket() {}
  38. unknownWord(tokens) {
  39. this.spaces += tokens.map(i => i[1]).join('')
  40. }
  41. unexpectedClose() {
  42. this.current.raws.after += '}'
  43. }
  44. doubleColon() {}
  45. unnamedAtrule(node) {
  46. node.name = ''
  47. }
  48. precheckMissedSemicolon(tokens) {
  49. let colon = this.colon(tokens)
  50. if (colon === false) return
  51. let nextStart, prevEnd
  52. for (nextStart = colon - 1; nextStart >= 0; nextStart--) {
  53. if (tokens[nextStart][0] === 'word') break
  54. }
  55. if (nextStart === 0) return
  56. for (prevEnd = nextStart - 1; prevEnd >= 0; prevEnd--) {
  57. if (tokens[prevEnd][0] !== 'space') {
  58. prevEnd += 1
  59. break
  60. }
  61. }
  62. let other = tokens.slice(nextStart)
  63. let spaces = tokens.slice(prevEnd, nextStart)
  64. tokens.splice(prevEnd, tokens.length - prevEnd)
  65. this.spaces = spaces.map(i => i[1]).join('')
  66. this.decl(other)
  67. }
  68. checkMissedSemicolon() {}
  69. endFile() {
  70. if (this.current.nodes && this.current.nodes.length) {
  71. this.current.raws.semicolon = this.semicolon
  72. }
  73. this.current.raws.after = (this.current.raws.after || '') + this.spaces
  74. while (this.current.parent) {
  75. this.current = this.current.parent
  76. this.current.raws.after = ''
  77. }
  78. }
  79. }
  80. module.exports = SafeParser