luciopaiva / witchcraft

Inject Javascript and CSS right from your file system. Think GreaseMonkey for more advanced users.
https://luciopaiva.com/witchcraft
MIT License
254 stars 18 forks source link

Issue in gmail causes Witchcraft js injection to fail #17

Closed Jeff-411 closed 4 years ago

Jeff-411 commented 5 years ago

Witchcraft's CSS code-injection into gmail works just great - and so far I've been able to 're-do' gmail's Inbox so it works very well for a visually-impaired family member. (The attached "Witchcraft_css_injection.png" screenshot shows the 're-done' Inbox at Chrome's default 100% zoom level.)

Witchcraft_css_injection

However, when I tried to inject some js code into the same page, I got the following error message: "The service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil() or respondWith() to wait for the promise to settle."

I then tried the js-injection in Opera, and (somewhere in the process) got a more helpful error message, which directed me to the page at; https://www.chromestatus.com/feature/5527160148197376

I have no idea what the info on the chromestatus page means! But I experimented around in Chrome a bit more - and found that the Witchcraft js code seems to be running twice - with quite different results. For one trial, I used the following code block in the Witchcraft js:

// @include jquery-3.4.0.min.js

$(document).ready(function(){
    console.log("HELLO");
    var pickle = $("body");
    console.log("pickle is: ", pickle);
});

The following "Chrome_error___Witchcraft_js_injection_failure.png" screenshot shows the resulting Console output.

Chrome_error___Witchcraft_js_injection_failure

Note that the expand/collapse arrows are in the expanded mode for both the first & second iterations... BUT, in the second instance, the 'pickle' var has no content! (The additional 'expand' arrows in the first instance work as expected - e.g. clicking on the body.aAU arrow will expand the BODY element in the normal way.)

I realize this is not really a Witchcraft issue - but I'm wondering if you could suggest some workaround that would let me inject Witchcraft js code into gmail.

Either way, I figured you'd probably want to know there was an issue affecting the functionality of this beautiful program. :)

Thanks for your time.

Jeff.

luciopaiva commented 4 years ago

Hey Jeff,

Sorry it took me so long to respond, but it's been busy over here :sweat_smile:

About the Gmail issue, I was able to reproduce it too:

image

The interesting thing, though, is that that is not a Witchcraft issue at all šŸ™‚. I just removed Witchcraft from my browser and the message still appears. It looks like Chrome throttles the loading of resources being requested by background tabs; nothing to worry about, though, as everything will eventually get loaded.

As for Witchcraft running twice, this is easy to explain. Head to mail.google.com and then open Chrome's console window. Click the dropdown list where it says top. You will see something like this:

image

Notice the about:blank item. It points to main.google.com as well. See, Witchcraft runs once for each and every frame in the window, not just the top one. If it finds another frame running in the same domain, your scripts will run there as well. And that explains why you were seeing two different "pickles" in your test. Let me reproduce what you saw:

image

This was the result of running the following Witchcraft script named main.google.com.js:


window.addEventListener("load", () => {
    console.info(document.body);
});

So Witchcraft found two body elements. It's easy to find both if you inspect the HTML. Here they are:

image

Notice the second body element; it lives inside an iframe. That's where the second instance of Witchcraft is running from! Notice it is a totally separate #document.

I realize this is not really a Witchcraft issue - but I'm wondering if you could suggest some workaround that would let me inject Witchcraft js code into gmail.

To work around the fact that you don't want Witchcraft to run inside the iframe, I guess your best option is to first check if you're running in the top frame. Here's an easy way to do it:

window.addEventListener("load", () => {
    const isTopFrame = window.self === window.top;
    console.info(isTopFrame ? "I am in the top frame!" : "I'm in some other frame");
});

And here's the result:

image

And that's it šŸ™‚ Hope I could help. Let me know if you have any other questions. Since this is not a Witchcraft issue, I am closing this issue now.

Cheers!