Wikipedia:User scripts/Guide

This is an old revision of this page, as edited by Davidgothberg (talk | contribs) at 19:39, 19 September 2008 (Call from Monobook.js: Adding explanation how to load CSS files from a local web server.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Small guide on writing user scripts for Wikimedia sites. Of course, some basic Javascript knowledge is required.

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(func_start); //means «execute func_start later»

//part 2 — executed when the page is loaded
function func_start (){

 //quite often it simply adds a javascript link
 <a onclick="func_action()" href="#">
}
//and then there is …

//part 3 — executed when 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.

Debugging

Previewing in Monobook.js

You can edit your script directly on your monobook.js page, then press «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 convinient and creates unnecessary load on WikiMedia servers.

Load from a localhost web server

The best and most recommended way is to insert into 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.

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.

CSS files

In the same way you can load a CSS file from your local web server. Put this string at the very top of your /monobook.css :

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

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

Once you have finished the CSS code you need to upload it to for instance User:Yourname/yourscript.css. If it should be used together with a user script written in JavaScript then from the JavaScript you can load the CSS file with this line of code:

importStylesheet( 'User:Yourname/yourscript.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