MediaWiki:Gadget-modifyEditsection.js
/*
* modifyEditsection
* トランスクルードされた節の節編集リンクを拡張する
*
*   dbenzhuser (de:Benutzer:Dbenzhuser)
*   Alex Smotrov (en:User:Alex Smotrov)
*   TheDJ (en:User:TheDJ)
*   mizusumashi (ja:User:Mizusumashi)
*   cpro (ja:User:Cpro)
*/
if( (mw.config.get('wgAction') == 'view' || mw.config.get('wgAction') == 'purge') &&
// Wikipedia名前空間、または各種ノートページのみで実行
(mw.config.get('wgNamespaceNumber') == 4 || mw.config.get('wgNamespaceNumber') % 2 == 1 )) {
mw.loader.using(['mediawiki.template', 'mediawiki.template.mustache']).done(function() {
/** mw.config の内容を保持 */
var conf = mw.config.get([
'wgPageName',
'wgUserLanguage',
'wgServer',
'wgScript',
'wgUserName',
'wgAction'
]);
// メッセージのセットアップ
var messages = {
en: {
'openTitle'          : 'open',
'openDescription'    : 'Open "$1#$2"',
'historyTitle'       : 'history',
'historyDescription' : 'Past version of "$1"',
'watchTitle'         : 'watch',
'watchDescription'   : 'Add "$1" to your watchlist',
'unwatchDescription' : 'Remove "$1" from your watchlist',
'purgeTitle'         : 'purge',
'purgeDescription'   : 'Clear the cache of "$1" and view the last version of "$2"'
},
ja: {
'openTitle'          : '閲覧',
'openDescription'    : '「$1#$2」を閲覧',
'historyTitle'       : '履歴',
'historyDescription' : '「$1」の履歴',
'watchTitle'         : 'ウォッチ',
'watchDescription'   : '「$1」をウォッチリストに追加',
'unwatchDescription' : '「$1」をウォッチリストから削除',
'purgeTitle'         : '更新',
'purgeDescription'   : '「$1」を更新し、「$2」の最新版を反映'
}
};
var myMessage = messages[conf.wgUserLanguage] || {};
/**
* キーを指定して現在の言語設定に対応するメッセージを取得する
* 第2引数以降に指定があれば、メッセージ内のプレースホルダー
* "$1", "$2"" ... を指定した文字列で置換する
* @returns {string}
*/
var message = function(key){
var msg = myMessage[key] || messages.en[key];
for(var i = 1; i < arguments.length; i++) {
msg = msg.replace('$' + i.toString(), arguments[i]);
}
return msg;
};
/**
* クエリ付きのMediaWiki URIを生成する (.../w/index.php?title=...)
* @returns {string}
*/
var getUri = function(pageName, action, fragment) {
var uri = new mw.Uri(conf.wgServer + conf.wgScript);
uri.query = {
title: pageName,
action: action
};
if(fragment)
uri.fragment = fragment;
return uri.toString();
};
/** 拡張リンクのmushtacheテンプレート */
var extensionTemplate = mw.template.add('_client', 'sectionEditLinkExtension.mustache', //
/**
* テンプレート用のデータを生成する
* @param {string} transcluded トランスクルードされているページ名
* @param {string} sectionName 節タイトル
* @param {string} sectionFragment 節リンク用識別子(URLの # 以降)
*/
var createExtLinkDataForTemplate = function(transcluded, sectionName, sectionFragment) {
var data = {
extension: [
{ // 閲覧
text: message('openTitle'),
href: getUri(transcluded, 'view', sectionFragment),
title: message('openDescription', transcluded, sectionName)
},
{ // 履歴
text: message('historyTitle'),
href: getUri(transcluded, 'history'),
title: message('historyDescription', transcluded)
},
{ // ウォッチリスト追加/削除
text: message('watchTitle'),
href: getUri(transcluded, 'watch'),
title: message('watchDescription', transcluded),
unwatchHref: getUri(transcluded, 'unwatch'),
unwatchTitle: message('unwatchDescription', transcluded),
// ログインしていない場合はウォッチリストの処理をスキップ
skip: conf.wgUserName === null
},
{ // 更新
text: message('purgeTitle'),
href: getUri(conf.wgPageName, 'purge', sectionFragment),
title: message('purgeDescription', conf.wgPageName, transcluded),
// パージ直後の場合はパージの処理をスキップ
skip: conf.wgAction == 'purge'
}
]
};
data.extension[0].first = true; // 最初の要素を認識させる(区切り線追加をスキップするため)
return data;
};
/** 拡張処理済みの節編集リンクの名前・見出しレベルを保持するオブジェクト */
var expanded = {};
/** 節編集リンクを拡張する */
var extendEditSectionLink = function(i, $editSpan) {
var href = $('a[href*="§ion=T-"]', $editSpan).attr('href');
/** トランスクルードされているページ名 */
var transcluded = (new mw.Uri(href)).query.title;
/** 節編集リンクを含んでいるh*要素 */
var parentHn = $editSpan.parentNode;
/** 節の見出しレベル */
var level = Number(parentHn.tagName.replace(/h/i, ));
// 以前に同じページからのトランスクルードがあり、かつ見出しレベルが下がっていれば、拡張しない
if(expanded[transcluded] && level > expanded[transcluded]){
return;
}
expanded[transcluded] = level;
var $section = $('span.mw-headline', parentHn);
var sectionName = $.trim($section.text());
/** 節リンク用識別子(URLの # 以降) */
var sectionFragment = $section.attr('id');
/** テンプレートに渡すデータ */
var data = createExtLinkDataForTemplate(transcluded, sectionName, sectionFragment);
$($editSpan).append(extensionTemplate.render(data));
};
$(function() {
/** トランスクルードされた節編集リンク(section=T-n を含む)を子要素に持つ span.mw-editsection */
var $editSectionLinks = $('span.mw-editsection').has('a[href*="§ion=T-"]');
// editsection が存在しなければ何もしない。
if($editSectionLinks.length === 0) {
return;
}
// 節編集リンクを順次処理
$editSectionLinks.each(extendEditSectionLink);
// ビジュアルエディターが無効だと区切り線が非表示なので強制表示
$('.editsection-extensions .mw-editsection-divider').show();
});
}); // mw.loader.using().done(function() {
} // end if