Search code examples
ajaxgoogle-chromeiframegoogle-chrome-extensiongoogle-search

Chrome-extension URL match patterns:Why rules are not working for Google.com?


I'm making an extension to customize Google' homepage background.So I write some match rules in manifest like this:

"content_scripts": [
    {
      "matches": ["https://www.google.com/", "http://www.google.com/"],
      "js": ["static/js/jquery.js", "static/js/contentscript.js"]
    }
],

and some scripts in contentscript.js:

var imgURL = chrome.extension.getURL("static/images/bg.jpg");
$('body').css('background-image', 'url(' + imgURL + ')');

The script works fine for https://www.google.com, but when I try to search something ,the page jumps to https://www.google.com/#newwindow=1&sclient=psy-ab&q=Google&oq=Google&gs_l=hp.3..35i39l2j0i20l2j0l6.4788.5717.2.5939.5.3.2.0.0.0.142.397.0j3.3.0....0.0..1c.1.20.hp.xCFVga8gVZU&bav=on.2,or.r_cp.r_qf.&bvm=bv.49784469%2Cd.dGI%2Cpv.xjs.s.en_US.MpiVkF51mpA.O&fp=806ba48f5b2ed550&biw=1920&bih=963

But the script is still working after the jumping! And if I paste the long url in a new tab directly, it won't work!

I think it should be related with iframe or Ajax or something else. Could someone give some more details? And how can I prevent scripts from running after the url changed?


Solution

  • If you want to apply a style to Google's home page, just use a selector which is very specific to Google's homepage. With the Inspector, I quickly discovered that the <body> tag at the homepage has a class "hp". This class does not show up in search results.

    Drop your JavaScript code, and use

    Part of manifest.json

    "content_scripts": [
        {
          "matches": ["*://www.google.com/*"],
          "css": ["my-google-style.css"]
        }
    ],
    "web_accessible_resources": [
        "static/images/bg.jpg"
    ],
    
    • The first wildcard, *, means "http" and "https".
    • The added wildcard at the end does not matter, because the "homepage" requirement is enforced in the next stylesheet.
    • The "web_accessible_resources" key is necessary if you want to display the image in an external (=non-extension) page.

    my-google-style.css

    body.hp {
        background-image: url("chrome-extension://__MSG_@@extension_id__/static/images/bg.jpg");
    }
    

    The first part of my answer is the recommendation for your case. In general, if you want to catch every (scripted and user-initiated) URL change, including but not limited to:

    • history.pushState / history.replaceState
    • location.hash = '...';
    • User goes back / forward (and changes hash / history state)

    ... then you need to use the chrome.webNavigation API in the background/event page, in particular the onHistoryStateUpdated and/or onReferenceFragmentUpdated events. In response to these events, you'll either send a message or execute a content script.

    If you only expect rewrites of the reference fragment (aka location hash), then there's no need for the webNavigation API. The implementation will be simplier, as you only need to listen to the global hashchange event in the content script.