Wikipedia:WikiProject User scripts/Guide
From Wikipedia, the free encyclopedia
|
Small guide on writing user scripts for Wikimedia sites. Of course, some basic Javascript knowledge is required.
[edit] Scripts
The following script files are executed for every Wikipedia visitor:
- some (wg) variables in the beginning of the page
- wikibits.js — shared by all Wikimedia projects
- MediaWiki:Common.js (as generated), supported by local Administrators
- monobook.js — your own script file, if you created one
- ajax.js — shared by all Wikimedia projects
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.
[edit] 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 (){ }
[edit] Basic methods
[edit] 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 it's 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.
[edit] 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 … …
[edit] 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 p-search p-tb p-lang |
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.
[edit] 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()
[edit] 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] Edit page
[edit] 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)
[edit] 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.
[edit] 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='#'><div></a>";
There is no crucial difference between toolbar and edittools, you can insert your own custom links into both.
[edit] Debugging
[edit] 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.
[edit] 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.
[edit] Call from Monobook.js
The best and most recommended way is to insert into your monobook.js
importScriptURI( 'http://localhost/test.js');
Then run any webserver on your computer and create test.js file in the appropriate folder. The code inside this file will be executed as if it was inside monobook.js
You can edit your test.js with any text editor with syntax highlighting and other convinient features, then save the file and simply update any Wikipedia page.
For example you could use TinyWeb which is less 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 test.js and any file index.html (required). Start TinyWeb with this shortcut; unload it with Task Manager.
[edit] Other methods
You can also debug your scripts:
- in FireFox with Greasemonkey
- in Opera with User JavaScript
- in Internet Explorer 6 (and maybe in some other browsers) with bookmarklet
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.
[edit] 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