AK-21/Graphite-Industrial-Intelligence
0
1'use strict'2 3let pico = require('picocolors')4 5let terminalHighlight = require('./terminal-highlight')6 7class CssSyntaxError extends Error {8 constructor(message, line, column, source, file, plugin) {9 super(message)10 this.name = 'CssSyntaxError'11 this.reason = message12 13 if (file) {14 this.file = file15 }16 if (source) {17 this.source = source18 }19 if (plugin) {20 this.plugin = plugin21 }22 if (typeof line !== 'undefined' && typeof column !== 'undefined') {23 if (typeof line === 'number') {24 this.line = line25 this.column = column26 } else {27 this.line = line.line28 this.column = line.column29 this.endLine = column.line30 this.endColumn = column.column31 }32 }33 34 this.setMessage()35 36 if (Error.captureStackTrace) {37 Error.captureStackTrace(this, CssSyntaxError)38 }39 }40 41 setMessage() {42 this.message = this.plugin ? this.plugin + ': ' : ''43 this.message += this.file ? this.file : '<css input>'44 if (typeof this.line !== 'undefined') {45 this.message += ':' + this.line + ':' + this.column46 }47 this.message += ': ' + this.reason48 }49 50 showSourceCode(color) {51 if (!this.source) return ''52 53 let css = this.source54 if (color == null) color = pico.isColorSupported55 56 let aside = text => text57 let mark = text => text58 let highlight = text => text59 if (color) {60 let { bold, gray, red } = pico.createColors(true)61 mark = text => bold(red(text))62 aside = text => gray(text)63 if (terminalHighlight) {64 highlight = text => terminalHighlight(text)65 }66 }67 68 let lines = css.split(/\r?\n/)69 let start = Math.max(this.line - 3, 0)70 let end = Math.min(this.line + 2, lines.length)71 let maxWidth = String(end).length72 73 return lines74 .slice(start, end)75 .map((line, index) => {76 let number = start + 1 + index77 let gutter = ' ' + (' ' + number).slice(-maxWidth) + ' | '78 if (number === this.line) {79 if (line.length > 160) {80 let padding = 2081 let subLineStart = Math.max(0, this.column - padding)82 let subLineEnd = Math.max(83 this.column + padding,84 this.endColumn + padding85 )86 let subLine = line.slice(subLineStart, subLineEnd)87 88 let spacing =89 aside(gutter.replace(/\d/g, ' ')) +90 line91 .slice(0, Math.min(this.column - 1, padding - 1))92 .replace(/[^\t]/g, ' ')93 94 return (95 mark('>') +96 aside(gutter) +97 highlight(subLine) +98 '\n ' +99 spacing +100 mark('^')101 )102 }103 104 let spacing =105 aside(gutter.replace(/\d/g, ' ')) +106 line.slice(0, this.column - 1).replace(/[^\t]/g, ' ')107 108 return (109 mark('>') +110 aside(gutter) +111 highlight(line) +112 '\n ' +113 spacing +114 mark('^')115 )116 }117 118 return ' ' + aside(gutter) + highlight(line)119 })120 .join('\n')121 }122 123 toString() {124 let code = this.showSourceCode()125 if (code) {126 code = '\n\n' + code + '\n'127 }128 return this.name + ': ' + this.message + code129 }130}131 132module.exports = CssSyntaxError133CssSyntaxError.default = CssSyntaxError134 