1

tl;dr

Don't use exotic dynamic injection of external libraries in Userscript. @require them instead.


Original Question

I am trying to modify this page with the following script:

console.log("run"); !function(){var e=document.createElement("SCRIPT") e.src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js",e.type="text/javascript",document.getElementsByTagName("head")[0].appendChild(e) var t=function(e){window.jQuery?e(jQuery):window.setTimeout(function(){t(e)},100)} t(function(e){e(".title").children().each(function(){this.href="/"+this.href.split("'")[1]})})}() 

The script works fine from the console (try it), transforming window-open links to URL hrefs. However, the same script in Tampermonkey does not work (and the debug line shows in the console, indicating that the script is indeed running):

screenshot

These are the settings for the particular script:

screenshot

What am I doing wrong? How can I make the script work from Tampermonkey?


After checking syntax (see comments):

syntax


Changing some commas to semicolons --- this is a mess.

bad parser

8
  • Have you clicked the check for syntax errors buttons? It's directly to the left of "update url". Commented May 29, 2014 at 0:43
  • @Vedaad, yes, it does say syntax errors (see edit), but the code "works". It's legal JavaScript --- it works form the console. Commented May 29, 2014 at 0:46
  • Why not simply replace those commas with semi-colons? At least then you can rule that out as a cause Commented May 29, 2014 at 0:52
  • @Phil I tried, rechecking syntax every time. Apparently the syntax parser is buggy. Halfway through I just gave up. See edit. Commented May 29, 2014 at 0:58
  • @Phil Can you try the code yourself, at least in the console? Commented May 29, 2014 at 0:59

1 Answer 1

2

That script relies on a very short timer for jQuery to load. That is very bad form; it sets up a race condition which might be okay in one circumstance but fail in others.

It might (usually) work from the console because most of the code operates synchronously and it's all in the same scope.

But that code from a Tampermonkey script switches scopes and injects some but not all of the needed code.

Don't use jQuery from a userscript that way! Keep the script sandboxed and use @require for better performance.

In this case, your entire script would become:

// ==UserScript== // @name OpenHymnal fix // @match http://openhymnal.org/genindex.html // @require http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js // @grant GM_addStyle // ==/UserScript== /*- The @grant directive is needed to work around a design change introduced in GM 1.0. It restores the sandbox. */ console.log ("run"); $(".title").children ().each (function () { this.href = "/" + this.href.split("'")[1] } ); 
Sign up to request clarification or add additional context in comments.

3 Comments

What's GM? Can you explain @grant?
Probably Grease Monkey
GM is Greasemonkey -- the Firefox add-on that Tampermonkey tries very hard to recreate. In this case @grant forces the sandbox back on and only allows the specified GM_ function(s). The @grant minimizes conflicts in both GM and TM, and that script works the same in both.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.