0

I'm new to Chrome extensions. I know there's lots of similar questions and info out there, but none of it seems to address this problem.

I need my content script to execute on every page that matches *://*.youtube.com/watch?v=*.

I've tried using the above value and *://*.youtube.com/* as the match property, but neither works supposedly due to the way YouTube handles requests. I've also tried using the onhashchange event, but of course YouTube doesn't use anchors in their URLs. I've read about webRequest, but I don't need the function to be called when somebody is scrolling through the comments and the page loads more comments.

All I need is a way to call my content script when the URL changes. How exactly can I accomplish this?

Additionally, I cannot load the content script at document_start because the extension scrapes the HTML and parses it.

oldboy
  • 5,729
  • 6
  • 38
  • 86
  • @wOxxOm your solution doesn't work for me... i cannot execute the content script at `document_start` because the extension scrapes the HTML and parses it – oldboy Jul 24 '17 at 07:22
  • Then simply use [webNavigation](https://developer.chrome.com/extensions/webNavigation)'s history events shown [here](https://stackoverflow.com/a/25932741) – wOxxOm Jul 24 '17 at 07:26
  • that's exactly what i am looking into right now. but can webNavigation even be used with a content script?? also, youtube doesn't use hashes?? – oldboy Jul 24 '17 at 07:27
  • No, it cannot be used in a content script, which is exactly why I've suggested it as I misunderstood your comment about document_start. Also, url-hash change is only one event of the three shown in that link, simply use the other two. If you want to do it in a content script then my [initial suggestion](https://stackoverflow.com/questions/34077641/how-to-detect-page-navigation-on-youtube-and-modify-html-before-page-is-rendered/34100952?s=3|0.1801#34100952) can be used because document_start is not an absolute requirement. – wOxxOm Jul 24 '17 at 07:31
  • @wOxxOm your solution in your other answer doesn't work since my content script is executed at `document_end`, and by that time the `DOMContentLoaded` event has already come and gone. additionally, the `spfdone` event is never called either. what events should i rebind those listeners to if not `DOMContentLoaded` or `spfdone`? – oldboy Jul 24 '17 at 07:43
  • 1
    That answer is an example. In your case there's no need for DOMContentLoaded at all: you can scrape the initial DOM immediately. Also, spfdone is triggered for me https://puu.sh/wRCVm/fa465cfb19.png when another video page is loaded, which is what this event is for. – wOxxOm Jul 24 '17 at 07:45
  • 1
    @wOxxOm i know it was an example. i got it working. i just removed the document listener and called the function within the content script. [this chosen solution also worked](https://stackoverflow.com/questions/20865581/chrome-extension-content-script-not-loaded-until-page-is-refreshed/21071357#21071357) ... never mind your solution still doesn't work lol – oldboy Jul 24 '17 at 07:52
  • @wOxxOm i jumped the gun when i said "this chosen solution also worked". it works to the extent that it executes the content script when the history changes, but even with `runAt: 'document_idle'` it executes **way** too early, which breaks the functionality of my extension :/ – oldboy Jul 24 '17 at 10:29
  • The new event used by youtube is `yt-navigate-start` on `window`, which you can discover by running `getEventListeners(window)` in devtools console. So simply attach event listener for that event and also for `load` on `window` for the first run of the content script. – wOxxOm Jul 24 '17 at 10:52
  • 2
    I've [edited that answer](https://stackoverflow.com/a/34100952/) to provide a more generalized approach. – wOxxOm Jul 24 '17 at 11:11
  • @wOxxOm okay, it works now. that was the issue, that i'm using the new YT. however, i'm running into the exact same issue as `chrome.tabs.executeScript`, which is that the script executes wayyy **too early**. my script needs to run **after** a script in the website's `body` is executed :.( the idea that i thought of last night would be maybe sending messages back and forth? maybe that's the best idea? – oldboy Jul 24 '17 at 20:03
  • 1
    Well, you can wait for the element produced by that script by using MutationObserver. – wOxxOm Jul 24 '17 at 20:07
  • @wOxxOm sweet. i'll look into that right now **<3** – oldboy Jul 24 '17 at 20:09
  • Possible duplicate of [How to detect page navigation on Youtube and modify HTML before page is rendered?](https://stackoverflow.com/questions/34077641/how-to-detect-page-navigation-on-youtube-and-modify-html-before-page-is-rendered) – Makyen Jul 25 '17 at 22:19

1 Answers1

-1

I had the same issue and this is what I did. I added a background script to listen to all changes

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    if (changeInfo.url) {
        chrome.tabs.sendMessage(tabId, {
            message: 'hello',
            url: changeInfo.url
        });
    }
});

Then in my content script, I listen to it and reload the URL

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
        if (request.message === 'hello') {
            const { url } = request;
            chrome.location.replace(url);
        }

});
Dharman
  • 30,962
  • 25
  • 85
  • 135
Wadson Vaval
  • 91
  • 1
  • 7