about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-02-28 04:24:18 +0000
committerbors <bors@rust-lang.org>2018-02-28 04:24:18 +0000
commit89e5a0796e0c5de52cd1d6c7541e5c2c7c47f2cd (patch)
treeeb2be45fee924d68902a4ea543cb01c89adaf935
parentaffe297c133a781c75c2494695e847354ae09156 (diff)
parentdf1b9a8584bf273fb807bae2d9dd55833aee5964 (diff)
downloadrust-89e5a0796e0c5de52cd1d6c7541e5c2c7c47f2cd.tar.gz
rust-89e5a0796e0c5de52cd1d6c7541e5c2c7c47f2cd.zip
Auto merge of #47894 - vi:rustdoc_foldable_impls, r=GuillaumeGomez,QuietMisdreavus
rustdoc: Foldable impl blocks

Addresses #40363, #45720, #24483, #23986 and so on

* Expands and refactors collapseDocs and toggleAllDocs
* Adds [-] toggle to all impls (including inherent impl)
* Makes it hiding though main css file, not though element inline style

May need to be addressed:

* "[-]" and anchor link copier are overlaid a bit
* Inherent methods are also hidden by the global [-] toggle.
* Auto-collapsing "Iterator" and so on by default is not implemented yet
* Tested only shallowly and only in Chromiuim
* No tests. Are there tests for css/js part here?
* The new implementation may be a bit slower.

What next steps are need to be done before the integration?
-rw-r--r--src/librustdoc/html/static/main.js173
-rw-r--r--src/librustdoc/html/static/rustdoc.css23
2 files changed, 144 insertions, 52 deletions
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 5c674cabde5..aa09e93e61a 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -297,9 +297,9 @@
     document.onkeydown = handleShortcut;
     document.onclick = function(ev) {
         if (hasClass(ev.target, 'collapse-toggle')) {
-            collapseDocs(ev.target);
+            collapseDocs(ev.target, "toggle");
         } else if (hasClass(ev.target.parentNode, 'collapse-toggle')) {
-            collapseDocs(ev.target.parentNode);
+            collapseDocs(ev.target.parentNode, "toggle");
         } else if (ev.target.tagName === 'SPAN' && hasClass(ev.target.parentNode, 'line-numbers')) {
             var prev_id = 0;
 
@@ -1636,19 +1636,8 @@
                 e.innerHTML = labelForToggleButton(false);
             });
             toggle.title = "collapse all docs";
-            onEach(document.getElementsByClassName("docblock"), function(e) {
-                e.style.display = 'block';
-            });
-            onEach(document.getElementsByClassName("toggle-label"), function(e) {
-                e.style.display = 'none';
-            });
-            onEach(document.getElementsByClassName("toggle-wrapper"), function(e) {
-                removeClass(e, "collapsed");
-            });
             onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
-                onEveryMatchingChild(e, "inner", function(i_e) {
-                    i_e.innerHTML = labelForToggleButton(false);
-                });
+                collapseDocs(e, "show");
             });
         } else {
             addClass(toggle, "will-expand");
@@ -1656,56 +1645,134 @@
                 e.innerHTML = labelForToggleButton(true);
             });
             toggle.title = "expand all docs";
-            onEach(document.getElementsByClassName("docblock"), function(e) {
-                e.style.display = 'none';
-            });
-            onEach(document.getElementsByClassName("toggle-label"), function(e) {
-                e.style.display = 'inline-block';
-            });
-            onEach(document.getElementsByClassName("toggle-wrapper"), function(e) {
-                addClass(e, "collapsed");
-            });
+
             onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
-                onEveryMatchingChild(e, "inner", function(i_e) {
-                    i_e.innerHTML = labelForToggleButton(true);
-                });
+                collapseDocs(e, "hide");
             });
         }
     }
 
-    function collapseDocs(toggle) {
+    function collapseDocs(toggle, mode) {
         if (!toggle || !toggle.parentNode) {
             return;
         }
-        var relatedDoc = toggle.parentNode.nextElementSibling;
-        if (hasClass(relatedDoc, "stability")) {
-            relatedDoc = relatedDoc.nextElementSibling;
-        }
-        if (hasClass(relatedDoc, "docblock")) {
-            if (!isHidden(relatedDoc)) {
-                relatedDoc.style.display = 'none';
-                onEach(toggle.childNodes, function(e) {
-                    if (hasClass(e, 'toggle-label')) {
+
+        function adjustToggle(arg) {
+            return function(e) {
+                if (hasClass(e, 'toggle-label')) {
+                    if (arg) {
                         e.style.display = 'inline-block';
+                    } else {
+                        e.style.display = 'none';
                     }
-                    if (hasClass(e, 'inner')) {
-                        e.innerHTML = labelForToggleButton(true);
+                }
+                if (hasClass(e, 'inner')) {
+                    e.innerHTML = labelForToggleButton(arg);
+                }
+            };
+        };
+
+        if (!hasClass(toggle.parentNode, "impl")) {
+            var relatedDoc = toggle.parentNode.nextElementSibling;
+            if (hasClass(relatedDoc, "stability")) {
+                relatedDoc = relatedDoc.nextElementSibling;
+            }
+            if (hasClass(relatedDoc, "docblock")) {
+                var action = mode;
+                if (action === "toggle") {
+                    if (hasClass(relatedDoc, "hidden-by-usual-hider")) {
+                        action = "show";
+                    } else {
+                        action = "hide";
                     }
-                });
-                addClass(toggle.parentNode, 'collapsed');
-            } else {
-                relatedDoc.style.display = 'block';
-                removeClass(toggle.parentNode, 'collapsed');
-                onEach(toggle.childNodes, function(e) {
-                    if (hasClass(e, 'toggle-label')) {
-                        e.style.display = 'none';
+                }
+                if (action === "hide") {
+                    addClass(relatedDoc, "hidden-by-usual-hider");
+                    onEach(toggle.childNodes, adjustToggle(true));
+                    addClass(toggle.parentNode, 'collapsed');
+                } else if (action === "show") {
+                    removeClass(relatedDoc, "hidden-by-usual-hider");
+                    removeClass(toggle.parentNode, 'collapsed');
+                    onEach(toggle.childNodes, adjustToggle(false));
+                }
+            }
+        } else {
+            // we are collapsing the impl block
+            function implHider(addOrRemove) {
+                return function(n) {
+                    if (hasClass(n, "method")) {
+                        if (addOrRemove) {
+                            addClass(n, "hidden-by-impl-hider");
+                        } else {
+                            removeClass(n, "hidden-by-impl-hider");
+                        }
+                        var ns = n.nextElementSibling;
+                        while (true) {
+                            if (ns && (
+                                    hasClass(ns, "docblock") ||
+                                    hasClass(ns, "stability") ||
+                                    false
+                                    )) {
+                                if (addOrRemove) {
+                                    addClass(ns, "hidden-by-impl-hider");
+                                } else {
+                                    removeClass(ns, "hidden-by-impl-hider");
+                                }
+                                ns = ns.nextElementSibling;
+                                continue;
+                            }
+                            break;
+                        }
                     }
-                    if (hasClass(e, 'inner')) {
-                        e.innerHTML = labelForToggleButton(false);
+                }
+            }
+
+            var relatedDoc = toggle.parentNode;
+
+            while (!hasClass(relatedDoc, "impl-items")) {
+                relatedDoc = relatedDoc.nextElementSibling;
+            }
+
+            if (!relatedDoc) {
+                return;
+            }
+
+            // Hide all functions, but not associated types/consts
+
+            var action = mode;
+            if (action === "toggle") {
+                if (hasClass(relatedDoc, "fns-now-collapsed")) {
+                    action = "show";
+                } else {
+                    action = "hide";
+                }
+            }
+
+            if (action === "show") {
+                removeClass(relatedDoc, "fns-now-collapsed");
+                onEach(toggle.childNodes, adjustToggle(false));
+                onEach(relatedDoc.childNodes, implHider(false));
+            } else if (action === "hide") {
+                addClass(relatedDoc, "fns-now-collapsed");
+                onEach(toggle.childNodes, adjustToggle(true));
+                onEach(relatedDoc.childNodes, implHider(true));
+            }
+        }
+    }
+
+    function autoCollapseAllImpls() {
+        // Automatically minimize all non-inherent impls
+        onEach(document.getElementsByClassName('impl'), function(n) {
+            // inherent impl ids are like 'impl' or impl-<number>'
+            var inherent = (n.id.match(/^impl(?:-\d+)?$/) !== null);
+            if (!inherent) {
+                onEach(n.childNodes, function(m) {
+                    if (hasClass(m, "collapse-toggle")) {
+                        collapseDocs(m, "hide");
                     }
                 });
             }
-        }
+        });
     }
 
     var x = document.getElementById('toggle-all-docs');
@@ -1732,8 +1799,12 @@
              hasClass(next.nextElementSibling, 'docblock'))) {
             insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
         }
+        if (hasClass(e, 'impl')) {
+            insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
+        }
     }
     onEach(document.getElementsByClassName('method'), func);
+    onEach(document.getElementsByClassName('impl'), func);
     onEach(document.getElementsByClassName('impl-items'), function(e) {
         onEach(e.getElementsByClassName('associatedconstant'), func);
     });
@@ -1781,6 +1852,8 @@
         }
     })
 
+    autoCollapseAllImpls();
+
     function createToggleWrapper() {
         var span = document.createElement('span');
         span.className = 'toggle-label';
@@ -1821,7 +1894,7 @@
     onEach(document.getElementById('main').getElementsByTagName('pre'), function(e) {
         onEach(e.getElementsByClassName('attributes'), function(i_e) {
             i_e.parentNode.insertBefore(createToggleWrapper(), i_e);
-            collapseDocs(i_e.previousSibling.childNodes[0]);
+            collapseDocs(i_e.previousSibling.childNodes[0], "toggle");
         });
     });
 
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index cd4f2cfa678..d91e0679ed0 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -110,6 +110,7 @@ h3.impl, h3.method, h4.method, h3.type, h4.type, h4.associatedconstant {
 }
 h3.impl, h3.method, h3.type {
 	margin-top: 15px;
+	padding-left: 15px;
 }
 
 h1, h2, h3, h4,
@@ -522,10 +523,10 @@ a {
 .anchor {
 	display: none;
 	position: absolute;
-	left: -25px;
+	left: -7px;
 }
 .anchor.field {
-	left: -20px;
+	left: -5px;
 }
 .anchor:before {
 	content: '\2002\00a7\2002';
@@ -926,6 +927,10 @@ span.since {
 	.content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant {
 		display: flex;
 	}
+
+	.anchor {
+		display: none !important;
+	}
 }
 
 @media print {
@@ -1083,6 +1088,14 @@ h4 > .important-traits {
 		z-index: -1;
 		border-bottom: 1px solid;
 	}
+
+	.collapse-toggle {
+		left: -20px;
+	}
+
+	.impl > .collapse-toggle {
+		left: -10px;
+	}
 }
 
 
@@ -1228,3 +1241,9 @@ kbd {
 		z-index: 1;
 	}
 }
+
+.hidden-by-impl-hider,
+.hidden-by-usual-hider {
+	/* important because of conflicting rule for small screens */
+	display: none !important;
+}