Skip navigation.

exploreopera

| Help

Sign up | Help

About user scripts in beta 3

, , , ,

NOTE: I've made a webpage now to present the user.js framework script. See <http://people.opera.com/rijk/opera/userjs.html>

Hallvord introduced Opera's latest surprise for tweakers in his Journal.

What is a user script

Basically it is a script from a local file that gets executed before any other scripts (or event handlers) on the page, once in every document.

I've collected some more or less interesting scripts that I'd like to run on all pages, and on specific sites, in this user script: <http://people.opera.com/rijk/opera/scripts/user.js>. I'm not yet using any versioning there BTW, it can be a different script tomorrow, or in an hour. The script is set up to easily add extra functions, and enable/disable them for all or for specific sites when you want. Don't expect me to explain specific functions, because I'm not a proficient JavaScripter myself. I'd say: experiment, share, and file bug reports if necessary.

Enabling user script in Opera 8 beta 3

[User Prefs]
User Javascript=1
User Javascript File=C:Program FilesOperauserjs.js

Security

The script has exactly the same restrictions as a script on the page, except that it can access some User JS specific functionality (we'll get back to you on that) and that it can read the text property on any script element (normal scripts can't read the text property of external scripts loaded from other servers than the document.)

The additional privileges are available when the User JS file is initially executed and when a User JS event is being handled. Global functions defined by User JS but called from a script in the page have no special privileges.

Add a 'BlogThis!' button to OperaHallvord unveils Opera's special User JavaScript events

Comments

avatar
Rijk, thanks for the slow trickle of info coming through! A really nice surprise you all landed on us.

You have an error in your example path: User Javascript File=Crogram FilesOperauserjs.js

/me goes off to read through your user.js

By non-troppo, # 16. March 2005, 21:22:11

avatar
That bug in the path is caused by the journal code.

By jor, # 16. March 2005, 21:22:11

avatar
Fixed that by escaping the slash with a slash (reload if necessary to see the fix).

By Rijk, # 16. March 2005, 21:22:11

avatar
I have the following function to clean all the (news - web sites) links out of Yahoo! News. The commented-out line should work but doesn't.
function yahooNewsCleanser(){
//document.body.innerHTML=document.body.innerHTML.replace(/ (<a(.*)a>)/g,'');
document.body.innerHTML=document.body.innerHTML.replace(/ ((.*)news(.*) - (.*)web sites(.*))/g,'');
}

By izzyo, # 16. March 2005, 21:22:11

avatar
domainHandler['news.yahoo.com'] = yahooNewsCleanser;
and try it here, for instance: http://story.news.yahoo.com/news?tmpl=story&cid=519&ncid=716&e=4&u=/ap/20050317/ap_on_re_us/laci_peterson

By izzyo, # 16. March 2005, 21:22:11

avatar
The journal code stripped out some of my slashes; the parentheses that I'm searching for are properly escaped with backslashes in my actual code.

By izzyo, # 16. March 2005, 21:22:11

avatar
But I'm not even sure what you are trying to achieve. And as I said, I'm no JavaScript expert.

By Rijk, # 16. March 2005, 21:22:11

avatar
Something tells me this could be used to kill target="_blank"s... :sherlock:

By scipio, # 16. March 2005, 21:22:11

avatar
"/me goes off to read through your user.js"

I've found the useful function called bodyIDforAll() in your user.js. Can you perhaps explain what the following piece of code is supposed to do?

--code--
.replace(/^d/,'_$&')
--------

By scipio, # 16. March 2005, 21:22:11

avatar
Heh... somebody thought of that already. It's in Rijk's example.

By scipio, # 16. March 2005, 21:22:11

avatar
Let's see if i can find that back, I got it via Robert B's Journal...

Here it is:
http://my.opera.com/quiris/journal/54 points to http://my.opera.com/forums/showthread.php?s=&postid=842398#post842333

"Above code generates CSS signuture for every entire site which lack such ID.
Rules:
- every dot in domain name is replaced with hyphen
- domain names started with count at beginning are started with underscore at beginning of css signature
- www. is cut off"

The part you asked about is the regular expression to replace a number with a underscore+number, because ID values are bot allowed to start with a number.

By Rijk, # 16. March 2005, 21:22:11

avatar
Rijk-it's simply a regular expression to replace all the (&lt;a href="blah"&gt;news&lt;/a&gt; - &lt;a href="blah"&gt;web sites&lt;/a&gt;) links that Yahoo!'s content management system peppers its news stories with nothing. I hate the stupid (news - web sites) links :-) The regular expression that doesn't work searches for the string " (<a" followed by any number of any character followed by "/a>)", which should capture all the (news) and (news - web sites) links. but it doesn't actually work, for some reason, so I had to write a more complicated regex that looks for "(" followed by any number of anything followed by "news" followed by any number of anything followed by " - " followed by any number of anything followed by "web sites" followed by any number of anything followed by ")" and replace it with nothing, cleaning up the text. It's fine, but I'm disturbed that I can't refer to tags directly in my valid (I tested it) regular expression. Is it because of the character &lt;? Does that get ignored by the user javascript's regex engine?

By izzyo, # 16. March 2005, 21:22:11

avatar
Oops. I guess I could have simply used < and >, eh?

By izzyo, # 16. March 2005, 21:22:11

avatar
Would it be possible to create a script that kills a tab if it is both empty and doesn't have focus? What I'm trying to get is autoclose of those annoying blank windows when saving files - or is there maybe a more intelligent approach for it?

Friedrich

By Friedrich, # 16. March 2005, 21:22:11

avatar
Can multiple scripts be added? user.js, test.js and etc?

By YtseJam, # 16. March 2005, 21:22:11

avatar
If I a not mistaken it means that if a URL starts with a number (/^d) it is replaced by a '_' followed by the actual number.

By MarkSchenk, # 16. March 2005, 21:22:11

avatar
Using Rijk's user.js as a basis, I have written some scripts of my own. The ones I consider generally useful, I will store here:

http://www.markschenk.com/webdesign/userjs/

Currently there are only two. The first is useful on W3C specs, and will make linking to specific areas in the spec useful. It will add links to the headers, so you just click on the header and the URL can be found in the addressbar.

The other is only useful for Dutch users, because it fixes a rendering error on www.nu.nl

Have fun!

By MarkSchenk, # 16. March 2005, 21:22:11

avatar
Nope. You can change the names on your computer, and then reload the webpage, for easy testing.

By Rijk, # 16. March 2005, 21:22:11

avatar
Friedrich, I don't think that is possible. Such empty pages contain no document at all, so the script has nothing to work on.

The blank-page issue is something that needs to be fixed by the Opera developers. I've been told it is not as easy as it looks, but a fix would be appreciated by users!

By Rijk, # 16. March 2005, 21:22:11

avatar
Hi Rijk,

Did you consider supporting greasemonkey's existing distribution model with the metadata header and installing separate userscripts (http://greasemonkey.mozdev.org/authoring.html)?

It would be really cool if we could share scripts between the two browsers.

-- Aaron Boodman (the greasemonkey guy)

By boogs, # 16. March 2005, 21:22:11

avatar
Hi Boogs,

First of all: I'm not the developer :smile:

Currently Opera doesn't have the capability to store multiple scripts and tie them to specific sites, so interoperability is not yet feasable. That is why I hacked together my user.js framework script. From what I've seen, the Greasemonkey scripts that don't use XPath should be perfectly usable in Opera. Already I've added some of them to my example userscript (with attribution of course).

I'm sure our developers know about Greasemonkey. But I don't know much about our plans for future development in this area, and what little I know is probably NDA'd. But I'll ask the responsible developer about this.

By Rijk, # 16. March 2005, 21:22:11

avatar
I take it you want a subdomain functionality. Fear not I needed it myself and added it quickly:

yahoo.com or news.yahoo.com will now match story.news.yahoo.com


function loadHandler() {

// Here we set a variable that holds the full path:
var
l=window.location,
fullpath=l.hostname+(l.port!=''?':'+l.port:'')+l.pathname;

if(window==window.top){
// Here we check if the current full path has a handler defined,
// and, if that is the case, run that handler function:
if(fullpath in pathHandler)
pathHandler[fullpath]();
// Here we check if the current domain has a handler defined,
// and, if that is the case, run that handler function:
for(dom in domainHandler) {
var pat = new RegExp(dom+"$")
if (pat.test(document.domain)) {
domainHandler[dom]();
}
}
// Here we run the functions for all pages:
while(allHandler.length>0)
allHandler.shift()();
}
}
// End of loadHandler function, all handlers are called.
// Mission accomplished, return to base.

By nicomen, # 16. March 2005, 21:22:11

avatar
Are the new in-line error messages documents, technically? Is it possible to apply user JS to them?

By Friedrich, # 16. March 2005, 21:22:11

avatar
Hello Rijk, I am getting a HTTP 500 error on http://people.opera.com/rijk/opera/scripts/user.js…

Is it still available?

By jor, # 16. March 2005, 21:22:11

avatar
It's back. I was making some changes, and forgot to upload using the right name. The script is smaller now, and selects on domain instead of server (thanks Nicomen). I'll create a bigger demo later.

By Rijk, # 16. March 2005, 21:22:11

avatar
Yes, these are documents. Use of 'View source' reveals they've already been fitted with IDs on the BODY element for easy user styling.

By Rijk, # 16. March 2005, 21:22:11

avatar
GREAT!

So, would the following be possible: As long as the error message is displayed, initiate a reload every ten seconds (essentially a "retry till success" script)?

In any case, this means we can (kinda a hack, but it would work, wouldn't it? I don't really know Javascript.) customize our error messages, can't we?

By Friedrich, # 16. March 2005, 21:22:11

avatar
Yep, should be possible. I'm no Javascript guru either, maybe you can post a message in the Customize Opera forum.

By Rijk, # 16. March 2005, 21:22:11

avatar
The only way Opera can do that at the moment is to wrap user javascript in some kind of API (kind of how Rijk does it now), which could parse your metaadata formating to input into the domain handling routines. As we cannot pull in seperate files, this would either need manual additions OR a web application (we've thought about a combined repository and user js manager) to roll up greasemonkey scripts selected by a user automatically into a single user.js file...

By non-troppo, # 16. March 2005, 21:22:11

avatar
Rijk, It is fairly easy to add a messaging system so you can see which functions trigger on which pages

1. Initialise a variable at the beginning of Rijk's script:

var notify='';

2. Add the following function to the function list:

function ScriptStatus() {
window.defaultStatus=notify;
}

3. Add the function as the last but 1 option on the allHandler list, like:

allHandler=[
bodyIDforAll,
killBlank,
ScriptStatus, //here it is
doNothing];

4. To each function add something like this as the last line

notify += '-Unique name-';

so for e.g.

// 'backgroundToGreen' can be used to test if the user script is working.
function backgroundToGreen(){
document.body.style.background = "green";
notify += '-Green-';
}

This will let you see which functions are activated for the page by providing the info in the status bar. Commenting out the line in allHandler can then turn messaging on/off

By non-troppo, # 16. March 2005, 21:22:11

avatar
"Compensating for Nu.nl stupidity", huh? :smile: I did the same for Trouw.nl: http://my.opera.com/scipio/journal/4

By scipio, # 16. March 2005, 21:22:11

avatar
I've been trying to figure out what the best way is to add the events Hallvord mentioned in his journal (http://my.opera.com/hallvors/journal/45) to the framework provided bij Rijk... Has anyone been thinking about that, too?

By scipio, # 16. March 2005, 21:22:11

avatar
Can't remember the URL, but someone had an idea a while back to give each site a body id tag identifying just that site (eg "www-ilovejackdaniels-com"). That allowed you to create a custom user style sheet just for that site. Very slick.

The problem with that, and the reason not many people caught on to it, was that not many web site developers added the tag to their sites.

This addition to Opera 8 should mean that you can set a script to run when you load a site to automatically give the body tag this ID. Then, it's fairly easy to (if you wanted to) define custom styles to apply to only that site, using the body id tag.

For example, Yahoo's interface is a bit of a mess. The user.js file could add 'id="www-yahoo-com"' to the body tag of all yahoo pages. Then in your user style sheet you could define styles just for yahoo, like so:

#www-yahoo.com * {
font-family: Georgia;
}

By ILoveJD, # 16. March 2005, 21:22:11

Write a comment

You must be logged in to write a comment. if you're not a registered member, please sign up.

May 2008
SMTWTFS
April 2008June 2008
123
45678910
11121314151617
18192021222324
25262728293031