Skip navigation.

miscoded

the web is a hack

Opera 8 beta 3 introduces User JavaScript

What is it?

User JavaScript is a new feature that lets the user configure Opera to include a specific JavaScript library on all pages. Users who know JavaScript can write their own scripts and share them with others.

What's the point?

This can be used for instance to


  • Fix broken pages

  • Enhance Opera with your own toolbars / buttons in the page

  • Control exactly what the scripts on a page are allowed to do

  • Customize and change the page any way you like

  • Simplify bookmarklets by adding functions they depend on to the User scripts


Security

Before we go into more details, a few words about User JavaScript and security: A user JavaScript file can in no way harm your computer or stored data but badly written files can slow down Opera and malicious files can spy on your browsing. Never install and use a script library from someone you don't know and trust - if in doubt post in the Opera forums, newsgroups or mailing lists and ask if the script you would like to use is well written and exploit-free.

Enabling User JavaScript

This entry in your Opera6.ini file will enable User JavaScript:


[User Prefs]
User JavaScript=1
User JavaScript File=c:\opera\user.js


Adapt the last line to point to the file you want to use.
Opera's "Help / About" screen will tell you what Opera6.ini file is being used, and the address of any active User JavaScript file.


Example

The following user script will enhance mail listings in Hotmail and Yahoo Mail with "QuickSearch" fields similar to those used in Opera's mail client. When you type a word into one of these fields, any mail that does not contain that word in its subject will disappear.

if(window.location.href.indexOf('mail.yahoo.')>-1){
document.addEventListener('load', function(ev){
if(self.name=='ymailmain'){
var inp = document.createElement('input');
inp.addEventListener('keyup', function(){try{
_OUSerJS_to = setTimeout("_Opera_User_JavaScript_quickSearch(document.getElementById('datatable').getElementsByTagName('tr'), '"+this.value+"')", 200);
}catch(e){}
}, false);
var elm = document.getElementById('movetop');
elm.parentNode.appendChild(document.createTextNode('QuickSearch: '));
elm.parentNode.appendChild(inp);
}
}, false);
}

if(window.location.href.indexOf('hotmail.msn')>-1){
document.addEventListener('load', function(ev){
if(document.getElementsByName('hotmail') && self==top){
var inp = document.createElement('input');
inp.addEventListener('keyup', function(){
try{
_OUSerJS_to = setTimeout("_Opera_User_JavaScript_quickSearch(document.getElementsByName('hotmail')[0].getElementsByTagName('tr'), '"+this.value+"' )", 200);
}catch(e){}
}, false);
var elm = document.getElementsByName('hotmail')[0];
elm.insertBefore(inp, elm.firstChild);
elm.insertBefore(document.createTextNode('QuickSearch: '), elm.firstChild);
}
}, false);
}

function _Opera_User_JavaScript_quickSearch(nodeList, text){
for(i = 0; i < nodeList.length; i++){
if (nodeList.innerText.indexOf(text) == -1 ){
nodeList.style.display = 'none';
}else {
nodeList.style.display = '';
}
}
}


(You may have to fix some linewrapping in the last example. Also note that it may fail if Hotmail or Yahoo one day update their code..)

document.all offers another IE quirkif today isn't yesterday, reload now!

Comments

Moose 16. March 2005, 16:33

This will put an end to torturing CSS with Javascript, as practised by some.

Thank you!!!!!!!!

M.

non-troppo 16. March 2005, 16:33

Hallvors, this is really great news. By looking at the ini syntax, it looks like we may at somepoint get a user JS switcher (User JavaScript=1) - is there anyway to do that at the moment? Is there an internal menu or command to show this list yet?

Obviously, this also would hopefully dovetail nicely into ua.ini — allowing trasparent updating of javascript workarounds for specific domains.

Excellent stuff indeed!

quiris 16. March 2005, 16:33

This will put an end to torturing CSS with Javascript, as practised by some.

I don't know what are you talking about ;):p

On the subject: it is another great news today :hat: :cheers:

Junyor 16. March 2005, 16:33

I think that's more of a binary setting. ;)

non-troppo 16. March 2005, 16:33

Oh, and what exactly is Junyor[1] going on about:

"Various prototype objects are now available to scripts. I really don't know what this means, but some of our testers were pretty excited about it."

[1] http://my.opera.com/Junyor/journal/47/

non-troppo 16. March 2005, 16:33

:)

scipio 16. March 2005, 16:33

I guess there'll be threads in the forums about this soon with some more information. But... when/how are the scripts executed?

hermen2048 16. March 2005, 16:33

This would be great to add Google keyword highlighting to every Google-referred page! :D

quiris 16. March 2005, 16:33

if(!document.body.hasAttribute('id')) {
document.body.setAttribute('id',document.location.host.replace(/^www./,'').replace(/^([0-9])/, '_$1').replace(/\./g, '-'));
}


I have got toObject conversion error :-/
What's wrong?

hallvors 16. March 2005, 16:33

Re: prototype objects - refers to stuff like HTMLElement . If i wasnt posting from a mobile i would link to the spec.

Timing: user js is run as the very first script in the page. This probably explains the to object conversion errors: you probably use document.body before the body tag has been parsed. Add an load event listener.

Keyword highlight: great idea, and easy...

virtuelvis 16. March 2005, 16:33

Hallvord gave you one reply, and I'll add: You also need to make sure that the document you're loading actually has a body element. Typically, text files and Javascripts don't.

quiris 16. March 2005, 16:33

Yes. I know. But onload event isn't good becuase the page is flickering during applying custom stylsheet. I wonder if is it possible to load script after loading document tree, but before displaying it by Opera?

Luchio 16. March 2005, 16:33

This is great feature, it will be of great help. But as you wrote in your text, this has ENORMOUS potential for hacking.

An malicious script could be used to generate popups or track user navigation habits. Since the uses of Javascript you suggested seems to be site-specific, why not put the Javascripts in the bookmark properties instead?

This would prevent malicious scripts to be permanently active in all webpages, and would limit this powerful feature to bookmarked pages only.

Luchio 16. March 2005, 16:33

You could always use my Ultimate Highlight Bookmarklet, available here: http://www.nontroppo.org/wiki/UHB

virtuelvis 16. March 2005, 16:33

AFAIK: No, the fundamental thing here is that the document doesn't actually exist in the DOM until it has finished loading.

hermen2048 16. March 2005, 16:33

http://wwwhome.cs.utwente.nl/~toerscheha/webjunk/user.js

This User.js will enable Google Highlighting, powered by the borked (popup-stripped, very annoying when shown on every page! :p ) Ultimate Highlight Bookmarklet.

It does not work:

* On framed pages
* On pages opened in a new tab

Outside of that, it works quite fine :)

hermen2048 16. March 2005, 16:33

By the way,

http://www.google.com/search?hl=en&lr=&q=10+teaspoons+in+litres&btnG=Search

screws up quite funnily in conjunction with the latter user.js :D (look at the left Search text field :p )

hallvors 16. March 2005, 16:33

Interesting idea - but it would obviously limit the usefulness of the whole feature, for instance the Google referrer keyword highlighting script would not be possible with a bookmark-based model.

The great question is: to what extent can we rely on user education with such a feature? It is a marvellous power feature in the hands of power users. Everyone else needs information about the dangers of using untrusted files. Will that information reach and protect the users who would know enough to enable the feature but not enough to understand the implications?

Rijk 16. March 2005, 16:33

I've linked an example user.js from my Journal, designed to make it easy to add (and hide) functions for several sites.

Journal post:
http://my.opera.com/Rijk/journal/54

Example user.js:
http://people.opera.com/rijk/opera/scripts/user.js

jdunck 16. March 2005, 16:33

Was this inspired by Greasemonkey (http://greasemonkey.mozdev.org ) or was it done without knowledge of that extension?

Is there any interest in keeping roughly similar features / coding styles?

I'm involved with Greasemonkey, and am excited to see Opera offering a similar feature!

jdunck 16. March 2005, 16:33

Sorry, I should mention, I just last night registered userscript.org with the intention of providing a Greasemonkey user script directory. I picked "userscript" instead of something greasemonkey specific because I was hoping other browsers might offer the same feature.

I had no idea that day might be today.

hallvors 16. March 2005, 16:33

Of course we're aware of Greasemonkey! However, I don't know enough about the features and coding styles to comment on whether we are interested in matching it, I think it would be difficult.

Actually, the User JavaScript idea predates Greasemonkey - it was more based on the way CSS works and the way you can make Opera apply your own user style sheets to all pages. The feature has been planned for years - the first implementation that actually went public was the famous Opera Bork edition that loaded a given external JS file into all MSN pages to mangle their language :) . Google for Opera Bork if you don't know that story...

Luchio 16. March 2005, 16:33

Nice mod, I will add this user.js on the UHB page.

porneL 16. March 2005, 16:33

Isn't it ideal helper for spyware?

Malicious software could modify opera ini and hook it's spying script.

With support for XMLHTTPRequest (without progressbar!) it might be soo easy to steal data from all forms...

hallvors 16. March 2005, 16:33

XMLHttpRequest can not be used to send data to other domains. However, it is a valid concern and we are discussing ways to make the implementation safer. I hope malware authors won't bother exploiting this because Opera is such a minority browser but we can't become complacent.

porneL 16. March 2005, 16:33

Security by obscurity is not wise.

Malware must not be able to find user js file or set its own. I suggest that Opera keeps path to user js file in an encrypted file (like wand data?). Path could be changed only from GUI.

This actually could be extended to something useful - code snippets manager. User could add/remove (named?) code snippets and maybe even enable them for certain domains only. That would require Opera to provide (secure!) storage for code.

How to use Quote function:

  1. Select some text
  2. Click on the Quote link

Write a comment

Comment
(BBcode and HTML is turned off for anonymous user comments.)

Type the two words displayed in the image below:


Smilies