Skip to content

Commit dc7d0bb

Browse files
authored
Support linkable attribute tokens (#636)
Resolves: rdar://108472125
1 parent e14a599 commit dc7d0bb

File tree

4 files changed

+60
-21
lines changed

4 files changed

+60
-21
lines changed

src/components/DocumentationTopic/PrimaryContent/DeclarationToken.vue

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
<script>
1212
import WordBreak from 'docc-render/components/WordBreak.vue';
1313
import ChangedToken from './DeclarationToken/ChangedToken.vue';
14+
import LinkableToken from './DeclarationToken/LinkableToken.vue';
1415
import RawText from './DeclarationToken/RawText.vue';
1516
import SyntaxToken from './DeclarationToken/SyntaxToken.vue';
16-
import TypeIdentifierLink from './DeclarationToken/TypeIdentifierLink.vue';
1717
1818
const TokenKind = {
1919
attribute: 'attribute',
@@ -46,10 +46,26 @@ export default {
4646
}
4747
case TokenKind.typeIdentifier: {
4848
const props = { identifier: this.identifier };
49-
return createElement(TypeIdentifierLink, { props }, [
49+
return createElement(LinkableToken, {
50+
class: 'type-identifier-link',
51+
props,
52+
}, [
5053
createElement(WordBreak, text),
5154
]);
5255
}
56+
case TokenKind.attribute: {
57+
const { identifier } = this;
58+
return identifier ? (
59+
createElement(LinkableToken, {
60+
class: 'attribute-link',
61+
props: { identifier },
62+
}, [
63+
createElement(WordBreak, text),
64+
])
65+
) : (
66+
createElement(SyntaxToken, { props: { kind, text } })
67+
);
68+
}
5369
case TokenKind.added:
5470
case TokenKind.removed:
5571
return createElement(ChangedToken, { props: { tokens, kind } });
@@ -110,7 +126,8 @@ export default {
110126
color: var(--syntax-string, var(--color-syntax-strings));
111127
}
112128
113-
.token-attribute {
129+
.token-attribute,
130+
.attribute-link {
114131
color: var(--syntax-attribute, var(--color-syntax-keywords));
115132
}
116133

src/components/DocumentationTopic/PrimaryContent/DeclarationToken/TypeIdentifierLink.vue renamed to src/components/DocumentationTopic/PrimaryContent/DeclarationToken/LinkableToken.vue

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@ import Reference from 'docc-render/components/ContentNode/Reference.vue';
1414
import referencesProvider from 'docc-render/mixins/referencesProvider';
1515
1616
export default {
17-
name: 'TypeIdentifierLink',
17+
name: 'LinkableToken',
1818
mixins: [referencesProvider],
1919
render(createElement) {
20-
const klass = 'type-identifier-link';
2120
const reference = this.references[this.identifier];
2221
// internal and external link
2322
if (reference && reference.url) {
2423
return createElement(Reference, {
25-
class: klass,
2624
props: {
2725
url: reference.url,
2826
kind: reference.kind,
@@ -33,9 +31,7 @@ export default {
3331
));
3432
}
3533
// unresolved link, use span tag
36-
return createElement('span', {
37-
class: klass,
38-
}, (
34+
return createElement('span', {}, (
3935
this.$slots.default
4036
));
4137
},

tests/unit/components/DocumentationTopic/PrimaryContent/DeclarationToken.spec.js

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import DeclarationToken from 'docc-render/components/DocumentationTopic/PrimaryC
1515
import RawText from 'docc-render/components/DocumentationTopic/PrimaryContent/DeclarationToken/RawText.vue';
1616
import SyntaxToken
1717
from 'docc-render/components/DocumentationTopic/PrimaryContent/DeclarationToken/SyntaxToken.vue';
18-
import TypeIdentifierLink
19-
from 'docc-render/components/DocumentationTopic/PrimaryContent/DeclarationToken/TypeIdentifierLink.vue';
18+
import LinkableToken
19+
from 'docc-render/components/DocumentationTopic/PrimaryContent/DeclarationToken/LinkableToken.vue';
2020
import WordBreak from 'docc-render/components/WordBreak.vue';
2121

2222
const { TokenKind } = DeclarationToken.constants;
@@ -36,19 +36,20 @@ describe('DeclarationToken', () => {
3636
expect(rawText.props()).toEqual({ text: propsData.text });
3737
});
3838

39-
it('renders a `TypeIdentifierLink` for `typeIdentifier` tokens', () => {
39+
it('renders a `LinkableToken` for `typeIdentifier` tokens', () => {
4040
const propsData = {
4141
kind: TokenKind.typeIdentifier,
4242
identifier: 'foo',
4343
text: 'foo',
4444
};
4545
const wrapper = mountToken({ propsData });
4646

47-
const link = wrapper.find(TypeIdentifierLink);
47+
const link = wrapper.find(LinkableToken);
4848
expect(link.exists()).toBe(true);
4949
expect(link.props()).toEqual({ identifier: propsData.identifier });
5050
expect(link.contains(WordBreak)).toBe(true);
5151
expect(link.text()).toBe(propsData.text);
52+
expect(link.classes()).toContain('type-identifier-link');
5253
});
5354

5455
it('renders a `SyntaxToken` for other tokens', () => {
@@ -97,4 +98,31 @@ describe('DeclarationToken', () => {
9798
expect(token.props('tokens')).toEqual(propsData.tokens);
9899
expect(token.props('kind')).toEqual(propsData.kind);
99100
});
101+
102+
it('renders a `SyntaxToken` for basic `attribute` tokens', () => {
103+
const propsData = {
104+
kind: TokenKind.attribute,
105+
text: '@foo',
106+
};
107+
const wrapper = mountToken({ propsData });
108+
const token = wrapper.find(SyntaxToken);
109+
expect(token.exists()).toBe(true);
110+
expect(token.props('kind')).toBe(TokenKind.attribute);
111+
expect(token.props('text')).toBe(propsData.text);
112+
});
113+
114+
it('renders a `LinkableToken` for `attribute` tokens with an `identifier`', () => {
115+
const propsData = {
116+
kind: TokenKind.attribute,
117+
identifier: 'foo',
118+
text: '@foo',
119+
};
120+
const wrapper = mountToken({ propsData });
121+
const link = wrapper.find(LinkableToken);
122+
expect(link.exists()).toBe(true);
123+
expect(link.props()).toEqual({ identifier: propsData.identifier });
124+
expect(link.contains(WordBreak)).toBe(true);
125+
expect(link.text()).toBe(propsData.text);
126+
expect(link.classes()).toContain('attribute-link');
127+
});
100128
});
Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
*/
1010

1111
import { shallowMount } from '@vue/test-utils';
12-
import TypeIdentifierLink
13-
from 'docc-render/components/DocumentationTopic/PrimaryContent/DeclarationToken/TypeIdentifierLink.vue';
12+
import LinkableToken
13+
from 'docc-render/components/DocumentationTopic/PrimaryContent/DeclarationToken/LinkableToken.vue';
1414
import Reference from 'docc-render/components/ContentNode/Reference.vue';
1515

16-
describe('TypeIdentifierLink', () => {
16+
describe('LinkableToken', () => {
1717
const foo = {
1818
identifier: 'foo',
1919
title: 'Foo',
@@ -46,13 +46,13 @@ describe('TypeIdentifierLink', () => {
4646
};
4747

4848
it('renders a span for unresolved references', () => {
49-
const wrapper = shallowMount(TypeIdentifierLink, defaultOpts);
50-
expect(wrapper.is('span.type-identifier-link')).toBe(true);
49+
const wrapper = shallowMount(LinkableToken, defaultOpts);
50+
expect(wrapper.is('span')).toBe(true);
5151
expect(wrapper.text()).toBe(foo.title);
5252
});
5353

5454
it('renders a link for resolved references', () => {
55-
const wrapper = shallowMount(TypeIdentifierLink, {
55+
const wrapper = shallowMount(LinkableToken, {
5656
...defaultOpts,
5757
provide: {
5858
store: {
@@ -65,10 +65,8 @@ describe('TypeIdentifierLink', () => {
6565
},
6666
});
6767

68-
expect(wrapper.is('.type-identifier-link')).toBe(true);
6968
const link = wrapper.find(Reference);
7069
expect(link.exists()).toBe(true);
71-
expect(link.classes('type-identifier-link')).toBe(true);
7270
expect(link.props('url')).toBe(foo.url);
7371
expect(link.text()).toBe(foo.title);
7472
});

0 commit comments

Comments
 (0)