mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-24 12:19:20 +00:00
Add acquireVsCodeApi to get handle to vscode api inside webview
Fixes #48540
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -3,33 +3,48 @@
|
|||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { MessagePoster } from './messaging';
|
||||||
import { getSettings } from './settings';
|
import { getSettings } from './settings';
|
||||||
import { getStrings } from './strings';
|
import { getStrings } from './strings';
|
||||||
import { postCommand } from './messaging';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows an alert when there is a content security policy violation.
|
* Shows an alert when there is a content security policy violation.
|
||||||
*/
|
*/
|
||||||
export class CspAlerter {
|
export class CspAlerter {
|
||||||
private didShow = false;
|
private didShow = false;
|
||||||
|
private didHaveCspWarning = false;
|
||||||
|
|
||||||
|
private messaging?: MessagePoster;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
document.addEventListener('securitypolicyviolation', () => {
|
document.addEventListener('securitypolicyviolation', () => {
|
||||||
this.showCspWarning();
|
this.onCspWarning();
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('message', (event) => {
|
window.addEventListener('message', (event) => {
|
||||||
if (event && event.data && event.data.name === 'vscode-did-block-svg') {
|
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() {
|
private showCspWarning() {
|
||||||
const strings = getStrings();
|
const strings = getStrings();
|
||||||
const settings = getSettings();
|
const settings = getSettings();
|
||||||
|
|
||||||
if (this.didShow || settings.disableSecurityWarnings) {
|
if (this.didShow || settings.disableSecurityWarnings || !this.messaging) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.didShow = true;
|
this.didShow = true;
|
||||||
@@ -42,7 +57,7 @@ export class CspAlerter {
|
|||||||
notification.setAttribute('role', 'button');
|
notification.setAttribute('role', 'button');
|
||||||
notification.setAttribute('aria-label', strings.cspAlertMessageLabel);
|
notification.setAttribute('aria-label', strings.cspAlertMessageLabel);
|
||||||
notification.onclick = () => {
|
notification.onclick = () => {
|
||||||
postCommand('markdown.showPreviewSecuritySelector', [settings.source]);
|
this.messaging!.postCommand('markdown.showPreviewSecuritySelector', [settings.source]);
|
||||||
};
|
};
|
||||||
document.body.appendChild(notification);
|
document.body.appendChild(notification);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,27 @@
|
|||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* 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 { onceDocumentLoaded } from './events';
|
|
||||||
import { getEditorLineNumberForPageOffset, scrollToRevealSourceLine } from './scroll-sync';
|
|
||||||
import { ActiveLineMarker } from './activeLineMarker';
|
import { ActiveLineMarker } from './activeLineMarker';
|
||||||
|
import { onceDocumentLoaded } from './events';
|
||||||
|
import { createPosterForVsCode } from './messaging';
|
||||||
|
import { getEditorLineNumberForPageOffset, scrollToRevealSourceLine } from './scroll-sync';
|
||||||
|
import { getSettings } from './settings';
|
||||||
import throttle = require('lodash.throttle');
|
import throttle = require('lodash.throttle');
|
||||||
|
|
||||||
|
declare var acquireVsCodeApi: any;
|
||||||
|
|
||||||
var scrollDisabled = true;
|
var scrollDisabled = true;
|
||||||
const marker = new ActiveLineMarker();
|
const marker = new ActiveLineMarker();
|
||||||
const settings = getSettings();
|
const settings = getSettings();
|
||||||
|
|
||||||
|
const vscode = acquireVsCodeApi();
|
||||||
|
vscode.postMessage({});
|
||||||
|
|
||||||
|
const messaging = createPosterForVsCode(vscode);
|
||||||
|
|
||||||
|
window.cspAlerter.setPoster(messaging);
|
||||||
|
window.styleLoadingMonitor.setPoster(messaging);
|
||||||
|
|
||||||
onceDocumentLoaded(() => {
|
onceDocumentLoaded(() => {
|
||||||
if (settings.scrollPreviewWithEditor) {
|
if (settings.scrollPreviewWithEditor) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -75,7 +85,7 @@ document.addEventListener('dblclick', event => {
|
|||||||
const offset = event.pageY;
|
const offset = event.pageY;
|
||||||
const line = getEditorLineNumberForPageOffset(offset);
|
const line = getEditorLineNumberForPageOffset(offset);
|
||||||
if (typeof line === 'number' && !isNaN(line)) {
|
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:')) {
|
if (node.href.startsWith('file://') || node.href.startsWith('vscode-resource:')) {
|
||||||
const [path, fragment] = node.href.replace(/^(file:\/\/|vscode-resource:)/i, '').split('#');
|
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.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
break;
|
break;
|
||||||
@@ -110,7 +120,7 @@ if (settings.scrollEditorWithPreview) {
|
|||||||
} else {
|
} else {
|
||||||
const line = getEditorLineNumberForPageOffset(window.scrollY);
|
const line = getEditorLineNumberForPageOffset(window.scrollY);
|
||||||
if (typeof line === 'number' && !isNaN(line)) {
|
if (typeof line === 'number' && !isNaN(line)) {
|
||||||
postMessage('revealLine', { line });
|
messaging.postMessage('revealLine', { line });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 50));
|
}, 50));
|
||||||
|
|||||||
@@ -2,10 +2,13 @@
|
|||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* 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 {
|
export class StyleLoadingMonitor {
|
||||||
private unloadedStyles: string[] = [];
|
private unloadedStyles: string[] = [];
|
||||||
|
private finishedLoading: boolean = false;
|
||||||
|
|
||||||
|
private poster?: MessagePoster;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
const onStyleLoadError = (event: any) => {
|
const onStyleLoadError = (event: any) => {
|
||||||
@@ -25,7 +28,17 @@ export class StyleLoadingMonitor {
|
|||||||
if (!this.unloadedStyles.length) {
|
if (!this.unloadedStyles.length) {
|
||||||
return;
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,22 +5,31 @@
|
|||||||
|
|
||||||
import { getSettings } from './settings';
|
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
|
/**
|
||||||
*/
|
* Post a command to be executed to the markdown extension
|
||||||
export function postMessage(type: string, body: object) {
|
*/
|
||||||
vscode.postMessage({
|
postCommand(command: string, args: any[]): void;
|
||||||
type,
|
|
||||||
source: getSettings().source,
|
|
||||||
body
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export const createPosterForVsCode = (vscode: any) => {
|
||||||
* Post a command to be executed to the markdown extension
|
return new class implements MessagePoster {
|
||||||
*/
|
postMessage(type: string, body: object): void {
|
||||||
export function postCommand(command: string, args: any[]) {
|
vscode.postMessage({
|
||||||
postMessage('command', { command, args });
|
type,
|
||||||
}
|
source: getSettings().source,
|
||||||
|
body
|
||||||
|
});
|
||||||
|
}
|
||||||
|
postCommand(command: string, args: any[]) {
|
||||||
|
this.postMessage('command', { command, args });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,12 @@
|
|||||||
import { CspAlerter } from './csp';
|
import { CspAlerter } from './csp';
|
||||||
import { StyleLoadingMonitor } from './loading';
|
import { StyleLoadingMonitor } from './loading';
|
||||||
|
|
||||||
// tslint:disable-next-line:no-unused-expression
|
declare global {
|
||||||
new CspAlerter();
|
interface Window {
|
||||||
|
cspAlerter: CspAlerter;
|
||||||
|
styleLoadingMonitor: StyleLoadingMonitor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// tslint:disable-next-line:no-unused-expression
|
window.cspAlerter = new CspAlerter();
|
||||||
new StyleLoadingMonitor();
|
window.styleLoadingMonitor = new StyleLoadingMonitor();
|
||||||
@@ -178,15 +178,25 @@
|
|||||||
if (enableWrappedPostMessage) {
|
if (enableWrappedPostMessage) {
|
||||||
const defaultScript = newDocument.createElement('script');
|
const defaultScript = newDocument.createElement('script');
|
||||||
defaultScript.textContent = `
|
defaultScript.textContent = `
|
||||||
const vscode = Object.freeze((function() {
|
const acquireVsCodeApi = (function() {
|
||||||
const originalPostMessage = window.parent.postMessage.bind(window.parent);
|
const originalPostMessage = window.parent.postMessage.bind(window.parent);
|
||||||
return {
|
let acquired = false;
|
||||||
postMessage: function(msg) {
|
|
||||||
return originalPostMessage(msg, '*');
|
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.parent;
|
||||||
|
delete window.top;
|
||||||
|
delete window.frameElement;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if (newDocument.head.hasChildNodes()) {
|
if (newDocument.head.hasChildNodes()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user