@21epub/epub-thirdparty
Version:
epub-thirdparty
156 lines (155 loc) • 6.91 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { LinkedList } from '../../../base/common/linkedList.js';
import { Position } from '../../common/core/position.js';
import { Range } from '../../common/core/range.js';
export class BracketSelectionRangeProvider {
provideSelectionRanges(model, positions) {
return __awaiter(this, void 0, void 0, function* () {
const result = [];
for (const position of positions) {
const bucket = [];
result.push(bucket);
const ranges = new Map();
yield new Promise(resolve => BracketSelectionRangeProvider._bracketsRightYield(resolve, 0, model, position, ranges));
yield new Promise(resolve => BracketSelectionRangeProvider._bracketsLeftYield(resolve, 0, model, position, ranges, bucket));
}
return result;
});
}
static _bracketsRightYield(resolve, round, model, pos, ranges) {
const counts = new Map();
const t1 = Date.now();
while (true) {
if (round >= BracketSelectionRangeProvider._maxRounds) {
resolve();
break;
}
if (!pos) {
resolve();
break;
}
let bracket = model.findNextBracket(pos);
if (!bracket) {
resolve();
break;
}
let d = Date.now() - t1;
if (d > BracketSelectionRangeProvider._maxDuration) {
setTimeout(() => BracketSelectionRangeProvider._bracketsRightYield(resolve, round + 1, model, pos, ranges));
break;
}
const key = bracket.close[0];
if (bracket.isOpen) {
// wait for closing
let val = counts.has(key) ? counts.get(key) : 0;
counts.set(key, val + 1);
}
else {
// process closing
let val = counts.has(key) ? counts.get(key) : 0;
val -= 1;
counts.set(key, Math.max(0, val));
if (val < 0) {
let list = ranges.get(key);
if (!list) {
list = new LinkedList();
ranges.set(key, list);
}
list.push(bracket.range);
}
}
pos = bracket.range.getEndPosition();
}
}
static _bracketsLeftYield(resolve, round, model, pos, ranges, bucket) {
const counts = new Map();
const t1 = Date.now();
while (true) {
if (round >= BracketSelectionRangeProvider._maxRounds && ranges.size === 0) {
resolve();
break;
}
if (!pos) {
resolve();
break;
}
let bracket = model.findPrevBracket(pos);
if (!bracket) {
resolve();
break;
}
let d = Date.now() - t1;
if (d > BracketSelectionRangeProvider._maxDuration) {
setTimeout(() => BracketSelectionRangeProvider._bracketsLeftYield(resolve, round + 1, model, pos, ranges, bucket));
break;
}
const key = bracket.close[0];
if (!bracket.isOpen) {
// wait for opening
let val = counts.has(key) ? counts.get(key) : 0;
counts.set(key, val + 1);
}
else {
// opening
let val = counts.has(key) ? counts.get(key) : 0;
val -= 1;
counts.set(key, Math.max(0, val));
if (val < 0) {
let list = ranges.get(key);
if (list) {
let closing = list.shift();
if (list.size === 0) {
ranges.delete(key);
}
const innerBracket = Range.fromPositions(bracket.range.getEndPosition(), closing.getStartPosition());
const outerBracket = Range.fromPositions(bracket.range.getStartPosition(), closing.getEndPosition());
bucket.push({ range: innerBracket });
bucket.push({ range: outerBracket });
BracketSelectionRangeProvider._addBracketLeading(model, outerBracket, bucket);
}
}
}
pos = bracket.range.getStartPosition();
}
}
static _addBracketLeading(model, bracket, bucket) {
if (bracket.startLineNumber === bracket.endLineNumber) {
return;
}
// xxxxxxxx {
//
// }
const startLine = bracket.startLineNumber;
const column = model.getLineFirstNonWhitespaceColumn(startLine);
if (column !== 0 && column !== bracket.startColumn) {
bucket.push({ range: Range.fromPositions(new Position(startLine, column), bracket.getEndPosition()) });
bucket.push({ range: Range.fromPositions(new Position(startLine, 1), bracket.getEndPosition()) });
}
// xxxxxxxx
// {
//
// }
const aboveLine = startLine - 1;
if (aboveLine > 0) {
const column = model.getLineFirstNonWhitespaceColumn(aboveLine);
if (column === bracket.startColumn && column !== model.getLineLastNonWhitespaceColumn(aboveLine)) {
bucket.push({ range: Range.fromPositions(new Position(aboveLine, column), bracket.getEndPosition()) });
bucket.push({ range: Range.fromPositions(new Position(aboveLine, 1), bracket.getEndPosition()) });
}
}
}
}
BracketSelectionRangeProvider._maxDuration = 30;
BracketSelectionRangeProvider._maxRounds = 2;