提交 1603d3e6 编写于 作者: J Johannes Rieken

validator must support URI and URL, also extract utils for re-use

上级 d891b0d3
......@@ -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];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册