提交 82d97b4c 编写于 作者: M Matt Bierner

Add acquireVsCodeApi to get handle to vscode api inside webview

Fixes #48540
上级 6d7bb1a1
......@@ -3,33 +3,48 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { MessagePoster } from './messaging';
import { getSettings } from './settings';
import { getStrings } from './strings';
import { postCommand } from './messaging';
/**
* Shows an alert when there is a content security policy violation.
*/
export class CspAlerter {
private didShow = false;
private didHaveCspWarning = false;
private messaging?: MessagePoster;
constructor() {
document.addEventListener('securitypolicyviolation', () => {
this.showCspWarning();
this.onCspWarning();
});
window.addEventListener('message', (event) => {
if (event && event.data && event.data.name === 'vscode-did-block-svg') {
this.showCspWarning();
this.onCspWarning();
}
});
}
public setPoster(poster: MessagePoster) {
this.messaging = poster;
if (this.didHaveCspWarning) {
this.showCspWarning();
}
}
private onCspWarning() {
this.didHaveCspWarning = true;
this.showCspWarning();
}
private showCspWarning() {
const strings = getStrings();
const settings = getSettings();
if (this.didShow || settings.disableSecurityWarnings) {
if (this.didShow || settings.disableSecurityWarnings || !this.messaging) {
return;
}
this.didShow = true;
......@@ -42,7 +57,7 @@ export class CspAlerter {
notification.setAttribute('role', 'button');
notification.setAttribute('aria-label', strings.cspAlertMessageLabel);
notification.onclick = () => {
postCommand('markdown.showPreviewSecuritySelector', [settings.source]);
this.messaging!.postCommand('markdown.showPreviewSecuritySelector', [settings.source]);
};
document.body.appendChild(notification);
}
......
......@@ -3,17 +3,27 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { getSettings } from './settings';
import { postCommand, postMessage } from './messaging';
import { ActiveLineMarker } from './activeLineMarker';
import { onceDocumentLoaded } from './events';
import { createPosterForVsCode } from './messaging';
import { getEditorLineNumberForPageOffset, scrollToRevealSourceLine } from './scroll-sync';
import { ActiveLineMarker } from './activeLineMarker';
import { getSettings } from './settings';
import throttle = require('lodash.throttle');
declare var acquireVsCodeApi: any;
var scrollDisabled = true;
const marker = new ActiveLineMarker();
const settings = getSettings();
const vscode = acquireVsCodeApi();
vscode.postMessage({});
const messaging = createPosterForVsCode(vscode);
window.cspAlerter.setPoster(messaging);
window.styleLoadingMonitor.setPoster(messaging);
onceDocumentLoaded(() => {
if (settings.scrollPreviewWithEditor) {
setTimeout(() => {
......@@ -75,7 +85,7 @@ document.addEventListener('dblclick', event => {
const offset = event.pageY;
const line = getEditorLineNumberForPageOffset(offset);
if (typeof line === 'number' && !isNaN(line)) {
postMessage('didClick', { line: Math.floor(line) });
messaging.postMessage('didClick', { line: Math.floor(line) });
}
});
......@@ -92,7 +102,7 @@ document.addEventListener('click', event => {
}
if (node.href.startsWith('file://') || node.href.startsWith('vscode-resource:')) {
const [path, fragment] = node.href.replace(/^(file:\/\/|vscode-resource:)/i, '').split('#');
postCommand('_markdown.openDocumentLink', [{ path, fragment }]);
messaging.postCommand('_markdown.openDocumentLink', [{ path, fragment }]);
event.preventDefault();
event.stopPropagation();
break;
......@@ -110,7 +120,7 @@ if (settings.scrollEditorWithPreview) {
} else {
const line = getEditorLineNumberForPageOffset(window.scrollY);
if (typeof line === 'number' && !isNaN(line)) {
postMessage('revealLine', { line });
messaging.postMessage('revealLine', { line });
}
}
}, 50));
......
......@@ -2,10 +2,13 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { postCommand } from './messaging';
import { MessagePoster } from './messaging';
export class StyleLoadingMonitor {
private unloadedStyles: string[] = [];
private finishedLoading: boolean = false;
private poster?: MessagePoster;
constructor() {
const onStyleLoadError = (event: any) => {
......@@ -25,7 +28,17 @@ export class StyleLoadingMonitor {
if (!this.unloadedStyles.length) {
return;
}
postCommand('_markdown.onPreviewStyleLoadError', [this.unloadedStyles]);
this.finishedLoading = true;
if (this.poster) {
this.poster.postCommand('_markdown.onPreviewStyleLoadError', [this.unloadedStyles]);
}
});
}
public setPoster(poster: MessagePoster): void {
this.poster = poster;
if (this.finishedLoading) {
poster.postCommand('_markdown.onPreviewStyleLoadError', [this.unloadedStyles]);
}
}
}
\ No newline at end of file
......@@ -5,22 +5,31 @@
import { getSettings } from './settings';
declare var vscode: any;
export interface MessagePoster {
/**
* Post a message to the markdown extension
*/
postMessage(type: string, body: object): void;
/**
* Post a message to the markdown extension
*/
export function postMessage(type: string, body: object) {
vscode.postMessage({
type,
source: getSettings().source,
body
});
}
/**
* Post a command to be executed to the markdown extension
*/
export function postCommand(command: string, args: any[]) {
postMessage('command', { command, args });
/**
* Post a command to be executed to the markdown extension
*/
postCommand(command: string, args: any[]): void;
}
export const createPosterForVsCode = (vscode: any) => {
return new class implements MessagePoster {
postMessage(type: string, body: object): void {
vscode.postMessage({
type,
source: getSettings().source,
body
});
}
postCommand(command: string, args: any[]) {
this.postMessage('command', { command, args });
}
};
};
......@@ -6,8 +6,12 @@
import { CspAlerter } from './csp';
import { StyleLoadingMonitor } from './loading';
// tslint:disable-next-line:no-unused-expression
new CspAlerter();
declare global {
interface Window {
cspAlerter: CspAlerter;
styleLoadingMonitor: StyleLoadingMonitor;
}
}
// tslint:disable-next-line:no-unused-expression
new StyleLoadingMonitor();
\ No newline at end of file
window.cspAlerter = new CspAlerter();
window.styleLoadingMonitor = new StyleLoadingMonitor();
\ No newline at end of file
......@@ -178,15 +178,25 @@
if (enableWrappedPostMessage) {
const defaultScript = newDocument.createElement('script');
defaultScript.textContent = `
const vscode = Object.freeze((function() {
const acquireVsCodeApi = (function() {
const originalPostMessage = window.parent.postMessage.bind(window.parent);
return {
postMessage: function(msg) {
return originalPostMessage(msg, '*');
let acquired = false;
return () => {
if (acquired) {
throw new Error('An instance of the VS Code API has already been acquired');
}
acquired = true;
return Object.freeze({
postMessage: function(msg) {
return originalPostMessage(msg, '*');
}
});
};
})());
})();
delete window.parent;
delete window.top;
delete window.frameElement;
`;
if (newDocument.head.hasChildNodes()) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册