-
Notifications
You must be signed in to change notification settings - Fork 65
Description
Description / Summary
The current output for each tab HTML resembles the following (Sphinx 3.5.0):
<input checked="checked" id="db39d00e-368e-4dab-abf8-5badaaa26cbc" name="7d84620b-ad40-493e-b46e-3e6490848a59" type="radio">
<label class="sd-tab-label" for="db39d00e-368e-4dab-abf8-5badaaa26cbc">
Plain Text</label>
<div class="sd-tab-content docutils"></div>
<input id="f41944c2-922c-4bad-a9c4-3590bf0b3717" name="7d84620b-ad40-493e-b46e-3e6490848a59" type="radio">
<label class="sd-tab-label" for="f41944c2-922c-4bad-a9c4-3590bf0b3717">
Text and Code</label>
<div class="sd-tab-content docutils"></div>I think that there is some intelligent HTML-ing where the browser knows that the div immediately following the label is "connected" in some way. if each div also stored the id of the components it shares controls with (i.e. radioid="UUID" or for="UUID".) it would make each "group" more tightly connected visually while allowing for less guesswork around JS scripts.
Value / benefit
- The combination of input + label + div have immediate visual groupings w/o requiring knowledge of how CSS-only "tab" designs work.
- Javascript (or other scripting) functions that operate on the tabs can more easily identify which component to act on (since the ids are all UUID).
For example, I rigged up some hacky javascript for whenever someone clicks into an anchor link by watching for the hash change. If the linked div element is inside of a div with sd-tab-content, it checks the previous sibling element (label, by expected ordering) to grab the radioid - and then set that radio button to checked.
That works, but is also fragile - assuming the order of HTML wont change is risky. If i could reliably derive the radioid from the div, then the code becomes simpler and more resistant to changes in ordering.
Implementation details
Looking at the code, I think that adding functions similar to the following might be sufficient:
class sd_tab_content(nodes.Element, nodes.General):
pass
def visit_tab_content(self, node):
attributes = {"radioid": node["radioid]"}
self.body.append(self.starttag(node, "div", **attributes))
def depart_tab_content(self, node):
self..body.append("</div>")
// in def setup_tabs
app.add_node(sd_tab_content, html=(visit_tab_content, depart_tab_content)
// in class TabSetHtmlTransform(...) run(self)
tab_content = sd_tab_content( "", *tab_content,radio_id=tab_item_identity)I'm not 100% sure if this works, this is just derived from existing code. I'm also not clear on how best to use the sd_tab_content code (i.e. do we pass *tab_content or *tab_content.children?)
Its also not clear whether this change might break something (it should just add the id to the div, but I also don't do a lot of Sphinx extensions, so there might be deeper effects I'm not seeing.
Tasks to complete
- Add code to insert the radio id into the related tab content
- Test for potential regressions in more current versions of Sphinx
- Test for behavioral regressions in general