Skip to content
This repository was archived by the owner on Mar 5, 2024. It is now read-only.

Commit 33a1b10

Browse files
DOCSP-879 - Update saved pref to support multiple tab sets and single pages.
1 parent 14e3a4d commit 33a1b10

File tree

5 files changed

+91
-28
lines changed

5 files changed

+91
-28
lines changed

sphinxext/tabs.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
.. raw:: html
2525
2626
<div class="tabs">
27-
<ul class="tab-strip tab-strip--singleton" role="tablist">
28-
{{ for tab in tabs FILTER }}
27+
<ul class="tab-strip tab-strip--singleton" role="tablist" %PREFERENCE%>
28+
{{ for tab in tabs %FILTER% }}
2929
{{ # Only render the tab here if i < 5 }}
3030
{{ if i lessThan(5) }}
3131
<li class="tab-strip__element" data-tabid="{{ tab.id }}" role="tab" aria-selected="{{ if i zero }}true{{ else }}false{{ end }}">{{ tab.name }}</li>
@@ -35,7 +35,7 @@
3535
<li class="tab-strip__element dropdown">
3636
<a class="dropdown-toggle" data-toggle="dropdown">Other <span class="caret"></span></a>
3737
<ul class="dropdown-menu tab-strip__dropdown" role="menu">
38-
{{ for tab in tabs FILTER }}
38+
{{ for tab in tabs %FILTER% }}
3939
{{ # Only render the tab here if i >= 5 }}
4040
{{ if i greaterThanOrEqual(5) }}
4141
<li data-tabid="{{ tab.id }}" aria-selected="{{ if i zero }}true{{ else }}false{{ end }}">{{ tab.name }}</li>
@@ -46,7 +46,7 @@
4646
{{ end }}
4747
</ul>
4848
<div class="tabs__content" role="tabpanel">
49-
{{ for tab in tabs FILTER }}
49+
{{ for tab in tabs %FILTER% }}
5050
<div class="tabpanel-{{ tab.id }}">
5151
5252
{{ tab.content convertSections }}
@@ -98,16 +98,33 @@ def setup(app):
9898
app.add_directive('h4', directive)
9999

100100
# Create drivers tab directive
101-
directive = template.create_directive('tabs-drivers', TABS_TEMPLATE.replace("FILTER", "sortLanguages"), template.BUILT_IN_PATH, True)
101+
directive = template.create_directive('tabs-drivers', buildTemplate("sortLanguages", "drivers"), template.BUILT_IN_PATH, True)
102102
app.add_directive('tabs-drivers', directive)
103103

104+
# Create getting started tab directive
105+
# Shares preference with drivers if possible, no error checking
106+
directive = template.create_directive('tabs-gs', buildTemplate("", "drivers"), template.BUILT_IN_PATH, True)
107+
app.add_directive('tabs-gs', directive)
108+
104109
# Create general purpose tab directive with no error checking
105-
directive = template.create_directive('tabs', TABS_TEMPLATE.replace("FILTER", ""), template.BUILT_IN_PATH, True)
110+
directive = template.create_directive('tabs', buildTemplate("", ""), template.BUILT_IN_PATH, True)
106111
app.add_directive('tabs', directive)
107112

108113
return {'parallel_read_safe': True,
109114
'parallel_write_safe': True}
110115

116+
def buildTemplate(tabFilter, preference):
117+
# If tabFilter is not a string, make it an empty string
118+
if type(tabFilter) != str:
119+
tabFilter = ""
120+
template = TABS_TEMPLATE.replace("%FILTER%", tabFilter)
121+
122+
if type(preference) == str and preference != "":
123+
template = template.replace("%PREFERENCE%", "data-tab-preference=\"" + preference + "\"")
124+
else:
125+
template = template.replace("%PREFERENCE%", "")
126+
127+
return template
111128

112129
def convertSections(tabContent):
113130
"""Convert rst-style sections into custom directives that ONLY insert

themes/mongodb/src/js/componentTabs.js

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,54 @@ class TabsSingleton {
1313
constructor(key) {
1414
this.key = key;
1515
this.tabStrip = document.querySelector('.tab-strip--singleton');
16+
17+
// Only tab sets will have a type, init and try to retrieve
18+
this.type = null;
19+
if (this.tabStrip !== null) {
20+
this.type = this.tabStrip.getAttribute('data-tab-preference');
21+
}
1622
}
1723

18-
get languagePref() {
19-
return window.localStorage.getItem(this.key);
24+
/**
25+
* Return the tabPref object containing preferences for tab sets
26+
* and page specific prefs. Returns an empty object if it doesn't
27+
* exist.
28+
* @returns {object} Tab preference object.
29+
*/
30+
get tabPref() {
31+
return JSON.parse(window.localStorage.getItem(this.key)) || {};
2032
}
2133

22-
set languagePref(value) {
23-
window.localStorage.setItem(this.key, value);
34+
/**
35+
* Sets the tabPref object depending on whether the tab belongs
36+
* to set (e.g., "drivers") or if it's a one-off page.
37+
* @param {object} value The "tabId" and optional "type" (tab set)
38+
*/
39+
set tabPref(value) {
40+
const tabPref = this.tabPref;
41+
42+
// If "type" exists it belongs to a tab set
43+
if (this.type) {
44+
// Set top-level fields for tab set preferences
45+
tabPref[value.type] = value.tabId;
46+
} else if (tabPref.pages) {
47+
// Store one-off pages in the pages embedded document
48+
tabPref.pages[window.location.pathname] = value.tabId;
49+
} else {
50+
// Init pages embedded doc if it doesnt exist and store one-off
51+
tabPref.pages = {};
52+
tabPref.pages[window.location.pathname] = value.tabId;
53+
}
54+
55+
// Write pref object back to localStorage
56+
window.localStorage.setItem(this.key, JSON.stringify(tabPref));
2457
}
2558

2659
/**
2760
* Return the first singleton tab ID on the page.
2861
* @returns {string} The first singleton tab ID found.
2962
*/
30-
getFirstLanguage() {
63+
getFirstTab() {
3164
const tabsElement = this.tabStrip.querySelector('.tab-strip__element[aria-selected=true]');
3265
if (!tabsElement) { return null; }
3366

@@ -42,12 +75,18 @@ class TabsSingleton {
4275
for (const element of this.tabStrip.querySelectorAll('[data-tabid]')) {
4376
element.onclick = (e) => {
4477
// Get the tab ID of the clicked tab
45-
const currentAttrValue = e.target.getAttribute('data-tabid');
78+
const tabId = e.target.getAttribute('data-tabid');
79+
const type = this.tabStrip.getAttribute('data-tab-preference');
80+
81+
// Build the pref object to set
82+
const pref = {};
83+
pref.tabId = tabId;
84+
pref.type = type;
4685

4786
// Check to make sure value is not null, i.e., don't do anything on "other"
48-
if (currentAttrValue) {
87+
if (tabId) {
4988
// Save the users preference and re-render
50-
this.languagePref = currentAttrValue;
89+
this.tabPref = pref;
5190
this.update();
5291

5392
e.preventDefault();
@@ -60,20 +99,27 @@ class TabsSingleton {
6099

61100
update() {
62101
if (!this.tabStrip) { return; }
63-
64-
let languagePref = this.languagePref;
65-
if (!languagePref) {
66-
languagePref = this.getFirstLanguage();
67-
} else if (!this.tabStrip.querySelector(`[data-tabid="${languagePref}"]`)) {
68-
// Confirm a tab for their languagePref exists at the top of the page
69-
languagePref = this.getFirstLanguage();
102+
let type = this.type;
103+
104+
let tabPref = this.tabPref;
105+
106+
if (!tabPref) {
107+
// Display the first tab when there is no pref
108+
tabPref = this.getFirstTab();
109+
} else if (tabPref.pages && tabPref.pages[window.location.pathname]) {
110+
// Check if current page has a one-off page specific pref
111+
tabPref = tabPref.pages;
112+
type = window.location.pathname;
113+
} else if (!this.tabStrip.querySelector(`[data-tabid="${tabPref[type]}"]`)) {
114+
// Confirm a tab for their tabPref exists at the top of the page
115+
tabPref = this.getFirstTab();
70116
}
71117

72-
if (!languagePref) { return; }
118+
if (!tabPref) { return; }
73119

74120
// Show the appropriate tab content and mark the tab as active
75-
showHideTabContent(languagePref);
76-
this.showHideSelectedTab(languagePref);
121+
showHideTabContent(tabPref[type]);
122+
this.showHideSelectedTab(tabPref[type]);
77123
}
78124

79125
/**
@@ -128,5 +174,5 @@ class TabsSingleton {
128174

129175
// Create tab functionality for code examples
130176
export function setup() {
131-
(new TabsSingleton('languagePref')).setup();
177+
(new TabsSingleton('tabPref')).setup();
132178
}

0 commit comments

Comments
 (0)