monaco-editor-core
Version:
A browser based code editor
278 lines (277 loc) • 10.4 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as errors from './errors.js';
import * as platform from './platform.js';
import { equalsIgnoreCase, startsWithIgnoreCase } from './strings.js';
import { URI } from './uri.js';
import * as paths from './path.js';
export var Schemas;
(function (Schemas) {
/**
* A schema that is used for models that exist in memory
* only and that have no correspondence on a server or such.
*/
Schemas.inMemory = 'inmemory';
/**
* A schema that is used for setting files
*/
Schemas.vscode = 'vscode';
/**
* A schema that is used for internal private files
*/
Schemas.internal = 'private';
/**
* A walk-through document.
*/
Schemas.walkThrough = 'walkThrough';
/**
* An embedded code snippet.
*/
Schemas.walkThroughSnippet = 'walkThroughSnippet';
Schemas.http = 'http';
Schemas.https = 'https';
Schemas.file = 'file';
Schemas.mailto = 'mailto';
Schemas.untitled = 'untitled';
Schemas.data = 'data';
Schemas.command = 'command';
Schemas.vscodeRemote = 'vscode-remote';
Schemas.vscodeRemoteResource = 'vscode-remote-resource';
Schemas.vscodeManagedRemoteResource = 'vscode-managed-remote-resource';
Schemas.vscodeUserData = 'vscode-userdata';
Schemas.vscodeCustomEditor = 'vscode-custom-editor';
Schemas.vscodeNotebookCell = 'vscode-notebook-cell';
Schemas.vscodeNotebookCellMetadata = 'vscode-notebook-cell-metadata';
Schemas.vscodeNotebookCellMetadataDiff = 'vscode-notebook-cell-metadata-diff';
Schemas.vscodeNotebookCellOutput = 'vscode-notebook-cell-output';
Schemas.vscodeNotebookCellOutputDiff = 'vscode-notebook-cell-output-diff';
Schemas.vscodeNotebookMetadata = 'vscode-notebook-metadata';
Schemas.vscodeInteractiveInput = 'vscode-interactive-input';
Schemas.vscodeSettings = 'vscode-settings';
Schemas.vscodeWorkspaceTrust = 'vscode-workspace-trust';
Schemas.vscodeTerminal = 'vscode-terminal';
/** Scheme used for code blocks in chat. */
Schemas.vscodeChatCodeBlock = 'vscode-chat-code-block';
/** Scheme used for LHS of code compare (aka diff) blocks in chat. */
Schemas.vscodeChatCodeCompareBlock = 'vscode-chat-code-compare-block';
/** Scheme used for the chat input editor. */
Schemas.vscodeChatSesssion = 'vscode-chat-editor';
/**
* Scheme used internally for webviews that aren't linked to a resource (i.e. not custom editors)
*/
Schemas.webviewPanel = 'webview-panel';
/**
* Scheme used for loading the wrapper html and script in webviews.
*/
Schemas.vscodeWebview = 'vscode-webview';
/**
* Scheme used for extension pages
*/
Schemas.extension = 'extension';
/**
* Scheme used as a replacement of `file` scheme to load
* files with our custom protocol handler (desktop only).
*/
Schemas.vscodeFileResource = 'vscode-file';
/**
* Scheme used for temporary resources
*/
Schemas.tmp = 'tmp';
/**
* Scheme used vs live share
*/
Schemas.vsls = 'vsls';
/**
* Scheme used for the Source Control commit input's text document
*/
Schemas.vscodeSourceControl = 'vscode-scm';
/**
* Scheme used for input box for creating comments.
*/
Schemas.commentsInput = 'comment';
/**
* Scheme used for special rendering of settings in the release notes
*/
Schemas.codeSetting = 'code-setting';
/**
* Scheme used for output panel resources
*/
Schemas.outputChannel = 'output';
})(Schemas || (Schemas = {}));
export function matchesScheme(target, scheme) {
if (URI.isUri(target)) {
return equalsIgnoreCase(target.scheme, scheme);
}
else {
return startsWithIgnoreCase(target, scheme + ':');
}
}
export function matchesSomeScheme(target, ...schemes) {
return schemes.some(scheme => matchesScheme(target, scheme));
}
export const connectionTokenQueryName = 'tkn';
class RemoteAuthoritiesImpl {
constructor() {
this._hosts = Object.create(null);
this._ports = Object.create(null);
this._connectionTokens = Object.create(null);
this._preferredWebSchema = 'http';
this._delegate = null;
this._serverRootPath = '/';
}
setPreferredWebSchema(schema) {
this._preferredWebSchema = schema;
}
get _remoteResourcesPath() {
return paths.posix.join(this._serverRootPath, Schemas.vscodeRemoteResource);
}
rewrite(uri) {
if (this._delegate) {
try {
return this._delegate(uri);
}
catch (err) {
errors.onUnexpectedError(err);
return uri;
}
}
const authority = uri.authority;
let host = this._hosts[authority];
if (host && host.indexOf(':') !== -1 && host.indexOf('[') === -1) {
host = `[${host}]`;
}
const port = this._ports[authority];
const connectionToken = this._connectionTokens[authority];
let query = `path=${encodeURIComponent(uri.path)}`;
if (typeof connectionToken === 'string') {
query += `&${connectionTokenQueryName}=${encodeURIComponent(connectionToken)}`;
}
return URI.from({
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
authority: `${host}:${port}`,
path: this._remoteResourcesPath,
query
});
}
}
export const RemoteAuthorities = new RemoteAuthoritiesImpl();
export const VSCODE_AUTHORITY = 'vscode-app';
class FileAccessImpl {
static { this.FALLBACK_AUTHORITY = VSCODE_AUTHORITY; }
/**
* Returns a URI to use in contexts where the browser is responsible
* for loading (e.g. fetch()) or when used within the DOM.
*
* **Note:** use `dom.ts#asCSSUrl` whenever the URL is to be used in CSS context.
*/
asBrowserUri(resourcePath) {
// ESM-comment-begin
// const uri = this.toUri(resourcePath, require);
// ESM-comment-end
// ESM-uncomment-begin
const uri = this.toUri(resourcePath);
// ESM-uncomment-end
return this.uriToBrowserUri(uri);
}
/**
* Returns a URI to use in contexts where the browser is responsible
* for loading (e.g. fetch()) or when used within the DOM.
*
* **Note:** use `dom.ts#asCSSUrl` whenever the URL is to be used in CSS context.
*/
uriToBrowserUri(uri) {
// Handle remote URIs via `RemoteAuthorities`
if (uri.scheme === Schemas.vscodeRemote) {
return RemoteAuthorities.rewrite(uri);
}
// Convert to `vscode-file` resource..
if (
// ...only ever for `file` resources
uri.scheme === Schemas.file &&
(
// ...and we run in native environments
platform.isNative ||
// ...or web worker extensions on desktop
(platform.webWorkerOrigin === `${Schemas.vscodeFileResource}://${FileAccessImpl.FALLBACK_AUTHORITY}`))) {
return uri.with({
scheme: Schemas.vscodeFileResource,
// We need to provide an authority here so that it can serve
// as origin for network and loading matters in chromium.
// If the URI is not coming with an authority already, we
// add our own
authority: uri.authority || FileAccessImpl.FALLBACK_AUTHORITY,
query: null,
fragment: null
});
}
return uri;
}
toUri(uriOrModule, moduleIdToUrl) {
if (URI.isUri(uriOrModule)) {
return uriOrModule;
}
if (globalThis._VSCODE_FILE_ROOT) {
const rootUriOrPath = globalThis._VSCODE_FILE_ROOT;
// File URL (with scheme)
if (/^\w[\w\d+.-]*:\/\//.test(rootUriOrPath)) {
return URI.joinPath(URI.parse(rootUriOrPath, true), uriOrModule);
}
// File Path (no scheme)
const modulePath = paths.join(rootUriOrPath, uriOrModule);
return URI.file(modulePath);
}
return URI.parse(moduleIdToUrl.toUrl(uriOrModule));
}
}
export const FileAccess = new FileAccessImpl();
export var COI;
(function (COI) {
const coiHeaders = new Map([
['1', { 'Cross-Origin-Opener-Policy': 'same-origin' }],
['2', { 'Cross-Origin-Embedder-Policy': 'require-corp' }],
['3', { 'Cross-Origin-Opener-Policy': 'same-origin', 'Cross-Origin-Embedder-Policy': 'require-corp' }],
]);
COI.CoopAndCoep = Object.freeze(coiHeaders.get('3'));
const coiSearchParamName = 'vscode-coi';
/**
* Extract desired headers from `vscode-coi` invocation
*/
function getHeadersFromQuery(url) {
let params;
if (typeof url === 'string') {
params = new URL(url).searchParams;
}
else if (url instanceof URL) {
params = url.searchParams;
}
else if (URI.isUri(url)) {
params = new URL(url.toString(true)).searchParams;
}
const value = params?.get(coiSearchParamName);
if (!value) {
return undefined;
}
return coiHeaders.get(value);
}
COI.getHeadersFromQuery = getHeadersFromQuery;
/**
* Add the `vscode-coi` query attribute based on wanting `COOP` and `COEP`. Will be a noop when `crossOriginIsolated`
* isn't enabled the current context
*/
function addSearchParam(urlOrSearch, coop, coep) {
if (!globalThis.crossOriginIsolated) {
// depends on the current context being COI
return;
}
const value = coop && coep ? '3' : coep ? '2' : '1';
if (urlOrSearch instanceof URLSearchParams) {
urlOrSearch.set(coiSearchParamName, value);
}
else {
urlOrSearch[coiSearchParamName] = value;
}
}
COI.addSearchParam = addSearchParam;
})(COI || (COI = {}));