Second prototype of markdown extensions (#22836)

This commit is contained in:
Matt Bierner 2017-03-20 11:16:18 -07:00 committed by GitHub
parent 188ef21ab3
commit 4f8e68b814
3 changed files with 48 additions and 20 deletions

View file

@ -40,7 +40,7 @@ interface PreviewSecurityPickItem extends vscode.QuickPickItem {
id: PreviewSecuritySelection;
}
class ExtensionContentSecurityProlicyArbiter implements ContentSecurityPolicyArbiter {
class ExtensionContentSecurityPolicyArbiter implements ContentSecurityPolicyArbiter {
private readonly key = 'trusted_preview_workspace:';
constructor(
@ -58,9 +58,16 @@ class ExtensionContentSecurityProlicyArbiter implements ContentSecurityPolicyArb
public removeTrustedWorkspace(rootPath: string): Thenable<void> {
return this.globalState.update(this.key + rootPath, false);
}
}
const resolveExtensionResources = (extension: vscode.Extension<any>, stylePath: string): vscode.Uri => {
const resource = vscode.Uri.parse(stylePath);
if (resource.scheme) {
return resource;
}
return vscode.Uri.file(path.join(extension.extensionPath, stylePath));
};
var telemetryReporter: TelemetryReporter | null;
export function activate(context: vscode.ExtensionContext) {
@ -70,12 +77,43 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(telemetryReporter);
}
const cspArbiter = new ExtensionContentSecurityProlicyArbiter(context.globalState);
const cspArbiter = new ExtensionContentSecurityPolicyArbiter(context.globalState);
const engine = new MarkdownEngine();
const contentProvider = new MDDocumentContentProvider(engine, context, cspArbiter);
const contentProviderRegistration = vscode.workspace.registerTextDocumentContentProvider('markdown', contentProvider);
if (vscode.workspace.getConfiguration('markdown').get('enableExperimentalExtensionApi', false)) {
for (const extension of vscode.extensions.all) {
const contributes = extension.packageJSON && extension.packageJSON.contributes;
if (!contributes) {
continue;
}
let styles = contributes['markdown.preview'] && contributes['markdown.preview'].styles;
if (styles) {
if (!Array.isArray(styles)) {
styles = [styles];
}
for (const style of styles) {
try {
contentProvider.addStyle(resolveExtensionResources(extension, style));
} catch (e) {
// noop
}
}
}
if (contributes['markdownit.plugins']) {
extension.activate().then(() => {
if (extension.exports && extension.exports.extendMarkdownIt) {
engine.addPlugin((md: any) => extension.exports.extendMarkdownIt(md));
}
});
}
}
}
const symbolsProvider = new MDDocumentSymbolProvider(engine);
const symbolsProviderRegistration = vscode.languages.registerDocumentSymbolProvider({ language: 'markdown' }, symbolsProvider);
context.subscriptions.push(contentProviderRegistration, symbolsProviderRegistration);
@ -231,18 +269,6 @@ export function activate(context: vscode.ExtensionContext) {
});
}
}));
if (vscode.workspace.getConfiguration('markdown').get('enableExperimentalExtensionApi', false)) {
vscode.commands.executeCommand('_markdown.onActivateExtensions')
.then(() => void 0, () => void 0);
return {
addPlugin(factory: (md: any) => any) {
engine.addPlugin(factory);
}
};
}
return undefined;
}

View file

@ -33,8 +33,6 @@ export class MarkdownEngine {
private plugins: Array<(md: any) => any> = [];
constructor() { }
public addPlugin(factory: (md: any) => any): void {
if (this.md) {
this.usePlugin(factory);

View file

@ -28,6 +28,7 @@ export function getMarkdownUri(uri: vscode.Uri) {
export class MDDocumentContentProvider implements vscode.TextDocumentContentProvider {
private _onDidChange = new vscode.EventEmitter<vscode.Uri>();
private _waiting: boolean = false;
private extraStyles: Array<vscode.Uri> = [];
constructor(
private engine: MarkdownEngine,
@ -35,6 +36,10 @@ export class MDDocumentContentProvider implements vscode.TextDocumentContentProv
private cspArbiter: ContentSecurityPolicyArbiter
) { }
public addStyle(resource: vscode.Uri): void {
this.extraStyles.push(resource);
}
private getMediaPath(mediaFile: string): string {
return vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile))).toString();
}
@ -97,7 +102,7 @@ export class MDDocumentContentProvider implements vscode.TextDocumentContentProv
const baseStyles = [
this.getMediaPath('markdown.css'),
this.getMediaPath('tomorrow.css')
];
].concat(this.extraStyles.map(resource => resource.toString()));
return `${baseStyles.map(href => `<link rel="stylesheet" type="text/css" href="${href}">`).join('\n')}
${this.getSettingsOverrideStyles(nonce)}
@ -105,8 +110,7 @@ export class MDDocumentContentProvider implements vscode.TextDocumentContentProv
}
private getScripts(nonce: string): string {
const scripts = [this.getMediaPath('main.js')];
return scripts
return [this.getMediaPath('main.js')]
.map(source => `<script src="${source}" nonce="${nonce}"></script>`)
.join('\n');
}