mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-26 10:16:01 +01:00
Remove network.URL
This commit is contained in:
@@ -4,425 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import assert = require('vs/base/common/assert');
|
||||
import objects = require('vs/base/common/objects');
|
||||
import strings = require('vs/base/common/strings');
|
||||
import hash = require('vs/base/common/hash');
|
||||
import paths = require('vs/base/common/paths');
|
||||
import URI from 'vs/base/common/uri';
|
||||
|
||||
var _colon = ':'.charCodeAt(0),
|
||||
_slash = '/'.charCodeAt(0),
|
||||
_questionMark = '?'.charCodeAt(0),
|
||||
_hash = '#'.charCodeAt(0);
|
||||
|
||||
export class ParsedUrl {
|
||||
|
||||
private spec:string;
|
||||
private specLength:number;
|
||||
private schemeStart:number;
|
||||
private domainStart:number;
|
||||
private portStart:number;
|
||||
private pathStart:number;
|
||||
private queryStringStart:number;
|
||||
private fragmentIdStart:number;
|
||||
|
||||
constructor(spec:string) {
|
||||
this.spec = spec || strings.empty;
|
||||
this.specLength = this.spec.length;
|
||||
|
||||
|
||||
|
||||
this.parse();
|
||||
}
|
||||
|
||||
private forwardSubstring(startIndex:number, endIndex:number): string {
|
||||
if (startIndex < endIndex) {
|
||||
return this.spec.substring(startIndex, endIndex);
|
||||
}
|
||||
return strings.empty;
|
||||
}
|
||||
|
||||
/**
|
||||
* http for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getScheme(): string {
|
||||
return this.forwardSubstring(this.schemeStart, this.domainStart - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* http: for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getProtocol(): string {
|
||||
return this.forwardSubstring(this.schemeStart, this.domainStart);
|
||||
}
|
||||
|
||||
/**
|
||||
* www.test.com for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getDomain(): string {
|
||||
return this.forwardSubstring(this.domainStart + 2, this.portStart);
|
||||
}
|
||||
|
||||
/**
|
||||
* 8000 for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getPort(): string {
|
||||
return this.forwardSubstring(this.portStart + 1, this.pathStart);
|
||||
}
|
||||
|
||||
/**
|
||||
* www.test.com:8000 for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getHost(): string {
|
||||
return this.forwardSubstring(this.domainStart + 2, this.pathStart);
|
||||
}
|
||||
|
||||
/**
|
||||
* /this/that/theother.html for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getPath(): string {
|
||||
return this.forwardSubstring(this.pathStart, this.queryStringStart);
|
||||
}
|
||||
|
||||
/**
|
||||
* query=foo for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getQueryString(): string {
|
||||
return this.forwardSubstring(this.queryStringStart + 1, this.fragmentIdStart);
|
||||
}
|
||||
|
||||
/**
|
||||
* hash for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getFragmentId(): string {
|
||||
return this.forwardSubstring(this.fragmentIdStart + 1, this.specLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* http://www.test.com:8000 for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getAllBeforePath(): string {
|
||||
return this.forwardSubstring(0, this.pathStart);
|
||||
}
|
||||
/**
|
||||
* http://www.test.com:8000/this/that/theother.html?query=foo for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getAllBeforeFragmentId(): string {
|
||||
return this.forwardSubstring(0, this.fragmentIdStart);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Combine with a relative url, returns absolute url
|
||||
* e.g.
|
||||
* http://www.test.com/this/that/theother.html?query=foo#hash=hash
|
||||
* combined with ../test.js?query=foo#hash
|
||||
* results in http://www.test.com/this/test.js?query=foo#hash
|
||||
*/
|
||||
public combine(relativeUrl:string):string {
|
||||
var questionMarkIndex = relativeUrl.indexOf('?');
|
||||
var hashIndex = relativeUrl.indexOf('#');
|
||||
var suffixIndex = relativeUrl.length;
|
||||
if (questionMarkIndex !== -1 && questionMarkIndex < suffixIndex) {
|
||||
suffixIndex = questionMarkIndex;
|
||||
}
|
||||
if (hashIndex !== -1 && hashIndex < suffixIndex) {
|
||||
suffixIndex = hashIndex;
|
||||
}
|
||||
|
||||
var relativeUrlPath = relativeUrl.substring(0, suffixIndex);
|
||||
var relativeUrlSuffix = relativeUrl.substring(suffixIndex);
|
||||
|
||||
|
||||
relativeUrlPath = relativeUrlPath.replace('\\', '/');
|
||||
|
||||
var resultPath: string;
|
||||
if (strings.startsWith(relativeUrlPath, '/')) {
|
||||
// Looks like an absolute URL
|
||||
resultPath = paths.join(relativeUrlPath);
|
||||
} else {
|
||||
resultPath = paths.join(paths.dirname(this.getPath()), relativeUrlPath);
|
||||
}
|
||||
|
||||
while (resultPath.charAt(0) === '/') {
|
||||
resultPath = resultPath.substr(1);
|
||||
}
|
||||
|
||||
while (resultPath.indexOf('../') === 0) {
|
||||
resultPath = resultPath.substr(3);
|
||||
}
|
||||
|
||||
return this.getAllBeforePath() + '/' + resultPath + relativeUrlSuffix;
|
||||
}
|
||||
|
||||
// scheme://domain:port/path?query_string#fragment_id
|
||||
private parse(): void {
|
||||
var IN_SCHEME = 0,
|
||||
IN_DOMAIN = 1,
|
||||
IN_PORT = 2,
|
||||
IN_PATH = 3,
|
||||
IN_QUERY_STRING = 4,
|
||||
state = IN_SCHEME,
|
||||
spec = this.spec,
|
||||
length = this.specLength,
|
||||
i:number,
|
||||
prevChCode:number = -1,
|
||||
prevPrevChCode:number = -1,
|
||||
chCode:number;
|
||||
|
||||
this.schemeStart = 0;
|
||||
this.domainStart = this.specLength;
|
||||
this.portStart = this.specLength;
|
||||
this.pathStart = this.specLength;
|
||||
this.queryStringStart = this.specLength;
|
||||
this.fragmentIdStart = this.specLength;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
chCode = spec.charCodeAt(i);
|
||||
|
||||
switch (state) {
|
||||
case IN_SCHEME:
|
||||
if (prevChCode === _slash && chCode === _slash) {
|
||||
// going into the domain
|
||||
state = IN_DOMAIN;
|
||||
this.domainStart = i - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case IN_DOMAIN:
|
||||
if (chCode === _colon) {
|
||||
// going into the port
|
||||
state = IN_PORT;
|
||||
this.portStart = i;
|
||||
} else if (chCode === _slash) {
|
||||
// skipping the port, going straight to the path
|
||||
state = IN_PATH;
|
||||
this.portStart = i;
|
||||
this.pathStart = i;
|
||||
} else if (chCode === _hash) {
|
||||
// skipping the port, path & query string, going straight to the fragment, we can halt now
|
||||
this.portStart = i;
|
||||
this.pathStart = i;
|
||||
this.queryStringStart = i;
|
||||
this.fragmentIdStart = i;
|
||||
i = length;
|
||||
}
|
||||
break;
|
||||
|
||||
case IN_PORT:
|
||||
if (chCode === _slash) {
|
||||
// going into the path
|
||||
state = IN_PATH;
|
||||
this.pathStart = i;
|
||||
} else if (chCode === _hash) {
|
||||
// skipping the path & query string, going straight to the fragment, we can halt now
|
||||
this.pathStart = i;
|
||||
this.queryStringStart = i;
|
||||
this.fragmentIdStart = i;
|
||||
i = length;
|
||||
}
|
||||
break;
|
||||
|
||||
case IN_PATH:
|
||||
if (chCode === _questionMark) {
|
||||
// going in to the query string
|
||||
state = IN_QUERY_STRING;
|
||||
this.queryStringStart = i;
|
||||
} else if (chCode === _hash) {
|
||||
// skipping the query string, going straight to the fragment, we can halt now
|
||||
this.queryStringStart = i;
|
||||
this.fragmentIdStart = i;
|
||||
i = length;
|
||||
}
|
||||
break;
|
||||
|
||||
case IN_QUERY_STRING:
|
||||
if (chCode === _hash) {
|
||||
// going into the hash, we can halt now
|
||||
this.fragmentIdStart = i;
|
||||
i = length;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
prevPrevChCode = prevChCode;
|
||||
prevChCode = chCode;
|
||||
}
|
||||
|
||||
if (state === IN_SCHEME) {
|
||||
// Looks like we had a very bad url
|
||||
this.schemeStart = this.specLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class URL extends URI implements objects.IEqualable {
|
||||
|
||||
/**
|
||||
* Creates a new URL from the provided value
|
||||
* by decoding it first.
|
||||
* @param value An encoded url value.
|
||||
*/
|
||||
public static fromEncoded(value:string):URL {
|
||||
return new URL(decodeURIComponent(value));
|
||||
}
|
||||
|
||||
public static fromValue(value:string):URL {
|
||||
return new URL(value);
|
||||
}
|
||||
|
||||
public static fromUri(value: URI): URL {
|
||||
if (!value) {
|
||||
return <any>value;
|
||||
} else if (value instanceof URL) {
|
||||
return value;
|
||||
} else {
|
||||
return new URL(value);
|
||||
}
|
||||
}
|
||||
|
||||
private _spec:string;
|
||||
private _uri: URI;
|
||||
private _parsed:ParsedUrl;
|
||||
|
||||
constructor(spec: string);
|
||||
constructor(spec: URI);
|
||||
constructor(stringOrURI: string|URI) {
|
||||
super();
|
||||
assert.ok(!!stringOrURI, 'spec must not be null');
|
||||
if(typeof stringOrURI === 'string') {
|
||||
this._uri = URI.parse(stringOrURI);
|
||||
} else {
|
||||
this._uri = stringOrURI;
|
||||
}
|
||||
this._spec = this._uri.toString(); // make sure spec is normalized
|
||||
this._parsed = null;
|
||||
}
|
||||
|
||||
public equals(other:any):boolean {
|
||||
if (this.toString() !== String(other)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (other instanceof URL || other instanceof URI);
|
||||
}
|
||||
|
||||
public hashCode():number {
|
||||
return hash.computeMurmur2StringHashCode(this._spec);
|
||||
}
|
||||
|
||||
public isInMemory(): boolean {
|
||||
return this.scheme === schemas.inMemory;
|
||||
}
|
||||
|
||||
/**
|
||||
* http for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getScheme():string {
|
||||
this._ensureParsedUrl();
|
||||
return this._parsed.getScheme();
|
||||
}
|
||||
|
||||
/**
|
||||
* /this/that/theother.html for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public getPath():string {
|
||||
this._ensureParsedUrl();
|
||||
return this._parsed.getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips out the hash part of the URL.
|
||||
* http://www.test.com:8000/this/that/theother.html?query=foo for http://www.test.com:8000/this/that/theother.html?query=foo#hash
|
||||
*/
|
||||
public toUnique():string {
|
||||
this._ensureParsedUrl();
|
||||
return this._parsed.getAllBeforeFragmentId();
|
||||
}
|
||||
|
||||
public startsWith(other:URL):boolean {
|
||||
return strings.startsWith(this._spec, other._spec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine with a relative url, returns absolute url
|
||||
* e.g.
|
||||
* http://www.test.com/this/that/theother.html?query=foo#hash=hash
|
||||
* combined with ../test.js?query=foo#hash
|
||||
* results in http://www.test.com/this/test.js?query=foo#hash
|
||||
*/
|
||||
public combine(relativeUrl:string):URL {
|
||||
this._ensureParsedUrl();
|
||||
return new URL(this._parsed.combine(relativeUrl));
|
||||
}
|
||||
|
||||
private _ensureParsedUrl(): void {
|
||||
if(this._parsed === null) {
|
||||
this._parsed = new ParsedUrl(this._spec);
|
||||
}
|
||||
}
|
||||
|
||||
// ----- URI implementation -------------------------
|
||||
|
||||
public get scheme(): string {
|
||||
return this._uri.scheme;
|
||||
}
|
||||
|
||||
public get authority(): string {
|
||||
return this._uri.authority;
|
||||
}
|
||||
|
||||
public get path(): string {
|
||||
return this._uri.path;
|
||||
}
|
||||
|
||||
public get fsPath(): string {
|
||||
return this._uri.fsPath;
|
||||
}
|
||||
|
||||
public get query(): string {
|
||||
return this._uri.query;
|
||||
}
|
||||
|
||||
public get fragment(): string {
|
||||
return this._uri.fragment;
|
||||
}
|
||||
|
||||
public withScheme(value: string): URI {
|
||||
return URI.create(value, this.authority, this.fsPath, this.query, this.fragment);
|
||||
}
|
||||
|
||||
public withAuthority(value: string): URI {
|
||||
return URI.create(this.scheme, value, this.fsPath, this.query, this.fragment);
|
||||
}
|
||||
|
||||
public withPath(value: string): URI {
|
||||
return URI.create(this.scheme, this.authority, value, this.query, this.fragment);
|
||||
}
|
||||
|
||||
public withQuery(value: string): URI {
|
||||
return URI.create(this.scheme, this.authority, this.fsPath, value, this.fragment);
|
||||
}
|
||||
|
||||
public withFragment(value: string): URI {
|
||||
return URI.create(this.scheme, this.authority, this.fsPath, this.query, value);
|
||||
}
|
||||
|
||||
public with(scheme: string, authority: string, path: string, query: string, fragment: string): URI {
|
||||
return URI.create(scheme, authority, path, query, fragment);
|
||||
}
|
||||
|
||||
public toString():string {
|
||||
return this._spec;
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return this.toString();
|
||||
}
|
||||
}
|
||||
|
||||
export namespace schemas {
|
||||
|
||||
/**
|
||||
@@ -436,4 +17,4 @@ export namespace schemas {
|
||||
export var https:string = 'https';
|
||||
|
||||
export var file:string = 'file';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,21 +6,8 @@
|
||||
|
||||
import * as assert from 'assert';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { URL, ParsedUrl } from 'vs/base/common/network';
|
||||
|
||||
function assertUrl(raw:string, scheme:string, domain:string, port:string, path:string, queryString:string, fragmentId:string): void {
|
||||
var url = new ParsedUrl(raw);
|
||||
assert.equal(url.getScheme(), scheme, 'getScheme ok for ' + raw);
|
||||
var protocol = scheme ? scheme + ':' : scheme;
|
||||
assert.equal(url.getProtocol(), protocol, 'getProtocol ok for ' + raw);
|
||||
assert.equal(url.getDomain(), domain, 'getDomain ok for ' + raw);
|
||||
assert.equal(url.getPort(), port, 'getPort ok for ' + raw);
|
||||
var host = domain + (port ? ':' + port : '');
|
||||
assert.equal(url.getHost(), host, 'getHost ok for ' + raw);
|
||||
assert.equal(url.getPath(), path, 'getPath ok for ' + raw);
|
||||
assert.equal(url.getQueryString(), queryString, 'getQueryString ok for ' + raw);
|
||||
assert.equal(url.getFragmentId(), fragmentId, 'getFragmentId ok for ' + raw);
|
||||
|
||||
// check for equivalent behaviour
|
||||
var uri = URI.parse(raw);
|
||||
assert.equal(uri.scheme, scheme);
|
||||
@@ -30,12 +17,6 @@ function assertUrl(raw:string, scheme:string, domain:string, port:string, path:s
|
||||
assert.equal(uri.fragment, fragmentId);
|
||||
}
|
||||
|
||||
function assertCombine(base:string, relativeUrl:string, expectedUrl:string): void {
|
||||
var url = new ParsedUrl(base);
|
||||
var result = url.combine(relativeUrl);
|
||||
assert.equal(result, expectedUrl, 'combine ok for ' + base + ' and ' + relativeUrl);
|
||||
}
|
||||
|
||||
suite('Network', () => {
|
||||
test('urls', () => {
|
||||
assertUrl('http://www.test.com:8000/this/that/theother.html?query=foo#hash',
|
||||
@@ -107,114 +88,5 @@ suite('Network', () => {
|
||||
);
|
||||
|
||||
assertUrl('file:///c/far/boo/file.cs', 'file', '', '', '/c/far/boo/file.cs', '', '');
|
||||
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '\\test.js',
|
||||
'http://www.test.com:8000/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '/test.js',
|
||||
'http://www.test.com:8000/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '////test.js',
|
||||
'http://www.test.com:8000/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '\\test.js?token=123',
|
||||
'http://www.test.com:8000/test.js?token=123'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '\\test.js?query=foo#hash',
|
||||
'http://www.test.com:8000/test.js?query=foo#hash'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '\\test.js#hash',
|
||||
'http://www.test.com:8000/test.js#hash'
|
||||
);
|
||||
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', 'test.js',
|
||||
'http://www.test.com:8000/this/that/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '../test.js',
|
||||
'http://www.test.com:8000/this/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '..\\test.js',
|
||||
'http://www.test.com:8000/this/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '..\\test.js?token=123',
|
||||
'http://www.test.com:8000/this/test.js?token=123'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '..\\test.js?query=foo#hash',
|
||||
'http://www.test.com:8000/this/test.js?query=foo#hash'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/theother.html?query=foo#hash', '..\\test.js#hash',
|
||||
'http://www.test.com:8000/this/test.js#hash'
|
||||
);
|
||||
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/', 'test.js',
|
||||
'http://www.test.com:8000/this/that/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/this/that/', './test.js',
|
||||
'http://www.test.com:8000/this/that/test.js'
|
||||
);
|
||||
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/', './test.js',
|
||||
'http://www.test.com:8000/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000/', './././test.js',
|
||||
'http://www.test.com:8000/test.js'
|
||||
);
|
||||
|
||||
assertCombine(
|
||||
'http://www.test.com:8000', './././test.js',
|
||||
'http://www.test.com:8000/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com:8000', 'test.js',
|
||||
'http://www.test.com:8000/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com', '../test.js',
|
||||
'http://www.test.com/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com', 'a/b/../../../test.js',
|
||||
'http://www.test.com/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com/a/b', 'a/b/../../../../../test.js',
|
||||
'http://www.test.com/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com', 'test.js',
|
||||
'http://www.test.com/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com', 'a/b/test.js',
|
||||
'http://www.test.com/a/b/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com', './a/b/test.js',
|
||||
'http://www.test.com/a/b/test.js'
|
||||
);
|
||||
assertCombine(
|
||||
'http://www.test.com/index.html', './a/b/test.js',
|
||||
'http://www.test.com/a/b/test.js'
|
||||
);
|
||||
|
||||
var url = new URL('inmemory://model/1#css');
|
||||
assert.equal(url.toUnique(), 'inmemory://model/1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@ import {getScanner, IHTMLScanner} from 'vs/languages/html/common/htmlScanner';
|
||||
import {isTag, DELIM_END, DELIM_START, DELIM_ASSIGN, ATTRIB_NAME, ATTRIB_VALUE} from 'vs/languages/html/common/htmlTokenTypes';
|
||||
import {isEmptyElement} from 'vs/languages/html/common/htmlEmptyTagsShared';
|
||||
import {filterSuggestions} from 'vs/editor/common/modes/supports/suggestSupport';
|
||||
import paths = require('vs/base/common/paths');
|
||||
|
||||
enum LinkDetectionState {
|
||||
LOOKING_FOR_HREF_OR_SRC = 1,
|
||||
@@ -516,11 +517,8 @@ export class HTMLWorker {
|
||||
}
|
||||
|
||||
public static _getWorkspaceUrl(modelAbsoluteUri: URI, rootAbsoluteUri: URI, tokenContent: string): string {
|
||||
var modelAbsoluteUrl = network.URL.fromUri(modelAbsoluteUri);
|
||||
var rootAbsoluteUrl = network.URL.fromUri(rootAbsoluteUri);
|
||||
tokenContent = HTMLWorker._stripQuotes(tokenContent);
|
||||
|
||||
|
||||
if (/^\s*javascript\:/i.test(tokenContent) || /^\s*\#/i.test(tokenContent)) {
|
||||
return null;
|
||||
}
|
||||
@@ -532,27 +530,29 @@ export class HTMLWorker {
|
||||
|
||||
if (/^\s*\/\//i.test(tokenContent)) {
|
||||
// Absolute link (that does not name the protocol)
|
||||
var modelScheme = modelAbsoluteUrl.getScheme();
|
||||
var pickedScheme = 'http';
|
||||
if (modelScheme === network.schemas.https) {
|
||||
let pickedScheme = network.schemas.http;
|
||||
if (modelAbsoluteUri.scheme === network.schemas.https) {
|
||||
pickedScheme = network.schemas.https;
|
||||
}
|
||||
return pickedScheme + ':' + tokenContent.replace(/^\s*/g, '');
|
||||
}
|
||||
|
||||
try {
|
||||
var potentialResult = modelAbsoluteUrl.combine(tokenContent).toString();
|
||||
} catch (err) {
|
||||
// invalid URL
|
||||
return null;
|
||||
let modelPath = paths.dirname(modelAbsoluteUri.path);
|
||||
let alternativeResultPath: string = null;
|
||||
if (tokenContent.length > 0 && tokenContent.charAt(0) === '/') {
|
||||
alternativeResultPath = tokenContent;
|
||||
} else {
|
||||
alternativeResultPath = paths.join(modelPath, tokenContent);
|
||||
alternativeResultPath = alternativeResultPath.replace(/^(\/\.\.)+/, '');
|
||||
}
|
||||
let potentialResult = modelAbsoluteUri.withPath(alternativeResultPath).toString();
|
||||
|
||||
if (rootAbsoluteUrl && modelAbsoluteUrl.startsWith(rootAbsoluteUrl)) {
|
||||
let rootAbsoluteUrlStr = (rootAbsoluteUri ? rootAbsoluteUri.toString() : null);
|
||||
if (rootAbsoluteUrlStr && strings.startsWith(modelAbsoluteUri.toString(), rootAbsoluteUrlStr)) {
|
||||
// The `rootAbsoluteUrl` is set and matches our current model
|
||||
// We need to ensure that this `potentialResult` does not escape `rootAbsoluteUrl`
|
||||
|
||||
var rootAbsoluteUrlStr = rootAbsoluteUrl.toString();
|
||||
var commonPrefixLength = strings.commonPrefixLength(rootAbsoluteUrlStr, potentialResult);
|
||||
let commonPrefixLength = strings.commonPrefixLength(rootAbsoluteUrlStr, potentialResult);
|
||||
if (strings.endsWith(rootAbsoluteUrlStr, '/')) {
|
||||
commonPrefixLength = potentialResult.lastIndexOf('/', commonPrefixLength) + 1;
|
||||
}
|
||||
@@ -562,7 +562,7 @@ export class HTMLWorker {
|
||||
return potentialResult;
|
||||
}
|
||||
|
||||
private createLink(modelAbsoluteUrl: URI, rootAbsoluteUrl: network.URL, tokenContent: string, lineNumber: number, startColumn: number, endColumn: number): Modes.ILink {
|
||||
private createLink(modelAbsoluteUrl: URI, rootAbsoluteUrl: URI, tokenContent: string, lineNumber: number, startColumn: number, endColumn: number): Modes.ILink {
|
||||
var workspaceUrl = HTMLWorker._getWorkspaceUrl(modelAbsoluteUrl, rootAbsoluteUrl, tokenContent);
|
||||
if (!workspaceUrl) {
|
||||
return null;
|
||||
@@ -596,15 +596,15 @@ export class HTMLWorker {
|
||||
tokenContent: string,
|
||||
link: Modes.ILink;
|
||||
|
||||
let rootAbsoluteUrl: network.URL = null;
|
||||
let rootAbsoluteUrl: URI = null;
|
||||
let workspace = this._contextService.getWorkspace();
|
||||
if (workspace) {
|
||||
// The workspace can be null in the no folder opened case
|
||||
let strRootAbsoluteUrl = String(workspace.resource);
|
||||
if (strRootAbsoluteUrl.charAt(strRootAbsoluteUrl.length - 1) === '/') {
|
||||
rootAbsoluteUrl = new network.URL(strRootAbsoluteUrl);
|
||||
rootAbsoluteUrl = URI.parse(strRootAbsoluteUrl);
|
||||
} else {
|
||||
rootAbsoluteUrl = new network.URL(strRootAbsoluteUrl + '/');
|
||||
rootAbsoluteUrl = URI.parse(strRootAbsoluteUrl + '/');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import assert = require('assert')
|
||||
import 'vs/languages/html/common/html.contribution';
|
||||
import assert = require('assert');
|
||||
import mm = require('vs/editor/common/model/mirrorModel');
|
||||
import htmlWorker = require('vs/languages/html/common/htmlWorker');
|
||||
import URI from 'vs/base/common/uri';
|
||||
@@ -61,7 +62,7 @@ suite('HTML - worker', () => {
|
||||
var proposalsFound = completion.suggestions.filter(function(suggestion: Modes.ISuggestion) {
|
||||
return suggestion.label === label && (!type || suggestion.type === type) && (!codeSnippet || suggestion.codeSnippet === codeSnippet);
|
||||
});
|
||||
if (proposalsFound.length != 1) {
|
||||
if (proposalsFound.length !== 1) {
|
||||
assert.fail('Suggestion not found: ' + label + ', has ' + completion.suggestions.map(s => s.label).join(', '));
|
||||
}
|
||||
};
|
||||
@@ -364,6 +365,7 @@ suite('HTML - worker', () => {
|
||||
testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, 'file:///C:\\Alex\\src\\path\\to\\file.txt', 'file:///C:\\Alex\\src\\path\\to\\file.txt');
|
||||
testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', 'http://www.microsoft.com/', 'http://www.microsoft.com/');
|
||||
testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', 'https://www.microsoft.com/', 'https://www.microsoft.com/');
|
||||
testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', 'https://www.microsoft.com/?q=1#h', 'https://www.microsoft.com/?q=1#h');
|
||||
testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', ' //www.microsoft.com/', 'http://www.microsoft.com/');
|
||||
testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', 'a.js', 'file:///C:/Alex/src/path/to/a.js');
|
||||
testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', '/a.js', 'file:///C:/Alex/src/a.js');
|
||||
@@ -373,7 +375,7 @@ suite('HTML - worker', () => {
|
||||
testLinkCreation('https://www.test.com/path/to/file.txt', 'https://www.test.com', '//www.microsoft.com/', 'https://www.microsoft.com/');
|
||||
|
||||
// invalid uris don't throw
|
||||
testLinkCreation('https://www.test.com/path/to/file.txt', 'https://www.test.com', '%', null);
|
||||
testLinkCreation('https://www.test.com/path/to/file.txt', 'https://www.test.com', '%', 'https://www.test.com/path/to/%25');
|
||||
|
||||
// Bug #18314: Ctrl + Click does not open existing file if folder's name starts with 'c' character
|
||||
testLinkCreation('file:///c:/Alex/working_dir/18314-link-detection/test.html', 'file:///c:/Alex/working_dir/18314-link-detection/', '/class/class.js', 'file:///c:/Alex/working_dir/18314-link-detection/class/class.js');
|
||||
|
||||
Reference in New Issue
Block a user