コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

MediaWiki:Test/vpTagHelper.js

お知らせ: 保存した後、ブラウザのキャッシュをクリアしてページを再読み込みする必要があります。

多くの WindowsLinux のブラウザ

  • Ctrl を押しながら F5 を押す。

Mac における Safari

  • Shift を押しながら、更新ボタン をクリックする。

Mac における ChromeFirefox

  • Cmd Shift を押しながら R を押す。

詳細についてはWikipedia:キャッシュを消すをご覧ください。

/*
 * 井戸端タグ支援ツール
 * [[利用者:Cpro|cpro]]
 * 井戸端サブページの編集画面に、タグ検索・編集機能を追加する
 */
if(mw.config.get('wgPageName').indexOf('Wikipedia:井戸端/subj/') == 0 && //井戸端サブページ
   (mw.config.get('wgAction') == 'edit' || mw.config.get('wgAction') == 'submit'))        //編集・プレビュー・差分確認時
{
	var vpTag = {};
	vpTag.categoryTitle =
		encodeURIComponent('Category:井戸端の話題/タグ別'.replace(/ /g, '_'))
		.replace('%3A', ':').replace('%2F', '/');
	vpTag.limit = 500;
	vpTag.URI =
		mw.config.get('wgServer') + wgScriptPath + '/api.php?format=json&callback=createVpTagList' +
		'&action=query&list=categorymembers&cmnamespace=14&cmprop=title' +
		'&cmlimit=' + vpTag.limit.toString() +
		'&cmtitle=' + vpTag.categoryTitle;
	vpTag.categoryPrefix = 'Category:井戸端の話題/';
	vpTag.positionId = 'editform';
	vpTag.tagList = [];
	vpTag.currentTagList = [];
	vpTag.recommendBlock = null;
	vpTag.searchResultBlock = null;
	
	$( function() {
		var sectionNum = -1;
		var sectionParam = document.getElementsByName('wpSection')[0];
		if(sectionParam) {
			sectionNum = parseInt(sectionParam.getAttribute('value').replace(/(?:T-)?(\d+)/, '$1'));
			if(isNaN(sectionNum)) sectionNum = -1;
		}
		if(sectionNum >= 1) return; //導入部以外の節編集モードでは無効

		var refNode = document.getElementById(vpTag.positionId);
		if(!refNode) return;
		
		var container = document.createElement('div');
		container.setAttribute('id', 'edittools_vptag');
		container.style.cssText = 'margin-top:0.25em;border-top:1px solid #ccc;font-size:90%';
		container.innerHTML =
			'<form action="#"><p>\n' +
				'<label for="vptagsearchinput" style="font-weight:bold">井戸端タグ検索:</label>\n' +
				'<input id="vptagsearchinput" type="text" />\n' +
				'<input type="text" style="position:absolute; visibility:hidden" />\n' + //dummy 誤送信防止
				'<button id="vptagappend" type="button">追加</button>\n' +
			'</p></form>\n' +
			'<p id="vptagsearchresult" class="vptagcontainer" style="line-height:1.8em;"></p>\n' +
			'<p style="border-top:1px solid #ccc; line-height:1.8em;" class="vptagcontainer">\n' +
				'<span style="font-weight:bold">おすすめタグ:</span>\n' +
				'<span id="vptagrecommend"></span>\n' +
			'</p>';
		
		refNode.parentNode.insertBefore(container, refNode);
		
		//動的に内容を変化させる要素の保持
		vpTag.recommendBlock = document.getElementById('vptagrecommend');
		vpTag.searchResultBlock = document.getElementById('vptagsearchresult');
		
		addHandler(document.getElementById('vptagsearchinput'), 'keyup', vpTagSearch);
		addHandler(document.getElementById('vptagappend'), 'click', vpTagAppendButton_onclick);
		
		vpTag.currentTagList = getCurrentVpTagList();
		
		mw.loader.load(vpTag.URI);
	});

}

//APIのクエリ結果からタグの配列を作成する
function createVpTagList(obj) {
	if(!obj['query'] || !obj['query']['categorymembers'])
		return;
	
	var cm = obj['query']['categorymembers'];
	for(var i = 0; i < cm.length; i++) {
		vpTag.tagList.push(cm[i]['title'].substring(vpTag.categoryPrefix.length));
	}
	
	//1回のロード件数 (vpTag.limit) より多ければ続きをロードする
	if(obj['query-continue'] && obj['query-continue']['categorymembers'] && obj['query-continue']['categorymembers']['cmcontinue']) {
		mw.loader.load(vpTag.URI + '&cmcontinue=' + obj['query-continue']['categorymembers']['cmcontinue']);
	} else {
		//ロード終了後処理: おすすめタグのボタンを生成
		createVpTagButtons(getRecommendedVpTagList(), vpTag.recommendBlock)
	}
}

function createVpTagButtons(tagList, container) {
	for(var i = 0; i < tagList.length; i++) {
		var a = document.createElement('a');
		a.setAttribute('href', 'javascript:void(0);');
		a.appendChild(document.createTextNode(tagList[i]));
		toggleVpTagButtonStyle(a, false);
		for(var j = 0; j < vpTag.currentTagList.length; j++) {
			if(tagList[i].toUpperCase() == vpTag.currentTagList[j].toUpperCase())
				toggleVpTagButtonStyle(a, true);
		}
		
		addHandler(a, 'click', vpTagButton_onclick);
		
		container.appendChild(document.createTextNode(' '));
		container.appendChild(a);
	}
}

function clearVpTagButtons(container) {
	container.innerHTML = '';
}

function getRecommendedVpTagList(tagList) {
	if(tagList == undefined) tagList = vpTag.tagList;
	
	var textarea = document.getElementById('wpTextbox1');
	if(!textarea) return;
	var text = textarea.value.toUpperCase()
		.replace(/\(UTC\)/g, '') //署名の(UTC)は拾わないように除去
		.replace(/<!--.+?-->/g, ''); //コメント内を拾わない
	
	//井戸端タグ以降を検索対象とする
	var searchStart = text.indexOf('{{VPTAG');
	if(searchStart < 0) searchStart = 0;
	
	var recList = [];
	for(var i = 0; i < tagList.length; i++) {
		if(text.indexOf(tagList[i].toUpperCase(), searchStart) >= 0)
			recList.push(tagList[i]);
	}
	return recList;
}

function getVpTagSearchList(query, tagList) {
	if(tagList == undefined) tagList = vpTag.tagList;
	
	var searchList = [];
	for(var i = 0; i < tagList.length; i++) {
		if(tagList[i].toUpperCase().indexOf(query.toUpperCase()) >= 0)
			searchList.push(tagList[i]);
	}
	return searchList;
}

function getCurrentVpTagList() {
	var tags = [];
	
	var textarea = document.getElementById('wpTextbox1');
	var m = textarea.value.match(/\{\{vptag(?:\s*\|\s*([^{}]*?)\s*)?\}\}/i);
	if(!m) return tags;
	
	if(m[1] && m[1].length > 0)
		tags = m[1].split(/\s*\|\s*/);
	
	return tags;
}

function toggleVpTagButtonStyle(button, toggled) {
	var commonStyle = 'white-space:nowrap; padding:0 2px;';
	if(toggled) {
		button.style.cssText = commonStyle + ' border:inset 1px #ccc; background-color:#eee';
		button.className = 'vptagbutton vptagbuttontoggled';
	} else {
		button.style.cssText = commonStyle;
		button.className = 'vptagbutton';
	}
}

//events
function vpTagSearch(e) {
	if(window.attachEvent && !window.opera) //MSIE
		e = window.event;
	
	clearVpTagButtons(vpTag.searchResultBlock);
	
	var query = (e.target || e.srcElement).value;
	if(query.length == 0) return;
	
	createVpTagButtons(getVpTagSearchList(query), vpTag.searchResultBlock);
}

function vpTagButton_onclick(e) {
	if(window.attachEvent && !window.opera) //MSIE
		e = window.event;
	var target = (e.target || e.srcElement);
	
	var toggled = toggleVpTag(target.innerHTML);
	toggleVpTagButtonStyle(target, toggled);
}

function vpTagAppendButton_onclick(e) {
	var tagName = document.getElementById('vptagsearchinput').value;
	toggleVpTag(tagName);
}

function toggleVpTag(tagName) {
	var textarea = document.getElementById('wpTextbox1');
	var reg = /\{\{vptag(?:\s*\|\s*([^{}]*?)\s*)?\}\}/i
	var m = textarea.value.match(reg);
	if(!m) {
		//テンプレートが記述されていなければ </noinclude> の直前にタグ追加
		reg = /\s*(?=<\/noinclude>)/i
		m = textarea.value.match(reg);
		if(!m) return;
	}
	
	var tags = [];
	if(m[1] && m[1].length > 0)
		tags = m[1].split(/\s*\|\s*/);
	
	var toggled = true;
	for(var i = 0; i < tags.length; i++) {
		if(tags[i] == tagName) {
			tags.splice(i, 1);
			toggled = false;
			break;
		}
	}
	if(toggled)
		tags.push(tagName);
	
	vpTag.currentTagList = tags;
	
	var dest = '{{vptag|\n' + tags.join(' | ') + '\n}}';
	textarea.value = textarea.value.replace(reg, dest);
	
	return toggled;
}