This commit is contained in:
157
node_modules/vscode-html-languageservice/lib/esm/services/htmlLinks.js
generated
vendored
157
node_modules/vscode-html-languageservice/lib/esm/services/htmlLinks.js
generated
vendored
@@ -1,157 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { createScanner } from '../parser/htmlScanner';
|
||||
import * as strings from '../utils/strings';
|
||||
import { URI as Uri } from 'vscode-uri';
|
||||
import { TokenType, Range } from '../htmlLanguageTypes';
|
||||
function normalizeRef(url) {
|
||||
const first = url[0];
|
||||
const last = url[url.length - 1];
|
||||
if (first === last && (first === '\'' || first === '\"')) {
|
||||
url = url.substring(1, url.length - 1);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
function validateRef(url, languageId) {
|
||||
if (!url.length) {
|
||||
return false;
|
||||
}
|
||||
if (languageId === 'handlebars' && /{{|}}/.test(url)) {
|
||||
return false;
|
||||
}
|
||||
return /\b(w[\w\d+.-]*:\/\/)?[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/?))/.test(url);
|
||||
}
|
||||
function getWorkspaceUrl(documentUri, tokenContent, documentContext, base) {
|
||||
if (/^\s*javascript\:/i.test(tokenContent) || /[\n\r]/.test(tokenContent)) {
|
||||
return undefined;
|
||||
}
|
||||
tokenContent = tokenContent.replace(/^\s*/g, '');
|
||||
const match = tokenContent.match(/^(\w[\w\d+.-]*):/);
|
||||
if (match) {
|
||||
// Absolute link that needs no treatment
|
||||
const schema = match[1].toLowerCase();
|
||||
if (schema === 'http' || schema === 'https' || schema === 'file') {
|
||||
return tokenContent;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
if (/^\#/i.test(tokenContent)) {
|
||||
return documentUri + tokenContent;
|
||||
}
|
||||
if (/^\/\//i.test(tokenContent)) {
|
||||
// Absolute link (that does not name the protocol)
|
||||
const pickedScheme = strings.startsWith(documentUri, 'https://') ? 'https' : 'http';
|
||||
return pickedScheme + ':' + tokenContent.replace(/^\s*/g, '');
|
||||
}
|
||||
if (documentContext) {
|
||||
return documentContext.resolveReference(tokenContent, base || documentUri);
|
||||
}
|
||||
return tokenContent;
|
||||
}
|
||||
function createLink(document, documentContext, attributeValue, startOffset, endOffset, base) {
|
||||
const tokenContent = normalizeRef(attributeValue);
|
||||
if (!validateRef(tokenContent, document.languageId)) {
|
||||
return undefined;
|
||||
}
|
||||
if (tokenContent.length < attributeValue.length) {
|
||||
startOffset++;
|
||||
endOffset--;
|
||||
}
|
||||
const workspaceUrl = getWorkspaceUrl(document.uri, tokenContent, documentContext, base);
|
||||
if (!workspaceUrl) {
|
||||
return undefined;
|
||||
}
|
||||
const target = validateAndCleanURI(workspaceUrl, document);
|
||||
return {
|
||||
range: Range.create(document.positionAt(startOffset), document.positionAt(endOffset)),
|
||||
target
|
||||
};
|
||||
}
|
||||
const _hash = '#'.charCodeAt(0);
|
||||
function validateAndCleanURI(uriStr, document) {
|
||||
try {
|
||||
let uri = Uri.parse(uriStr);
|
||||
if (uri.scheme === 'file' && uri.query) {
|
||||
// see https://github.com/microsoft/vscode/issues/194577 & https://github.com/microsoft/vscode/issues/206238
|
||||
uri = uri.with({ query: null });
|
||||
uriStr = uri.toString(/* skipEncodig*/ true);
|
||||
}
|
||||
if (uri.scheme === 'file' && uri.fragment && !(uriStr.startsWith(document.uri) && uriStr.charCodeAt(document.uri.length) === _hash)) {
|
||||
return uri.with({ fragment: null }).toString(/* skipEncodig*/ true);
|
||||
}
|
||||
return uriStr;
|
||||
}
|
||||
catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
export class HTMLDocumentLinks {
|
||||
constructor(dataManager) {
|
||||
this.dataManager = dataManager;
|
||||
}
|
||||
findDocumentLinks(document, documentContext) {
|
||||
const newLinks = [];
|
||||
const scanner = createScanner(document.getText(), 0);
|
||||
let token = scanner.scan();
|
||||
let lastAttributeName = undefined;
|
||||
let lastTagName = undefined;
|
||||
let afterBase = false;
|
||||
let base = void 0;
|
||||
const idLocations = {};
|
||||
while (token !== TokenType.EOS) {
|
||||
switch (token) {
|
||||
case TokenType.StartTag:
|
||||
lastTagName = scanner.getTokenText().toLowerCase();
|
||||
if (!base) {
|
||||
afterBase = lastTagName === 'base';
|
||||
}
|
||||
break;
|
||||
case TokenType.AttributeName:
|
||||
lastAttributeName = scanner.getTokenText().toLowerCase();
|
||||
break;
|
||||
case TokenType.AttributeValue:
|
||||
if (lastTagName && lastAttributeName && this.dataManager.isPathAttribute(lastTagName, lastAttributeName)) {
|
||||
const attributeValue = scanner.getTokenText();
|
||||
if (!afterBase) { // don't highlight the base link itself
|
||||
const link = createLink(document, documentContext, attributeValue, scanner.getTokenOffset(), scanner.getTokenEnd(), base);
|
||||
if (link) {
|
||||
newLinks.push(link);
|
||||
}
|
||||
}
|
||||
if (afterBase && typeof base === 'undefined') {
|
||||
base = normalizeRef(attributeValue);
|
||||
if (base && documentContext) {
|
||||
base = documentContext.resolveReference(base, document.uri);
|
||||
}
|
||||
}
|
||||
afterBase = false;
|
||||
lastAttributeName = undefined;
|
||||
}
|
||||
else if (lastAttributeName === 'id') {
|
||||
const id = normalizeRef(scanner.getTokenText());
|
||||
idLocations[id] = scanner.getTokenOffset();
|
||||
}
|
||||
break;
|
||||
}
|
||||
token = scanner.scan();
|
||||
}
|
||||
// change local links with ids to actual positions
|
||||
for (const link of newLinks) {
|
||||
const localWithHash = document.uri + '#';
|
||||
if (link.target && strings.startsWith(link.target, localWithHash)) {
|
||||
const target = link.target.substring(localWithHash.length);
|
||||
const offset = idLocations[target];
|
||||
if (offset !== undefined) {
|
||||
const pos = document.positionAt(offset);
|
||||
link.target = `${localWithHash}${pos.line + 1},${pos.character + 1}`;
|
||||
}
|
||||
else {
|
||||
link.target = document.uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
return newLinks;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user