帮助:维基用户脚本开发指南
这份指南介绍在维基百科上开发用户脚本的基本方法。维基用户脚本是用JavaScript(JS)编写的,但本文不会介绍JS的语法。
内置脚本
编辑所有维基百科页面都有MediaWiki生成的JS代码。浏览网页时,你的用户脚本可以访问这些内置代码生成的方法和变量。具体哪些页面可用哪些方法和变量,请参见en:Wikipedia:Catalogue of CSS classes#Stylesheets and JavaScript。
用户脚本可以使用JQuery,这是MediaWiki自带的。JQuery的最重要的方法是JQuery()
或$()
,用法说明请参考官方文档 (英文)。
最感兴趣的是:
- mw.config变量
- 可用的资源加载模块
- MediaWiki:Common.js(由中文维基百科的管理员所管理)
- 用户的全局脚本:/common.js
- 用户的特定皮肤脚本:/vector.js(实际名称取决于用户首选项中的皮肤设置)
用户脚本的结构
编辑个人“用户”模块(由/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也相当不错。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";
软件
编辑编辑器
编辑- 高亮JavaScript代码
- 快速插入JavaScript关键字和方法。快捷键是 Ctrl+↵ Enter。
- 查看所有JS方法,转到方法。
- 代码折叠
Mac OS X用户可以使用免费的
- Xcode
- JEdit (跨平台)
- Komodo Edit (跨平台)
- Aptana Studio(跨平台)
或收费的
调试器
编辑火狐浏览器:Firefox按钮->Web开发者->Web控制台。Firebug提供类似的功能。
Google Chrome和Chromium:菜单->工具->开发者工具。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"]')
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-navigation p-interaction p-tb p-lang |
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='#'><div></a>";
There is no crucial difference between toolbar and edittools, you can insert your own custom links into both.