UNPKG

@angular/cdk

Version:

Angular Material Component Development Kit

75 lines 3.01 kB
"use strict"; /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.dev/license */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getLineAndCharacterFromPosition = getLineAndCharacterFromPosition; exports.computeLineStartsMap = computeLineStartsMap; /* * Line mapping utilities which can be used to retrieve line and character based * on an absolute character position in a given file. This functionality is similar * to TypeScript's "ts.getLineAndCharacterFromPosition" utility, but we cannot leverage * their logic for line mappings as it's internal and we need to generate line mappings * for non-TypeScript files such as HTML templates or stylesheets. * * Line and character can be retrieved by splitting a given source text based on * line breaks into line start entries. Later when a specific position is requested, * the closest line-start position is determined based on the given position. */ const LF_CHAR = 10; const CR_CHAR = 13; const LINE_SEP_CHAR = 8232; const PARAGRAPH_CHAR = 8233; /** Gets the line and character for the given position from the line starts map. */ function getLineAndCharacterFromPosition(lineStartsMap, position) { const lineIndex = findClosestLineStartPosition(lineStartsMap, position); return { character: position - lineStartsMap[lineIndex], line: lineIndex }; } /** * Computes the line start map of the given text. This can be used in order to * retrieve the line and character of a given text position index. */ function computeLineStartsMap(text) { const result = [0]; let pos = 0; while (pos < text.length) { const char = text.charCodeAt(pos++); // Handles the "CRLF" line break. In that case we peek the character // after the "CR" and check if it is a line feed. if (char === CR_CHAR) { if (text.charCodeAt(pos) === LF_CHAR) { pos++; } result.push(pos); } else if (char === LF_CHAR || char === LINE_SEP_CHAR || char === PARAGRAPH_CHAR) { result.push(pos); } } result.push(pos); return result; } /** Finds the closest line start for the given position. */ function findClosestLineStartPosition(linesMap, position, low = 0, high = linesMap.length - 1) { while (low <= high) { const pivotIndex = Math.floor((low + high) / 2); const pivotEl = linesMap[pivotIndex]; if (pivotEl === position) { return pivotIndex; } else if (position > pivotEl) { low = pivotIndex + 1; } else { high = pivotIndex - 1; } } // In case there was no exact match, return the closest "lower" line index. We also // subtract the index by one because want the index of the previous line start. return low - 1; } //# sourceMappingURL=line-mappings.js.map