Skip to content

Commit

Permalink
Fix component data not shown in hover when template interpolation is on
Browse files Browse the repository at this point in the history
In cases where template interpolation provided some data for the hover
popup, it overrode the popup contents without letting component data
hover info to show.

Ask both services and merge the results together so that nothing is
lost.

Fixes vuejs#2878
  • Loading branch information
rchl committed Apr 21, 2021
1 parent da59c05 commit 4a31b8b
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 5 deletions.
33 changes: 31 additions & 2 deletions server/src/modes/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { HTMLMode } from './htmlMode';
import { VueInterpolationMode } from './interpolationMode';
import { IServiceHost } from '../../services/typescriptService/serviceHost';
import { HTMLDocument, parseHTMLDocument } from './parser/htmlParser';
import { inferVueVersion } from '../../utils/vueVersion';
import { DependencyService, RuntimeLibrary } from '../../services/dependencyService';
import { VCancellationToken } from '../../utils/cancellationToken';
import { AutoImportSfcPlugin } from '../plugins/autoImportSfcPlugin';
Expand Down Expand Up @@ -70,8 +69,38 @@ export class VueHTMLMode implements LanguageMode {
return this.vueInterpolationMode.doResolve(document, item);
}
doHover(document: TextDocument, position: Position): Hover {
// Return concatanated results from both vueInterpolationMode and htmlMode.
const interpolationHover = this.vueInterpolationMode.doHover(document, position);
return interpolationHover.contents.length !== 0 ? interpolationHover : this.htmlMode.doHover(document, position);
let markdownContent = '';
if (interpolationHover.contents.length > 0) {
for (const content of interpolationHover.contents) {
if (typeof content === 'string') {
markdownContent += `${content}\n`;
} else {
markdownContent += `\`\`\`${content.language}\n${content.value}\n\`\`\`\n`;
}
}
}
const htmlResult = this.htmlMode.doHover(document, position);
if (htmlResult.contents && Array.isArray(htmlResult.contents)) {
for (const content of htmlResult.contents) {
if (typeof content === 'string') {
markdownContent += `${content}\n`;
} else {
markdownContent += `\`\`\`${content.language}\n${content.value}\n\`\`\`\n`;
}
}
} else if (typeof htmlResult.contents === 'string') {
markdownContent += `${htmlResult.contents}\n`;
} else if ('kind' in htmlResult.contents) {
markdownContent += `${htmlResult.contents.value}\n`;
} else {
markdownContent += `\`\`\`${htmlResult.contents.language}\n${htmlResult.contents.value}\n\`\`\`\n`;
}
return {
contents: { kind: 'markdown', value: markdownContent },
range: interpolationHover.range || htmlResult.range
};
}
findDocumentHighlight(document: TextDocument, position: Position) {
return this.htmlMode.findDocumentHighlight(document, position);
Expand Down
30 changes: 30 additions & 0 deletions test/componentData/features/hover/basic.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { testHover } from '../../../hoverHelper';
import { position, sameLineRange } from '../../../util';
import { getDocUri } from '../../path';

describe('Should show hover info with component data', () => {
const docUri = getDocUri('hover/Element.vue');

it('shows element description', async () => {
await testHover(docUri, position(2, 5), {
contents: [
'```ts\n(property) __vlsComponentData<Record<string, any>>.props: Record<string, any>\n```\nA foo tag'
],
range: sameLineRange(2, 5, 12)
});
});

it('shows attribute description for non-dynamic attribute', async () => {
await testHover(docUri, position(2, 15), {
contents: ['An foo-attr description'],
range: sameLineRange(2, 13, 21)
});
});

it('shows attribute description for dynamic attribute with template interpolation enabled', async () => {
await testHover(docUri, position(3, 15), {
contents: ['```ts\n(property) "foo-attr": string\n```\nAn foo-attr description'],
range: sameLineRange(3, 14, 22)
});
});
});
3 changes: 3 additions & 0 deletions test/componentData/fixture/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"vetur.experimental.templateInterpolationService": true
}
5 changes: 4 additions & 1 deletion test/componentData/fixture/attributes.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"foo-tag/foo-attr": {
"description": "An foo-attr description"
},
"handle-foo": {
"type": "event",
"documentation": "You gotta handle foo"
}
}
}
6 changes: 6 additions & 0 deletions test/componentData/fixture/hover/Element.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<template>
<div>
<foo-tag foo-attr="v" />
<foo-tag :foo-attr="'v'" />
</div>
</template>
4 changes: 2 additions & 2 deletions test/componentData/fixture/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"element-ui": "^2.13.2"
},
"vetur": {
"tags": "./tags.json",
"attributes": "./attributes.json"
"attributes": "./attributes.json",
"tags": "./tags.json"
}
}

0 comments on commit 4a31b8b

Please sign in to comment.