mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-15 18:46:36 -05:00
* Fix initial build breaks from 1.67 merge (#2514) * Update yarn lock files * Update build scripts * Fix tsconfig * Build breaks * WIP * Update yarn lock files * Misc breaks * Updates to package.json * Breaks * Update yarn * Fix breaks * Breaks * Build breaks * Breaks * Breaks * Breaks * Breaks * Breaks * Missing file * Breaks * Breaks * Breaks * Breaks * Breaks * Fix several runtime breaks (#2515) * Missing files * Runtime breaks * Fix proxy ordering issue * Remove commented code * Fix breaks with opening query editor * Fix post merge break * Updates related to setup build and other breaks (#2516) * Fix bundle build issues * Update distro * Fix distro merge and update build JS files * Disable pipeline steps * Remove stats call * Update license name * Make new RPM dependencies a warning * Fix extension manager version checks * Update JS file * Fix a few runtime breaks * Fixes * Fix runtime issues * Fix build breaks * Update notebook tests (part 1) * Fix broken tests * Linting errors * Fix hygiene * Disable lint rules * Bump distro * Turn off smoke tests * Disable integration tests * Remove failing "activate" test * Remove failed test assertion * Disable other broken test * Disable query history tests * Disable extension unit tests * Disable failing tasks
142 lines
5.3 KiB
TypeScript
142 lines
5.3 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { Constants } from 'vs/base/common/uint';
|
|
import { FloatHorizontalRange } from 'vs/editor/browser/view/renderingContext';
|
|
|
|
export class RangeUtil {
|
|
|
|
/**
|
|
* Reusing the same range here
|
|
* because IE is buggy and constantly freezes when using a large number
|
|
* of ranges and calling .detach on them
|
|
*/
|
|
private static _handyReadyRange: Range;
|
|
|
|
private static _createRange(): Range {
|
|
if (!this._handyReadyRange) {
|
|
this._handyReadyRange = document.createRange();
|
|
}
|
|
return this._handyReadyRange;
|
|
}
|
|
|
|
private static _detachRange(range: Range, endNode: HTMLElement): void {
|
|
// Move range out of the span node, IE doesn't like having many ranges in
|
|
// the same spot and will act badly for lines containing dashes ('-')
|
|
range.selectNodeContents(endNode);
|
|
}
|
|
|
|
private static _readClientRects(startElement: Node, startOffset: number, endElement: Node, endOffset: number, endNode: HTMLElement): DOMRectList | null {
|
|
const range = this._createRange();
|
|
try {
|
|
range.setStart(startElement, startOffset);
|
|
range.setEnd(endElement, endOffset);
|
|
|
|
return range.getClientRects();
|
|
} catch (e) {
|
|
// This is life ...
|
|
return null;
|
|
} finally {
|
|
this._detachRange(range, endNode);
|
|
}
|
|
}
|
|
|
|
private static _mergeAdjacentRanges(ranges: FloatHorizontalRange[]): FloatHorizontalRange[] {
|
|
if (ranges.length === 1) {
|
|
// There is nothing to merge
|
|
return ranges;
|
|
}
|
|
|
|
ranges.sort(FloatHorizontalRange.compare);
|
|
|
|
const result: FloatHorizontalRange[] = [];
|
|
let resultLen = 0;
|
|
let prev = ranges[0];
|
|
|
|
for (let i = 1, len = ranges.length; i < len; i++) {
|
|
const range = ranges[i];
|
|
if (prev.left + prev.width + 0.9 /* account for browser's rounding errors*/ >= range.left) {
|
|
prev.width = Math.max(prev.width, range.left + range.width - prev.left);
|
|
} else {
|
|
result[resultLen++] = prev;
|
|
prev = range;
|
|
}
|
|
}
|
|
|
|
result[resultLen++] = prev;
|
|
|
|
return result;
|
|
}
|
|
|
|
private static _createHorizontalRangesFromClientRects(clientRects: DOMRectList | null, clientRectDeltaLeft: number, clientRectScale: number): FloatHorizontalRange[] | null {
|
|
if (!clientRects || clientRects.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
// We go through FloatHorizontalRange because it has been observed in bi-di text
|
|
// that the clientRects are not coming in sorted from the browser
|
|
|
|
const result: FloatHorizontalRange[] = [];
|
|
for (let i = 0, len = clientRects.length; i < len; i++) {
|
|
const clientRect = clientRects[i];
|
|
result[i] = new FloatHorizontalRange(Math.max(0, (clientRect.left - clientRectDeltaLeft) / clientRectScale), clientRect.width / clientRectScale);
|
|
}
|
|
|
|
return this._mergeAdjacentRanges(result);
|
|
}
|
|
|
|
public static readHorizontalRanges(domNode: HTMLElement, startChildIndex: number, startOffset: number, endChildIndex: number, endOffset: number, clientRectDeltaLeft: number, clientRectScale: number, endNode: HTMLElement): FloatHorizontalRange[] | null {
|
|
// Panic check
|
|
const min = 0;
|
|
const max = domNode.children.length - 1;
|
|
if (min > max) {
|
|
return null;
|
|
}
|
|
startChildIndex = Math.min(max, Math.max(min, startChildIndex));
|
|
endChildIndex = Math.min(max, Math.max(min, endChildIndex));
|
|
|
|
if (startChildIndex === endChildIndex && startOffset === endOffset && startOffset === 0 && !domNode.children[startChildIndex].firstChild) {
|
|
// We must find the position at the beginning of a <span>
|
|
// To cover cases of empty <span>s, avoid using a range and use the <span>'s bounding box
|
|
const clientRects = domNode.children[startChildIndex].getClientRects();
|
|
return this._createHorizontalRangesFromClientRects(clientRects, clientRectDeltaLeft, clientRectScale);
|
|
}
|
|
|
|
// If crossing over to a span only to select offset 0, then use the previous span's maximum offset
|
|
// Chrome is buggy and doesn't handle 0 offsets well sometimes.
|
|
if (startChildIndex !== endChildIndex) {
|
|
if (endChildIndex > 0 && endOffset === 0) {
|
|
endChildIndex--;
|
|
endOffset = Constants.MAX_SAFE_SMALL_INTEGER;
|
|
}
|
|
}
|
|
|
|
let startElement = domNode.children[startChildIndex].firstChild;
|
|
let endElement = domNode.children[endChildIndex].firstChild;
|
|
|
|
if (!startElement || !endElement) {
|
|
// When having an empty <span> (without any text content), try to move to the previous <span>
|
|
if (!startElement && startOffset === 0 && startChildIndex > 0) {
|
|
startElement = domNode.children[startChildIndex - 1].firstChild;
|
|
startOffset = Constants.MAX_SAFE_SMALL_INTEGER;
|
|
}
|
|
if (!endElement && endOffset === 0 && endChildIndex > 0) {
|
|
endElement = domNode.children[endChildIndex - 1].firstChild;
|
|
endOffset = Constants.MAX_SAFE_SMALL_INTEGER;
|
|
}
|
|
}
|
|
|
|
if (!startElement || !endElement) {
|
|
return null;
|
|
}
|
|
|
|
startOffset = Math.min(startElement.textContent!.length, Math.max(0, startOffset));
|
|
endOffset = Math.min(endElement.textContent!.length, Math.max(0, endOffset));
|
|
|
|
const clientRects = this._readClientRects(startElement, startOffset, endElement, endOffset, endNode);
|
|
return this._createHorizontalRangesFromClientRects(clientRects, clientRectDeltaLeft, clientRectScale);
|
|
}
|
|
}
|