3

I have a Chrome extension that is limited to an url like this: https://*.example.com/fix-path, however, it would not load when I navigate to the url unless I refresh the page.

I've managed to overcome the issue in two ways, but neither one is good enough and I'd like to understand why it would not work the way I wrote it originally.

Original solution

manifest.json

{
    "manifest_version": 2,
    "name": "Example",
    "version": "1",
    "content_scripts": [
        {
            "matches": [
                "https://*.example.com/fix-path"
            ],
            "js": [
                "main.js"
            ],
            "run_at": "document_end"
        }
    ]
}

main.js

document.onmousemove = event => {
    console.log('hello world');
};

Workaround #1

manifest.json

{
    "manifest_version": 2,
    "name": "Example",
    "version": "1",
    "content_scripts": [
        {
            "matches": [
                "https://*.example.com/*"
            ],
            "js": [
                "main.js"
            ],
            "run_at": "document_end"
        }
    ]
}

main.js

document.onmousemove = event => {
    console.log('hello world');
};

Issues with this solution

Note, that almost everything is the same. The only difference is that I do not limit my script to a specific url, but to the whole domain. My only problem is that I really need document.onmousemove, which produces tons of events. It is unnecessary to listen to them on other sub pages.

Workaround #2

Solution borrowed from https://stackoverflow.com/a/21071357/1372608

manifest.json

{
    "manifest_version": 2,
    "name": "Example",
    "version": "1",
    "background": {
        "scripts": [
            "background.js"
        ]
    },
    "content_scripts": [
        {
            "matches": [
                "https://*.example.com/fix-path"
            ],
            "js": [
                "main.js"
            ],
            "run_at": "document_end"
        }
    ],
    "permissions": [
        "https://*.example.com/fix-path",
        "tabs",
        "webNavigation"
    ]
}

background.js

chrome.webNavigation.onHistoryStateUpdated.addListener(details => {
    chrome.tabs.executeScript(null, { file: 'main.js' });
});

main.js

document.onmousemove = event => {
    console.log('hello world');
};

Issues with this solution

If I navigate to the https://example.com and then I just click on the menu item to open /fix-path, the extension will load without the need for refresh, however, after this, if I navigate anywhere else, the extension will be loaded. Even the main page will have it loaded once I navigate back.

Conclusion / Final words

It is not the end of the World for me to use either one of these workarounds for neither one is that bad. However, I'd very much want to know why it is not working the way I think it should...

Anyone? : )

UPDATE: After some fiddling, I've found that the second workaround is almost good. The issue is that once the main.js is loaded, document.onmousemove will have a function to call. I somehow have to "delete" this... I have to unload the content script.

Community
  • 1
  • 1
ppseprus
  • 538
  • 1
  • 8
  • 26
  • Please describe **exactly** the URLs you visit and user interaction which you perform in the non-working/working cases: number the steps; be very specific. We need to be able to duplicate the issue without having to guess at what you were doing, or needing to fiddle around to find the broken case. – Makyen Feb 07 '17 at 12:53
  • It was intentional. The website I'm doing it for asks for registration, therefore, you can't really try it unless you put even more effort in it. https://github.com/ppseprus/globalxplorer-tile-enhancer – ppseprus Feb 07 '17 at 13:28
  • Also, I've added an update... – ppseprus Feb 07 '17 at 13:28
  • [Is there a JavaScript/jQuery DOM change listener?](//stackoverflow.com/a/39508954) – wOxxOm Feb 07 '17 at 14:42
  • If the solution (#1) of injecting your content script on somewhat more pages works for the subset of pages in which you have an interest, then that sound like a good solution. Your content script can then look at `location.href` and choose to enable, or not, the `mousemove` listener, which should be added with `document.addEventListener`, or `window.addEventListener`, not the `onmousemove` property). In other words, even if the content script is injected, it does not *have to* add the `mousemove` listener to every page in which it is injected. – Makyen Feb 07 '17 at 14:45
  • Thanks. Yes. I actually have this and I realise now, that this is not in the repo. It is only on my local machine... However, as I said in the original post in the "Conclusion / Final words" block, the above solutions are all fine and if I spend enought time with it, I might have even more. I want to know why the original version does not work the way I think it should. That is the question, not how many workarounds can I come up with or which one is sufficient... – ppseprus Feb 07 '17 at 15:27
  • Also, what you just wrote would not work. Watching the change of the "location" would not work that simply, since the content scripts do not have any idea about that... I've created a background script that messages to the content script upon `onHistoryStateUpdated`... – ppseprus Feb 07 '17 at 15:35

0 Answers0