UNPKG

monaco-editor

Version:
288 lines (287 loc) 14.7 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); } return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); import * as browser from '../../../base/browser/browser.js'; import { Emitter } from '../../../base/common/event.js'; import { Disposable } from '../../../base/common/lifecycle.js'; import * as platform from '../../../base/common/platform.js'; import { CharWidthRequest, readCharWidths } from './charWidthReader.js'; import { ElementSizeObserver } from './elementSizeObserver.js'; import { CommonEditorConfiguration } from '../../common/config/commonEditorConfig.js'; import { FontInfo } from '../../common/config/fontInfo.js'; var CSSBasedConfigurationCache = /** @class */ (function () { function CSSBasedConfigurationCache() { this._keys = Object.create(null); this._values = Object.create(null); } CSSBasedConfigurationCache.prototype.has = function (item) { var itemId = item.getId(); return !!this._values[itemId]; }; CSSBasedConfigurationCache.prototype.get = function (item) { var itemId = item.getId(); return this._values[itemId]; }; CSSBasedConfigurationCache.prototype.put = function (item, value) { var itemId = item.getId(); this._keys[itemId] = item; this._values[itemId] = value; }; CSSBasedConfigurationCache.prototype.remove = function (item) { var itemId = item.getId(); delete this._keys[itemId]; delete this._values[itemId]; }; CSSBasedConfigurationCache.prototype.getValues = function () { var _this = this; return Object.keys(this._keys).map(function (id) { return _this._values[id]; }); }; return CSSBasedConfigurationCache; }()); var CSSBasedConfiguration = /** @class */ (function (_super) { __extends(CSSBasedConfiguration, _super); function CSSBasedConfiguration() { var _this = _super.call(this) || this; _this._onDidChange = _this._register(new Emitter()); _this.onDidChange = _this._onDidChange.event; _this._cache = new CSSBasedConfigurationCache(); _this._evictUntrustedReadingsTimeout = -1; return _this; } CSSBasedConfiguration.prototype.dispose = function () { if (this._evictUntrustedReadingsTimeout !== -1) { clearTimeout(this._evictUntrustedReadingsTimeout); this._evictUntrustedReadingsTimeout = -1; } _super.prototype.dispose.call(this); }; CSSBasedConfiguration.prototype._writeToCache = function (item, value) { var _this = this; this._cache.put(item, value); if (!value.isTrusted && this._evictUntrustedReadingsTimeout === -1) { // Try reading again after some time this._evictUntrustedReadingsTimeout = setTimeout(function () { _this._evictUntrustedReadingsTimeout = -1; _this._evictUntrustedReadings(); }, 5000); } }; CSSBasedConfiguration.prototype._evictUntrustedReadings = function () { var values = this._cache.getValues(); var somethingRemoved = false; for (var i = 0, len = values.length; i < len; i++) { var item = values[i]; if (!item.isTrusted) { somethingRemoved = true; this._cache.remove(item); } } if (somethingRemoved) { this._onDidChange.fire(); } }; CSSBasedConfiguration.prototype.readConfiguration = function (bareFontInfo) { if (!this._cache.has(bareFontInfo)) { var 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), canUseHalfwidthRightwardsArrow: readConfig.canUseHalfwidthRightwardsArrow, spaceWidth: Math.max(readConfig.spaceWidth, 5), maxDigitWidth: Math.max(readConfig.maxDigitWidth, 5), }, false); } this._writeToCache(bareFontInfo, readConfig); } return this._cache.get(bareFontInfo); }; CSSBasedConfiguration.createRequest = function (chr, type, all, monospace) { var result = new CharWidthRequest(chr, type); all.push(result); if (monospace) { monospace.push(result); } return result; }; CSSBasedConfiguration._actualReadConfiguration = function (bareFontInfo) { var all = []; var monospace = []; var typicalHalfwidthCharacter = this.createRequest('n', 0 /* Regular */, all, monospace); var typicalFullwidthCharacter = this.createRequest('\uff4d', 0 /* Regular */, all, null); var space = this.createRequest(' ', 0 /* Regular */, all, monospace); var digit0 = this.createRequest('0', 0 /* Regular */, all, monospace); var digit1 = this.createRequest('1', 0 /* Regular */, all, monospace); var digit2 = this.createRequest('2', 0 /* Regular */, all, monospace); var digit3 = this.createRequest('3', 0 /* Regular */, all, monospace); var digit4 = this.createRequest('4', 0 /* Regular */, all, monospace); var digit5 = this.createRequest('5', 0 /* Regular */, all, monospace); var digit6 = this.createRequest('6', 0 /* Regular */, all, monospace); var digit7 = this.createRequest('7', 0 /* Regular */, all, monospace); var digit8 = this.createRequest('8', 0 /* Regular */, all, monospace); var digit9 = this.createRequest('9', 0 /* Regular */, all, monospace); // monospace test: used for whitespace rendering var rightwardsArrow = this.createRequest('→', 0 /* Regular */, all, monospace); var halfwidthRightwardsArrow = this.createRequest('→', 0 /* Regular */, all, null); this.createRequest('·', 0 /* Regular */, all, monospace); // monospace test: some characters this.createRequest('|', 0 /* Regular */, all, monospace); this.createRequest('/', 0 /* Regular */, all, monospace); this.createRequest('-', 0 /* Regular */, all, monospace); this.createRequest('_', 0 /* Regular */, all, monospace); this.createRequest('i', 0 /* Regular */, all, monospace); this.createRequest('l', 0 /* Regular */, all, monospace); this.createRequest('m', 0 /* Regular */, all, monospace); // monospace italic test this.createRequest('|', 1 /* Italic */, all, monospace); this.createRequest('_', 1 /* Italic */, all, monospace); this.createRequest('i', 1 /* Italic */, all, monospace); this.createRequest('l', 1 /* Italic */, all, monospace); this.createRequest('m', 1 /* Italic */, all, monospace); this.createRequest('n', 1 /* Italic */, all, monospace); // monospace bold test this.createRequest('|', 2 /* Bold */, all, monospace); this.createRequest('_', 2 /* Bold */, all, monospace); this.createRequest('i', 2 /* Bold */, all, monospace); this.createRequest('l', 2 /* Bold */, all, monospace); this.createRequest('m', 2 /* Bold */, all, monospace); this.createRequest('n', 2 /* Bold */, all, monospace); readCharWidths(bareFontInfo, all); var maxDigitWidth = Math.max(digit0.width, digit1.width, digit2.width, digit3.width, digit4.width, digit5.width, digit6.width, digit7.width, digit8.width, digit9.width); var isMonospace = true; var referenceWidth = monospace[0].width; for (var i = 1, len = monospace.length; i < len; i++) { var diff = referenceWidth - monospace[i].width; if (diff < -0.001 || diff > 0.001) { isMonospace = false; break; } } var canUseHalfwidthRightwardsArrow = true; if (isMonospace && halfwidthRightwardsArrow.width !== referenceWidth) { // using a halfwidth rightwards arrow would break monospace... canUseHalfwidthRightwardsArrow = false; } if (halfwidthRightwardsArrow.width > rightwardsArrow.width) { // using a halfwidth rightwards arrow would paint a larger arrow than a regular rightwards arrow canUseHalfwidthRightwardsArrow = false; } // let's trust the zoom level only 2s after it was changed. var 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, canUseHalfwidthRightwardsArrow: canUseHalfwidthRightwardsArrow, spaceWidth: space.width, maxDigitWidth: maxDigitWidth }, canTrustBrowserZoomLevel); }; CSSBasedConfiguration.INSTANCE = new CSSBasedConfiguration(); return CSSBasedConfiguration; }(Disposable)); var Configuration = /** @class */ (function (_super) { __extends(Configuration, _super); function Configuration(options, referenceDomElement) { if (referenceDomElement === void 0) { referenceDomElement = null; } var _this = _super.call(this, options) || this; _this._elementSizeObserver = _this._register(new ElementSizeObserver(referenceDomElement, function () { return _this._onReferenceDomElementSizeChanged(); })); _this._register(CSSBasedConfiguration.INSTANCE.onDidChange(function () { return _this._onCSSBasedConfigurationChanged(); })); if (_this._validatedOptions.automaticLayout) { _this._elementSizeObserver.startObserving(); } _this._register(browser.onDidChangeZoomLevel(function (_) { return _this._recomputeOptions(); })); _this._register(browser.onDidChangeAccessibilitySupport(function () { return _this._recomputeOptions(); })); _this._recomputeOptions(); return _this; } Configuration.applyFontInfoSlow = function (domNode, fontInfo) { domNode.style.fontFamily = fontInfo.getMassagedFontFamily(); domNode.style.fontWeight = fontInfo.fontWeight; domNode.style.fontSize = fontInfo.fontSize + 'px'; domNode.style.lineHeight = fontInfo.lineHeight + 'px'; domNode.style.letterSpacing = fontInfo.letterSpacing + 'px'; }; Configuration.applyFontInfo = function (domNode, fontInfo) { domNode.setFontFamily(fontInfo.getMassagedFontFamily()); domNode.setFontWeight(fontInfo.fontWeight); domNode.setFontSize(fontInfo.fontSize); domNode.setLineHeight(fontInfo.lineHeight); domNode.setLetterSpacing(fontInfo.letterSpacing); }; Configuration.prototype._onReferenceDomElementSizeChanged = function () { this._recomputeOptions(); }; Configuration.prototype._onCSSBasedConfigurationChanged = function () { this._recomputeOptions(); }; Configuration.prototype.observeReferenceElement = function (dimension) { this._elementSizeObserver.observe(dimension); }; Configuration.prototype.dispose = function () { _super.prototype.dispose.call(this); }; Configuration.prototype._getExtraEditorClassName = function () { var extra = ''; if (browser.isIE) { extra += 'ie '; } else if (browser.isFirefox) { extra += 'ff '; } else if (browser.isEdge) { extra += 'edge '; } else if (browser.isSafari) { extra += 'safari '; } if (platform.isMacintosh) { extra += 'mac '; } return extra; }; Configuration.prototype._getEnvConfiguration = function () { return { extraEditorClassName: this._getExtraEditorClassName(), outerWidth: this._elementSizeObserver.getWidth(), outerHeight: this._elementSizeObserver.getHeight(), emptySelectionClipboard: browser.isWebKit || browser.isFirefox, pixelRatio: browser.getPixelRatio(), zoomLevel: browser.getZoomLevel(), accessibilitySupport: browser.getAccessibilitySupport() }; }; Configuration.prototype.readConfiguration = function (bareFontInfo) { return CSSBasedConfiguration.INSTANCE.readConfiguration(bareFontInfo); }; return Configuration; }(CommonEditorConfiguration)); export { Configuration };