2

I wrote a short content script, which stops a particular site from creating new windows for link clicks.

This is my first Chrome extension, and I've scored this website and the internet for a reason why it won't run, but I can't find any. I'm probably making a fundamental amateur mistake somewhere.

Manifest.json:

{
"manifest_version": 2,

"name": "DHS Links",
"description": "Stops the school's site from constantly opening new windows.",
"version": "1.0",

"browser_action": {
"default_icon": "icon.png"
},

"content_scripts":[
  {
    "matches": ["*://www.darienps.org/dhs/*"],
    "js": ["jquery.js", "makeNormalLinks.js"],
    "run_at": "document_end"

  }
 ]
}

I tested the Javascript file by itself on a local version of the site, so I'm pretty sure it's fine, but just in case:

makeNormalLinks.js:

$(document).ready(function() {
    $("a").each(function(){
        $(this).removeAttr("onclick");
    });
});

A copy of jQuery is in the same directory and doesn't seem to have any issues.

Here's the onclick code for many links on the website:

onclick="window.open(this.href,'targetWindow','toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,')

Thank you for looking this over!


Edit:

I tried two of the injection methods from Rob W's response to another question linked to in the comments by Teepeemm.

Here's the new code for Method 1:

Manifest.json:

{
"manifest_version": 2,

"name": "DHS Links",
"description": "Stops the school's site from constantly opening new windows.",
"version": "1.0",

"browser_action": {
"default_icon": "icon.png"
},

"content_scripts":[
  {
    "matches": ["*://www.darienps.org/dhs/*"],
    "js": ["jquery.js", "scriptLauncher.js"]

  }
 ],
"web_accessible_resources": ["makeNormalLinks.js"]
}

scriptLauncher.js:

var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.extension.getURL('makeNormalLinks.js');
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);

Method 2a:

(Uses old Manifest.js)

makeNormalLinks.js:

var actualCode = ['$(document).ready(function(){',
                  '$("a").each(function(){',
                  '$(this).removeAttr("onclick");',
                  '});',
                  '});'].join('\n');

var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);

Unfortunately, neither method seems to work. I'm extremely grateful to those who commented and think we're getting close to an answer.


Solution:

Manifest.json:

{
"manifest_version": 2,

"name": "DHS Links",
"description": "Stops the school's site from constantly opening new windows.",
"version": "1.0",

"browser_action": {
"default_icon": "icon.png"
},

"content_scripts":[
  {
    "matches": ["*://www.darienps.org/dhs/*"],
    "js": ["makeNormalLinks.js"]

  }
 ]
}

makeNormalLinks.js:

document.addEventListener("click", function(e) {
    e.stopPropagation();
}, true);

Thanks you, Scott and all who commented!

Nick
  • 581
  • 1
  • 7
  • 13
  • `$("document").ready(function(){` should probably be `$(document).ready(function(){`, or just `$(function(){`. – Alexander O'Mara Jul 13 '14 at 00:57
  • I can't believe I made that mistake. Thanks for catching it! Unfortunately, the extension still doesn't seem to work. – Nick Jul 13 '14 at 01:25
  • Unrelated, but you don't need "browser_action" or "permissions" to do this. And "document_end" is the default, and can be omitted. – Teepeemm Jul 13 '14 at 20:51
  • 1
    How are the links created? If `a onclick=`, then I think this would work. But if it's `a href="" target="_blank"` or `$("a")[0].attachEventListener`, then you may need a different approach. – Teepeemm Jul 13 '14 at 20:53
  • Thanks for the tips, Teepee! I left the browser_action in to keep my spiffy logo though. I'll update the main post with a removal of the permissions bit and the onclick code. – Nick Jul 14 '14 at 20:30
  • Could `onclick` counts as the page’s javascript, and not its DOM? If so, you’re getting caught by [isolated worlds](https://developer.chrome.com/extensions/content_scripts#execution-environment). See [this answer](http://stackoverflow.com/a/9517879/2336725) for what to do. Incidentally, welcome to SO. A feature I’ll share is if you type @ before you start typing a username, the server will complete the username for you. This has the advantage of avoiding misspellings (e.g., you left off “mm” ;)) and typing non-ascii characters that some people use. It also notifies the other person: @Nick – Teepeemm Jul 15 '14 at 01:45
  • For example, [this question](http://stackoverflow.com/q/24752464/2336725) just popped up, and has the same symptoms. – Teepeemm Jul 15 '14 at 13:52
  • I tried two of the injection methods and will update the main post with the code. No successes, but I feel like I'm on the right track. @Teepeemm – Nick Jul 15 '14 at 20:36
  • It appears that on their site, `$` is for Mootools, so you would need to change `$` to `jQuery` in your latter attempts. The weird thing is that all three of these do remove the `onclick` attribute, but the windows still open. Go with ScottF's answer. – Teepeemm Jul 17 '14 at 14:30

2 Answers2

1

Using the onclick attribute has many weird side effects. A more up to date approach would be to add a listener to the document that filters unwanted events. Like:

document.addEventListener("click", function(e) {
  e.stopPropagation();
}, true);

The true argument is important (see event capture). This will block all click event listeners from firing, but the default click action will still be triggered.

Scott
  • 604
  • 3
  • 7
  • It worked! The method doesn't even require injecting the script or jQuery. Thank you so much! – Nick Jul 16 '14 at 14:49
0

I was having a similiar issue getting the content script to fire in Google Mail. I stumbled upon a page that recommended using the "hashchange" event.

// Event listener
window.addEventListener("hashchange", function () {
  alert("hashchanged");
}, false);