mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
SQL Operations Studio Public Preview 1 (0.23) release source code
This commit is contained in:
159
src/vs/editor/browser/config/charWidthReader.ts
Normal file
159
src/vs/editor/browser/config/charWidthReader.ts
Normal file
@@ -0,0 +1,159 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
|
||||
export const enum CharWidthRequestType {
|
||||
Regular = 0,
|
||||
Italic = 1,
|
||||
Bold = 2
|
||||
}
|
||||
|
||||
export class CharWidthRequest {
|
||||
|
||||
public readonly chr: string;
|
||||
public readonly type: CharWidthRequestType;
|
||||
public width: number;
|
||||
|
||||
constructor(chr: string, type: CharWidthRequestType) {
|
||||
this.chr = chr;
|
||||
this.type = type;
|
||||
this.width = 0;
|
||||
}
|
||||
|
||||
public fulfill(width: number) {
|
||||
this.width = width;
|
||||
}
|
||||
}
|
||||
|
||||
interface ICharWidthReader {
|
||||
read(): void;
|
||||
}
|
||||
|
||||
class DomCharWidthReader implements ICharWidthReader {
|
||||
|
||||
private readonly _bareFontInfo: BareFontInfo;
|
||||
private readonly _requests: CharWidthRequest[];
|
||||
|
||||
private _container: HTMLElement;
|
||||
private _testElements: HTMLSpanElement[];
|
||||
|
||||
constructor(bareFontInfo: BareFontInfo, requests: CharWidthRequest[]) {
|
||||
this._bareFontInfo = bareFontInfo;
|
||||
this._requests = requests;
|
||||
|
||||
this._container = null;
|
||||
this._testElements = null;
|
||||
}
|
||||
|
||||
public read(): void {
|
||||
// Create a test container with all these test elements
|
||||
this._createDomElements();
|
||||
|
||||
// Add the container to the DOM
|
||||
document.body.appendChild(this._container);
|
||||
|
||||
// Read character widths
|
||||
this._readFromDomElements();
|
||||
|
||||
// Remove the container from the DOM
|
||||
document.body.removeChild(this._container);
|
||||
|
||||
this._container = null;
|
||||
this._testElements = null;
|
||||
}
|
||||
|
||||
private _createDomElements(): void {
|
||||
let container = document.createElement('div');
|
||||
container.style.position = 'absolute';
|
||||
container.style.top = '-50000px';
|
||||
container.style.width = '50000px';
|
||||
|
||||
let regularDomNode = document.createElement('div');
|
||||
regularDomNode.style.fontFamily = this._bareFontInfo.fontFamily;
|
||||
regularDomNode.style.fontWeight = this._bareFontInfo.fontWeight;
|
||||
regularDomNode.style.fontSize = this._bareFontInfo.fontSize + 'px';
|
||||
regularDomNode.style.lineHeight = this._bareFontInfo.lineHeight + 'px';
|
||||
regularDomNode.style.letterSpacing = this._bareFontInfo.letterSpacing + 'px';
|
||||
container.appendChild(regularDomNode);
|
||||
|
||||
let boldDomNode = document.createElement('div');
|
||||
boldDomNode.style.fontFamily = this._bareFontInfo.fontFamily;
|
||||
boldDomNode.style.fontWeight = 'bold';
|
||||
boldDomNode.style.fontSize = this._bareFontInfo.fontSize + 'px';
|
||||
boldDomNode.style.lineHeight = this._bareFontInfo.lineHeight + 'px';
|
||||
boldDomNode.style.letterSpacing = this._bareFontInfo.letterSpacing + 'px';
|
||||
container.appendChild(boldDomNode);
|
||||
|
||||
let italicDomNode = document.createElement('div');
|
||||
italicDomNode.style.fontFamily = this._bareFontInfo.fontFamily;
|
||||
italicDomNode.style.fontWeight = this._bareFontInfo.fontWeight;
|
||||
italicDomNode.style.fontSize = this._bareFontInfo.fontSize + 'px';
|
||||
italicDomNode.style.lineHeight = this._bareFontInfo.lineHeight + 'px';
|
||||
italicDomNode.style.letterSpacing = this._bareFontInfo.letterSpacing + 'px';
|
||||
italicDomNode.style.fontStyle = 'italic';
|
||||
container.appendChild(italicDomNode);
|
||||
|
||||
let testElements: HTMLSpanElement[] = [];
|
||||
for (let i = 0, len = this._requests.length; i < len; i++) {
|
||||
const request = this._requests[i];
|
||||
|
||||
let parent: HTMLElement;
|
||||
if (request.type === CharWidthRequestType.Regular) {
|
||||
parent = regularDomNode;
|
||||
}
|
||||
if (request.type === CharWidthRequestType.Bold) {
|
||||
parent = boldDomNode;
|
||||
}
|
||||
if (request.type === CharWidthRequestType.Italic) {
|
||||
parent = italicDomNode;
|
||||
}
|
||||
|
||||
parent.appendChild(document.createElement('br'));
|
||||
|
||||
let testElement = document.createElement('span');
|
||||
DomCharWidthReader._render(testElement, request);
|
||||
parent.appendChild(testElement);
|
||||
|
||||
testElements[i] = testElement;
|
||||
}
|
||||
|
||||
this._container = container;
|
||||
this._testElements = testElements;
|
||||
}
|
||||
|
||||
private static _render(testElement: HTMLElement, request: CharWidthRequest): void {
|
||||
if (request.chr === ' ') {
|
||||
let htmlString = ' ';
|
||||
// Repeat character 256 (2^8) times
|
||||
for (let i = 0; i < 8; i++) {
|
||||
htmlString += htmlString;
|
||||
}
|
||||
testElement.innerHTML = htmlString;
|
||||
} else {
|
||||
let testString = request.chr;
|
||||
// Repeat character 256 (2^8) times
|
||||
for (let i = 0; i < 8; i++) {
|
||||
testString += testString;
|
||||
}
|
||||
testElement.textContent = testString;
|
||||
}
|
||||
}
|
||||
|
||||
private _readFromDomElements(): void {
|
||||
for (let i = 0, len = this._requests.length; i < len; i++) {
|
||||
const request = this._requests[i];
|
||||
const testElement = this._testElements[i];
|
||||
|
||||
request.fulfill(testElement.offsetWidth / 256);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function readCharWidths(bareFontInfo: BareFontInfo, requests: CharWidthRequest[]): void {
|
||||
let reader = new DomCharWidthReader(bareFontInfo, requests);
|
||||
reader.read();
|
||||
}
|
||||
364
src/vs/editor/browser/config/configuration.ts
Normal file
364
src/vs/editor/browser/config/configuration.ts
Normal file
@@ -0,0 +1,364 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { CommonEditorConfiguration, IEnvConfiguration } from 'vs/editor/common/config/commonEditorConfig';
|
||||
import { IDimension } from 'vs/editor/common/editorCommon';
|
||||
import { FontInfo, BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver';
|
||||
import { FastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { CharWidthRequest, CharWidthRequestType, readCharWidths } from 'vs/editor/browser/config/charWidthReader';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
|
||||
class CSSBasedConfigurationCache {
|
||||
|
||||
private _keys: { [key: string]: BareFontInfo; };
|
||||
private _values: { [key: string]: FontInfo; };
|
||||
|
||||
constructor() {
|
||||
this._keys = Object.create(null);
|
||||
this._values = Object.create(null);
|
||||
}
|
||||
|
||||
public has(item: BareFontInfo): boolean {
|
||||
let itemId = item.getId();
|
||||
return !!this._values[itemId];
|
||||
}
|
||||
|
||||
public get(item: BareFontInfo): FontInfo {
|
||||
let itemId = item.getId();
|
||||
return this._values[itemId];
|
||||
}
|
||||
|
||||
public put(item: BareFontInfo, value: FontInfo): void {
|
||||
let itemId = item.getId();
|
||||
this._keys[itemId] = item;
|
||||
this._values[itemId] = value;
|
||||
}
|
||||
|
||||
public remove(item: BareFontInfo): void {
|
||||
let itemId = item.getId();
|
||||
delete this._keys[itemId];
|
||||
delete this._values[itemId];
|
||||
}
|
||||
|
||||
public getKeys(): BareFontInfo[] {
|
||||
return Object.keys(this._keys).map(id => this._keys[id]);
|
||||
}
|
||||
|
||||
public getValues(): FontInfo[] {
|
||||
return Object.keys(this._keys).map(id => this._values[id]);
|
||||
}
|
||||
}
|
||||
|
||||
export function readFontInfo(bareFontInfo: BareFontInfo): FontInfo {
|
||||
return CSSBasedConfiguration.INSTANCE.readConfiguration(bareFontInfo);
|
||||
}
|
||||
|
||||
export function restoreFontInfo(storageService: IStorageService): void {
|
||||
let strStoredFontInfo = storageService.get('editorFontInfo', StorageScope.GLOBAL);
|
||||
if (typeof strStoredFontInfo !== 'string') {
|
||||
return;
|
||||
}
|
||||
let storedFontInfo: ISerializedFontInfo[] = null;
|
||||
try {
|
||||
storedFontInfo = JSON.parse(strStoredFontInfo);
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(storedFontInfo)) {
|
||||
return;
|
||||
}
|
||||
CSSBasedConfiguration.INSTANCE.restoreFontInfo(storedFontInfo);
|
||||
}
|
||||
|
||||
export function saveFontInfo(storageService: IStorageService): void {
|
||||
let knownFontInfo = CSSBasedConfiguration.INSTANCE.saveFontInfo();
|
||||
storageService.store('editorFontInfo', JSON.stringify(knownFontInfo), StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
export interface ISerializedFontInfo {
|
||||
readonly zoomLevel: number;
|
||||
readonly fontFamily: string;
|
||||
readonly fontWeight: string;
|
||||
readonly fontSize: number;
|
||||
readonly lineHeight: number;
|
||||
readonly letterSpacing: number;
|
||||
readonly isMonospace: boolean;
|
||||
readonly typicalHalfwidthCharacterWidth: number;
|
||||
readonly typicalFullwidthCharacterWidth: number;
|
||||
readonly spaceWidth: number;
|
||||
readonly maxDigitWidth: number;
|
||||
}
|
||||
|
||||
class CSSBasedConfiguration extends Disposable {
|
||||
|
||||
public static INSTANCE = new CSSBasedConfiguration();
|
||||
|
||||
private _cache: CSSBasedConfigurationCache;
|
||||
private _evictUntrustedReadingsTimeout: number;
|
||||
|
||||
private _onDidChange = this._register(new Emitter<void>());
|
||||
public onDidChange: Event<void> = this._onDidChange.event;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._cache = new CSSBasedConfigurationCache();
|
||||
this._evictUntrustedReadingsTimeout = -1;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this._evictUntrustedReadingsTimeout !== -1) {
|
||||
clearTimeout(this._evictUntrustedReadingsTimeout);
|
||||
this._evictUntrustedReadingsTimeout = -1;
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private _writeToCache(item: BareFontInfo, value: FontInfo): void {
|
||||
this._cache.put(item, value);
|
||||
|
||||
if (!value.isTrusted && this._evictUntrustedReadingsTimeout === -1) {
|
||||
// Try reading again after some time
|
||||
this._evictUntrustedReadingsTimeout = setTimeout(() => {
|
||||
this._evictUntrustedReadingsTimeout = -1;
|
||||
this._evictUntrustedReadings();
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
private _evictUntrustedReadings(): void {
|
||||
let values = this._cache.getValues();
|
||||
let somethingRemoved = false;
|
||||
for (let i = 0, len = values.length; i < len; i++) {
|
||||
let item = values[i];
|
||||
if (!item.isTrusted) {
|
||||
somethingRemoved = true;
|
||||
this._cache.remove(item);
|
||||
}
|
||||
}
|
||||
if (somethingRemoved) {
|
||||
this._onDidChange.fire();
|
||||
}
|
||||
}
|
||||
|
||||
public saveFontInfo(): ISerializedFontInfo[] {
|
||||
// Only save trusted font info (that has been measured in this running instance)
|
||||
return this._cache.getValues().filter(item => item.isTrusted);
|
||||
}
|
||||
|
||||
public restoreFontInfo(savedFontInfo: ISerializedFontInfo[]): void {
|
||||
// Take all the saved font info and insert them in the cache without the trusted flag.
|
||||
// The reason for this is that a font might have been installed on the OS in the meantime.
|
||||
for (let i = 0, len = savedFontInfo.length; i < len; i++) {
|
||||
let fontInfo = new FontInfo(savedFontInfo[i], false);
|
||||
this._writeToCache(fontInfo, fontInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public readConfiguration(bareFontInfo: BareFontInfo): FontInfo {
|
||||
if (!this._cache.has(bareFontInfo)) {
|
||||
let readConfig = CSSBasedConfiguration._actualReadConfiguration(bareFontInfo);
|
||||
|
||||
if (readConfig.typicalHalfwidthCharacterWidth <= 2 || readConfig.typicalFullwidthCharacterWidth <= 2 || readConfig.spaceWidth <= 2 || readConfig.maxDigitWidth <= 2) {
|
||||
// Hey, it's Bug 14341 ... we couldn't read
|
||||
readConfig = new FontInfo({
|
||||
zoomLevel: browser.getZoomLevel(),
|
||||
fontFamily: readConfig.fontFamily,
|
||||
fontWeight: readConfig.fontWeight,
|
||||
fontSize: readConfig.fontSize,
|
||||
lineHeight: readConfig.lineHeight,
|
||||
letterSpacing: readConfig.letterSpacing,
|
||||
isMonospace: readConfig.isMonospace,
|
||||
typicalHalfwidthCharacterWidth: Math.max(readConfig.typicalHalfwidthCharacterWidth, 5),
|
||||
typicalFullwidthCharacterWidth: Math.max(readConfig.typicalFullwidthCharacterWidth, 5),
|
||||
spaceWidth: Math.max(readConfig.spaceWidth, 5),
|
||||
maxDigitWidth: Math.max(readConfig.maxDigitWidth, 5),
|
||||
}, false);
|
||||
}
|
||||
|
||||
this._writeToCache(bareFontInfo, readConfig);
|
||||
}
|
||||
return this._cache.get(bareFontInfo);
|
||||
}
|
||||
|
||||
private static createRequest(chr: string, type: CharWidthRequestType, all: CharWidthRequest[], monospace: CharWidthRequest[]): CharWidthRequest {
|
||||
let result = new CharWidthRequest(chr, type);
|
||||
all.push(result);
|
||||
if (monospace) {
|
||||
monospace.push(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static _actualReadConfiguration(bareFontInfo: BareFontInfo): FontInfo {
|
||||
let all: CharWidthRequest[] = [];
|
||||
let monospace: CharWidthRequest[] = [];
|
||||
|
||||
const typicalHalfwidthCharacter = this.createRequest('n', CharWidthRequestType.Regular, all, monospace);
|
||||
const typicalFullwidthCharacter = this.createRequest('\uff4d', CharWidthRequestType.Regular, all, null);
|
||||
const space = this.createRequest(' ', CharWidthRequestType.Regular, all, monospace);
|
||||
const digit0 = this.createRequest('0', CharWidthRequestType.Regular, all, monospace);
|
||||
const digit1 = this.createRequest('1', CharWidthRequestType.Regular, all, monospace);
|
||||
const digit2 = this.createRequest('2', CharWidthRequestType.Regular, all, monospace);
|
||||
const digit3 = this.createRequest('3', CharWidthRequestType.Regular, all, monospace);
|
||||
const digit4 = this.createRequest('4', CharWidthRequestType.Regular, all, monospace);
|
||||
const digit5 = this.createRequest('5', CharWidthRequestType.Regular, all, monospace);
|
||||
const digit6 = this.createRequest('6', CharWidthRequestType.Regular, all, monospace);
|
||||
const digit7 = this.createRequest('7', CharWidthRequestType.Regular, all, monospace);
|
||||
const digit8 = this.createRequest('8', CharWidthRequestType.Regular, all, monospace);
|
||||
const digit9 = this.createRequest('9', CharWidthRequestType.Regular, all, monospace);
|
||||
|
||||
// monospace test: used for whitespace rendering
|
||||
this.createRequest('→', CharWidthRequestType.Regular, all, monospace);
|
||||
this.createRequest('·', CharWidthRequestType.Regular, all, monospace);
|
||||
|
||||
// monospace test: some characters
|
||||
this.createRequest('|', CharWidthRequestType.Regular, all, monospace);
|
||||
this.createRequest('/', CharWidthRequestType.Regular, all, monospace);
|
||||
this.createRequest('-', CharWidthRequestType.Regular, all, monospace);
|
||||
this.createRequest('_', CharWidthRequestType.Regular, all, monospace);
|
||||
this.createRequest('i', CharWidthRequestType.Regular, all, monospace);
|
||||
this.createRequest('l', CharWidthRequestType.Regular, all, monospace);
|
||||
this.createRequest('m', CharWidthRequestType.Regular, all, monospace);
|
||||
|
||||
// monospace italic test
|
||||
this.createRequest('|', CharWidthRequestType.Italic, all, monospace);
|
||||
this.createRequest('_', CharWidthRequestType.Italic, all, monospace);
|
||||
this.createRequest('i', CharWidthRequestType.Italic, all, monospace);
|
||||
this.createRequest('l', CharWidthRequestType.Italic, all, monospace);
|
||||
this.createRequest('m', CharWidthRequestType.Italic, all, monospace);
|
||||
this.createRequest('n', CharWidthRequestType.Italic, all, monospace);
|
||||
|
||||
// monospace bold test
|
||||
this.createRequest('|', CharWidthRequestType.Bold, all, monospace);
|
||||
this.createRequest('_', CharWidthRequestType.Bold, all, monospace);
|
||||
this.createRequest('i', CharWidthRequestType.Bold, all, monospace);
|
||||
this.createRequest('l', CharWidthRequestType.Bold, all, monospace);
|
||||
this.createRequest('m', CharWidthRequestType.Bold, all, monospace);
|
||||
this.createRequest('n', CharWidthRequestType.Bold, all, monospace);
|
||||
|
||||
readCharWidths(bareFontInfo, all);
|
||||
|
||||
const maxDigitWidth = Math.max(digit0.width, digit1.width, digit2.width, digit3.width, digit4.width, digit5.width, digit6.width, digit7.width, digit8.width, digit9.width);
|
||||
|
||||
let isMonospace = true;
|
||||
let referenceWidth = monospace[0].width;
|
||||
for (let i = 1, len = monospace.length; i < len; i++) {
|
||||
const diff = referenceWidth - monospace[i].width;
|
||||
if (diff < -0.001 || diff > 0.001) {
|
||||
isMonospace = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// let's trust the zoom level only 2s after it was changed.
|
||||
const canTrustBrowserZoomLevel = (browser.getTimeSinceLastZoomLevelChanged() > 2000);
|
||||
return new FontInfo({
|
||||
zoomLevel: browser.getZoomLevel(),
|
||||
fontFamily: bareFontInfo.fontFamily,
|
||||
fontWeight: bareFontInfo.fontWeight,
|
||||
fontSize: bareFontInfo.fontSize,
|
||||
lineHeight: bareFontInfo.lineHeight,
|
||||
letterSpacing: bareFontInfo.letterSpacing,
|
||||
isMonospace: isMonospace,
|
||||
typicalHalfwidthCharacterWidth: typicalHalfwidthCharacter.width,
|
||||
typicalFullwidthCharacterWidth: typicalFullwidthCharacter.width,
|
||||
spaceWidth: space.width,
|
||||
maxDigitWidth: maxDigitWidth
|
||||
}, canTrustBrowserZoomLevel);
|
||||
}
|
||||
}
|
||||
|
||||
export class Configuration extends CommonEditorConfiguration {
|
||||
|
||||
public static applyFontInfoSlow(domNode: HTMLElement, fontInfo: BareFontInfo): void {
|
||||
domNode.style.fontFamily = fontInfo.fontFamily;
|
||||
domNode.style.fontWeight = fontInfo.fontWeight;
|
||||
domNode.style.fontSize = fontInfo.fontSize + 'px';
|
||||
domNode.style.lineHeight = fontInfo.lineHeight + 'px';
|
||||
domNode.style.letterSpacing = fontInfo.letterSpacing + 'px';
|
||||
}
|
||||
|
||||
public static applyFontInfo(domNode: FastDomNode<HTMLElement>, fontInfo: BareFontInfo): void {
|
||||
domNode.setFontFamily(fontInfo.fontFamily);
|
||||
domNode.setFontWeight(fontInfo.fontWeight);
|
||||
domNode.setFontSize(fontInfo.fontSize);
|
||||
domNode.setLineHeight(fontInfo.lineHeight);
|
||||
domNode.setLetterSpacing(fontInfo.letterSpacing);
|
||||
}
|
||||
|
||||
private readonly _elementSizeObserver: ElementSizeObserver;
|
||||
|
||||
constructor(options: IEditorOptions, referenceDomElement: HTMLElement = null) {
|
||||
super(options);
|
||||
|
||||
this._elementSizeObserver = this._register(new ElementSizeObserver(referenceDomElement, () => this._onReferenceDomElementSizeChanged()));
|
||||
|
||||
this._register(CSSBasedConfiguration.INSTANCE.onDidChange(() => this._onCSSBasedConfigurationChanged()));
|
||||
|
||||
if (this._validatedOptions.automaticLayout) {
|
||||
this._elementSizeObserver.startObserving();
|
||||
}
|
||||
|
||||
this._register(browser.onDidChangeZoomLevel(_ => this._recomputeOptions()));
|
||||
this._register(browser.onDidChangeAccessibilitySupport(() => this._recomputeOptions()));
|
||||
|
||||
this._recomputeOptions();
|
||||
}
|
||||
|
||||
private _onReferenceDomElementSizeChanged(): void {
|
||||
this._recomputeOptions();
|
||||
}
|
||||
|
||||
private _onCSSBasedConfigurationChanged(): void {
|
||||
this._recomputeOptions();
|
||||
}
|
||||
|
||||
public observeReferenceElement(dimension?: IDimension): void {
|
||||
this._elementSizeObserver.observe(dimension);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private _getExtraEditorClassName(): string {
|
||||
let extra = '';
|
||||
if (browser.isIE) {
|
||||
extra += 'ie ';
|
||||
} else if (browser.isFirefox) {
|
||||
extra += 'ff ';
|
||||
} else if (browser.isEdge) {
|
||||
extra += 'edge ';
|
||||
}
|
||||
if (platform.isMacintosh) {
|
||||
extra += 'mac ';
|
||||
}
|
||||
return extra;
|
||||
}
|
||||
|
||||
protected _getEnvConfiguration(): IEnvConfiguration {
|
||||
return {
|
||||
extraEditorClassName: this._getExtraEditorClassName(),
|
||||
outerWidth: this._elementSizeObserver.getWidth(),
|
||||
outerHeight: this._elementSizeObserver.getHeight(),
|
||||
emptySelectionClipboard: browser.isWebKit,
|
||||
pixelRatio: browser.getPixelRatio(),
|
||||
zoomLevel: browser.getZoomLevel(),
|
||||
accessibilitySupport: browser.getAccessibilitySupport()
|
||||
};
|
||||
}
|
||||
|
||||
protected readConfiguration(bareFontInfo: BareFontInfo): FontInfo {
|
||||
return CSSBasedConfiguration.INSTANCE.readConfiguration(bareFontInfo);
|
||||
}
|
||||
}
|
||||
79
src/vs/editor/browser/config/elementSizeObserver.ts
Normal file
79
src/vs/editor/browser/config/elementSizeObserver.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IDimension } from 'vs/editor/common/editorCommon';
|
||||
|
||||
export class ElementSizeObserver extends Disposable {
|
||||
|
||||
private referenceDomElement: HTMLElement;
|
||||
private measureReferenceDomElementToken: number;
|
||||
private changeCallback: () => void;
|
||||
private width: number;
|
||||
private height: number;
|
||||
|
||||
constructor(referenceDomElement: HTMLElement, changeCallback: () => void) {
|
||||
super();
|
||||
this.referenceDomElement = referenceDomElement;
|
||||
this.changeCallback = changeCallback;
|
||||
this.measureReferenceDomElementToken = -1;
|
||||
this.width = -1;
|
||||
this.height = -1;
|
||||
this.measureReferenceDomElement(false);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this.stopObserving();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public getWidth(): number {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public getHeight(): number {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public startObserving(): void {
|
||||
if (this.measureReferenceDomElementToken === -1) {
|
||||
this.measureReferenceDomElementToken = setInterval(() => this.measureReferenceDomElement(true), 100);
|
||||
}
|
||||
}
|
||||
|
||||
public stopObserving(): void {
|
||||
if (this.measureReferenceDomElementToken !== -1) {
|
||||
clearInterval(this.measureReferenceDomElementToken);
|
||||
this.measureReferenceDomElementToken = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public observe(dimension?: IDimension): void {
|
||||
this.measureReferenceDomElement(true, dimension);
|
||||
}
|
||||
|
||||
private measureReferenceDomElement(callChangeCallback: boolean, dimension?: IDimension): void {
|
||||
let observedWidth = 0;
|
||||
let observedHeight = 0;
|
||||
if (dimension) {
|
||||
observedWidth = dimension.width;
|
||||
observedHeight = dimension.height;
|
||||
} else if (this.referenceDomElement) {
|
||||
observedWidth = this.referenceDomElement.clientWidth;
|
||||
observedHeight = this.referenceDomElement.clientHeight;
|
||||
}
|
||||
observedWidth = Math.max(5, observedWidth);
|
||||
observedHeight = Math.max(5, observedHeight);
|
||||
if (this.width !== observedWidth || this.height !== observedHeight) {
|
||||
this.width = observedWidth;
|
||||
this.height = observedHeight;
|
||||
if (callChangeCallback) {
|
||||
this.changeCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user