Wikipedia:User scripts/Guide

This is an old revision of this page, as edited by Davidgothberg (talk | contribs) at 02:34, 20 September 2008 (Some fixing in the lead section. Added link to JavaScript syntax.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

This is a small guide on writing user scripts for Wikimedia sites. Of course, some basic JavaScript knowledge is required. (See also JavaScript syntax.)

Scripts

The following script files are executed for every Wikipedia visitor:

It is recommended that you save the «system» script files locally and view them with your text editor (with syntax highlighting). There are some useful functions there that you can use in your scripts, some of them are mentioned below.


Structure

When your /monobook.js is executed most HTML page elements do not exist yet. So most user scripts look like this:

//Part 1
addOnloadHook( function() {   //Means execute "function()" later.

  //Part 2 — executed when the page has loaded

  //Quite often it simply adds a JavaScript link
  <a onclick="func_action()" href="#">

} );

//And then there is …

//Part 3 — executed when the user clicks on this link
function func_action (){
}

Basic methods

Finding elements

Every HTML element is a node of DOM model which allows scripts to access the element. For example on this page

<form name="frmname" id="frmid">
<textarea name="txtname" id="txtid">
<input id="neighbor">

we can «find» element textarea:

  • using its id: document.getElementById('txtid')
  • in the array of all elements with the same tag: document.getElementsByTagName('textarea')[0]
  • using element next to it: document.getElementById('neighbor').previousSibling
  • as a child of its parent: document.getElementById('frmid').childNodes[0]
  • as a form element, using name: document.frmname.txtname

Also see w3schools or mozilla.org.

Checking the page

Many scripts are supposed to work only on some pages. You can check:

  • page address
if (document.URL.indexOf('action=history') != -1) {
  //continue only on history pages
  • wg variables; many of them have the same meaning as Magic words
if (wgCanonicalNamespace == 'User_talk') {
  //continue only on User_talk pages
  • presense of elements (only in 2nd and 3rd parts of the script)
function func_start () {
   if (!document.editform) return; //no edit form  → exit
    

portlets

Usual places to add your own links — portlet blocks with these id's:

p-logo p-personal name my talk my preferences
p-cactions article discussion edit this page

p-navigation

 Main page …

p-search

 

p-tb
Upload file…


p-lang
(interwikis)

Portlet structure:

<div id="…" class="portlet">
 <h5>Header</h5>
 <div class="pBody">
  <ul>
  <li id="…"> <a >  //links
  <li id="…"> <a >
  … …


There is a special function in wikibits.js that simplifies the process of adding your own links into portlets:
addPortletLink (portlet, href, text, id, tooltip, accesskey, nextnode)

//Example: add the link into «toolbox» portlet
addPortletLink ('p-tb', '/wiki/Special:MyPage/monobook.js', 'My monobook.js');

Last 4 arguments are optional; all arguments are explained in the code.


Adding elements

In all other cases there are two ways to insert new elements:

1) adding them to innerHTML of the parent element

//Example: using innerHTML to create a new portlet
document.getElementById('p-participation').innerHTML +=
 '</div>'+
 '<div id=my class=portlet>'+
   '<h5>mine</h5>'+
   '<div class=pBody><ul>'+
     '<li><a href=\"/wiki/Special:MyPage/monobook.js\">My monobook.js</a>'+
 '</ul></div></div>';


2) using DOM methods: CreateElement, then atach as child using AppendChild or InsertBefore. For examples of usage see the code of addPortletLink()


Removing elements

To move an element simply attach it in another place with AppendChild or InsertBefore.

To hide an element you can set its style.display to none:

//Example: remove copyright warning from edit page
var el = document.getElementById('editpage-copywarn');
if (el) el.style.display = 'none';

This is easier with your monobook.css though: #editpage-copywarn {display:none}


Edit page

Text manipulation

The most important element on the edit page is a <textarea> with the article text inside. You can reference it with
var txt = document.editform.wpTextbox1 // or
var txt = document.getElementById('wpTextbox1')

You can add new text to the beginning: txt += "new phrase" or to the end: txt = "new phrase" + txt

There is a function in wikibits.js that can add text to cursor position:
insertTags (tagOpen, tagClose, sampleText)


Toolbar

Buttons above textarea are located inside <div id='toolbar'>.

Buttons are defined with mwEditButtons[] and mwCustomEditButtons[] arrays. Then the 2nd part of your script is called by addOnloadHook. Only after that the buttons are created by mwSetupToolbar() in wikibits.js.

So the easiest way to modify buttons is to work with these arrays:

//Example: modify signature button.
if (mwEditButtons.length >= 10 && mwEditButtons[9].tagOpen == '--~~~~')
  mwEditButtons[9].tagOpen = ' — ~~~~';

Also see en:User:MarkS/Extra_edit_buttons.


Edittools

There is another edit panel under textarea. It's generated from MediaWiki:Edittools by Extension:CharInsert, it consists of a lot of javascript links to the insertTags().

//Example: adding your own quick insert to Edittools
var specialchars = document.getElementById ('editpage-specialchars');
specialchars.innerHTML +=
"<a onclick=\"insertTags('<div>','</div>','');return false\"
href='#'>&lt;div&gt;</a>";

There is no crucial difference between toolbar and edittools, you can insert your own custom links into both.

Editing and loading the user script

Previewing in /monobook.js

You can edit your script directly on your /monobook.js page, then click [Show preview] and the new code is executed right away on the preview page.

Saving in /monobook.js

If required elements are missing on the preview page (for example, your script does something on history pages), you will have to save the script in order to test it.

However it's not convenient and creates unnecessary load on the WikiMedia servers. (It usually involves waiting for some minute after you saved your /monobook.js, then bypassing your browser cache.)

Load from a localhost web server

The best and most recommended way is to load a JavaScript file from your local web server. (See below for an easy to install web server.) Put this string in your /monobook.js:

importScriptURI( 'http://localhost/wikipediatest.js');

Then run any web server on your computer and create the wikipediatest.js file in the appropriate folder. The code inside this file will be executed as if it was inside your /monobook.js.

You can edit your wikipediatest.js file with any text editor, perhaps with syntax highlighting and other convenient features, then save the file and simply reload any Wikipedia page to see the results. (You don't need to wait, and if your web server is nice or you set it right you don't even need to bypass your browser cache.)

For example you could use TinyWeb which is less than 100kbyte on disk and doesn't require installation. Save and unzip tinyweb.zip for example into c:\Program Files\Tinyweb, then create a shortcut to tiny.exe, in shortcut properties add an argument — path to your folder with wikipediatest.js and any file index.html (required). Start TinyWeb with this shortcut; unload it with Task Manager.

Publishing your user script

Once you have finished the user script code you either need to paste it into your /monobook.js if it is only for personal use. Or if it is for use by others then you should upload it to for instance User:Yourname/yourscript.js. Then other users can import it by putting this line in their /monobook.js.

importScript( 'User:Yourname/yourscript.css' );

CSS files

Some user scripts also use some CSS code, or even are built with CSS only. Then you need to code and test CSS code. That can be done in your /monobook.css, but that is slow and messy.

Instead you can load a CSS file from your local web server. (See previous section for an easy to install web server.) Put this line at the very top of your /monobook.css:

@import "http://localhost/wikipediatest.css";

Note! Such @import statements must come before any other declarations in your /monobook.css. But there can be /* comments */ above them.

An alternative way is to put this line anywhere in your /monobook.js instead:

importStylesheetURI( 'http://localhost/wikipediatest.css' );

Publishing a CSS file

Once you have finished the CSS code you either need to paste it into your /monobook.css if it is only for personal use. Or if it is for use by others then you should upload it to for instance User:Yourname/yourscript.css. Then other users can import it by putting this line in their /monobook.js. Note, that is in their ".js", not their ".css".

importStylesheet( 'User:Yourname/yourscript.css' );

If the CSS should be used together with a user script written in JavaScript then you can make it easy for the users. Simply put the line above in the JavaScript code for your user script, then the users only need to "install" your JavaScript.

For completeness, in case someone wonders. You can import your User:Yourname/yourscript.css from your /monobook.css too, although that takes this rather messy line of code:

@import "/w/index.php?title=User:Yourname/yourscript.css&action=raw&ctype=text/css";

Other methods

You can also debug your scripts:

javascript: var s = document.createElement('script');
s.src = 'file://C:/myscript.js';
document.getElementsByTagName('head')[0].appendChild(s);void 0

However all these methods execute your user script at slightly different time than monobook.js, so you might have to do some temporary code modifications during debugging.

Software

Any text editor will do. If you plan to use non-ascii characters in string, your text editor should support UTF-8.

Notepad++ is recommended, since it can:

  • highlight Javascript code
  • quickly insert standart Javascript keywords and methods with Ctrl-Enter
  • show the list of all functions and quickly jump to any function
  • Code folding


For debugging in Firefox you can use Tools → Javascript Console which shows all Javascript and CSS errors. FireBug is strongly recommended for convenient debugging.

For debugging in IE see IEBlog: Scripting Debugging in Internet Explorer