svelte-language-server
Version:
A language server for Svelte
92 lines • 3.82 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getHoverInfo = getHoverInfo;
const SvelteTags_1 = require("./SvelteTags");
const utils_1 = require("../../../utils");
const parseHtml_1 = require("../../../lib/documents/parseHtml");
const utils_2 = require("./utils");
const getModifierData_1 = require("./getModifierData");
/**
* Get hover information for special svelte tags within moustache tags.
*/
function getHoverInfo(document, svelteDoc, position) {
const offset = svelteDoc.offsetAt(position);
const offsetStart = Math.max(offset - 10, 0);
const charactersAroundOffset = svelteDoc
.getText()
// use last 10 and next 10 characters, should cover 99% of all cases
.substr(offsetStart, 20);
const isSvelteTag = tagRegexp.test(charactersAroundOffset);
if ((0, utils_2.inStyleOrScript)(svelteDoc, position)) {
return null;
}
if (isSvelteTag) {
return getTagHoverInfoAtOffset(svelteDoc, offsetStart, charactersAroundOffset, offset);
}
const attributeContext = (0, parseHtml_1.getAttributeContextAtPosition)(document, position);
if (!attributeContext || !(0, utils_2.attributeCanHaveEventModifier)(attributeContext)) {
return null;
}
const attributeOffset = svelteDoc.getText().lastIndexOf(attributeContext.name, offset);
return getEventModifierHoverInfo(attributeContext, attributeOffset, offset);
}
function getTagHoverInfoAtOffset(svelteDoc, charactersOffset, charactersAroundOffset, offset) {
const tag = getTagAtOffset(svelteDoc, charactersOffset, charactersAroundOffset, offset);
if (!tag) {
return null;
}
return { contents: SvelteTags_1.documentation[tag] };
}
/**
* Get the tag that is at the offset.
*/
function getTagAtOffset(svelteDoc, charactersOffset, charactersAroundOffset, offset) {
const foundTag = tagPossibilities.find((tagAndValues) => tagAndValues.values.find((value) => isAroundOffset(charactersOffset, charactersAroundOffset, value, offset)));
if (!foundTag) {
return null;
}
if (foundTag.tag !== ':else') {
return foundTag.tag;
}
// ':else can be part of one of each, await, if --> find out which one
return (0, SvelteTags_1.getLatestOpeningTag)(svelteDoc, offset);
}
function isAroundOffset(charactersOffset, charactersAroundOffset, toFind, offset) {
const match = charactersAroundOffset.match(toFind);
if (!match || match.index === undefined) {
return false;
}
const idx = match.index + charactersOffset;
return idx <= offset && idx + toFind.length >= offset;
}
const tagPossibilities = [
{ tag: 'if', values: ['#if', '/if', ':else if'] },
// each
{ tag: 'each', values: ['#each', '/each'] },
// await
{ tag: 'await', values: ['#await', '/await', ':then', ':catch'] },
// key
{ tag: 'key', values: ['#key', '/key'] },
// snippet
{ tag: 'snippet', values: ['#snippet', '/snippet'] },
// @
{ tag: 'html', values: ['@html'] },
{ tag: 'debug', values: ['@debug'] },
{ tag: 'const', values: ['@const'] },
{ tag: 'render', values: ['@render'] },
// this tag has multiple possibilities
{ tag: ':else', values: [':else'] }
];
const tagRegexp = new RegExp(`[\\s\\S]*{\\s*(${(0, utils_1.flatten)(tagPossibilities.map((p) => p.values)).join('|')})(\\s|})`);
function getEventModifierHoverInfo(attributeContext, attributeOffset, offset) {
const { name } = attributeContext;
const modifierData = (0, getModifierData_1.getModifierData)();
const found = modifierData.find((modifier) => isAroundOffset(attributeOffset, name, modifier.modifier, offset));
if (!found) {
return null;
}
return {
contents: found.documentation
};
}
//# sourceMappingURL=getHoverInfo.js.map