Search code examples
google-chrome-extensioncontent-script

content_script not running on GitHub when following links


I am writing a Chrome Extension mainly for Pull Requests on Github Enterprise and have ran into an issue. When the page is loaded via a refresh or direct entering of the url from your browser it runs, when it is ran from clicking a link within Github it does not.

For instance if you go to this page with Pull Requests and click into one of them it will not run. But if you refresh that same page it will run.

manifest.json

{
    "name": "Github Sample",
    "manifest_version": 2,
    "version": "0.0.1",
    "description": "Sample",
    "permissions": [
        "tabs", "<all_urls>",
        "http://github.com/*"
    ],
    "content_scripts": [
        {
            "matches": [ "https://github.com/*" ],
            "js": ["github.sample.js"],
            "run_at": "document_end"
        }
    ]
}

github.sample.json

// ==UserScript==
// @author Jacob Schoen
// ==/UserScript==

alert("Extension has Ran");

To make this easier I have pushed this to github.

Any ideas on how to address this?


Solution

  • GitHub site uses jquery-pjax library (see How to make github style page transitions by pjax).

    • Basically you only need to run the content script once and attach pjax event handlers inside an injected <script> element code which will be reusing a jQueryor $ variable of the site.

      • In those handlers you can send a message with document.dispatchEvent to your content script that will receive it in its window.addEventListener("blabla", ...)
      • or you can allow the access to chrome.runtime.sendMessage on the github site in manifest.json so that page-injected code will be able to send a message that can be received by the extension in chrome.runtime.onMessageExternal listener.
    • Alternatively you can use chrome.webNavigation.onHistoryStateUpdated in the background script but that will cause a warning during the installation that the extension can "Read your browsing history" which is a global permission unlike the content script solution.