Skip to content

Commit 6a83cbe

Browse files
authored
Add support for variantOverrides Render JSON key. (#10)
Adds renderer support for the newly introduced `variantOverrides` key in DocC Render JSON, which allows for using the same JSON file to represent documentation data for a symbol which is available in more than one variant—most commonly for a symbol available in both Swift and Objective-C languages. For symbols available in both Swift/Objective-C, there will now be an affordance in the sidebar that can be used to toggle between the current language.
1 parent a5cbca1 commit 6a83cbe

File tree

15 files changed

+849
-62
lines changed

15 files changed

+849
-62
lines changed

src/components/DocumentationTopic.vue

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ import { getSetting } from 'docc-render/utils/theme-settings';
9898
import Aside from 'docc-render/components/ContentNode/Aside.vue';
9999
import DocumentationNav from 'theme/components/DocumentationTopic/DocumentationNav.vue';
100100
import BetaLegalText from 'theme/components/DocumentationTopic/BetaLegalText.vue';
101+
import LanguageSwitcher from 'theme/components/DocumentationTopic/Summary/LanguageSwitcher.vue';
101102
import Abstract from './DocumentationTopic/Description/Abstract.vue';
102103
import ContentNode from './DocumentationTopic/ContentNode.vue';
103104
import CallToActionButton from './CallToActionButton.vue';
@@ -113,7 +114,6 @@ import SeeAlso from './DocumentationTopic/SeeAlso.vue';
113114
import Summary from './DocumentationTopic/Summary.vue';
114115
import Title from './DocumentationTopic/Title.vue';
115116
import Topics from './DocumentationTopic/Topics.vue';
116-
import LanguageSwitcher from './DocumentationTopic/Summary/LanguageSwitcher.vue';
117117
118118
export default {
119119
name: 'DocumentationTopic',
@@ -307,25 +307,33 @@ export default {
307307
// hierarchy/breadcrumb for a given topic. We choose to render only the
308308
// first one.
309309
parentTopicIdentifiers: ({ hierarchy: { paths: [ids = []] = [] } }) => ids,
310-
shouldShowLanguageSwitcher: ({ isTargetIDE, objcPath, swiftPath }) => (
311-
isTargetIDE && objcPath && swiftPath
312-
),
310+
shouldShowLanguageSwitcher: ({ objcPath, swiftPath }) => objcPath && swiftPath,
313311
hideSummary: () => getSetting(['features', 'docs', 'summary', 'hide'], false),
314312
},
313+
methods: {
314+
normalizePath(path) {
315+
// Sometimes `paths` data from `variants` are prefixed with a leading
316+
// slash and sometimes they aren't
317+
return path.startsWith('/') ? path : `/${path}`;
318+
},
319+
},
315320
created() {
316321
// Switch to the Objective-C variant of a page if the query parameter is not
317322
// present in the URL _but_ the user has previously selected Objective-C
318323
// using the navigation toggle (indicating a semi-global preference/mode)
319324
if (this.topicState.preferredLanguage === Language.objectiveC.key.url
320325
&& this.interfaceLanguage !== Language.objectiveC.key.api
321-
&& this.objcPath) {
326+
&& this.objcPath && this.$route.query.language !== Language.objectiveC.key.url) {
322327
const { query } = this.$route;
323-
this.$router.replace({
324-
path: `/${this.objcPath}`,
325-
query: {
326-
...query,
327-
language: Language.objectiveC.key.url,
328-
},
328+
329+
this.$nextTick().then(() => {
330+
this.$router.replace({
331+
path: this.normalizePath(this.objcPath),
332+
query: {
333+
...query,
334+
language: Language.objectiveC.key.url,
335+
},
336+
});
329337
});
330338
}
331339

src/components/DocumentationTopic/Summary/LanguageSwitcher.vue

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,19 @@
1515
class="language-option swift"
1616
:class="{ active: swift.active }"
1717
:url="swift.active ? null : swift.url"
18+
@click="chooseLanguage(swift)"
1819
>{{swift.name}}</LanguageSwitcherLink>
1920
<LanguageSwitcherLink
2021
class="language-option objc"
2122
:class="{ active: objc.active }"
2223
:url="objc.active ? null : objc.url"
24+
@click="chooseLanguage(objc)"
2325
>{{objc.name}}</LanguageSwitcherLink>
2426
</Section>
2527
</template>
2628

2729
<script>
30+
import { buildUrl } from 'docc-render/utils/url-helper';
2831
import Language from 'docc-render/constants/Language';
2932
3033
import LanguageSwitcherLink from './LanguageSwitcherLink.vue';
@@ -38,6 +41,18 @@ export default {
3841
Section,
3942
Title,
4043
},
44+
inject: {
45+
isTargetIDE: {
46+
default: () => false,
47+
},
48+
store: {
49+
default() {
50+
return {
51+
setPreferredLanguage() {},
52+
};
53+
},
54+
},
55+
},
4156
props: {
4257
interfaceLanguage: {
4358
type: String,
@@ -59,31 +74,44 @@ export default {
5974
// leading slash so that it doesn't try to link to a page relative to the
6075
// current URL.
6176
objc: ({
62-
interfaceLanguage, isCurrentPath, objcPath, $route: { query },
77+
interfaceLanguage,
78+
normalizePath,
79+
objcPath,
80+
$route: { query },
6381
}) => ({
6482
...Language.objectiveC,
6583
active: Language.objectiveC.key.api === interfaceLanguage,
66-
url: {
67-
path: isCurrentPath(objcPath) ? null : `/${objcPath}`,
68-
query: { language: Language.objectiveC.key.url, context: query.context },
69-
},
84+
url: buildUrl(normalizePath(objcPath), {
85+
...query,
86+
language: Language.objectiveC.key.url,
87+
}),
7088
}),
7189
swift: ({
72-
interfaceLanguage, isCurrentPath, swiftPath, $route: { query },
90+
interfaceLanguage,
91+
normalizePath,
92+
swiftPath,
93+
$route: { query },
7394
}) => ({
7495
...Language.swift,
7596
active: Language.swift.key.api === interfaceLanguage,
76-
url: {
77-
path: isCurrentPath(swiftPath) ? null : `/${swiftPath}`,
78-
query: { language: undefined, context: query.context },
79-
},
97+
url: buildUrl(normalizePath(swiftPath), {
98+
...query,
99+
language: undefined,
100+
}),
80101
}),
81102
},
82103
methods: {
83-
isCurrentPath(path) {
84-
// the `.replace` call is needed since paths vended by the backend do not
85-
// include a leading slash, while the router provided path does
86-
return this.$route.path.replace(/^\//, '') === path;
104+
chooseLanguage(language) {
105+
if (!this.isTargetIDE) {
106+
this.store.setPreferredLanguage(language.key.url);
107+
}
108+
109+
this.$router.push(language.url);
110+
},
111+
normalizePath(path) {
112+
// Sometimes `paths` data from `variants` are prefixed with a leading
113+
// slash and sometimes they aren't
114+
return path.startsWith('/') ? path : `/${path}`;
87115
},
88116
},
89117
};

src/components/DocumentationTopic/Summary/LanguageSwitcherLink.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
-->
1010

1111
<template>
12-
<router-link v-if="url" :to="url"><slot /></router-link>
12+
<a v-if="url" :href="url" @click.prevent="$emit('click')"><slot /></a>
1313
<span v-else><slot /></span>
1414
</template>
1515

src/styles/core/colors/_dark.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
--color-fill-blue: #{dark-color(fill-blue)};
1616
--color-fill-gray: #{dark-color(fill-gray)};
1717
--color-fill-gray-secondary: #{dark-color(fill-gray-secondary)};
18+
--color-fill-gray-tertiary: #{dark-color(fill-gray-tertiary)};
1819
--color-fill-green-secondary: #{dark-color(fill-green-secondary)};
1920
--color-fill-orange-secondary: #{dark-color(fill-orange-secondary)};
2021
--color-fill-red-secondary: #{dark-color(fill-red-secondary)};

src/styles/core/colors/_light.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
--color-fill-blue: #{light-color(fill-blue)};
1717
--color-fill-gray: #{light-color(fill-gray)};
1818
--color-fill-gray-secondary: #{light-color(fill-gray-secondary)};
19+
--color-fill-gray-tertiary: #{light-color(fill-gray-tertiary)};
1920
--color-fill-green-secondary: #{light-color(fill-green-secondary)};
2021
--color-fill-orange-secondary: #{light-color(fill-orange-secondary)};
2122
--color-fill-red-secondary: #{light-color(fill-red-secondary)};

src/utils/data.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,7 @@ export async function fetchAPIChangesForRoute(route, changes) {
102102

103103
return data;
104104
}
105+
106+
export function clone(jsonObject) {
107+
return JSON.parse(JSON.stringify(jsonObject));
108+
}

0 commit comments

Comments
 (0)