Skip to content

Embedded JS: Conditionally inject jQuery #9861

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

Merged
merged 5 commits into from
Jan 5, 2023
Merged

Embedded JS: Conditionally inject jQuery #9861

merged 5 commits into from
Jan 5, 2023

Conversation

stsewd
Copy link
Member

@stsewd stsewd commented Jan 4, 2023

For injecting the flyout menu we are relying on a script from our theme, that script depends on jQuery, so it needs to be present for the flyout menu to work.

/// Inject the Read the Docs Sphinx theme code
/// This is necessary on older versions of the RTD theme (<0.4.0)
/// and on themes other then the RTD theme (used for the version menu)
if (window.SphinxRtdTheme === undefined) {
sphinx_theme = require('sphinx-rtd-theme'); // eslint-disable-line global-require
var theme = sphinx_theme.ThemeNav;
// Enable the version selector (flyout) menu
// This is necessary for 3rd party themes
domReady(function () {
setTimeout(function () {
if (!theme.navBar) {
theme.enable();
}
}, 1000);
});

We have migrated most of our code to vanilla JS,
but this piece isn't simple to migrate.

For injecting the flyout menu we are relying on a script from our theme,
that script depends on jQuery, so it needs to be present for the
flyout menu to work.

https://github.com/readthedocs/readthedocs.org/blob/67c44a1f1b27dcc66bd14520d019459fcf86354d/readthedocs/core/static-src/core/js/doc-embed/sphinx.js#L43-L59

We have migrated most of our code to vanilla JS,
but this piece isn't simple to migrate.
@stsewd stsewd requested a review from a team as a code owner January 4, 2023 16:01
@stsewd stsewd requested a review from agjohnson January 4, 2023 16:01
Copy link
Member

@ericholscher ericholscher left a 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 addition, and something I've been wanting for a while now 👍

console.log("JQuery not found. Injecting.");
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://code.jquery.com/jquery-3.6.3.min.js";
Copy link
Member

Choose a reason for hiding this comment

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

Should we define this as a constant? Looks like we have 3.5.1 in current RTD docs: https://docs.readthedocs.io/en/stable/_static/jquery.js

Copy link
Member Author

Choose a reason for hiding this comment

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

Do you mean like something people can override? We would need to have two constants, one for the url and the other for the integrity hash. But if people want to inject a specific version, they can just do that, since we inject ours only if jquery isn't present.

Copy link
Contributor

Choose a reason for hiding this comment

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

Should this also be loaded from a readthedocs.io domain because of CSP?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah agreed with @benjaoming, for CSP and CORS related headaches, this should be from our own domain.

I'd probably say we should just inject our existing jQuery vendored bundle, which is compiled using Gulp/Bower. Our current vendored jQuery is 2.0 however, but the API hasn't changed too much as well: https://github.com/readthedocs/readthedocs.org/blob/main/bower.json#L17

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 loaded from docs domains, we don't have a CSP there, but +1 on serving this from /_/static/. About the version, guess, anything that works with https://github.com/readthedocs/sphinx_rtd_theme/blob/0.3.1/js/theme.js should be fine. But since our theme was depending on the jquery version from sphinx not sure if there would be any problems, but running locally should be enough to test it I guess

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm guessing we're also probably okay upgrading the jQuery version installed via Bower, we don't do anything particularly interesting in the existing templates/JS.

Copy link
Member Author

Choose a reason for hiding this comment

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

Unable to find a suitable version for jquery, please choose one by typing one of the numbers below:
    1) jquery#~1.8.1 which resolved to 1.8.3 and is required by jquery-ui#1.8.23
    2) jquery#3.6.3 which resolved to 3.6.3 and is required by readthedocs
    3) jquery#>=1.5 which resolved to 3.6.3 and is required by jquery.payment#1.3.3

Don't think we are using the other plugins. I went ahead and wrote 2!, but I don't see the new files being copied to media, hmm, do we have a script for copying the files? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@agjohnson agjohnson Jan 4, 2023

Choose a reason for hiding this comment

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

I don't recall what we even use jquery-ui for, but the latest version of jquery-ui is a minor version bump and supports jQuery =< 3.6.

Good question on the static files. Vendored libraries are processed with Gulp here:
https://github.com/readthedocs/readthedocs.org/blob/main/gulpfile.js#L193

And are output here:
https://github.com/readthedocs/readthedocs.org/tree/main/readthedocs/static/vendor

As far as I know, this should just work with static collection. I see the assets in prod, and are requested from the application successfully.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah missed your reply until reload. I thought gulp build built all assets, but the command is separate, gulp vendor.

@stsewd stsewd requested a review from a team as a code owner January 4, 2023 19:40
@stsewd stsewd requested a review from humitos January 4, 2023 19:40
Comment on lines 28 to 30
// Set jQuery to its expected globals.
window.$ = require("jquery");
window.jQuery = window.$;
Copy link
Member Author

Choose a reason for hiding this comment

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

Not really sure if this is the way of doing it... but just adding the script from vendor/jquery.js doesn't add the global variables :/ /cc @agjohnson

Copy link
Contributor

Choose a reason for hiding this comment

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

Yup, this is normal. Relying on every module to be a global is an antipattern that doesn't work well with various forms of module importing -- commonJS, AMD, ES6 module imports, etc. Modern JS would tend to use jQuery as a module instead.

Your change is about what I'd do.

@stsewd
Copy link
Member Author

stsewd commented Jan 4, 2023

Ok, I have updated this PR to:

Comment on lines +282 to +283
"proxied_static_path": self.project.proxied_static_path,
"proxied_api_host": self.project.proxied_api_host,
Copy link
Member Author

Choose a reason for hiding this comment

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

We were missing including these for mkdocs, but it's only relevant when using a path different from _/, so

Copy link
Contributor

@benjaoming benjaoming left a comment

Choose a reason for hiding this comment

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

Solid work @santos22 💯 I'm wondering if there's any adjustments that we'd want to make in the Sphinx 6 post readthedocs/blog#201

On top of my head, I think it's great that this change ensures that nothing breaks - both our own Fly Out menu and whatever people have going on in their themes and projects can continue to use jQuery.

However, I'm a bit 👎 on documenting jQuery as something that's provided, hence also mentioning this in a blog post. People might use it, and then it gets even harder to remove.. when we want to deprecate it at some point.

I suppose that proxied_static_path is a heavily cached location?

@benjaoming benjaoming changed the title Embedded JS: Inject jQuery is isn't present Embedded JS: Conditionally inject jQuery Jan 5, 2023
@stsewd
Copy link
Member Author

stsewd commented Jan 5, 2023

I suppose that proxied_static_path is a heavily cached location?

Yeah, that's cached at the CDN level.

Also, I think you tagged the wrong user p:

Solid work @\santos22

Copy link
Contributor

@agjohnson agjohnson left a comment

Choose a reason for hiding this comment

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

This is a great fix for now 👍

I'll definitely want to remove this dependency as we break apart the theme and flyout JS. There definitely shouldn't be theme specific JS in the flyout JS and there shouldn't be flyout specific JS in the theme.

@stsewd stsewd merged commit 7ed657e into main Jan 5, 2023
@stsewd stsewd deleted the inject-jquery branch January 5, 2023 21:53
stsewd added a commit that referenced this pull request Jan 9, 2023
I guess this is related to the jquery update from #9861,
or maybe this line wasn't working and we were relying
in something else?

Not sure why I didn't notice this before,
maybe my browser cache :(

Ref #9861
stsewd added a commit that referenced this pull request Jan 9, 2023
I guess this is related to the jquery update from #9861,
or maybe this line wasn't working and we were relying
in something else?

Not sure why I didn't notice this before,
maybe my browser cache :(

Ref #9861
stsewd added a commit that referenced this pull request Jan 9, 2023
I guess this is related to the jquery update from #9861,
or maybe this line wasn't working and we were relying
in something else?

Not sure why I didn't notice this before,
maybe my browser cache :(

Ref #9861
mitya57 added a commit to mitya57/sphinx that referenced this pull request Mar 19, 2023
Loading jQuery is not needed since this PR was merged in Read the Docs:
readthedocs/readthedocs.org#9861.

And exposing app.{info,warn,debug} was not needed since 2018:
readthedocs/readthedocs-sphinx-ext#51.
AA-Turner pushed a commit to sphinx-doc/sphinx that referenced this pull request Mar 23, 2023
Loading jQuery is not needed since January 2023:
readthedocs/readthedocs.org#9861

And exposing app.{info,warn,debug} is not needed since September 2018:
readthedocs/readthedocs-sphinx-ext#51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants