summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorBrian Campbell <lambda@continuation.org>2018-05-31 13:58:33 -0400
committerMatt Clay <matt@mystile.com>2018-06-01 10:37:39 -0700
commit7d3ce99a6f848718a2d3ff29335ae7bbf5827079 (patch)
treef37c2a42b3d34f8a89ca73377a13aa285c1d36c0 /docs
parent4536fcc722a2bd3b1e200f303b758430842e7002 (diff)
downloadansible-7d3ce99a6f848718a2d3ff29335ae7bbf5827079.tar.gz
Use colspan on td instead of divs for hierarchical tables (#39948)
Address Firefox table-rendering issues in docs. Refactor to use colspan to provide table cells which can vary in width and indentation; the outermost has the greatest colspan, and each nested key has a colspan of one less than the parent, with padding cells for indentation. Apply styling to table cells to get the table height to work without hacks or browser-specific styling. Simplify the markup and CSS by removing extra divs. Use two passes over the options, return values, and return facts in the Jinja2 module-docs template: one to determine the maximum nesting depth to compute the maximum colspan needed, plus one to lay out the rows. (cherry picked from commit fa5c0282a4816c4dd48e80b983ffc1e14506a1f5)
Diffstat (limited to 'docs')
-rw-r--r--docs/docsite/_themes/sphinx_rtd_theme/static/css/theme.css42
-rw-r--r--docs/docsite/_themes/srtd/static/css/theme.css41
-rw-r--r--docs/templates/plugin.rst.j2294
3 files changed, 162 insertions, 215 deletions
diff --git a/docs/docsite/_themes/sphinx_rtd_theme/static/css/theme.css b/docs/docsite/_themes/sphinx_rtd_theme/static/css/theme.css
index e20a3466ef..15fd8915f1 100644
--- a/docs/docsite/_themes/sphinx_rtd_theme/static/css/theme.css
+++ b/docs/docsite/_themes/sphinx_rtd_theme/static/css/theme.css
@@ -421,51 +421,17 @@ table {
max-width: 100%;
}
-
-.outer-elbow-container {
- display: flex;
- height: 100%;
- flex-direction: row;
-}
-
-.elbow-placeholder {
+.documentation-table td.elbow-placeholder {
border-left: 1px solid #000;
- height: 100%;
+ border-top: 0px;
width: 30px;
+ min-width: 30px;
}
-.elbow-key {
- height: 100%;
- padding: 4px;
- border-top: 1px solid #000;
- flex-grow: 1;
- border-left: 1px solid #000;
-}
-
-.elbow-blocker {
- height: 0;
- overflow: hidden;
-}
-
-.return-value-column {
- height: 1px
-}
-
-.return-value-column td {
- height: inherit
-}
-
-@-moz-document url-prefix() {
- .return-value-column td {
- height: 100%
- }
-}
-
-.cell-border {
+.documentation-table th, .documentation-table td {
padding: 4px;
border-left: 1px solid #000;
border-top: 1px solid #000;
- height: 100%;
}
.documentation-table {
diff --git a/docs/docsite/_themes/srtd/static/css/theme.css b/docs/docsite/_themes/srtd/static/css/theme.css
index fc4d036c6f..8694ee7a2e 100644
--- a/docs/docsite/_themes/srtd/static/css/theme.css
+++ b/docs/docsite/_themes/srtd/static/css/theme.css
@@ -4867,50 +4867,17 @@ table {
}
}
-.outer-elbow-container {
- display: flex;
- height: 100%;
- flex-direction: row;
-}
-
-.elbow-placeholder {
+.documentation-table td.elbow-placeholder {
border-left: 1px solid #000;
- height: 100%;
+ border-top: 0px;
width: 30px;
+ min-width: 30px;
}
-.elbow-key {
- height: 100%;
- padding: 4px;
- border-top: 1px solid #000;
- flex-grow: 1;
- border-left: 1px solid #000;
-}
-
-.elbow-blocker {
- height: 0;
- overflow: hidden;
-}
-
-.return-value-column {
- height: 1px
-}
-
-.return-value-column td {
- height: inherit
-}
-
-@-moz-document url-prefix() {
- .return-value-column td {
- height: 100%
- }
-}
-
-.cell-border {
+.documentation-table th, .documentation-table td {
padding: 4px;
border-left: 1px solid #000;
border-top: 1px solid #000;
- height: 100%;
}
.documentation-table {
diff --git a/docs/templates/plugin.rst.j2 b/docs/templates/plugin.rst.j2
index 421e681c57..a928d32758 100644
--- a/docs/templates/plugin.rst.j2
+++ b/docs/templates/plugin.rst.j2
@@ -88,104 +88,107 @@ Parameters
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
+ {# Pre-compute the nesting depth to allocate columns #}
+ {% set ns = namespace(maxdepth=1) %}
+ {% for key, value in options|dictsort recursive %}
+ {% set ns.maxdepth = [loop.depth, ns.maxdepth] | max %}
+ {% if value.suboptions %}
+ {% if value.suboptions.items %}
+ @{ loop(value.suboptions.items()) }@
+ {% elif value.suboptions[0].items %}
+ @{ loop(value.suboptions[0].items()) }@
+ {% endif %}
+ {% endif %}
+ {% endfor %}
{# Header of the documentation #}
<tr>
- <th class="head"><div class="cell-border">Parameter</div></th>
- <th class="head"><div class="cell-border">Choices/<font color="blue">Defaults</font></div></th>
+ <th colspan="@{ ns.maxdepth }@">Parameter</th>
+ <th>Choices/<font color="blue">Defaults</font></th>
{% if plugin_type != 'module' %}
- <th class="head"><div class="cell-border">Configuration</div></th>
+ <th>Configuration</th>
{% endif %}
- <th class="head" width="100%"><div class="cell-border">Comments</div></th>
+ <th width="100%">Comments</th>
</tr>
{% for key, value in options|dictsort recursive %}
- <tr class="return-value-column">
+ <tr>
+ {# indentation based on nesting level #}
+ {% for i in range(1, loop.depth) %}
+ <td class="elbow-placeholder"></td>
+ {% endfor %}
{# parameter name with required and/or introduced label #}
- <td>
- <div class="outer-elbow-container">
- {% for i in range(1, loop.depth) %}
- <div class="elbow-placeholder">&nbsp;</div>
- {% endfor %}
- <div class="elbow-key">
- <b>@{ key }@</b>
- {% if value.get('required', False) %}<br/><div style="font-size: small; color: red">required</div>{% endif %}
- {% if value.version_added %}<br/><div style="font-size: small; color: darkgreen">(added in @{value.version_added}@)</div>{% endif %}
- </div>
- </div>
+ <td colspan="@{ ns.maxdepth - loop.depth0 }@">
+ <b>@{ key }@</b>
+ {% if value.get('required', False) %}<br/><div style="font-size: small; color: red">required</div>{% endif %}
+ {% if value.version_added %}<br/><div style="font-size: small; color: darkgreen">(added in @{value.version_added}@)</div>{% endif %}
</td>
{# default / choices #}
<td>
- <div class="cell-border">
- {# Turn boolean values in 'yes' and 'no' values #}
- {% if value.default is sameas true %}
- {% set _x = value.update({'default': 'yes'}) %}
- {% elif value.default is sameas false %}
- {% set _x = value.update({'default': 'no'}) %}
- {% endif %}
- {% if value.type == 'bool' %}
- {% set _x = value.update({'choices': ['no', 'yes']}) %}
- {% endif %}
- {# Show possible choices and highlight details #}
- {% if value.choices %}
- <ul><b>Choices:</b>
- {% for choice in value.choices %}
- {# Turn boolean values in 'yes' and 'no' values #}
- {% if choice is sameas true %}
- {% set choice = 'yes' %}
- {% elif choice is sameas false %}
- {% set choice = 'no' %}
- {% endif %}
- {% if (value.default is string and value.default == choice) or (value.default is iterable and value.default is not string and choice in value.default) %}
- <li><div style="color: blue"><b>@{ choice | escape }@</b>&nbsp;&larr;</div></li>
- {% else %}
- <li>@{ choice | escape }@</li>
- {% endif %}
- {% endfor %}
- </ul>
- {% endif %}
- {# Show default value, when multiple choice or no choices #}
- {% if value.default is defined and value.default not in value.choices %}
- <b>Default:</b><br/><div style="color: blue">@{ value.default | escape }@</div>
- {% endif %}
- </div>
+ {# Turn boolean values in 'yes' and 'no' values #}
+ {% if value.default is sameas true %}
+ {% set _x = value.update({'default': 'yes'}) %}
+ {% elif value.default is sameas false %}
+ {% set _x = value.update({'default': 'no'}) %}
+ {% endif %}
+ {% if value.type == 'bool' %}
+ {% set _x = value.update({'choices': ['no', 'yes']}) %}
+ {% endif %}
+ {# Show possible choices and highlight details #}
+ {% if value.choices %}
+ <ul><b>Choices:</b>
+ {% for choice in value.choices %}
+ {# Turn boolean values in 'yes' and 'no' values #}
+ {% if choice is sameas true %}
+ {% set choice = 'yes' %}
+ {% elif choice is sameas false %}
+ {% set choice = 'no' %}
+ {% endif %}
+ {% if (value.default is string and value.default == choice) or (value.default is iterable and value.default is not string and choice in value.default) %}
+ <li><div style="color: blue"><b>@{ choice | escape }@</b>&nbsp;&larr;</div></li>
+ {% else %}
+ <li>@{ choice | escape }@</li>
+ {% endif %}
+ {% endfor %}
+ </ul>
+ {% endif %}
+ {# Show default value, when multiple choice or no choices #}
+ {% if value.default is defined and value.default not in value.choices %}
+ <b>Default:</b><br/><div style="color: blue">@{ value.default | escape }@</div>
+ {% endif %}
</td>
{# configuration #}
{% if plugin_type != 'module' %}
<td>
- <div class="cell-border">
- {% if 'ini' in value %}
- <div> ini entries:
- {% for ini in value.ini %}
- <p>[@{ ini.section }@ ]<br>@{ ini.key }@ = @{ value.default | default('VALUE') }@</p>
- {% endfor %}
- </div>
- {% endif %}
- {% if 'env' in value %}
- {% for env in value.env %}
- <div>env:@{ env.name }@</div>
+ {% if 'ini' in value %}
+ <div> ini entries:
+ {% for ini in value.ini %}
+ <p>[@{ ini.section }@ ]<br>@{ ini.key }@ = @{ value.default | default('VALUE') }@</p>
{% endfor %}
- {% endif %}
- {% if 'vars' in value %}
- {% for myvar in value.vars %}
- <div>var: @{ myvar.name }@</div>
- {% endfor %}
- {% endif %}
- </div>
+ </div>
+ {% endif %}
+ {% if 'env' in value %}
+ {% for env in value.env %}
+ <div>env:@{ env.name }@</div>
+ {% endfor %}
+ {% endif %}
+ {% if 'vars' in value %}
+ {% for myvar in value.vars %}
+ <div>var: @{ myvar.name }@</div>
+ {% endfor %}
+ {% endif %}
</td>
{% endif %}
{# description #}
<td>
- <div class="cell-border">
- {% if value.description is string %}
- <div>@{ value.description | replace('\n', '\n ') | html_ify }@</div>
- {% else %}
- {% for desc in value.description %}
- <div>@{ desc | replace('\n', '\n ') | html_ify }@</div>
- {% endfor %}
- {% endif %}
- {% if 'aliases' in value and value.aliases %}
- <div style="font-size: small; color: darkgreen"><br/>aliases: @{ value.aliases|join(', ') }@</div>
- {% endif %}
- </div>
+ {% if value.description is string %}
+ <div>@{ value.description | replace('\n', '\n ') | html_ify }@</div>
+ {% else %}
+ {% for desc in value.description %}
+ <div>@{ desc | replace('\n', '\n ') | html_ify }@</div>
+ {% endfor %}
+ {% endif %}
+ {% if 'aliases' in value and value.aliases %}
+ <div style="font-size: small; color: darkgreen"><br/>aliases: @{ value.aliases|join(', ') }@</div>
+ {% endif %}
</td>
</tr>
{% if value.suboptions %}
@@ -242,43 +245,49 @@ Facts returned by this module are added/updated in the ``hostvars`` host facts a
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
+ {# Pre-compute the nesting depth to allocate columns #}
+ {% set ns = namespace(maxdepth=1) %}
+ {% for key, value in returnfacts|dictsort recursive %}
+ {% set ns.maxdepth = [loop.depth, ns.maxdepth] | max %}
+ {% if value.contains %}
+ {% if value.contains.items %}
+ @{ loop(value.contains.items()) }@
+ {% elif value.contains[0].items %}
+ @{ loop(value.contains[0].items()) }@
+ {% endif %}
+ {% endif %}
+ {% endfor %}
<tr>
- <th class="head"><div class="cell-border">Fact</div></th>
- <th class="head"><div class="cell-border">Returned</div></th>
- <th class="head" width="100%"><div class="cell-border">Description</div></th>
+ <th colspan="@{ ns.maxdepth }@">Fact</th>
+ <th>Returned</th>
+ <th width="100%">Description</th>
</tr>
{% for key, value in returnfacts|dictsort recursive %}
- <tr class="return-value-column">
- <td>
- <div class="outer-elbow-container">
- {% for i in range(1, loop.depth) %}
- <div class="elbow-placeholder">&nbsp;</div>
- {% endfor %}
- <div class="elbow-key">
- <b>@{ key }@</b>
- <br/><div style="font-size: small; color: red">@{ value.type }@</div>
- </div>
- </div>
+ <tr>
+ {% for i in range(1, loop.depth) %}
+ <td class="elbow-placeholder"></td>
+ {% endfor %}
+ <td colspan="@{ ns.maxdepth - loop.depth0 }@" colspan="@{ ns.maxdepth - loop.depth0 }@">
+ <b>@{ key }@</b>
+ <br/><div style="font-size: small; color: red">@{ value.type }@</div>
</td>
- <td><div class="cell-border">@{ value.returned | html_ify }@</div></td>
+ <td>@{ value.returned | html_ify }@</td>
<td>
- <div class="cell-border">
- {% if value.description is string %}
- <div>@{ value.description | html_ify }@
+ {% if value.description is string %}
+ <div>@{ value.description | html_ify }@
+ </div>
+ {% else %}
+ {% for desc in value.description %}
+ <div>@{ desc | html_ify }@
</div>
- {% else %}
- {% for desc in value.description %}
- <div>@{ desc | html_ify }@
- </div>
- {% endfor %}
- {% endif %}
- <br/>
- {% if value.sample is defined and value.sample %}
- <div style="font-size: smaller"><b>Sample:</b></div>
- {# TODO: The sample should be escaped, using | escape or | htmlify, but both mess things up beyond repair with dicts #}
- <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">@{ value.sample | replace('\n', '\n ') | html_ify }@</div>
- {% endif %}
- </div>
+ {% endfor %}
+ {% endif %}
+ <br/>
+ {% if value.sample is defined and value.sample %}
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ {# TODO: The sample should be escaped, using | escape or | htmlify, but both mess things up beyond repair with dicts #}
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">@{ value.sample | replace('\n', '\n ') | html_ify }@</div>
+ {% endif %}
</td>
</tr>
{# ---------------------------------------------------------
@@ -308,41 +317,46 @@ Common return values are documented :ref:`here <common_return_values>`, the foll
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
+ {% set ns = namespace(maxdepth=1) %}
+ {% for key, value in returndocs|dictsort recursive %}
+ {% set ns.maxdepth = [loop.depth, ns.maxdepth] | max %}
+ {% if value.contains %}
+ {% if value.contains.items %}
+ @{ loop(value.contains.items()) }@
+ {% elif value.contains[0].items %}
+ @{ loop(value.contains[0].items()) }@
+ {% endif %}
+ {% endif %}
+ {% endfor %}
<tr>
- <th class="head"><div class="cell-border">Key</div></th>
- <th class="head"><div class="cell-border">Returned</div></th>
- <th class="head" width="100%"><div class="cell-border">Description</div></th>
+ <th colspan="@{ ns.maxdepth }@">Key</th>
+ <th>Returned</th>
+ <th width="100%">Description</th>
</tr>
{% for key, value in returndocs|dictsort recursive %}
- <tr class="return-value-column">
- <td>
- <div class="outer-elbow-container">
- {% for i in range(1, loop.depth) %}
- <div class="elbow-placeholder">&nbsp;</div>
- {% endfor %}
- <div class="elbow-key">
- <b>@{ key }@</b>
- <br/><div style="font-size: small; color: red">@{ value.type }@</div>
- </div>
- </div>
+ <tr>
+ {% for i in range(1, loop.depth) %}
+ <td class="elbow-placeholder">&nbsp;</td>
+ {% endfor %}
+ <td colspan="@{ ns.maxdepth - loop.depth0 }@">
+ <b>@{ key }@</b>
+ <br/><div style="font-size: small; color: red">@{ value.type }@</div>
</td>
- <td><div class="cell-border">@{ value.returned | html_ify }@</div></td>
+ <td>@{ value.returned | html_ify }@</td>
<td>
- <div class="cell-border">
- {% if value.description is string %}
- <div>@{ value.description | html_ify |indent(4)}@</div>
- {% else %}
- {% for desc in value.description %}
- <div>@{ desc | html_ify |indent(4)}@</div>
- {% endfor %}
- {% endif %}
- <br/>
- {% if value.sample is defined and value.sample %}
- <div style="font-size: smaller"><b>Sample:</b></div>
- {# TODO: The sample should be escaped, using |escape or |htmlify, but both mess things up beyond repair with dicts #}
- <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">@{ value.sample | replace('\n', '\n ') | html_ify }@</div>
- {% endif %}
- </div>
+ {% if value.description is string %}
+ <div>@{ value.description | html_ify |indent(4)}@</div>
+ {% else %}
+ {% for desc in value.description %}
+ <div>@{ desc | html_ify |indent(4)}@</div>
+ {% endfor %}
+ {% endif %}
+ <br/>
+ {% if value.sample is defined and value.sample %}
+ <div style="font-size: smaller"><b>Sample:</b></div>
+ {# TODO: The sample should be escaped, using |escape or |htmlify, but both mess things up beyond repair with dicts #}
+ <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">@{ value.sample | replace('\n', '\n ') | html_ify }@</div>
+ {% endif %}
</td>
</tr>
{# ---------------------------------------------------------