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

Commit b80da59

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

File tree

5 files changed

+94
-25
lines changed

5 files changed

+94
-25
lines changed

sphinxext/tabs.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
.. raw:: html
2525
2626
<div class="tabs">
27-
<ul class="tab-strip tab-strip--singleton" role="tablist">
27+
<ul class="tab-strip tab-strip--singleton" role="tablist" PREFERENCE>
2828
{{ for tab in tabs FILTER }}
2929
{{ # Only render the tab here if i < 5 }}
3030
{{ if i lessThan(5) }}
@@ -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: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,60 @@ 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+
let pref = JSON.parse(window.localStorage.getItem(this.key));
32+
33+
if (!pref) {
34+
pref = {};
35+
}
36+
37+
return pref;
2038
}
2139

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

2665
/**
2766
* Return the first singleton tab ID on the page.
2867
* @returns {string} The first singleton tab ID found.
2968
*/
30-
getFirstLanguage() {
69+
getFirstTab() {
3170
const tabsElement = this.tabStrip.querySelector('.tab-strip__element[aria-selected=true]');
3271
if (!tabsElement) { return null; }
3372

@@ -42,12 +81,18 @@ class TabsSingleton {
4281
for (const element of this.tabStrip.querySelectorAll('[data-tabid]')) {
4382
element.onclick = (e) => {
4483
// Get the tab ID of the clicked tab
45-
const currentAttrValue = e.target.getAttribute('data-tabid');
84+
const tabId = e.target.getAttribute('data-tabid');
85+
const type = this.tabStrip.getAttribute('data-tab-preference');
86+
87+
// Build the pref object to set
88+
const pref = {};
89+
pref.tabId = tabId;
90+
pref.type = type;
4691

4792
// Check to make sure value is not null, i.e., don't do anything on "other"
48-
if (currentAttrValue) {
93+
if (tabId) {
4994
// Save the users preference and re-render
50-
this.languagePref = currentAttrValue;
95+
this.tabPref = pref;
5196
this.update();
5297

5398
e.preventDefault();
@@ -60,20 +105,27 @@ class TabsSingleton {
60105

61106
update() {
62107
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();
108+
let type = this.type;
109+
110+
let tabPref = this.tabPref;
111+
112+
if (!tabPref) {
113+
// Display the first tab when there is no pref
114+
tabPref = this.getFirstTab();
115+
} else if (tabPref.pages && tabPref.pages[window.location.pathname]) {
116+
// Check if current page has a one-off page specific pref
117+
tabPref = tabPref.pages;
118+
type = window.location.pathname;
119+
} else if (!this.tabStrip.querySelector(`[data-tabid="${tabPref[type]}"]`)) {
120+
// Confirm a tab for their tabPref exists at the top of the page
121+
tabPref = this.getFirstTab();
70122
}
71123

72-
if (!languagePref) { return; }
124+
if (!tabPref) { return; }
73125

74126
// Show the appropriate tab content and mark the tab as active
75-
showHideTabContent(languagePref);
76-
this.showHideSelectedTab(languagePref);
127+
showHideTabContent(tabPref[type]);
128+
this.showHideSelectedTab(tabPref[type]);
77129
}
78130

79131
/**
@@ -128,5 +180,5 @@ class TabsSingleton {
128180

129181
// Create tab functionality for code examples
130182
export function setup() {
131-
(new TabsSingleton('languagePref')).setup();
183+
(new TabsSingleton('tabPref')).setup();
132184
}

0 commit comments

Comments
 (0)