astro-ghostcms/.pnpm-store/v3/files/08/1ee8370ae2fecbc6bdb93fe6909...

149 lines
5.9 KiB
Plaintext
Raw Normal View History

2024-02-14 14:10:47 +00:00
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as nodes from '../parser/cssNodes';
import * as languageFacts from '../languageFacts/facts';
import { SelectorPrinting } from './selectorPrinting';
import { startsWith } from '../utils/strings';
import { Range, MarkupKind } from '../cssLanguageTypes';
import { isDefined } from '../utils/objects';
export class CSSHover {
constructor(clientCapabilities, cssDataManager) {
this.clientCapabilities = clientCapabilities;
this.cssDataManager = cssDataManager;
this.selectorPrinting = new SelectorPrinting(cssDataManager);
}
configure(settings) {
this.defaultSettings = settings;
}
doHover(document, position, stylesheet, settings = this.defaultSettings) {
function getRange(node) {
return Range.create(document.positionAt(node.offset), document.positionAt(node.end));
}
const offset = document.offsetAt(position);
const nodepath = nodes.getNodePath(stylesheet, offset);
/**
* nodepath is top-down
* Build up the hover by appending inner node's information
*/
let hover = null;
for (let i = 0; i < nodepath.length; i++) {
const node = nodepath[i];
if (node instanceof nodes.Selector) {
hover = {
contents: this.selectorPrinting.selectorToMarkedString(node),
range: getRange(node)
};
break;
}
if (node instanceof nodes.SimpleSelector) {
/**
* Some sass specific at rules such as `@at-root` are parsed as `SimpleSelector`
*/
if (!startsWith(node.getText(), '@')) {
hover = {
contents: this.selectorPrinting.simpleSelectorToMarkedString(node),
range: getRange(node)
};
}
break;
}
if (node instanceof nodes.Declaration) {
const propertyName = node.getFullPropertyName();
const entry = this.cssDataManager.getProperty(propertyName);
if (entry) {
const contents = languageFacts.getEntryDescription(entry, this.doesSupportMarkdown(), settings);
if (contents) {
hover = {
contents,
range: getRange(node)
};
}
else {
hover = null;
}
}
continue;
}
if (node instanceof nodes.UnknownAtRule) {
const atRuleName = node.getText();
const entry = this.cssDataManager.getAtDirective(atRuleName);
if (entry) {
const contents = languageFacts.getEntryDescription(entry, this.doesSupportMarkdown(), settings);
if (contents) {
hover = {
contents,
range: getRange(node)
};
}
else {
hover = null;
}
}
continue;
}
if (node instanceof nodes.Node && node.type === nodes.NodeType.PseudoSelector) {
const selectorName = node.getText();
const entry = selectorName.slice(0, 2) === '::'
? this.cssDataManager.getPseudoElement(selectorName)
: this.cssDataManager.getPseudoClass(selectorName);
if (entry) {
const contents = languageFacts.getEntryDescription(entry, this.doesSupportMarkdown(), settings);
if (contents) {
hover = {
contents,
range: getRange(node)
};
}
else {
hover = null;
}
}
continue;
}
}
if (hover) {
hover.contents = this.convertContents(hover.contents);
}
return hover;
}
convertContents(contents) {
if (!this.doesSupportMarkdown()) {
if (typeof contents === 'string') {
return contents;
}
// MarkupContent
else if ('kind' in contents) {
return {
kind: 'plaintext',
value: contents.value
};
}
// MarkedString[]
else if (Array.isArray(contents)) {
return contents.map(c => {
return typeof c === 'string' ? c : c.value;
});
}
// MarkedString
else {
return contents.value;
}
}
return contents;
}
doesSupportMarkdown() {
if (!isDefined(this.supportsMarkdown)) {
if (!isDefined(this.clientCapabilities)) {
this.supportsMarkdown = true;
return this.supportsMarkdown;
}
const hover = this.clientCapabilities.textDocument && this.clientCapabilities.textDocument.hover;
this.supportsMarkdown = hover && hover.contentFormat && Array.isArray(hover.contentFormat) && hover.contentFormat.indexOf(MarkupKind.Markdown) !== -1;
}
return this.supportsMarkdown;
}
}