Skip to content
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

Merged
merged 1 commit into from
Aug 29, 2019

Conversation

GuillaumeGomez
Copy link
Member

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

@jonas-schievink jonas-schievink added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Jul 26, 2019
@rust-lang rust-lang deleted a comment from rust-highfive Jul 27, 2019
@rust-lang rust-lang deleted a comment from rust-highfive Jul 27, 2019
@rust-lang rust-lang deleted a comment from rust-highfive Jul 27, 2019
@rust-lang rust-lang deleted a comment from rust-highfive Jul 27, 2019
@rust-lang rust-lang deleted a comment from rust-highfive Jul 27, 2019
@rust-lang rust-lang deleted a comment from rust-highfive Jul 27, 2019
@GuillaumeGomez
Copy link
Member Author

@bors: try

@bors
Copy link
Contributor

bors commented Jul 27, 2019

⌛ Trying commit ef31242846ccd0b20945216a5982d5ea0d5d087e with merge eef66491f53a32b2c37f3188a8b4cf6f481488db...

@bors
Copy link
Contributor

bors commented Jul 27, 2019

☀️ Try build successful - checks-azure
Build commit: eef66491f53a32b2c37f3188a8b4cf6f481488db

@rust-lang rust-lang deleted a comment from rust-highfive Jul 27, 2019
@rust-lang rust-lang deleted a comment from rust-highfive Jul 27, 2019
@GuillaumeGomez
Copy link
Member Author

@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db

@rust-highfive
Copy link
Collaborator

Rustdoc-UI starting test...

@bors
Copy link
Contributor

bors commented Jul 28, 2019

☀️ Try build successful - checks-azure
Build commit: eef66491f53a32b2c37f3188a8b4cf6f481488db

@bors
Copy link
Contributor

bors commented Jul 28, 2019

☀️ Try build successful - checks-azure
Build commit: eef66491f53a32b2c37f3188a8b4cf6f481488db

@GuillaumeGomez
Copy link
Member Author

@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db

@rust-highfive
Copy link
Collaborator

Rustdoc-UI starting test...

@GuillaumeGomez
Copy link
Member Author

@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db

@rust-highfive
Copy link
Collaborator

Rustdoc-UI starting test...

@GuillaumeGomez
Copy link
Member Author

@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db

@rust-highfive
Copy link
Collaborator

Rustdoc-UI starting test...

@GuillaumeGomez
Copy link
Member Author

@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db

@rust-highfive
Copy link
Collaborator

Rustdoc-UI starting test...

@rust-highfive
Copy link
Collaborator

Rustdoc-UI tests failed "successfully"!

Click to expand the log.
=> Starting doc-ui tests...

basic-code... FAILED (images "basic-code-eef66491f53a32b2c37f3188a8b4cf6f481488db.png" and "basic-code.png" are different)
basic... FAILED (images "basic-eef66491f53a32b2c37f3188a8b4cf6f481488db.png" and "basic.png" are different)
code-sidebar-toggle-mobile... FAILED (images "code-sidebar-toggle-mobile-eef66491f53a32b2c37f3188a8b4cf6f481488db.png" and "code-sidebar-toggle-mobile.png" are different)
code-sidebar-toggle... FAILED (images "code-sidebar-toggle-eef66491f53a32b2c37f3188a8b4cf6f481488db.png" and "code-sidebar-toggle.png" are different)
list_code_block... FAILED (images "list_code_block-eef66491f53a32b2c37f3188a8b4cf6f481488db.png" and "list_code_block.png" are different)
module-mobile... FAILED (images "module-mobile-eef66491f53a32b2c37f3188a8b4cf6f481488db.png" and "module-mobile.png" are different)
theme-change... FAILED (images "theme-change-eef66491f53a32b2c37f3188a8b4cf6f481488db.png" and "theme-change.png" are different)
toggle-docs... FAILED (images "toggle-docs-eef66491f53a32b2c37f3188a8b4cf6f481488db.png" and "toggle-docs.png" are different)

<= doc-ui tests done: 0 succeeded, 0 ignored, 8 failed

@GuillaumeGomez
Copy link
Member Author

@highfive: run-doc-ui eef66491f53a32b2c37f3188a8b4cf6f481488db

Copy link
Member

@Mark-Simulacrum Mark-Simulacrum left a 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?

}

function getSavedCrates(savedCrates) {
if (typeof savedCrates === "undefined") {
Copy link
Member

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.

Copy link
Member Author

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!

var elems = getSavedCrates(savedCrates);
if (elems.hasOwnProperty(getCratesHash())) {
onEach(window.crates, function(e) {
if (e === elems[window.hashCode]) {
Copy link
Member

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

});
window.crates.sort();
}
window.hashCode = window.crates.join(",").hashCode();
Copy link
Member

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?

Copy link
Member Author

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.

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)
Copy link
Member

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.

Copy link
Member Author

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. :)

Copy link
Member

@Mark-Simulacrum Mark-Simulacrum Aug 9, 2019

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.

if (selectCrate) {
selectCrate.onchange = function() {
var savedCrates = getSavedCrates();
const value = selectCrate.value;
savedCrates[getCratesHash()] = value === "All crates" ? undefined : value;
Copy link
Member

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?

Copy link
Member Author

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...

Copy link
Member Author

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.

Copy link
Member

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

@GuillaumeGomez
Copy link
Member Author

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?

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.

@Mark-Simulacrum
Copy link
Member

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.

@GuillaumeGomez
Copy link
Member Author

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).

@Mark-Simulacrum
Copy link
Member

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.

@GuillaumeGomez
Copy link
Member Author

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!)

@Mark-Simulacrum
Copy link
Member

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.

@GuillaumeGomez
Copy link
Member Author

Ok, I'll rewrite the PR then. Thanks a lot for your review @Mark-Simulacrum!

@@ -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);
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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.

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 10, 2019
@joelpalmer
Copy link

Ping from Triage: Hi @GuillaumeGomez - any update on this?

@GuillaumeGomez
Copy link
Member Author

Updated.

@totsteps
Copy link
Member

Ping from triage, @Mark-Simulacrum it seems GuillaumeGomez have made required changes. Can you please review this PR once again.

Thanks.

@@ -445,6 +445,18 @@ if (!DOMTokenList.prototype.remove) {
var OUTPUT_DATA = 1;
var params = getQueryStringParams();

// Loading the crate filter if any.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated change, I hope?

Copy link
Member Author

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...

@@ -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);
Copy link
Member

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.

@GuillaumeGomez
Copy link
Member Author

Updated.

@Mark-Simulacrum
Copy link
Member

@bors r+

Okay, this looks good to me. Thanks of bearing with me on reviews!

@bors
Copy link
Contributor

bors commented Aug 28, 2019

📌 Commit 06228d3 has been approved by Mark-Simulacrum

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 28, 2019
@GuillaumeGomez
Copy link
Member Author

Thanks to you for handling the reviews!

@bors
Copy link
Contributor

bors commented Aug 28, 2019

⌛ Testing commit 06228d3 with merge 0414dfa...

bors added a commit that referenced this pull request Aug 28, 2019
…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
@bors
Copy link
Contributor

bors commented Aug 29, 2019

☀️ Test successful - checks-azure
Approved by: Mark-Simulacrum
Pushing 0414dfa to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Aug 29, 2019
@bors bors merged commit 06228d3 into rust-lang:master Aug 29, 2019
@GuillaumeGomez GuillaumeGomez deleted the save-crate-filter branch August 29, 2019 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Documentation: remember the selected crate in search
8 participants