error.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. 'use strict';
  2. var createCustomError = require('../utils/createCustomError');
  3. var MAX_LINE_LENGTH = 100;
  4. var OFFSET_CORRECTION = 60;
  5. var TAB_REPLACEMENT = ' ';
  6. function sourceFragment(error, extraLines) {
  7. function processLines(start, end) {
  8. return lines.slice(start, end).map(function(line, idx) {
  9. var num = String(start + idx + 1);
  10. while (num.length < maxNumLength) {
  11. num = ' ' + num;
  12. }
  13. return num + ' |' + line;
  14. }).join('\n');
  15. }
  16. var lines = error.source.split(/\r\n?|\n|\f/);
  17. var line = error.line;
  18. var column = error.column;
  19. var startLine = Math.max(1, line - extraLines) - 1;
  20. var endLine = Math.min(line + extraLines, lines.length + 1);
  21. var maxNumLength = Math.max(4, String(endLine).length) + 1;
  22. var cutLeft = 0;
  23. // column correction according to replaced tab before column
  24. column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
  25. if (column > MAX_LINE_LENGTH) {
  26. cutLeft = column - OFFSET_CORRECTION + 3;
  27. column = OFFSET_CORRECTION - 2;
  28. }
  29. for (var i = startLine; i <= endLine; i++) {
  30. if (i >= 0 && i < lines.length) {
  31. lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
  32. lines[i] =
  33. (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
  34. lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
  35. (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
  36. }
  37. }
  38. return [
  39. processLines(startLine, line),
  40. new Array(column + maxNumLength + 2).join('-') + '^',
  41. processLines(line, endLine)
  42. ].filter(Boolean).join('\n');
  43. }
  44. var CssSyntaxError = function(message, source, offset, line, column) {
  45. var error = createCustomError('CssSyntaxError', message);
  46. error.source = source;
  47. error.offset = offset;
  48. error.line = line;
  49. error.column = column;
  50. error.sourceFragment = function(extraLines) {
  51. return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
  52. };
  53. Object.defineProperty(error, 'formattedMessage', {
  54. get: function() {
  55. return (
  56. 'Parse error: ' + error.message + '\n' +
  57. sourceFragment(error, 2)
  58. );
  59. }
  60. });
  61. // for backward capability
  62. error.parseError = {
  63. offset: offset,
  64. line: line,
  65. column: column
  66. };
  67. return error;
  68. };
  69. module.exports = CssSyntaxError;