UNPKG

monaco-editor

Version:
285 lines (284 loc) • 10.8 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { Color } from '../../../../base/common/color.js'; var ParsedTokenThemeRule = /** @class */ (function () { function ParsedTokenThemeRule(token, index, fontStyle, foreground, background) { this.token = token; this.index = index; this.fontStyle = fontStyle; this.foreground = foreground; this.background = background; } return ParsedTokenThemeRule; }()); export { ParsedTokenThemeRule }; /** * Parse a raw theme into rules. */ export function parseTokenTheme(source) { if (!source || !Array.isArray(source)) { return []; } var result = [], resultLen = 0; for (var i = 0, len = source.length; i < len; i++) { var entry = source[i]; var fontStyle = -1 /* NotSet */; if (typeof entry.fontStyle === 'string') { fontStyle = 0 /* None */; var segments = entry.fontStyle.split(' '); for (var j = 0, lenJ = segments.length; j < lenJ; j++) { var segment = segments[j]; switch (segment) { case 'italic': fontStyle = fontStyle | 1 /* Italic */; break; case 'bold': fontStyle = fontStyle | 2 /* Bold */; break; case 'underline': fontStyle = fontStyle | 4 /* Underline */; break; } } } var foreground = null; if (typeof entry.foreground === 'string') { foreground = entry.foreground; } var background = null; if (typeof entry.background === 'string') { background = entry.background; } result[resultLen++] = new ParsedTokenThemeRule(entry.token || '', i, fontStyle, foreground, background); } return result; } /** * Resolve rules (i.e. inheritance). */ function resolveParsedTokenThemeRules(parsedThemeRules, customTokenColors) { // Sort rules lexicographically, and then by index if necessary parsedThemeRules.sort(function (a, b) { var r = strcmp(a.token, b.token); if (r !== 0) { return r; } return a.index - b.index; }); // Determine defaults var defaultFontStyle = 0 /* None */; var defaultForeground = '000000'; var defaultBackground = 'ffffff'; while (parsedThemeRules.length >= 1 && parsedThemeRules[0].token === '') { var incomingDefaults = parsedThemeRules.shift(); if (incomingDefaults.fontStyle !== -1 /* NotSet */) { defaultFontStyle = incomingDefaults.fontStyle; } if (incomingDefaults.foreground !== null) { defaultForeground = incomingDefaults.foreground; } if (incomingDefaults.background !== null) { defaultBackground = incomingDefaults.background; } } var colorMap = new ColorMap(); // start with token colors from custom token themes for (var _i = 0, customTokenColors_1 = customTokenColors; _i < customTokenColors_1.length; _i++) { var color = customTokenColors_1[_i]; colorMap.getId(color); } var foregroundColorId = colorMap.getId(defaultForeground); var backgroundColorId = colorMap.getId(defaultBackground); var defaults = new ThemeTrieElementRule(defaultFontStyle, foregroundColorId, backgroundColorId); var root = new ThemeTrieElement(defaults); for (var i = 0, len = parsedThemeRules.length; i < len; i++) { var rule = parsedThemeRules[i]; root.insert(rule.token, rule.fontStyle, colorMap.getId(rule.foreground), colorMap.getId(rule.background)); } return new TokenTheme(colorMap, root); } var colorRegExp = /^#?([0-9A-Fa-f]{6})([0-9A-Fa-f]{2})?$/; var ColorMap = /** @class */ (function () { function ColorMap() { this._lastColorId = 0; this._id2color = []; this._color2id = new Map(); } ColorMap.prototype.getId = function (color) { if (color === null) { return 0; } var match = color.match(colorRegExp); if (!match) { throw new Error('Illegal value for token color: ' + color); } color = match[1].toUpperCase(); var value = this._color2id.get(color); if (value) { return value; } value = ++this._lastColorId; this._color2id.set(color, value); this._id2color[value] = Color.fromHex('#' + color); return value; }; ColorMap.prototype.getColorMap = function () { return this._id2color.slice(0); }; return ColorMap; }()); export { ColorMap }; var TokenTheme = /** @class */ (function () { function TokenTheme(colorMap, root) { this._colorMap = colorMap; this._root = root; this._cache = new Map(); } TokenTheme.createFromRawTokenTheme = function (source, customTokenColors) { return this.createFromParsedTokenTheme(parseTokenTheme(source), customTokenColors); }; TokenTheme.createFromParsedTokenTheme = function (source, customTokenColors) { return resolveParsedTokenThemeRules(source, customTokenColors); }; TokenTheme.prototype.getColorMap = function () { return this._colorMap.getColorMap(); }; TokenTheme.prototype._match = function (token) { return this._root.match(token); }; TokenTheme.prototype.match = function (languageId, token) { // The cache contains the metadata without the language bits set. var result = this._cache.get(token); if (typeof result === 'undefined') { var rule = this._match(token); var standardToken = toStandardTokenType(token); result = (rule.metadata | (standardToken << 8 /* TOKEN_TYPE_OFFSET */)) >>> 0; this._cache.set(token, result); } return (result | (languageId << 0 /* LANGUAGEID_OFFSET */)) >>> 0; }; return TokenTheme; }()); export { TokenTheme }; var STANDARD_TOKEN_TYPE_REGEXP = /\b(comment|string|regex)\b/; export function toStandardTokenType(tokenType) { var m = tokenType.match(STANDARD_TOKEN_TYPE_REGEXP); if (!m) { return 0 /* Other */; } switch (m[1]) { case 'comment': return 1 /* Comment */; case 'string': return 2 /* String */; case 'regex': return 4 /* RegEx */; } throw new Error('Unexpected match for standard token type!'); } export function strcmp(a, b) { if (a < b) { return -1; } if (a > b) { return 1; } return 0; } var ThemeTrieElementRule = /** @class */ (function () { function ThemeTrieElementRule(fontStyle, foreground, background) { this._fontStyle = fontStyle; this._foreground = foreground; this._background = background; this.metadata = ((this._fontStyle << 11 /* FONT_STYLE_OFFSET */) | (this._foreground << 14 /* FOREGROUND_OFFSET */) | (this._background << 23 /* BACKGROUND_OFFSET */)) >>> 0; } ThemeTrieElementRule.prototype.clone = function () { return new ThemeTrieElementRule(this._fontStyle, this._foreground, this._background); }; ThemeTrieElementRule.prototype.acceptOverwrite = function (fontStyle, foreground, background) { if (fontStyle !== -1 /* NotSet */) { this._fontStyle = fontStyle; } if (foreground !== 0 /* None */) { this._foreground = foreground; } if (background !== 0 /* None */) { this._background = background; } this.metadata = ((this._fontStyle << 11 /* FONT_STYLE_OFFSET */) | (this._foreground << 14 /* FOREGROUND_OFFSET */) | (this._background << 23 /* BACKGROUND_OFFSET */)) >>> 0; }; return ThemeTrieElementRule; }()); export { ThemeTrieElementRule }; var ThemeTrieElement = /** @class */ (function () { function ThemeTrieElement(mainRule) { this._mainRule = mainRule; this._children = new Map(); } ThemeTrieElement.prototype.match = function (token) { if (token === '') { return this._mainRule; } var dotIndex = token.indexOf('.'); var head; var tail; if (dotIndex === -1) { head = token; tail = ''; } else { head = token.substring(0, dotIndex); tail = token.substring(dotIndex + 1); } var child = this._children.get(head); if (typeof child !== 'undefined') { return child.match(tail); } return this._mainRule; }; ThemeTrieElement.prototype.insert = function (token, fontStyle, foreground, background) { if (token === '') { // Merge into the main rule this._mainRule.acceptOverwrite(fontStyle, foreground, background); return; } var dotIndex = token.indexOf('.'); var head; var tail; if (dotIndex === -1) { head = token; tail = ''; } else { head = token.substring(0, dotIndex); tail = token.substring(dotIndex + 1); } var child = this._children.get(head); if (typeof child === 'undefined') { child = new ThemeTrieElement(this._mainRule.clone()); this._children.set(head, child); } child.insert(tail, fontStyle, foreground, background); }; return ThemeTrieElement; }()); export { ThemeTrieElement }; export function generateTokensCSSForColorMap(colorMap) { var rules = []; for (var i = 1, len = colorMap.length; i < len; i++) { var color = colorMap[i]; rules[i] = ".mtk" + i + " { color: " + color + "; }"; } rules.push('.mtki { font-style: italic; }'); rules.push('.mtkb { font-weight: bold; }'); rules.push('.mtku { text-decoration: underline; text-underline-position: under; }'); return rules.join('\n'); }