說明:維基用戶腳本開發指南

這份指南介紹在維基百科上開發用戶腳本的基本方法。維基用戶腳本是用JavaScript(JS)編寫的,但本文不會介紹JS的語法。

內置腳本

編輯

所有維基百科頁面都有MediaWiki生成的JS代碼。瀏覽網頁時,你的用戶腳本可以訪問這些內置代碼生成的方法和變量。具體哪些頁面可用哪些方法和變量,請參見en:Wikipedia:Catalogue of CSS classes#Stylesheets and JavaScript

用戶腳本可以使用JQuery,這是MediaWiki自帶的。JQuery的最重要的方法是JQuery()$(),用法說明請參考官方文檔 (英文)

最感興趣的是:

用戶腳本的結構

編輯

個人「用戶」模塊(由/common.js, /common.css 和非必需的當前皮膚的特定文件構建)以及小工具會被加載到所有頁面

大部分腳本都需要訪問頁面上的HTML元素,因此需要在頁面加載完成後再運行。(實際加載模塊時可能並非如此)

function myScript() {
  // ... 
};

// 在文档加载完成后执行myScript方法。
jQuery( myScript );

也可以內聯myScript。

jQuery( function () {
  //... code ...
} );

編輯和加載用戶腳本

編輯

預覽用戶腳本

編輯

你可以直接在/common.js編寫腳本,「顯示預覽」時,代碼就會執行。

保存用戶腳本

編輯

如果你的腳本的工作頁面與預覽頁面不同,比如你想開發一個針對分類的腳本,那麼你就要保存腳本,然後去目標頁面調試。

這種方法極為不便,也會在維基上產生大量的編輯歷史。

本地HTML文件

編輯
  • 用瀏覽器將欲調試的維基頁面(HTML)連同該頁面調用的CSS和JS保存到本地。
  • 用編輯器打開HTML,插入你正在開發的JS代碼。
  • 用瀏覽器打開HTML,查看代碼的運行情況。

這種方法很節省網絡流量,但有以下的缺點:

  • 瀏覽器一般不會允許你從本地向外地(zh.wikipedia.org)發起Ajax
  • 您必須根據實際需要測試的頁面(歷史記錄等)來保存不同的頁面
  • 您必須定期重新保存所有.js文件,以便與MediaWiki更改同步
  • 需要保存HTML、CSS、JS。如果你只是對別人的腳本進行小修改,這個「前期準備」工作可能有些煩人。

推薦:從本機伺服器上加載用戶腳本

編輯

推薦的方法是從本機伺服器上加載用戶腳本,而你需要搭建一個本機伺服器。在/common.js加入代碼

mw.loader.load( 'http://localhost/wikipediatest.js' );

然後在你的電腦上運行網頁伺服器,創建wikipediatest.js。於是,每次刷新維基百科頁面時,本機伺服器上的wikipediatest.js就會運行,如同維基用戶腳本。

至於如何編輯wikipediatest.js,大家就可以八仙過海各顯神通了,比如用簡單的記事本、Vim,甚至Visual Studio。如果你的網頁伺服器設置的好,每次修改wikipediatest.js後,再刷新維基百科,修改就能自動反映出來,甚至不需要刷新緩存

TinyWeb是個不錯的網頁伺服器,不到100KB,也不需要安裝。 Save and unzip tinyweb.zip for example into c:\Program Files\Tinyweb, create a shortcut to tiny.exe, and add an argument in shortcut properties — path to your folder with wikipediatest.js and any file index.html (required). Start TinyWeb with this shortcut; unload it with Task Manager.

Opera自9.50版起加強了安全限制,這個方法對Opera不起作用。參見Opera 9.50 Windows更新日誌: 」本地伺服器可以調用遠程資源,但遠程伺服器不能調用本地資源「(本地伺服器可以使用遠程資源,反之亦然))

Browser-specific

編輯

有些瀏覽器(或瀏覽器插件)允許你瀏覽網頁時執行你自己設置的JS。我們可以利用這個特性來開發維基用戶腳本。

最有名的是火狐瀏覽器的擴展Greasemonkey(油猴子),Scriptish英語Scriptish也相當不錯。en:Greasemonkey#Greasemonkey compatibility and equivalents for other browsers列出了Greasemonkey的類似軟體。

然而,在瀏覽器或瀏覽器插件里能運行不代表能作為維基百科用戶腳本運行。

Opera用戶注意:

  • Placing your script in a corresponding folder as <name>.js file should work for many user scripts.
  • Opera約9.50版本以前不支持UTF-8編碼的本地腳本, meaning you could only use Latin characters.

代碼片段

編輯

你可以在瀏覽網頁時運行代碼片段,如在瀏覽器地址欄輸入javascript: var s = document.title; alert(s); void 0並回車。但在瀏覽器地址欄里不能輸入大段代碼。

你可以使用bookmarklet JavaScript Shell。它可以打開一個新窗口,在這個窗口裡編寫並執行的JS代碼可以訪問原頁面。

當然,用一個成熟的JavaScript調試器會更加方便。

CSS文件

編輯

用戶腳本可以使用CSS代碼,甚至可以只用CSS。那麼你就需要把JS和CSS一起調試。That can be done in your /common.css, but it is slow and messy.

你應該在本地伺服器里放置你的CSS文件(見上節),然後從/common.css里用

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

導入。注意,@import語句要寫在其他CSS語句之前。

An alternative way is to put this line anywhere in your css instead:

mw.loader.load( 'http://localhost/wikipediatest.css', 'text/css' );

發布CSS文件

編輯

當你寫完CSS代碼時, you either need to paste it into your /vector.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 the following line in their /common.js file. 注意,以下語句需要被添加到".js"文件而不是".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, users can import your User:Yourname/yourscript.css from their /common.css too. This of course has the advantage that it works even if the user has JavaScript disabled. Although it takes this slightly complex line of code:

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

軟體

編輯

編輯器

編輯

Windows用戶可以使用Notepad++,它可以

  • 高亮JavaScript代碼
  • 快速插入JavaScript關鍵字和方法。快捷鍵是 Ctrl+↵ Enter
  • 查看所有JS方法,轉到方法。
  • 代碼摺疊


Mac OS X用戶可以使用免費的

或收費的

Linux用戶可以用geditKate

調試器

編輯

火狐瀏覽器:Firefox按鈕->Web開發者->Web控制台。Firebug提供類似的功能。

Google ChromeChromium:菜單->工具->開發者工具。Firebug提供類似的功能。

Internet Explorer:按F12鍵打開開發者工具。

For debugging in Safari, open up Safari → Preferences → Advanced and enable the "Show Develop menu in menu bar" option. Afterwards, you can use Develop → Show Web Inspector to open up the development tools.

For debugging in Opera, you can use Tools → Advanced → Error Console which shows all JavaScript and CSS errors. Dragonfly is strongly recommended for convenient debugging.

DHTML 方法

編輯

檢索元素

編輯

每一個 HTML 元素都是DOM中的節點。因此Javascript腳本可以訪問這些元素。for example, on the following HTML page.

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

可以通過以下方法訪問textarea元素:

  • Using its id: $( '#txtid' )
  • In the array of all elements with the same tag: $( 'textarea' )
  • Using an element next to it: $( '#neighbor').prev()
  • As a child of its parent: $( '#frmid' ).children( 'form' )
  • As a form element, using name: $( '#frmid [name="txtname"]')

This example on jsFiddle

The jQuery documentation and jQuery API reference are excellent sources for documentation.

何時執行腳本

編輯

很多腳本只在特定的維基頁面工作。 You can check:

  • The page address
if ( mw.config.get( 'wgAction' ) === 'history' ) {
  //Continue only on history pages.
  • wg variables; many of them have the same meaning as Magic words
if ( mw.config.get( 'wgCanonicalNamespace' ) === 'User_talk') {
  //Continue only on User_talk pages.
  • Presence of elements (only in second and third parts of the script)
function func_start() {
   if ( $( '#editForm' ).length == 0  ) 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-search

 
p-cactions Article Discussion Read Edit History

p-navigation

 Main page …

p-interaction
  …


p-tb

Upload file


p-lang
(interwikis)

Portlet structure:

<div id="p-myname" class="portlet">
 <h5>Header</h5>
 <div class="body">
  <ul>
  <li id="…"> <a >  //Links
  <li id="…"> <a >
  … …

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

// Several examples of portlet links

// Adds a link to your js file to the toolbox
mw.util.addPortletLink ( 'p-tb', mw.util.getUrl( 'Special:MyPage/common.js' ),
	'My JS', 'pt-myvector', 'Visit your js file');

// Add a link to the edit page for your Notes in your personal links
// Note: We assume that short/pretty URLs are in use with ?action, ideally you
// would check for that.
mw.util.addPortletLink ( 'p-personal', mw.util.getUrl( 'Special:MyPage/Notes' ) + '?action=edit',
	'My notes', 'pt-mynotes', 'Edit your personal notes' );

// Adds a link to prefix index for the current page to the toolbox
mw.util.addPortletLink ( 'p-tb',
	mw.util.getUrl( 'Special:Prefixindex/' + mw.config.get( 'wgPageName' ) ),
	'Prefixindex', 'tb-prefixindex');
	
// Adds a link to 
mw.util.addPortletLink ( 'p-personal',
	mw.util.getUrl( 'Special:Log/' + mw.config.get( 'wgUserName' ) ),
	'My logs', 'pt-mylogs');

移除元素

編輯

如想移動一個元素,可使用.append().prepend()

如想隱藏一個元素,使用.hide()

// 举例: 隐藏编辑页面中的“特殊字符”工具栏
$( '#editpage-specialchars' ).hide();

// 或通过jQuery改CSS
$( '#editpage-specialchars' ).css( 'display', 'none' );

或在您的CSS代碼頁加入:

#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 = $( '#wpTextbox1' );

You can add new text to the beginning: $txt.prepend( 'new phrase' ) or to the end: $txt.append( 'new phrase' ).

There is a function in mediawiki.action.edit.js that can add text to the cursor position:

// This surrounds the cursor with '<pre>' and '</pre>' and pre-fills the selection with 'Test!' highlighted.
mw.toolbar.insertTags( '<pre>', '</pre>', 'Test!' );

Toolbar

編輯

The buttons above a text area are located inside <div id='toolbar'>.

Buttons are defined with mwEditButtons[] and mwCustomEditButtons[] arrays. Then the second part of your script is called by addOnloadHook. Only after that the buttons are created by the initialization of the mediawiki.action.edit module.

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. Usually it's generated from MediaWiki:Edittools by Extension:CharInsert and consists of a lot of JavaScript links to the insertTags(). In the English Wikipedia, this approach was replaced by MediaWiki:Edittools.js.

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

參考資料

編輯