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:operauser.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..)

26 thoughts on “Opera 8 beta 3 introduces User JavaScript

  1. 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!

  2. 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:

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

  4. 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?

  5. 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…

  6. 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.

  7. 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?

  8. 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.

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

  10. 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?

  11. 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!

  12. 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.

  13. 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…

  14. 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…

  15. 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.

  16. 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.

Leave a reply to quiris Cancel reply