/**
* modifyEditsection (mediawiki.template.mustacheを使わないバージョン)
* @author [[User:Dragoniez]]
* @link https://ja.wikipedia.org/wiki/MediaWiki:Gadget-modifyEditsection.js
*/
//<nowiki>
(function() {
// *********************************************************************************
if (['view', 'purge'].indexOf(mw.config.get('wgAction')) === -1 || // action=view または action=purgeのみで実行
mw.config.get('wgNamespaceNumber') % 2 === 0 && mw.config.get('wgNamespaceNumber') !== 4 // Wikipedia名前空間、または各種ノートページのみで実行
) {
return;
}
$.when(
mw.loader.using('mediawiki.Uri'),
$.ready
).then(function() {
/** @type {HTMLSpanElement[]} */
var esSpans = Array.prototype.slice.call(document.querySelectorAll('.mw-editsection'));
if (!esSpans.length) return;
// styleタグを追加 (拡張したeditsectionリンクの区切り用擬似エレメント)
var style = document.createElement('style');
style.textContent = '.mw-editsection > .es-extended::before { content: " | "; }';
document.head.appendChild(style);
/**
* 拡張したeditsectionリンクのページタイトルとヘッダーレベルを格納するオブジェクト
* @type {Object.<string, number>}
*/
var extended = {};
/**
* 拡張リンクを挿入する関数
* @param {HTMLElement} parent
* @param {HTMLElement} newNode 挿入する要素
* @param {Element} child この要素の前
*/
var addExtendedLink = function(parent, newNode, child) {
parent.insertBefore(newNode, child);
};
mw.messages.set({
'es-view': '閲覧',
'es-view-tooltip': '「$1#$2」を閲覧',
'es-history': '履歴',
'es-history-tooltip': '「$1」の履歴',
'es-watch': 'ウォッチ',
'es-watch-tooltip': '「$1」をウォッチリストに追加',
'es-unwatch': '-',
'es-unwatch-tooltip': '「$1」をウォッチリストから削除',
'es-purge': '更新',
'es-purge-tooltip': '「$1」の最新版を反映',
});
/**
* @param {"view"|"history"|"watch"|"unwatch"|"purge"} action
* @param {mw.Uri} uri このUriオブジェクトをもとにアンカーを作成; actionパラメターは関数内で自動付与
* @param {HTMLSpanElement} [refSpan] 指定されている場合、作成したアンカーを括弧で囲みこのspanにappend (新規のラッパーspanは作成しない)
* @returns {HTMLSpanElement} 作成したラッパーspan、またはrefSpan指定時はアップデートされたrefSpan自身
*/
var createExtendedLink = function(action, uri, refSpan) {
uri.extend({action: action});
var anchor = document.createElement('a');
anchor.href = uri.toString();
anchor.textContent = mw.msg('es-' + action);
anchor.title = mw.msg('es-' + action + '-tooltip', uri.query.title, uri.fragment || '');
var span;
if (refSpan) {
span = refSpan;
span.appendChild(document.createTextNode('('));
span.appendChild(anchor);
span.appendChild(document.createTextNode(')'));
} else {
span = document.createElement('span');
span.classList.add('es-extended');
span.appendChild(anchor);
}
return span;
};
esSpans.forEach(function(span) {
// リンク拡張に必要な要素の情報を取得
var insertPoint = span.querySelectorAll('.mw-editsection-bracket')[1];
if (!insertPoint) return;
/**
* トランスクルードされた節のアンカー (section=T-nを含む)
* @type {HTMLAnchorElement|null}
*/
var a = span.querySelector('a[href*="§ion=T-"]');
if (!a) return;
var href = a.href;
var pr = span.parentElement;
if (!pr) return;
var m = pr.tagName.match(/^H(\d)$/);
if (!m) return;
var level = parseInt(m[1]);
var headline;
var section = (headline = pr.querySelector('.mw-headline')) ? headline.id : '';
// 「ソースを編集」に割り当てられたページ名を取得し参照用mw.Uriインスタンスを作成
var uri = new mw.Uri(href);
/** @type {string|undefined} */
var title = uri.query.title;
if (!title) {
// "title=" パラメターがない場合: "section=T-" をhrefにもつeditsectionアンカーは全て "/w/index.php" のため、基本的にこのブロックに辿り付くことはない
console.warn(a);
return;
}
if (!extended[title]) {
extended[title] = level;
} else if (level > extended[title]) { // 以前に同じページからのトランスクルードがあり、かつ見出しレベルが下がっていれば拡張しない
return;
}
var baseUri = new mw.Uri(mw.config.get('wgServer') + mw.config.get('wgScript'));
baseUri.extend({title: title});
// リンクを拡張
var viewUri = baseUri.clone();
if (section) viewUri.fragment = section;
var viewSpan = createExtendedLink('view', viewUri);
addExtendedLink(span, viewSpan, insertPoint);
var historySpan = createExtendedLink('history', baseUri.clone());
addExtendedLink(span, historySpan, insertPoint);
var watchSpan = createExtendedLink('watch', baseUri.clone());
watchSpan = createExtendedLink('unwatch', baseUri.clone(), watchSpan);
addExtendedLink(span, watchSpan, insertPoint);
var purgeSpan = createExtendedLink('purge', baseUri.clone());
addExtendedLink(span, purgeSpan, insertPoint);
});
});
// *********************************************************************************
})();
//</nowiki>