| 'use strict'; |
| |
| var createCustomError = require('../utils/createCustomError'); |
| var MAX_LINE_LENGTH = 100; |
| var OFFSET_CORRECTION = 60; |
| var TAB_REPLACEMENT = ' '; |
| |
| function sourceFragment(error, extraLines) { |
| function processLines(start, end) { |
| return lines.slice(start, end).map(function(line, idx) { |
| var num = String(start + idx + 1); |
| |
| while (num.length < maxNumLength) { |
| num = ' ' + num; |
| } |
| |
| return num + ' |' + line; |
| }).join('\n'); |
| } |
| |
| var lines = error.source.split(/\r\n?|\n|\f/); |
| var line = error.line; |
| var column = error.column; |
| var startLine = Math.max(1, line - extraLines) - 1; |
| var endLine = Math.min(line + extraLines, lines.length + 1); |
| var maxNumLength = Math.max(4, String(endLine).length) + 1; |
| var cutLeft = 0; |
| |
| // column correction according to replaced tab before column |
| column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length; |
| |
| if (column > MAX_LINE_LENGTH) { |
| cutLeft = column - OFFSET_CORRECTION + 3; |
| column = OFFSET_CORRECTION - 2; |
| } |
| |
| for (var i = startLine; i <= endLine; i++) { |
| if (i >= 0 && i < lines.length) { |
| lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT); |
| lines[i] = |
| (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') + |
| lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) + |
| (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : ''); |
| } |
| } |
| |
| return [ |
| processLines(startLine, line), |
| new Array(column + maxNumLength + 2).join('-') + '^', |
| processLines(line, endLine) |
| ].filter(Boolean).join('\n'); |
| } |
| |
| var CssSyntaxError = function(message, source, offset, line, column) { |
| var error = createCustomError('CssSyntaxError', message); |
| |
| error.source = source; |
| error.offset = offset; |
| error.line = line; |
| error.column = column; |
| |
| error.sourceFragment = function(extraLines) { |
| return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines); |
| }; |
| Object.defineProperty(error, 'formattedMessage', { |
| get: function() { |
| return ( |
| 'Parse error: ' + error.message + '\n' + |
| sourceFragment(error, 2) |
| ); |
| } |
| }); |
| |
| // for backward capability |
| error.parseError = { |
| offset: offset, |
| line: line, |
| column: column |
| }; |
| |
| return error; |
| }; |
| |
| module.exports = CssSyntaxError; |