[IMP] odoo_theme: tweak the HTML structure of TOC entries
task-3046383
X-original-commit: 877d1de3c2
Part-of: odoo/documentation#4114
This commit is contained in:
parent
71f3ea88bd
commit
febf7c4188
@ -32,15 +32,15 @@ class Dfn(SphinxRole):
|
|||||||
sphinx.nodes.* class to prevent automatically setting the name of the node as class (e.g.,
|
sphinx.nodes.* class to prevent automatically setting the name of the node as class (e.g.,
|
||||||
"container") on the element.
|
"container") on the element.
|
||||||
"""
|
"""
|
||||||
outer_span = Span(classes=['dfn'])
|
outer_span = DfnSpan(classes=['dfn'])
|
||||||
inner_span = Span()
|
inner_span = DfnSpan()
|
||||||
outer_span.append(inner_span)
|
outer_span.append(inner_span)
|
||||||
text = nodes.Text(self.text)
|
text = nodes.Text(self.text)
|
||||||
inner_span.append(text)
|
inner_span.append(text)
|
||||||
return [outer_span], []
|
return [outer_span], []
|
||||||
|
|
||||||
|
|
||||||
class Span(nodes.General, nodes.Element):
|
class DfnSpan(nodes.General, nodes.Element):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def visit(translator, node):
|
def visit(translator, node):
|
||||||
@ -63,7 +63,7 @@ def setup(app):
|
|||||||
lambda self, node: self.depart_admonition(node),
|
lambda self, node: self.depart_admonition(node),
|
||||||
))
|
))
|
||||||
app.add_role('dfn', Dfn(), override=True)
|
app.add_role('dfn', Dfn(), override=True)
|
||||||
app.add_node(Span, html=(Span.visit, Span.depart))
|
app.add_node(DfnSpan, html=(DfnSpan.visit, DfnSpan.depart))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'parallel_read_safe': True,
|
'parallel_read_safe': True,
|
||||||
|
@ -4,63 +4,78 @@ let tocEntryListId = 0; // Used to generate IDs of toc entry lists for both the
|
|||||||
* Update the provided TOC to allow collapsing its entries with Bootstrap's accordion.
|
* Update the provided TOC to allow collapsing its entries with Bootstrap's accordion.
|
||||||
*
|
*
|
||||||
* The typical structure of a TOC menu is a follows:
|
* The typical structure of a TOC menu is a follows:
|
||||||
* <ul><li>
|
* <ul>
|
||||||
* <a href="#"/>
|
* <li>
|
||||||
* <ul>
|
* <a name="heading_without_children" href="something.html">Something</a>
|
||||||
* <li><a href="#heading_without_child"/></li>
|
* </li>
|
||||||
* <li>
|
* <li>
|
||||||
* <a href="#heading_with_children"/>
|
* <a name="non-clickable_heading_with_children" href="#">Something</a>
|
||||||
* <ul>...</ul>
|
* <ul>...</ul>
|
||||||
* </li>
|
* </li>
|
||||||
* </ul>
|
* <li>
|
||||||
* </li></ul>
|
* <a name="clickable_heading_with_children" href="something.html">Something</a>
|
||||||
|
* <ul>...</ul>
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* Since a <ul> is always preceded by a <a>, and since we only need to make change to <a>
|
* 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
|
* elements followed by a <ul>, we simply loop on <ul> elements to access all parts of the DOM
|
||||||
* that need to be modified.
|
* that need to be modified.
|
||||||
*
|
*
|
||||||
* The final structure must look like this:
|
* The final structure must look like this:
|
||||||
* <ul><li>
|
* <ul>
|
||||||
* <!-- Only <a> element with empty href must expand/collapse on click -->
|
* <!-- Unchanged -->
|
||||||
* <a href="#" data-bs-target="#o_target_{id}>" data-bs-toggle="collapse"/>
|
* <li>
|
||||||
* <ul>
|
* <a name="heading_without_children" href="something.html">Something</a>
|
||||||
* <li><a href="#heading_without_child"/></li>
|
* </li>
|
||||||
* <li>
|
* <!-- Create a <div>; append <i> and <a> to <div>; set BS target on <a> and <i>; set id on <ul> -->
|
||||||
* <div class="o_toc_entry_wrapper">
|
* <li>
|
||||||
* <i class="i-chevron-right" data-bs-target="#o_target_{id}" data-bs-toggle="collapse"/>
|
* <div class="o_toc_entry_wrapper">
|
||||||
* <a href="#heading_with_children"/>
|
* <i class="i-chevron-right" data-bs-target="#o_target_123" data-bs-toggle="collapse"/>
|
||||||
* </div>
|
* <a name="non-clickable_heading_with_children" href="#" data-bs-target="#o_target_123>" data-bs-toggle="collapse">Something</a>
|
||||||
* <ul id="o_target_{id}" class="collapse">...</ul>
|
* </div>
|
||||||
* </li>
|
* <ul id="o_target_123" class="collapse">...</ul>
|
||||||
* </ul>
|
* </li>
|
||||||
* </li></ul>
|
* <!-- Create a <div>; append <i> and <a> to <div>; set BS target on only <i> to let the <a> redirect; set id on <ul> -->
|
||||||
|
* <li>
|
||||||
|
* <div class="o_toc_entry_wrapper">
|
||||||
|
* <i class="i-chevron-right" data-bs-target="#o_target_456" data-bs-toggle="collapse"/>
|
||||||
|
* <a name="clickable_heading_with_children" href="something.html">Something</a>
|
||||||
|
* </div>
|
||||||
|
* <ul id="o_target_456" class="collapse">...</ul>
|
||||||
|
* </li>
|
||||||
|
*</ul>
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} tocElement - The element containing the TOC
|
* @param {HTMLElement} tocElement - The element containing the TOC.
|
||||||
*/
|
*/
|
||||||
const _prepareAccordion = (tocElement) => {
|
const _prepareAccordion = (tocElement) => {
|
||||||
// Start at the second TOC entry list (<ul>) to avoid collapsing the entire TOC
|
// Start at the second TOC entry list (<ul>) to avoid collapsing the entire TOC.
|
||||||
const tocRoot = tocElement.querySelector('ul');
|
const tocRoot = tocElement.querySelector('ul');
|
||||||
tocRoot.querySelectorAll('ul').forEach(tocEntryList => {
|
tocRoot.querySelectorAll('ul').forEach(tocEntryList => {
|
||||||
// Modify the <ul> element
|
// Modify the <ul> element.
|
||||||
tocEntryList.id = `o_target_${tocEntryListId++}`;
|
tocEntryList.id = `o_target_${tocEntryListId++}`;
|
||||||
tocEntryList.classList.add('collapse');
|
tocEntryList.classList.add('collapse');
|
||||||
// Create and configure an <i> element
|
|
||||||
const arrowButton = document.createElement('I');
|
// Modify the <a> element only if it has no href; otherwise, let the redirection happen.
|
||||||
arrowButton.setAttribute('data-bs-target', `#${tocEntryList.id}`);
|
|
||||||
arrowButton.setAttribute('data-bs-toggle', 'collapse');
|
|
||||||
arrowButton.classList.add('i-chevron-right');
|
|
||||||
// Modify the <a> element (only if it has no href, otherwise let the redirection happen)
|
|
||||||
const relatedHeadingRef = tocEntryList.previousSibling;
|
const relatedHeadingRef = tocEntryList.previousSibling;
|
||||||
if (relatedHeadingRef.getAttribute('href') === '#') {
|
if (relatedHeadingRef.getAttribute('href') === '#') {
|
||||||
relatedHeadingRef.setAttribute('data-bs-target', `#${tocEntryList.id}`);
|
relatedHeadingRef.setAttribute('data-bs-target', `#${tocEntryList.id}`);
|
||||||
relatedHeadingRef.setAttribute('data-bs-toggle', 'collapse');
|
relatedHeadingRef.setAttribute('data-bs-toggle', 'collapse');
|
||||||
}
|
}
|
||||||
// Create a <div> element
|
|
||||||
|
// Create and configure a <div> element.
|
||||||
const tocEntryWrapper = document.createElement('DIV');
|
const tocEntryWrapper = document.createElement('DIV');
|
||||||
tocEntryWrapper.classList.add('o_toc_entry_wrapper');
|
tocEntryWrapper.classList.add('o_toc_entry_wrapper');
|
||||||
// Insert the <i> and <a> elements inside the <div> and prepend the <div> to the <ul>
|
tocEntryList.parentElement.insertBefore(tocEntryWrapper, tocEntryList);
|
||||||
|
|
||||||
|
// Create and configure an <i> 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');
|
||||||
|
|
||||||
|
// Insert the <i> and <a> elements inside the <div>.
|
||||||
tocEntryWrapper.append(arrowButton, relatedHeadingRef);
|
tocEntryWrapper.append(arrowButton, relatedHeadingRef);
|
||||||
tocEntryList.parentNode.insertBefore(tocEntryWrapper, tocEntryList);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user