add accordion logic to menu
This commit is contained in:
parent
54091476d4
commit
673777a48c
2
Makefile
2
Makefile
@ -30,7 +30,7 @@ clean:
|
|||||||
$(RM_CMD) extensions/odoo_theme/static/style.css
|
$(RM_CMD) extensions/odoo_theme/static/style.css
|
||||||
@echo "Cleaning finished."
|
@echo "Cleaning finished."
|
||||||
|
|
||||||
edi: SPHINXOPTS += -A collapse_menu=True
|
#edi: SPHINXOPTS += -A collapse_menu=True # If needed, comment rather than setting False
|
||||||
edi: VERSIONS += 12.0,13.0,14.0
|
edi: VERSIONS += 12.0,13.0,14.0
|
||||||
edi: CANONICAL_VERSION += 14.0
|
edi: CANONICAL_VERSION += 14.0
|
||||||
edi: LANGUAGES += en,fr,es
|
edi: LANGUAGES += en,fr,es
|
||||||
|
@ -14,6 +14,7 @@ def setup(app):
|
|||||||
# If not, remove update_meta method
|
# If not, remove update_meta method
|
||||||
app.connect('html-page-context', update_meta)
|
app.connect('html-page-context', update_meta)
|
||||||
|
|
||||||
|
app.add_js_file('js/utils.js') # Keep in first position
|
||||||
app.add_js_file('js/layout.js')
|
app.add_js_file('js/layout.js')
|
||||||
app.add_js_file('js/menu.js')
|
app.add_js_file('js/menu.js')
|
||||||
app.add_js_file('js/page_toc.js')
|
app.add_js_file('js/page_toc.js')
|
||||||
|
@ -5,5 +5,8 @@
|
|||||||
title_only: Whether menu items for content pages (without toctree) should be hidden
|
title_only: Whether menu items for content pages (without toctree) should be hidden
|
||||||
includehidden: Whether menu items of pages inside a hidden toctree should be rendered
|
includehidden: Whether menu items of pages inside a hidden toctree should be rendered
|
||||||
#}
|
#}
|
||||||
|
{#
|
||||||
|
`collapse_menu` is passed directly to Jinja with sphinx-build's option `-A collapse_menu=True`.
|
||||||
|
It it evaluated as a string, so what we're really evaluating here is `collapse_menu != None`.
|
||||||
|
#}
|
||||||
{{ toctree(collapse=collapse_menu, titles_only=True, includehidden=True)}}
|
{{ toctree(collapse=collapse_menu, titles_only=True, includehidden=True)}}
|
||||||
{# TODO replace `collapse_menu` by `True` and remove Makefile entry 'light' #}
|
|
@ -1,19 +1,20 @@
|
|||||||
(function ($) {
|
(function ($) {
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const navigationMenu = document.getElementById('o_main_toctree');
|
this.navigationMenu = document.getElementById('o_main_toctree');
|
||||||
|
|
||||||
|
// Allow to automatically collapse and expand TOC entries
|
||||||
|
_prepareAccordion(this.navigationMenu);
|
||||||
|
|
||||||
// Add a class with the name of the file to each corresponding menu item
|
// Add a class with the name of the file to each corresponding menu item
|
||||||
_flagMenuItemsWithFileName(navigationMenu);
|
_flagMenuItemsWithFileName();
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the name of the file as class of the corresponding menu item.
|
* Add the name of the file as class of the corresponding menu item.
|
||||||
*
|
|
||||||
* @param {HTMLElement} navigationMenu - The navigation menu containing the global TOC
|
|
||||||
*/
|
*/
|
||||||
const _flagMenuItemsWithFileName = (navigationMenu) => {
|
const _flagMenuItemsWithFileName = () => {
|
||||||
navigationMenu.querySelectorAll('li').forEach(menuItem => {
|
this.navigationMenu.querySelectorAll('li').forEach(menuItem => {
|
||||||
let href = menuItem.querySelector('a').href;
|
let href = menuItem.querySelector('a').href;
|
||||||
if (href === '#') { // Selected nodes don't have their file name in the href
|
if (href === '#') { // Selected nodes don't have their file name in the href
|
||||||
href = window.location.href; // Get it from the current window location
|
href = window.location.href; // Get it from the current window location
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
_flagFirstHeadingRef();
|
_flagFirstHeadingRef();
|
||||||
|
|
||||||
// Allow to automatically collapse and expand TOC entries
|
// Allow to automatically collapse and expand TOC entries
|
||||||
_prepareAccordion();
|
_prepareAccordion(this.pageToc);
|
||||||
|
|
||||||
// Allow to respectively highlight and expand the TOC entries and their related TOC
|
// Allow to respectively highlight and expand the TOC entries and their related TOC
|
||||||
// entry list whose section is focused.
|
// entry list whose section is focused.
|
||||||
@ -115,48 +115,4 @@
|
|||||||
*/
|
*/
|
||||||
const _hidePageToc = () => this.pageToc.style.visibility = 'hidden';
|
const _hidePageToc = () => this.pageToc.style.visibility = 'hidden';
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the page TOC entries and heading references to allow collapsing them.
|
|
||||||
*
|
|
||||||
* The typical structure of a TOC menu is a follows:
|
|
||||||
* <ul><li>
|
|
||||||
* <a href="#"/>
|
|
||||||
* <ul>
|
|
||||||
* <li><a href="#heading_without_child"/></li>
|
|
||||||
* <li>
|
|
||||||
* <a href="#heading_with_children"/>
|
|
||||||
* <ul>...</ul>
|
|
||||||
* </li>
|
|
||||||
* </ul>
|
|
||||||
* </li></ul>
|
|
||||||
*
|
|
||||||
* Since a <ul> is always preceded by a <a>, and since we only need to make change to <a>
|
|
||||||
* elements followed by a <ul>, we simply loop on <ul> elements to access all parts of the DOM
|
|
||||||
* that need to be modified.
|
|
||||||
*
|
|
||||||
* For a given <a> and <ul> pair, the final structure must look like this:
|
|
||||||
* <a href="#heading_with_children">
|
|
||||||
* <i data-bs-target="#o_target_heading_with_children" data-bs-toggle="collapse"
|
|
||||||
* class="i-chevron-right"/>
|
|
||||||
* </a>
|
|
||||||
* <ul id="o_target_heading_with_children" class="collapse">...</ul>
|
|
||||||
*/
|
|
||||||
const _prepareAccordion = () => {
|
|
||||||
// Start at the second TOC entry list (<ul>) to avoid collapsing the entire TOC
|
|
||||||
const pageTocRoot = this.pageToc.querySelectorAll('ul')[1];
|
|
||||||
pageTocRoot.querySelectorAll('ul').forEach(tocEntryList => {
|
|
||||||
const relatedHeadingRef = tocEntryList.previousSibling; // The preceding <a> element
|
|
||||||
// Modify the <ul> element
|
|
||||||
tocEntryList.id = `o_target_${relatedHeadingRef.getAttribute('href').replace('#', '')}`
|
|
||||||
tocEntryList.classList.add('collapse');
|
|
||||||
// Create and configure an <li> element and insert it in the <a> element
|
|
||||||
const arrowButton = document.createElement('I');
|
|
||||||
arrowButton.setAttribute('data-bs-target', `#${tocEntryList.id}`);
|
|
||||||
arrowButton.setAttribute('data-bs-toggle', 'collapse');
|
|
||||||
arrowButton.classList.add('i-chevron-right');
|
|
||||||
relatedHeadingRef.insertBefore(arrowButton, relatedHeadingRef.firstChild);
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
44
extensions/odoo_theme/static/js/utils.js
Normal file
44
extensions/odoo_theme/static/js/utils.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Update the page TOC entries and heading references to allow collapsing them.
|
||||||
|
*
|
||||||
|
* The typical structure of a TOC menu is a follows:
|
||||||
|
* <ul><li>
|
||||||
|
* <a href="#"/>
|
||||||
|
* <ul>
|
||||||
|
* <li><a href="#heading_without_child"/></li>
|
||||||
|
* <li>
|
||||||
|
* <a href="#heading_with_children"/>
|
||||||
|
* <ul>...</ul>
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
* </li></ul>
|
||||||
|
*
|
||||||
|
* Since a <ul> is always preceded by a <a>, and since we only need to make change to <a>
|
||||||
|
* elements followed by a <ul>, we simply loop on <ul> elements to access all parts of the DOM
|
||||||
|
* that need to be modified.
|
||||||
|
*
|
||||||
|
* For a given <a> and <ul> pair, the final structure must look like this:
|
||||||
|
* <a href="#heading_with_children">
|
||||||
|
* <i data-bs-target="#o_target_heading_with_children" data-bs-toggle="collapse"
|
||||||
|
* class="i-chevron-right"/>
|
||||||
|
* </a>
|
||||||
|
* <ul id="o_target_heading_with_children" class="collapse">...</ul>
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} tocElement - The element containing the TOC
|
||||||
|
*/
|
||||||
|
const _prepareAccordion = (tocElement) => {
|
||||||
|
// Start at the second TOC entry list (<ul>) to avoid collapsing the entire TOC
|
||||||
|
const tocRoot = tocElement.querySelector('ul');
|
||||||
|
tocRoot.querySelectorAll('ul').forEach(tocEntryList => {
|
||||||
|
const relatedHeadingRef = tocEntryList.previousSibling; // The preceding <a> element
|
||||||
|
// Modify the <ul> element
|
||||||
|
tocEntryList.id = `o_target_${relatedHeadingRef.getAttribute('href').replace('#', '')}`
|
||||||
|
tocEntryList.classList.add('collapse');
|
||||||
|
// Create and configure an <li> element and insert it in the <a> element
|
||||||
|
const arrowButton = document.createElement('I');
|
||||||
|
arrowButton.setAttribute('data-bs-target', `#${tocEntryList.id}`);
|
||||||
|
arrowButton.setAttribute('data-bs-toggle', 'collapse');
|
||||||
|
arrowButton.classList.add('i-chevron-right');
|
||||||
|
relatedHeadingRef.insertBefore(arrowButton, relatedHeadingRef.firstChild);
|
||||||
|
});
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user