/*
* modifyEditsection
* トランスクルードされた節の節編集リンクを拡張する
*
* dbenzhuser (de:Benutzer:Dbenzhuser)
* Alex Smotrov (en:User:Alex Smotrov)
* TheDJ (en:User:TheDJ)
* mizusumashi (ja:User:Mizusumashi)
* cpro (ja:User:Cpro)
* 鈴音雨 (ja:User:鈴音雨)
*/
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', 'mediawiki.Uri']).done(function () {
if (!window.modifyEditsectionConfig) {
window.modifyEditsectionConfig = {
show: ["view", "copy", "history", "watch", "purge"],
};
}
/** mw.config の内容を保持 */
var conf = mw.config.get([
'wgPageName',
'wgUserLanguage',
'wgServer',
'wgScript',
'wgUserName',
'wgAction'
]);
// メッセージのセットアップ
var messages = {
en: {
'openTitle': 'open',
'openDescription': 'Open "$1#$2"',
'copyTitle': 'copy',
'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」を閲覧',
'copyTitle': 'コピー',
'copyDescription': '「$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', // <!--
'<span class="editsection-extensions">' +
'<span class="mw-editsection-bracket">[</span>' +
'{{#extension}}' +
'{{^skip}}' +
'{{^first}}<span class="mw-editsection-divider"> | </span>{{/first}}' +
'<a href="{{href}}" onclick="{{onclick}}" title="{{title}}">{{text}}</a>' +
'{{#unwatchHref}}(<a href="{{unwatchHref}}" title="{{unwatchTitle}}">-</a>){{/unwatchHref}}' +
'{{/skip}}' +
'{{/extension}}' +
'<span class="mw-editsection-bracket">]</span>' +
'</span>'); // -->
/**
* テンプレート用のデータを生成する
* @param {string} transcluded トランスクルードされているページ名
* @param {string} sectionName 節タイトル
* @param {string} sectionFragment 節リンク用識別子(URLの # 以降)
*/
var createExtLinkDataForTemplate = function (transcluded, sectionName, sectionFragment, isTranscluded) {
var data = {
extension: [
window.modifyEditsectionConfig.show.includes("view") && isTranscluded && { // 閲覧
text: message('openTitle'),
href: getUri(transcluded, 'view', sectionFragment),
title: message('openDescription', transcluded, sectionName)
},
window.modifyEditsectionConfig.show.includes("copy") && { // コピー
text: message('copyTitle'),
href: 'javascript:void(0);',
onclick: `navigator.clipboard.writeText('${mw.config.get("wgPageName")}#${sectionFragment}');mw.notify("Copied ${mw.config.get("wgPageName")}#${sectionFragment}");return false;`,
title: message('copyDescription', transcluded, sectionName)
},
window.modifyEditsectionConfig.show.includes("history") && isTranscluded & { // 履歴
text: message('historyTitle'),
href: getUri(transcluded, 'history'),
title: message('historyDescription', transcluded)
},
window.modifyEditsectionConfig.show.includes("watch") && isTranscluded && { // ウォッチリスト追加/削除
text: message('watchTitle'),
href: getUri(transcluded, 'watch'),
title: message('watchDescription', transcluded),
unwatchHref: getUri(transcluded, 'unwatch'),
unwatchTitle: message('unwatchDescription', transcluded),
// ログインしていない場合はウォッチリストの処理をスキップ
skip: conf.wgUserName === null
},
window.modifyEditsectionConfig.show.includes("purge") && isTranscluded && { // 更新
text: message('purgeTitle'),
href: getUri(conf.wgPageName, 'purge', sectionFragment),
title: message('purgeDescription', conf.wgPageName, transcluded),
// パージ直後の場合はパージの処理をスキップ
skip: conf.wgAction == 'purge'
}
].filter(Boolean)
};
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 = $section.text().trim();
/** 節リンク用識別子(URLの # 以降) */
var sectionFragment = $section.attr('id');
/** テンプレートに渡すデータ */
var data = createExtLinkDataForTemplate(transcluded, sectionName, sectionFragment, true);
$($editSpan).append(extensionTemplate.render(data));
};
var extendEditSectionLinkNoTransclude = function (i, $editSpan) {
var label = (
$('a[href*="§ion="]', $editSpan).parent().parent().find(".mw-headline").attr("id") || ''
).trim();
if ( !label ) {
return;
}
var uri = new mw.Uri($('a[href*="§ion="]', $editSpan).attr('href'));
var transcluded = uri.query.title;
var sectionName = "";//$(`#${sectionFragment}`).text().trim();
var data = createExtLinkDataForTemplate(transcluded, sectionName, label, false);
$($editSpan).append(extensionTemplate.render(data));
}
$(function () {
/** トランスクルードされた節編集リンク(section=T-n を含む)を子要素に持つ span.mw-editsection */
var $editSectionLinks = $('span.mw-editsection').has('a[href*="§ion=T-"]');
var $editSection = $('span.mw-editsection').has('a[href*="§ion="]').filter(function (i, el) {
console.log($(el).find("a").attr('href'));
return $(el).find("a").attr('href').indexOf("§ion=T-") === -1;
});
console.log($editSection);
if ($editSection.length === 0 && $editSectionLinks.length === 0) {
return;
}
$editSection.each(extendEditSectionLinkNoTransclude);
// ビジュアルエディターが無効だと区切り線が非表示なので強制表示
$('.editsection-extensions .mw-editsection-divider').show();
// 節編集リンクを順次処理
$editSectionLinks.each(extendEditSectionLink);
// ビジュアルエディターが無効だと区切り線が非表示なので強制表示
$('.editsection-extensions .mw-editsection-divider').show();
});
}); // mw.loader.using().done(function() {
} // end if