mirror of
https://github.com/Microsoft/vscode
synced 2024-10-12 22:37:41 +00:00
validator must support URI and URL, also extract utils for re-use
This commit is contained in:
parent
d891b0d349
commit
1603d3e6e5
|
@ -361,3 +361,25 @@ export function toLocalResource(resource: URI, authority: string | undefined): U
|
|||
|
||||
return resource.with({ scheme: Schemas.file });
|
||||
}
|
||||
|
||||
export function matchesScheme(target: URI | URL, scheme: string) {
|
||||
if (URI.isUri(target)) {
|
||||
return equalsIgnoreCase(target.scheme, scheme);
|
||||
} else {
|
||||
return equalsIgnoreCase(target.protocol, scheme + ':');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `true` when urls can be constructed via `new URL("string")`, should only be `false` in IE:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/URL/URL#Browser_compatibility
|
||||
*/
|
||||
export const hasURLCtor = (function () {
|
||||
try {
|
||||
// tslint:disable-next-line: no-unused-expression
|
||||
new URL('some://thing');
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
|
|
|
@ -8,21 +8,13 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
|||
import { LinkedList } from 'vs/base/common/linkedList';
|
||||
import { parse } from 'vs/base/common/marshalling';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { equalsIgnoreCase } from 'vs/base/common/strings';
|
||||
import { matchesScheme, normalizePath } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IOpener, IOpenerService, IValidator, IExternalUriResolver, OpenOptions, ResolveExternalUriOptions, IResolvedExternalUri, IExternalOpener } from 'vs/platform/opener/common/opener';
|
||||
import { EditorOpenContext } from 'vs/platform/editor/common/editor';
|
||||
|
||||
function hasScheme(target: URI | URL, scheme: string) {
|
||||
if (URI.isUri(target)) {
|
||||
return equalsIgnoreCase(target.scheme, scheme);
|
||||
} else {
|
||||
return equalsIgnoreCase(target.protocol, scheme + ':');
|
||||
}
|
||||
}
|
||||
|
||||
export class OpenerService implements IOpenerService {
|
||||
|
||||
|
@ -52,7 +44,7 @@ export class OpenerService implements IOpenerService {
|
|||
// Default opener: maito, http(s), command, and catch-all-editors
|
||||
this._openerAsExternal = {
|
||||
open: async (target: URI | URL, options?: OpenOptions) => {
|
||||
if (options?.openExternal || hasScheme(target, Schemas.mailto) || hasScheme(target, Schemas.http) || hasScheme(target, Schemas.https)) {
|
||||
if (options?.openExternal || matchesScheme(target, Schemas.mailto) || matchesScheme(target, Schemas.http) || matchesScheme(target, Schemas.https)) {
|
||||
// open externally
|
||||
await this._doOpenExternal(target, options);
|
||||
return true;
|
||||
|
@ -63,7 +55,7 @@ export class OpenerService implements IOpenerService {
|
|||
|
||||
this._openerAsCommand = {
|
||||
open: async (target) => {
|
||||
if (!hasScheme(target, Schemas.command)) {
|
||||
if (!matchesScheme(target, Schemas.command)) {
|
||||
return false;
|
||||
}
|
||||
// run command or bail out if command isn't known
|
||||
|
@ -107,7 +99,7 @@ export class OpenerService implements IOpenerService {
|
|||
}
|
||||
|
||||
if (target.scheme === Schemas.file) {
|
||||
target = resources.normalizePath(target); // workaround for non-normalized paths (https://github.com/Microsoft/vscode/issues/12954)
|
||||
target = normalizePath(target); // workaround for non-normalized paths (https://github.com/Microsoft/vscode/issues/12954)
|
||||
}
|
||||
|
||||
await editorService.openCodeEditor(
|
||||
|
@ -142,17 +134,9 @@ export class OpenerService implements IOpenerService {
|
|||
|
||||
async open(target: URI | URL, options?: OpenOptions): Promise<boolean> {
|
||||
|
||||
const resource = URI.isUri(target) ? target : URI.from(target);
|
||||
|
||||
// no scheme ?!?
|
||||
if (!resource.scheme) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
//todo@joh adopt validator
|
||||
// check with contributed validators
|
||||
for (const validator of this._validators.toArray()) {
|
||||
if (!(await validator.shouldOpen(resource))) {
|
||||
if (!(await validator.shouldOpen(target))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,18 +13,7 @@ import { IModelService } from 'vs/editor/common/services/modelService';
|
|||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { isDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
|
||||
// in IE11 there is URL but a constructor
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/URL/URL#Browser_compatibility
|
||||
const canUseUrl = (function () {
|
||||
try {
|
||||
// tslint:disable-next-line: no-unused-expression
|
||||
new URL('some://thing');
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
import { hasURLCtor } from 'vs/base/common/resources';
|
||||
|
||||
export class Link implements ILink {
|
||||
|
||||
|
@ -61,7 +50,7 @@ export class Link implements ILink {
|
|||
try {
|
||||
if (URI.isUri(this._link.url)) {
|
||||
return this._link.url;
|
||||
} else if (!canUseUrl) {
|
||||
} else if (!hasURLCtor) {
|
||||
return URI.parse(this._link.url);
|
||||
} else {
|
||||
return new URL(this._link.url);
|
||||
|
|
|
@ -43,7 +43,7 @@ export interface IExternalOpener {
|
|||
}
|
||||
|
||||
export interface IValidator {
|
||||
shouldOpen(resource: URI): Promise<boolean>;
|
||||
shouldOpen(resource: URI | URL): Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface IExternalUriResolver {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { equalsIgnoreCase } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
|
@ -20,6 +19,7 @@ import {
|
|||
} from 'vs/workbench/contrib/url/common/trustedDomains';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { matchesScheme } from 'vs/base/common/resources';
|
||||
|
||||
export class OpenerValidatorContributions implements IWorkbenchContribution {
|
||||
constructor(
|
||||
|
@ -34,13 +34,16 @@ export class OpenerValidatorContributions implements IWorkbenchContribution {
|
|||
this._openerService.registerValidator({ shouldOpen: r => this.validateLink(r) });
|
||||
}
|
||||
|
||||
async validateLink(resource: URI): Promise<boolean> {
|
||||
const { scheme, authority, path, query, fragment } = resource;
|
||||
|
||||
if (!equalsIgnoreCase(scheme, Schemas.http) && !equalsIgnoreCase(scheme, Schemas.https)) {
|
||||
async validateLink(resource: URI | URL): Promise<boolean> {
|
||||
if (!matchesScheme(resource, Schemas.http) && !matchesScheme(resource, Schemas.https)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!URI.isUri(resource)) {
|
||||
resource = URI.from(resource);
|
||||
}
|
||||
const { scheme, authority, path, query, fragment } = resource;
|
||||
|
||||
const domainToOpen = `${scheme}://${authority}`;
|
||||
const { defaultTrustedDomains, trustedDomains } = readTrustedDomains(this._storageService, this._productService);
|
||||
const allTrustedDomains = [...defaultTrustedDomains, ...trustedDomains];
|
||||
|
|
Loading…
Reference in a new issue