diff --git a/.github/commands.yml b/.github/commands.yml index 8076f05fd1f..ba8c8d7f3ce 100644 --- a/.github/commands.yml +++ b/.github/commands.yml @@ -56,5 +56,11 @@ action: 'updateLabels', addLabel: 'confirmed' }, + { + type: 'comment', + name: 'findDuplicates', + action: 'comment', + comment: "Potential duplicates:\n${potentialDuplicates}" + }, ] } diff --git a/.github/similarity.yml b/.github/similarity.yml index 4ec8e6cc7d4..cd51cd2da64 100644 --- a/.github/similarity.yml +++ b/.github/similarity.yml @@ -1,5 +1,5 @@ { perform: true, whenCreatedByTeam: false, - comment: "Thanks for submitting this issue. Please also check if it is already covered by an existing one, like:\n${potentialDuplicates}" + comment: "(Experimental duplicate detection)\nThanks for submitting this issue. Please also check if it is already covered by an existing one, like:\n${potentialDuplicates}" } diff --git a/extensions/css/client/src/cssMain.ts b/extensions/css/client/src/cssMain.ts index 5cc90fff537..a8aaa53a18a 100644 --- a/extensions/css/client/src/cssMain.ts +++ b/extensions/css/client/src/cssMain.ts @@ -8,12 +8,9 @@ import * as path from 'path'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -import { languages, window, commands, ExtensionContext, TextDocument, ColorInformation, ColorPresentation, Color, Range, Position, CompletionItem, CompletionItemKind, TextEdit, SnippetString } from 'vscode'; +import { languages, window, commands, ExtensionContext, Range, Position, CompletionItem, CompletionItemKind, TextEdit, SnippetString } from 'vscode'; import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; -import { ConfigurationFeature } from 'vscode-languageclient/lib/configuration.proposed'; -import { DocumentColorRequest, DocumentColorParams, ColorPresentationRequest, ColorPresentationParams } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed'; - // this method is called when vs code is activated export function activate(context: ExtensionContext) { @@ -43,46 +40,13 @@ export function activate(context: ExtensionContext) { // Create the language client and start the client. let client = new LanguageClient('css', localize('cssserver.name', 'CSS Language Server'), serverOptions, clientOptions); - client.registerFeature(new ConfigurationFeature(client)); + client.registerProposedFeatures(); let disposable = client.start(); // Push the disposable to the context's subscriptions so that the // client can be deactivated on extension deactivation context.subscriptions.push(disposable); - client.onReady().then(_ => { - // register color provider - context.subscriptions.push(languages.registerColorProvider(documentSelector, { - provideDocumentColors(document: TextDocument): Thenable { - let params: DocumentColorParams = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document) - }; - return client.sendRequest(DocumentColorRequest.type, params).then(symbols => { - return symbols.map(symbol => { - let range = client.protocol2CodeConverter.asRange(symbol.range); - let color = new Color(symbol.color.red, symbol.color.green, symbol.color.blue, symbol.color.alpha); - return new ColorInformation(range, color); - }); - }); - }, - provideColorPresentations(color: Color, context): ColorPresentation[] | Thenable { - let params: ColorPresentationParams = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(context.document), - color, - range: client.code2ProtocolConverter.asRange(context.range) - }; - return client.sendRequest(ColorPresentationRequest.type, params).then(presentations => { - return presentations.map(p => { - let presentation = new ColorPresentation(p.label); - presentation.textEdit = p.textEdit && client.protocol2CodeConverter.asTextEdit(p.textEdit); - presentation.additionalTextEdits = p.additionalTextEdits && client.protocol2CodeConverter.asTextEdits(p.additionalTextEdits); - return presentation; - }); - }); - } - })); - }); - let indentationRules = { increaseIndentPattern: /(^.*\{[^}]*$)/, decreaseIndentPattern: /^\s*\}/ diff --git a/extensions/git/package.json b/extensions/git/package.json index 808b1cf9170..7b757fb21b8 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1026,7 +1026,7 @@ "byline": "^5.0.0", "file-type": "^7.2.0", "iconv-lite": "0.4.19", - "vscode-extension-telemetry": "0.0.12", + "vscode-extension-telemetry": "0.0.13", "vscode-nls": "^3.2.1", "which": "^1.3.0" }, diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index b1342318802..93801131a77 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -253,9 +253,9 @@ supports-color@3.1.2: dependencies: has-flag "^1.0.0" -vscode-extension-telemetry@0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.12.tgz#b3a93b72673bc485524770e0a32fcf493da07d85" +vscode-extension-telemetry@0.0.13: + version "0.0.13" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.13.tgz#8a4438cbb0a9f9f8ad65479e4ec08683aa4de0f7" dependencies: applicationinsights "1.0.1" diff --git a/extensions/html/client/src/htmlMain.ts b/extensions/html/client/src/htmlMain.ts index 107ac7ce11d..1ddf5f1b665 100644 --- a/extensions/html/client/src/htmlMain.ts +++ b/extensions/html/client/src/htmlMain.ts @@ -8,14 +8,12 @@ import * as path from 'path'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -import { languages, ExtensionContext, IndentAction, Position, TextDocument, Color, ColorInformation, ColorPresentation, Range, CompletionItem, CompletionItemKind, SnippetString } from 'vscode'; +import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString } from 'vscode'; import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, TextDocumentPositionParams } from 'vscode-languageclient'; import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared'; import { activateTagClosing } from './tagClosing'; import TelemetryReporter from 'vscode-extension-telemetry'; -import { DocumentColorRequest, DocumentColorParams, ColorPresentationRequest, ColorPresentationParams } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed'; - namespace TagCloseRequest { export const type: RequestType = new RequestType('html/tag'); } @@ -67,37 +65,6 @@ export function activate(context: ExtensionContext) { let disposable = client.start(); toDispose.push(disposable); client.onReady().then(() => { - disposable = languages.registerColorProvider(documentSelector, { - provideDocumentColors(document: TextDocument): Thenable { - let params: DocumentColorParams = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document) - }; - return client.sendRequest(DocumentColorRequest.type, params).then(symbols => { - return symbols.map(symbol => { - let range = client.protocol2CodeConverter.asRange(symbol.range); - let color = new Color(symbol.color.red, symbol.color.green, symbol.color.blue, symbol.color.alpha); - return new ColorInformation(range, color); - }); - }); - }, - provideColorPresentations(color, context): Thenable { - let params: ColorPresentationParams = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(context.document), - color, - range: client.code2ProtocolConverter.asRange(context.range) - }; - return client.sendRequest(ColorPresentationRequest.type, params).then(presentations => { - return presentations.map(p => { - let presentation = new ColorPresentation(p.label); - presentation.textEdit = p.textEdit && client.protocol2CodeConverter.asTextEdit(p.textEdit); - presentation.additionalTextEdits = p.additionalTextEdits && client.protocol2CodeConverter.asTextEdits(p.additionalTextEdits); - return presentation; - }); - }); - } - }); - toDispose.push(disposable); - let tagRequestor = (document: TextDocument, position: Position) => { let param = client.code2ProtocolConverter.asTextDocumentPositionParams(document, position); return client.sendRequest(TagCloseRequest.type, param); diff --git a/extensions/html/package.json b/extensions/html/package.json index bed34bf9f45..39231d83b13 100644 --- a/extensions/html/package.json +++ b/extensions/html/package.json @@ -226,7 +226,7 @@ } }, "dependencies": { - "vscode-extension-telemetry": "0.0.12", + "vscode-extension-telemetry": "0.0.13", "vscode-languageclient": "^4.0.0-next.9", "vscode-nls": "^3.2.1" }, diff --git a/extensions/html/yarn.lock b/extensions/html/yarn.lock index eb2e530e3af..293e9314996 100644 --- a/extensions/html/yarn.lock +++ b/extensions/html/yarn.lock @@ -28,9 +28,9 @@ semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" -vscode-extension-telemetry@0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.12.tgz#b3a93b72673bc485524770e0a32fcf493da07d85" +vscode-extension-telemetry@0.0.13: + version "0.0.13" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.13.tgz#8a4438cbb0a9f9f8ad65479e4ec08683aa4de0f7" dependencies: applicationinsights "1.0.1" diff --git a/extensions/json/package.json b/extensions/json/package.json index 95e0738922b..0c5dd480b2d 100644 --- a/extensions/json/package.json +++ b/extensions/json/package.json @@ -162,7 +162,7 @@ } }, "dependencies": { - "vscode-extension-telemetry": "0.0.12", + "vscode-extension-telemetry": "0.0.13", "vscode-languageclient": "^4.0.0-next.9", "vscode-nls": "^3.2.1" }, diff --git a/extensions/json/yarn.lock b/extensions/json/yarn.lock index eb2e530e3af..293e9314996 100644 --- a/extensions/json/yarn.lock +++ b/extensions/json/yarn.lock @@ -28,9 +28,9 @@ semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" -vscode-extension-telemetry@0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.12.tgz#b3a93b72673bc485524770e0a32fcf493da07d85" +vscode-extension-telemetry@0.0.13: + version "0.0.13" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.13.tgz#8a4438cbb0a9f9f8ad65479e4ec08683aa4de0f7" dependencies: applicationinsights "1.0.1" diff --git a/extensions/markdown/media/main.js b/extensions/markdown/media/main.js index 53ac317d851..42bac764d7a 100644 --- a/extensions/markdown/media/main.js +++ b/extensions/markdown/media/main.js @@ -155,9 +155,10 @@ if (previous) { if (next) { const betweenProgress = (offset - window.scrollY - previous.element.getBoundingClientRect().top) / (next.element.getBoundingClientRect().top - previous.element.getBoundingClientRect().top); - return previous.line + betweenProgress * (next.line - previous.line); + const line = previous.line + betweenProgress * (next.line - previous.line); + return Math.max(line, 0); } else { - return previous.line; + return Math.max(previous.line, 0); } } return null; @@ -232,7 +233,7 @@ } // Ignore clicks on links - for (let node = event.target; node; node = node.parentNode) { + for (let node = /** @type {HTMLElement} */(event.target); node; node = /** @type {HTMLElement} */(node.parentNode)) { if (node.tagName === "A") { return; } @@ -255,13 +256,13 @@ /** @type {*} */ let node = event.target; while (node) { - if (node.tagName && node.tagName.toLowerCase() === 'a' && node.href) { + if (node.tagName && node.tagName === 'A' && node.href) { if (node.getAttribute('href').startsWith('#')) { break; } - if (node.href.startsWith('file://')) { - const [path, fragment] = node.href.replace(/^file:\/\//i, '').split('#'); - postMessage('_markdown.openDocumentLink', { path, fragment }); + if (node.href.startsWith('file://') || node.href.startsWith('vscode-workspace-resource:')) { + const [path, fragment] = node.href.replace(/^(file:\/\/|vscode-workspace-resource:)/i, '').split('#'); + postMessage('_markdown.openDocumentLink', [{ path, fragment }]); event.preventDefault(); event.stopPropagation(); break; diff --git a/extensions/markdown/package.json b/extensions/markdown/package.json index 99ce9bedd46..a3b4df103e1 100644 --- a/extensions/markdown/package.json +++ b/extensions/markdown/package.json @@ -314,7 +314,7 @@ "highlight.js": "9.5.0", "markdown-it": "^8.4.0", "markdown-it-named-headers": "0.0.4", - "vscode-extension-telemetry": "^0.0.12", + "vscode-extension-telemetry": "^0.0.13", "vscode-nls": "^3.2.1" }, "devDependencies": { diff --git a/extensions/markdown/yarn.lock b/extensions/markdown/yarn.lock index 61798cfa83d..6a725e5ec59 100644 --- a/extensions/markdown/yarn.lock +++ b/extensions/markdown/yarn.lock @@ -1743,9 +1743,9 @@ vinyl@~2.0.1: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" -vscode-extension-telemetry@^0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.12.tgz#b3a93b72673bc485524770e0a32fcf493da07d85" +vscode-extension-telemetry@^0.0.13: + version "0.0.13" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.13.tgz#8a4438cbb0a9f9f8ad65479e4ec08683aa4de0f7" dependencies: applicationinsights "1.0.1" diff --git a/extensions/merge-conflict/package.json b/extensions/merge-conflict/package.json index 739eb66f0ed..cd4de32ff61 100644 --- a/extensions/merge-conflict/package.json +++ b/extensions/merge-conflict/package.json @@ -99,7 +99,7 @@ } }, "dependencies": { - "vscode-extension-telemetry": "0.0.12", + "vscode-extension-telemetry": "0.0.13", "vscode-nls": "^3.2.1" }, "devDependencies": { diff --git a/extensions/merge-conflict/yarn.lock b/extensions/merge-conflict/yarn.lock index 7d01dc5cbd7..30b8b37fab8 100644 --- a/extensions/merge-conflict/yarn.lock +++ b/extensions/merge-conflict/yarn.lock @@ -28,9 +28,9 @@ semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" -vscode-extension-telemetry@0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.12.tgz#b3a93b72673bc485524770e0a32fcf493da07d85" +vscode-extension-telemetry@0.0.13: + version "0.0.13" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.13.tgz#8a4438cbb0a9f9f8ad65479e4ec08683aa4de0f7" dependencies: applicationinsights "1.0.1" diff --git a/extensions/typescript/package.json b/extensions/typescript/package.json index 4fd18ae4e55..45bd4019079 100644 --- a/extensions/typescript/package.json +++ b/extensions/typescript/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "semver": "4.3.6", - "vscode-extension-telemetry": "^0.0.12", + "vscode-extension-telemetry": "^0.0.13", "vscode-nls": "^3.2.1" }, "devDependencies": { diff --git a/extensions/typescript/src/features/completionItemProvider.ts b/extensions/typescript/src/features/completionItemProvider.ts index 485f0bb2029..293b2c9cac1 100644 --- a/extensions/typescript/src/features/completionItemProvider.ts +++ b/extensions/typescript/src/features/completionItemProvider.ts @@ -464,7 +464,8 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP let hasAddedParameters = false; const snippet = new SnippetString(); - snippet.appendText(item.label || item.insertText as string); + const methodName = detail.displayParts.find(part => part.kind === 'methodName'); + snippet.appendText((methodName && methodName.text) || item.label || item.insertText as string); snippet.appendText('('); let parenCount = 0; diff --git a/extensions/typescript/src/features/jsDocCompletionProvider.ts b/extensions/typescript/src/features/jsDocCompletionProvider.ts index ab515a9a074..34963657b28 100644 --- a/extensions/typescript/src/features/jsDocCompletionProvider.ts +++ b/extensions/typescript/src/features/jsDocCompletionProvider.ts @@ -170,6 +170,12 @@ class TryCompleteJsDocCommand implements Command { if (!res || !res.body) { return undefined; } + // Workaround for #43619 + // docCommentTemplate previously returned undefined for empty jsdoc templates. + // TS 2.7 now returns a single line doc comment, which breaks indentation. + if (res.body.newText === '/** */') { + return undefined; + } return TryCompleteJsDocCommand.templateToSnippet(res.body.newText); }, () => undefined); } diff --git a/extensions/typescript/yarn.lock b/extensions/typescript/yarn.lock index 858a1816905..bf3aa153c3e 100644 --- a/extensions/typescript/yarn.lock +++ b/extensions/typescript/yarn.lock @@ -36,9 +36,9 @@ semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" -vscode-extension-telemetry@^0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.12.tgz#b3a93b72673bc485524770e0a32fcf493da07d85" +vscode-extension-telemetry@^0.0.13: + version "0.0.13" + resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.13.tgz#8a4438cbb0a9f9f8ad65479e4ec08683aa4de0f7" dependencies: applicationinsights "1.0.1" diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 8bb4ed5e331..13951c0ec24 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -251,41 +251,26 @@ export function addDisposableNonBubblingMouseOutListener(node: Element, handler: }); } -const _animationFrame = (function () { - let emulatedRequestAnimationFrame = (callback: (time: number) => void): number => { - return setTimeout(() => callback(new Date().getTime()), 0); - }; - let nativeRequestAnimationFrame: (callback: (time: number) => void) => number = - self.requestAnimationFrame - || (self).msRequestAnimationFrame - || (self).webkitRequestAnimationFrame - || (self).mozRequestAnimationFrame - || (self).oRequestAnimationFrame; - - - - let emulatedCancelAnimationFrame = (id: number) => { }; - let nativeCancelAnimationFrame: (id: number) => void = - self.cancelAnimationFrame || (self).cancelRequestAnimationFrame - || (self).msCancelAnimationFrame || (self).msCancelRequestAnimationFrame - || (self).webkitCancelAnimationFrame || (self).webkitCancelRequestAnimationFrame - || (self).mozCancelAnimationFrame || (self).mozCancelRequestAnimationFrame - || (self).oCancelAnimationFrame || (self).oCancelRequestAnimationFrame; - - let isNative = !!nativeRequestAnimationFrame; - let request = nativeRequestAnimationFrame || emulatedRequestAnimationFrame; - let cancel = nativeCancelAnimationFrame || emulatedCancelAnimationFrame; - - return { - isNative: isNative, - request: (callback: (time: number) => void): number => { - return request(callback); - }, - cancel: (id: number) => { - return cancel(id); - } - }; -})(); +interface IRequestAnimationFrame { + (callback: (time: number) => void): number; +} +let _animationFrame: IRequestAnimationFrame = null; +function doRequestAnimationFrame(callback: (time: number) => void): number { + if (!_animationFrame) { + const emulatedRequestAnimationFrame = (callback: (time: number) => void): number => { + return setTimeout(() => callback(new Date().getTime()), 0); + }; + _animationFrame = ( + self.requestAnimationFrame + || (self).msRequestAnimationFrame + || (self).webkitRequestAnimationFrame + || (self).mozRequestAnimationFrame + || (self).oRequestAnimationFrame + || emulatedRequestAnimationFrame + ); + } + return _animationFrame(callback); +} /** * Schedule a callback to be run at the next animation frame. @@ -375,7 +360,7 @@ class AnimationFrameQueueItem implements IDisposable { if (!animFrameRequested) { animFrameRequested = true; - _animationFrame.request(animationFrameRunner); + doRequestAnimationFrame(animationFrameRunner); } return item; @@ -662,7 +647,13 @@ export function createStyleSheet(container: HTMLElement = document.getElementsBy return style; } -const sharedStyle = createStyleSheet(); +let _sharedStyleSheet: HTMLStyleElement = null; +function getSharedStyleSheet(): HTMLStyleElement { + if (!_sharedStyleSheet) { + _sharedStyleSheet = createStyleSheet(); + } + return _sharedStyleSheet; +} function getDynamicStyleSheetRules(style: any) { if (style && style.sheet && style.sheet.rules) { @@ -676,7 +667,7 @@ function getDynamicStyleSheetRules(style: any) { return []; } -export function createCSSRule(selector: string, cssText: string, style: HTMLStyleElement = sharedStyle): void { +export function createCSSRule(selector: string, cssText: string, style: HTMLStyleElement = getSharedStyleSheet()): void { if (!style || !cssText) { return; } @@ -684,7 +675,7 @@ export function createCSSRule(selector: string, cssText: string, style: HTMLStyl (style.sheet).insertRule(selector + '{' + cssText + '}', 0); } -export function removeCSSRulesContainingSelector(ruleName: string, style = sharedStyle): void { +export function removeCSSRulesContainingSelector(ruleName: string, style: HTMLStyleElement = getSharedStyleSheet()): void { if (!style) { return; } @@ -699,7 +690,7 @@ export function removeCSSRulesContainingSelector(ruleName: string, style = share } for (let i = toDelete.length - 1; i >= 0; i--) { - style.sheet.deleteRule(toDelete[i]); + (style.sheet).deleteRule(toDelete[i]); } } diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index f92114291d6..c5fd25c7269 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -462,15 +462,18 @@ class MouseController implements IDisposable { } let reference = this.list.getFocus()[0]; - reference = reference === undefined ? this.list.getSelection()[0] : reference; + const selection = this.list.getSelection(); + reference = reference === undefined ? selection[0] : reference; + + const focus = e.index; + if (selection.every(s => s !== focus)) { + this.list.setFocus([focus]); + } if (this.multipleSelectionSupport && this.isSelectionRangeChangeEvent(e)) { return this.changeSelection(e, reference); } - const focus = e.index; - this.list.setFocus([focus]); - if (this.multipleSelectionSupport && this.isSelectionChangeEvent(e)) { return this.changeSelection(e, reference); } diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index 93c6dda80c2..34247aa7796 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -6,7 +6,6 @@ 'use strict'; import * as errors from 'vs/base/common/errors'; -import * as platform from 'vs/base/common/platform'; import { Promise, TPromise, ValueCallback, ErrorCallback, ProgressCallback } from 'vs/base/common/winjs.base'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; @@ -525,7 +524,7 @@ export function setDisposableTimeout(handler: Function, timeout: number, ...args } export class TimeoutTimer extends Disposable { - private _token: platform.TimeoutToken; + private _token: number; constructor() { super(); @@ -539,14 +538,14 @@ export class TimeoutTimer extends Disposable { cancel(): void { if (this._token !== -1) { - platform.clearTimeout(this._token); + clearTimeout(this._token); this._token = -1; } } cancelAndSet(runner: () => void, timeout: number): void { this.cancel(); - this._token = platform.setTimeout(() => { + this._token = setTimeout(() => { this._token = -1; runner(); }, timeout); @@ -557,7 +556,7 @@ export class TimeoutTimer extends Disposable { // timer is already set return; } - this._token = platform.setTimeout(() => { + this._token = setTimeout(() => { this._token = -1; runner(); }, timeout); @@ -566,7 +565,7 @@ export class TimeoutTimer extends Disposable { export class IntervalTimer extends Disposable { - private _token: platform.IntervalToken; + private _token: number; constructor() { super(); @@ -580,14 +579,14 @@ export class IntervalTimer extends Disposable { cancel(): void { if (this._token !== -1) { - platform.clearInterval(this._token); + clearInterval(this._token); this._token = -1; } } cancelAndSet(runner: () => void, interval: number): void { this.cancel(); - this._token = platform.setInterval(() => { + this._token = setInterval(() => { runner(); }, interval); } @@ -595,7 +594,7 @@ export class IntervalTimer extends Disposable { export class RunOnceScheduler { - private timeoutToken: platform.TimeoutToken; + private timeoutToken: number; private runner: () => void; private timeout: number; private timeoutHandler: () => void; @@ -620,7 +619,7 @@ export class RunOnceScheduler { */ cancel(): void { if (this.isScheduled()) { - platform.clearTimeout(this.timeoutToken); + clearTimeout(this.timeoutToken); this.timeoutToken = -1; } } @@ -630,7 +629,7 @@ export class RunOnceScheduler { */ schedule(delay = this.timeout): void { this.cancel(); - this.timeoutToken = platform.setTimeout(this.timeoutHandler, delay); + this.timeoutToken = setTimeout(this.timeoutHandler, delay); } /** diff --git a/src/vs/base/common/diagnostics.ts b/src/vs/base/common/diagnostics.ts index 66c522cb3a7..7ad7daa18d4 100644 --- a/src/vs/base/common/diagnostics.ts +++ b/src/vs/base/common/diagnostics.ts @@ -62,7 +62,7 @@ export function register(what: string, fn: Function): (...args: any[]) => void { const thisArguments = allArgs.shift(); fn.apply(fn, thisArguments); if (allArgs.length > 0) { - Platform.setTimeout(doIt, 500); + setTimeout(doIt, 500); } }; doIt(); diff --git a/src/vs/base/common/errors.ts b/src/vs/base/common/errors.ts index 1d3502e4801..a3dfa070fb9 100644 --- a/src/vs/base/common/errors.ts +++ b/src/vs/base/common/errors.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import platform = require('vs/base/common/platform'); import types = require('vs/base/common/types'); import { IAction } from 'vs/base/common/actions'; import Severity from 'vs/base/common/severity'; @@ -79,7 +78,7 @@ export class ErrorHandler { this.listeners = []; this.unexpectedErrorHandler = function (e: any) { - platform.setTimeout(() => { + setTimeout(() => { if (e.stack) { throw new Error(e.message + '\n\n' + e.stack); } diff --git a/src/vs/base/common/performance.js b/src/vs/base/common/performance.js index a7ebc4c627c..a2646638ed0 100644 --- a/src/vs/base/common/performance.js +++ b/src/vs/base/common/performance.js @@ -11,7 +11,6 @@ // Because we want both instances to use the same perf-data // we store them globally // stores data as 'type','name','startTime','duration' -global._performanceEntries = global._performanceEntries || []; if (typeof define !== "function" && typeof module === "object" && typeof module.exports === "object") { // this is commonjs, fake amd @@ -23,6 +22,12 @@ if (typeof define !== "function" && typeof module === "object" && typeof module. define([], function () { + var _global = this; + if (typeof global !== 'undefined') { + _global = global; + } + _global._performanceEntries = _global._performanceEntries || []; + // const _now = global.performance && performance.now ? performance.now : Date.now const _now = Date.now; diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index 0306de78a92..5bee1d98f35 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -4,12 +4,9 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -// --- THIS FILE IS TEMPORARY UNTIL ENV.TS IS CLEANED UP. IT CAN SAFELY BE USED IN ALL TARGET EXECUTION ENVIRONMENTS (node & dom) --- - let _isWindows = false; let _isMacintosh = false; let _isLinux = false; -let _isRootUser = false; let _isNative = false; let _isWeb = false; let _locale: string = undefined; @@ -48,12 +45,11 @@ if (typeof process === 'object') { _isWindows = (process.platform === 'win32'); _isMacintosh = (process.platform === 'darwin'); _isLinux = (process.platform === 'linux'); - _isRootUser = !_isWindows && (process.getuid() === 0); - let rawNlsConfig = process.env['VSCODE_NLS_CONFIG']; + const rawNlsConfig = process.env['VSCODE_NLS_CONFIG']; if (rawNlsConfig) { try { - let nlsConfig: NLSConfig = JSON.parse(rawNlsConfig); - let resolved = nlsConfig.availableLanguages['*']; + const nlsConfig: NLSConfig = JSON.parse(rawNlsConfig); + const resolved = nlsConfig.availableLanguages['*']; _locale = nlsConfig.locale; // VSCode's default language is 'en' _language = resolved ? resolved : LANGUAGE_DEFAULT; @@ -63,7 +59,7 @@ if (typeof process === 'object') { } _isNative = true; } else if (typeof navigator === 'object') { - let userAgent = navigator.userAgent; + const userAgent = navigator.userAgent; _isWindows = userAgent.indexOf('Windows') >= 0; _isMacintosh = userAgent.indexOf('Macintosh') >= 0; _isLinux = userAgent.indexOf('Linux') >= 0; @@ -93,11 +89,14 @@ if (_isNative) { export const isWindows = _isWindows; export const isMacintosh = _isMacintosh; export const isLinux = _isLinux; -export const isRootUser = _isRootUser; export const isNative = _isNative; export const isWeb = _isWeb; export const platform = _platform; +export function isRootUser(): boolean { + return _isNative && !_isWindows && (process.getuid() === 0); +} + /** * The language used for the user interface. The format of * the string is all lower case (e.g. zh-tw for Traditional @@ -117,30 +116,9 @@ export const locale = _locale; */ export const translationsConfigFile = _translationsConfigFile; -export interface TimeoutToken { -} - -export interface IntervalToken { -} - -interface IGlobals { - Worker?: any; - setTimeout(callback: (...args: any[]) => void, delay: number, ...args: any[]): TimeoutToken; - clearTimeout(token: TimeoutToken): void; - - setInterval(callback: (...args: any[]) => void, delay: number, ...args: any[]): IntervalToken; - clearInterval(token: IntervalToken): void; -} - -const _globals = (typeof self === 'object' ? self : global); +const _globals = (typeof self === 'object' ? self : typeof global === 'object' ? global : {} as any); export const globals: any = _globals; -export const setTimeout = _globals.setTimeout.bind(_globals); -export const clearTimeout = _globals.clearTimeout.bind(_globals); - -export const setInterval = _globals.setInterval.bind(_globals); -export const clearInterval = _globals.clearInterval.bind(_globals); - export const enum OperatingSystem { Windows = 1, Macintosh = 2, diff --git a/src/vs/base/common/winjs.base.raw.js b/src/vs/base/common/winjs.base.raw.js index 0ffe0bc96cc..d827548303e 100644 --- a/src/vs/base/common/winjs.base.raw.js +++ b/src/vs/base/common/winjs.base.raw.js @@ -7,7 +7,7 @@ */ (function() { -var _modules = {}; +var _modules = Object.create(null);//{}; _modules["WinJS/Core/_WinJS"] = {}; var _winjs = function(moduleId, deps, factory) { @@ -64,11 +64,24 @@ _winjs("WinJS/Core/_BaseCoreUtils", ["WinJS/Core/_Global"], function baseCoreUti return func; } + var actualSetImmediate = null; + return { hasWinRT: hasWinRT, markSupportedForProcessing: markSupportedForProcessing, - _setImmediate: _Global.setImmediate ? _Global.setImmediate.bind(_Global) : function (handler) { - _Global.setTimeout(handler, 0); + _setImmediate: function (callback) { + // BEGIN monaco change + if (actualSetImmediate === null) { + if (_Global.setImmediate) { + actualSetImmediate = _Global.setImmediate.bind(_Global); + } else if (typeof process !== 'undefined' && typeof process.nextTick === 'function') { + actualSetImmediate = process.nextTick.bind(process); + } else { + actualSetImmediate = _Global.setTimeout.bind(_Global); + } + } + actualSetImmediate(callback); + // END monaco change } }; }); @@ -2057,15 +2070,9 @@ _winjs("WinJS/Promise", ["WinJS/Core/_Base","WinJS/Promise/_StateMachine"], func var exported = _modules["WinJS/Core/_WinJS"]; if (typeof exports === 'undefined' && typeof define === 'function' && define.amd) { - define(exported); + define([], exported); } else { module.exports = exported; } -if (typeof process !== 'undefined' && typeof process.nextTick === 'function') { - _modules["WinJS/Core/_BaseCoreUtils"]._setImmediate = function(handler) { - return process.nextTick(handler); - }; -} - -})(); \ No newline at end of file +})(); diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index 415660a12fe..ed06f5e3d63 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -339,13 +339,6 @@ export class SimpleWorkerServer { delete loaderConfig.paths['vs']; } } - let nlsConfig = loaderConfig['vs/nls']; - // We need to have pseudo translation - if (nlsConfig && nlsConfig.pseudo) { - require(['vs/nls'], function (nlsPlugin) { - nlsPlugin.setPseudoTranslation(nlsConfig.pseudo); - }); - } // Since this is in a web worker, enable catching errors loaderConfig.catchError = true; diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index 5fdb5cb0264..c16be6ca58d 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -161,8 +161,14 @@ export function fileExists(path: string): TPromise { /** * Deletes a path from disk. */ -const tmpDir = os.tmpdir(); -export function del(path: string, tmp = tmpDir): TPromise { +let _tmpDir: string = null; +function getTmpDir(): string { + if (!_tmpDir) { + _tmpDir = os.tmpdir(); + } + return _tmpDir; +} +export function del(path: string, tmp = getTmpDir()): TPromise { return nfcall(extfs.del, path, tmp); } @@ -185,4 +191,4 @@ export function whenDeleted(path: string): TPromise { } }, 1000); }); -} \ No newline at end of file +} diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts index 7aa6034bba6..32ee843b5ae 100644 --- a/src/vs/base/node/processes.ts +++ b/src/vs/base/node/processes.ts @@ -6,9 +6,6 @@ import path = require('path'); import * as cp from 'child_process'; -import ChildProcess = cp.ChildProcess; -import exec = cp.exec; -import spawn = cp.spawn; import { fork } from 'vs/base/node/stdFork'; import nls = require('vs/nls'); import { PPromise, TPromise, TValueCallback, TProgressCallback, ErrorCallback } from 'vs/base/common/winjs.base'; @@ -40,7 +37,7 @@ function getWindowsCode(status: number): TerminateResponseCode { } } -export function terminateProcess(process: ChildProcess, cwd?: string): TerminateResponse { +export function terminateProcess(process: cp.ChildProcess, cwd?: string): TerminateResponse { if (Platform.isWindows) { try { let options: any = { @@ -80,8 +77,8 @@ export abstract class AbstractProcess { private options: CommandOptions | ForkOptions; protected shell: boolean; - private childProcess: ChildProcess; - protected childProcessPromise: TPromise; + private childProcess: cp.ChildProcess; + protected childProcessPromise: TPromise; protected terminateRequested: boolean; private static WellKnowCommands: IStringDictionary = { @@ -173,7 +170,7 @@ export abstract class AbstractProcess { if (this.args) { cmd = cmd + ' ' + this.args.join(' '); } - this.childProcess = exec(cmd, this.options, (error, stdout, stderr) => { + this.childProcess = cp.exec(cmd, this.options, (error, stdout, stderr) => { this.childProcess = null; let err: any = error; // This is tricky since executing a command shell reports error back in case the executed command return an @@ -186,7 +183,7 @@ export abstract class AbstractProcess { } }); } else { - let childProcess: ChildProcess = null; + let childProcess: cp.ChildProcess = null; let closeHandler = (data: any) => { this.childProcess = null; this.childProcessPromise = null; @@ -231,13 +228,13 @@ export abstract class AbstractProcess { } else { args.push(commandLine.join(' ')); } - childProcess = spawn(getWindowsShell(), args, options); + childProcess = cp.spawn(getWindowsShell(), args, options); } else { if (this.cmd) { - childProcess = spawn(this.cmd, this.args, this.options); + childProcess = cp.spawn(this.cmd, this.args, this.options); } else if (this.module) { - this.childProcessPromise = new TPromise((c, e, p) => { - fork(this.module, this.args, this.options, (error: any, childProcess: ChildProcess) => { + this.childProcessPromise = new TPromise((c, e, p) => { + fork(this.module, this.args, this.options, (error: any, childProcess: cp.ChildProcess) => { if (error) { e(error); ee({ terminated: this.terminateRequested, error: error }); @@ -269,7 +266,7 @@ export abstract class AbstractProcess { } protected abstract handleExec(cc: TValueCallback, pp: TProgressCallback, error: Error, stdout: Buffer, stderr: Buffer): void; - protected abstract handleSpawn(childProcess: ChildProcess, cc: TValueCallback, pp: TProgressCallback, ee: ErrorCallback, sync: boolean): void; + protected abstract handleSpawn(childProcess: cp.ChildProcess, cc: TValueCallback, pp: TProgressCallback, ee: ErrorCallback, sync: boolean): void; protected handleClose(data: any, cc: TValueCallback, pp: TProgressCallback, ee: ErrorCallback): void { // Default is to do nothing. @@ -315,7 +312,7 @@ export abstract class AbstractProcess { if (!this.shell || !Platform.isWindows) { c(false); } - let cmdShell = spawn(getWindowsShell(), ['/s', '/c']); + let cmdShell = cp.spawn(getWindowsShell(), ['/s', '/c']); cmdShell.on('error', (error: Error) => { c(true); }); @@ -353,7 +350,7 @@ export class LineProcess extends AbstractProcess { cc({ terminated: this.terminateRequested, error: error }); } - protected handleSpawn(childProcess: ChildProcess, cc: TValueCallback, pp: TProgressCallback, ee: ErrorCallback, sync: boolean): void { + protected handleSpawn(childProcess: cp.ChildProcess, cc: TValueCallback, pp: TProgressCallback, ee: ErrorCallback, sync: boolean): void { this.stdoutLineDecoder = new LineDecoder(); this.stderrLineDecoder = new LineDecoder(); childProcess.stdout.on('data', (data: Buffer) => { @@ -384,7 +381,7 @@ export interface IQueuedSender { // queue is free again to consume messages. // On Windows we always wait for the send() method to return before sending the next message // to workaround https://github.com/nodejs/node/issues/7657 (IPC can freeze process) -export function createQueuedSender(childProcess: ChildProcess | NodeJS.Process): IQueuedSender { +export function createQueuedSender(childProcess: cp.ChildProcess | NodeJS.Process): IQueuedSender { let msgQueue: string[] = []; let useQueue = false; diff --git a/src/vs/code/electron-browser/issue/issueReporter.js b/src/vs/code/electron-browser/issue/issueReporter.js index 07e8b8663d7..01d097357b0 100644 --- a/src/vs/code/electron-browser/issue/issueReporter.js +++ b/src/vs/code/electron-browser/issue/issueReporter.js @@ -146,6 +146,8 @@ function main() { // In the bundled version the nls plugin is packaged with the loader so the NLS Plugins // loads as soon as the loader loads. To be able to have pseudo translation createScript(rootUrl + '/vs/loader.js', function () { + var define = global.define; + global.define = undefined; define('fs', ['original-fs'], function (originalFS) { return originalFS; }); // replace the patched electron fs with the original node fs for all AMD code window.MonacoEnvironment = {}; diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index d4508cc68b8..d4845ccf973 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -67,6 +67,7 @@ export class IssueReporter extends Disposable { private logService: ILogService; private issueReporterModel: IssueReporterModel; private shouldQueueSearch = true; + private numberOfSearchResultsDisplayed = 0; private features: IssueReporterFeatures; private receivedSystemInfo = false; private receivedPerformanceInfo = false; @@ -187,15 +188,15 @@ export class IssueReporter extends Disposable { } if (styles.sliderBackgroundColor) { - content.push(`.issues-container::-webkit-scrollbar-thumb, body::-webkit-scrollbar-thumb { background-color: ${styles.sliderBackgroundColor}; }`); + content.push(`::-webkit-scrollbar-thumb { background-color: ${styles.sliderBackgroundColor}; }`); } if (styles.sliderActiveColor) { - content.push(`.issues-container::-webkit-scrollbar-thumb:active, body::-webkit-scrollbar-thumb:active { background-color: ${styles.sliderActiveColor}; }`); + content.push(`::-webkit-scrollbar-thumb:active { background-color: ${styles.sliderActiveColor}; }`); } if (styles.sliderHoverColor) { - content.push(`.issues-container::-webkit-scrollbar-thumb:hover, body::-webkit-scrollbar-thumb:hover { background-color: ${styles.sliderHoverColor}; }`); + content.push(`::--webkit-scrollbar-thumb:hover { background-color: ${styles.sliderHoverColor}; }`); } styleTag.innerHTML = content.join('\n'); @@ -444,6 +445,7 @@ export class IssueReporter extends Disposable { private clearSearchResults(): void { const similarIssues = document.getElementById('similar-issues'); similarIssues.innerHTML = ''; + this.numberOfSearchResultsDisplayed = 0; } @debounce(300) @@ -520,8 +522,8 @@ export class IssueReporter extends Disposable { const issuesText = $('div.list-title'); issuesText.textContent = localize('similarIssues', "Similar issues"); - const numResultsToDisplay = results.length < 5 ? results.length : 5; - for (let i = 0; i < numResultsToDisplay; i++) { + this.numberOfSearchResultsDisplayed = results.length < 5 ? results.length : 5; + for (let i = 0; i < this.numberOfSearchResultsDisplayed; i++) { const issue = results[i]; const link = issue.state ? $('a.issue-link', { href: issue.html_url }) : $('a', { href: issue.html_url }); link.textContent = issue.title; @@ -676,14 +678,13 @@ export class IssueReporter extends Disposable { return false; } - if (this.telemetryService) { - /* __GDPR__ - "issueReporterSubmit" : { - "issueType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('issueReporterSubmit', { issueType: this.issueReporterModel.getData().issueType }); - } + /* __GDPR__ + "issueReporterSubmit" : { + "issueType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "numSimilarIssuesDisplayed" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('issueReporterSubmit', { issueType: this.issueReporterModel.getData().issueType, numSimilarIssuesDisplayed: this.numberOfSearchResultsDisplayed }); const issueTitle = encodeURIComponent((document.getElementById('issue-title')).value); const queryStringPrefix = product.reportIssueUrl.indexOf('?') === -1 ? '?' : '&'; diff --git a/src/vs/code/electron-browser/issue/issueReporterModel.ts b/src/vs/code/electron-browser/issue/issueReporterModel.ts index 1669eaeebe2..fec01f2d9e7 100644 --- a/src/vs/code/electron-browser/issue/issueReporterModel.ts +++ b/src/vs/code/electron-browser/issue/issueReporterModel.ts @@ -73,7 +73,8 @@ ${this._data.issueDescription} VS Code version: ${this._data.versionInfo && this._data.versionInfo.vscodeVersion} OS version: ${this._data.versionInfo && this._data.versionInfo.os} -${this.getInfos()}`; +${this.getInfos()} +`; } private getIssueTypeTitle(): string { diff --git a/src/vs/code/electron-browser/issue/media/issueReporter.css b/src/vs/code/electron-browser/issue/media/issueReporter.css index 8f1de9a6a4d..8a6158c0f04 100644 --- a/src/vs/code/electron-browser/issue/media/issueReporter.css +++ b/src/vs/code/electron-browser/issue/media/issueReporter.css @@ -116,6 +116,7 @@ html { body { margin: 0; + overflow: scroll; } .hidden { @@ -223,16 +224,11 @@ summary { .include-data { display: inline-block; - position: relative; } .include-data > .caption { display: inline-block; font-size: 12px; - position: absolute; - width: 80px; - top: 2px; - left: 30px; cursor: pointer; } @@ -263,9 +259,12 @@ input:disabled { margin-top: .5em; } +.workbenchCommand { + cursor: pointer; +} .workbenchCommand:disabled { color: #868e96; - cursor: pointer; + cursor: default } .block-extensions .block-info { @@ -303,6 +302,7 @@ button { #issue-type { width: calc(100% - 100px); + cursor: pointer; } #issue-title-label { @@ -348,14 +348,18 @@ button { } } -.issues-container::-webkit-scrollbar, body::-webkit-scrollbar { +::-webkit-scrollbar { width: 14px; } -.issues-container::-webkit-scrollbar, body::-webkit-scrollbar-thumb { +::-webkit-scrollbar-thumb { min-height: 20px; } +::-webkit-scrollbar-corner { + display: none; +} + .issues-container { margin-top: .5em; height: 108px; @@ -397,4 +401,4 @@ div.issues-container { .issues-container > .issue > .issue-state .octicon { padding-right: 5px; -} \ No newline at end of file +} diff --git a/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts b/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts index f9a885220cb..eaeb2ae6de4 100644 --- a/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts +++ b/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts @@ -39,6 +39,7 @@ undefined VS Code version: undefined OS version: undefined -`); + +`); }); }); diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcess.js b/src/vs/code/electron-browser/sharedProcess/sharedProcess.js index b4e968d7990..ffc640718d0 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcess.js +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcess.js @@ -131,6 +131,8 @@ function main() { // In the bundled version the nls plugin is packaged with the loader so the NLS Plugins // loads as soon as the loader loads. To be able to have pseudo translation createScript(rootUrl + '/vs/loader.js', function () { + var define = global.define; + global.define = undefined; define('fs', ['original-fs'], function (originalFS) { return originalFS; }); // replace the patched electron fs with the original node fs for all AMD code window.MonacoEnvironment = {}; diff --git a/src/vs/css.js b/src/vs/css.js index ae281dacb7b..4a2d5a4d299 100644 --- a/src/vs/css.js +++ b/src/vs/css.js @@ -20,7 +20,7 @@ var CSSLoaderPlugin; * Known issue: * - In IE there is no way to know if the CSS file loaded successfully or not. */ - var BrowserCSSLoader = (function () { + var BrowserCSSLoader = /** @class */ (function () { function BrowserCSSLoader() { this._pendingLoads = 0; } @@ -93,7 +93,7 @@ var CSSLoaderPlugin; return BrowserCSSLoader; }()); // ------------------------------ Finally, the plugin - var CSSPlugin = (function () { + var CSSPlugin = /** @class */ (function () { function CSSPlugin() { this._cssLoader = new BrowserCSSLoader(); } @@ -110,12 +110,5 @@ var CSSLoaderPlugin; return CSSPlugin; }()); CSSLoaderPlugin.CSSPlugin = CSSPlugin; - function init() { - define('vs/css', new CSSPlugin()); - } - CSSLoaderPlugin.init = init; - ; - if (typeof doNotInitLoader === 'undefined') { - init(); - } + define('vs/css', new CSSPlugin()); })(CSSLoaderPlugin || (CSSLoaderPlugin = {})); diff --git a/src/vs/editor/browser/services/bulkEdit.ts b/src/vs/editor/browser/services/bulkEdit.ts index cded7ca6be5..6753f7bb6e1 100644 --- a/src/vs/editor/browser/services/bulkEdit.ts +++ b/src/vs/editor/browser/services/bulkEdit.ts @@ -271,7 +271,7 @@ export class BulkEdit { constructor( editor: ICodeEditor, progress: IProgressRunner, - @ITextModelService private _textModelService: ITextModelService, + @ITextModelService private readonly _textModelService: ITextModelService, @optional(IFileService) private _fileService: IFileService ) { this._editor = editor; diff --git a/src/vs/editor/common/core/stringBuilder.ts b/src/vs/editor/common/core/stringBuilder.ts index ff9ec2bedfc..e49d40e4d63 100644 --- a/src/vs/editor/common/core/stringBuilder.ts +++ b/src/vs/editor/common/core/stringBuilder.ts @@ -21,7 +21,7 @@ export interface IStringBuilder { export let createStringBuilder: (capacity: number) => IStringBuilder; -if ((self).TextDecoder) { +if (typeof TextDecoder !== 'undefined') { createStringBuilder = (capacity) => new StringBuilder(capacity); } else { createStringBuilder = (capacity) => new CompatStringBuilder(); diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index 39a9e6a9280..cd669a4a94b 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -21,6 +21,7 @@ import { BasicInplaceReplace } from 'vs/editor/common/modes/supports/inplaceRepl import { getWordAtText, ensureValidWordDefinition } from 'vs/editor/common/model/wordHelper'; import { createMonacoBaseAPI } from 'vs/editor/common/standalone/standaloneBase'; import { IWordAtPosition, EndOfLineSequence } from 'vs/editor/common/model'; +import { globals } from 'vs/base/common/platform'; export interface IMirrorModel { readonly uri: URI; @@ -567,8 +568,7 @@ export function create(): IRequestHandler { return new EditorSimpleWorkerImpl(); } -var global: any = self; -let isWebWorker = (typeof global.importScripts === 'function'); -if (isWebWorker) { - global.monaco = createMonacoBaseAPI(); +if (typeof importScripts === 'function') { + // Running in a web worker + globals.monaco = createMonacoBaseAPI(); } diff --git a/src/vs/editor/common/view/editorColorRegistry.ts b/src/vs/editor/common/view/editorColorRegistry.ts index 4960109a2ea..bec51990776 100644 --- a/src/vs/editor/common/view/editorColorRegistry.ts +++ b/src/vs/editor/common/view/editorColorRegistry.ts @@ -14,6 +14,8 @@ import { Color, RGBA } from 'vs/base/common/color'; export const editorLineHighlight = registerColor('editor.lineHighlightBackground', { dark: null, light: null, hc: null }, nls.localize('lineHighlight', 'Background color for the highlight of line at the cursor position.')); export const editorLineHighlightBorder = registerColor('editor.lineHighlightBorder', { dark: '#282828', light: '#eeeeee', hc: '#f38518' }, nls.localize('lineHighlightBorderBox', 'Background color for the border around the line at the cursor position.')); export const editorRangeHighlight = registerColor('editor.rangeHighlightBackground', { dark: '#ffffff0b', light: '#fdff0033', hc: null }, nls.localize('rangeHighlight', 'Background color of highlighted ranges, like by quick open and find features. The color must not be opaque to not hide underlying decorations.'), true); +export const editorRangeHighlightBorder = registerColor('editor.rangeHighlightBorder', { dark: null, light: null, hc: activeContrastBorder }, nls.localize('rangeHighlightBorder', 'Background color of the border around highlighted ranges.'), true); + export const editorCursorForeground = registerColor('editorCursor.foreground', { dark: '#AEAFAD', light: Color.black, hc: Color.white }, nls.localize('caret', 'Color of the editor cursor.')); export const editorCursorBackground = registerColor('editorCursor.background', null, nls.localize('editorCursorBackground', 'The background color of the editor cursor. Allows customizing the color of a character overlapped by a block cursor.')); export const editorWhitespaces = registerColor('editorWhitespace.foreground', { dark: '#e3e4e229', light: '#33333333', hc: '#e3e4e229' }, nls.localize('editorWhitespaces', 'Color of whitespace characters in the editor.')); @@ -45,7 +47,6 @@ export const overviewRulerError = registerColor('editorOverviewRuler.errorForegr export const overviewRulerWarning = registerColor('editorOverviewRuler.warningForeground', { dark: new Color(new RGBA(18, 136, 18, 0.7)), light: new Color(new RGBA(18, 136, 18, 0.7)), hc: new Color(new RGBA(50, 255, 50, 1)) }, nls.localize('overviewRuleWarning', 'Overview ruler marker color for warnings.')); export const overviewRulerInfo = registerColor('editorOverviewRuler.infoForeground', { dark: new Color(new RGBA(18, 18, 136, 0.7)), light: new Color(new RGBA(18, 18, 136, 0.7)), hc: new Color(new RGBA(50, 50, 255, 1)) }, nls.localize('overviewRuleInfo', 'Overview ruler marker color for infos.')); - // contains all color rules that used to defined in editor/browser/widget/editor.css registerThemingParticipant((theme, collector) => { let background = theme.getColor(editorBackground); @@ -56,21 +57,18 @@ registerThemingParticipant((theme, collector) => { if (foreground) { collector.addRule(`.monaco-editor, .monaco-editor .inputarea.ime-input { color: ${foreground}; }`); } - let gutter = theme.getColor(editorGutter); if (gutter) { collector.addRule(`.monaco-editor .margin { background-color: ${gutter}; }`); } - let rangeHighlight = theme.getColor(editorRangeHighlight); if (rangeHighlight) { collector.addRule(`.monaco-editor .rangeHighlight { background-color: ${rangeHighlight}; }`); } - let outline = theme.getColor(activeContrastBorder); - if (outline) { - collector.addRule(`.monaco-editor .rangeHighlight { border: 1px dotted ${outline}; }`); + let rangeHighlightBorder = theme.getColor(editorRangeHighlightBorder); + if (rangeHighlightBorder) { + collector.addRule(`.monaco-editor .rangeHighlight { border: 1px dotted ${rangeHighlightBorder}; }`); } - let invisibles = theme.getColor(editorWhitespaces); if (invisibles) { collector.addRule(`.vs-whitespace { color: ${invisibles} !important; }`); diff --git a/src/vs/editor/contrib/codelens/codelensController.ts b/src/vs/editor/contrib/codelens/codelensController.ts index 1b23413d4d7..693ecec734c 100644 --- a/src/vs/editor/contrib/codelens/codelensController.ts +++ b/src/vs/editor/contrib/codelens/codelensController.ts @@ -22,7 +22,7 @@ import { IModelDecorationsChangeAccessor } from 'vs/editor/common/model'; export class CodeLensContribution implements editorCommon.IEditorContribution { - private static ID: string = 'css.editor.codeLens'; + private static readonly ID: string = 'css.editor.codeLens'; private _isEnabled: boolean; @@ -36,8 +36,8 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { constructor( private _editor: editorBrowser.ICodeEditor, - @ICommandService private _commandService: ICommandService, - @IMessageService private _messageService: IMessageService + @ICommandService private readonly _commandService: ICommandService, + @IMessageService private readonly _messageService: IMessageService ) { this._isEnabled = this._editor.getConfiguration().contribInfo.codeLens; diff --git a/src/vs/editor/contrib/colorPicker/colorDetector.ts b/src/vs/editor/contrib/colorPicker/colorDetector.ts index a1a967f0427..b839e90d207 100644 --- a/src/vs/editor/contrib/colorPicker/colorDetector.ts +++ b/src/vs/editor/contrib/colorPicker/colorDetector.ts @@ -21,7 +21,7 @@ const MAX_DECORATORS = 500; export class ColorDetector implements IEditorContribution { - private static ID: string = 'editor.contrib.colorDetector'; + private static readonly ID: string = 'editor.contrib.colorDetector'; static RECOMPUTE_TIME = 1000; // ms @@ -39,8 +39,8 @@ export class ColorDetector implements IEditorContribution { private _isEnabled: boolean; constructor(private _editor: ICodeEditor, - @ICodeEditorService private _codeEditorService: ICodeEditorService, - @IConfigurationService private _configurationService: IConfigurationService + @ICodeEditorService private readonly _codeEditorService: ICodeEditorService, + @IConfigurationService private readonly _configurationService: IConfigurationService ) { this._globalToDispose.push(_editor.onDidChangeModel((e) => { this._isEnabled = this.isEnabled(); diff --git a/src/vs/editor/contrib/contextmenu/contextmenu.ts b/src/vs/editor/contrib/contextmenu/contextmenu.ts index c3028475d32..f3c1ab86c25 100644 --- a/src/vs/editor/contrib/contextmenu/contextmenu.ts +++ b/src/vs/editor/contrib/contextmenu/contextmenu.ts @@ -40,11 +40,11 @@ export class ContextMenuController implements IEditorContribution { constructor( editor: ICodeEditor, - @IContextMenuService private _contextMenuService: IContextMenuService, - @IContextViewService private _contextViewService: IContextViewService, - @IContextKeyService private _contextKeyService: IContextKeyService, - @IKeybindingService private _keybindingService: IKeybindingService, - @IMenuService private _menuService: IMenuService + @IContextMenuService private readonly _contextMenuService: IContextMenuService, + @IContextViewService private readonly _contextViewService: IContextViewService, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IKeybindingService private readonly _keybindingService: IKeybindingService, + @IMenuService private readonly _menuService: IMenuService ) { this._editor = editor; diff --git a/src/vs/editor/contrib/find/findController.ts b/src/vs/editor/contrib/find/findController.ts index aea6fb8abbc..334de9e40e2 100644 --- a/src/vs/editor/contrib/find/findController.ts +++ b/src/vs/editor/contrib/find/findController.ts @@ -362,10 +362,10 @@ export class FindController extends CommonFindController implements IFindControl constructor( editor: ICodeEditor, - @IContextViewService private _contextViewService: IContextViewService, - @IContextKeyService private _contextKeyService: IContextKeyService, - @IKeybindingService private _keybindingService: IKeybindingService, - @IThemeService private _themeService: IThemeService, + @IContextViewService private readonly _contextViewService: IContextViewService, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IKeybindingService private readonly _keybindingService: IKeybindingService, + @IThemeService private readonly _themeService: IThemeService, @IStorageService storageService: IStorageService, @optional(IClipboardService) clipboardService: IClipboardService ) { diff --git a/src/vs/editor/contrib/find/findDecorations.ts b/src/vs/editor/contrib/find/findDecorations.ts index 1a81d8c7e66..b5b5287decb 100644 --- a/src/vs/editor/contrib/find/findDecorations.ts +++ b/src/vs/editor/contrib/find/findDecorations.ts @@ -8,7 +8,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -import { editorFindMatchHighlight, editorFindMatch } from 'vs/platform/theme/common/colorRegistry'; +import { overviewRulerFindMatchForeground } from 'vs/platform/theme/common/colorRegistry'; import { themeColorFromId } from 'vs/platform/theme/common/themeService'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IModelDecorationsChangeAccessor, FindMatch, IModelDeltaDecoration, TrackedRangeStickiness, OverviewRulerLane } from 'vs/editor/common/model'; @@ -226,8 +226,8 @@ export class FindDecorations implements IDisposable { className: 'currentFindMatch', showIfCollapsed: true, overviewRuler: { - color: themeColorFromId(editorFindMatch), - darkColor: themeColorFromId(editorFindMatch), + color: themeColorFromId(overviewRulerFindMatchForeground), + darkColor: themeColorFromId(overviewRulerFindMatchForeground), position: OverviewRulerLane.Center } }); @@ -237,8 +237,8 @@ export class FindDecorations implements IDisposable { className: 'findMatch', showIfCollapsed: true, overviewRuler: { - color: themeColorFromId(editorFindMatchHighlight), - darkColor: themeColorFromId(editorFindMatchHighlight), + color: themeColorFromId(overviewRulerFindMatchForeground), + darkColor: themeColorFromId(overviewRulerFindMatchForeground), position: OverviewRulerLane.Center } }); @@ -252,8 +252,8 @@ export class FindDecorations implements IDisposable { private static readonly _FIND_MATCH_ONLY_OVERVIEW_DECORATION = ModelDecorationOptions.register({ stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, overviewRuler: { - color: themeColorFromId(editorFindMatchHighlight), - darkColor: themeColorFromId(editorFindMatchHighlight), + color: themeColorFromId(overviewRulerFindMatchForeground), + darkColor: themeColorFromId(overviewRulerFindMatchForeground), position: OverviewRulerLane.Center } }); diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 19faa63f3b0..d5c25699fbc 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -28,7 +28,7 @@ import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/c import { ITheme, registerThemingParticipant, IThemeService } from 'vs/platform/theme/common/themeService'; import { Color } from 'vs/base/common/color'; import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; -import { editorFindRangeHighlight, editorFindMatch, editorFindMatchHighlight, activeContrastBorder, contrastBorder, inputBackground, editorWidgetBackground, inputActiveOptionBorder, widgetShadow, inputForeground, inputBorder, inputValidationInfoBackground, inputValidationInfoBorder, inputValidationWarningBackground, inputValidationWarningBorder, inputValidationErrorBackground, inputValidationErrorBorder, errorForeground, editorWidgetBorder } from 'vs/platform/theme/common/colorRegistry'; +import { editorFindRangeHighlight, editorFindMatch, editorFindMatchHighlight, contrastBorder, inputBackground, editorWidgetBackground, inputActiveOptionBorder, widgetShadow, inputForeground, inputBorder, inputValidationInfoBackground, inputValidationInfoBorder, inputValidationWarningBackground, inputValidationWarningBorder, inputValidationErrorBackground, inputValidationErrorBorder, errorForeground, editorWidgetBorder, editorFindMatchBorder, editorFindMatchHighlightBorder, editorFindRangeHighlightBorder } from 'vs/platform/theme/common/colorRegistry'; export interface IFindController { @@ -1076,12 +1076,19 @@ registerThemingParticipant((theme, collector) => { collector.addRule(`.monaco-editor .find-widget { box-shadow: 0 2px 8px ${widgetShadowColor}; }`); } - let hcOutline = theme.getColor(activeContrastBorder); - if (hcOutline) { - collector.addRule(`.monaco-editor .findScope { border: 1px dashed ${hcOutline.transparent(0.4)}; }`); - collector.addRule(`.monaco-editor .currentFindMatch { border: 2px solid ${hcOutline}; padding: 1px; -moz-box-sizing: border-box; box-sizing: border-box; }`); - collector.addRule(`.monaco-editor .findMatch { border: 1px dotted ${hcOutline}; -moz-box-sizing: border-box; box-sizing: border-box; }`); + let findMatchHighlightBorder = theme.getColor(editorFindMatchHighlightBorder); + if (findMatchHighlightBorder) { + collector.addRule(`.monaco-editor .findMatch { border: 1px dotted ${findMatchHighlightBorder}; -moz-box-sizing: border-box; box-sizing: border-box; }`); } + let findMatchBorder = theme.getColor(editorFindMatchBorder); + if (findMatchBorder) { + collector.addRule(`.monaco-editor .currentFindMatch { border: 2px solid ${findMatchBorder}; padding: 1px; -moz-box-sizing: border-box; box-sizing: border-box; }`); + } + let findRangeHighlightBorder = theme.getColor(editorFindRangeHighlightBorder); + if (findRangeHighlightBorder) { + collector.addRule(`.monaco-editor .findScope { border: 1px dashed ${findRangeHighlightBorder}; }`); + } + let hcBorder = theme.getColor(contrastBorder); if (hcBorder) { collector.addRule(`.monaco-editor .find-widget { border: 2px solid ${hcBorder}; }`); diff --git a/src/vs/editor/contrib/find/simpleFindWidget.ts b/src/vs/editor/contrib/find/simpleFindWidget.ts index a4216e51f39..b4c396e4e40 100644 --- a/src/vs/editor/contrib/find/simpleFindWidget.ts +++ b/src/vs/editor/contrib/find/simpleFindWidget.ts @@ -33,7 +33,7 @@ export abstract class SimpleFindWidget extends Widget { protected _updateHistoryDelayer: Delayer; constructor( - @IContextViewService private _contextViewService: IContextViewService, + @IContextViewService private readonly _contextViewService: IContextViewService, private animate: boolean = true ) { super(); diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index d898a618ca4..e4dad463739 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -104,7 +104,11 @@ export class FoldingController implements IEditorContribution { if (!model || !this._isEnabled || model.isTooLargeForTokenization()) { return {}; } - return { collapsedRegions: this.foldingModel.getMemento(), lineCount: model.getLineCount() }; + if (this.foldingModel) { // disposed ? + let collapsedRegions = this.foldingModel.isInitialized ? this.foldingModel.getMemento() : this.hiddenRangeModel.getMemento(); + return { collapsedRegions, lineCount: model.getLineCount() }; + } + return void 0; } /** diff --git a/src/vs/editor/contrib/folding/foldingModel.ts b/src/vs/editor/contrib/folding/foldingModel.ts index eb230e2d66e..33e1826061c 100644 --- a/src/vs/editor/contrib/folding/foldingModel.ts +++ b/src/vs/editor/contrib/folding/foldingModel.ts @@ -26,18 +26,21 @@ export class FoldingModel { private _ranges: FoldingRanges; private _editorDecorationIds: string[]; + private _isInitialized: boolean; private _updateEventEmitter = new Emitter(); public get ranges(): FoldingRanges { return this._ranges; } public get onDidChange(): Event { return this._updateEventEmitter.event; } public get textModel() { return this._textModel; } + public get isInitialized() { return this._isInitialized; } constructor(textModel: ITextModel, decorationProvider: IDecorationProvider) { this._textModel = textModel; this._decorationProvider = decorationProvider; this._ranges = new FoldingRanges(new Uint32Array(0), new Uint32Array(0)); this._editorDecorationIds = []; + this._isInitialized = false; } public toggleCollapseState(regions: FoldingRegion[]) { @@ -128,6 +131,7 @@ export class FoldingModel { this._editorDecorationIds = this._decorationProvider.deltaDecorations(this._editorDecorationIds, newEditorDecorations); this._ranges = newRanges; + this._isInitialized = true; this._updateEventEmitter.fire({ model: this }); } diff --git a/src/vs/editor/contrib/folding/hiddenRangeModel.ts b/src/vs/editor/contrib/folding/hiddenRangeModel.ts index a684890bb84..fee0f5108c2 100644 --- a/src/vs/editor/contrib/folding/hiddenRangeModel.ts +++ b/src/vs/editor/contrib/folding/hiddenRangeModel.ts @@ -12,7 +12,7 @@ import { findFirst } from 'vs/base/common/arrays'; export class HiddenRangeModel { private _foldingModel: FoldingModel; - private _hiddenRanges: IRange[] = []; + private _hiddenRanges: IRange[]; private _foldingModelListener: IDisposable; private _updateEventEmitter = new Emitter(); @@ -22,6 +22,7 @@ export class HiddenRangeModel { public constructor(model: FoldingModel) { this._foldingModel = model; this._foldingModelListener = model.onDidChange(_ => this.updateHiddenRanges()); + this._hiddenRanges = []; if (model.ranges.length) { this.updateHiddenRanges(); } @@ -80,6 +81,13 @@ export class HiddenRangeModel { return true; } + /** + * Collapse state memento, for persistence only, only used if folding model is not yet initialized + */ + public getMemento(): CollapseMemento { + return this._hiddenRanges.map(r => ({ startLineNumber: r.startLineNumber - 1, endLineNumber: r.endLineNumber })); + } + private applyHiddenRanges(newHiddenAreas: IRange[]) { this._hiddenRanges = newHiddenAreas; this._updateEventEmitter.fire(newHiddenAreas); diff --git a/src/vs/editor/contrib/gotoError/gotoError.ts b/src/vs/editor/contrib/gotoError/gotoError.ts index 9efd2151ada..626e4c802e8 100644 --- a/src/vs/editor/contrib/gotoError/gotoError.ts +++ b/src/vs/editor/contrib/gotoError/gotoError.ts @@ -430,9 +430,9 @@ class MarkerController implements editorCommon.IEditorContribution { constructor( editor: ICodeEditor, - @IMarkerService private _markerService: IMarkerService, - @IContextKeyService private _contextKeyService: IContextKeyService, - @IThemeService private _themeService: IThemeService + @IMarkerService private readonly _markerService: IMarkerService, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IThemeService private readonly _themeService: IThemeService ) { this._editor = editor; this._markersNavigationVisible = CONTEXT_MARKERS_NAVIGATION_VISIBLE.bindTo(this._contextKeyService); diff --git a/src/vs/editor/contrib/hover/hover.ts b/src/vs/editor/contrib/hover/hover.ts index 047e21db91b..af7f1a66d41 100644 --- a/src/vs/editor/contrib/hover/hover.ts +++ b/src/vs/editor/contrib/hover/hover.ts @@ -56,8 +56,8 @@ export class ModesHoverController implements editorCommon.IEditorContribution { } constructor(editor: ICodeEditor, - @IOpenerService private _openerService: IOpenerService, - @IModeService private _modeService: IModeService + @IOpenerService private readonly _openerService: IOpenerService, + @IModeService private readonly _modeService: IModeService ) { this._editor = editor; diff --git a/src/vs/editor/contrib/links/links.ts b/src/vs/editor/contrib/links/links.ts index 87a1c0365ab..5f09afd3250 100644 --- a/src/vs/editor/contrib/links/links.ts +++ b/src/vs/editor/contrib/links/links.ts @@ -130,7 +130,7 @@ class LinkOccurrence { class LinkDetector implements editorCommon.IEditorContribution { - private static ID: string = 'editor.linkDetector'; + private static readonly ID: string = 'editor.linkDetector'; public static get(editor: ICodeEditor): LinkDetector { return editor.getContribution(LinkDetector.ID); diff --git a/src/vs/editor/contrib/quickFix/quickFix.ts b/src/vs/editor/contrib/quickFix/quickFix.ts index 10bbbe4d5e8..8e273057dc1 100644 --- a/src/vs/editor/contrib/quickFix/quickFix.ts +++ b/src/vs/editor/contrib/quickFix/quickFix.ts @@ -13,7 +13,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { onUnexpectedExternalError, illegalArgument } from 'vs/base/common/errors'; import { IModelService } from 'vs/editor/common/services/modelService'; import { registerLanguageCommand } from 'vs/editor/browser/editorExtensions'; -import { isFalsyOrEmpty } from 'vs/base/common/arrays'; +import { isFalsyOrEmpty, mergeSort } from 'vs/base/common/arrays'; import { CodeActionKind } from './codeActionTrigger'; export function getCodeActions(model: ITextModel, range: Range, scope?: CodeActionKind): TPromise { @@ -36,7 +36,7 @@ export function getCodeActions(model: ITextModel, range: Range, scope?: CodeActi }); return TPromise.join(promises).then( - () => allResults.sort(codeActionsComparator) + () => mergeSort(allResults, codeActionsComparator) ); } diff --git a/src/vs/editor/contrib/referenceSearch/referencesController.ts b/src/vs/editor/contrib/referenceSearch/referencesController.ts index d82c3378137..0dc0f36b083 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesController.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesController.ts @@ -55,14 +55,14 @@ export class ReferencesController implements editorCommon.IEditorContribution { public constructor( editor: ICodeEditor, @IContextKeyService contextKeyService: IContextKeyService, - @IEditorService private _editorService: IEditorService, - @ITextModelService private _textModelResolverService: ITextModelService, - @IMessageService private _messageService: IMessageService, - @IInstantiationService private _instantiationService: IInstantiationService, - @IWorkspaceContextService private _contextService: IWorkspaceContextService, - @IStorageService private _storageService: IStorageService, - @IThemeService private _themeService: IThemeService, - @IConfigurationService private _configurationService: IConfigurationService, + @IEditorService private readonly _editorService: IEditorService, + @ITextModelService private readonly _textModelResolverService: ITextModelService, + @IMessageService private readonly _messageService: IMessageService, + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, + @IStorageService private readonly _storageService: IStorageService, + @IThemeService private readonly _themeService: IThemeService, + @IConfigurationService private readonly _configurationService: IConfigurationService, @optional(IEnvironmentService) private _environmentService: IEnvironmentService ) { this._editor = editor; diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index 7b0e5ee38ed..ee73377d033 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -164,7 +164,7 @@ class DecorationsManager implements IDisposable { class DataSource implements tree.IDataSource { constructor( - @ITextModelService private _textModelResolverService: ITextModelService + @ITextModelService private readonly _textModelResolverService: ITextModelService ) { // } @@ -305,7 +305,7 @@ class FileReferencesTemplate { constructor( container: HTMLElement, - @IWorkspaceContextService private _contextService: IWorkspaceContextService, + @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, @optional(IEnvironmentService) private _environmentService: IEnvironmentService, @IThemeService themeService: IThemeService, ) { @@ -372,8 +372,8 @@ class Renderer implements tree.IRenderer { }; constructor( - @IWorkspaceContextService private _contextService: IWorkspaceContextService, - @IThemeService private _themeService: IThemeService, + @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, + @IThemeService private readonly _themeService: IThemeService, @optional(IEnvironmentService) private _environmentService: IEnvironmentService, ) { // diff --git a/src/vs/editor/contrib/rename/rename.ts b/src/vs/editor/contrib/rename/rename.ts index f6cbd734f42..1d7cda764c7 100644 --- a/src/vs/editor/contrib/rename/rename.ts +++ b/src/vs/editor/contrib/rename/rename.ts @@ -113,9 +113,9 @@ class RenameController implements IEditorContribution { constructor( private editor: ICodeEditor, - @IMessageService private _messageService: IMessageService, - @ITextModelService private _textModelResolverService: ITextModelService, - @IProgressService private _progressService: IProgressService, + @IMessageService private readonly _messageService: IMessageService, + @ITextModelService private readonly _textModelResolverService: ITextModelService, + @IProgressService private readonly _progressService: IProgressService, @IContextKeyService contextKeyService: IContextKeyService, @IThemeService themeService: IThemeService, @optional(IFileService) private _fileService: IFileService diff --git a/src/vs/editor/contrib/snippet/snippetController2.ts b/src/vs/editor/contrib/snippet/snippetController2.ts index eda1c4e1509..f929ab3239f 100644 --- a/src/vs/editor/contrib/snippet/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/snippetController2.ts @@ -42,7 +42,7 @@ export class SnippetController2 implements IEditorContribution { constructor( private readonly _editor: ICodeEditor, - @ILogService private _logService: ILogService, + @ILogService private readonly _logService: ILogService, @IContextKeyService contextKeyService: IContextKeyService ) { this._inSnippet = SnippetController2.InSnippetMode.bindTo(contextKeyService); diff --git a/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts b/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts index 6979ff09551..a7e46d98f0d 100644 --- a/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts @@ -18,7 +18,7 @@ class TestSnippetController extends SnippetController2 { constructor( editor: ICodeEditor, - @IContextKeyService private _contextKeyService: IContextKeyService + @IContextKeyService private readonly _contextKeyService: IContextKeyService ) { super(editor, new NullLogService(), _contextKeyService); } diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index b800056c46c..d5b911c551c 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -77,7 +77,7 @@ class AcceptOnCharacterOracle { export class SuggestController implements IEditorContribution { - private static ID: string = 'editor.contrib.suggestController'; + private static readonly ID: string = 'editor.contrib.suggestController'; public static get(editor: ICodeEditor): SuggestController { return editor.getContribution(SuggestController.ID); @@ -90,9 +90,9 @@ export class SuggestController implements IEditorContribution { constructor( private _editor: ICodeEditor, - @ICommandService private _commandService: ICommandService, - @IContextKeyService private _contextKeyService: IContextKeyService, - @IInstantiationService private _instantiationService: IInstantiationService, + @ICommandService private readonly _commandService: ICommandService, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IInstantiationService private readonly _instantiationService: IInstantiationService, ) { this._model = new SuggestModel(this._editor); this._memory = _instantiationService.createInstance(SuggestMemories, this._editor.getConfiguration().contribInfo.suggestSelection); diff --git a/src/vs/editor/contrib/suggest/suggestMemory.ts b/src/vs/editor/contrib/suggest/suggestMemory.ts index 58df1fd7179..7ead0af993a 100644 --- a/src/vs/editor/contrib/suggest/suggestMemory.ts +++ b/src/vs/editor/contrib/suggest/suggestMemory.ts @@ -177,7 +177,7 @@ export class SuggestMemories { constructor( mode: MemMode, - @IStorageService private _storageService: IStorageService + @IStorageService private readonly _storageService: IStorageService ) { this._persistSoon = new RunOnceScheduler(() => this._flush(), 3000); this.setMode(mode); diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 944076be107..180d53dc16a 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -343,7 +343,7 @@ export interface ISelectedSuggestion { export class SuggestWidget implements IContentWidget, IDelegate, IDisposable { - private static ID: string = 'editor.widget.suggestWidget'; + private static readonly ID: string = 'editor.widget.suggestWidget'; static LOADING_MESSAGE: string = nls.localize('suggestWidget.loading', "Loading..."); static NO_SUGGESTIONS_MESSAGE: string = nls.localize('suggestWidget.noSuggestions', "No suggestions."); diff --git a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts index 02875a72eab..3918a0f64db 100644 --- a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts +++ b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts @@ -15,7 +15,7 @@ import { registerEditorContribution, EditorAction, IActionOptions, registerEdito import { DocumentHighlight, DocumentHighlightKind, DocumentHighlightProviderRegistry } from 'vs/editor/common/modes'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { Position } from 'vs/editor/common/core/position'; -import { registerColor, editorSelectionHighlight, activeContrastBorder, overviewRulerSelectionHighlightForeground } from 'vs/platform/theme/common/colorRegistry'; +import { registerColor, editorSelectionHighlight, overviewRulerSelectionHighlightForeground, activeContrastBorder, editorSelectionHighlightBorder } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant, themeColorFromId } from 'vs/platform/theme/common/themeService'; import { CursorChangeReason, ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; @@ -29,6 +29,8 @@ import { ITextModel, TrackedRangeStickiness, OverviewRulerLane, IModelDeltaDecor export const editorWordHighlight = registerColor('editor.wordHighlightBackground', { dark: '#575757B8', light: '#57575740', hc: null }, nls.localize('wordHighlight', 'Background color of a symbol during read-access, like reading a variable. The color must not be opaque to not hide underlying decorations.'), true); export const editorWordHighlightStrong = registerColor('editor.wordHighlightStrongBackground', { dark: '#004972B8', light: '#0e639c40', hc: null }, nls.localize('wordHighlightStrong', 'Background color of a symbol during write-access, like writing to a variable. The color must not be opaque to not hide underlying decorations.'), true); +export const editorWordHighlightBorder = registerColor('editor.wordHighlightBorder', { light: null, dark: null, hc: activeContrastBorder }, nls.localize('wordHighlightBorder', 'Border color of a symbol during read-access, like reading a variable.')); +export const editorWordHighlightStrongBorder = registerColor('editor.wordHighlightStrongBorder', { light: null, dark: null, hc: activeContrastBorder }, nls.localize('wordHighlightStrongBorder', 'Border color of a symbol during write-access, like writing to a variable.')); export const overviewRulerWordHighlightForeground = registerColor('editorOverviewRuler.wordHighlightForeground', { dark: '#A0A0A0', light: '#A0A0A0', hc: '#A0A0A0' }, nls.localize('overviewRulerWordHighlightForeground', 'Overview ruler marker color for symbol highlights.')); export const overviewRulerWordHighlightStrongForeground = registerColor('editorOverviewRuler.wordHighlightStrongForeground', { dark: '#C0A0C0', light: '#C0A0C0', hc: '#C0A0C0' }, nls.localize('overviewRulerWordHighlightStrongForeground', 'Overview ruler marker color for write-access symbol highlights.')); @@ -515,11 +517,17 @@ registerThemingParticipant((theme, collector) => { if (wordHighlightStrong) { collector.addRule(`.monaco-editor .wordHighlightStrong { background-color: ${wordHighlightStrong}; }`); } - let hcOutline = theme.getColor(activeContrastBorder); - if (hcOutline) { - collector.addRule(`.monaco-editor .selectionHighlight { border: 1px dotted ${hcOutline}; box-sizing: border-box; }`); - collector.addRule(`.monaco-editor .wordHighlight { border: 1px dashed ${hcOutline}; box-sizing: border-box; }`); - collector.addRule(`.monaco-editor .wordHighlightStrong { border: 1px dashed ${hcOutline}; box-sizing: border-box; }`); + let selectionHighlightBorder = theme.getColor(editorSelectionHighlightBorder); + if (selectionHighlightBorder) { + collector.addRule(`.monaco-editor .selectionHighlight { border: 1px dotted ${selectionHighlightBorder}; box-sizing: border-box; }`); + } + let wordHighlightBorder = theme.getColor(editorWordHighlightBorder); + if (wordHighlightBorder) { + collector.addRule(`.monaco-editor .wordHighlight { border: 1px dashed ${wordHighlightBorder}; box-sizing: border-box; }`); + } + let wordHighlightStrongBorder = theme.getColor(editorWordHighlightStrongBorder); + if (wordHighlightStrongBorder) { + collector.addRule(`.monaco-editor .wordHighlightStrong { border: 1px dashed ${wordHighlightStrongBorder}; box-sizing: border-box; }`); } }); diff --git a/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts b/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts index 44f2fca8421..7f6504e4607 100644 --- a/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts +++ b/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts @@ -115,9 +115,9 @@ class AccessibilityHelpWidget extends Widget implements IOverlayWidget { constructor( editor: ICodeEditor, - @IContextKeyService private _contextKeyService: IContextKeyService, - @IKeybindingService private _keybindingService: IKeybindingService, - @IOpenerService private _openerService: IOpenerService + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IKeybindingService private readonly _keybindingService: IKeybindingService, + @IOpenerService private readonly _openerService: IOpenerService ) { super(); diff --git a/src/vs/loader.js b/src/vs/loader.js index aa1ae79ae5e..291f0e8b6b3 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -22,20 +22,55 @@ var _amdLoaderGlobal = this; var AMDLoader; (function (AMDLoader) { AMDLoader.global = _amdLoaderGlobal; - var Environment = (function () { - function Environment(opts) { - this.isWindows = opts.isWindows; - this.isNode = opts.isNode; - this.isElectronRenderer = opts.isElectronRenderer; - this.isWebWorker = opts.isWebWorker; + var Environment = /** @class */ (function () { + function Environment() { + this._detected = false; + this._isWindows = false; + this._isNode = false; + this._isElectronRenderer = false; + this._isWebWorker = false; } - Environment.detect = function () { - return new Environment({ - isWindows: this._isWindows(), - isNode: (typeof module !== 'undefined' && !!module.exports), - isElectronRenderer: (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer'), - isWebWorker: (typeof AMDLoader.global.importScripts === 'function') - }); + Object.defineProperty(Environment.prototype, "isWindows", { + get: function () { + this._detect(); + return this._isWindows; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Environment.prototype, "isNode", { + get: function () { + this._detect(); + return this._isNode; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Environment.prototype, "isElectronRenderer", { + get: function () { + this._detect(); + return this._isElectronRenderer; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Environment.prototype, "isWebWorker", { + get: function () { + this._detect(); + return this._isWebWorker; + }, + enumerable: true, + configurable: true + }); + Environment.prototype._detect = function () { + if (this._detected) { + return; + } + this._detected = true; + this._isWindows = Environment._isWindows(); + this._isNode = (typeof module !== 'undefined' && !!module.exports); + this._isElectronRenderer = (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer'); + this._isWebWorker = (typeof AMDLoader.global.importScripts === 'function'); }; Environment._isWindows = function () { if (typeof navigator !== 'undefined') { @@ -58,20 +93,7 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - var LoaderEventType; - (function (LoaderEventType) { - LoaderEventType[LoaderEventType["LoaderAvailable"] = 1] = "LoaderAvailable"; - LoaderEventType[LoaderEventType["BeginLoadingScript"] = 10] = "BeginLoadingScript"; - LoaderEventType[LoaderEventType["EndLoadingScriptOK"] = 11] = "EndLoadingScriptOK"; - LoaderEventType[LoaderEventType["EndLoadingScriptError"] = 12] = "EndLoadingScriptError"; - LoaderEventType[LoaderEventType["BeginInvokeFactory"] = 21] = "BeginInvokeFactory"; - LoaderEventType[LoaderEventType["EndInvokeFactory"] = 22] = "EndInvokeFactory"; - LoaderEventType[LoaderEventType["NodeBeginEvaluatingScript"] = 31] = "NodeBeginEvaluatingScript"; - LoaderEventType[LoaderEventType["NodeEndEvaluatingScript"] = 32] = "NodeEndEvaluatingScript"; - LoaderEventType[LoaderEventType["NodeBeginNativeRequire"] = 33] = "NodeBeginNativeRequire"; - LoaderEventType[LoaderEventType["NodeEndNativeRequire"] = 34] = "NodeEndNativeRequire"; - })(LoaderEventType = AMDLoader.LoaderEventType || (AMDLoader.LoaderEventType = {})); - var LoaderEvent = (function () { + var LoaderEvent = /** @class */ (function () { function LoaderEvent(type, detail, timestamp) { this.type = type; this.detail = detail; @@ -80,9 +102,9 @@ var AMDLoader; return LoaderEvent; }()); AMDLoader.LoaderEvent = LoaderEvent; - var LoaderEventRecorder = (function () { + var LoaderEventRecorder = /** @class */ (function () { function LoaderEventRecorder(loaderAvailableTimestamp) { - this._events = [new LoaderEvent(LoaderEventType.LoaderAvailable, '', loaderAvailableTimestamp)]; + this._events = [new LoaderEvent(1 /* LoaderAvailable */, '', loaderAvailableTimestamp)]; } LoaderEventRecorder.prototype.record = function (type, detail) { this._events.push(new LoaderEvent(type, detail, AMDLoader.Utilities.getHighPerformanceTimestamp())); @@ -93,7 +115,7 @@ var AMDLoader; return LoaderEventRecorder; }()); AMDLoader.LoaderEventRecorder = LoaderEventRecorder; - var NullLoaderEventRecorder = (function () { + var NullLoaderEventRecorder = /** @class */ (function () { function NullLoaderEventRecorder() { } NullLoaderEventRecorder.prototype.record = function (type, detail) { @@ -102,9 +124,9 @@ var AMDLoader; NullLoaderEventRecorder.prototype.getEvents = function () { return []; }; + NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); return NullLoaderEventRecorder; }()); - NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder(); AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- @@ -113,7 +135,7 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - var Utilities = (function () { + var Utilities = /** @class */ (function () { function Utilities() { } /** @@ -199,11 +221,11 @@ var AMDLoader; } return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now()); }; + Utilities.NEXT_ANONYMOUS_ID = 1; + Utilities.PERFORMANCE_NOW_PROBED = false; + Utilities.HAS_PERFORMANCE_NOW = false; return Utilities; }()); - Utilities.NEXT_ANONYMOUS_ID = 1; - Utilities.PERFORMANCE_NOW_PROBED = false; - Utilities.HAS_PERFORMANCE_NOW = false; AMDLoader.Utilities = Utilities; })(AMDLoader || (AMDLoader = {})); /*--------------------------------------------------------------------------------------------- @@ -212,13 +234,13 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { - var ConfigurationOptionsUtil = (function () { + var ConfigurationOptionsUtil = /** @class */ (function () { function ConfigurationOptionsUtil() { } /** * Ensure configuration options make sense */ - ConfigurationOptionsUtil.validateConfigurationOptions = function (isWebWorker, options) { + ConfigurationOptionsUtil.validateConfigurationOptions = function (options) { function defaultOnError(err) { if (err.errorCode === 'load') { console.error('Loading "' + err.moduleId + '" failed'); @@ -253,8 +275,7 @@ var AMDLoader; options.config = {}; } if (typeof options.catchError === 'undefined') { - // Catch errors by default in web workers, do not catch errors by default in other contexts - options.catchError = isWebWorker; + options.catchError = false; } if (typeof options.urlArgs !== 'string') { options.urlArgs = ''; @@ -295,7 +316,7 @@ var AMDLoader; } return options; }; - ConfigurationOptionsUtil.mergeConfigurationOptions = function (isWebWorker, overwrite, base) { + ConfigurationOptionsUtil.mergeConfigurationOptions = function (overwrite, base) { if (overwrite === void 0) { overwrite = null; } if (base === void 0) { base = null; } var result = AMDLoader.Utilities.recursiveClone(base || {}); @@ -314,25 +335,25 @@ var AMDLoader; result[key] = AMDLoader.Utilities.recursiveClone(value); } }); - return ConfigurationOptionsUtil.validateConfigurationOptions(isWebWorker, result); + return ConfigurationOptionsUtil.validateConfigurationOptions(result); }; return ConfigurationOptionsUtil; }()); AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil; - var Configuration = (function () { + var Configuration = /** @class */ (function () { function Configuration(env, options) { this._env = env; - this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(this._env.isWebWorker, options); + this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options); this._createIgnoreDuplicateModulesMap(); this._createNodeModulesMap(); this._createSortedPathsRules(); if (this.options.baseUrl === '') { - if (this._env.isNode && this.options.nodeRequire && this.options.nodeRequire.main && this.options.nodeRequire.main.filename) { + if (this.options.nodeRequire && this.options.nodeRequire.main && this.options.nodeRequire.main.filename && this._env.isNode) { var nodeMain = this.options.nodeRequire.main.filename; var dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\')); this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1); } - if (this._env.isNode && this.options.nodeMain) { + if (this.options.nodeMain && this._env.isNode) { var nodeMain = this.options.nodeMain; var dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\')); this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1); @@ -383,7 +404,7 @@ var AMDLoader; * @result A new configuration */ Configuration.prototype.cloneAndMerge = function (options) { - return new Configuration(this._env, ConfigurationOptionsUtil.mergeConfigurationOptions(this._env.isWebWorker, options, this.options)); + return new Configuration(this._env, ConfigurationOptionsUtil.mergeConfigurationOptions(options, this.options)); }; /** * Get current options bag. Useful for passing it forward to plugins. @@ -530,41 +551,49 @@ var AMDLoader; /** * Load `scriptSrc` only once (avoid multiple