Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 34e3183

Browse files
committedDec 6, 2018
Prevent lazy iterations over DOM
1 parent edfe2a8 commit 34e3183

File tree

1 file changed

+99
-105
lines changed

1 file changed

+99
-105
lines changed
 

‎src/librustdoc/html/static/main.js

Lines changed: 99 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,10 @@ if (!DOMTokenList.prototype.remove) {
148148
var TY_PRIMITIVE = itemTypes.indexOf("primitive");
149149
var TY_KEYWORD = itemTypes.indexOf("keyword");
150150

151-
onEach(document.getElementsByClassName("js-only"), function(e) {
151+
onEach(Array.prototype.slice.call(document.getElementsByClassName("js-only")), function(e) {
152152
removeClass(e, "js-only");
153153
});
154154

155-
console.log('1', Date.now() - start);
156-
157155
function getQueryStringParams() {
158156
var params = {};
159157
window.location.search.substring(1).split("&").
@@ -170,6 +168,8 @@ if (!DOMTokenList.prototype.remove) {
170168
window.history && typeof window.history.pushState === "function";
171169
}
172170

171+
var main = document.getElementById("main");
172+
173173
function highlightSourceLines(ev) {
174174
// If we're in mobile mode, we should add the sidebar in any case.
175175
hideSidebar();
@@ -190,8 +190,9 @@ if (!DOMTokenList.prototype.remove) {
190190
x.scrollIntoView();
191191
}
192192
}
193-
onEach(document.getElementsByClassName("line-numbers"), function(e) {
194-
onEach(e.getElementsByTagName("span"), function(i_e) {
193+
onEach(Array.prototype.slice.call(document.getElementsByClassName("line-numbers")),
194+
function(e) {
195+
onEach(Array.prototype.slice.call(e.getElementsByTagName("span")), function(i_e) {
195196
removeClass(i_e, "line-highlighted");
196197
});
197198
});
@@ -200,7 +201,7 @@ if (!DOMTokenList.prototype.remove) {
200201
}
201202
} else if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
202203
addClass(search, "hidden");
203-
removeClass(document.getElementById("main"), "hidden");
204+
removeClass(main, "hidden");
204205
var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
205206
if (browserSupportsHistoryApi()) {
206207
history.replaceState(hash, "", "?search=#" + hash);
@@ -233,8 +234,6 @@ if (!DOMTokenList.prototype.remove) {
233234
highlightSourceLines(null);
234235
window.onhashchange = highlightSourceLines;
235236

236-
console.log('2', Date.now() - start);
237-
238237
// Gets the human-readable string for the virtual-key code of the
239238
// given KeyboardEvent, ev.
240239
//
@@ -279,7 +278,7 @@ if (!DOMTokenList.prototype.remove) {
279278
} else if (hasClass(search, "hidden") === false) {
280279
ev.preventDefault();
281280
addClass(search, "hidden");
282-
removeClass(document.getElementById("main"), "hidden");
281+
removeClass(main, "hidden");
283282
document.title = titleBeforeSearch;
284283
}
285284
defocusSearchBar();
@@ -407,8 +406,6 @@ if (!DOMTokenList.prototype.remove) {
407406
};
408407
}
409408

410-
console.log('3', Date.now() - start);
411-
412409
/**
413410
* A function to compute the Levenshtein distance between two strings
414411
* Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported
@@ -1183,7 +1180,7 @@ if (!DOMTokenList.prototype.remove) {
11831180
dst = dst[0];
11841181
if (window.location.pathname === dst.pathname) {
11851182
addClass(document.getElementById("search"), "hidden");
1186-
removeClass(document.getElementById("main"), "hidden");
1183+
removeClass(main, "hidden");
11871184
document.location.href = dst.href;
11881185
}
11891186
};
@@ -1411,7 +1408,7 @@ if (!DOMTokenList.prototype.remove) {
14111408
"</div><div id=\"results\">" +
14121409
ret_others[0] + ret_in_args[0] + ret_returned[0] + "</div>";
14131410

1414-
addClass(document.getElementById("main"), "hidden");
1411+
addClass(main, "hidden");
14151412
var search = document.getElementById("search");
14161413
removeClass(search, "hidden");
14171414
search.innerHTML = output;
@@ -1421,7 +1418,7 @@ if (!DOMTokenList.prototype.remove) {
14211418
td_width = tds[0].offsetWidth;
14221419
}
14231420
var width = search.offsetWidth - 40 - td_width;
1424-
onEach(search.getElementsByClassName("desc"), function(e) {
1421+
onEach(Array.prototype.slice.call(search.getElementsByClassName("desc")), function(e) {
14251422
e.style.width = width + "px";
14261423
});
14271424
initSearchNav();
@@ -1619,7 +1616,6 @@ if (!DOMTokenList.prototype.remove) {
16191616
if (browserSupportsHistoryApi()) {
16201617
history.replaceState("", "std - Rust", "?search=");
16211618
}
1622-
var main = document.getElementById("main");
16231619
if (hasClass(main, "content")) {
16241620
removeClass(main, "hidden");
16251621
}
@@ -1666,7 +1662,6 @@ if (!DOMTokenList.prototype.remove) {
16661662
// When browsing back from search results the main page
16671663
// visibility must be reset.
16681664
if (!params.search) {
1669-
var main = document.getElementById("main");
16701665
if (hasClass(main, "content")) {
16711666
removeClass(main, "hidden");
16721667
}
@@ -1862,8 +1857,6 @@ if (!DOMTokenList.prototype.remove) {
18621857
window.register_implementors(window.pending_implementors);
18631858
}
18641859

1865-
console.log('4', Date.now() - start);
1866-
18671860
function labelForToggleButton(sectionIsCollapsed) {
18681861
if (sectionIsCollapsed) {
18691862
// button will expand the section
@@ -1889,31 +1882,35 @@ if (!DOMTokenList.prototype.remove) {
18891882
}
18901883

18911884
function toggleAllDocs(pageId, fromAutoCollapse) {
1892-
var toggle = document.getElementById("toggle-all-docs");
1893-
if (!toggle) {
1885+
var innerToggle = document.getElementById("toggle-all-docs");
1886+
if (!innerToggle) {
18941887
return;
18951888
}
1896-
if (hasClass(toggle, "will-expand")) {
1889+
if (hasClass(innerToggle, "will-expand")) {
18971890
updateLocalStorage("rustdoc-collapse", "false");
1898-
removeClass(toggle, "will-expand");
1899-
onEveryMatchingChild(toggle, "inner", function(e) {
1891+
removeClass(innerToggle, "will-expand");
1892+
onEveryMatchingChild(innerToggle, "inner", function(e) {
19001893
e.innerHTML = labelForToggleButton(false);
19011894
});
1902-
toggle.title = "collapse all docs";
1895+
innerToggle.title = "collapse all docs";
19031896
if (fromAutoCollapse !== true) {
1904-
onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
1897+
onEach(Array.prototype.slice.call(
1898+
document.getElementsByClassName("collapse-toggle")),
1899+
function(e) {
19051900
collapseDocs(e, "show");
19061901
});
19071902
}
19081903
} else {
19091904
updateLocalStorage("rustdoc-collapse", "true");
1910-
addClass(toggle, "will-expand");
1911-
onEveryMatchingChild(toggle, "inner", function(e) {
1905+
addClass(innerToggle, "will-expand");
1906+
onEveryMatchingChild(innerToggle, "inner", function(e) {
19121907
e.innerHTML = labelForToggleButton(true);
19131908
});
1914-
toggle.title = "expand all docs";
1909+
innerToggle.title = "expand all docs";
19151910
if (fromAutoCollapse !== true) {
1916-
onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
1911+
onEach(Array.prototype.slice.call(
1912+
document.getElementsByClassName("collapse-toggle")),
1913+
function(e) {
19171914
collapseDocs(e, "hide", pageId);
19181915
});
19191916
}
@@ -1987,12 +1984,12 @@ if (!DOMTokenList.prototype.remove) {
19871984
}
19881985
if (action === "hide") {
19891986
addClass(relatedDoc, "hidden-by-usual-hider");
1990-
onEach(toggle.childNodes, adjustToggle(true));
1987+
onEach(Array.prototype.slice.call(toggle.childNodes), adjustToggle(true));
19911988
addClass(toggle.parentNode, "collapsed");
19921989
} else if (action === "show") {
19931990
removeClass(relatedDoc, "hidden-by-usual-hider");
19941991
removeClass(toggle.parentNode, "collapsed");
1995-
onEach(toggle.childNodes, adjustToggle(false));
1992+
onEach(Array.prototype.slice.call(toggle.childNodes), adjustToggle(false));
19961993
}
19971994
}
19981995
} else {
@@ -2025,13 +2022,13 @@ if (!DOMTokenList.prototype.remove) {
20252022
if (action === "show") {
20262023
removeClass(relatedDoc, "fns-now-collapsed");
20272024
removeClass(docblock, "hidden-by-usual-hider");
2028-
onEach(toggle.childNodes, adjustToggle(false));
2029-
onEach(relatedDoc.childNodes, implHider(false));
2025+
onEach(Array.prototype.slice.call(toggle.childNodes), adjustToggle(false));
2026+
onEach(Array.prototype.slice.call(relatedDoc.childNodes), implHider(false));
20302027
} else if (action === "hide") {
20312028
addClass(relatedDoc, "fns-now-collapsed");
20322029
addClass(docblock, "hidden-by-usual-hider");
2033-
onEach(toggle.childNodes, adjustToggle(true));
2034-
onEach(relatedDoc.childNodes, implHider(true));
2030+
onEach(Array.prototype.slice.call(toggle.childNodes), adjustToggle(true));
2031+
onEach(Array.prototype.slice.call(relatedDoc.childNodes), implHider(true));
20352032
}
20362033
}
20372034
}
@@ -2055,7 +2052,9 @@ if (!DOMTokenList.prototype.remove) {
20552052
var impl_list = document.getElementById("implementations-list");
20562053

20572054
if (impl_list !== null) {
2058-
onEach(impl_list.getElementsByClassName("collapse-toggle"), collapser);
2055+
onEach(Array.prototype.slice.call(
2056+
impl_list.getElementsByClassName("collapse-toggle")),
2057+
collapser);
20592058
}
20602059
}
20612060
}
@@ -2069,30 +2068,30 @@ if (!DOMTokenList.prototype.remove) {
20692068
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
20702069
}
20712070

2072-
var toggle = document.createElement("a");
2073-
toggle.href = "javascript:void(0)";
2074-
toggle.className = "collapse-toggle";
2075-
toggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(false) + "</span>]";
2071+
function createSimpleToggle(sectionIsCollapsed) {
2072+
var toggle = document.createElement("a");
2073+
toggle.href = "javascript:void(0)";
2074+
toggle.className = "collapse-toggle";
2075+
toggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(sectionIsCollapsed) +
2076+
"</span>]";
2077+
return toggle;
2078+
}
2079+
2080+
var toggle = createSimpleToggle(false);
20762081

20772082
var func = function(e) {
20782083
var next = e.nextElementSibling;
2079-
if (next && hasClass(e, "impl") && hasClass(next, "docblock")) {
2080-
next = next.nextElementSibling;
2081-
}
20822084
if (!next) {
20832085
return;
20842086
}
2085-
if ((hasClass(e, "method") || hasClass(e, "associatedconstant") ||
2086-
next.getElementsByClassName("method").length > 0) &&
2087-
(hasClass(next, "docblock") ||
2088-
hasClass(e, "impl") ||
2089-
(hasClass(next, "stability") &&
2090-
hasClass(next.nextElementSibling, "docblock")))) {
2087+
if (hasClass(next, "docblock") ||
2088+
(hasClass(next, "stability") &&
2089+
hasClass(next.nextElementSibling, "docblock"))) {
20912090
insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
20922091
}
20932092
};
20942093

2095-
var func2 = function(e) {
2094+
var funcImpl = function(e) {
20962095
var next = e.nextElementSibling;
20972096
if (next && hasClass(next, "docblock")) {
20982097
next = next.nextElementSibling;
@@ -2105,13 +2104,9 @@ if (!DOMTokenList.prototype.remove) {
21052104
}
21062105
};
21072106

2108-
console.log('5', Date.now() - start);
2109-
onEach(document.getElementsByClassName("method"), func);
2110-
console.log('6', Date.now() - start);
2111-
onEach(document.getElementsByClassName("associatedconstant"), func);
2112-
console.log('7', Date.now() - start);
2113-
onEach(document.getElementsByClassName("impl"), func2 );
2114-
console.log('8', Date.now() - start);
2107+
onEach(Array.prototype.slice.call(document.getElementsByClassName("method")), func);
2108+
onEach(Array.prototype.slice.call(document.getElementsByClassName("associatedconstant")), func);
2109+
onEach(Array.prototype.slice.call(document.getElementsByClassName("impl")), funcImpl);
21152110
var impl_call = function() {};
21162111
if (getCurrentValue("rustdoc-method-docs") !== "false") {
21172112
impl_call = function(e, newToggle, pageId) {
@@ -2132,7 +2127,8 @@ if (!DOMTokenList.prototype.remove) {
21322127
function toggleClicked() {
21332128
if (hasClass(this, "collapsed")) {
21342129
removeClass(this, "collapsed");
2135-
onEach(this.parentNode.getElementsByClassName("hidden"), function(x) {
2130+
onEach(Array.prototype.slice.call(this.parentNode.getElementsByClassName("hidden")),
2131+
function(x) {
21362132
if (hasClass(x, "content") === false) {
21372133
removeClass(x, "hidden");
21382134
addClass(x, "x");
@@ -2142,7 +2138,8 @@ if (!DOMTokenList.prototype.remove) {
21422138
"</span>] Hide undocumented items";
21432139
} else {
21442140
addClass(this, "collapsed");
2145-
onEach(this.parentNode.getElementsByClassName("x"), function(x) {
2141+
onEach(Array.prototype.slice.call(this.parentNode.getElementsByClassName("x")),
2142+
function(x) {
21462143
if (hasClass(x, "content") === false) {
21472144
addClass(x, "hidden");
21482145
removeClass(x, "x");
@@ -2152,8 +2149,8 @@ if (!DOMTokenList.prototype.remove) {
21522149
"</span>] Show hidden undocumented items";
21532150
}
21542151
}
2155-
onEach(document.getElementsByClassName("impl-items"), function(e) {
2156-
onEach(e.getElementsByClassName("associatedconstant"), func);
2152+
onEach(Array.prototype.slice.call(document.getElementsByClassName("impl-items")), function(e) {
2153+
onEach(Array.prototype.slice.call(e.getElementsByClassName("associatedconstant")), func);
21572154
var hiddenElems = e.getElementsByClassName("hidden");
21582155
var needToggle = false;
21592156

@@ -2166,13 +2163,12 @@ if (!DOMTokenList.prototype.remove) {
21662163
}
21672164
}
21682165
if (needToggle === true) {
2169-
var toggle = newToggle.cloneNode(true);
2170-
toggle.onclick = toggleClicked;
2171-
e.insertBefore(toggle, e.firstChild);
2172-
impl_call(e, toggle, pageId);
2166+
var inner_toggle = newToggle.cloneNode(true);
2167+
inner_toggle.onclick = toggleClicked;
2168+
e.insertBefore(inner_toggle, e.firstChild);
2169+
impl_call(e, inner_toggle, pageId);
21732170
}
21742171
});
2175-
console.log('9', Date.now() - start);
21762172

21772173
function createToggle(otherMessage, fontSize, extraClass, show) {
21782174
var span = document.createElement("span");
@@ -2214,15 +2210,18 @@ if (!DOMTokenList.prototype.remove) {
22142210
if (hasClass(e, "autohide")) {
22152211
var wrap = e.previousElementSibling;
22162212
if (wrap && hasClass(wrap, "toggle-wrapper")) {
2217-
var toggle = wrap.childNodes[0];
2213+
var inner_toggle = wrap.childNodes[0];
22182214
var extra = e.childNodes[0].tagName === "H3";
22192215

22202216
e.style.display = "none";
22212217
addClass(wrap, "collapsed");
2222-
onEach(toggle.getElementsByClassName("inner"), function(e) {
2218+
onEach(Array.prototype.slice.call(inner_toggle.getElementsByClassName("inner")),
2219+
function(e) {
22232220
e.innerHTML = labelForToggleButton(true);
22242221
});
2225-
onEach(toggle.getElementsByClassName("toggle-label"), function(e) {
2222+
onEach(Array.prototype.slice.call(
2223+
inner_toggle.getElementsByClassName("toggle-label")),
2224+
function(e) {
22262225
e.style.display = "inline-block";
22272226
if (extra === true) {
22282227
i_e.innerHTML = " Show " + e.childNodes[0].innerHTML;
@@ -2269,40 +2268,28 @@ if (!DOMTokenList.prototype.remove) {
22692268
}
22702269
}
22712270

2272-
console.log('10', Date.now() - start);
2273-
onEach(document.getElementsByClassName("docblock"), buildToggleWrapper);
2274-
console.log('11', Date.now() - start);
2275-
onEach(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
2276-
console.log('12', Date.now() - start);
2277-
2278-
function createToggleWrapper(tog) {
2279-
var span = document.createElement("span");
2280-
span.className = "toggle-label";
2281-
span.style.display = "none";
2282-
span.innerHTML = "&nbsp;Expand&nbsp;attributes";
2283-
tog.appendChild(span);
2284-
2285-
var wrapper = document.createElement("div");
2286-
wrapper.className = "toggle-wrapper toggle-attributes";
2287-
wrapper.appendChild(tog);
2288-
return wrapper;
2289-
}
2271+
onEach(Array.prototype.slice.call(document.getElementsByClassName("docblock")),
2272+
buildToggleWrapper);
2273+
onEach(Array.prototype.slice.call(document.getElementsByClassName("sub-variant")),
2274+
buildToggleWrapper);
22902275

22912276
// In the search display, allows to switch between tabs.
22922277
function printTab(nb) {
22932278
if (nb === 0 || nb === 1 || nb === 2) {
22942279
currentTab = nb;
22952280
}
22962281
var nb_copy = nb;
2297-
onEach(document.getElementById("titles").childNodes, function(elem) {
2282+
onEach(Array.prototype.slice.call(document.getElementById("titles").childNodes),
2283+
function(elem) {
22982284
if (nb_copy === 0) {
22992285
addClass(elem, "selected");
23002286
} else {
23012287
removeClass(elem, "selected");
23022288
}
23032289
nb_copy -= 1;
23042290
});
2305-
onEach(document.getElementById("results").childNodes, function(elem) {
2291+
onEach(Array.prototype.slice.call(document.getElementById("results").childNodes),
2292+
function(elem) {
23062293
if (nb === 0) {
23072294
elem.style.display = "";
23082295
} else {
@@ -2312,18 +2299,31 @@ if (!DOMTokenList.prototype.remove) {
23122299
});
23132300
}
23142301

2302+
function createToggleWrapper(tog) {
2303+
var span = document.createElement("span");
2304+
span.className = "toggle-label";
2305+
span.style.display = "none";
2306+
span.innerHTML = "&nbsp;Expand&nbsp;attributes";
2307+
tog.appendChild(span);
2308+
2309+
var wrapper = document.createElement("div");
2310+
wrapper.className = "toggle-wrapper toggle-attributes";
2311+
wrapper.appendChild(tog);
2312+
return wrapper;
2313+
}
2314+
23152315
// To avoid checking on "rustdoc-item-attributes" value on every loop...
23162316
var itemAttributesFunc = function() {};
23172317
if (getCurrentValue("rustdoc-item-attributes") !== "false") {
23182318
itemAttributesFunc = function(x) {
23192319
collapseDocs(x.previousSibling.childNodes[0], "toggle");
23202320
};
23212321
}
2322-
onEach(document.getElementById("main").getElementsByClassName("attributes"), function(i_e) {
2323-
i_e.parentNode.insertBefore(createToggleWrapper(toggle.cloneNode(true)), i_e);
2322+
var attributesToggle = createToggleWrapper(createSimpleToggle(false));
2323+
onEach(Array.prototype.slice.call(main.getElementsByClassName("attributes")), function(i_e) {
2324+
i_e.parentNode.insertBefore(attributesToggle.cloneNode(true), i_e);
23242325
itemAttributesFunc(i_e);
23252326
});
2326-
console.log('12a', Date.now() - start);
23272327

23282328
// To avoid checking on "rustdoc-line-numbers" value on every loop...
23292329
var lineNumbersFunc = function() {};
@@ -2340,8 +2340,8 @@ if (!DOMTokenList.prototype.remove) {
23402340
x.parentNode.insertBefore(node, x);
23412341
};
23422342
}
2343-
console.log('13', Date.now() - start);
2344-
onEach(document.getElementsByClassName("rust-example-rendered"), function(e) {
2343+
onEach(Array.prototype.slice.call(document.getElementsByClassName("rust-example-rendered")),
2344+
function(e) {
23452345
if (hasClass(e, "compile_fail")) {
23462346
e.addEventListener("mouseover", function(event) {
23472347
this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00";
@@ -2359,7 +2359,6 @@ if (!DOMTokenList.prototype.remove) {
23592359
}
23602360
lineNumbersFunc(e);
23612361
});
2362-
console.log('14', Date.now() - start);
23632362

23642363
function showModal(content) {
23652364
var modal = document.createElement("div");
@@ -2380,16 +2379,16 @@ if (!DOMTokenList.prototype.remove) {
23802379
}
23812380
}
23822381

2383-
onEach(document.getElementsByClassName("important-traits"), function(e) {
2382+
onEach(Array.prototype.slice.call(document.getElementsByClassName("important-traits")),
2383+
function(e) {
23842384
e.onclick = function() {
23852385
showModal(e.lastElementChild.innerHTML);
23862386
};
23872387
});
2388-
console.log('15', Date.now() - start);
23892388

23902389
function putBackSearch(search_input) {
23912390
if (search_input.value !== "") {
2392-
addClass(document.getElementById("main"), "hidden");
2391+
addClass(main, "hidden");
23932392
removeClass(document.getElementById("search"), "hidden");
23942393
if (browserSupportsHistoryApi()) {
23952394
history.replaceState(search_input.value,
@@ -2407,7 +2406,7 @@ if (!DOMTokenList.prototype.remove) {
24072406

24082407
var params = getQueryStringParams();
24092408
if (params && params.search) {
2410-
addClass(document.getElementById("main"), "hidden");
2409+
addClass(main, "hidden");
24112410
var search = document.getElementById("search");
24122411
removeClass(search, "hidden");
24132412
search.innerHTML = "<h3 style=\"text-align: center;\">Loading search results...</h3>";
@@ -2429,23 +2428,18 @@ if (!DOMTokenList.prototype.remove) {
24292428
hideSidebar();
24302429
};
24312430

2432-
console.log('16', Date.now() - start);
24332431
autoCollapse(getPageId(), getCurrentValue("rustdoc-collapse") === "true");
2434-
console.log('17', Date.now() - start);
24352432

24362433
if (window.location.hash && window.location.hash.length > 0) {
24372434
expandSection(window.location.hash.replace(/^#/, ""));
24382435
}
24392436

2440-
var main = document.getElementById("main");
24412437
if (main) {
2442-
console.log('18', Date.now() - start);
2443-
onEach(main.childNodes, function(e) {
2438+
onEach(Array.prototype.slice.call(main.childNodes), function(e) {
24442439
if (e.tagName === "H2" || e.tagName === "H3") {
24452440
e.nextElementSibling.style.display = "block";
24462441
}
24472442
});
2448-
console.log('19', Date.now() - start);
24492443
}
24502444

24512445
function addSearchOptions(crates) {

0 commit comments

Comments
 (0)
Please sign in to comment.