-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Save crate filtering on rustdoc #62941
Conversation
ad00098
to
ef31242
Compare
@bors: try |
⌛ Trying commit ef31242846ccd0b20945216a5982d5ea0d5d087e with merge eef66491f53a32b2c37f3188a8b4cf6f481488db... |
☀️ Try build successful - checks-azure |
@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db |
Rustdoc-UI starting test... |
☀️ Try build successful - checks-azure |
☀️ Try build successful - checks-azure |
@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db |
Rustdoc-UI starting test... |
@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db |
Rustdoc-UI starting test... |
@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db |
Rustdoc-UI starting test... |
@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db |
Rustdoc-UI starting test... |
Rustdoc-UI tests failed "successfully"! Click to expand the log.
|
@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm following this patch correctly, it'll ignore the stored preference if the crate list has changed since the last time the page was loaded. That sounds not entirely helpful, at least in most scenarios, where you might have N crates (including dependencies) and one of your dependencies changing shouldn't really lead to the selector here getting reset.
With that all in mind, maybe this PR can be simplified quite a bit by just storing the single name of the crate most recently selected in local storage?
src/librustdoc/html/static/main.js
Outdated
} | ||
|
||
function getSavedCrates(savedCrates) { | ||
if (typeof savedCrates === "undefined") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this checking for undefined here? Why can't call sites just pass in getCurrentValue(...)
as needed?
It looks like there's two call sites to this function: one passes getCurrentValue after a !== null
check, the other calls this function with no arguments. The discrepancy there is a bit odd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good point, this check is completely useless. Good catch!
src/librustdoc/html/static/main.js
Outdated
var elems = getSavedCrates(savedCrates); | ||
if (elems.hasOwnProperty(getCratesHash())) { | ||
onEach(window.crates, function(e) { | ||
if (e === elems[window.hashCode]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid storing the crates hash in a global variable and simply have it in a variable here? It looks like this function should presumably be called only once so presumably that's equivalent performance wise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
src/librustdoc/html/static/main.js
Outdated
}); | ||
window.crates.sort(); | ||
} | ||
window.hashCode = window.crates.join(",").hashCode(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole list of crates isn't that long in most cases, and we store it in memory here anyway, so why do we need to compute it's hash? Can't the crate list simply be stored as a string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the storage, not just as is.
src/librustdoc/html/static/main.js
Outdated
if (window.hashCode === undefined || window.hashCode === 0) { | ||
if (window.crates === undefined || window.crates.length === 0) { | ||
window.crates = cloneArray(document.getElementById("crate-search") | ||
.getElementsByTagName("option"), 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICT, we wouldn't actually break anything if we didn't skip the first element in the options list here (it's always the same, sure, but that doesn't hurt). Can we do that to simplify the code here a little? It should also allow dropping the skip
arg from cloneArray
which is pretty irrelevant to the main purpose of the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It adds a useless element into the hash computation and slows it down. If we remove the hash system, then this skip will become useless indeed but for the moment it's important to keep it. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cost of hashing this string is likely to be near-zero compared to all the other JS and such that we're running. I would rather pay that cost and have simpler to read code; as-is we at the very least should have a comment to the effect of strips out default 'all crates' at the beginning.
src/librustdoc/html/static/main.js
Outdated
if (selectCrate) { | ||
selectCrate.onchange = function() { | ||
var savedCrates = getSavedCrates(); | ||
const value = selectCrate.value; | ||
savedCrates[getCratesHash()] = value === "All crates" ? undefined : value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, it seems reasonable that we can store "All crates"
in local storage as well since it'll simplify the code here a little and ultimately doesn't affect anything presumably?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just to avoid keeping unused values. Otherwise, every time you go visit a crate, it'll be added to the local storage, which doesn't sound that nice...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It affect local storage space (which is surprisingly limited). Like this, we don't store the defaults.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work if there's only one crate? It seems like we presumably just don't run this code then? Can we get comments about:
- the 'no select crate' dialog case
- the reasoning for why we want to not store anything for the all crates case
If I do this, it'll get applied to all documentations (on docs.rs for example) and then you'll get some conflicts. Which is why I used this system. If you update dependencies, it'll be reset but it sounded better than having conflicts between crates. |
Hm, sure, but that seems like an orthogonal problem. On docs.rs it doesn't matter anyway I think because all crates are built on their own, there's no crate list anyway. |
Yes but then you'll save this only for one crate. That doesn't seem very useful if done this way... If you provide a website which provides documentation for multiple crates and their dependencies, you'll need it (like doc.rust-lang.org for example which provides std and rustc-internals). |
I think it being reset is fine for now, since it simplifies the code quite a bit. The only notable site for which it'll matter I think is doc.rust-lang.org, and even there it's only if you're both a) using the selection dialog and b) navigate to both std docs and rustc internals docs. I'd guess the combination there is pretty rare, so solving that use case in this PR seems unnecessary. If we were to solve that use case, I would prefer to solve it (not in this PR!) by having rustdoc itself, not the JS, embed some sort of identifier into pages of "build unit" style that we could then use. There's a lot of complexity here (hash function, etc.) that seems like it could be avoided for relatively low impact on most users, and I think we should do that. |
I think you're right. If I just store current selected crate name, is it good for you? (the PR will become much smaller indeed!) |
Yes, I think this should store the selected crate name, and if it is not found, fall back to all crates (but, importantly, not remove the stored preference). I think that gives us the behavior most users want (at least on one "build") and it doesn't erase preferences unnecessarily. |
Ok, I'll rewrite the PR then. Thanks a lot for your review @Mark-Simulacrum! |
src/librustdoc/html/render.rs
Outdated
@@ -1157,7 +1157,7 @@ themePicker.onblur = handleThemeButtonsBlur; | |||
&format!("{}\n{}", variables.join(""), all_indexes.join("\n")), | |||
options.enable_minification), | |||
&dst); | |||
try_err!(write!(&mut v, "initSearch(searchIndex);addSearchOptions(searchIndex);"), &dst); | |||
try_err!(write!(&mut v, "addSearchOptions(searchIndex);initSearch(searchIndex);"), &dst); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I forgot to note during initial review -- can you explain why this has changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A global variable story. Not sure if it'll be needed anymore once I apply the new changes you suggested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should now be not needed since I believe we've eliminated global variables entirely.
Ping from Triage: Hi @GuillaumeGomez - any update on this? |
ef31242
to
ff5d1ba
Compare
Updated. |
Ping from triage, @Mark-Simulacrum it seems GuillaumeGomez have made required changes. Can you please review this PR once again. Thanks. |
src/librustdoc/html/static/main.js
Outdated
@@ -445,6 +445,18 @@ if (!DOMTokenList.prototype.remove) { | |||
var OUTPUT_DATA = 1; | |||
var params = getQueryStringParams(); | |||
|
|||
// Loading the crate filter if any. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Loading the crate filter if any. | |
// Set the crate filter from saved storage, if the current page has the saved crate filter. | |
// If not, ignore the crate filter -- we want to support filtering for crates on sites like doc.rust-lang.org | |
// where the crates may differ from page to page while on the same domain. |
@@ -57,7 +57,7 @@ function onEachLazy(lazyArray, func, reversed) { | |||
|
|||
function usableLocalStorage() { | |||
// Check if the browser supports localStorage at all: | |||
if (typeof(Storage) === "undefined") { | |||
if (typeof Storage === "undefined") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated change, I hope?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, syntax fix. Didn't even think about it...
src/librustdoc/html/render.rs
Outdated
@@ -1157,7 +1157,7 @@ themePicker.onblur = handleThemeButtonsBlur; | |||
&format!("{}\n{}", variables.join(""), all_indexes.join("\n")), | |||
options.enable_minification), | |||
&dst); | |||
try_err!(write!(&mut v, "initSearch(searchIndex);addSearchOptions(searchIndex);"), &dst); | |||
try_err!(write!(&mut v, "addSearchOptions(searchIndex);initSearch(searchIndex);"), &dst); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should now be not needed since I believe we've eliminated global variables entirely.
ff5d1ba
to
06228d3
Compare
Updated. |
@bors r+ Okay, this looks good to me. Thanks of bearing with me on reviews! |
📌 Commit 06228d3 has been approved by |
Thanks to you for handling the reviews! |
…acrum Save crate filtering on rustdoc Fixes #62929. I added a hashmap and a hash encoding for the current crate list in case you have multiple crates handling on a same website (who talked about docs.rs?!). Like that, for each context, you have the filter crate selected. r? @QuietMisdreavus
☀️ Test successful - checks-azure |
Fixes #62929.
I added a hashmap and a hash encoding for the current crate list in case you have multiple crates handling on a same website (who talked about docs.rs?!). Like that, for each context, you have the filter crate selected.
r? @QuietMisdreavus