123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- "use strict";
- const Input = require("postcss/lib/input");
- const Document = require("./document");
- const reNewLine = /\r?\n|\r/g;
- class Locations {
- constructor(source) {
- let match;
- const lines = [];
- reNewLine.lastIndex = 0;
- while ((match = reNewLine.exec(source))) {
- lines.push(match.index);
- }
- lines.push(source.length);
- this.lines = lines;
- this.source = source;
- }
- getOffsetFromLoc(loc) {
- const lineIndex = loc.line - 2;
- return (lineIndex >= 0 ? this.lines[lineIndex] : -1) + loc.column;
- }
- getLocFromOffset(offset) {
- const lines = this.lines;
- for (let index = 0; index < lines.length; index++) {
- const lineEndIndex = lines[index];
- if (lineEndIndex >= offset) {
- const before = this.lines[index - 1];
- return {
- line: index + 1,
- column: offset - (before != null ? before : -1),
- };
- }
- }
- const before = this.lines[this.lines.length - 2];
- return {
- line: lines.length,
- column: offset - (before != null ? before : -1),
- };
- }
- }
- class LocalFixer {
- constructor(locations, style) {
- const { line, column } = locations.getLocFromOffset(style.startIndex);
- this.line = line - 1;
- this.column = column - 1;
- this.style = style;
- }
- fixLocation(object) {
- if (object) {
- if (object.line === 1) {
- object.column += this.column;
- }
- object.line += this.line;
- if (typeof object.offset === "number") {
- object.offset += this.style.startIndex;
- }
- if (typeof object.endLine === "number") {
- if (object.endLine === 1) {
- object.endColumn += this.column;
- }
- object.endLine += this.line;
- }
- }
- }
- node(node) {
- this.fixLocation(node.source.start);
- this.fixLocation(node.source.end);
- }
- root(root) {
- this.node(root);
- root.walk((node) => {
- this.node(node);
- });
- }
- error(error) {
- if (error && error.name === "CssSyntaxError") {
- this.fixLocation(error);
- this.fixLocation(error.input);
- error.message = error.message.replace(
- /:\d+:\d+:/,
- `:${error.line}:${error.column}:`
- );
- }
- return error;
- }
- parse(opts) {
- const style = this.style;
- const syntax = style.syntax;
- let root;
- try {
- root = syntax.parse(
- style.content,
- Object.assign(
- {},
- opts,
- {
- map: false,
- },
- style.opts
- )
- );
- } catch (error) {
- this.error(error);
- throw error;
- }
- this.root(root);
- root.source.inline = Boolean(style.inline);
- root.source.lang = style.lang;
- root.source.syntax = syntax;
- patchRoot(root, syntax);
- return root;
- }
- }
- function docFixer(source, opts) {
- const locations = new Locations(source);
- return function parseStyle(style) {
- return new LocalFixer(locations, style).parse(opts);
- };
- }
- function parseStyles(source, opts, styles) {
- const document = new Document();
- let index = 0;
- if (styles.length) {
- const parseStyle = docFixer(source, opts);
- styles
- .sort((a, b) => a.startIndex - b.startIndex)
- .forEach((style) => {
- const root = parseStyle(style);
- if (root) {
- root.raws.codeBefore = source.slice(index, style.startIndex);
- // Note: Stylelint is still using this property.
- try {
- Object.defineProperty(root.raws, "beforeStart", {
- configurable: true,
- get() {
- return root.raws.codeBefore;
- },
- set(value) {
- root.raws.codeBefore = value;
- },
- });
- } catch {
- // ignore
- }
- index =
- style.startIndex + (style.content || root.source.input.css).length;
- root.document = document;
- document.nodes.push(root);
- }
- });
- }
- const last = document.nodes[document.nodes.length - 1];
- if (last) {
- last.raws.codeAfter = index ? source.slice(index) : source;
- }
- document.source = {
- input: new Input(source, opts),
- start: {
- line: 1,
- column: 1,
- },
- opts,
- };
- return document;
- }
- module.exports = parseStyles;
- function patchRoot(root, syntax) {
- const originalToString = root.toString;
- try {
- Object.defineProperty(root, "toString", {
- configurable: true,
- enumerable: false,
- value(stringifier) {
- return originalToString.call(this, stringifier || syntax);
- },
- });
- } catch {
- // ignore
- }
- }
|