LLWiki正在建設中,歡迎加入我們!
「LLWiki:管理员技术手册」修訂間的差異
小 (→滥用过滤器: // 使用Wikiplus小工具快速编辑) 標籤:行動版網頁編輯 行動版編輯 |
小 (// 使用Wikiplus小工具快速编辑) 標籤:行動版網頁編輯 行動版編輯 |
||
(未顯示由 3 位使用者於中間所作的 72 次修訂) | |||
第1行: | 第1行: | ||
{{内容缺失}} |
{{内容缺失}} |
||
由于LLWiki使用的不是最新版本的MediaWiki系统以及MediaWiki的帮助页面可能未得到及时和正确的更新,编辑这个页面时请不要简单地复制或翻译来自MediaWiki的内容,应该在条件允许的情况下先实际测试。 |
|||
{{目录折叠}} |
|||
==全站CSS== |
==全站CSS== |
||
这里所说的全站CSS包含[[mediawiki:common.css|common.css]]、[[mediawiki:mobile.css|mobile.css]]和各[[:category:CSS小工具|CSS小工具]],有时由于功能的相似性也会涉及用户CSS([[special:mypage/common.css|common.css]]、[[special:mypage/vector.css|vector.css]]和[[special:mypage/minerva.css|minerva.css]])。LLWiki暂时没有建立针对不同用户组的专门CSS页面。 |
|||
===优先加载的CSS=== |
|||
一些CSS会以<code lang="html"><link rel="stylesheet"></code>的形式在首次渲染前完成加载,包括[[mediawiki:common.css|common.css]]和各[[:category:纯CSS小工具|纯CSS小工具]],这些CSS页面适合处理静态HTML元素就需要的样式。注意[[:category:纯CSS小工具|纯CSS小工具]]即使在定义时规定了<code>targets=mobile</code>也一定会在桌面版加载,因此手机版的专用CSS需要添加<code lang="css">.skin-minerva</code>选择器。 |
|||
由于[[mediawiki:common.css|common.css]]本身就会优先加载,桌面版专用的全站CSS写入该页面即可,与手机版通用的CSS写入[[mediawiki:gadget-site-styles.css|gadget-site-styles.css]]。某个小工具专用的CSS如果需要用于静态HTML元素,请将CSS部分单独定义为<code>type=styles</code>(可省略,但添加后方便区分)的纯CSS小工具,然后以<code>peers=<纯CSS小工具名称></code>的语法添加到对应的JS小工具上。参见[[#小工具定义]]。 |
|||
===滞后加载的CSS=== |
|||
一些CSS的加载需要依赖JS,加载时机可能晚于首次渲染,包括[[mediawiki:mobile.css|mobile.css]]和除[[:category:纯CSS小工具|纯CSS小工具]]以外的[[:category:CSS小工具|CSS小工具]],这些CSS页面适合处理依赖JS动态加载的HTML元素。 |
|||
由于[[mediawiki:mobile.css|mobile.css]]加载滞后,静态HTML元素需要的手机版样式请添加<code lang="css">.skin-minerva</code>选择器后写入[[mediawiki:gadget-site-styles.css|gadget-site-styles.css]]。 |
|||
===CSS小工具分类=== |
|||
定义为<code>type=styles</code>的小工具应添加[[:category:纯CSS小工具|纯CSS小工具]]分类,其他CSS小工具应添加[[:category:CSS小工具|CSS小工具]]分类。其他分类与JS小工具一致,参见[[#小工具分类]]。 |
|||
==Widget(小部件)== |
==Widget(小部件)== |
||
===小部件页面格式=== |
|||
===小部件分类=== |
|||
===小部件JS的特殊之处=== |
|||
==Gadget(小工具)和全站JS== |
==Gadget(小工具)和全站JS== |
||
这里所涉及的JS页面包含[[mediawiki:common.js|common.js]]、[[mediawiki:mobile.js|mobile.js]]和各[[:category:JavaScript小工具|JS小工具]],有时由于功能的相似性也会涉及用户JS([[special:mypage/common.js|common.js]]、[[special:mypage/vector.js|vector.js]]和[[special:mypage/minerva.js|minerva.js]])。LLWiki暂时没有建立针对不同用户组的专门JS页面。 |
|||
===ResourceLoader和JS模块=== |
|||
[[mediawiki:common.js|common.js]]、[[mediawiki:mobile.js|mobile.js]]、[[special:mypage/common.js|用户JS]]和[[MediaWiki:Gadgets-definition]]页面定义的小工具等JS页面会作为ResourceLoader的模块加载,这些JS将在语法检查和压缩后由load.php打包下载,且可以作为mw.loader.getState()方法、mw.loader.using()方法的参数。 |
|||
作为ResourceLoader的模块加载时,不可使用ES6语法。这里的语法指关键字、算符等,不包括对象原型方法,例如<code lang="js">Object.fromEntries()</code>方法或<code lang="js">new Map()</code>构造器仍可照常使用。下表列出一些常见的JS模块不可使用的语法及其替代。 |
|||
{| class="wikitable" |
|||
! ES6以上语法 !! 替代 |
|||
|- |
|||
| <code>=> output</code> || <code lang="js">function() { return output; }</code> |
|||
|- |
|||
| <pre class="hljs javascript">class NewClass extends Parent { |
|||
constructor(params) { super(params); } |
|||
}</pre> || <pre class="hljs javascript">function NewClass(params) { NewClass.super.call(this, params); } |
|||
OO.inheritClass(NewClass, Parent);</pre> |
|||
|- |
|||
| <code>{key}</code> || <code lang="js">{key: key}</code> |
|||
|- |
|||
| <pre class="hljs javascript">`firstline |
|||
secondline`</pre> || <pre class="hljs javascript">'firstline\n' + 'secondline'</pre> |
|||
|- |
|||
| <code lang="js">`string${variable}`</code> || <code lang="js">'string' + variable</code> |
|||
|- |
|||
| <code>[variable] = array;</code> || <code lang="js"> variable = array[0];</code> |
|||
|- |
|||
| <code lang="js">{key: variable} = {key: value};</code> || <code lang="js">variable = {key: value}['key'];</code> |
|||
|- |
|||
| <code lang="js">function(params = defaults)</code> || <code lang="js"><nowiki>function() { params = params || defaults; }</nowiki></code> |
|||
|- |
|||
| <code>[...iterator]</code> || <code lang="js">Array.from( iterator )</code> |
|||
|- |
|||
| <code>array2 = [...array1];</code> || <code>array2 = array1.slice();</code> |
|||
|- |
|||
| <code>[...array1, ...array2]</code> || <code>array1.concat( array2 )</code> |
|||
|- |
|||
| <code>[element, ...rest] = array;</code> || <code lang="js">element = array[0], rest = array.slice(1);</code> |
|||
|- |
|||
| <code lang="js">let</code><ref><code lang="js">const</code>可用。</ref> || <code lang="js">var</code> |
|||
|- |
|||
| <code>2**3</code><ref name="jshint">ES7以上语法虽然在不作为ResourceLoader的模块时允许使用,但因为CodeEditor安装的[[#JSHint|JSHint]]版本不支持语法分析,可能会造成代码除错时的困难。</ref> || <code lang="js">Math.pow(2, 3)</code> |
|||
|- |
|||
| <code lang="js">async function()</code><ref name="jshint" /> || <code lang="js">function() { return new Promise(resolve, reject); }</code> |
|||
|- |
|||
| <code lang="js">try { variable = await func(); } catch {}</code><ref name="jshint" /> || <code lang="js">func().then(function(result) { variable = result; }, function() {});</code> |
|||
|- |
|||
| <code>obj1 = {...obj2};</code><ref name="jshint" /> || <code lang="js">obj1 = $.extend(true, {}, obj2);</code> |
|||
|- |
|||
| <code>{...object1, ...object2}</code><ref name="jshint" /> || <code lang="js">$.extend(object1, object2)</code>或<code lang="js">Object.assign(object1, object2)</code><ref>注意$.extend()方法与另两者并不完全一致,但更推荐使用$.extend()。</ref> |
|||
|} |
|||
===不作为模块的JS脚本=== |
|||
===小工具定义=== |
|||
===小工具简介=== |
|||
===小工具分类=== |
|||
===MediaWiki核心模块介绍=== |
|||
本章节介绍LLWiki使用或曾经使用的MediaWiki核心模块,更完整的列表参见[[mw:ResourceLoader/Core_modules/zh|MediaWiki]]和[https://doc.wikimedia.org/mediawiki-core/master/js/ JSDuck]。 |
|||
====mediawiki==== |
|||
mediawiki是任何页面都会预加载的两个环境模块之一,包含不少功能<ref name="core-modules">[[mw:ResourceLoader/Core_modules/zh|MW:ResourceLoader/核心模块]]</ref>。这里只介绍LLWiki常使用的一些属性和方法。 |
|||
;mw.config |
|||
:这个属性提供了大量重要的站点、页面和用户信息<ref>[[mw:Manual:Interface/JavaScript/zh#mw.config|完整列表]]</ref>,一般常用mw.config.get()方法获取对应的变量值。下表整理了LLWiki常用的一些变量: |
|||
{| class="wikitable" |
|||
! 变量名 !! 说明 !! 手机版可用性 |
|||
|- |
|||
| skin || 皮肤 || 桌面版为“vector”,手机版为“minerva”,这也是区分桌面版和手机版的主要依据 |
|||
|- |
|||
| wgFormattedNamespaces || 储存了所有命名空间本地化译名的数组,不过目前除了“模块”都是英文 || 可用 |
|||
|- |
|||
| wgNamespaceIds || 储存了所有可接受的中英文命名空间名称对应的编号,注意英文名称中的空格都显示为下划线 || 可用 |
|||
|- |
|||
| wgScript || <code>/mediawiki/index.php</code>,在LLWiki也可简化为<code>/zh</code>,主要用于不同MediaWiki站点间的代码通用,非必需且不推荐使用 || 可用 |
|||
|- |
|||
| wgAction || index.php的action参数<ref>[[mw:Manual:Parameters_to_index.php/zh|完整参数列表]]</ref> || 相比于桌面版,手机版由于添加了[[Special:历史]]而少了“history”这个可能值 |
|||
|- |
|||
| wgArticleId || 内容页面编号,不存在时值为0,可以用于判断是否是内容页面且页面是否已建立 || 需要注意查看[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]时值为0 |
|||
|- |
|||
| wgCanonicalSpecialPageName || 标准化的特殊页面名,也可被wgPageName取代,主要用于不同MediaWiki站点间的代码通用,非必需 || 可用,而且多了“History”和"MobileDiff"等可能的取值<ref>[[mw:Extension:MobileFrontend/zh|移动前端的扩展说明]]</ref> |
|||
|- |
|||
| wgCategories || 当前阅读的历史版本所属的分类,不含命名空间,下划线显示为空格,且总是包含隐藏分类。繁简规则遵从实际分类页面 || 仅LLWiki可用 |
|||
|- |
|||
| wgCurRevisionId || 页面最新的版本编号,不存在时值为0 || 在[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面不可用 |
|||
|- |
|||
| wgIsArticle || 是否是内容页面(包含由某个页面的Wikitext源代码解析生成的HTML,可能是历史页面和差异下方的历史页面) || 由于[[special:移动版差异|{{int:diff}}]]页面不可同时显示历史页面,此时不可用 |
|||
|- |
|||
| wgIsRedirect || 最新版本是否是重定向页面 || 在[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面不可用 |
|||
|- |
|||
| wgIsProbablyEditable || 是否可能可以编辑 || 在[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面不可用 |
|||
|- |
|||
| wgNamespaceNumber || 命名空间编号 || 在[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面会显示为-1 |
|||
|- |
|||
| wgPageContentModel || 页面内容模型,特殊页面为“wikitext” || 由于[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]是特殊页面,会错误地显示为“wikitext” |
|||
|- |
|||
| wgPageName || 页面名称,空格显示为下划线 || 在[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面不可用 |
|||
|- |
|||
| wgRedirectFrom || 跳转自重定向时为对应的重定向页,空格显示为下划线 || 可用 |
|||
|- |
|||
| '''wgRelevantPageName''' || 关联的页面名称,空格显示为下划线 || 可以用于[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面,此时效果与桌面版一致 |
|||
|- |
|||
| '''wgRelevantArticleId''' || 关联的内容页面编号,不存在时值为0 || 可以用于[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面,此时效果与桌面版一致 |
|||
|- |
|||
| wgRelevantUserName || 关联的用户名 || [[special:用户贡献|{{int:contributions}}]]页面不可用 |
|||
|- |
|||
| '''wgRelevantPageIsProbablyEditable''' || 关联的页面是否可能可以编辑 || 可以用于[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面,此时效果与桌面版一致 |
|||
|- |
|||
| wgRestrictionEdit || 编辑保护,不存在的页面(含受保护的标题)或特殊页面为<code lang="js">null</code>,存在的内容页面受全保护时为<code lang="js">["sysop"]</code>,受半保护时为<code lang="js">["autoconfirmed"]</code>,未保护为<code>[]</code>;不包含命名空间保护和级联保护 || 在[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面不可用,另外未保护的内容页面为<code lang="js">["*"]</code> |
|||
|- |
|||
| wgRestrictionMove || 移动保护,不存在的页面或特殊页面为<code lang="js">null</code>,存在的内容页面受全保护时为<code lang="js">["sysop"]</code>,受半保护时为<code lang="js">["autoconfirmed"]</code>,未保护为<code>[]</code>;不包含命名空间保护和级联保护 || 在[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面不可用 |
|||
|- |
|||
| wgRevisionId || 当前显示的页面版本的编号,不存在时值为0。注意和index.php的oldid参数可能不同 || 由于[[special:移动版差异|{{int:diff}}]]页面不可同时显示历史页面,此时不可用 |
|||
|- |
|||
| wgTitle || 不含命名空间的页面名称,下划线显示为空格 || 在[[special:历史|历史]]和[[special:移动版差异|{{int:diff}}]]页面不可用 |
|||
|- |
|||
| wgUserEditCount || 当前用户的编辑次数 || 可用 |
|||
|- |
|||
| wgUserGroups || 当前用户所属的用户组,未登入时为<code lang="js">["*"]</code> || 可用 |
|||
|- |
|||
| wgUserLanguage || 当前用户使用的界面语言 || 可用 |
|||
|- |
|||
| wgUserName || 当前用户的用户名,下划线显示为空格 || 可用 |
|||
|- |
|||
| wgUserRegistration || 当前用户的注册时间,显示为毫秒数;可以使用mw.user.getRegistration()方法替代,该方法会生成Date对象 || 可用 |
|||
|- |
|||
| wgUserVariant || 当前用户阅读页面时的内容语言,在不可更改内容语言的页面总是为该用户的默认内容语言 || 可用 |
|||
|- |
|||
| wgDiffOldId || 差异页面位于左侧的版本的编号 || 不可用 |
|||
|- |
|||
| wgDiffNewId || 差异页面位于右侧的版本的编号 || 不可用 |
|||
|} |
|||
;mw.hook() |
|||
:这个方法是LLWiki建立异步JS框架的重要一环。常用以下两个方法: |
|||
:*<code>mw.hook(hook).fire(data)</code>: 用于唤起一个Hook事件,其中data为传递给事件处理程序的可选参数。 |
|||
:*<code>mw.hook(hook).add(handler)</code>: 用于处理一个Hook事件,handler为该事件处理函数,参数传递自<code>mw.hook().fire()</code>方法。 |
|||
:这个方法应与jQuery的event delegation和各Promise对象结合使用,以在恰当的时机执行恰当的函数。以下列举LLWiki常用的Hook事件。 |
|||
{| class="wikitable" |
|||
! Hook名称 !! 说明 |
|||
|- |
|||
! colspan=2 | MediaWiki预定义的Hook |
|||
|- |
|||
| postEdit || 一次非空编辑提交成功,一般发生在自动重载页面后,可以搭配<code lang="js">mw.config.get( 'wgPostEdit' )</code>。需要注意各类编辑小工具提交编辑后的页面重载均未适配这个事件 |
|||
|- |
|||
| structuredChangeFilters.ui.initialized || [[special:recentchanges|{{int:recentchanges}}]]、[[special:recentchangeslinked|{{int:recentchangeslinked}}]]和[[special:watchlist|{{int:watchlist}}]]页面的过滤器加载完成,一般至多发生一次 |
|||
|- |
|||
| wikipage.categories || 页面下方的<code lang="css">div#catlinks</code>加载完成。特殊页面或没有添加任何分类时也能触发,因为此时<code lang="css">#catlinks</code>仍然存在只是隐藏起来 |
|||
|- |
|||
| wikipage.collapsibleContent || 某个或某组<code>mw-collapsible</code>类的元素添加折叠JS完成 |
|||
|- |
|||
| wikipage.content || 最常用的Hook,表示页面内容(一般即<code lang="css">div#mw-content-text</code>)加载完成,几乎无处不在,与<code>$.ready</code>最大的区别在于这个事件可能多次触发 |
|||
|- |
|||
| wikipage.diff || 差异(一般即<code lang="css">table.diff</code>)加载完成 |
|||
|- |
|||
| wikipage.editform || 编辑区加载完成,需要注意此时[[mw:extension:wikiEditor/zh|WikiEditor]]的工具栏可能尚未加载完成 |
|||
|- |
|||
| codeEditor.configure || 切换至[[mw:extension:codeEditor/zh|CodeEditor]] |
|||
|- |
|||
! colspan=2 | LLWiki定义的Hook |
|||
|- |
|||
| code.prettify || 代码高亮完成 |
|||
|- |
|||
| codemirror.config || CodeMirror扩展的设置下载完成 |
|||
|- |
|||
| hotcat.ready || HotCat小工具加载完成 |
|||
|- |
|||
| local.comments || 签名时间替换为本地时区 |
|||
|- |
|||
| to.bottom || 添加滚动至底部的按钮 |
|||
|- |
|||
| transclusion.preview || 用于预览嵌入页面的编辑区加载完成 |
|||
|- |
|||
| wikiplus.dialog || 打开Wikiplus小工具的对话框 |
|||
|} |
|||
;mw.loader |
|||
:mw.loader包含了很多用于ResourceLoader的方法。 |
|||
:*mw.loader.addStyleTag(),用于在<code lang="css">header</code>的末尾插入一个<code lang="html"><style></code>。由于返回的是一个HTML元素,后续操作不如mw.util.addCSS()返回的StyleSheet对象方便,但在不需要后续操作的场合可以不用加载mediawiki.util模块。由于mediawiki.util在LLWiki的广泛使用,这个方法几乎没有任何优点。 |
|||
:*mw.loader.getScript(),用于加载外部JS脚本,相比mw.loader.load()方法优点在于会返回一个Promise对象。 |
|||
:*mw.loader.getState(),用于获取模块的当前状态,不可用的模块返回<code lang="js">null</code>,可用但未加载的模块返回<code lang="js">'registered'</code>,可用且正在加载的模块可能返回<code lang="js">'loaded'</code>或<code lang="js">'loading'</code>,已加载完成的模块返回<code lang="js">'ready'</code>。注意加载完成的模块未必已经执行完。 |
|||
:*mw.loader.load(),用于加载模块、其他JS或其他CSS,加载模块时参数为模块名或一个模块名构成的数组,加载JS或CSS时填写url,加载CSS还需要额外填写第二参数<code lang="js">'text/css'</code>。缺点在于不会返回一个Promise对象。 |
|||
:*mw.loader.using(),用于加载模块,相比mw.loader.load()方法优点在于会返回一个Promise对象,任一模块加载失败即返回rejected。 |
|||
;mw.notify() |
|||
:调用这个方法可以在桌面版的右上角、手机版的上方显示一个[[mw:Bubble_notifications/zh|泡泡通知]]。LLWiki一般使用这个方法取代window.alert()或OO.ui.alert()。 |
|||
:方法<code>mw.notify(message, options)</code>接受两个参数。第一个必需参数<code>message</code>指定通知内容,可以是字符串、HTML元素对象或元素对象数组、jQuery对象或mw.message对象;第二个可选参数<code>options</code>则指定自定义选项,是一个JS对象。 |
|||
:<code>options</code>中可自定义的选项有: |
|||
:*<code>autoHide</code>:布尔值,决定通知是否会自行消失。默认为<code lang="js">true</code>。 |
|||
:*<code>autoHideSeconds</code>:如果启用了<code>autoHide</code>(如默认情形),则指定通知自行消失的时间。默认为<code lang="js">'short'</code>(5秒),可以指定为<code lang="js">'long'</code>(30秒)。 |
|||
:*<code>tag</code>:字符串,指定通知的标签,类似于HTML的ID。如果发送多个拥有同一个tag的通知,会导致之前的通知被后来的在原位覆盖。 |
|||
:*<code>title</code>:标题。如果指定,则会于内容上方加粗显示。 |
|||
:*<code>type</code>:字符串,指定通知的种类。除默认效果外其他可选类型为<code lang="js">'success'</code>、<code lang="js">'warn'</code>和<code lang="js">'error'</code>。 |
|||
;mw.now() |
|||
:这个方法理论上和Date.now()差不多,但实际测试表明和Date.now()的取值不同,因此请勿混合使用。非必需,基本可以完全被Date.now()替换。 |
|||
;mw.messages |
|||
:用于改善代码结构,在代码开头使用mw.messages.set()方法结合[[#LLWiki添加的全局变量和方法|wgULS()和wgUCS()]]设置自定义消息的繁简名称,然后使用mw.msg()方法即可调用。使用这一方法时,还能以<code>$1</code>的形式设置待定参数,或使用部分解析器函数。 |
|||
====jquery==== |
|||
jquery是任何页面都会预加载的两个环境模块之一,尤其在DOM操作和Ajax请求方面功能强大,非常推荐在JS编程之前预先熟悉[https://api.jquery.com/ API文档]。考虑到mw.loader已经集成了不少的常用Ajax方法,这里主要推荐熟练掌握DOM相关的内容,包括[https://api.jquery.com/category/events/ 事件]、[https://api.jquery.com/category/manipulation/ DOM操作]、[https://api.jquery.com/category/selectors/ 选择器]和[https://api.jquery.com/category/traversing/ 遍历]。特别需要提醒的是滥用htmlString有造成XSS的风险,因此请尽量使用如<code lang="js"><nowiki>$('<p>', {html: $('<a>', {text: '文字', href: 'https://llwiki.org'})})</nowiki></code>或<code lang="js"><nowiki>$('<p>').append( $('<a>').text('文字').attr('href', 'https://llwiki.org') )</nowiki></code>等语法进行规避。 |
|||
因未被mw.loader包含而可能用到的Ajax方法主要为<code>$.getJSON()</code>,需要注意在MW的默认设置下调用jQuery的Ajax方法必须手动设置<code lang="js">{cache: true}</code>。 |
|||
另外jQuery也提供了一些[https://api.jquery.com/category/utilities/ 工具方法],可以用于缓解ResourceLoader的JS模块不允许使用ES6语法的问题,或是方便键值对相关的语句的书写,或是方便连锁。比如用<code>$.extend()</code>方法代替<code>...</code>算符、用<code>$.each(obj, (key, val) => {})</code>方法代替<code lang="js">for (const key in obj) {}</code>等。 |
|||
应用jQuery时可能出现的一些常见错误列举如下: |
|||
*混淆<code>.attr()</code>方法和<code>.prop()</code>方法。 |
|||
*混淆jQuery对象的<code>.data()</code>方法和HTML元素的<code>.dataset</code>属性。 |
|||
*使用<code>.toggle()</code>、<code>.fadeToggle()</code>等方法时不慎破坏较复杂的CSS布局。 |
|||
*错误使用<code>.remove()</code>、<code>.clone()</code>等方法造成丢失数据和事件处理程序。 |
|||
*混淆<code>event.target</code>、<code>event.currentTarget</code>、<code>event.delegateTarget</code>和<code lang="js">this</code>关键字。 |
|||
*混淆<code>$.when()</code>方法和<code lang="js">Promise.all()</code>方法的参数格式和回调函数。 |
|||
====mediawiki.api==== |
|||
这个模块提供了一系列方法用于简化API请求。使用这一模块时,需要首先建立一个mw.Api对象,常用语法为<code lang="js">const api = new mw.Api();</code>。以下列举这个mw.Api对象常用的方法,没有出现在以下列表中的方法可能不仅是不推荐使用,而是因为未适配中文的繁简转换而不应在LLWiki使用。 |
|||
*api.get(),这是最基础的两个方法之一,用于提交类型为GET的Ajax请求,参数基本与api.php的参数一致,区别在于返回的格式已经限定为JSON对象,即可省略参数<code lang="js">{action: 'query', format: "json"}</code>。API请求的参数列表详见[[mw:API:Main_page/zh|API文档]],这里特别推荐一下generator参数<ref>[[mw:API:Query/zh|API文档(action = query)]]</ref>的强大功能和<code lang="js">{formatversion: 2}</code>这个参数。 |
|||
*api.post(),这是最基础的两个方法之一,用于提交类型为POST的Ajax请求,用法与api.get()方法高度相似。一般情形下,<code lang="js">{action: 'query'}</code>的请求应该使用api.get()方法以充分利用浏览器缓存等优点;但如果请求的数据量过大,可能不得不使用api.post()方法代替。 |
|||
*api.postWithToken(),提交改动时一般使用这个快捷方法而非传统的api.post(),但在很多情形下都可以替换为下述更为方便的方法,只有用于<code lang="js">{action: 'patrol'}</code>时难以替代。 |
|||
*api.postWithEditToken(),相当于<code lang="js">api.postWithToken('csrf', params)</code>,主要用于提交编辑。大部分情况下不推荐使用api.edit()方法替代,因为api.edit()在大多数应用场合会造成重复而不必要的<code lang="js">{action: 'query', prop: 'revisions'}</code>请求。为了避免编辑冲突,在LLWiki请尽可能使用[[#LLWiki添加的全局变量和方法|mw.safeEdit()]]方法。另外在建立新页面(<code lang="js">{createonly: 1}</code>或直接应用api.create()方法)时,请务必先检查对应的繁简中文标题是否已经存在。 |
|||
*api.newSection(),这个方法相比api.postWithEditToken()可以进一步简化添加新章节的代码。 |
|||
*api.rollback(),相当于<code lang="js">api.postWithToken('rollback', params)</code>,用于回退。 |
|||
*api.watch(),相当于<code lang="js">api.postWithToken('watch', params)</code>,用于监视。 |
|||
*api.unwatch(),相当于<code lang="js">api.postWithToken('watch', params)</code>,用于取消监视。 |
|||
*api.upload(),相当于api.postWithEditToken()的<code lang="js">{action: 'upload'}</code>。注意这个方法只能上传本地文件,需要通过url上传的请使用api.postWithEditToken()方法。 |
|||
*api.parse(),用于解析HTML的快捷方法,常用于生成预览。如果要获得现存页面的HTML,还需要加载mediawiki.Title,此时建议可以直接使用标准的api.get()方法代替。 |
|||
====mediawiki.util==== |
|||
mediawiki.util提供了很多非常方便的方法,可以用于满足形形色色的需要。这个模块会在加载很多其他模块时加载,如mediawiki.api、mediawiki.Title和mediawiki.Uri等。 |
|||
*mw.util.addCSS(),相比mw.loader.addStyleTag()方法,因为返回值是一个StyleSheet对象而更便于后续动态操作。 |
|||
*mw.util.addPortletLink(),实际上并不如直接使用jQuery自由度更大,但这个方法可能会出现在一些从其他维基导入的小工具里,不推荐使用。 |
|||
*mw.util.debounce(),这个方法用于降低一个函数被调用的频率,常见的比如scroll事件。 |
|||
*mw.util.escapeRegExp(),mw.util还有其他的转义方法<ref>[https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.util mw.util文档]</ref>,但应用较少,不再赘述。 |
|||
*mw.util.getParamValue(),提取php参数,能够满足可能存在的各种奇怪情形,不建议使用自己写的正则匹配替代。 |
|||
*mw.util.getUrl(),获取页面对应的相对网址,一般来说使用<code lang="js">mw.config.get('wgScript') + '/' + pageName</code>即可。但如果页面名称中含需要转义的字符(如<code>?</code>和<code>&</code>),使用这个方法还是挺方便的。 |
|||
*mw.util.wikiUrlencode(),非常好用的方法,相比encodeURIComponent不会转义<code>:</code>和<code>/</code>,相比encodeURI则增加了对<code>?</code>和<code>&</code>的转义,是转义页面名称的最佳选择,同时在用做url时也比mw.util.getUrl()方法有更大的自由度。 |
|||
====mediawiki.Uri==== |
|||
除了可以替代mw.util.getParamValue()方法用于获得URI的各项参数,mediawiki.Uri还可以方便地修改或生成URI。使用时首先需要应用<code lang="js">const uri = new mw.Uri(str, options);</code>语法来构建一个mw.Uri对象,强烈推荐在options中设置<code lang="js">{overrideKeys: true}</code>以免后续出现未预期的JS语法错误。 |
|||
*uri.fragment,获得<code>#</code>后的章节名。 |
|||
*uri.host,在LLWiki总是为<code lang="js">'llwiki.org'</code>。 |
|||
*uri.path,在LLWiki的内容页面一般总是为<code lang="js">'/zh'</code>或<code lang="js">'/mediawiki/index.php'</code>(两者等效)。 |
|||
*uri.protocol,在LLWiki总是为<code lang="js">'https'</code>。 |
|||
*uri.query,包含了所有php参数的JS对象,在规定了<code lang="js">{overrideKeys: true}</code>时每个值都是字符串,否则重复参数的值为数组。 |
|||
*uri.clone(),复制mw.Uri对象。 |
|||
*<code lang="js">uri.extend({key: value})</code>,添加或覆盖php参数,这在URI以<code>#</code>结尾时非常方便。如果需要删除php参数的话,可以直接使用<code lang="js">delete uri.query.param</code>的语法。 |
|||
*uri.getQueryString(),获得整个php请求字符串。 |
|||
*uri.getRelativePath(),获得相对地址。 |
|||
*uri.toString(),获得包含协议的绝对地址。 |
|||
====mediawiki.Title==== |
|||
彻底解决关于页面名称或文件名称的各种烦恼,包括大小写、空格/下划线、命名空间别名等等。通常用法为先使用<code lang="js">const title = new mw.Title(str);</code>的语法构建一个mw.Title对象。与mw.util的很多方法以及<code lang="js">new mw.Uri()</code>不同,<code lang="js">new mw.Title(str)</code>不会以当前页面作为默认参数。因为未统一大小写、空格/下划线等,请勿直接访问title.title属性,而是根据需要使用下列方法。 |
|||
*title.getExtension(),获取文件名的扩展名。 |
|||
*title.getFragment(),如果页面名称中含<code>#</code>,获取章节名。也可以直接使用title.fragment属性访问。 |
|||
*title.getMain(),获取页面名,首字母大写,空格替换为下划线。 |
|||
*title.getMainText(),获取页面名,首字母大写,下划线被替换为空格。 |
|||
*title.getName(),获取文件名,不含扩展名,首字母大写,空格替换为下划线。 |
|||
*title.getNameText(),获取文件名,不含扩展名,首字母大写,下划线替换为空格。 |
|||
*title.getNamespaceId(),获取命名空间,能识别一切别名。也可以直接使用title.namespace属性访问。 |
|||
*title.getNamespacePrefix(),获取标准命名空间前缀,含<code>:</code>。 |
|||
*title.toString(),获取完整页面名称,命名空间使用标准前缀,不含<code>#</code>,空格替换为下划线。 |
|||
*title.toText(),相比title.toString()方法,下划线替换为空格。 |
|||
*<code>title.getRelativeText(nsid)</code>,相比title.toText()方法,会命名空间编号匹配时移除命名空间前缀。 |
|||
*title.getSubjectPage(),生成讨论页对应的主页面的mw.Title对象。 |
|||
*title.getTalkPage(),生成对应的讨论页的mw.Title对象。 |
|||
*title.getUrl(),生成地址,可以添加JS对象格式的php参数。 |
|||
*title.isTalkPage(),是否是讨论页。 |
|||
此外,mediawiki.Title还有一些静态方法用于生成mw.Title对象。 |
|||
*<code>mw.Title.makeTitle(nsid, title)</code>,给定命名空间编号和标题生成对象。不存在的命名空间会报错。仅当命名空间为0时,会根据标题生成正确的命名空间。 |
|||
*<code>mw.Title.newFromFileName(filename)</code>,给定文件名生成对象。 |
|||
*<code>mw.Title.newFromImg(node)</code>,给定<code lang="html"><img></code>节点或对应的jQuery对象生成mw.Title对象。 |
|||
*<code>mw.Title.newFromText(title, nsid)</code>,相比mw.Title.makeTitle()方法,错误的命名空间编号也不会报错,且当标题含命名空间前缀时总是覆盖第二个命名空间参数。 |
|||
====mediawiki.storage==== |
|||
mediawiki.storage提供了处理localStorage或sessionStorage的便利方法。注意出于安全性的考虑,请勿使用localStorage存储用户的个人信息。mw.storage对象对应localStorage,mw.storage.session对象对应sessionStorage,这两个对象拥有相同的方法,所以以下只介绍mw.storage对象。 |
|||
*mw.storage.get(),相当于localStorage.getItem()方法,所以使用价值不高。 |
|||
*mw.storage.set(),相当于localStorage.setItem()方法,所以使用价值不高。 |
|||
*mw.storage.remove(),相当于localStorage.removeItem()方法。 |
|||
*mw.storage.getObject(),相当于<code lang="js">JSON.parse( localStorage.getItem(key) )</code>。 |
|||
*mw.storage.setObject(),相当于<code lang="js">localStorage.setItem(key, JSON.stringify(value))</code>。 |
|||
====user.options==== |
|||
用于方便地获取用户设置。 |
|||
*mw.user.options.values,存儲了所有用戶設置。 |
|||
*mw.user.options.get()方法,用於獲取特定用戶設置。比如想獲取用戶有無啟用某一小工具,可以使用<code lang="js">mw.user.options.get( 'gadget-name' )</code>方法。如果不想加載user.options模塊,也可以使用<code lang="js">['loaded', 'loading', 'ready'].includes( mw.loader.getState( 'ext.gadget.name' ) )</code>代替,但兩者會因手動加載小工具(如<code lang="js">mw.loader.load( 'ext.gadget.name' )</code>或在手機版檢查僅在桌面版註冊的小工具而產生差異。 |
|||
下表整理了一些JS中常用的用戶設置,完整列表請參閱[[mw:Manual:$wgDefaultUserOptions/zh|MediaWiki]]。 |
|||
{| class="wikitable" |
|||
! 設置名 !! 說明 |
|||
|- |
|||
| date || 日期格式 |
|||
|- |
|||
| timecorrection || 時區 |
|||
|- |
|||
| multimediaview-enable || 啟用媒體查看器 |
|||
|- |
|||
| diffonly || 差異下方不顯示頁面內容 |
|||
|- |
|||
| norollbackdiff || 回退不顯示差異 |
|||
|- |
|||
| showhiddencats || 顯示隱藏分類 |
|||
|- |
|||
| numberheadings || 標題自動編號 |
|||
|- |
|||
| showrollbackconfirmation || 回退確認 |
|||
|- |
|||
| editsectiononrightclick || 右鍵段落編輯 |
|||
|- |
|||
| editondblclick || 雙擊編輯 |
|||
|- |
|||
| minordefault || 默認小編輯 |
|||
|- |
|||
| useeditwarning || 提示未保存的編輯 |
|||
|- |
|||
| usebetatoolbar || 使用WikiEditor的增強工具欄 |
|||
|- |
|||
| previewontop || 在編輯框上方顯示預覽 |
|||
|- |
|||
| uselivepreview || Ajax預覽 |
|||
|- |
|||
| extendwatchlist || 監視列表顯示所有更改 |
|||
|- |
|||
| rcenhancedfilters-disable || 禁用最近更改過濾器 |
|||
|- |
|||
| wlenhancedfilters-disable || 禁用監視列表過濾器 |
|||
|} |
|||
====jquery.makeCollapsible==== |
|||
用於摺疊<code lang="css">.mw-collapsible</code>類,使用語法非常簡單。 |
|||
====jquery.tablesorter==== |
|||
用於<code lang="css">table.sortable</code>的排序,使用語法非常簡單。 |
|||
====jquery.textSelection==== |
|||
用於快速處理<code lang="css">textarea</code>相關的操作。比如CharInsert擴展就是主要基於這個模塊開發的。 |
|||
*<code>textSelection(command, [options])</code>方法,以下所有指令均借助這一方法執行。 |
|||
*<code lang="js">'encapsulateSelection'</code>,在選中的文字前後插入文字。 |
|||
*<code lang="js">'getCaretPosition'</code>,獲取光標位置。 |
|||
*<code lang="js">'getSelection'</code>,獲取選中文字。 |
|||
*<code lang="js">'replaceSelection'</code>,替換選中文字。 |
|||
*<code lang="js">'scrollToCaretPosition'</code>,滾動到光標位置。 |
|||
*<code lang="js">'setSelection'</code>,設置選中區域。 |
|||
====jquery.client==== |
|||
用於查詢用戶設備和瀏覽器的相關信息,相比直接使用navigator,這個模塊使用起來更加簡便和友好。这个模块会在加载mediawiki.util时加载。 |
|||
*<code lang="js">const profile = $.client.profile();</code>,以對象的形式輸出設備和瀏覽器信息。 |
|||
*profile.platform,可識別的設備類型:iphone、linux、mac、win。 |
|||
*profile.name,可識別的瀏覽器類型:android、chrome(包括手機chrome、edge、opera等)、iphone、edge(舊版edge)、firefox(包括手機firefox)、opera(舊版opera)、safari等。 |
|||
*profile.layout,可識別的引擎類型:edge、gecko、konqueror、opera、trident、webkit。 |
|||
====jquery.color==== |
|||
可以進行CSS顏色的十六進制、RGB和HSL的轉換或計算亮度,但因為這個模塊在手機版未註冊,請謹慎使用。如確有必要在手機版調用此模塊,請聯繫有後台訪問權限的管理人員。 |
|||
====jquery.ui==== |
|||
====jquery.tipsy==== |
|||
用於統一tooltip的顯示樣式,使用語法非常簡單,同時效果也相比一些瀏覽器的默認行為更加美觀和醒目。然而這個模塊並未在手機版註冊,同時對窄屏的適配也欠佳,因此請替換為[[#LLWiki添加的全局變量和方法|mw.tipsy()方法]]。 |
|||
====jquery.chosen==== |
|||
用於將<code lang="css">select</code>元素轉化爲combo box,語法非常簡單,但該模塊未在手機版註冊,請替換為OO.ui.ComBoxInputWidget對象。 |
|||
====jquery.confirmable==== |
|||
用於以內聯形式添加一個確認步驟,需要根據使用場所調整需要的CSS,也因此用起來相對繁瑣。另外這個模塊也未在手機版註冊,請替換為[[#LLWiki添加的全局變量和方法|mw.confirm()方法]]。 |
|||
====oojs-ui-core==== |
|||
对于各种用于用户交互的HTML元素,如<button>、<select>、<input>等,不同浏览器往往会默认添加不同的样式。为了统一这些表单元素的外观,MediaWiki的界面UI大多基于OOUI设计,oojs-ui-core则包含了OOUI的最基本元素。这些元素往往借助<div>等基本HTML元素和CSS/JavaScript模拟出表单元素的效果。下表列出oojs-ui-core中供直接使用的对象实例: |
|||
{| class="wikitable" |
|||
! 对象实例 !! 说明 |
|||
|- |
|||
| ActionFieldLayout || 包含一个输入元素、一个按钮和一个可选的帮助信息 |
|||
|- |
|||
| ButtonGroupWidget || 可包含一组ButtonWidget |
|||
|- |
|||
| ButtonInputWidget || 用于FormLayout的按钮 |
|||
|- |
|||
| ButtonWidget || 最基础的按钮 |
|||
|- |
|||
| CheckboxInputWidget || 复选框,最好置于设置为<code lang="js">{align: 'inline'}</code>的各种layout内 |
|||
|- |
|||
| CheckboxMultiSelectInputWidget || 用于FormLayout的真正意义上的“复选框” |
|||
|- |
|||
| CheckboxMultiSelectWidget || 真正意义上的“复选框” |
|||
|- |
|||
| ComboBoxInputWidget || 既可键盘输入,又可选择选项 |
|||
|- |
|||
| DecoratedOptionWidget || 用于SelectWidget的带图标的选项 |
|||
|- |
|||
| DropdownInputWidget || 用于FormLayout的下拉选单 |
|||
|- |
|||
| DropdownWidget || 下拉选单 |
|||
|- |
|||
| FieldLayout || 包含一个输入元素和标签或帮助信息 |
|||
|- |
|||
| FieldSetLayout || FieldLayout的组合 |
|||
|- |
|||
| FormLayout || 用于构建表单 |
|||
|- |
|||
| HorizontalLayout || 行内样式的layout |
|||
|- |
|||
| HtmlSnippet || 用于插入htmlString |
|||
|- |
|||
| IconWidget || 图标 |
|||
|- |
|||
| IndicatorWidget || 另一种小图标 |
|||
|- |
|||
| LabelWidget || 标签 |
|||
|- |
|||
| MultilineTextInputWidget || 相当于textarea |
|||
|- |
|||
| NumberInputWidget || 带增减按钮的输入仅限数字的文本框,由min/max/step/required设置代替validate设置 |
|||
|- |
|||
| PanelLayout || 占据整个父容器的layout |
|||
|- |
|||
| PopupButtonWidget || PopupWidget的开关 |
|||
|- |
|||
| PopupWidget || 相当于tooltip |
|||
|- |
|||
| ProgressBarWidget || 进度条 |
|||
|- |
|||
| RadioInputWidget || 一个单独的单选框,一般下不应使用 |
|||
|- |
|||
| RadioSelectInputWidget || 用于FormLayout的单选框 |
|||
|- |
|||
| RadioSelectWidget || 单选框 |
|||
|- |
|||
| SearchInputWidget || 搜索框 |
|||
|- |
|||
| SelectFileInputWidget || 上传本地文件,不可拖拽 |
|||
|- |
|||
| TextInputWidget || 文本框 |
|||
|} |
|||
====oojs-ui-windows==== |
|||
oojs-ui-windows在oojs-ui-core的基础上补充了各类对话框及相关元素。下表列出了oojs-ui-windows添加供直接使用的对象实例: |
|||
{| class="wikitable" |
|||
! 对象实例 !! 说明 |
|||
|- |
|||
| ActionWidget || 用于对话框的按钮 |
|||
|- |
|||
| Dialog || 最基础的对话框,所有对话框均必须使用WindowManager打开,且大部分无法直接使用 |
|||
|- |
|||
| MessageDialog || 消息对话框,唯一一种可直接使用的自定义对话框 |
|||
|- |
|||
| ProcessDialog || 进程对话框,无法直接使用 |
|||
|- |
|||
| WindowManager || 用来打开各种对话框 |
|||
|- |
|||
| OO.ui.alert() || 相当于window.alert(),但手机版的CSS设计有缺陷,请使用mw.notify()方法替代 |
|||
|- |
|||
| OO.ui.confirm() || 相当于window.confirm(),但返回的是Promise对象 |
|||
|- |
|||
| OO.ui.prompt() || 相当于window.prompt(),但返回的是Promise对象 |
|||
|} |
|||
====oojs-ui-widgets==== |
|||
oojs-ui-widgets在oojs-ui-core的基础上补充了一些更复杂的元素。下表列出了oojs-ui-widgets添加供直接使用的对象实例: |
|||
{| class="wikitable" |
|||
! 对象实例 !! 说明 |
|||
|- |
|||
| BookletLayout || 左侧分页布局 |
|||
|- |
|||
| ButtonMenuSelectWidget || 点击按钮展开下拉选单 |
|||
|- |
|||
| ButtonSelectWidget || 使用按钮的单选框 |
|||
|- |
|||
| IndexLayout || 分页 |
|||
|- |
|||
| MenuLayout || 同时包含了菜单和内容 |
|||
|- |
|||
| MenuTagMultiselectWidget || 使用菜单进行多选 |
|||
|- |
|||
| PopupTagMultiselectWidget || 使用气泡输入的多选 |
|||
|- |
|||
| SelectFileWidget || 选择文件 |
|||
|- |
|||
| StackLayout || 堆叠布局 |
|||
|- |
|||
| TagMultiselectWidget || 使用文本输入生成标签多选,是MenuTagMultiselectWidget和PopupTagMultiselectWidget的基础类型 |
|||
|- |
|||
| ToggleButtonWidget || 使用按钮开关 |
|||
|- |
|||
| ToggleSwitchWidget || 开关 |
|||
|} |
|||
====mediawiki.widgets==== |
|||
===LLWiki添加的全局變量和方法=== |
|||
;<code lang="js">window.wgULS(hans, [hant])</code>和<code lang="js">window.wgUCS(hans, [hant])</code><ref name="site-lib">需要加載[[mediawiki:gadget-site-lib.js|site-lib.js]]</ref> |
|||
:用于处理繁简文字信息,wgULS()用于界面语言,wgUCS()用于内容语言。为方便维护,在大量使用繁简转换的页面,请将所有繁简文字以mw.messages.set()方法的形式至于代码开头,然后在使用时以mw.msg()方法调用即可。 |
|||
;mw.gadgets |
|||
:这个对象储存了所有小工具的设置。 |
|||
;mw.request |
|||
:这个对象储存了一个mw.standardQuery()方法返回的Promise对象,即获取当前版本全文Wikitext的API请求。 |
|||
;mw.sections |
|||
:这个数组的每一项对应一个mw.sectionQuery()方法返回的Promise对象,即获取对应段落Wikitext的API请求。 |
|||
;mw.widget |
|||
:这个对象储存了小部件的执行情况,防止Ajax预览造成小部件重复执行。 |
|||
;mw.settingsDialog<ref>需要加载[[mediawiki:gadget-SettingsDialog.js|SettingsDialog.js]]</ref> |
|||
:这个对象是一个SettingsDialog类,用于小工具设置的图形界面。这个类提供了多种方法,包括:获取小工具名称(getName)、获取小工具对象(getObject)、获取小工具标签页(getPanel)、添加小工具(addTab)、生成设置对象(generateOptions)、将设置保存到localStorage(saveOptions)、还原设置(clearOptions)和导出设置(export)。用法复杂,详见[[mediawiki:gadget-SettingsDialog.js|代码页]]。 |
|||
;<code>mw.pagenamee()</code><ref name="site-lib" /> |
|||
:这个方法用于获取转义后的当前页面名称。需要mediawiki.util。 |
|||
;<code>mw.addMobileLinks(link)</code><ref name="site-lib" /> |
|||
:这个方法生成手机版菜单需要的列表构成的数组,可以随后加入DOM中。link为对象或对象数组,每一项包含链接地址href(可选)、FontAwesome图标icon(默认为[https://fontawesome.com/icons/arrow-circle-right 圆圈包裹的一个向右箭头])、文字信息text(需要手动设置繁简转换,优先级低于msg)或mw.messages的键值msg和<code><li></code>元素属性attr(可选)。 |
|||
;<code>mw.isModule(name, [flag])</code><ref name="site-lib" /> |
|||
:这个方法用于检测一个模块是否正在或已经加载。name为模块名或小工具名;flag为真时自动在小工具名name前添加前缀<code lang="js">'ext.gadget.'</code>。 |
|||
;<code>mw.apiFailure(reason, topic)</code><ref name="site-lib" /> |
|||
:这个方法用于输出一个API请求失败的气泡通知。reason为API返回的错误信息,一般来自状态为reject的API请求;topic为简短的文字说明,需要手动设置繁简转换。 |
|||
;<code>mw.timedQuery(api, params, topic)</code><ref name="site-lib" /> |
|||
:这个方法用于提交一个可自定义的API请求,并记录用时,失败时应用mw.apiFailure()方法生成气泡通知并抛出错误。api为一个mw.Api对象;params即API参数,默认已填入<code lang="js">{action: 'query', formatversion: 2}</code>,可以覆盖;topic为简短文字描述,需要手动设置繁简转换。需要mediawiki.api。 |
|||
;<code>mw.timedParse(api, params, topic)</code><ref name="site-lib" /> |
|||
:Ajax使用POST而非GET,因此适合预览大段Wikitext。params的默认设置为<code lang="js">{action: 'parse', prop: 'text', title: mw.config.get( 'wgPageName' ), disablelimitreport: 1, disableeditsection: 1, pst: 1, formatversion: 2}</code>,可以覆盖。填入page、pageid或oldid参数时请勿使用此方法,应当选用包含<code lang="js">{action: 'parse'}</code>参数的mw.timedQuery()。topic同样需要手动设置繁简转换。需要mediawiki.api。 |
|||
;<code>mw.standardQuery(api)</code><ref name="site-lib" /> |
|||
:使用mw.timedQuery()方法提交一个API请求以获取当前版本的全文Wikitext并保存至mw.request。需要mediawiki.api。 |
|||
;<code>mw.sectionQuery(api, section, [force])</code><ref name="site-lib" /> |
|||
:使用mw.timedQuery()方法提交一个API请求以获取段落Wikitext并保存至mw.sections。section为段落编号,默认为序言;为降低错误编辑历史版本的风险,想要获取历史版本的段落Wikitext时,必须手动添加为真的force参数。需要mediawiki.api。 |
|||
;<code>mw.safeEdit(api, curRevid, params, [flag])</code><ref name="site-lib" /> |
|||
:检查有无编辑冲突后提交编辑。api为mw.Api对象;curRevid为当前最新版本的编号,默认为<code lang="js">mw.config.get( 'wgCurRevisionId' )</code>;parmas为API参数,默认为<code lang="js">{action: 'edit'}</code>,可以覆盖,但原则上请勿使用这一方法执行其他操作;flag参数对应是否开启自动备份小工具,这会改变检测到编辑冲突时的错误通知。检测到编辑冲突抛出错误<code lang="js">'editConflict'</code>,API请求失败抛出错误<code lang="js">'editFailure'</code>或<code lang="js">'revisionQueryFailure'</code>。需要mediawiki.api。 |
|||
;<code>mw.safeRedirect(api, title, target, [summary])</code><ref name="site-lib" /> |
|||
:检查繁简转换后的页面是否已经存在后创建新重定向。api为mw.Api对象;title为重定向页标题;target为重定向目标页标题,默认为当前页面;summary为可选摘要。页面已存在时抛出<code lang="js">'pageExists'</code>,API请求失败时抛出<code lang="js">'createFailure'</code>或<code lang="js">'queryFailure'</code>。需要mediawiki.api。 |
|||
;<code>mw.confirm(text, [flags])</code><ref name="site-lib" /> |
|||
:借助OO.ui.confirm()方法生成一个确认对话框。text为确认提示,可以是字符串或jQuery;flags为确认键的样式数组,可选元素包括<code lang="js">'primary'</code>、<code lang="js">'progressive'</code>和<code lang="js">'destructive'</code>,其中<code lang="js">'primary'</code>不能单独生效。返回值为一个状态为resolve的Promise对象,值为真表示确认。需要oojs-ui-windows。 |
|||
;<code>mw.prompt(text, [flags], [config])</code><ref name="site-lib" /> |
|||
:借助OO.ui.prompt()方法生成一个prompt对话框。text为文字提示,可以是字符串或jQuery;flags为确认键的样式数组,可选元素包括<code lang="js">'primary'</code>、<code lang="js">'progressive'</code>和<code lang="js">'destructive'</code>,其中<code lang="js">'primary'</code>不能单独生效;config为可选的文本框设置。返回值为一个状态为resolve的Promise对象,值为<code lang="js">null</code>表示取消。需要oojs-ui-windows。 |
|||
;<code>mw.dialog(dialog, actions, $message, [$title])</code><ref name="site-lib" /> |
|||
:借助OO.ui.MessageDialog对象生成一个更复杂的对话框。dialog为预先准备的OO.ui.MessageDialog对象;actions为OO.ui.ActionWidget对象构成的数组;$message为提示信息,相比mw.confirm()方法的进步之处在于可以使用jQuery或htmlString;$title为对话框标题。返回值为点击按钮时的Promise对象。需要oojs-ui-windows。 |
|||
;<code>mw.tipsy($container, [target], [params], [$content])</code><ref name="site-lib" /> |
|||
:借助OO.ui.PopupWidget对象生成一个手机版也有效的tooltip。$container为外部容器的jQuery对象(不能是body);target为目标元素的选择器;params为建立OO.ui.PopupWidget对象时的参数,默认为<code lang="js">{padded: true, width: null, classes: ['mw-tipsy']}</code>,可以覆盖;$content为自定义的tooltip内容,默认为title或data-title属性。需要oojs-ui-core。 |
|||
;<code>mw.menu(options, [config], [unselectable])</code><ref name="site-lib" /> |
|||
:借助于OO.ui.MenuSelectWidget生成一个浮动菜单。options为选项数组,每一项包含文本text(需要手动设置繁简转换)、FontAwesome图标icon(可选)、数据data(可选)、链接href(可选)和点击事件click(可选);config为菜单设置,默认为<code lang="js">{classes: ['site-menu'], hideWhenOutOfView: false}</code>,可以覆盖;unselectable为真时,菜单不会保留之前最后一次的选择记录。这个UI方法的用法较为复杂,详见[[mediawiki:gadget-site-lib.js#L311|代码页]]。 |
|||
;<code>mw.convertTimezone(then, timezone)</code><ref name="site-lib" /> |
|||
:改变moment对象的时区。then为待处理的moment对象,默认为现在;timezone为时区的IANA名称或数值表示的UTC偏移量,需要提前检查合法性,默认为本地时区。注意这个方法的返回值不是一个真实存在的时间点,只能用于输出而不能用于进一步运算。需要moment。 |
|||
;mw.resizeLyrics()<ref>需要加載[[user:bhsd/widget/lyrics.js|Widget:Lyrics]]</ref> |
|||
:重新计算<code lang="css">.Lyrics_box</code>的大小,并调整原文和译文的排列方式。 |
|||
===JSHint=== |
|||
CodeEditor使用JSHint标注可能存在的语法问题。LLWiki會在大部分JS页面添加JSHint设置<code lang="js">/* global mw */</code>和<code lang="js">/* jshint jquery: true, bitwise: true, curly: true, latedef: 'nofunc', nonew: true, singleGroups: true, unused: true */</code><ref>[https://jshint.com/docs/options/ 新版JSHint的设置列表],注意可能存在的版本差异。</ref>。但在小部件页面,为了提示小部件JS加载在模块mediawiki和jquery之前,<code lang="js |
|||
>/* global mw */</code>和<code lang="js">/* jshint jquery: true */</code>被替换为<code lang="js">/* jshint varstmt: true */</code>。注意JSHint并不会对大多数JS模块不允许使用的ES6语法作出警告(详见[[#ResourceLoader和JS模块]]),因此请勿过度依赖这一功能来除错。另外CodeEditor安装的JSHint版本较老,无法识别ES7以上的语法,因此在代码中使用ES7语法可能会造成除错时的困难。 |
|||
===注意事项=== |
|||
==手机版== |
==手机版== |
||
===手机版解析器=== |
|||
====图片懒加载==== |
|||
===手机版CSS=== |
|||
手机版LLWiki使用Minerva Neue皮肤,与桌面版的Vector皮肤相比,不仅界面有很大差异,众多基础HTML元素也都添加了不同的CSS样式。为了适配窄屏设备,Minerva皮肤还添加了大量基于<code lang="css">@media</code>的规则,一般以设备宽度720px为分界使用不同的样式。以下着重介绍<code><table></code>和<code><img></code>这两种需要CSS修正的重灾区。 |
|||
手机版CSS很多时候依赖外层容器的<code>content</code>类来生效,与此同时<code lang="css">#mw-content-text .mw-parser-output</code>的外层结构也同样有效,设计各种基于API的快速编辑工具(如Wikiplus等)的预览界面时需要考虑。 |
|||
====表格==== |
|||
对于<code><table></code>元素及其子节点,手机版已知会自动添加以下样式: |
|||
<pre lang="css"> |
|||
table, caption, tbody, tfoot, thead, tr, th, td { |
|||
font-size: 100%; |
|||
} |
|||
table { |
|||
border-collapse: collapse; |
|||
} |
|||
.content table { |
|||
margin: 1em 0; |
|||
overflow: auto; |
|||
overflow-y: hidden; |
|||
overflow-x: auto; |
|||
} |
|||
@media only screen and (max-width: 720px) { |
|||
.content table { |
|||
display: block; |
|||
width: 100% !important; |
|||
} |
|||
} |
|||
</pre> |
|||
这里重点说明一下第二和第四条规则造成的影响。第二条规则使得表格的外层边框、行边框和单元格边框合并,可能造成一系列关于边框的CSS规则出现不符合预期的表现,尤其是<code><table></code>的<code>cellspacing</code>属性会无法生效。因此一般建议避免使用<code>cellspacing</code>这一HTML属性,改为使用CSS中的<code>border-spacing</code>。另外,在需要<code>border-spacing</code>或<code>border-radius</code>等样式时,请同时指定<code class="hljs">border-collapse: separate;</code>以使手机版生效。 |
|||
第四条规则的本意是在窄屏上<code><table></code>元素不会将页面撑得过宽,但这同时会造成外层的<code><table></code>和内层的<code><tbody></code>分离。特别是如果外层<code><table></code>规定了边框或背景色时,很容易看出样式的错误。为此一般需要主动指定<code class="hljs">display: table;</code>以修复这一问题,LLWiki有很多预定义的表格CSS类也都添加了这一规则<ref name="site-styles">[[mediawiki:gadget-site-styles.css|全站CSS]]</ref>。但这样修改的话又会重新面临过宽的表格将整个页面撑大的问题。LLWiki现定义了<code>table-wrapper</code>类<ref name="site-styles" />,用于套在宽表格外:<code lang="html"><nowiki><div class="table-wrapper"></nowiki></code>,这个外层容器会在窄屏上通过<code class="hljs">overflow-x: auto;</code>限制里面的表格宽度。 |
|||
====图片==== |
|||
====皮肤界面==== |
|||
====其他==== |
|||
===手机版JS=== |
|||
====手机版JS模块==== |
|||
==繁简转换== |
==繁简转换== |
||
===Wikitext繁简转换=== |
|||
====转换表==== |
|||
====[[Template:NoteTA]]==== |
|||
====基本手工转换语法==== |
|||
===系统消息=== |
|||
===CSS繁简转换=== |
|||
===JS繁简转换=== |
|||
==滥用过滤器== |
==滥用过滤器== |
||
==测试账户== |
==测试账户== |
||
如果管理员需要一个没有[[project:自动确认用户|自确]]权限的测试账户用于滥用过滤器测试、小工具测试等,可以临时启用[[special:abusefilter/6|6号滥用过滤器]]来移除某个测试账户的自确权限。这个滥用过滤器的使用语法非常简单,请根据样例修改为对应的用户名即可,这里不再赘述。 |
|||
==参考资料== |
|||
<references /> |
|||
[[Category:LLWiki指引]] |
[[Category:LLWiki指引]] |
於 2023年3月17日 (五) 13:29 的最新修訂
此頁面內容嚴重缺失,急需您幫忙補充!(點此編輯) 可參考同類條目添加所需內容,並從官方等可靠渠道搜集資料編寫,亦建議附上資料來源。
|
由於LLWiki使用的不是最新版本的MediaWiki系統以及MediaWiki的幫助頁面可能未得到及時和正確的更新,編輯這個頁面時請不要簡單地複製或翻譯來自MediaWiki的內容,應該在條件允許的情況下先實際測試。
全站CSS
這裡所說的全站CSS包含common.css、mobile.css和各CSS小工具,有時由於功能的相似性也會涉及用戶CSS(common.css、vector.css和minerva.css)。LLWiki暫時沒有建立針對不同用戶組的專門CSS頁面。
優先加載的CSS
一些CSS會以<link rel="stylesheet">
的形式在首次渲染前完成加載,包括common.css和各純CSS小工具,這些CSS頁面適合處理靜態HTML元素就需要的樣式。注意純CSS小工具即使在定義時規定了targets=mobile
也一定會在桌面版加載,因此手機版的專用CSS需要添加.skin-minerva
選擇器。
由於common.css本身就會優先加載,桌面版專用的全站CSS寫入該頁面即可,與手機版通用的CSS寫入gadget-site-styles.css。某個小工具專用的CSS如果需要用於靜態HTML元素,請將CSS部分單獨定義為type=styles
(可省略,但添加後方便區分)的純CSS小工具,然後以peers=<纯CSS小工具名称>
的語法添加到對應的JS小工具上。參見#小工具定義。
滯後加載的CSS
一些CSS的加載需要依賴JS,加載時機可能晚於首次渲染,包括mobile.css和除純CSS小工具以外的CSS小工具,這些CSS頁面適合處理依賴JS動態加載的HTML元素。
由於mobile.css加載滯後,靜態HTML元素需要的手機版樣式請添加.skin-minerva
選擇器後寫入gadget-site-styles.css。
CSS小工具分類
定義為type=styles
的小工具應添加純CSS小工具分類,其他CSS小工具應添加CSS小工具分類。其他分類與JS小工具一致,參見#小工具分類。
Widget(小部件)
小部件頁面格式
小部件分類
小部件JS的特殊之處
Gadget(小工具)和全站JS
這裡所涉及的JS頁面包含common.js、mobile.js和各JS小工具,有時由於功能的相似性也會涉及用戶JS(common.js、vector.js和minerva.js)。LLWiki暫時沒有建立針對不同用戶組的專門JS頁面。
ResourceLoader和JS模塊
common.js、mobile.js、用戶JS和MediaWiki:Gadgets-definition頁面定義的小工具等JS頁面會作為ResourceLoader的模塊加載,這些JS將在語法檢查和壓縮後由load.php打包下載,且可以作為mw.loader.getState()方法、mw.loader.using()方法的參數。
作為ResourceLoader的模塊加載時,不可使用ES6語法。這裡的語法指關鍵字、算符等,不包括對象原型方法,例如Object.fromEntries()
方法或new Map()
構造器仍可照常使用。下表列出一些常見的JS模塊不可使用的語法及其替代。
ES6以上語法 | 替代 |
---|---|
=> output |
function() { return output; }
|
class NewClass extends Parent { constructor(params) { super(params); } } |
function NewClass(params) { NewClass.super.call(this, params); } OO.inheritClass(NewClass, Parent); |
{key} |
{key: key}
|
`firstline secondline` |
'firstline\n' + 'secondline' |
`string${variable}` |
'string' + variable
|
[variable] = array; |
variable = array[0];
|
{key: variable} = {key: value}; |
variable = {key: value}['key'];
|
function(params = defaults) |
function() { params = params || defaults; }
|
[...iterator] |
Array.from( iterator )
|
array2 = [...array1]; |
array2 = array1.slice();
|
[...array1, ...array2] |
array1.concat( array2 )
|
[element, ...rest] = array; |
element = array[0], rest = array.slice(1);
|
let [1] |
var
|
2**3 [2] |
Math.pow(2, 3)
|
async function() [2] |
function() { return new Promise(resolve, reject); }
|
try { variable = await func(); } catch {} [2] |
func().then(function(result) { variable = result; }, function() {});
|
obj1 = {...obj2}; [2] |
obj1 = $.extend(true, {}, obj2);
|
{...object1, ...object2} [2] |
$.extend(object1, object2) 或Object.assign(object1, object2) [3]
|
不作為模塊的JS腳本
小工具定義
小工具簡介
小工具分類
MediaWiki核心模塊介紹
本章節介紹LLWiki使用或曾經使用的MediaWiki核心模塊,更完整的列表參見MediaWiki和JSDuck。
mediawiki
mediawiki是任何頁面都會預加載的兩個環境模塊之一,包含不少功能[4]。這裡只介紹LLWiki常使用的一些屬性和方法。
- mw.config
- 這個屬性提供了大量重要的站點、頁面和用戶信息[5],一般常用mw.config.get()方法獲取對應的變量值。下表整理了LLWiki常用的一些變量:
變量名 | 說明 | 手機版可用性 |
---|---|---|
skin | 皮膚 | 桌面版為「vector」,手機版為「minerva」,這也是區分桌面版和手機版的主要依據 |
wgFormattedNamespaces | 儲存了所有命名空間本地化譯名的數組,不過目前除了「模塊」都是英文 | 可用 |
wgNamespaceIds | 儲存了所有可接受的中英文命名空間名稱對應的編號,注意英文名稱中的空格都顯示為下劃線 | 可用 |
wgScript | /mediawiki/index.php ,在LLWiki也可簡化為/zh ,主要用於不同MediaWiki站點間的代碼通用,非必需且不推薦使用 |
可用 |
wgAction | index.php的action參數[6] | 相比於桌面版,手機版由於添加了Special:歷史而少了「history」這個可能值 |
wgArticleId | 內容頁面編號,不存在時值為0,可以用於判斷是否是內容頁面且頁面是否已建立 | 需要注意查看歷史和差異時值為0 |
wgCanonicalSpecialPageName | 標準化的特殊頁面名,也可被wgPageName取代,主要用於不同MediaWiki站點間的代碼通用,非必需 | 可用,而且多了「History」和"MobileDiff"等可能的取值[7] |
wgCategories | 當前閱讀的歷史版本所屬的分類,不含命名空間,下劃線顯示為空格,且總是包含隱藏分類。繁簡規則遵從實際分類頁面 | 僅LLWiki可用 |
wgCurRevisionId | 頁面最新的版本編號,不存在時值為0 | 在歷史和差異頁面不可用 |
wgIsArticle | 是否是內容頁面(包含由某個頁面的Wikitext原始碼解析生成的HTML,可能是歷史頁面和差異下方的歷史頁面) | 由於差異頁面不可同時顯示歷史頁面,此時不可用 |
wgIsRedirect | 最新版本是否是重定向頁面 | 在歷史和差異頁面不可用 |
wgIsProbablyEditable | 是否可能可以編輯 | 在歷史和差異頁面不可用 |
wgNamespaceNumber | 命名空間編號 | 在歷史和差異頁面會顯示為-1 |
wgPageContentModel | 頁面內容模型,特殊頁面為「wikitext」 | 由於歷史和差異是特殊頁面,會錯誤地顯示為「wikitext」 |
wgPageName | 頁面名稱,空格顯示為下劃線 | 在歷史和差異頁面不可用 |
wgRedirectFrom | 跳轉自重定向時為對應的重定向頁,空格顯示為下劃線 | 可用 |
wgRelevantPageName | 關聯的頁面名稱,空格顯示為下劃線 | 可以用於歷史和差異頁面,此時效果與桌面版一致 |
wgRelevantArticleId | 關聯的內容頁面編號,不存在時值為0 | 可以用於歷史和差異頁面,此時效果與桌面版一致 |
wgRelevantUserName | 關聯的用戶名 | 使用者貢獻頁面不可用 |
wgRelevantPageIsProbablyEditable | 關聯的頁面是否可能可以編輯 | 可以用於歷史和差異頁面,此時效果與桌面版一致 |
wgRestrictionEdit | 編輯保護,不存在的頁面(含受保護的標題)或特殊頁面為null ,存在的內容頁面受全保護時為["sysop"] ,受半保護時為["autoconfirmed"] ,未保護為[] ;不包含命名空間保護和級聯保護 |
在歷史和差異頁面不可用,另外未保護的內容頁面為["*"]
|
wgRestrictionMove | 移動保護,不存在的頁面或特殊頁面為null ,存在的內容頁面受全保護時為["sysop"] ,受半保護時為["autoconfirmed"] ,未保護為[] ;不包含命名空間保護和級聯保護 |
在歷史和差異頁面不可用 |
wgRevisionId | 當前顯示的頁面版本的編號,不存在時值為0。注意和index.php的oldid參數可能不同 | 由於差異頁面不可同時顯示歷史頁面,此時不可用 |
wgTitle | 不含命名空間的頁面名稱,下劃線顯示為空格 | 在歷史和差異頁面不可用 |
wgUserEditCount | 當前用戶的編輯次數 | 可用 |
wgUserGroups | 當前用戶所屬的用戶組,未登入時為["*"] |
可用 |
wgUserLanguage | 當前用戶使用的界面語言 | 可用 |
wgUserName | 當前用戶的用戶名,下劃線顯示為空格 | 可用 |
wgUserRegistration | 當前用戶的註冊時間,顯示為毫秒數;可以使用mw.user.getRegistration()方法替代,該方法會生成Date對象 | 可用 |
wgUserVariant | 當前用戶閱讀頁面時的內容語言,在不可更改內容語言的頁面總是為該用戶的默認內容語言 | 可用 |
wgDiffOldId | 差異頁面位於左側的版本的編號 | 不可用 |
wgDiffNewId | 差異頁面位於右側的版本的編號 | 不可用 |
- mw.hook()
- 這個方法是LLWiki建立異步JS框架的重要一環。常用以下兩個方法:
mw.hook(hook).fire(data)
: 用於喚起一個Hook事件,其中data為傳遞給事件處理程序的可選參數。mw.hook(hook).add(handler)
: 用於處理一個Hook事件,handler為該事件處理函數,參數傳遞自mw.hook().fire()
方法。
- 這個方法應與jQuery的event delegation和各Promise對象結合使用,以在恰當的時機執行恰當的函數。以下列舉LLWiki常用的Hook事件。
Hook名稱 | 說明 |
---|---|
MediaWiki預定義的Hook | |
postEdit | 一次非空編輯提交成功,一般發生在自動重載頁面後,可以搭配mw.config.get( 'wgPostEdit' ) 。需要注意各類編輯小工具提交編輯後的頁面重載均未適配這個事件
|
structuredChangeFilters.ui.initialized | 近期變更、相關變更和監視清單頁面的過濾器加載完成,一般至多發生一次 |
wikipage.categories | 頁面下方的div#catlinks 加載完成。特殊頁面或沒有添加任何分類時也能觸發,因為此時#catlinks 仍然存在只是隱藏起來
|
wikipage.collapsibleContent | 某個或某組mw-collapsible 類的元素添加摺疊JS完成
|
wikipage.content | 最常用的Hook,表示頁面內容(一般即div#mw-content-text )加載完成,幾乎無處不在,與$.ready 最大的區別在於這個事件可能多次觸發
|
wikipage.diff | 差異(一般即table.diff )加載完成
|
wikipage.editform | 編輯區加載完成,需要注意此時WikiEditor的工具欄可能尚未加載完成 |
codeEditor.configure | 切換至CodeEditor |
LLWiki定義的Hook | |
code.prettify | 代碼高亮完成 |
codemirror.config | CodeMirror擴展的設置下載完成 |
hotcat.ready | HotCat小工具加載完成 |
local.comments | 簽名時間替換為本地時區 |
to.bottom | 添加滾動至底部的按鈕 |
transclusion.preview | 用於預覽嵌入頁面的編輯區加載完成 |
wikiplus.dialog | 打開Wikiplus小工具的對話框 |
- mw.loader
- mw.loader包含了很多用於ResourceLoader的方法。
- mw.loader.addStyleTag(),用於在
header
的末尾插入一個<style>
。由於返回的是一個HTML元素,後續操作不如mw.util.addCSS()返回的StyleSheet對象方便,但在不需要後續操作的場合可以不用加載mediawiki.util模塊。由於mediawiki.util在LLWiki的廣泛使用,這個方法幾乎沒有任何優點。 - mw.loader.getScript(),用於加載外部JS腳本,相比mw.loader.load()方法優點在於會返回一個Promise對象。
- mw.loader.getState(),用於獲取模塊的當前狀態,不可用的模塊返回
null
,可用但未加載的模塊返回'registered'
,可用且正在加載的模塊可能返回'loaded'
或'loading'
,已加載完成的模塊返回'ready'
。注意加載完成的模塊未必已經執行完。 - mw.loader.load(),用於加載模塊、其他JS或其他CSS,加載模塊時參數為模塊名或一個模塊名構成的數組,加載JS或CSS時填寫url,加載CSS還需要額外填寫第二參數
'text/css'
。缺點在於不會返回一個Promise對象。 - mw.loader.using(),用於加載模塊,相比mw.loader.load()方法優點在於會返回一個Promise對象,任一模塊加載失敗即返回rejected。
- mw.loader.addStyleTag(),用於在
- mw.notify()
- 調用這個方法可以在桌面版的右上角、手機版的上方顯示一個泡泡通知。LLWiki一般使用這個方法取代window.alert()或OO.ui.alert()。
- 方法
mw.notify(message, options)
接受兩個參數。第一個必需參數message
指定通知內容,可以是字符串、HTML元素對象或元素對象數組、jQuery對象或mw.message對象;第二個可選參數options
則指定自定義選項,是一個JS對象。 options
中可自定義的選項有:autoHide
:布爾值,決定通知是否會自行消失。默認為true
。autoHideSeconds
:如果啟用了autoHide
(如默認情形),則指定通知自行消失的時間。默認為'short'
(5秒),可以指定為'long'
(30秒)。tag
:字符串,指定通知的標籤,類似於HTML的ID。如果發送多個擁有同一個tag的通知,會導致之前的通知被後來的在原位覆蓋。title
:標題。如果指定,則會於內容上方加粗顯示。type
:字符串,指定通知的種類。除默認效果外其他可選類型為'success'
、'warn'
和'error'
。
- mw.now()
- 這個方法理論上和Date.now()差不多,但實際測試表明和Date.now()的取值不同,因此請勿混合使用。非必需,基本可以完全被Date.now()替換。
- mw.messages
- 用於改善代碼結構,在代碼開頭使用mw.messages.set()方法結合wgULS()和wgUCS()設置自定義消息的繁簡名稱,然後使用mw.msg()方法即可調用。使用這一方法時,還能以
$1
的形式設置待定參數,或使用部分解析器函數。
jquery
jquery是任何頁面都會預加載的兩個環境模塊之一,尤其在DOM操作和Ajax請求方面功能強大,非常推薦在JS編程之前預先熟悉API文檔。考慮到mw.loader已經集成了不少的常用Ajax方法,這裡主要推薦熟練掌握DOM相關的內容,包括事件、DOM操作、選擇器和遍歷。特別需要提醒的是濫用htmlString有造成XSS的風險,因此請儘量使用如$('<p>', {html: $('<a>', {text: '文字', href: 'https://llwiki.org'})})
或$('<p>').append( $('<a>').text('文字').attr('href', 'https://llwiki.org') )
等語法進行規避。
因未被mw.loader包含而可能用到的Ajax方法主要為$.getJSON()
,需要注意在MW的默認設置下調用jQuery的Ajax方法必須手動設置{cache: true}
。
另外jQuery也提供了一些工具方法,可以用於緩解ResourceLoader的JS模塊不允許使用ES6語法的問題,或是方便鍵值對相關的語句的書寫,或是方便連鎖。比如用$.extend()
方法代替...
算符、用$.each(obj, (key, val) => {})
方法代替for (const key in obj) {}
等。
應用jQuery時可能出現的一些常見錯誤列舉如下:
- 混淆
.attr()
方法和.prop()
方法。 - 混淆jQuery對象的
.data()
方法和HTML元素的.dataset
屬性。 - 使用
.toggle()
、.fadeToggle()
等方法時不慎破壞較複雜的CSS布局。 - 錯誤使用
.remove()
、.clone()
等方法造成丟失數據和事件處理程序。 - 混淆
event.target
、event.currentTarget
、event.delegateTarget
和this
關鍵字。 - 混淆
$.when()
方法和Promise.all()
方法的參數格式和回調函數。
mediawiki.api
這個模塊提供了一系列方法用於簡化API請求。使用這一模塊時,需要首先建立一個mw.Api對象,常用語法為const api = new mw.Api();
。以下列舉這個mw.Api對象常用的方法,沒有出現在以下列表中的方法可能不僅是不推薦使用,而是因為未適配中文的繁簡轉換而不應在LLWiki使用。
- api.get(),這是最基礎的兩個方法之一,用於提交類型為GET的Ajax請求,參數基本與api.php的參數一致,區別在於返回的格式已經限定為JSON對象,即可省略參數
{action: 'query', format: "json"}
。API請求的參數列表詳見API文檔,這裡特別推薦一下generator參數[8]的強大功能和{formatversion: 2}
這個參數。 - api.post(),這是最基礎的兩個方法之一,用於提交類型為POST的Ajax請求,用法與api.get()方法高度相似。一般情形下,
{action: 'query'}
的請求應該使用api.get()方法以充分利用瀏覽器緩存等優點;但如果請求的數據量過大,可能不得不使用api.post()方法代替。 - api.postWithToken(),提交改動時一般使用這個快捷方法而非傳統的api.post(),但在很多情形下都可以替換為下述更為方便的方法,只有用於
{action: 'patrol'}
時難以替代。 - api.postWithEditToken(),相當於
api.postWithToken('csrf', params)
,主要用於提交編輯。大部分情況下不推薦使用api.edit()方法替代,因為api.edit()在大多數應用場合會造成重複而不必要的{action: 'query', prop: 'revisions'}
請求。為了避免編輯衝突,在LLWiki請儘可能使用mw.safeEdit()方法。另外在建立新頁面({createonly: 1}
或直接應用api.create()方法)時,請務必先檢查對應的繁簡中文標題是否已經存在。 - api.newSection(),這個方法相比api.postWithEditToken()可以進一步簡化添加新章節的代碼。
- api.rollback(),相當於
api.postWithToken('rollback', params)
,用於回退。 - api.watch(),相當於
api.postWithToken('watch', params)
,用於監視。 - api.unwatch(),相當於
api.postWithToken('watch', params)
,用於取消監視。 - api.upload(),相當於api.postWithEditToken()的
{action: 'upload'}
。注意這個方法只能上傳本地文件,需要通過url上傳的請使用api.postWithEditToken()方法。 - api.parse(),用於解析HTML的快捷方法,常用於生成預覽。如果要獲得現存頁面的HTML,還需要加載mediawiki.Title,此時建議可以直接使用標準的api.get()方法代替。
mediawiki.util
mediawiki.util提供了很多非常方便的方法,可以用於滿足形形色色的需要。這個模塊會在加載很多其他模塊時加載,如mediawiki.api、mediawiki.Title和mediawiki.Uri等。
- mw.util.addCSS(),相比mw.loader.addStyleTag()方法,因為返回值是一個StyleSheet對象而更便於後續動態操作。
- mw.util.addPortletLink(),實際上並不如直接使用jQuery自由度更大,但這個方法可能會出現在一些從其他維基導入的小工具里,不推薦使用。
- mw.util.debounce(),這個方法用於降低一個函數被調用的頻率,常見的比如scroll事件。
- mw.util.escapeRegExp(),mw.util還有其他的轉義方法[9],但應用較少,不再贅述。
- mw.util.getParamValue(),提取php參數,能夠滿足可能存在的各種奇怪情形,不建議使用自己寫的正則匹配替代。
- mw.util.getUrl(),獲取頁面對應的相對網址,一般來說使用
mw.config.get('wgScript') + '/' + pageName
即可。但如果頁面名稱中含需要轉義的字符(如?
和&
),使用這個方法還是挺方便的。 - mw.util.wikiUrlencode(),非常好用的方法,相比encodeURIComponent不會轉義
:
和/
,相比encodeURI則增加了對?
和&
的轉義,是轉義頁面名稱的最佳選擇,同時在用做url時也比mw.util.getUrl()方法有更大的自由度。
mediawiki.Uri
除了可以替代mw.util.getParamValue()方法用於獲得URI的各項參數,mediawiki.Uri還可以方便地修改或生成URI。使用時首先需要應用const uri = new mw.Uri(str, options);
語法來構建一個mw.Uri對象,強烈推薦在options中設置{overrideKeys: true}
以免後續出現未預期的JS語法錯誤。
- uri.fragment,獲得
#
後的章節名。 - uri.host,在LLWiki總是為
'llwiki.org'
。 - uri.path,在LLWiki的內容頁面一般總是為
'/zh'
或'/mediawiki/index.php'
(兩者等效)。 - uri.protocol,在LLWiki總是為
'https'
。 - uri.query,包含了所有php參數的JS對象,在規定了
{overrideKeys: true}
時每個值都是字符串,否則重複參數的值為數組。 - uri.clone(),複製mw.Uri對象。
uri.extend({key: value})
,添加或覆蓋php參數,這在URI以#
結尾時非常方便。如果需要刪除php參數的話,可以直接使用delete uri.query.param
的語法。- uri.getQueryString(),獲得整個php請求字符串。
- uri.getRelativePath(),獲得相對地址。
- uri.toString(),獲得包含協議的絕對地址。
mediawiki.Title
徹底解決關於頁面名稱或文件名稱的各種煩惱,包括大小寫、空格/下劃線、命名空間別名等等。通常用法為先使用const title = new mw.Title(str);
的語法構建一個mw.Title對象。與mw.util的很多方法以及new mw.Uri()
不同,new mw.Title(str)
不會以當前頁面作為默認參數。因為未統一大小寫、空格/下劃線等,請勿直接訪問title.title屬性,而是根據需要使用下列方法。
- title.getExtension(),獲取文件名的擴展名。
- title.getFragment(),如果頁面名稱中含
#
,獲取章節名。也可以直接使用title.fragment屬性訪問。 - title.getMain(),獲取頁面名,首字母大寫,空格替換為下劃線。
- title.getMainText(),獲取頁面名,首字母大寫,下劃線被替換為空格。
- title.getName(),獲取文件名,不含擴展名,首字母大寫,空格替換為下劃線。
- title.getNameText(),獲取文件名,不含擴展名,首字母大寫,下劃線替換為空格。
- title.getNamespaceId(),獲取命名空間,能識別一切別名。也可以直接使用title.namespace屬性訪問。
- title.getNamespacePrefix(),獲取標準命名空間前綴,含
:
。 - title.toString(),獲取完整頁面名稱,命名空間使用標準前綴,不含
#
,空格替換為下劃線。 - title.toText(),相比title.toString()方法,下劃線替換為空格。
title.getRelativeText(nsid)
,相比title.toText()方法,會命名空間編號匹配時移除命名空間前綴。- title.getSubjectPage(),生成討論頁對應的主頁面的mw.Title對象。
- title.getTalkPage(),生成對應的討論頁的mw.Title對象。
- title.getUrl(),生成地址,可以添加JS對象格式的php參數。
- title.isTalkPage(),是否是討論頁。
此外,mediawiki.Title還有一些靜態方法用於生成mw.Title對象。
mw.Title.makeTitle(nsid, title)
,給定命名空間編號和標題生成對象。不存在的命名空間會報錯。僅當命名空間為0時,會根據標題生成正確的命名空間。mw.Title.newFromFileName(filename)
,給定文件名生成對象。mw.Title.newFromImg(node)
,給定<img>
節點或對應的jQuery對象生成mw.Title對象。mw.Title.newFromText(title, nsid)
,相比mw.Title.makeTitle()方法,錯誤的命名空間編號也不會報錯,且當標題含命名空間前綴時總是覆蓋第二個命名空間參數。
mediawiki.storage
mediawiki.storage提供了處理localStorage或sessionStorage的便利方法。注意出於安全性的考慮,請勿使用localStorage存儲用戶的個人信息。mw.storage對象對應localStorage,mw.storage.session對象對應sessionStorage,這兩個對象擁有相同的方法,所以以下只介紹mw.storage對象。
- mw.storage.get(),相當於localStorage.getItem()方法,所以使用價值不高。
- mw.storage.set(),相當於localStorage.setItem()方法,所以使用價值不高。
- mw.storage.remove(),相當於localStorage.removeItem()方法。
- mw.storage.getObject(),相當於
JSON.parse( localStorage.getItem(key) )
。 - mw.storage.setObject(),相當於
localStorage.setItem(key, JSON.stringify(value))
。
user.options
用於方便地獲取用戶設置。
- mw.user.options.values,存儲了所有用戶設置。
- mw.user.options.get()方法,用於獲取特定用戶設置。比如想獲取用戶有無啟用某一小工具,可以使用
mw.user.options.get( 'gadget-name' )
方法。如果不想加載user.options模塊,也可以使用['loaded', 'loading', 'ready'].includes( mw.loader.getState( 'ext.gadget.name' ) )
代替,但兩者會因手動加載小工具(如mw.loader.load( 'ext.gadget.name' )
或在手機版檢查僅在桌面版註冊的小工具而產生差異。
下表整理了一些JS中常用的用戶設置,完整列表請參閱MediaWiki。
設置名 | 說明 |
---|---|
date | 日期格式 |
timecorrection | 時區 |
multimediaview-enable | 啟用媒體查看器 |
diffonly | 差異下方不顯示頁面內容 |
norollbackdiff | 回退不顯示差異 |
showhiddencats | 顯示隱藏分類 |
numberheadings | 標題自動編號 |
showrollbackconfirmation | 回退確認 |
editsectiononrightclick | 右鍵段落編輯 |
editondblclick | 雙擊編輯 |
minordefault | 默認小編輯 |
useeditwarning | 提示未保存的編輯 |
usebetatoolbar | 使用WikiEditor的增強工具欄 |
previewontop | 在編輯框上方顯示預覽 |
uselivepreview | Ajax預覽 |
extendwatchlist | 監視列表顯示所有更改 |
rcenhancedfilters-disable | 禁用最近更改過濾器 |
wlenhancedfilters-disable | 禁用監視列表過濾器 |
jquery.makeCollapsible
用於摺疊.mw-collapsible
類,使用語法非常簡單。
jquery.tablesorter
用於table.sortable
的排序,使用語法非常簡單。
jquery.textSelection
用於快速處理textarea
相關的操作。比如CharInsert擴展就是主要基於這個模塊開發的。
textSelection(command, [options])
方法,以下所有指令均藉助這一方法執行。'encapsulateSelection'
,在選中的文字前後插入文字。'getCaretPosition'
,獲取光標位置。'getSelection'
,獲取選中文字。'replaceSelection'
,替換選中文字。'scrollToCaretPosition'
,滾動到光標位置。'setSelection'
,設置選中區域。
jquery.client
用於查詢用戶設備和瀏覽器的相關信息,相比直接使用navigator,這個模塊使用起來更加簡便和友好。這個模塊會在加載mediawiki.util時加載。
const profile = $.client.profile();
,以對象的形式輸出設備和瀏覽器信息。- profile.platform,可識別的設備類型:iphone、linux、mac、win。
- profile.name,可識別的瀏覽器類型:android、chrome(包括手機chrome、edge、opera等)、iphone、edge(舊版edge)、firefox(包括手機firefox)、opera(舊版opera)、safari等。
- profile.layout,可識別的引擎類型:edge、gecko、konqueror、opera、trident、webkit。
jquery.color
可以進行CSS顏色的十六進制、RGB和HSL的轉換或計算亮度,但因為這個模塊在手機版未註冊,請謹慎使用。如確有必要在手機版調用此模塊,請聯繫有後台訪問權限的管理人員。
jquery.ui
jquery.tipsy
用於統一tooltip的顯示樣式,使用語法非常簡單,同時效果也相比一些瀏覽器的默認行為更加美觀和醒目。然而這個模塊並未在手機版註冊,同時對窄屏的適配也欠佳,因此請替換為mw.tipsy()方法。
jquery.chosen
用於將select
元素轉化爲combo box,語法非常簡單,但該模塊未在手機版註冊,請替換為OO.ui.ComBoxInputWidget對象。
jquery.confirmable
用於以內聯形式添加一個確認步驟,需要根據使用場所調整需要的CSS,也因此用起來相對繁瑣。另外這個模塊也未在手機版註冊,請替換為mw.confirm()方法。
oojs-ui-core
對於各種用於用戶交互的HTML元素,如<button>、<select>、<input>等,不同瀏覽器往往會默認添加不同的樣式。為了統一這些表單元素的外觀,MediaWiki的界面UI大多基於OOUI設計,oojs-ui-core則包含了OOUI的最基本元素。這些元素往往藉助<div>等基本HTML元素和CSS/JavaScript模擬出表單元素的效果。下表列出oojs-ui-core中供直接使用的對象實例:
對象實例 | 說明 |
---|---|
ActionFieldLayout | 包含一個輸入元素、一個按鈕和一個可選的幫助信息 |
ButtonGroupWidget | 可包含一組ButtonWidget |
ButtonInputWidget | 用於FormLayout的按鈕 |
ButtonWidget | 最基礎的按鈕 |
CheckboxInputWidget | 複選框,最好置於設置為{align: 'inline'} 的各種layout內
|
CheckboxMultiSelectInputWidget | 用於FormLayout的真正意義上的「複選框」 |
CheckboxMultiSelectWidget | 真正意義上的「複選框」 |
ComboBoxInputWidget | 既可鍵盤輸入,又可選擇選項 |
DecoratedOptionWidget | 用於SelectWidget的帶圖標的選項 |
DropdownInputWidget | 用於FormLayout的下拉選單 |
DropdownWidget | 下拉選單 |
FieldLayout | 包含一個輸入元素和標籤或幫助信息 |
FieldSetLayout | FieldLayout的組合 |
FormLayout | 用於構建表單 |
HorizontalLayout | 行內樣式的layout |
HtmlSnippet | 用於插入htmlString |
IconWidget | 圖標 |
IndicatorWidget | 另一種小圖標 |
LabelWidget | 標籤 |
MultilineTextInputWidget | 相當於textarea |
NumberInputWidget | 帶增減按鈕的輸入僅限數字的文本框,由min/max/step/required設置代替validate設置 |
PanelLayout | 占據整個父容器的layout |
PopupButtonWidget | PopupWidget的開關 |
PopupWidget | 相當於tooltip |
ProgressBarWidget | 進度條 |
RadioInputWidget | 一個單獨的單選框,一般下不應使用 |
RadioSelectInputWidget | 用於FormLayout的單選框 |
RadioSelectWidget | 單選框 |
SearchInputWidget | 搜索框 |
SelectFileInputWidget | 上傳本地文件,不可拖拽 |
TextInputWidget | 文本框 |
oojs-ui-windows
oojs-ui-windows在oojs-ui-core的基礎上補充了各類對話框及相關元素。下表列出了oojs-ui-windows添加供直接使用的對象實例:
對象實例 | 說明 |
---|---|
ActionWidget | 用於對話框的按鈕 |
Dialog | 最基礎的對話框,所有對話框均必須使用WindowManager打開,且大部分無法直接使用 |
MessageDialog | 消息對話框,唯一一種可直接使用的自定義對話框 |
ProcessDialog | 進程對話框,無法直接使用 |
WindowManager | 用來打開各種對話框 |
OO.ui.alert() | 相當於window.alert(),但手機版的CSS設計有缺陷,請使用mw.notify()方法替代 |
OO.ui.confirm() | 相當於window.confirm(),但返回的是Promise對象 |
OO.ui.prompt() | 相當於window.prompt(),但返回的是Promise對象 |
oojs-ui-widgets
oojs-ui-widgets在oojs-ui-core的基礎上補充了一些更複雜的元素。下表列出了oojs-ui-widgets添加供直接使用的對象實例:
對象實例 | 說明 |
---|---|
BookletLayout | 左側分頁布局 |
ButtonMenuSelectWidget | 點擊按鈕展開下拉選單 |
ButtonSelectWidget | 使用按鈕的單選框 |
IndexLayout | 分頁 |
MenuLayout | 同時包含了菜單和內容 |
MenuTagMultiselectWidget | 使用菜單進行多選 |
PopupTagMultiselectWidget | 使用氣泡輸入的多選 |
SelectFileWidget | 選擇文件 |
StackLayout | 堆疊布局 |
TagMultiselectWidget | 使用文本輸入生成標籤多選,是MenuTagMultiselectWidget和PopupTagMultiselectWidget的基礎類型 |
ToggleButtonWidget | 使用按鈕開關 |
ToggleSwitchWidget | 開關 |
mediawiki.widgets
LLWiki添加的全局變量和方法
window.wgULS(hans, [hant])
和window.wgUCS(hans, [hant])
[10]- 用於處理繁簡文字信息,wgULS()用於界面語言,wgUCS()用於內容語言。為方便維護,在大量使用繁簡轉換的頁面,請將所有繁簡文字以mw.messages.set()方法的形式至於代碼開頭,然後在使用時以mw.msg()方法調用即可。
- mw.gadgets
- 這個對象儲存了所有小工具的設置。
- mw.request
- 這個對象儲存了一個mw.standardQuery()方法返回的Promise對象,即獲取當前版本全文Wikitext的API請求。
- mw.sections
- 這個數組的每一項對應一個mw.sectionQuery()方法返回的Promise對象,即獲取對應段落Wikitext的API請求。
- mw.widget
- 這個對象儲存了小部件的執行情況,防止Ajax預覽造成小部件重複執行。
- mw.settingsDialog[11]
- 這個對象是一個SettingsDialog類,用於小工具設置的圖形界面。這個類提供了多種方法,包括:獲取小工具名稱(getName)、獲取小工具對象(getObject)、獲取小工具標籤頁(getPanel)、添加小工具(addTab)、生成設置對象(generateOptions)、將設置保存到localStorage(saveOptions)、還原設置(clearOptions)和導出設置(export)。用法複雜,詳見代碼頁。
mw.pagenamee()
[10]- 這個方法用於獲取轉義後的當前頁面名稱。需要mediawiki.util。
mw.addMobileLinks(link)
[10]- 這個方法生成手機版菜單需要的列表構成的數組,可以隨後加入DOM中。link為對象或對象數組,每一項包含連結地址href(可選)、FontAwesome圖標icon(默認為圓圈包裹的一個向右箭頭)、文字信息text(需要手動設置繁簡轉換,優先級低於msg)或mw.messages的鍵值msg和
<li>
元素屬性attr(可選)。
mw.isModule(name, [flag])
[10]- 這個方法用於檢測一個模塊是否正在或已經加載。name為模塊名或小工具名;flag為真時自動在小工具名name前添加前綴
'ext.gadget.'
。
mw.apiFailure(reason, topic)
[10]- 這個方法用於輸出一個API請求失敗的氣泡通知。reason為API返回的錯誤信息,一般來自狀態為reject的API請求;topic為簡短的文字說明,需要手動設置繁簡轉換。
mw.timedQuery(api, params, topic)
[10]- 這個方法用於提交一個可自定義的API請求,並記錄用時,失敗時應用mw.apiFailure()方法生成氣泡通知並拋出錯誤。api為一個mw.Api對象;params即API參數,默認已填入
{action: 'query', formatversion: 2}
,可以覆蓋;topic為簡短文字描述,需要手動設置繁簡轉換。需要mediawiki.api。
mw.timedParse(api, params, topic)
[10]- Ajax使用POST而非GET,因此適合預覽大段Wikitext。params的默認設置為
{action: 'parse', prop: 'text', title: mw.config.get( 'wgPageName' ), disablelimitreport: 1, disableeditsection: 1, pst: 1, formatversion: 2}
,可以覆蓋。填入page、pageid或oldid參數時請勿使用此方法,應當選用包含{action: 'parse'}
參數的mw.timedQuery()。topic同樣需要手動設置繁簡轉換。需要mediawiki.api。
mw.standardQuery(api)
[10]- 使用mw.timedQuery()方法提交一個API請求以獲取當前版本的全文Wikitext並保存至mw.request。需要mediawiki.api。
mw.sectionQuery(api, section, [force])
[10]- 使用mw.timedQuery()方法提交一個API請求以獲取段落Wikitext並保存至mw.sections。section為段落編號,默認為序言;為降低錯誤編輯歷史版本的風險,想要獲取歷史版本的段落Wikitext時,必須手動添加為真的force參數。需要mediawiki.api。
mw.safeEdit(api, curRevid, params, [flag])
[10]- 檢查有無編輯衝突後提交編輯。api為mw.Api對象;curRevid為當前最新版本的編號,默認為
mw.config.get( 'wgCurRevisionId' )
;parmas為API參數,默認為{action: 'edit'}
,可以覆蓋,但原則上請勿使用這一方法執行其他操作;flag參數對應是否開啟自動備份小工具,這會改變檢測到編輯衝突時的錯誤通知。檢測到編輯衝突拋出錯誤'editConflict'
,API請求失敗拋出錯誤'editFailure'
或'revisionQueryFailure'
。需要mediawiki.api。
mw.safeRedirect(api, title, target, [summary])
[10]- 檢查繁簡轉換後的頁面是否已經存在後創建新重定向。api為mw.Api對象;title為重定向頁標題;target為重定向目標頁標題,默認為當前頁面;summary為可選摘要。頁面已存在時拋出
'pageExists'
,API請求失敗時拋出'createFailure'
或'queryFailure'
。需要mediawiki.api。
mw.confirm(text, [flags])
[10]- 藉助OO.ui.confirm()方法生成一個確認對話框。text為確認提示,可以是字符串或jQuery;flags為確認鍵的樣式數組,可選元素包括
'primary'
、'progressive'
和'destructive'
,其中'primary'
不能單獨生效。返回值為一個狀態為resolve的Promise對象,值為真表示確認。需要oojs-ui-windows。
mw.prompt(text, [flags], [config])
[10]- 藉助OO.ui.prompt()方法生成一個prompt對話框。text為文字提示,可以是字符串或jQuery;flags為確認鍵的樣式數組,可選元素包括
'primary'
、'progressive'
和'destructive'
,其中'primary'
不能單獨生效;config為可選的文本框設置。返回值為一個狀態為resolve的Promise對象,值為null
表示取消。需要oojs-ui-windows。
mw.dialog(dialog, actions, $message, [$title])
[10]- 藉助OO.ui.MessageDialog對象生成一個更複雜的對話框。dialog為預先準備的OO.ui.MessageDialog對象;actions為OO.ui.ActionWidget對象構成的數組;$message為提示信息,相比mw.confirm()方法的進步之處在於可以使用jQuery或htmlString;$title為對話框標題。返回值為點擊按鈕時的Promise對象。需要oojs-ui-windows。
mw.tipsy($container, [target], [params], [$content])
[10]- 藉助OO.ui.PopupWidget對象生成一個手機版也有效的tooltip。$container為外部容器的jQuery對象(不能是body);target為目標元素的選擇器;params為建立OO.ui.PopupWidget對象時的參數,默認為
{padded: true, width: null, classes: ['mw-tipsy']}
,可以覆蓋;$content為自定義的tooltip內容,默認為title或data-title屬性。需要oojs-ui-core。
mw.menu(options, [config], [unselectable])
[10]- 藉助於OO.ui.MenuSelectWidget生成一個浮動菜單。options為選項數組,每一項包含文本text(需要手動設置繁簡轉換)、FontAwesome圖標icon(可選)、數據data(可選)、連結href(可選)和點擊事件click(可選);config為菜單設置,默認為
{classes: ['site-menu'], hideWhenOutOfView: false}
,可以覆蓋;unselectable為真時,菜單不會保留之前最後一次的選擇記錄。這個UI方法的用法較為複雜,詳見代碼頁。
mw.convertTimezone(then, timezone)
[10]- 改變moment對象的時區。then為待處理的moment對象,默認為現在;timezone為時區的IANA名稱或數值表示的UTC偏移量,需要提前檢查合法性,默認為本地時區。注意這個方法的返回值不是一個真實存在的時間點,只能用於輸出而不能用於進一步運算。需要moment。
- mw.resizeLyrics()[12]
- 重新計算
.Lyrics_box
的大小,並調整原文和譯文的排列方式。
JSHint
CodeEditor使用JSHint標註可能存在的語法問題。LLWiki會在大部分JS頁面添加JSHint設置/* global mw */
和/* jshint jquery: true, bitwise: true, curly: true, latedef: 'nofunc', nonew: true, singleGroups: true, unused: true */
[13]。但在小部件頁面,為了提示小部件JS加載在模塊mediawiki和jquery之前,/* global mw */
和/* jshint jquery: true */
被替換為/* jshint varstmt: true */
。注意JSHint並不會對大多數JS模塊不允許使用的ES6語法作出警告(詳見#ResourceLoader和JS模塊),因此請勿過度依賴這一功能來除錯。另外CodeEditor安裝的JSHint版本較老,無法識別ES7以上的語法,因此在代碼中使用ES7語法可能會造成除錯時的困難。
注意事項
手機版
手機版解析器
圖片懶加載
手機版CSS
手機版LLWiki使用Minerva Neue皮膚,與桌面版的Vector皮膚相比,不僅界面有很大差異,眾多基礎HTML元素也都添加了不同的CSS樣式。為了適配窄屏設備,Minerva皮膚還添加了大量基於@media
的規則,一般以設備寬度720px為分界使用不同的樣式。以下著重介紹<table>
和<img>
這兩種需要CSS修正的重災區。
手機版CSS很多時候依賴外層容器的content
類來生效,與此同時#mw-content-text .mw-parser-output
的外層結構也同樣有效,設計各種基於API的快速編輯工具(如Wikiplus等)的預覽界面時需要考慮。
表格
對於<table>
元素及其子節點,手機版已知會自動添加以下樣式:
table, caption, tbody, tfoot, thead, tr, th, td {
font-size: 100%;
}
table {
border-collapse: collapse;
}
.content table {
margin: 1em 0;
overflow: auto;
overflow-y: hidden;
overflow-x: auto;
}
@media only screen and (max-width: 720px) {
.content table {
display: block;
width: 100% !important;
}
}
這裡重點說明一下第二和第四條規則造成的影響。第二條規則使得表格的外層邊框、行邊框和單元格邊框合併,可能造成一系列關於邊框的CSS規則出現不符合預期的表現,尤其是<table>
的cellspacing
屬性會無法生效。因此一般建議避免使用cellspacing
這一HTML屬性,改為使用CSS中的border-spacing
。另外,在需要border-spacing
或border-radius
等樣式時,請同時指定border-collapse: separate;
以使手機版生效。
第四條規則的本意是在窄屏上<table>
元素不會將頁面撐得過寬,但這同時會造成外層的<table>
和內層的<tbody>
分離。特別是如果外層<table>
規定了邊框或背景色時,很容易看出樣式的錯誤。為此一般需要主動指定display: table;
以修復這一問題,LLWiki有很多預定義的表格CSS類也都添加了這一規則[14]。但這樣修改的話又會重新面臨過寬的表格將整個頁面撐大的問題。LLWiki現定義了table-wrapper
類[14],用於套在寬表格外:<div class="table-wrapper">
,這個外層容器會在窄屏上通過overflow-x: auto;
限制裡面的表格寬度。
圖片
皮膚界面
其他
手機版JS
手機版JS模塊
繁簡轉換
Wikitext繁簡轉換
轉換表
Template:NoteTA
基本手工轉換語法
系統消息
CSS繁簡轉換
JS繁簡轉換
濫用過濾器
測試帳戶
如果管理員需要一個沒有自確權限的測試帳戶用於濫用過濾器測試、小工具測試等,可以臨時啟用6號濫用過濾器來移除某個測試帳戶的自確權限。這個濫用過濾器的使用語法非常簡單,請根據樣例修改為對應的用戶名即可,這裡不再贅述。
參考資料
- ↑
const
可用。 - ↑ 2.0 2.1 2.2 2.3 2.4 ES7以上語法雖然在不作為ResourceLoader的模塊時允許使用,但因為CodeEditor安裝的JSHint版本不支持語法分析,可能會造成代碼除錯時的困難。
- ↑ 注意$.extend()方法與另兩者並不完全一致,但更推薦使用$.extend()。
- ↑ MW:ResourceLoader/核心模塊
- ↑ 完整列表
- ↑ 完整參數列表
- ↑ 移動前端的擴展說明
- ↑ API文檔(action = query)
- ↑ mw.util文檔
- ↑ 10.00 10.01 10.02 10.03 10.04 10.05 10.06 10.07 10.08 10.09 10.10 10.11 10.12 10.13 10.14 10.15 10.16 需要加載site-lib.js
- ↑ 需要加載SettingsDialog.js
- ↑ 需要加載Widget:Lyrics
- ↑ 新版JSHint的設置列表,注意可能存在的版本差異。
- ↑ 14.0 14.1 全站CSS