MediaWiki:Common.js
注意: 保存後、変更を確認するにはブラウザーのキャッシュを消去する必要がある場合があります。
- Firefox / Safari: Shift を押しながら 再読み込み をクリックするか、Ctrl-F5 または Ctrl-R を押してください (Mac では ⌘-R)
- Google Chrome: Ctrl-Shift-R を押してください (Mac では ⌘-Shift-R)
- Internet Explorer: Ctrl を押しながら 最新の情報に更新 をクリックするか、Ctrl-F5 を押してください
- Opera: メニュー → 設定 (Mac では Opera → 環境設定) に移動し、プライバシーとセキュリティ → 閲覧データを消去 → キャッシュされた画像およびファイル からキャッシュをクリアしてください。
// <source lang="javascript">
/* ここに書いたスクリプトは全ての外装に反映されます */
/**
* Collapsible tables *********************************************************
*
* Description: Allows tables to be collapsed, showing only the header. See
* [[Wikipedia:NavFrame]].
* Maintainers: [[User:R. Koot]]
*/
var autoCollapse = 2;
var collapseCaption = "隠す";
var expandCaption = "表示";
window.collapseTable = function ( tableIndex ) {
var Button = document.getElementById( 'collapseButton' + tableIndex );
var Table = document.getElementById( 'collapsibleTable' + tableIndex );
if ( !Table || !Button ) {
return false;
}
var Rows = Table.rows;
var i;
if ( Button.firstChild.data === collapseCaption ) {
for ( i = 1; i < Rows.length; i++ ) {
Rows[i].style.display = 'none';
}
Button.firstChild.data = expandCaption;
} else {
for ( i = 1; i < Rows.length; i++ ) {
Rows[i].style.display = Rows[0].style.display;
}
Button.firstChild.data = collapseCaption;
}
};
function createCollapseButtons() {
var tableIndex = 0;
var NavigationBoxes = {};
var Tables = document.getElementsByTagName( 'table' );
var i;
function handleButtonLink( index, e ) {
window.collapseTable( index );
e.preventDefault();
}
for ( i = 0; i < Tables.length; i++ ) {
if ( $( Tables[i] ).hasClass( 'collapsible' ) ) {
/* only add button and increment count if there is a header row to work with */
var HeaderRow = Tables[i].getElementsByTagName( 'tr' )[0];
if ( !HeaderRow ) continue;
var Header = HeaderRow.getElementsByTagName( 'th' )[0];
if ( !Header ) continue;
NavigationBoxes[ tableIndex ] = Tables[i];
Tables[i].setAttribute( 'id', 'collapsibleTable' + tableIndex );
var Button = document.createElement( 'span' );
var ButtonLink = document.createElement( 'a' );
var ButtonText = document.createTextNode( collapseCaption );
Button.className = 'collapseButton'; /* Styles are declared in Common.css */
ButtonLink.style.color = Header.style.color;
ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex );
ButtonLink.setAttribute( 'href', '#' );
$( ButtonLink ).on( 'click', $.proxy( handleButtonLink, ButtonLink, tableIndex ) );
ButtonLink.appendChild( ButtonText );
Button.appendChild( document.createTextNode( '[' ) );
Button.appendChild( ButtonLink );
Button.appendChild( document.createTextNode( ']' ) );
Header.insertBefore( Button, Header.firstChild );
tableIndex++;
}
}
for ( i = 0; i < tableIndex; i++ ) {
if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) || ( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) ) ) {
window.collapseTable( i );
}
else if ( $( NavigationBoxes[i] ).hasClass ( 'innercollapse' ) ) {
var element = NavigationBoxes[i];
while ((element = element.parentNode)) {
if ( $( element ).hasClass( 'outercollapse' ) ) {
window.collapseTable ( i );
break;
}
}
}
}
}
mw.hook( 'wikipage.content' ).add( createCollapseButtons );
/////////////////////////////////////////////////////////////////
// 記事名チェッカ for SRW Wiki
// Originally written by Tietew and Hatukanezumi
// Modified by ocha
/////////////////////////////////////////////////////////////////
/*jslint regexp: true, browser: true */
/*global $, wgPageName, wgNamespaceNumber, wgTitle, wgArticleId, skin, getElementsByClassName */
// 無効化のフラグ変数
// 無効化は、利用者のユーザスクリプトで真に設定することでする
var disableTitleChecker = false;
var titleChecker = (function () {
'use strict';
// 記事名チェッカによる処理を適用しない記事名のリスト(除外リスト)
var excludes = [
// [名前空間番号, 項目名], ...
],
lenExcludes = excludes.length,
/*
* 記事名を検査し、結果を返す
* 引数:args {
* ns: 名前空間番号(標準:0;ノート:1;…)
* title: 項目名
* body: 項目本文の内容
* }
* 返値:{
* action: 処理
* reasons: 理由。[{message: 説明文, guides: [ガイドライン等, ...]}]
* for_redirect: リダイレクトの即時削除対象になりうるかどうか
* }
* ただし、処理が「許可」であるときは false
*/
check = function (args) {
var ns = args.ns,
title = args.title,
body = args.body,
matchesSafari, // 'AppleWebkit' へのマッチ
is_redirect, // リダイレクトであるかどうか
action = 0, // 処理。0:許可する;1:警告する;2:拒否する
reasons = [], // 理由。[{message: 説明文,
// guides: [ガイドライン等, ...]}]
for_redirect = false,
i,
do_check = function (args) {
var re,
m,
matched,
reason,
msgstr;
re = new RegExp(args.pattern, 'g');
m = title.match(re);
if (m && (matched = m.join(' ')) !== '') {
if (args.newaction > action) {
action = args.newaction;
}
msgstr = args.message;
msgstr = msgstr.replace('%s', matched)
.replace('%%', '%');
reason = {
message: msgstr,
guides: args.guides || null
};
reasons.push(reason);
/*
* if (guides && is_redirect) {
* lenGuides = guids.length;
* for (var i = 0; i < lenGuides; i += 1) {
* if (guides[i] === "Wikipedia:即時削除の方針#リダイレクト") {
* for_redirect = true;
* break;
* }
* }
* }
*/
}
};
title = title.replace(/_/g, ' ');
// 記事ごとの無効化。除外リストにあれば検査をしない。
if (lenExcludes > 0) {
for (i = 0; i < lenExcludes; i += 1) {
if (excludes[i][0] === ns && excludes[i][1] === title) {
return false;
}
}
}
// プラットフォームの判別
// AppleWebKit/416 (Safari/2.0.2) 以降か?
matchesSafari = navigator.userAgent.match(/\bAppleWebKit\/(\d+)/);
if (matchesSafari && matchesSafari[1] < 416) {
return false; // Safari/1.x ならば検査をしない
}
// リダイレクトであるかどうかの判定
is_redirect = (body && body.match(/^#(?:redirect|転送)\s*\[\[.+?\]\]/i));
/*
* 書式の検査
*/
// 記事名の全体を「」または『』などでくくっているもの
// ないしは、その後に曖昧さ回避の括弧があるもの(拒否)
do_check({
pattern: '^[「『].*[」』]([ _]+[(][^)]+[)])?$',
newaction: 2,
message: '記事名が鈎括弧でくくられています。' +
'タイトルは鈎括弧でくくるべきではありません。'
});
// 記事名の末尾の括弧書きに半角の小括弧(丸括弧)を使用する場合に、
// 左括弧の前に半角スペースがないもの(警告)
// 注: 入れ子は2重まで
do_check({
pattern: '[^ ][(]([(][^()]*[)]|[^()])*[)]$',
newaction: 1,
message: '記事名の最後の左括弧の前に半角スペースがありません' +
': %s。' +
'曖昧さ回避の括弧である場合は、括弧の前に半角スペースを' +
'入れてください。' +
'名称自体に括弧を含んでいる場合はこの限りではありません。',
guides: ['Project:記事制作のポイント#記事名の表記法']
});
// 記事名に半角の小括弧(丸括弧)を使用する場合に、
// 括弧の左右が対称でないもの(警告)
// 注: 入れ子は2重まで
do_check({
pattern: '[(]([(][^()()]*[)]|[(][^()()]*[)]|[^()()])*[)]|[(]([(][^()()]*[)]|[(][^()()]*[)]|[^()()])*[)]',
newaction: 1,
message: '括弧の左右が対称ではありません: %s。' +
'両方を、半角括弧か全角括弧に統一してください。'
});
// 記事名に実体参照または数値文字参照を含んでいるもの(拒否)
do_check({
pattern: '([&][#]?[A-Za-z\\d]+;)+',
newaction: 2,
message: '記事名に実体参照を含んでいます: %s。' +
'実体参照を記事名に使うべきではありません。'
});
/*
* 使用文字種の検査
*/
// 技術的な考慮(拒否)
do_check({
pattern: '&',
newaction: 2,
message: '半角アンパサンド (&) を含んでいます。' +
'記事が正常に表示されなくなるため、' +
'この文字は記事名に使用できません。' +
'代わりに全角アンパサンド(&)を使用してください。'
});
do_check({
pattern: '\\+',
newaction: 2,
message: '半角プラス記号 (+) を含んでいます。' +
'記事が正常に表示されなくなるため、' +
'この文字は記事名に使用できません。' +
'代わりに全角プラス記号(+)を使用してください。'
});
do_check({
pattern: '[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]',
newaction: 2,
message: '文字でないものを含んでいます。' +
'文字でないものを記事名に使うべきではありません。'
});
do_check({
pattern: '[\u0080-\u009F\uFFF0-\uFFFD\uDB40-\uDB7F]',
newaction: 2,
message: '制御文字を含んでいます。' +
'制御文字を記事名に使うべきではありません。'
});
do_check({
pattern: '[\u00A0]',
newaction: 2,
message: 'ノーブレークスペースを含んでいます。' +
'通常のスペースを使ってください。'
});
do_check({
pattern: '[\u00AD]',
newaction: 2,
message: 'ソフトハイフンを含んでいます。' +
'ソフトハイフンを記事名に使うべきではありません。'
});
do_check({
pattern: '[\u2000-\u200A\u200B\u205F]',
newaction: 2,
message: '特別な幅のスペースを含んでいます。' +
'通常のスペースを使ってください。'
});
do_check({
pattern: '[\u200C\u200D\u2060]',
newaction: 2,
message: '書式制御文字を含んでいます。' +
'一部の言語ではこの文字を使いますが、' +
'記事名には日本語を使ってください。'
});
do_check({
pattern: '[\u2011]',
newaction: 2,
message: 'ノンプレーキングハイフンを含んでいます。' +
'ハイフンマイナス (-) を使ってください。'
});
do_check({
pattern: '[\u2028-\u202E\u2061-\u206F]',
newaction: 2,
message: '書式制御文字を含んでいます。' +
'書式制御文字を記事名に使うべきではありません。'
});
do_check({
pattern: '[\u202F]',
newaction: 2,
message: '特別な幅のノーブレークスペースを含んでいます。' +
'通常のスペースを使ってください。'
});
do_check({
pattern: '[\uE000-\uF8FF\uDB80-\uDBFF]',
newaction: 2,
message: '私用文字を含んでいます。' +
'私用文字(外字)を記事名に使うべきではありません。'
});
do_check({
pattern: '[\uFEFF]',
newaction: 2,
message: '不可視な文字を含んでいます。' +
'この文字を記事名に使うべきではありません。'
});
// その他のガイドライン等(拒否)
do_check({
pattern: '[\uFF65]',
newaction: 2,
message: '半角中黒 (・) を含んでいます。' +
'代わりに全角中黒(・)を使用してください。',
guides: ['Project:記事制作のポイント#記事名の表記法']
});
do_check({
pattern: '[=\u30A0]',
newaction: 2,
message: '半角等号 (=) またはダブルハイフン(゠)を含んでいます。' +
'代わりに全角等号(=)を使用してください。',
guides: ['Project:記事制作のポイント#記事名の表記法']
});
do_check({
pattern: '[\uFF08\uFF09]',
newaction: 2,
message: '全角括弧を含んでいます。' +
'代わりに半角括弧を使用してください。',
guides: ['Project:記事制作のポイント#記事名の表記法']
});
do_check({
pattern: '[\u2160-\u217F]+',
newaction: 2,
message: 'ローマ数字を含んでいます: %s。' +
'これは機種依存文字です。' +
'ローマ数字は半角英字(iやVなど)を並べて表記してください。'
});
do_check({
pattern: '[\u2460-\u2473\u24EA-\u24FF\u3251-\u325F\u32B1-\u32BF]+',
newaction: 2,
message: '丸数字を含んでいます: %s。' +
'これは機種依存文字です。' +
'代わりに (1)、(2)、(3) などを使用してください。'
});
do_check({
pattern: '[\u2474-\u24B5\u3200-\u3250\u32C0-\u32CF\u3300-\u33FF]+',
newaction: 2,
message: '組文字を含んでいます: %s。' +
'片仮名や、漢字、英数字で表記してください。' +
'これは機種依存文字である場合もあります。'
});
do_check({
pattern: '[\u3000]',
newaction: 2,
message: '全角空白を含んでいます。' +
'全角空白を記事名に使うべきではありません。',
guides: ['Project:記事制作のポイント#記事名の表記法']
});
do_check({
pattern: '[\uFB00-\uFEFE\uFFE0-\uFFE7\uFFE8-\uFFEF]+',
newaction: 2,
message: '機種依存文字を含んでいます: %s。' +
'機種依存文字を記事名に使うべきではありません。'
});
do_check({
pattern: '[\uFF10-\uFF19]+',
newaction: 2,
message: '全角数字を含んでいます: %s。' +
'全角英数字を記事名に使うべきではありません。',
guides: ['Project:記事制作のポイント#記事名の表記法']
});
do_check({
pattern: '[\uFF21-\uFF3A\uFF41-\uFF5A]+',
newaction: 2,
message: '全角英字を含んでいます: %s。' +
'全角英数字を記事名に使うべきではありません。',
guides: ['Project:記事制作のポイント#記事名の表記法']
});
/*
* do_check({
* pattern: '[\uFF00\uFF02\uFF04-\uFF07\uFF0A-\uFF0F\uFF1B\uFF20\uFF3C\uFF3E-\uFF40\uFF5F-\uFF60]+',
* newaction: 1,
* message: '全角英記号を含んでいます: %s。' +
* '全角英記号を記事名に使うべきではありません。',
* guides: ['Project:記事制作のポイント#記事名の表記法']
* });
*/
do_check({
pattern: '[\uFF61-\uFF64\uFF66-\uFF9F]+',
newaction: 2,
message: '半角片仮名を含んでいます: %s。' +
'半角片仮名を記事名に使うべきではありません。'
});
do_check({
pattern: '[\uFFA0-\uFFDF]+',
newaction: 2,
message: '半角ハングル字母を含んでいます: %s。' +
'半角ハングル字母を記事名に使うべきではありません。'
});
// その他のガイドライン等(警告)
if (!is_redirect) { // リダイレクトでない場合のみ
do_check({
pattern: '[\uFF5E]+',
newaction: 1,
message: '全角チルダを含んでいます。' +
'この文字は、一部の環境で正しく表示されません。' +
'波ダッシュ(〜)か、できればハイフンマイナス (-) を' +
'使ってください。' +
'波ダッシュを使った記事名へのリダイレクトを作成しようと' +
'している場合は、この限りではありません。'
});
}
if (action === 0) {
return false; // 処理が「許可」であるときは false を返す
}
return {
action: action,
reasons: reasons,
for_redirect: for_redirect
};
},
/*
* 記事名を検査した結果を表示する
* 引数:args {
* mark: 説明文などを挿入する場所のelement
* action: 処理
* reasons: 理由。[{message: 説明文, guides: [ガイドライン等, ...]}]
* for_redirect: リダイレクトの即時削除対象でありうるかどうか
* }
* 返値:
* なし
*/
warn = function (args) {
/*
* プロトタイプ拡張
*/
// [関数]
// メソッドの追加
Function.prototype.method = function (name, func) {
if (!this.prototype[name]) {
this.prototype[name] = func;
return this;
}
};
// [文字列]
// '<'、'>'、'&' の実体参照化
String.method('entityify', function () {
return this.replace(/&/g, '&').replace(/</g, '<')
.replace(/>/g, '>');
});
/*
* 処理
*/
var mark = args.mark,
reasons = args.reasons,
lenReasons,
guides = [],
lenGuides,
guideLinks = [],
wl = function (pageName, opt_linkName) {
pageName = pageName.replace(/_/g, ' ');
var linkName = opt_linkName || pageName,
url = encodeURI(pageName.replace(/ /g, '_')),
hashIndex;
// アンカーを MediaWiki の形式に変換する
hashIndex = url.lastIndexOf('#');
if (hashIndex !== -1) {
url = url.slice(0, hashIndex) +
url.slice(hashIndex).replace(/%/g, '.');
}
return '<a href="' + url +
'" title="' + pageName.entityify() + '">' +
linkName.entityify() + '</a>';
},
divWarn,
html = '\n<p><strong>警告: このページの記事名の付け方は、' +
wl('Project:記事制作のポイント', '{{SITENAME}}の方針') +
'に沿っていないかもしれません。' +
'理由は以下のとおりです。</strong></p>',
i,
j;
if (reasons) {
html += '\n<ul>';
lenReasons = reasons.length;
for (i = 0; i < lenReasons; i += 1) {
html = html + '\n<li>' +
reasons[i].message.entityify(); // 説明文
if (reasons[i].guides) {
guides = reasons[i].guides.concat(); // 配列のコピー
lenGuides = guides.length;
guideLinks = [];
for (j = 0; j < lenGuides; j += 1) {
guideLinks.push(wl(guides[j]));
}
html = html + '詳しくは、' + guideLinks.join('、') +
'を参照してください。';
}
html += '</li>';
}
html += '\n</ul>';
}
html = html +
'\n<p>記事名の変更を検討してみてください。' +
'なお、記事名を変更したときは、' +
wl('特別:Whatlinkshere/' + wgPageName, 'このページのリンク元') +
'を調べて、新しい記事へのリンクに変更するようにしてください。</p>\n';
/*
* '<p>記事名チェック機能の詳細は、' +
* wl('Help:記事名のチェック') +
* 'をご覧ください。</p>';
*/
/*
* if (for_redirect && wgArticleId)
* html = html +
* '<p>編集中のページは' + wl('Wikipedia:リダイレクト', 'リダイレクト') + 'ですが、' +
* '即時削除に出せるかもしれません。' +
* 'リダイレクトの即時削除に出すことができるのは、以下のすべてが該当する場合です。</p><ul>' +
* '<li>項目名の書き誤りで、それが誰が見ても明らかに誤りだとわかる。</li>' +
* '<li>項目が有益な履歴を持っていない。</li>' +
* '<li>項目がどこからもリンクされていない。</li>' +
* '</ul><p>リダイレクトの即時削除についての詳細は、' + wl('Wikipedia:即時削除の方針')+'を参照してください。</p>';
*/
divWarn = document.createElement('div');
divWarn.className = 'titleChecker-warn';
divWarn.innerHTML = html;
mark.parentNode.insertBefore(divWarn, mark.nextSibling);
};
/*
* 記事名チェッカの処理を実行する。
* 引数:
* なし。
* 返値:
* 処理を実行したならば true
* 処理を実行しなかったならば false
*/
return function () {
/*
* 要素のdisabled属性をオンにする
* 引数:
* elements: 要素の配列
* 返値:
* なし
*/
var disableElements = function (elements) {
var lenElements = elements.length,
e,
i;
for (i = 0; i < lenElements; i += 1) {
e = document.getElementById(elements[i]);
if (e) {
e.disabled = true;
}
}
},
editform = document.getElementById('editform'),
checkResult,
mark;
// 利用者ごとの無効化
if (disableTitleChecker) {
return false;
}
// 検査は標準名前空間の記事に対してのみ行う
if (wgNamespaceNumber !== 0) {
return false;
}
// 検査は利用者が新規作成または編集しようとしたときにのみ行う
if (!editform) {
return false;
}
// 検査して結果を得る
checkResult = check({
ns: wgNamespaceNumber,
title: wgTitle,
body: document.getElementById('wpTextbox1').value
});
// 検査の結果、次のいずれかの処理を行う
// 許可:「警告」や「拒否」に該当する処理をしない場合は、何もしない
if (!checkResult) {
return false;
}
// 拒否:編集をできなくする
if (checkResult.action > 1) {
if (wgArticleId === 0) {
editform.parentNode.removeChild(editform);
} else {
disableElements([
'wpSummary',
'wpMinoredit',
'wpWatchthis',
'wpSave',
'wpPreview',
'wpDiff'
]);
document.getElementById('wpTextbox1').readOnly = true;
}
}
// 警告と拒否:説明文を表示する
if (skin === 'standard' || skin === 'cologneblue' ||
skin === 'nostalgia') {
mark = document.getElementById('specialpages') ?
document.getElementById('topbar') :
getElementsByClassName(document, 'h1', 'pagetitle')[0]
.nextSibling;
} else {
mark = document.getElementById('jump-to-nav') ||
document.getElementById('contentSub');
}
warn({
mark: mark,
action: checkResult.action,
reasons: checkResult.reasons,
for_redirect: checkResult.for_redirect
});
return true;
};
}());
/*
* 以上の処理は、ページ読み込みの際に実行する
*/
$(titleChecker);
// </source>