move workbench/themes to browser namespace

This commit is contained in:
Martin Aeschlimann
2019-02-13 23:20:26 +01:00
parent 18d81329b9
commit aadfc43a87
8 changed files with 518 additions and 39 deletions

View File

@@ -28,7 +28,6 @@
},
"dependencies": {
"applicationinsights": "1.0.8",
"fast-plist": "0.1.2",
"gc-signals": "^0.0.1",
"getmac": "1.4.1",
"graceful-fs": "4.1.11",
@@ -82,6 +81,7 @@
"event-stream": "3.3.4",
"express": "^4.13.1",
"fancy-log": "^1.3.3",
"fast-plist": "0.1.2",
"glob": "^5.0.13",
"gulp": "^4.0.0",
"gulp-atom-electron": "^1.20.0",

View File

@@ -1,7 +0,0 @@
declare module "fast-plist" {
/**
* A very fast plist parser
*/
export function parse(content: string): any;
}

View File

@@ -175,7 +175,7 @@ import { LifecycleService } from 'vs/platform/lifecycle/electron-browser/lifecyc
import { ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions';
import { registerWindowDriver } from 'vs/platform/driver/electron-browser/driver';
import { IExtensionUrlHandler, ExtensionUrlHandler } from 'vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler';
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
import { WorkbenchThemeService } from 'vs/workbench/services/themes/browser/workbenchThemeService';
import { DialogService, FileDialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogService';
import { ShowPreviousWindowTab, MoveWindowTabToNewWindow, MergeAllWindowTabs, ShowNextWindowTab, ToggleWindowTabsBar, NewWindowTab, OpenRecentAction, ReloadWindowAction, ReloadWindowWithExtensionsDisabledAction } from 'vs/workbench/electron-browser/actions/windowActions';
import { IBroadcastService, BroadcastService } from 'vs/workbench/services/broadcast/electron-browser/broadcastService';

View File

@@ -8,7 +8,7 @@ import { basename } from 'vs/base/common/path';
import * as Json from 'vs/base/common/json';
import { Color } from 'vs/base/common/color';
import { ExtensionData, ITokenColorCustomizations, ITokenColorizationRule, IColorTheme, IColorMap, IThemeExtensionPoint, VS_LIGHT_THEME, VS_HC_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { convertSettings } from 'vs/workbench/services/themes/electron-browser/themeCompatibility';
import { convertSettings } from 'vs/workbench/services/themes/browser/themeCompatibility';
import * as nls from 'vs/nls';
import * as types from 'vs/base/common/types';
import * as objects from 'vs/base/common/objects';
@@ -16,10 +16,11 @@ import * as resources from 'vs/base/common/resources';
import { Extensions, IColorRegistry, ColorIdentifier, editorBackground, editorForeground } from 'vs/platform/theme/common/colorRegistry';
import { ThemeType } from 'vs/platform/theme/common/themeService';
import { Registry } from 'vs/platform/registry/common/platform';
import { IColorCustomizations } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
import { IColorCustomizations } from 'vs/workbench/services/themes/browser/workbenchThemeService';
import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages';
import { URI } from 'vs/base/common/uri';
import { IFileService } from 'vs/platform/files/common/files';
import { parse as parsePList } from 'vs/workbench/services/themes/common/plistParser';
let colorRegistry = Registry.as<IColorRegistry>(Extensions.ColorContribution);
@@ -330,29 +331,19 @@ function _loadColorTheme(fileService: IFileService, themeLocation: URI, resultRu
}
}
let pListParser: Promise<{ parse(content: string) }>;
function getPListParser() {
if (!pListParser) {
pListParser = import('fast-plist');
}
return pListParser;
}
function _loadSyntaxTokens(fileService: IFileService, themeLocation: URI, resultRules: ITokenColorizationRule[], resultColors: IColorMap): Promise<any> {
return fileService.resolveContent(themeLocation, { encoding: 'utf8' }).then(content => {
return getPListParser().then(parser => {
try {
let contentValue = parser.parse(content.value.toString());
let settings: ITokenColorizationRule[] = contentValue.settings;
if (!Array.isArray(settings)) {
return Promise.reject(new Error(nls.localize('error.plist.invalidformat', "Problem parsing tmTheme file: {0}. 'settings' is not array.")));
}
convertSettings(settings, resultRules, resultColors);
return Promise.resolve(null);
} catch (e) {
return Promise.reject(new Error(nls.localize('error.cannotparse', "Problems parsing tmTheme file: {0}", e.message)));
try {
let contentValue = parsePList(content.value.toString());
let settings: ITokenColorizationRule[] = contentValue.settings;
if (!Array.isArray(settings)) {
return Promise.reject(new Error(nls.localize('error.plist.invalidformat', "Problem parsing tmTheme file: {0}. 'settings' is not array.")));
}
});
convertSettings(settings, resultRules, resultColors);
return Promise.resolve(null);
} catch (e) {
return Promise.reject(new Error(nls.localize('error.cannotparse', "Problems parsing tmTheme file: {0}", e.message)));
}
}, error => {
return Promise.reject(new Error(nls.localize('error.cannotload', "Problems loading tmTheme file {0}: {1}", themeLocation.toString(), error.message)));
});

View File

@@ -9,7 +9,7 @@ import * as types from 'vs/base/common/types';
import * as resources from 'vs/base/common/resources';
import { ExtensionsRegistry, ExtensionMessageCollector } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { ExtensionData, IThemeExtensionPoint, VS_LIGHT_THEME, VS_DARK_THEME, VS_HC_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { ColorThemeData } from 'vs/workbench/services/themes/electron-browser/colorThemeData';
import { ColorThemeData } from 'vs/workbench/services/themes/browser/colorThemeData';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { Event, Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';

View File

@@ -8,8 +8,6 @@ import { Color } from 'vs/base/common/color';
import * as colorRegistry from 'vs/platform/theme/common/colorRegistry';
import * as editorColorRegistry from 'vs/editor/common/view/editorColorRegistry';
import * as wordHighlighter from 'vs/editor/contrib/wordHighlighter/wordHighlighter';
import { peekViewEditorMatchHighlight, peekViewResultsMatchHighlight } from 'vs/editor/contrib/referenceSearch/referencesWidget';
const settingToColorIdMapping: { [settingId: string]: string[] } = {};
function addSettingMapping(settingId: string, colorId: string) {
@@ -56,11 +54,11 @@ addSettingMapping('selectionHighlightColor', colorRegistry.editorSelectionHighli
addSettingMapping('findMatchHighlight', colorRegistry.editorFindMatchHighlight);
addSettingMapping('currentFindMatchHighlight', colorRegistry.editorFindMatch);
addSettingMapping('hoverHighlight', colorRegistry.editorHoverHighlight);
addSettingMapping('wordHighlight', wordHighlighter.editorWordHighlight);
addSettingMapping('wordHighlightStrong', wordHighlighter.editorWordHighlightStrong);
addSettingMapping('wordHighlight', 'editor.wordHighlightBackground'); // inlined to avoid editor/contrib dependenies
addSettingMapping('wordHighlightStrong', 'editor.wordHighlightStrongBackground');
addSettingMapping('findRangeHighlight', colorRegistry.editorFindRangeHighlight);
addSettingMapping('findMatchHighlight', peekViewResultsMatchHighlight);
addSettingMapping('referenceHighlight', peekViewEditorMatchHighlight);
addSettingMapping('findMatchHighlight', 'peekViewResult.matchHighlightBackground');
addSettingMapping('referenceHighlight', 'peekViewEditor.matchHighlightBackground');
addSettingMapping('lineHighlight', editorColorRegistry.editorLineHighlight);
addSettingMapping('rangeHighlight', editorColorRegistry.editorRangeHighlight);
addSettingMapping('caret', editorColorRegistry.editorCursorForeground);

View File

@@ -19,7 +19,7 @@ import { ITheme, Extensions as ThemingExtensions, IThemingRegistry } from 'vs/pl
import { Event, Emitter } from 'vs/base/common/event';
import { registerFileIconThemeSchemas } from 'vs/workbench/services/themes/common/fileIconThemeSchema';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ColorThemeStore } from 'vs/workbench/services/themes/electron-browser/colorThemeStore';
import { ColorThemeStore } from 'vs/workbench/services/themes/browser/colorThemeStore';
import { FileIconThemeStore } from 'vs/workbench/services/themes/common/fileIconThemeStore';
import { FileIconThemeData } from 'vs/workbench/services/themes/common/fileIconThemeData';
import { IWindowService } from 'vs/platform/windows/common/windows';

View File

@@ -0,0 +1,497 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const enum ChCode {
BOM = 65279,
SPACE = 32,
TAB = 9,
CARRIAGE_RETURN = 13,
LINE_FEED = 10,
SLASH = 47,
LESS_THAN = 60,
QUESTION_MARK = 63,
EXCLAMATION_MARK = 33,
}
const enum State {
ROOT_STATE = 0,
DICT_STATE = 1,
ARR_STATE = 2
}
export function parseWithLocation(content: string, filename: string, locationKeyName: string): any {
return _parse(content, filename, locationKeyName);
}
/**
* A very fast plist parser
*/
export function parse(content: string): any {
return _parse(content, null, null);
}
function _parse(content: string, filename: string | null, locationKeyName: string | null): any {
const len = content.length;
let pos = 0;
let line = 1;
let char = 0;
// Skip UTF8 BOM
if (len > 0 && content.charCodeAt(0) === ChCode.BOM) {
pos = 1;
}
function advancePosBy(by: number): void {
if (locationKeyName === null) {
pos = pos + by;
} else {
while (by > 0) {
let chCode = content.charCodeAt(pos);
if (chCode === ChCode.LINE_FEED) {
pos++; line++; char = 0;
} else {
pos++; char++;
}
by--;
}
}
}
function advancePosTo(to: number): void {
if (locationKeyName === null) {
pos = to;
} else {
advancePosBy(to - pos);
}
}
function skipWhitespace(): void {
while (pos < len) {
let chCode = content.charCodeAt(pos);
if (chCode !== ChCode.SPACE && chCode !== ChCode.TAB && chCode !== ChCode.CARRIAGE_RETURN && chCode !== ChCode.LINE_FEED) {
break;
}
advancePosBy(1);
}
}
function advanceIfStartsWith(str: string): boolean {
if (content.substr(pos, str.length) === str) {
advancePosBy(str.length);
return true;
}
return false;
}
function advanceUntil(str: string): void {
let nextOccurence = content.indexOf(str, pos);
if (nextOccurence !== -1) {
advancePosTo(nextOccurence + str.length);
} else {
// EOF
advancePosTo(len);
}
}
function captureUntil(str: string): string {
let nextOccurence = content.indexOf(str, pos);
if (nextOccurence !== -1) {
let r = content.substring(pos, nextOccurence);
advancePosTo(nextOccurence + str.length);
return r;
} else {
// EOF
let r = content.substr(pos);
advancePosTo(len);
return r;
}
}
let state = State.ROOT_STATE;
let cur: any = null;
let stateStack: State[] = [];
let objStack: any[] = [];
let curKey: string | null = null;
function pushState(newState: State, newCur: any): void {
stateStack.push(state);
objStack.push(cur);
state = newState;
cur = newCur;
}
function popState(): void {
if (stateStack.length === 0) {
return fail('illegal state stack');
}
state = stateStack.pop()!;
cur = objStack.pop();
}
function fail(msg: string): void {
throw new Error('Near offset ' + pos + ': ' + msg + ' ~~~' + content.substr(pos, 50) + '~~~');
}
const dictState = {
enterDict: function () {
if (curKey === null) {
return fail('missing <key>');
}
let newDict = {};
if (locationKeyName !== null) {
newDict[locationKeyName] = {
filename: filename,
line: line,
char: char
};
}
cur[curKey] = newDict;
curKey = null;
pushState(State.DICT_STATE, newDict);
},
enterArray: function () {
if (curKey === null) {
return fail('missing <key>');
}
let newArr: any[] = [];
cur[curKey] = newArr;
curKey = null;
pushState(State.ARR_STATE, newArr);
}
};
const arrState = {
enterDict: function () {
let newDict = {};
if (locationKeyName !== null) {
newDict[locationKeyName] = {
filename: filename,
line: line,
char: char
};
}
cur.push(newDict);
pushState(State.DICT_STATE, newDict);
},
enterArray: function () {
let newArr: any[] = [];
cur.push(newArr);
pushState(State.ARR_STATE, newArr);
}
};
function enterDict() {
if (state === State.DICT_STATE) {
dictState.enterDict();
} else if (state === State.ARR_STATE) {
arrState.enterDict();
} else { // ROOT_STATE
cur = {};
if (locationKeyName !== null) {
cur[locationKeyName] = {
filename: filename,
line: line,
char: char
};
}
pushState(State.DICT_STATE, cur);
}
}
function leaveDict() {
if (state === State.DICT_STATE) {
popState();
} else if (state === State.ARR_STATE) {
return fail('unexpected </dict>');
} else { // ROOT_STATE
return fail('unexpected </dict>');
}
}
function enterArray() {
if (state === State.DICT_STATE) {
dictState.enterArray();
} else if (state === State.ARR_STATE) {
arrState.enterArray();
} else { // ROOT_STATE
cur = [];
pushState(State.ARR_STATE, cur);
}
}
function leaveArray() {
if (state === State.DICT_STATE) {
return fail('unexpected </array>');
} else if (state === State.ARR_STATE) {
popState();
} else { // ROOT_STATE
return fail('unexpected </array>');
}
}
function acceptKey(val: string) {
if (state === State.DICT_STATE) {
if (curKey !== null) {
return fail('too many <key>');
}
curKey = val;
} else if (state === State.ARR_STATE) {
return fail('unexpected <key>');
} else { // ROOT_STATE
return fail('unexpected <key>');
}
}
function acceptString(val: string) {
if (state === State.DICT_STATE) {
if (curKey === null) {
return fail('missing <key>');
}
cur[curKey] = val;
curKey = null;
} else if (state === State.ARR_STATE) {
cur.push(val);
} else { // ROOT_STATE
cur = val;
}
}
function acceptReal(val: number) {
if (isNaN(val)) {
return fail('cannot parse float');
}
if (state === State.DICT_STATE) {
if (curKey === null) {
return fail('missing <key>');
}
cur[curKey] = val;
curKey = null;
} else if (state === State.ARR_STATE) {
cur.push(val);
} else { // ROOT_STATE
cur = val;
}
}
function acceptInteger(val: number) {
if (isNaN(val)) {
return fail('cannot parse integer');
}
if (state === State.DICT_STATE) {
if (curKey === null) {
return fail('missing <key>');
}
cur[curKey] = val;
curKey = null;
} else if (state === State.ARR_STATE) {
cur.push(val);
} else { // ROOT_STATE
cur = val;
}
}
function acceptDate(val: Date) {
if (state === State.DICT_STATE) {
if (curKey === null) {
return fail('missing <key>');
}
cur[curKey] = val;
curKey = null;
} else if (state === State.ARR_STATE) {
cur.push(val);
} else { // ROOT_STATE
cur = val;
}
}
function acceptData(val: string) {
if (state === State.DICT_STATE) {
if (curKey === null) {
return fail('missing <key>');
}
cur[curKey] = val;
curKey = null;
} else if (state === State.ARR_STATE) {
cur.push(val);
} else { // ROOT_STATE
cur = val;
}
}
function acceptBool(val: boolean) {
if (state === State.DICT_STATE) {
if (curKey === null) {
return fail('missing <key>');
}
cur[curKey] = val;
curKey = null;
} else if (state === State.ARR_STATE) {
cur.push(val);
} else { // ROOT_STATE
cur = val;
}
}
function escapeVal(str: string): string {
return str.replace(/&#([0-9]+);/g, function (_: string, m0: string) {
return (<any>String).fromCodePoint(parseInt(m0, 10));
}).replace(/&#x([0-9a-f]+);/g, function (_: string, m0: string) {
return (<any>String).fromCodePoint(parseInt(m0, 16));
}).replace(/&amp;|&lt;|&gt;|&quot;|&apos;/g, function (_: string) {
switch (_) {
case '&amp;': return '&';
case '&lt;': return '<';
case '&gt;': return '>';
case '&quot;': return '"';
case '&apos;': return '\'';
}
return _;
});
}
interface IParsedTag {
name: string;
isClosed: boolean;
}
function parseOpenTag(): IParsedTag {
let r = captureUntil('>');
let isClosed = false;
if (r.charCodeAt(r.length - 1) === ChCode.SLASH) {
isClosed = true;
r = r.substring(0, r.length - 1);
}
return {
name: r.trim(),
isClosed: isClosed
};
}
function parseTagValue(tag: IParsedTag): string {
if (tag.isClosed) {
return '';
}
let val = captureUntil('</');
advanceUntil('>');
return escapeVal(val);
}
while (pos < len) {
skipWhitespace();
if (pos >= len) {
break;
}
const chCode = content.charCodeAt(pos);
advancePosBy(1);
if (chCode !== ChCode.LESS_THAN) {
return fail('expected <');
}
if (pos >= len) {
return fail('unexpected end of input');
}
const peekChCode = content.charCodeAt(pos);
if (peekChCode === ChCode.QUESTION_MARK) {
advancePosBy(1);
advanceUntil('?>');
continue;
}
if (peekChCode === ChCode.EXCLAMATION_MARK) {
advancePosBy(1);
if (advanceIfStartsWith('--')) {
advanceUntil('-->');
continue;
}
advanceUntil('>');
continue;
}
if (peekChCode === ChCode.SLASH) {
advancePosBy(1);
skipWhitespace();
if (advanceIfStartsWith('plist')) {
advanceUntil('>');
continue;
}
if (advanceIfStartsWith('dict')) {
advanceUntil('>');
leaveDict();
continue;
}
if (advanceIfStartsWith('array')) {
advanceUntil('>');
leaveArray();
continue;
}
return fail('unexpected closed tag');
}
let tag = parseOpenTag();
switch (tag.name) {
case 'dict':
enterDict();
if (tag.isClosed) {
leaveDict();
}
continue;
case 'array':
enterArray();
if (tag.isClosed) {
leaveArray();
}
continue;
case 'key':
acceptKey(parseTagValue(tag));
continue;
case 'string':
acceptString(parseTagValue(tag));
continue;
case 'real':
acceptReal(parseFloat(parseTagValue(tag)));
continue;
case 'integer':
acceptInteger(parseInt(parseTagValue(tag), 10));
continue;
case 'date':
acceptDate(new Date(parseTagValue(tag)));
continue;
case 'data':
acceptData(parseTagValue(tag));
continue;
case 'true':
parseTagValue(tag);
acceptBool(true);
continue;
case 'false':
parseTagValue(tag);
acceptBool(false);
continue;
}
if (/^plist/.test(tag.name)) {
continue;
}
return fail('unexpected opened tag ' + tag.name);
}
return cur;
}