-
Notifications
You must be signed in to change notification settings - Fork 183
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
fix(patchUrlMappings): recreate script elements when patching their src attribute #242
Conversation
docs/local-sdk-development.md
Outdated
@@ -11,3 +11,4 @@ To test changes to the SDK, locally, with either of these projects, you must do | |||
|
|||
1. From terminal, navigate to the root of either project's directory, (i.e. examples/discord-application-start or examples/sdk-playground) | |||
2. Start up the example's web server with `pnpm dev`. | |||
3. Start up the SDK's development pipeline with `pnpm dev`. |
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.
🙃
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.
Great callout. We may want to clarify this one is run from the root of the repo
function attemptRecreateScriptNode(node: HTMLElement, {url, mappings}: RemapInput) { | ||
const newUrl = attemptRemap({url, mappings}); | ||
if (url.toString() !== newUrl.toString()) { | ||
const newNode = document.createElement(node.tagName); |
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.
I couldn't node.clone()
here because script nodes have internal state on whether or not the node has started its fetch. See https://html.spec.whatwg.org/multipage/scripting.html and search the page for "already started", or this StackOverflow answer.
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.
Looks great. Thanks for calling out how we got here. It may be worth leaving a comment to explain the motivation
Well done 👏🏻
src/utils/patchUrlMappings.ts
Outdated
attemptSetNodeSrc(node, mappings); | ||
|
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.
Copying my feedback from Andrew's PR
Super-opinionated-pedantic nit
We should rename the function to recursivelyRemapNodeAndChildNodes
or we can call attemptSetNodeSrc inside the original mutation's added nodes
if (patchSrcAttributes) {
const callback: MutationCallback = function (mutationsList) {
for (const mutation of mutationsList) {
if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
attemptSetNodeSrc(mutation.target, mappings);
} else if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
attemptSetNodeSrc(node, mappings); // Heres the added line
recursivelyRemapChildNodes(node, mappings);
});
}
}
};
Either works. I'm pro the code-snippet above as it should result in less function calls. But we should double-check that it still solves the core issue
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.
looks great! 🚢
Currently, when a new
script
tag is created via an imported JavaScript package, we are changing thesrc
attribute for that script tag when it goes through the normalMutationObserver
flow. However, a refetch doesn't happen;MutationObserver
only goes off when the HTML element is added, but never stops the outgoing request.With this change, if the
MutationObserver
sees that it's modifying a<script src=
attribute, it'll instead create a newscript
tag in the DOM next to the one it would have modified, and then destroy the original. Unfortunately this will still show the error from the request blocked by the CSP, but it will go off separately and make the new request with the second script tag as well, loading in the content.I'd be curious to collect thoughts on this solution. It's obviously destructive to do this for things like
img
tags (since React for instance would break when it goes to rerender), but I'm hoping this will solve the problem forscript
tags.Includes the change from #239, since it was needed to fix my local test case as well.