mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Vscode merge (#4582)
* Merge from vscode 37cb23d3dd4f9433d56d4ba5ea3203580719a0bd * fix issues with merges * bump node version in azpipe * replace license headers * remove duplicate launch task * fix build errors * fix build errors * fix tslint issues * working through package and linux build issues * more work * wip * fix packaged builds * working through linux build errors * wip * wip * wip * fix mac and linux file limits * iterate linux pipeline * disable editor typing * revert series to parallel * remove optimize vscode from linux * fix linting issues * revert testing change * add work round for new node * readd packaging for extensions * fix issue with angular not resolving decorator dependencies
This commit is contained in:
@@ -1,28 +1,5 @@
|
||||
{
|
||||
"registrations": [
|
||||
{
|
||||
"component": {
|
||||
"type": "git",
|
||||
"git": {
|
||||
"name": "chriskempson/tomorrow-theme",
|
||||
"repositoryUrl": "https://github.com/chriskempson/tomorrow-theme",
|
||||
"commitHash": "0e0d35ac303f99b8aa182091ebeaee81cf2183a0"
|
||||
}
|
||||
},
|
||||
"licenseDetail": [
|
||||
"Copyright (C) 2013 Chris Kempson",
|
||||
"",
|
||||
"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,",
|
||||
"and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:",
|
||||
"",
|
||||
"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
|
||||
"",
|
||||
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
|
||||
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
|
||||
],
|
||||
"license": "MIT",
|
||||
"version": "0.0.0"
|
||||
},
|
||||
{
|
||||
"component": {
|
||||
"type": "git",
|
||||
@@ -52,4 +29,4 @@
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -160,6 +160,14 @@
|
||||
"command": "markdown.preview.toggleLock",
|
||||
"when": "markdownPreviewFocus"
|
||||
},
|
||||
{
|
||||
"command": "markdown.preview.refresh",
|
||||
"when": "editorLangId == markdown"
|
||||
},
|
||||
{
|
||||
"command": "markdown.preview.refresh",
|
||||
"when": "markdownPreviewFocus"
|
||||
},
|
||||
{
|
||||
"command": "notebook.showPreview",
|
||||
"when": "false"
|
||||
@@ -315,12 +323,12 @@
|
||||
"@types/highlight.js": "9.12.3",
|
||||
"@types/lodash.throttle": "^4.1.3",
|
||||
"@types/markdown-it": "0.0.2",
|
||||
"@types/node": "^8.10.25",
|
||||
"@types/node": "^10.12.21",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"ts-loader": "^4.0.1",
|
||||
"typescript": "^2.7.2",
|
||||
"typescript": "^3.3.1",
|
||||
"vscode": "^1.1.10",
|
||||
"webpack": "^4.1.0",
|
||||
"webpack-cli": "^2.0.10"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export function onceDocumentLoaded(f: () => void) {
|
||||
if (document.readyState === 'loading' || document.readyState === 'uninitialized') {
|
||||
if (document.readyState === 'loading' || document.readyState as string === 'uninitialized') {
|
||||
document.addEventListener('DOMContentLoaded', f);
|
||||
} else {
|
||||
f();
|
||||
|
||||
@@ -19,7 +19,7 @@ const settings = getSettings();
|
||||
const vscode = acquireVsCodeApi();
|
||||
|
||||
// Set VS Code state
|
||||
const state = getData('data-state');
|
||||
let state = getData('data-state');
|
||||
vscode.setState(state);
|
||||
|
||||
const messaging = createPosterForVsCode(vscode);
|
||||
@@ -152,6 +152,8 @@ if (settings.scrollEditorWithPreview) {
|
||||
const line = getEditorLineNumberForPageOffset(window.scrollY);
|
||||
if (typeof line === 'number' && !isNaN(line)) {
|
||||
messaging.postMessage('revealLine', { line });
|
||||
state.line = line;
|
||||
vscode.setState(state);
|
||||
}
|
||||
}
|
||||
}, 50));
|
||||
|
||||
@@ -24,13 +24,13 @@ const getCodeLineElements = (() => {
|
||||
let elements: CodeLineElement[];
|
||||
return () => {
|
||||
if (!elements) {
|
||||
elements = ([{ element: document.body, line: 0 }]).concat(Array.prototype.map.call(
|
||||
document.getElementsByClassName('code-line'),
|
||||
(element: any) => {
|
||||
const line = +element.getAttribute('data-line');
|
||||
return { element, line };
|
||||
})
|
||||
.filter((x: any) => !isNaN(x.line)));
|
||||
elements = [{ element: document.body, line: 0 }];
|
||||
for (const element of document.getElementsByClassName('code-line')) {
|
||||
const line = +element.getAttribute('data-line')!;
|
||||
if (!isNaN(line)) {
|
||||
elements.push({ element: element as HTMLElement, line });
|
||||
}
|
||||
}
|
||||
}
|
||||
return elements;
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"jsx": "react",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"strictBindCallApply": true,
|
||||
"noImplicitAny": true,
|
||||
"noUnusedLocals": true
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ import MarkdownWorkspaceSymbolProvider from './features/workspaceSymbolProvider'
|
||||
import { Logger } from './logger';
|
||||
import { MarkdownEngine } from './markdownEngine';
|
||||
import { getMarkdownExtensionContributions } from './markdownExtensions';
|
||||
import { ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector } from './security';
|
||||
import { loadDefaultTelemetryReporter } from './telemetryReporter';
|
||||
import { ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector, ContentSecurityPolicyArbiter } from './security';
|
||||
import { loadDefaultTelemetryReporter, TelemetryReporter } from './telemetryReporter';
|
||||
import { githubSlugifier } from './slugify';
|
||||
|
||||
|
||||
@@ -25,33 +25,55 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(telemetryReporter);
|
||||
|
||||
const contributions = getMarkdownExtensionContributions(context);
|
||||
context.subscriptions.push(contributions);
|
||||
|
||||
const cspArbiter = new ExtensionContentSecurityPolicyArbiter(context.globalState, context.workspaceState);
|
||||
const engine = new MarkdownEngine(contributions, githubSlugifier);
|
||||
const logger = new Logger();
|
||||
|
||||
const selector: vscode.DocumentSelector = [
|
||||
{ language: 'markdown', scheme: 'file' },
|
||||
{ language: 'markdown', scheme: 'untitled' }
|
||||
];
|
||||
|
||||
const contentProvider = new MarkdownContentProvider(engine, context, cspArbiter, contributions, logger);
|
||||
const symbolProvider = new MDDocumentSymbolProvider(engine);
|
||||
const previewManager = new MarkdownPreviewManager(contentProvider, logger, contributions);
|
||||
context.subscriptions.push(previewManager);
|
||||
|
||||
context.subscriptions.push(vscode.languages.setLanguageConfiguration('markdown', {
|
||||
wordPattern: new RegExp('(\\p{Alphabetic}|\\p{Number})+', 'ug'),
|
||||
}));
|
||||
context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(selector, symbolProvider));
|
||||
context.subscriptions.push(vscode.languages.registerDocumentLinkProvider(selector, new LinkProvider()));
|
||||
context.subscriptions.push(vscode.languages.registerFoldingRangeProvider(selector, new MarkdownFoldingProvider(engine)));
|
||||
context.subscriptions.push(vscode.languages.registerWorkspaceSymbolProvider(new MarkdownWorkspaceSymbolProvider(symbolProvider)));
|
||||
context.subscriptions.push(registerMarkdownLanguageFeatures(symbolProvider, engine));
|
||||
context.subscriptions.push(registerMarkdownCommands(previewManager, telemetryReporter, cspArbiter, engine));
|
||||
|
||||
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => {
|
||||
logger.updateConfiguration();
|
||||
previewManager.updateConfiguration();
|
||||
}));
|
||||
}
|
||||
|
||||
function registerMarkdownLanguageFeatures(
|
||||
symbolProvider: MDDocumentSymbolProvider,
|
||||
engine: MarkdownEngine
|
||||
): vscode.Disposable {
|
||||
const selector: vscode.DocumentSelector = [
|
||||
{ language: 'markdown', scheme: 'file' },
|
||||
{ language: 'markdown', scheme: 'untitled' }
|
||||
];
|
||||
|
||||
return vscode.Disposable.from(
|
||||
vscode.languages.setLanguageConfiguration('markdown', {
|
||||
wordPattern: new RegExp('(\\p{Alphabetic}|\\p{Number})+', 'ug'),
|
||||
}),
|
||||
vscode.languages.registerDocumentSymbolProvider(selector, symbolProvider),
|
||||
vscode.languages.registerDocumentLinkProvider(selector, new LinkProvider()),
|
||||
vscode.languages.registerFoldingRangeProvider(selector, new MarkdownFoldingProvider(engine)),
|
||||
vscode.languages.registerWorkspaceSymbolProvider(new MarkdownWorkspaceSymbolProvider(symbolProvider))
|
||||
);
|
||||
}
|
||||
|
||||
function registerMarkdownCommands(
|
||||
previewManager: MarkdownPreviewManager,
|
||||
telemetryReporter: TelemetryReporter,
|
||||
cspArbiter: ContentSecurityPolicyArbiter,
|
||||
engine: MarkdownEngine
|
||||
): vscode.Disposable {
|
||||
const previewSecuritySelector = new PreviewSecuritySelector(cspArbiter, previewManager);
|
||||
|
||||
const commandManager = new CommandManager();
|
||||
context.subscriptions.push(commandManager);
|
||||
commandManager.register(new commands.ShowPreviewCommand(previewManager, telemetryReporter));
|
||||
commandManager.register(new commands.ShowPreviewToSideCommand(previewManager, telemetryReporter));
|
||||
commandManager.register(new commands.ShowLockedPreviewToSideCommand(previewManager, telemetryReporter));
|
||||
@@ -63,9 +85,5 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
commandManager.register(new commands.ToggleLockCommand(previewManager));
|
||||
// {{SQL CARBON EDIT}}
|
||||
commandManager.register(new commands.ShowNotebookPreview(engine));
|
||||
|
||||
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => {
|
||||
logger.updateConfiguration();
|
||||
previewManager.updateConfiguration();
|
||||
}));
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ import * as path from 'path';
|
||||
|
||||
import { Logger } from '../logger';
|
||||
import { MarkdownContentProvider } from './previewContentProvider';
|
||||
import { disposeAll } from '../util/dispose';
|
||||
import { Disposable } from '../util/dispose';
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
import { getVisibleLine, MarkdownFileTopmostLineMonitor } from '../util/topmostLineMonitor';
|
||||
import { MarkdownPreviewConfigurationManager } from './previewConfig';
|
||||
import { MarkdownContributions } from '../markdownExtensions';
|
||||
import { MarkdownContributionProvider, MarkdownContributions } from '../markdownExtensions';
|
||||
import { isMarkdownFile } from '../util/file';
|
||||
import { resolveLinkToMarkdownFile } from '../commands/openDocumentLink';
|
||||
const localize = nls.loadMessageBundle();
|
||||
@@ -60,7 +60,7 @@ interface PreviewStyleLoadErrorMessage extends WebviewMessage {
|
||||
};
|
||||
}
|
||||
|
||||
export class MarkdownPreview {
|
||||
export class MarkdownPreview extends Disposable {
|
||||
|
||||
public static viewType = 'markdown.preview';
|
||||
|
||||
@@ -70,7 +70,6 @@ export class MarkdownPreview {
|
||||
private readonly editor: vscode.WebviewPanel;
|
||||
private throttleTimer: any;
|
||||
private line: number | undefined = undefined;
|
||||
private readonly disposables: vscode.Disposable[] = [];
|
||||
private firstUpdate = true;
|
||||
private currentVersion?: { resource: vscode.Uri, version: number };
|
||||
private forceUpdate = false;
|
||||
@@ -85,7 +84,7 @@ export class MarkdownPreview {
|
||||
previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
logger: Logger,
|
||||
topmostLineMonitor: MarkdownFileTopmostLineMonitor,
|
||||
contributions: MarkdownContributions,
|
||||
contributionProvider: MarkdownContributionProvider,
|
||||
): Promise<MarkdownPreview> {
|
||||
const resource = vscode.Uri.parse(state.resource);
|
||||
const locked = state.locked;
|
||||
@@ -99,9 +98,9 @@ export class MarkdownPreview {
|
||||
previewConfigurations,
|
||||
logger,
|
||||
topmostLineMonitor,
|
||||
contributions);
|
||||
contributionProvider);
|
||||
|
||||
preview.editor.webview.options = MarkdownPreview.getWebviewOptions(resource, contributions);
|
||||
preview.editor.webview.options = MarkdownPreview.getWebviewOptions(resource, contributionProvider.contributions);
|
||||
|
||||
if (!isNaN(line)) {
|
||||
preview.line = line;
|
||||
@@ -118,14 +117,14 @@ export class MarkdownPreview {
|
||||
previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
logger: Logger,
|
||||
topmostLineMonitor: MarkdownFileTopmostLineMonitor,
|
||||
contributions: MarkdownContributions
|
||||
contributionProvider: MarkdownContributionProvider
|
||||
): MarkdownPreview {
|
||||
const webview = vscode.window.createWebviewPanel(
|
||||
MarkdownPreview.viewType,
|
||||
MarkdownPreview.getPreviewTitle(resource, locked),
|
||||
previewColumn, {
|
||||
enableFindWidget: true,
|
||||
...MarkdownPreview.getWebviewOptions(resource, contributions)
|
||||
...MarkdownPreview.getWebviewOptions(resource, contributionProvider.contributions)
|
||||
});
|
||||
|
||||
return new MarkdownPreview(
|
||||
@@ -136,7 +135,7 @@ export class MarkdownPreview {
|
||||
previewConfigurations,
|
||||
logger,
|
||||
topmostLineMonitor,
|
||||
contributions);
|
||||
contributionProvider);
|
||||
}
|
||||
|
||||
private constructor(
|
||||
@@ -147,19 +146,24 @@ export class MarkdownPreview {
|
||||
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
private readonly _logger: Logger,
|
||||
topmostLineMonitor: MarkdownFileTopmostLineMonitor,
|
||||
private readonly _contributions: MarkdownContributions,
|
||||
private readonly _contributionProvider: MarkdownContributionProvider,
|
||||
) {
|
||||
super();
|
||||
this._resource = resource;
|
||||
this._locked = locked;
|
||||
this.editor = webview;
|
||||
|
||||
this.editor.onDidDispose(() => {
|
||||
this.dispose();
|
||||
}, null, this.disposables);
|
||||
}, null, this._disposables);
|
||||
|
||||
this.editor.onDidChangeViewState(e => {
|
||||
this._onDidChangeViewStateEmitter.fire(e);
|
||||
}, null, this.disposables);
|
||||
}, null, this._disposables);
|
||||
|
||||
_contributionProvider.onContributionsChanged(() => {
|
||||
setImmediate(() => this.refresh());
|
||||
}, null, this._disposables);
|
||||
|
||||
this.editor.webview.onDidReceiveMessage((e: CacheImageSizesMessage | RevealLineMessage | DidClickMessage | ClickLinkMessage | ShowPreviewSecuritySelectorMessage | PreviewStyleLoadErrorMessage) => {
|
||||
if (e.source !== this._resource.toString()) {
|
||||
@@ -191,19 +195,19 @@ export class MarkdownPreview {
|
||||
vscode.window.showWarningMessage(localize('onPreviewStyleLoadError', "Could not load 'markdown.styles': {0}", e.body.unloadedStyles.join(', ')));
|
||||
break;
|
||||
}
|
||||
}, null, this.disposables);
|
||||
}, null, this._disposables);
|
||||
|
||||
vscode.workspace.onDidChangeTextDocument(event => {
|
||||
if (this.isPreviewOf(event.document.uri)) {
|
||||
this.refresh();
|
||||
}
|
||||
}, null, this.disposables);
|
||||
}, null, this._disposables);
|
||||
|
||||
topmostLineMonitor.onDidChangeTopmostLine(event => {
|
||||
if (this.isPreviewOf(event.resource)) {
|
||||
this.updateForView(event.resource, event.line);
|
||||
}
|
||||
}, null, this.disposables);
|
||||
}, null, this._disposables);
|
||||
|
||||
vscode.window.onDidChangeTextEditorSelection(event => {
|
||||
if (this.isPreviewOf(event.textEditor.document.uri)) {
|
||||
@@ -213,13 +217,13 @@ export class MarkdownPreview {
|
||||
source: this.resource.toString()
|
||||
});
|
||||
}
|
||||
}, null, this.disposables);
|
||||
}, null, this._disposables);
|
||||
|
||||
vscode.window.onDidChangeActiveTextEditor(editor => {
|
||||
if (editor && isMarkdownFile(editor.document) && !this._locked) {
|
||||
this.update(editor.document.uri);
|
||||
}
|
||||
}, null, this.disposables);
|
||||
}, null, this._disposables);
|
||||
}
|
||||
|
||||
private readonly _onDisposeEmitter = new vscode.EventEmitter<void>();
|
||||
@@ -242,18 +246,17 @@ export class MarkdownPreview {
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
super.dispose();
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._disposed = true;
|
||||
this._onDisposeEmitter.fire();
|
||||
|
||||
this._onDisposeEmitter.dispose();
|
||||
|
||||
this._onDidChangeViewStateEmitter.dispose();
|
||||
this.editor.dispose();
|
||||
|
||||
disposeAll(this.disposables);
|
||||
}
|
||||
|
||||
public update(resource: vscode.Uri) {
|
||||
@@ -328,7 +331,7 @@ export class MarkdownPreview {
|
||||
}
|
||||
|
||||
private get iconPath() {
|
||||
const root = path.join(this._contributions.extensionPath, 'media');
|
||||
const root = path.join(this._contributionProvider.extensionPath, 'media');
|
||||
return {
|
||||
light: vscode.Uri.file(path.join(root, 'Preview.svg')),
|
||||
dark: vscode.Uri.file(path.join(root, 'Preview_inverse.svg'))
|
||||
@@ -392,7 +395,7 @@ export class MarkdownPreview {
|
||||
if (this._resource === resource) {
|
||||
this.editor.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked);
|
||||
this.editor.iconPath = this.iconPath;
|
||||
this.editor.webview.options = MarkdownPreview.getWebviewOptions(resource, this._contributions);
|
||||
this.editor.webview.options = MarkdownPreview.getWebviewOptions(resource, this._contributionProvider.contributions);
|
||||
this.editor.webview.html = content;
|
||||
}
|
||||
}
|
||||
@@ -410,7 +413,7 @@ export class MarkdownPreview {
|
||||
private static getLocalResourceRoots(
|
||||
resource: vscode.Uri,
|
||||
contributions: MarkdownContributions
|
||||
): vscode.Uri[] {
|
||||
): ReadonlyArray<vscode.Uri> {
|
||||
const baseRoots = contributions.previewResourceRoots;
|
||||
|
||||
const folder = vscode.workspace.getWorkspaceFolder(resource);
|
||||
|
||||
@@ -13,7 +13,7 @@ const localize = nls.loadMessageBundle();
|
||||
import { Logger } from '../logger';
|
||||
import { ContentSecurityPolicyArbiter, MarkdownPreviewSecurityLevel } from '../security';
|
||||
import { MarkdownPreviewConfigurationManager, MarkdownPreviewConfiguration } from './previewConfig';
|
||||
import { MarkdownContributions } from '../markdownExtensions';
|
||||
import { MarkdownContributionProvider } from '../markdownExtensions';
|
||||
|
||||
/**
|
||||
* Strings used inside the markdown preview.
|
||||
@@ -40,7 +40,7 @@ export class MarkdownContentProvider {
|
||||
private readonly engine: MarkdownEngine,
|
||||
private readonly context: vscode.ExtensionContext,
|
||||
private readonly cspArbiter: ContentSecurityPolicyArbiter,
|
||||
private readonly contributions: MarkdownContributions,
|
||||
private readonly contributionProvider: MarkdownContributionProvider,
|
||||
private readonly logger: Logger
|
||||
) { }
|
||||
|
||||
@@ -163,7 +163,7 @@ export class MarkdownContentProvider {
|
||||
}
|
||||
|
||||
private getStyles(resource: vscode.Uri, nonce: string, config: MarkdownPreviewConfiguration, state?: any): string {
|
||||
const baseStyles = this.contributions.previewStyles
|
||||
const baseStyles = this.contributionProvider.contributions.previewStyles
|
||||
.map(resource => `<link rel="stylesheet" type="text/css" href="${resource.toString()}">`)
|
||||
.join('\n');
|
||||
|
||||
@@ -174,7 +174,7 @@ export class MarkdownContentProvider {
|
||||
}
|
||||
|
||||
private getScripts(nonce: string): string {
|
||||
return this.contributions.previewScripts
|
||||
return this.contributionProvider.contributions.previewScripts
|
||||
.map(resource => `<script async src="${resource.toString()}" nonce="${nonce}" charset="UTF-8"></script>`)
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { Logger } from '../logger';
|
||||
import { MarkdownContributions } from '../markdownExtensions';
|
||||
import { MarkdownContributionProvider } from '../markdownExtensions';
|
||||
import { disposeAll } from '../util/dispose';
|
||||
import { MarkdownFileTopmostLineMonitor } from '../util/topmostLineMonitor';
|
||||
import { MarkdownPreview, PreviewSettings } from './preview';
|
||||
@@ -25,7 +25,7 @@ export class MarkdownPreviewManager implements vscode.WebviewPanelSerializer {
|
||||
public constructor(
|
||||
private readonly _contentProvider: MarkdownContentProvider,
|
||||
private readonly _logger: Logger,
|
||||
private readonly _contributions: MarkdownContributions
|
||||
private readonly _contributions: MarkdownContributionProvider
|
||||
) {
|
||||
this._disposables.push(vscode.window.registerWebviewPanelSerializer(MarkdownPreview.viewType, this));
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { disposeAll } from '../util/dispose';
|
||||
import { Disposable } from '../util/dispose';
|
||||
import { isMarkdownFile } from '../util/file';
|
||||
import { Lazy, lazy } from '../util/lazy';
|
||||
import MDDocumentSymbolProvider from './documentSymbolProvider';
|
||||
@@ -18,25 +18,13 @@ export interface WorkspaceMarkdownDocumentProvider {
|
||||
readonly onDidDeleteMarkdownDocument: vscode.Event<vscode.Uri>;
|
||||
}
|
||||
|
||||
class VSCodeWorkspaceMarkdownDocumentProvider implements WorkspaceMarkdownDocumentProvider {
|
||||
class VSCodeWorkspaceMarkdownDocumentProvider extends Disposable implements WorkspaceMarkdownDocumentProvider {
|
||||
|
||||
private readonly _onDidChangeMarkdownDocumentEmitter = new vscode.EventEmitter<SkinnyTextDocument>();
|
||||
private readonly _onDidCreateMarkdownDocumentEmitter = new vscode.EventEmitter<SkinnyTextDocument>();
|
||||
private readonly _onDidDeleteMarkdownDocumentEmitter = new vscode.EventEmitter<vscode.Uri>();
|
||||
private readonly _onDidChangeMarkdownDocumentEmitter = this._register(new vscode.EventEmitter<SkinnyTextDocument>());
|
||||
private readonly _onDidCreateMarkdownDocumentEmitter = this._register(new vscode.EventEmitter<SkinnyTextDocument>());
|
||||
private readonly _onDidDeleteMarkdownDocumentEmitter = this._register(new vscode.EventEmitter<vscode.Uri>());
|
||||
|
||||
private _watcher: vscode.FileSystemWatcher | undefined;
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
|
||||
public dispose() {
|
||||
this._onDidChangeMarkdownDocumentEmitter.dispose();
|
||||
this._onDidDeleteMarkdownDocumentEmitter.dispose();
|
||||
|
||||
if (this._watcher) {
|
||||
this._watcher.dispose();
|
||||
}
|
||||
|
||||
disposeAll(this._disposables);
|
||||
}
|
||||
|
||||
async getAllMarkdownDocuments() {
|
||||
const resources = await vscode.workspace.findFiles('**/*.md', '**/node_modules/**');
|
||||
@@ -64,7 +52,7 @@ class VSCodeWorkspaceMarkdownDocumentProvider implements WorkspaceMarkdownDocume
|
||||
return;
|
||||
}
|
||||
|
||||
this._watcher = vscode.workspace.createFileSystemWatcher('**/*.md');
|
||||
this._watcher = this._register(vscode.workspace.createFileSystemWatcher('**/*.md'));
|
||||
|
||||
this._watcher.onDidChange(async resource => {
|
||||
const document = await this.getMarkdownDocument(resource);
|
||||
@@ -98,15 +86,16 @@ class VSCodeWorkspaceMarkdownDocumentProvider implements WorkspaceMarkdownDocume
|
||||
}
|
||||
|
||||
|
||||
export default class MarkdownWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider {
|
||||
export default class MarkdownWorkspaceSymbolProvider extends Disposable implements vscode.WorkspaceSymbolProvider {
|
||||
private _symbolCache = new Map<string, Lazy<Thenable<vscode.SymbolInformation[]>>>();
|
||||
private _symbolCachePopulated: boolean = false;
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
|
||||
public constructor(
|
||||
private _symbolProvider: MDDocumentSymbolProvider,
|
||||
private _workspaceMarkdownDocumentProvider: WorkspaceMarkdownDocumentProvider = new VSCodeWorkspaceMarkdownDocumentProvider()
|
||||
) { }
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
public async provideWorkspaceSymbols(query: string): Promise<vscode.SymbolInformation[]> {
|
||||
if (!this._symbolCachePopulated) {
|
||||
@@ -130,10 +119,6 @@ export default class MarkdownWorkspaceSymbolProvider implements vscode.Workspace
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
disposeAll(this._disposables);
|
||||
}
|
||||
|
||||
private getSymbols(document: SkinnyTextDocument): Lazy<Thenable<vscode.SymbolInformation[]>> {
|
||||
return lazy(async () => {
|
||||
return this._symbolProvider.provideDocumentSymbolInformation(document);
|
||||
|
||||
@@ -7,7 +7,7 @@ import * as crypto from 'crypto';
|
||||
import { MarkdownIt, Token } from 'markdown-it';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import { MarkdownContributions } from './markdownExtensions';
|
||||
import { MarkdownContributionProvider as MarkdownContributionProvider } from './markdownExtensions';
|
||||
import { Slugifier } from './slugify';
|
||||
import { SkinnyTextDocument } from './tableOfContentsProvider';
|
||||
import { getUriForLinkWithKnownExternalScheme } from './util/links';
|
||||
@@ -57,16 +57,21 @@ export class MarkdownEngine {
|
||||
private _tokenCache = new TokenCache();
|
||||
|
||||
public constructor(
|
||||
private readonly extensionPreviewResourceProvider: MarkdownContributions,
|
||||
private readonly contributionProvider: MarkdownContributionProvider,
|
||||
private readonly slugifier: Slugifier,
|
||||
) { }
|
||||
) {
|
||||
contributionProvider.onContributionsChanged(() => {
|
||||
// Markdown plugin contributions may have changed
|
||||
this.md = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
private async getEngine(config: MarkdownItConfig): Promise<MarkdownIt> {
|
||||
if (!this.md) {
|
||||
this.md = import('markdown-it').then(async markdownIt => {
|
||||
let md: MarkdownIt = markdownIt(await getMarkdownOptions(() => md));
|
||||
|
||||
for (const plugin of this.extensionPreviewResourceProvider.markdownItPlugins) {
|
||||
for (const plugin of this.contributionProvider.contributions.markdownItPlugins.values()) {
|
||||
try {
|
||||
md = (await plugin)(md);
|
||||
} catch {
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
import { Disposable } from './util/dispose';
|
||||
import * as arrays from './util/arrays';
|
||||
|
||||
const resolveExtensionResource = (extension: vscode.Extension<any>, resourcePath: string): vscode.Uri => {
|
||||
return vscode.Uri.file(path.join(extension.extensionPath, resourcePath))
|
||||
.with({ scheme: 'vscode-resource' });
|
||||
};
|
||||
|
||||
const resolveExtensionResources = (extension: vscode.Extension<any>, resourcePaths: any): vscode.Uri[] => {
|
||||
const resolveExtensionResources = (extension: vscode.Extension<any>, resourcePaths: unknown): vscode.Uri[] => {
|
||||
const result: vscode.Uri[] = [];
|
||||
if (Array.isArray(resourcePaths)) {
|
||||
for (const resource of resourcePaths) {
|
||||
@@ -26,96 +28,135 @@ const resolveExtensionResources = (extension: vscode.Extension<any>, resourcePat
|
||||
};
|
||||
|
||||
export interface MarkdownContributions {
|
||||
readonly extensionPath: string;
|
||||
readonly previewScripts: vscode.Uri[];
|
||||
readonly previewStyles: vscode.Uri[];
|
||||
readonly markdownItPlugins: Thenable<(md: any) => any>[];
|
||||
readonly previewResourceRoots: vscode.Uri[];
|
||||
readonly previewScripts: ReadonlyArray<vscode.Uri>;
|
||||
readonly previewStyles: ReadonlyArray<vscode.Uri>;
|
||||
readonly previewResourceRoots: ReadonlyArray<vscode.Uri>;
|
||||
readonly markdownItPlugins: Map<string, Thenable<(md: any) => any>>;
|
||||
}
|
||||
|
||||
class MarkdownExtensionContributions implements MarkdownContributions {
|
||||
private readonly _scripts: vscode.Uri[] = [];
|
||||
private readonly _styles: vscode.Uri[] = [];
|
||||
private readonly _previewResourceRoots: vscode.Uri[] = [];
|
||||
private readonly _plugins: Thenable<(md: any) => any>[] = [];
|
||||
export namespace MarkdownContributions {
|
||||
export const Empty: MarkdownContributions = {
|
||||
previewScripts: [],
|
||||
previewStyles: [],
|
||||
previewResourceRoots: [],
|
||||
markdownItPlugins: new Map()
|
||||
};
|
||||
|
||||
private _loaded = false;
|
||||
|
||||
public constructor(
|
||||
public readonly extensionPath: string,
|
||||
) { }
|
||||
|
||||
public get previewScripts(): vscode.Uri[] {
|
||||
this.ensureLoaded();
|
||||
return this._scripts;
|
||||
export function merge(a: MarkdownContributions, b: MarkdownContributions): MarkdownContributions {
|
||||
return {
|
||||
previewScripts: [...a.previewScripts, ...b.previewScripts],
|
||||
previewStyles: [...a.previewStyles, ...b.previewStyles],
|
||||
previewResourceRoots: [...a.previewResourceRoots, ...b.previewResourceRoots],
|
||||
markdownItPlugins: new Map([...a.markdownItPlugins.entries(), ...b.markdownItPlugins.entries()]),
|
||||
};
|
||||
}
|
||||
|
||||
public get previewStyles(): vscode.Uri[] {
|
||||
this.ensureLoaded();
|
||||
return this._styles;
|
||||
function uriEqual(a: vscode.Uri, b: vscode.Uri): boolean {
|
||||
return a.toString() === b.toString();
|
||||
}
|
||||
|
||||
public get previewResourceRoots(): vscode.Uri[] {
|
||||
this.ensureLoaded();
|
||||
return this._previewResourceRoots;
|
||||
export function equal(a: MarkdownContributions, b: MarkdownContributions): boolean {
|
||||
return arrays.equals(a.previewScripts, b.previewScripts, uriEqual)
|
||||
&& arrays.equals(a.previewStyles, b.previewStyles, uriEqual)
|
||||
&& arrays.equals(a.previewResourceRoots, b.previewResourceRoots, uriEqual)
|
||||
&& arrays.equals(Array.from(a.markdownItPlugins.keys()), Array.from(b.markdownItPlugins.keys()));
|
||||
}
|
||||
|
||||
public get markdownItPlugins(): Thenable<(md: any) => any>[] {
|
||||
this.ensureLoaded();
|
||||
return this._plugins;
|
||||
}
|
||||
|
||||
private ensureLoaded() {
|
||||
if (this._loaded) {
|
||||
return;
|
||||
export function fromExtension(
|
||||
extension: vscode.Extension<any>
|
||||
): MarkdownContributions {
|
||||
const contributions = extension.packageJSON && extension.packageJSON.contributes;
|
||||
if (!contributions) {
|
||||
return MarkdownContributions.Empty;
|
||||
}
|
||||
|
||||
this._loaded = true;
|
||||
for (const extension of vscode.extensions.all) {
|
||||
const contributes = extension.packageJSON && extension.packageJSON.contributes;
|
||||
if (!contributes) {
|
||||
continue;
|
||||
}
|
||||
const previewStyles = getContributedStyles(contributions, extension);
|
||||
const previewScripts = getContributedScripts(contributions, extension);
|
||||
const previewResourceRoots = previewStyles.length || previewScripts.length ? [vscode.Uri.file(extension.extensionPath)] : [];
|
||||
const markdownItPlugins = getContributedMarkdownItPlugins(contributions, extension);
|
||||
|
||||
this.tryLoadPreviewStyles(contributes, extension);
|
||||
this.tryLoadPreviewScripts(contributes, extension);
|
||||
this.tryLoadMarkdownItPlugins(contributes, extension);
|
||||
|
||||
if (contributes['markdown.previewScripts'] || contributes['markdown.previewStyles']) {
|
||||
this._previewResourceRoots.push(vscode.Uri.file(extension.extensionPath));
|
||||
}
|
||||
}
|
||||
return {
|
||||
previewScripts,
|
||||
previewStyles,
|
||||
previewResourceRoots,
|
||||
markdownItPlugins
|
||||
};
|
||||
}
|
||||
|
||||
private tryLoadMarkdownItPlugins(
|
||||
function getContributedMarkdownItPlugins(
|
||||
contributes: any,
|
||||
extension: vscode.Extension<any>
|
||||
) {
|
||||
): Map<string, Thenable<(md: any) => any>> {
|
||||
const map = new Map<string, Thenable<(md: any) => any>>();
|
||||
if (contributes['markdown.markdownItPlugins']) {
|
||||
this._plugins.push(extension.activate().then(() => {
|
||||
map.set(extension.id, extension.activate().then(() => {
|
||||
if (extension.exports && extension.exports.extendMarkdownIt) {
|
||||
return (md: any) => extension.exports.extendMarkdownIt(md);
|
||||
}
|
||||
return (md: any) => md;
|
||||
}));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private tryLoadPreviewScripts(
|
||||
function getContributedScripts(
|
||||
contributes: any,
|
||||
extension: vscode.Extension<any>
|
||||
) {
|
||||
this._scripts.push(...resolveExtensionResources(extension, contributes['markdown.previewScripts']));
|
||||
return resolveExtensionResources(extension, contributes['markdown.previewScripts']);
|
||||
}
|
||||
|
||||
private tryLoadPreviewStyles(
|
||||
function getContributedStyles(
|
||||
contributes: any,
|
||||
extension: vscode.Extension<any>
|
||||
) {
|
||||
this._styles.push(...resolveExtensionResources(extension, contributes['markdown.previewStyles']));
|
||||
return resolveExtensionResources(extension, contributes['markdown.previewStyles']);
|
||||
}
|
||||
}
|
||||
|
||||
export function getMarkdownExtensionContributions(context: vscode.ExtensionContext): MarkdownContributions {
|
||||
return new MarkdownExtensionContributions(context.extensionPath);
|
||||
export interface MarkdownContributionProvider {
|
||||
readonly extensionPath: string;
|
||||
readonly contributions: MarkdownContributions;
|
||||
readonly onContributionsChanged: vscode.Event<this>;
|
||||
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
class VSCodeExtensionMarkdownContributionProvider extends Disposable implements MarkdownContributionProvider {
|
||||
private _contributions?: MarkdownContributions;
|
||||
|
||||
public constructor(
|
||||
public readonly extensionPath: string,
|
||||
) {
|
||||
super();
|
||||
|
||||
vscode.extensions.onDidChange(() => {
|
||||
const currentContributions = this.getCurrentContributions();
|
||||
const existingContributions = this._contributions || MarkdownContributions.Empty;
|
||||
if (!MarkdownContributions.equal(existingContributions, currentContributions)) {
|
||||
this._contributions = currentContributions;
|
||||
this._onContributionsChanged.fire(this);
|
||||
}
|
||||
}, undefined, this._disposables);
|
||||
}
|
||||
|
||||
private readonly _onContributionsChanged = this._register(new vscode.EventEmitter<this>());
|
||||
public readonly onContributionsChanged = this._onContributionsChanged.event;
|
||||
|
||||
public get contributions(): MarkdownContributions {
|
||||
if (!this._contributions) {
|
||||
this._contributions = this.getCurrentContributions();
|
||||
}
|
||||
return this._contributions;
|
||||
}
|
||||
|
||||
private getCurrentContributions(): MarkdownContributions {
|
||||
return vscode.extensions.all
|
||||
.map(MarkdownContributions.fromExtension)
|
||||
.reduce(MarkdownContributions.merge, MarkdownContributions.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
export function getMarkdownExtensionContributions(context: vscode.ExtensionContext): MarkdownContributionProvider {
|
||||
return new VSCodeExtensionMarkdownContributionProvider(context.extensionPath);
|
||||
}
|
||||
@@ -5,15 +5,14 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { MarkdownEngine } from '../markdownEngine';
|
||||
import { MarkdownContributions } from '../markdownExtensions';
|
||||
import { MarkdownContributionProvider, MarkdownContributions } from '../markdownExtensions';
|
||||
import { githubSlugifier } from '../slugify';
|
||||
import { Disposable } from '../util/dispose';
|
||||
|
||||
const emptyContributions = new class implements MarkdownContributions {
|
||||
const emptyContributions = new class extends Disposable implements MarkdownContributionProvider {
|
||||
readonly extensionPath = '';
|
||||
readonly previewScripts: vscode.Uri[] = [];
|
||||
readonly previewStyles: vscode.Uri[] = [];
|
||||
readonly previewResourceRoots: vscode.Uri[] = [];
|
||||
readonly markdownItPlugins: Promise<(md: any) => any>[] = [];
|
||||
readonly contributions = MarkdownContributions.Empty;
|
||||
readonly onContributionsChanged = this._register(new vscode.EventEmitter<this>()).event;
|
||||
};
|
||||
|
||||
export function createNewMarkdownEngine(): MarkdownEngine {
|
||||
|
||||
@@ -38,7 +38,7 @@ suite('markdown.WorkspaceSymbolProvider', () => {
|
||||
const fileNameCount = 10;
|
||||
const files: vscode.TextDocument[] = [];
|
||||
for (let i = 0; i < fileNameCount; ++i) {
|
||||
const testFileName = vscode.Uri.parse(`test${i}.md`);
|
||||
const testFileName = vscode.Uri.file(`test${i}.md`);
|
||||
files.push(new InMemoryDocument(testFileName, `# common\nabc\n## header${i}`));
|
||||
}
|
||||
|
||||
|
||||
18
extensions/markdown-language-features/src/util/arrays.ts
Normal file
18
extensions/markdown-language-features/src/util/arrays.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export function equals<T>(one: ReadonlyArray<T>, other: ReadonlyArray<T>, itemEquals: (a: T, b: T) => boolean = (a, b) => a === b): boolean {
|
||||
if (one.length !== other.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0, len = one.length; i < len; i++) {
|
||||
if (!itemEquals(one[i], other[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -14,3 +14,29 @@ export function disposeAll(disposables: vscode.Disposable[]) {
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class Disposable {
|
||||
private _isDisposed = false;
|
||||
|
||||
protected _disposables: vscode.Disposable[] = [];
|
||||
|
||||
public dispose(): any {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
this._isDisposed = true;
|
||||
disposeAll(this._disposables);
|
||||
}
|
||||
|
||||
protected _register<T extends vscode.Disposable>(value: T): T {
|
||||
if (this._isDisposed) {
|
||||
value.dispose();
|
||||
} else {
|
||||
this._disposables.push(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
protected get isDisposed() {
|
||||
return this._isDisposed;
|
||||
}
|
||||
}
|
||||
@@ -29,10 +29,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.2.tgz#5d9ad19e6e6508cdd2f2596df86fd0aade598660"
|
||||
integrity sha1-XZrRnm5lCM3S8llt+G/Qqt5ZhmA=
|
||||
|
||||
"@types/node@^8.10.25":
|
||||
version "8.10.25"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.25.tgz#801fe4e39372cef18f268db880a5fbfcf71adc7e"
|
||||
integrity sha512-WXvAXaknB0c2cJ7N44e1kUrVu5K90mSfPPaT5XxfuSMxEWva86EYIwxUZM3jNZ2P1CIC9e2z4WJqpAF69PQxeA==
|
||||
"@types/node@^10.12.21":
|
||||
version "10.12.21"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.21.tgz#7e8a0c34cf29f4e17a36e9bd0ea72d45ba03908e"
|
||||
integrity sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==
|
||||
|
||||
abbrev@1:
|
||||
version "1.1.1"
|
||||
@@ -6010,10 +6010,10 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||
|
||||
typescript@^2.7.2:
|
||||
version "2.7.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836"
|
||||
integrity sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==
|
||||
typescript@^3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.1.tgz#6de14e1db4b8a006ac535e482c8ba018c55f750b"
|
||||
integrity sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==
|
||||
|
||||
uc.micro@^1.0.1:
|
||||
version "1.0.3"
|
||||
|
||||
Reference in New Issue
Block a user