astro-ghostcms/.pnpm-store/v3/files/66/7215077952310ae52a50fff67d1...

204 lines
8.4 KiB
Plaintext
Raw Normal View History

2024-02-14 14:10:47 +00:00
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "../parser/cssScanner", "../parser/scssScanner", "../parser/lessScanner"], factory);
}
})(function (require, exports) {
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFoldingRanges = void 0;
const cssScanner_1 = require("../parser/cssScanner");
const scssScanner_1 = require("../parser/scssScanner");
const lessScanner_1 = require("../parser/lessScanner");
function getFoldingRanges(document, context) {
const ranges = computeFoldingRanges(document);
return limitFoldingRanges(ranges, context);
}
exports.getFoldingRanges = getFoldingRanges;
function computeFoldingRanges(document) {
function getStartLine(t) {
return document.positionAt(t.offset).line;
}
function getEndLine(t) {
return document.positionAt(t.offset + t.len).line;
}
function getScanner() {
switch (document.languageId) {
case 'scss':
return new scssScanner_1.SCSSScanner();
case 'less':
return new lessScanner_1.LESSScanner();
default:
return new cssScanner_1.Scanner();
}
}
function tokenToRange(t, kind) {
const startLine = getStartLine(t);
const endLine = getEndLine(t);
if (startLine !== endLine) {
return {
startLine,
endLine,
kind
};
}
else {
return null;
}
}
const ranges = [];
const delimiterStack = [];
const scanner = getScanner();
scanner.ignoreComment = false;
scanner.setSource(document.getText());
let token = scanner.scan();
let prevToken = null;
while (token.type !== cssScanner_1.TokenType.EOF) {
switch (token.type) {
case cssScanner_1.TokenType.CurlyL:
case scssScanner_1.InterpolationFunction:
{
delimiterStack.push({ line: getStartLine(token), type: 'brace', isStart: true });
break;
}
case cssScanner_1.TokenType.CurlyR: {
if (delimiterStack.length !== 0) {
const prevDelimiter = popPrevStartDelimiterOfType(delimiterStack, 'brace');
if (!prevDelimiter) {
break;
}
let endLine = getEndLine(token);
if (prevDelimiter.type === 'brace') {
/**
* Other than the case when curly brace is not on a new line by itself, for example
* .foo {
* color: red; }
* Use endLine minus one to show ending curly brace
*/
if (prevToken && getEndLine(prevToken) !== endLine) {
endLine--;
}
if (prevDelimiter.line !== endLine) {
ranges.push({
startLine: prevDelimiter.line,
endLine,
kind: undefined
});
}
}
}
break;
}
/**
* In CSS, there is no single line comment prefixed with //
* All comments are marked as `Comment`
*/
case cssScanner_1.TokenType.Comment: {
const commentRegionMarkerToDelimiter = (marker) => {
if (marker === '#region') {
return { line: getStartLine(token), type: 'comment', isStart: true };
}
else {
return { line: getEndLine(token), type: 'comment', isStart: false };
}
};
const getCurrDelimiter = (token) => {
const matches = token.text.match(/^\s*\/\*\s*(#region|#endregion)\b\s*(.*?)\s*\*\//);
if (matches) {
return commentRegionMarkerToDelimiter(matches[1]);
}
else if (document.languageId === 'scss' || document.languageId === 'less') {
const matches = token.text.match(/^\s*\/\/\s*(#region|#endregion)\b\s*(.*?)\s*/);
if (matches) {
return commentRegionMarkerToDelimiter(matches[1]);
}
}
return null;
};
const currDelimiter = getCurrDelimiter(token);
// /* */ comment region folding
// All #region and #endregion cases
if (currDelimiter) {
if (currDelimiter.isStart) {
delimiterStack.push(currDelimiter);
}
else {
const prevDelimiter = popPrevStartDelimiterOfType(delimiterStack, 'comment');
if (!prevDelimiter) {
break;
}
if (prevDelimiter.type === 'comment') {
if (prevDelimiter.line !== currDelimiter.line) {
ranges.push({
startLine: prevDelimiter.line,
endLine: currDelimiter.line,
kind: 'region'
});
}
}
}
}
// Multiline comment case
else {
const range = tokenToRange(token, 'comment');
if (range) {
ranges.push(range);
}
}
break;
}
}
prevToken = token;
token = scanner.scan();
}
return ranges;
}
function popPrevStartDelimiterOfType(stack, type) {
if (stack.length === 0) {
return null;
}
for (let i = stack.length - 1; i >= 0; i--) {
if (stack[i].type === type && stack[i].isStart) {
return stack.splice(i, 1)[0];
}
}
return null;
}
/**
* - Sort regions
* - Remove invalid regions (intersections)
* - If limit exceeds, only return `rangeLimit` amount of ranges
*/
function limitFoldingRanges(ranges, context) {
const maxRanges = context && context.rangeLimit || Number.MAX_VALUE;
const sortedRanges = ranges.sort((r1, r2) => {
let diff = r1.startLine - r2.startLine;
if (diff === 0) {
diff = r1.endLine - r2.endLine;
}
return diff;
});
const validRanges = [];
let prevEndLine = -1;
sortedRanges.forEach(r => {
if (!(r.startLine < prevEndLine && prevEndLine < r.endLine)) {
validRanges.push(r);
prevEndLine = r.endLine;
}
});
if (validRanges.length < maxRanges) {
return validRanges;
}
else {
return validRanges.slice(0, maxRanges);
}
}
});