1

Though I've had my fair share of experience with JS, I'm just wanting to make a quick Chrome Extension for personal use. Essentially, all I'm looking for is pulling all urls that fit a certain pattern - for example, test.example.com/abcdefg and change them to test.newexample.com/abcdefg. That way, when the page is loaded, I can click the URLs and be sent to the new page without any redirects. The catch is, however, that some page content is loaded dynamically, meaning you can load more entries of said URL without actually reloading the page and you run into issues with being able to convert those too.

Since I've never done this before, I'm not much further than my manifest.json:

{
  "name": "Test",
  "version": "1.0",
  "description": "Test",
}

I also wrote up some basic code that I've used in the past for a firefox plugin, but the problem is actually implementing it into my chrome plugin and executing it.

self.port.on("getElements", function(tag) {
  var links = document.getElementsByTagName(tag);
  for (var i = 0; i < links.length; i++) {
    if (links[i].href.indexOf("currentpage.com") == -1) {
        links[i].href = links[i].href.replace("example.com","brandnewexample.com");
    }
  }
});

So, I guess my question is how I can tie the above code or something similar into the plugin in order to actually get my code to execute? My roadblock right now is getting as far as being able to test and utilize it - after that, troubleshooting and adjusting shouldn't be too big of a problem.

Jtaylorapps
  • 5,680
  • 8
  • 40
  • 56

1 Answers1

1

Okay this is quite simple you just need a content script and if you include jquery in your project. Something like this would do it.

you will need to create a folder structure like this:

------------------
-- + - Extension
   |----- manifest.json
   |----- jquery.js (optional as per the solution)
   |----- contentScript.js (important)

Get into developer mode of chrome (google that) and load extension as unpacked.

the manifest.json would look something like:

{
        "name"                  : "",
        "version"               : "",
        "manifest_version"      : 2,
        "description"           : "",
        "content_scripts"       :
                [{
                        "matches"       : 
                        [
                                "*://*"
                        ],
                        "js"            :
                        [
                                "jquery.js",
                                "contentScript.js"
                        ],
                        "all_frames"    : true
                }],
        "permissions"           :
                [
                        "*://*"
                ]
}

the contentScript.js would look something like this

$(document).ready(function(){
  $('a').each(function(){
    if($(this).attr('href').indexOf("example.com") != -1){
      $(this).attr('href') = $(this).attr('href').replace("example.com","brandnewexample.com");
    }
  });
});

Or you can also use this, in case the links are not fully qualified domain (read more).

$(document).ready(function(){
  $('a').each(function(){
    if(this.href.indexOf("example.com") != -1){
      this.href = this.href.replace("example.com","brandnewexample.com");
    }
  });
});

Theoretically you could avoid jquery entirely and use your old code. I am not sure if this works but you can try. You can remove jquery from your manifest.json and replace the contentScript with:

document.onreadystatechange = function() {
  if (document.readyState === 'complete') {
    // DOM should be ready!
    var links = document.getElementsByTagName(tag);
    for (var i = 0; i < links.length; i++) {
      if (links[i].href.indexOf("example.com") != -1) {
          links[i].href = links[i].href.replace("example.com","brandnewexample.com");
      }
    }
  }
};

In case you need to fire this function every time content is added to page you could simply do this in contentScript.js (read more):

$(document).bind('DOMSubtreeModified', processLinks);
$(document).ready(processLinks);
function processLinks(){
  $('a').each(function(){
    if(this.href.indexOf("example.com") != -1){
      this.href = this.href.replace("example.com","brandnewexample.com");
    }
  });
});

Look for added permission incase you need to display fancy stuff like icons or something. but basically any JS in contentScript.js will get executed as if it were a part of the page when served.

Community
  • 1
  • 1
whizzzkid
  • 1,174
  • 12
  • 30
  • Giving it a try... manifest is giving me some packing errors. I'll try and figure it out – Jtaylorapps Oct 09 '13 at 18:55
  • @JTApps did you fill in all the empty fields?... save http://code.jquery.com/jquery-1.10.2.min.js as jquery.js in root folder of the plugin... Also why would you get the packing error?... you just need to load an unpacked extension for testing... – whizzzkid Oct 09 '13 at 18:58
  • @JTApps updated the answer to make use of your code directly. not tested but you can give it a try. – whizzzkid Oct 09 '13 at 19:07
  • Okay, I fixed the errors, but my code doesn't appear to be working. I'm working on figuring out the troubleshooting, but essentially the URLs on the page are the same as before the extension was there. – Jtaylorapps Oct 09 '13 at 19:37
  • @JTApps did you create the contentScript.js file in the right place?... I updated the answer to give you an idea of the file placement and the you can load the complete extension folder as unpacked extension. – whizzzkid Oct 09 '13 at 19:45
  • @JTApps I just copied your logic and if it was working in ff then so would here. you sure about the logic indexof(...) == -1?... that actually compares that the value does not exist. can you give me an example of the page and urls you are wanting to change. – whizzzkid Oct 09 '13 at 19:48
  • Okay, I managed to figure a couple things out. I yanked that conditional out of there and fixed some things in the manifest and it is working now. However, there's still something a bit weird in its behavior and I get a feeling it's my fault. Though, my problem should be solved. I'll mark you as the answer once I finalize it. Thanks! – Jtaylorapps Oct 09 '13 at 19:51
  • Thanks!... i would love to see the changes. So we can edit the answer so it helps the people looking for it. – whizzzkid Oct 09 '13 at 19:57
  • In total, I used your second example of contentScript. I dropped the conditional you asked about, and there's a couple misspelling errors in there, no problem. In the manifest, I just filled in all of the fields. The reason I had issues compiling was because I didn't fill in the url wildcards for the site as well. I do have ONE problem, and it's that, when I load more pages (kind of like facebook), a whole bunch more links in need of conversion show up and, since I'm not reloading the page, they don't get changed. Any thoughts on that? – Jtaylorapps Oct 09 '13 at 20:00
  • @JTApps check out the new example I added in the end. Also the condition statement I added would work. – whizzzkid Oct 09 '13 at 20:10
  • Hey, worked like a charm! Thanks so much man. It's been a huge help in getting started with chrome extensions, and I think I'll be good to tackle some of it on my own now. Thanks! – Jtaylorapps Oct 09 '13 at 20:17
  • @JTApps you're welcome!... chrome extensions are just so much fun to work with... :) – whizzzkid Oct 09 '13 at 20:20
  • Hey, I had a quick question for you. I've noticed that there's quite a performance hit with this plugin active.. it's probably changing 35 links per load or so. I wonder... is it possible to make the selector more... selective? For example, something like `$('a.title, a.madeVisible, .md [href*="linktoconvert.com"]')` for a performance boost? – Jtaylorapps Oct 10 '13 at 18:32
  • @JTApps it actually might help, read this http://stackoverflow.com/a/17566290/1114922 – whizzzkid Oct 11 '13 at 14:05