User JavaScripts collection

for Opera 8

Intro

Opera 8 beta 3 introduced support for User JavaScript. On this page I'll link to compatible scripts that can be pasted in my example framework file user.js. Paste the new function at the end of the framework file, and call the function from one of the three handlers in the top of the file. I've also provided Greasemonkey installable versions (using anonymous functions) where possible for those who want to try them in that other browser. These scripts have all been tested at least a little bit.

See also the links to standalone User JavaScripts for Opera below, some interesting scripts I saw in the Forums or newsgroups or elsewhere.

A big and nicely organized collection of User JavaScripts is building up at UserJs.org. I'll move some of my scripts to that repository (some of these scripts or the ideas for them have already ended up there), and only keep some examples here and links to interesting scripts on other sites.

JavaScript functions for framework

autocompleteOff (GM)

//Remember password
// Makes the browser ignore web site requests to not remember passwords.

/*
Script source:
  Jesse's Bookmarklets collection
  http://www.squarefree.com/bookmarklets/forms.html#remember_password

Changes:
  Made the alert conditional, only shows when there is something to report,
  and when variable 'showalert' is 1.
  Removed the 'onsubmit' removal.
  Simplified alert message.
  This adaption made by Rijk van Geijtenbeek, 2005-03-25.
*/

function autocompleteOff() {
  var showalert=1;
  var ca,cea,cs,df,dfe,i,j,x,y;
  function n(i,what){return i+" "+what+((i==1)?"":"s")}
  ca=cea=cs=0;
  df=document.forms;
  for(i=0;i<df.length;++i){
    x=df[i];
    dfe=x.elements;
//    if(x.onsubmit){
//      x.onsubmit="";
//      ++cs;
//    }
    if(x.attributes["autocomplete"]){
      x.attributes["autocomplete"].value="on";
      ++ca;
    }
    for(j=0;j<dfe.length;++j){
      y=dfe[j];
      if(y.attributes["autocomplete"]){
        y.attributes["autocomplete"].value="on";
        ++cea;
      }
    }
  }

  if (showalert=1){
    if (ca!=0||cea!=0||cs!=0){
//      alert("Removed autocomplete=off from "+n(ca,"form")+" and from "+n(cea,"form element")+", and removed onsubmit from "+n(cs,"form")+". After you type your password and submit the form, the browser will offer to remember your password.")
      alert("Greasemonkey removed autocomplete=off from "+n(ca,"form")+" and from "+n(cea,"form element")+".")
    }
  }
}

bodyIDforAll (GM)

// Body ID for all
// Adds an ID attribute to body elements

/*
  ID value is build from the server name:
   - www is dropped
   - dots are replaced with dashes
   - numbers are prepended with an underscore

  Rewritten by liorean, 2005-03-20. Repackaged by Rijk.
*/

function bodyIDforAll() {
    if(document.body){
        var
            b=document.body;
        if(!b.hasAttribute('id'))
            b.setAttribute('id',location.host
                .replace(/^www\./,'')
                .replace(/^\d/,'_$&')
                .replace(/\./g,'-'));
    // debug: uncomment the next line to see the body-IDs (this gets old really fast)
    //  alert(document.body.id);
    }
}

addCitationLinks (GM)

// Add links to citation source (cite attribute) to blockquote elements

/*
Script source:
  Dunstan Orchard http://www.1976design.com/blog/
  http://dealmeida.net/js/46_blockquotes.js
  Altered from original idea by Simon Willison at:
  http://simon.incutio.com/archive/2002/12/20/blockquoteCitations


Changes:
  Made the alert conditional, only shows when there is something to report,
  and when variable 'showalert' is 1.
  Removed the 'onsubmit' removal.
  Simplified alert message.
  This adaption made by liorean, 2005-03-20. Repackaged by Rijk.
*/

function addCitationLinks(){
//    if(confirm('Cancel addCitationLinks?'))
//        return;
    var
        i=0,
        elm,
        cite,
        coll=document.getElementsByTagName('blockquote'),
        oP=document.createElement('p');
    oP.className='source';
//    alert(coll.length);
    while(elm=coll.item(i++))
        if(cite=elm.getAttribute('cite')){
//            alert(cite);
            if(/http:\/\/|ftp:\/\//i.test(cite))
                appendCite(
                    cite.replace(/^(?:http|ftp):\/\/(.{32}).+/,'$1\u2026'),
                    cite,
                    'Go to '+cite);
            else if(/urn:quote:/i.test(cite))
                appendCite(
                    (cite=cite.replace(/urn:quote:/g,'').replace(/\s/g,'_')),
                    'http://www.quotationspage.com/quotes/'+cite);
            else if(/urn:author:/i.test(cite))
                appendCite(
                    cite.replace(/%20/g,' ').replace(/urn:author:/g,''));
            else
                appendCite(
                    cite.replace(/%20/g,' '));
        }
    function appendCite(text,href,title){ // Doesn't that sound nasty?
        var
            p=oP.cloneNode(false);
        p.appendChild(document.createTextNode('\u2014'+(href!=undefined?'':text)));
        if(href!=undefined){
            (tmp=document.createElement('a'))
                .setAttribute('href',href);
            tmp.appendChild(document.createTextNode(text));
            if(title!=undefined)
                tmp.setAttribute('title',title);
            p.appendChild(tmp);
        }
        elm.appendChild(p);
    }
} 

FlashUnhide (GM)

// Flash Unhide
// Click on a hidden Flash to make it fullsize
// To be used together with a user stylesheet that hides Flash embeds

/*
Script source:
  Fabian Valkenburg

Changes:
  This adaption made by Rijk van Geijtenbeek, 2005-03-25.
*/

function FlashUnhide() {
    window.onclick=function(){
        var
            srcElem=window.event.srcElement;
// For now, this needs to be limited to EMBED elements
//        if(/embed|object/i.test(srcElem.tagName))
        if(/embed/i.test(srcElem.tagName))
            srcElem.className='zichtbaar';
    };
}

/* Note: Flash Unhider is only useful together with FlashHider user.css below: */
/*
embed[type="application/x-shockwave-flash"] {content:"Flash"; outline: 1px dotted gray; color: gray; background: black}
embed[type="application/x-shockwave-flash"].zichtbaar {content: normal; outline: none}
*/}

redirectGmail (GM)

// Gmail Redirection
// Intended to trigger redirecting to the fancy interface *after* logging in

/*
Script inspiration:
  Robert Blaut
  http://my.opera.com/quiris/journal/56
  Jor
  http://my.opera.com/jor/journal/39

Changes:
  This adaption made by Rijk van Geijtenbeek, 2005-03-25.
*/

function redirectGmail() {
    if(document.getElementById('bm'))
        window.location='http://gmail.google.com/gmail/?nocheckbrowser';
}

hideAdsense (GM)

// Hide Google adsense
// Deprive interesting sites of potential income

/*
Script source:
  (c) Carlo Zottmann, carlo@g-blog.net
  http://G-Spotting.net/
  Original script from http://docs.g-blog.net/code/greasemonkey/hide_google_adsense.user.js
  Copy, use, modify, spread as you see fit.

Changes:
  Rewritten completely by liorean, 2005-03-20. Repackaged by Rijk.
*/

function hideAdSense() {
    var
        b=false,
        i=0,
        elm,
        aElms=document.getElementsByTagName('iframe');
    while(elm=aElms.item(i++))
        if(/google_ads_frame/i.test(elm.name)){
            injectCSS('iframe[name="google_ads_frame"]{display:none;}');
            break;
        }
}

function injectCSS(sCSS){
    var
        elm=document.createElement('style');
    elm.setAttribute('type','text/css')
    elm.appendChild(document.createTextNode(sCSS));
    document.getElementsByTagName('head').item(0).appendChild(elm);
}

killBlank (GM)

// killblank
// Replaces target=_blank attributes with target=_self

/*
Script source:
  'Destroy Target' Greasemonkey script
  http://meddle.dzygn.com/eng/weblog/destroy.target/


Changes:
  Rewritten by liorean, 2005-03-20. Repackaged by Rijk.
*/

function killBlank() {
    var
        elm,
        i=0,
        external=document.links;
    while(elm=external.item(i++))
        if(elm.href&&(/_blank|_userwww/.test(elm.target)))
            elm.target='_self';
}

noFollowStriken (GM)

// Nofollow striken
// Styles nofollow links with a strike through

/*
Script source:
  
  http://speed.insane.com/files/nofollow.user.js

Changes:
  Rewritten completely by liorean, 2005-03-20. Repackaged by Rijk.
*/

function noFollowStriken() {
  var
        re=/nofollow/i,
        i=0
        candidates=document.getElementsByTagName('a'),
        cand,
        theStyle;
  while(cand=candidates.item(i++))
        if(re.test(cand.getAttribute('rel')))
            cand.style.textDecoration='line-through;';
}

trouwnlFixer01 (GM)

// Trouw.nl fixer 01
// Avoiding browser sniffer on Trouw.nl

/*
Script source:
  Scipio
  http://my.opera.com/scipio/journal/4

  This adaption made by Rijk van Geijtenbeek, 2005-03-25.
*/

function trouwnlFixer01(){
  var str=document.body.getAttribute('onload');
  if(str.indexOf('ververs')>=0) {
    str=str.replace("ververs('","").replace("')","");
    location.replace(str);
  }
}

w3c-spec-linker (GM)

// Accessible Specs
// Make the anchors in the headers on W3C specpages clickable

/*
Script source:
  Mark Schenk
  http://www.markschenk.com/webdesign/userjs/accessiblespecs.js
  On W3C specpages, such as the CSS2.1, this script makes the anchors in
  the headers clickable. So if you click on a header, the browser will
  jump to that fragment identifier and you can copy-paste the URL from the
  addressfield.

  This adaption made by Rijk van Geijtenbeek, 2005-03-25.
*/

function accessibleSpecs() {
  var elements = document.body.childNodes;
  var headers = new Array();
  for (var i=0;i<elements.length;i++) {
    if (elements[i].nodeName.indexOf('H') != -1)
      headers.push(elements[i])
  }
  for(var j=0;j<headers.length; j++) {
    var tmp = headers[j].getElementsByTagName('A')[0];
    if (tmp && tmp.getAttribute('name')) {
      naam = tmp.getAttribute('name');
      tmp.setAttribute('href','#' + naam)
    }
  }
}

wwsrbp (GM)

// WeightWatchers SiteRequirements Bypass
// 2005-03-03: www.weightwatchers.* are "optimized" for IE and Netscape 4 etc. Using Firefox, you end up on a page telling you that, and you're stuck. This script is redirecting you to their frontpage.

/*
Script source:
  (c) Carlo Zottmann, carlo@g-blog.net
  http://G-Spotting.net/
  Original script from http://docs.g-blog.net/code/greasemonkey
  Copy, use, modify, spread as you see fit.

Changes:
  Rewritten by liorean, 2005-03-20. Repackaged by Rijk.
*/

function WWSRBypass() {
    var
        currentURL=location.href;
    if(/siteRequirements/i.test(currentURL))
    location.href=currentURL.match(/^(https?:\/\/[^\/]+)\//i)[1]+'/index.aspx';
}

Standalone Opera User JavaScripts

Arve's proof of concept Plainscript, the world's most primitive, and probably also most useless “scripting language”: plainscript.js (hosted externally)

Via Peter, Google Suggest everywhere googlesuggest.user.js (hosted externally)

Scipio's bba-fixer also depends on Opera-specific userscript functionality:

// Fix browserdetection BBA.nl

/*
Script source:
  Scipio
  http://my.opera.com/forums/showthread.php?s=&threadid=85468#post874994

Changes:
  Packaged by Rijk van Geijtenbeek, 2005-03-28.
*/

if(window.location.href.indexOf('www.bba.nl')>-1){
  window.opera.addEventListener('BeforeScript',function(ev){ev.element.text=ev.element.text.replace("window.location.href ='/browser.aspx?ex=brand';","{};");},false);
}

Found in the Forums, Ukrainian Opera user vvsite offers two scripts to enhance Opera's functionality: a Flash Panel for Opera 8 and an autoFormFiller, both hosted externally, zipped. These scripts add little in-page toolbars to pages containing Flash or forms respectively, to quickly disable Flash but also to open Flash movies separately for easy download, or to save and automatically reuse form values on return visits to a page.