コンテンツにスキップ

利用者:NA sounds/new page watcher.js

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

多くの WindowsLinux のブラウザ

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

Mac における Safari

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

Mac における ChromeFirefox

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

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

//<pre>
function new_page_watcher(){

with( new_page_watcher ){

/***************import*/
if( !na_lib.message ) na_lib();

if( !na_lib.browser.with_namespace ) /*ie*/
    for( var p in na_lib )
      eval( "var "+p+" = na_lib."+p+";" );

with(na_lib){

/***************定数*/
var _prog_name = "new_page_watcher";	//プログラムの名前
var _page_name = _prog_name;
var _prog_version = "0.1";

//この辺は決め打ちでも良いかも。
var _wiki_uri_base = "/wiki";
var _member_uri_base = _wiki_uri_base + "/" + encodeURIComponent("利用者") + ":";
var _save_page_name = encodeURIComponent("利用者") + ":"+ encodeURIComponent(wgUserName) + "/" + _page_name; //特別:Mypageに切り替えるべき?
var _save_page_base = "/w/index.php?title=";

var _content_id = "content";	//wikipediaのコンテンツのid。view_tabsetで使う


//設定の値。<div class='x-config'><div class='debug_level'>1</div></div>の様に数値が設定できる。
//idやnameではなくclassを利用する理由は謎
var opts = {	"enable_message_output":false,
		"debug_level":"2",		//0=debug, 1=verbose, 2=error

	 	"replace_tools":false,
		"enable_section_editor": false,
		"enable_comment_visualization": false,//コメントの可視化。mediawikiがコメントを除去してしまうため全く動かない
		"add_red_link_list":true,

		"save_page_name":_save_page_name,	//出力先のページ。このページのresults_section番目のsectionが出力先
		"results_section":"1",		//出力先。この番号のセクションを丸ごと書き換える。楽なので。
		"disable_version_check":true,	//現在versionは特に意味があるわけではない。
		"results_upload_preview":true,	//結果の書き込み時に、previewを行う。
		"reject_owned":true,		//自分の結果をダウンロードしない。
		"load_inner_results":true,	//ページ内の<div id='x-results'>を読み込む。
						//faleの場合、wgUserNameと同じ名前のmemberを読み込む。
		"auto_load_size":"6",
		"auto_loading_interval":"5000",	//5sec

		"replace_content_link":true,	//contentとして読んだページのリンクにonclickを付けてview_page()に切り替える
		"add_check_list_separator":true,	//check_listにhr class="separator"を入れる。

		"add_member_name":true,
		"input_size":"60"
};


/****************/
var _message_tab = undefined;
function config_func(element){
	var config_elements = element.getElementsByTagName( "div" );
	for( var i=0; i<config_elements.length; i++ ){
		var s = config_elements[i].getAttribute( "name" ); //divはname attrを持たない?
		if( !s || s.length <= 0 ){
			if( browser.setAttr_class )	s = config_elements[i].getAttribute( "class" );
			else			s = config_elements[i].className;
		}
		var val = get_text( config_elements[i] );
		if( val == "true" ){
			opts[s] = true;
		}
		else if( val == "false" ){
			opts[s] = false;
		}
		else {
			opts[s] = val;
		}
	}
}

/***************拡張ツール類*/
function setup_tools( element ){
	if( opts["enable_message_output"] ){
		_message_tab = create_tab( "message", "msg" );
		init_message_element( _message_tab['frame'], Number(opts["debug_level"]) );
	}

	if( opts["replace_tools"] ){
		var tabset = replace_tools(element);
		if( opts["enable_message_output"] ){
			tabset.append_tab( _message_tab, false, false );
		}

		if( opts["add_red_link_list"] ){
			var red_link_tab = create_tab("red_link_list_tab", "RL");
			var rll_div = createElement_defaultNS( "div");
			rll_div.setAttribute( "id", "x-red_link_list" );
			red_link_tab['frame'].appendChild( rll_div );
			tabset.append_tab( red_link_tab, false, false );
		}
	}

	if( opts["enable_section_editor"] ){
		var elements = document.getElementsByTagName("a");
		for( var i=0; i<elements.length; i++ )
			add_section_editor(elements[i]);
	}

	if( opts["enable_comment_visualization"] )
		comment_visualization( document.getElementById("bodyContent") );
}

var _tool_ids = [ 'p-navigation', 'p-help', 'p-search', 'p-tb', 'p-lang' ];
var _tool_tabset_name = "col_one";
var _tool_tabset = undefined;
function replace_tools( element ){
	var column_one = element;
	var tabset = new tabset_Constructor( _tool_tabset_name );
	tabset.append_tab( create_tab("_tools", "tools"), false );

	var tabset_node = tabset.get_node( undefined, "_tools", true );
	var tool_tabframe = tabset.tabs["_tools"]["frame"];

	class_change( tabset_node, "portlet", true );
	tool_tabframe.style.padding = "0";
	tool_tabframe.style.borderLeft = tool_tabframe.style.borderRight = "0";

	for( var i=0; i<_tool_ids.length; i++ ){
		node = document.getElementById( _tool_ids[i] );
		if( node ){
			var e = node.parentNode.removeChild( node );
			tool_tabframe.appendChild( e );
		}
	}
	column_one.appendChild( tabset_node );

	tabset_node.style.height = (tabset.set_tabframe_height()+1) + "px"; //umm.

	_tool_tabset = tabset;
	return tabset;
}


function red_link_list( element ){
	var elements = getElementsByTagAttrValue( document, "a", "class", "new");
	var ul = createElement_defaultNS( "ul" );
	for( var i=0; i<elements.length; i++ ){
		var li = createElement_defaultNS( "li" );
		li.appendChild( elements[i].cloneNode(true) );
		ul.appendChild(li);
	}
	element.appendChild( ul );
}


/***************view tabset*/
var _content_tabset = undefined;
function create_content_tabset( element ){
	_content_tabset = new tabset_Constructor( "view_tabset" );
	var top_tab = "";
	if( _message_tab ){
		_content_tabset.append_tab( _message_tab, false, false );
		top_tab = _message_tab["name"];
	}
	element.appendChild( _content_tabset.get_node(undefined, top_tab, false) );
}

function view_page( title, bg, url, element ){
	if( !title )
		title = url;
	if( !url )
		url = _wiki_uri_base + "/" + encodeURIComponent(title);

	if( _content_tabset ){
		var tabname = "_content_"+title+"_tab";
		if( _content_tabset.select_tab(tabname) )
			return false;

		var tab = create_tab( tabname, title );

		tab.onchange = function(title, flag){
			if( flag ) editor_update(title);
		}.preset_args(title);

		_content_tabset.append_tab( tab, !bg, true );

		var func = function(title, tab, xmlhttp){
			var doc = parse_from_string( xmlhttp.responseText );
			var tmp = getElementByTagAttrValue( doc, "div", "id", _content_id );
			if( !tmp ){ message("content not found.",2); return false; }
			//tmp.className = ""; //umm?
			//tmp.setAttribute( "id", tab['name']+"_content" );
			tmp.setAttribute( "id", undefined ); //これは平気?
			var node = document.importNode( tmp, true );

			if( opts["enable_comment_visualization"] )
				comment_visualization( node );

			if( opts["enable_section_editor"] ){
				var edit = createElement_defaultNS( "span" );
				class_change( edit, "editsection", true );
				var url = _save_page_base + encodeURIComponent(title) + "&action=edit";
				edit.innerHTML = "[<a href='"+url+"'>編集</a>]"
				var firstHeading = node.getElementsByTagName("h1")[0];
				if( firstHeading )
					insertFirstChild( firstHeading, edit );
			}

			if( opts["replace_content_link"] ){
				var elements = node.getElementsByTagName("a");
				for( var i=0; i<elements.length; i++ ){
					if( !opts["enable_section_editor"] || !add_section_editor(elements[i]) ){
						var func = redirect_to_view_page.preset_args(get_text(elements[i]), false, elements[i].getAttribute("href",2)); /*ie*/
						addEventListener( elements[i], "click", func, true );
					}
				}
			}

			tab['frame'].appendChild( node );
		}
		download_xml( url, func.preset_args(title, tab), tab['tip'] );
	}
}


//a要素のclickイベントとして登録する。
function redirect_to_view_page(key, bg, url, e){
	e.preventDefault();
	view_page(key, bg, url);
	if( key ){ editor_update(key); }
}


/***************エディタ周り*/
var _current_item = undefined;
var _editor = undefined;		//input
var _editor_target = undefined;
var _textarea = undefined;		//textarea
function create_editor(element){
	_editor = createElement_defaultNS( "input" );
	_editor.type = "text";
	_editor.size = Number(opts["input_size"]);
	addEventListener( _editor, "change", editor_onchange.preset_args(_editor), false );
	element.appendChild( _editor );

	_editor_target = document.getElementById("x-editor_target");

	var e = document.getElementById("x-test_textarea");
	if( e ){
		_textarea = createElement_defaultNS( "textarea" );
		e.appendChild( _textarea );
	}

	function editor_onchange( element ){
		var value = element.value;
		message( "editor_onchange(), "+value, 1 );
		if( _current_item ){
			//tagも入れられるように、innerHTMLが一番適当...?
			var genres_element = _current_item['dd'][0].getElementsByTagName( "ul" )[0];
			if( genres_element ){
				_current_item['dd'][0].removeChild( genres_element );
			}
			_current_item['dd'][0].innerHTML = value;
			if( genres_element ){
				insertFirstChild( _current_item['dd'][0], genres_element );
			}
		}
		if( _textarea ){
			_textarea.value = array_to_wikifmt(_check_items);
		}
		return false;
	}
}

var _genre_checkboxes = undefined;
function genre_list( element ){
    var elements = element.getElementsByTagName("ul");
    for( var i=0; i<elements.length; i++ ){
	var root = elements[i];
	if( !root ){return false;}

	var genres = root.getElementsByTagName( "li" );
	for( var j=0; j<genres.length; j++ ){
		var s = get_text(genres[j]).replace(/\s*$/,""); //ie?
		var input = createElement_defaultNS( "input" );
		input.type = "checkbox";	
		input.checked = false;
		input.name = s;
		addEventListener( input, "click", genre_onchange.preset_args(s,input), false );
		insertFirstChild( genres[j], input );
	}
    }
    _genre_checkboxes = element.getElementsByTagName( "input" );

    function genre_onchange( name, input ){
	var val = input.checked;
	message( name+" "+val, 0 );
	if( _current_item ){
		var old_e = _current_item['dd'][0].getElementsByTagName( "ul" )[0];
		var new_e = update_genres_element(old_e);
		if( !old_e ){
			insertFirstChild( _current_item['dd'][0], new_e );
		}
	}
	if( _textarea ){
		_textarea.value = array_to_wikifmt(_check_items);
	}
    }

    function update_genres_element( genres_element ){
	if( !genres_element ){
		genres_element = createElement_defaultNS( "ul" );
	}
	var genres = _genre_checkboxes;
	var last_e = undefined;
	for( var i=0; i<genres.length; i++ ){
		var e = getElementsByTextNodeValue( genres_element, "li", genres[i].name )[0];
		if( e ){
			if( !genres[i].checked )
				genres_element.removeChild( e );
			else
				last_e = e;
		}
		else if( genres[i].checked ){
			var new_e = createElement_defaultNS( "li" );
			set_text( new_e, genres[i].name, true );
			if( last_e )
				insertAfter( genres_element, new_e, last_e );
			else
				insertFirstChild( genres_element, new_e );
		}
	}
	return genres_element;
    }
}


function editor_update( title ){
	if( !_check_items || !_check_items[title] ){
		return false;
	}
	if( _current_item ){
		class_change( _current_item['dt'], "selected", false );
		class_change( _current_item['dd'][0], "selected", false );
	}
	_current_item = _check_items[title];
	class_change( _current_item['dt'], "selected", true );
	class_change( _current_item['dd'][0], "selected", true );

	if( _editor_target ) { set_text(_editor_target,title,true);  }

	var tmp = _current_item['dd'][0].cloneNode(true); //バラバラにしてから使うので。
	var genres_element = tmp.getElementsByTagName("ul")[0];
	if( genres_element ){ tmp.removeChild(genres_element); }

	if( _editor ) {
		node_to_wikifmt(tmp);
		_editor.value = tmp.innerHTML;
		_editor.focus();
	}
	if( _genre_checkboxes ){
		for( var key in _genre_checkboxes )
			_genre_checkboxes[key].checked = false;

		if( genres_element ){
			var genre_elements = genres_element.getElementsByTagName("li");
			for( var i=0; i<genre_elements.length; i++ ){
				var s = get_text(genre_elements[i]).replace(/\s*$/,"");  //ie?
				for( var j=0; j<_genre_checkboxes.length; j++ ){
					if( _genre_checkboxes[j].name == s )
						_genre_checkboxes[j].checked = true;
				}
			}
		}
	}
}


/***************更新ボタン*/
function create_update_button( element ){
	var input = createElement_defaultNS( "input" );
	input.type = "button";
	addEventListener( input, "click", update_members_results, false );
	input.value = "update";
	element.appendChild( input );

	function update_members_results() {
		if( _check_items ){
			_current_item = undefined;
			if( _editor_target )
				set_text( _editor_target,"none" );

			if( _editor )
				_editor.value = "";

			if( _update_members_results )
				_update_members_results(); //もう一度ダウンロード。
		}
	}
}


/***************自動読み込み*/
function init_auto_loading( element ){
	if( !_content_tabset ) return;

	var _auto_loading_timer = undefined;
	var _auto_loading_list = [];
	var _auto_loading_itr = 0;

	var input = createElement_defaultNS( "input" );
	input.type = "checkbox";
	input.checked = false;

	var f = auto_loading.preset_args(input);
	addEventListener( input, "click", auto_loading_onoff.preset_args("f = "+f.global_func().toString()+"; f();", input), false );

	element.appendChild( input );
	element.appendChild( document.createTextNode("auto loading") );

	for( var key in _check_items )
		_auto_loading_list.push( key );

	function auto_loading_onoff( func_str, input ){
		var flag = input.checked;
		if( _auto_loading_timer )
			clearInterval( _auto_loading_timer );

		//_auto_loading_listはlockするべき?
		if( flag ){
			message( "auto loading start", 1 );
			if( _auto_loading_list.length <= _auto_loading_itr )
				_auto_loading_itr = 0;

			_auto_loading_timer = setInterval( func_str, Number(opts["auto_loading_interval"]) );
		}
		else
			message( "auto loading stop", 1 );
	}

	function auto_loading( input ){
		message( "auto loading...", 0 );
		if( _auto_loading_list && _auto_loading_itr < _auto_loading_list.length ){
			var count = _content_tabset.get_tabs_num();
			message( "size=" + Number(opts["auto_load_size"]) + " list length="+_auto_loading_list.length + " itr="+_auto_loading_itr, 0 );
			if( count < Number(opts["auto_load_size"]) ){
				class_change( input, "downloading", true );
				view_page( _auto_loading_list[_auto_loading_itr], true );
				class_change( input, "downloading", false );
				_auto_loading_itr += 1;
			}
		}
		else{
			input.checked = false;
			auto_loading_onoff("", input);
		}
	}
}



/***************チェックリスト*/
var _check_items = undefined;		//dl_to_arrayの返値。編集対象になる。
var _check_list_element = undefined;	//_check_itemsが在れば、必ず存在する?
function check_list_func( element ){
	var root = merge_dl( element.getElementsByTagName("dl") ); //マージしない方がよい?
	if( !root )
		return false;

	class_change( root, "check_items", true );
	_check_list_element = root;

	_check_items = dl_to_array( root, true );

	for( var k in _check_items ){ 
		var item = _check_items[k];
		if( opts["add_check_list_separator"] ){
			var hr = createElement_defaultNS( "hr" );
			class_change( hr, "separator", true );
			item.dt.parentNode.insertBefore( hr, item.dt );
		}

		if( item.dd[0].hasChildNodes() ){
			class_change( item.dd[0], "system", true );
			if( opts["add_member_name"] ){
				var name_tag = createElement_defaultNS( "span" );
				class_change( name_tag, "member_name", true );
				set_text( name_tag, "system", true );
				insertFirstChild( node, name_tag );
			}
			var dd = createElement_defaultNS( "dd" );
			root.insertBefore( dd, item.dd[0] );
		}

		var link = _check_items[k]['dt'].getElementsByTagName("a")[0];

		addEventListener( link, "click", redirect_to_view_page.preset_args(k, false, link.getAttribute("href",2)), true ); /*ie*/
		addEventListener( _check_items[k]['dd'][0], "click", editor_update.preset_args(k), false );
	}

	if( _results_dl_array )
		load_default( _results_dl_array );
}

//デフォルト値の読み込みと、_check_itemsの初期化。
//複数回呼んだ場合、ulが複数出来る可能性がある。
function load_default( array ){
	for( var key in _check_items ){
		message( "add array, name = "+key, 0 );
		if( array[key] ){
			for( var j=0; j<array[key]['dd'].length; j++ ){
				message( "add dd, key="+key+" j="+j, 0 );
				_check_items[key]['dd'][0].innerHTML += array[key]['dd'][j].innerHTML;
				if( opts["replace_content_link"] ){
					var elements = _check_items[key]['dd'][0].getElementsByTagName("a");
					for( var i=0; i<elements.length; i++ ){
						var func = redirect_to_view_page.preset_args(get_text(elements[i]), false, elements[i].getAttribute("href",2)); /*ie*/
						addEventListener( elements[i], "click", func, true );
					}
				}
			}
			var ul = _check_items[key]['dd'][0].getElementsByTagName( "ul" )[0];
			if( ul ){
				_check_items[key]['dd'][0].removeChild(ul);
				insertFirstChild( _check_items[key]['dd'][0], ul );
			}
		}

		if( !_check_items[key]['dd'][0].hasChildNodes() ) { //
			var ul = createElement_defaultNS("ul" );
			_check_items[key]['dd'][0].appendChild( ul );
		}
	}
	if( _textarea )
		_textarea.value = array_to_wikifmt(_check_items);
}


/***************デフォルト値として読み込まれるデータ*/
//membersに自分を登録してload_defaultする機能を付けたので、余り使われないかも。
var _results_dl_array = undefined;		
function results_func( element ){
	var root = merge_dl( element.getElementsByTagName("dl") );
	if( !root )
		return false;

	if( opts["load_inner_results"] ){
		root.innerHTML = remove_LF(root.innerHTML); //umm.
		_results_dl_array = dl_to_array( root );
	}
}


/***************他メンバーの結果読み込み*/
var _update_members_results = undefined;
function members_func( element ){
	var _members = {};		//他メンバーのリスト。
	var members_results = {};	//各メンバーの分類結果。dl_to_arrayの返値が入っている。

	var root = element.getElementsByTagName("ul")[0];
	if( !root ){
		return false;
	}

	var nodes = element.getElementsByTagName("a");
	for( var i=0; i<nodes.length; i++ )
		_members[i] = get_text(nodes[i]);

	for( var k in _members ){
		if( _members[k] == wgUserName ){
			if( ! opts["load_inner_results"] ){ //登録されていない人は自分のページが読めない? 特別:MyPageを使って書き直し?
				var url = _member_uri_base + encodeURIComponent(_members[k]) + "/" + _page_name;
				message( "load default from "+url, 2 );
				download_xml( url, update_member_results.preset_args(_members[k], true, members_results, _check_list_element, _check_items), undefined );
			}
			if( opts["reject_owned"] ){ //wgPageName == _save_page_name ) //_の扱いが微妙。
				message( "remove own", 1 );
				delete _members[k];
			}
		}
	}

	_update_members_results = download_members_results.preset_args( _members, members_results, _check_list_element, _check_items );
	_update_members_results();

	//他メンバーの分類結果を読み取る。
	function download_members_results( members, members_results, dl_element, base_array ){
		for( var k in members ){
			message( "member="+members[k], 1 );

			var url = _member_uri_base + encodeURIComponent(members[k]) + "/" + _page_name;
			download_xml( url, update_member_results.preset_args(members[k], false, members_results, dl_element, base_array), undefined );
		}
	}

	function update_member_results(name, defaults, members_results, dl_element, base_array, xmlhttp) {
		var nodes = parse_from_string( xmlhttp.responseText, true );
		if( nodes ){
			var version_el = getElementByTagAttrValue( nodes, "div", "id", _prog_name+"_version");
			var version;
			if( version_el ) version = get_text(version_el);
			if( version == "0.1" || opts["disable_version_check"] ){
				var n = getElementByTagAttrValue(nodes, "div", "id", "x-results")
				if( !n ){ message( "results not found, user "+name, 0 ); return; }
				var results_node = document.importNode(n, true);
				if( results_node ){
					message( "create dl array, user="+name, 1 );
					var new_array = dl_to_array( merge_dl(results_node.getElementsByTagName("dl")) );
					if( defaults ){
						load_default(new_array);
					}
					else{
						var old = members_results[name];
						update_array( dl_element, base_array, new_array, old, name );
						members_results[name] = new_array;
						var counter = 0;
						for( var k in members_results[name] )	counter +=1;
						message( "load "+name+"'s results. num="+counter, 2 );
					}
				}
			}
			else {
				message( "version error! name="+name, 2 );
			}
		}
		else{
			message( "response error?<br/>response text: "+xmlhttp.responseText, 0 );
		}
	}

	function update_array(dl_element, base_array, new_array, old_array, name){
		for( var key in base_array ){
			message( "key="+key, 1 );
			//消去はしない。面倒。実害はないはず。
			if( !new_array[key] ){
				continue;
			}
			for( var j=0; j<new_array[key]['dd'].length; j++ ){
				message( "found dd, key="+key+" name="+name, 1 );

				var node = new_array[key]['dd'][j];
				class_change( node, "member", true );
				class_change( node, "member_"+name, true );
				addEventListener( node, "click", editor_update.preset_args(key), false );

				//リンクの変換
				if( opts["replace_content_link"] ){
					var elements = node.getElementsByTagName("a");
					for( var i=0; i<elements.length; i++ ){
						var func = redirect_to_view_page.preset_args(get_text(elements[i]), false, elements[i].getAttribute("href",2)); /*ie*/
						addEventListener( elements[i], "click", func, true );
					}
				}

				//並べ替え。umm.
				var ul = node.getElementsByTagName( "ul" )[0];
				if( ul ){
					node.removeChild(ul);
					insertFirstChild( node, ul );
				}

				if( opts["add_member_name"] ){
					var name_tag = createElement_defaultNS( "span" );
					class_change( name_tag, "member_name", true );
					set_text( name_tag, name, true );
					insertFirstChild( node, name_tag );
				}

				if( old_array && old_array[key] && old_array[key]['dd'][j] ){
					message( "update dd key="+key+", name="+name, 1 );
					dl_element.replaceChild(new_array[key]['dd'][j], old_array[key]['dd'][j]);
				}
				else {
					message( "append dd key="+key+", name="+name, 1 );
					insertAfter( dl_element, new_array[key]['dd'][j], base_array[key]['dd'][0] );
				}
			}
		}
	}
}



/***************オモシロ機能:セクションエディタ*/
var _section_edit_num = 0;
function add_section_editor(link){
	var element = link.parentNode;
	if( !class_check( element, "editsection" ) )
		return false;

	var args = link.getAttribute("href",2).split( "&" ); //全体的に手抜き。/*ie*/
	var section;
	var url = args[0];
	for( var j=1; j<args.length; j++ ){
		var pair = args[j].split( "=" );
		if( pair[0] == "section" )
			section = pair[1];
	}
	var id = "section_edit_"+_section_edit_num+"_s"+section;
	addEventListener( link, "click", click_ev.preset_args(id, url, section, element), true );

	return true;

	function click_ev( id, url, section, editsect_element, e ){
		var prev_element = editsect_element.parentNode; //umm.
		e.stopPropagation();
		e.preventDefault();
		var preview_id = "wikiPreview" + id;
		var section_editor = document.getElementById(id);
		if( !section_editor ){
			var tmp_iframe = createElement("iframe", "temporary");
			tmp_iframe.setAttribute( "id", id+"_tmp" );
			tmp_iframe.setAttribute( "name", id+"_tmp" );
			tmp_iframe.style.display = "none";

			var preset_inputs_data = {
				"save":		["submit", "wpSave", "save", false],
				"diff":		["submit", "wpDiff", "diff", false],
				"preview":	["submit", "wpPreview", "preview", false],
				"instaview":	["button", "", "instaview", false],
				"summary":	["text", "wpSummary", "", true ],
				"minor":	["checkbox", "wpMinoredit", "", true ],
				"watch":	["checkbox", "wpWatchthis", "", true ],
				"textarea":	["textarea", "wpTextbox1", "now loading...", true ]
			}
			var form = create_edit_form( id, args[0], submit_section_editor.preset_args(preview_id, tmp_iframe), section, preset_inputs_data );
			function submit_onclick(form, e){ form.action_name = e.target.name; };
			for( var k in form.preset_inputs ){
				var input = form.preset_inputs[k];
				class_change( input, k, true );
				if( input.type == "submit" )
					addEventListener(input, "click", submit_onclick.preset_args(form), false);
			}
			_section_edit_num += 1;

			insertAfter( form, document.createTextNode("minor"), form.preset_inputs["minor"] );
			insertAfter( form, document.createTextNode("watch"), form.preset_inputs["watch"] );

			var section_editor = createElement_defaultNS("div");
			class_change( section_editor, "section_editor", true );
			section_editor.appendChild( form );
			section_editor.setAttribute( "id", id );

			section_editor.appendChild( tmp_iframe );

			if( window.InstaView && InstaView.convert ){
				function do_instaview( preview_id ){
					var elm = document.getElementById( preview_id );
					if( !elm ){
						elm = createElement("div", "preview", ["frame_box", "relative"] );
						elm.setAttribute( "id", preview_id );
						insertAfter( form.parentNode, elm, form );
					}
					elm.innerHTML = InstaView.convert(form.preset_inputs["textarea"].value);
					//リンクの切り替えなども必要?
					if( opts["replace_content_link"] ){
					}
				}
				addEventListener( form.preset_inputs["instaview"], "click", do_instaview.preset_args(preview_id), false );
			}
			else{
				form.preset_inputs["instaview"].style.display = "none";
			}

			insertAfter( prev_element.parentNode, section_editor, prev_element );
		}
		else {
			if( section_editor.style.display != "none" )
				section_editor.style.display = "none";
			else
				section_editor.style.display = "block";
		}
	}

	function submit_section_editor( preview_id, tmp_iframe, form, e ){
		var preview_mode = false;
		if( form.action_name && form.action_name != "wpSave" )
			preview_mode = true;

		if( !tmp_iframe ){ //もっとましな方法は?
			if( preview_mode ){ e.preventDefault(); }
			form.target = undefined;
			return !preview_mode;
		}

		if( preview_mode ){
			addEventListener( tmp_iframe, "load", update_preview.preset_args( tmp_iframe, form ) );
			form.target = tmp_iframe.getAttribute("id");
		}
		else if( _content_tabset ){
			var tab = append_iframe_tab( _content_tabset, "save" );
			form.target = tab['iframe'].getAttribute("id");
		}

		function update_preview( iframe, form ){  /*ページから内容だけ奪う*/
			message( "update_preview", 1 );
			var n = iframe.contentDocument.getElementById("wikiPreview");
			if( !n || !n.hasChildNodes() ){
				message( "wikiPreview not found.", 1 );
				n = iframe.contentDocument.getElementById("wikiDiff");
				if( !n ){
					message( "wikiPreview and wikiDiff not found.", 2 );
					return false;
				}
			}
			var preview_div = document.importNode(n, true);
			var h2;
			if( get_text(preview_div.firstChild) == "プレビュー" ){ //umm. remove <h2>preview</h2>
				preview_div.removeChild( preview_div.firstChild );
				while( preview_div.hasChildNodes() ){
					var node = preview_div.removeChild( preview_div.firstChild );
					if( node.nodeType == browser.Node.ELEMENT_NODE && class_check(node, "previewnote") ){
						break;
					}
/*					if( node.nodeName[0] == "H" || node.nodeName[0] == "h" ){
						h2 = node;
						break;
					}
*/
				}
			}
			while( preview_div.hasChildNodes() ){
				if( remove_LF(get_text(preview_div.lastChild)).length <= 0 ){
					preview_div.removeChild( preview_div.lastChild );
				}
				else{
					break;
				}
			}

			var new_div = createElement("div", "preview", ["frame_box", "relative"] );
			new_div.setAttribute( "id", preview_id );
			if( h2 ){ new_div.appendChild(h2); }
			new_div.appendChild(preview_div);

			var catlinks = iframe.contentDocument.getElementById("catlinks");
			if( catlinks )
				new_div.appendChild( catlinks );

			if( opts["replace_content_link"] ){
				//fixme
			}

			var old = document.getElementById( preview_id );
			if( old )
				old.parentNode.replaceChild( new_div, old );
			else
				insertAfter( form.parentNode, new_div, form );
		}
	}
}


/***************フォーム。データの保存*/
function create_upload_form( element ){
	var url = _save_page_base + opts["save_page_name"];
	var preset_inputs_data = { "textarea":	["textarea", "wpTextbox1", "", false ] };
	if( opts["results_upload_preview"] )
		preset_inputs_data["(save)"] = ["submit", "wpPreview", "preview", false];
	else
		preset_inputs_data["save"] = ["submit", "wpSave", "save", false];

	var submit_form = create_edit_form( "editform", url, upload_results, opts["results_section"], preset_inputs_data );
	submit_form.preset_inputs["textarea"].style.display = "none";
	element.appendChild( submit_form );

	function upload_results( submit_form, e ){
		//var version = "<div id='"+_prog_name+"_version'>"+_prog_version+"</div>\n";
		submit_form.preset_inputs["textarea"].value = "== results ==\r\n<div id='x-results'>\r\n" + array_to_wikifmt(_check_items) + "</div>";
		var tab = append_iframe_tab( _content_tabset, "save", opts["results_upload_preview"] );
		submit_form.target = tab['iframe'].getAttribute( "id" );
	}
}


/***************フォーム。セクション単位の編集のサポート。一回action=editで(節単位)編集ページを呼びだし、inputを奪う*/
/*
var preset_inputs = {
	//key: [ type = String, name = String, value = String, read value = bool ]
	"preview":	["submit", "wpPreview", "preview", false],
	"save":		["submit", "wpSave", "save", false],
	"textarea":	["textarea", "wpTextbox1", "now loading...", true ],
	"summary":	["text", "wpSummary", "", true ]
}
*/
//返値はformオブジェクト。idは設定されない。
//submit_func = function( String, String, Function(From, Event), String or undefined, bool or undefined )
function create_edit_form( name, url, submit_func, section, preset_inputs ){
	var form = createElement_defaultNS( "form" );
	form.name = name;
	form.action = url + "&action=submit",
	form.method = "POST";
	form.enctype = "multipart/form-data";

	addEventListener( form, "submit", submit_func.preset_args(form), true );

	form.preset_inputs = {};
	for( var key in preset_inputs ){
		var e;
		if( preset_inputs[key][0] != "textarea" ){
			e = createElement_defaultNS("input");
			e.type = preset_inputs[key][0];
		}
		else{ e = createElement_defaultNS("textarea"); }
		e.name = preset_inputs[key][1];
		e.value = preset_inputs[key][2];
		form.appendChild(e);
		form.preset_inputs[key] = e;
	}

	var edit_page_url = url + "&action=edit";
	if( section ){
		edit_page_url += "&section="+section;
	}
	download_xml( edit_page_url, func.preset_args(form, preset_inputs), undefined );

	return form;

	//一度編集画面を呼びだし、input tagを奪う。
	//wpEdittimeが正しくないと、wpSectionが効かない。(多分)
	//二度め以降にsaveする場合、wpEdittimeは更新した方が良い?
	function func( form, preset_inputs, xmlhttp ){
		var nodes = parse_from_string( xmlhttp.responseText );
		var f = getElementByTagAttrValue( nodes, "*", "id", "editform" );
		if( !f ){ message( "editform not found.", 2 ); return false; }

		var elements = f.getElementsByTagName( "input" );
		get_inputs( form, elements, preset_inputs );

		elements = f.getElementsByTagName( "textarea" );
		get_inputs( form, elements, preset_inputs );

		function get_inputs( form, elements, preset_inputs ){
			for( var i=0; i<elements.length; i++ ){
				var name = elements[i].getAttribute("name");
				var type = elements[i].getAttribute("type");
				var preset = false;
				for( var k in preset_inputs ){
					if( preset_inputs[k][1] == name ){
						preset = true;
						if( preset_inputs[k][3] ){
							message( "read "+name, 1 );
							if( type == "checkbox" ){
								form.preset_inputs[k].checked = elements[i].getAttribute("checked");
							}
							var value = elements[i].getAttribute("value");
							if( !value && elements[i].nodeName == "textarea" )
								value = get_text(elements[i]);
							form.preset_inputs[k].value = value;

							//defaultChecked, defaultValue
						}
						else
							message( "preset. ("+name+")", 1 );
					}
				}
				if( !preset ){
					message( "add "+name, 1 );
					var n = document.importNode( elements[i], true );
					n.style.display = "none";
					form.appendChild( n );
				}
			}
		}
	}
}


/***************サポート*/
var _iframe_count=0;
function append_iframe_tab( tabset, name, bg ){

	if( tabset ){
		var new_id = "iframe_"+_iframe_count;
		var tab = create_iframe_tab( "iframe_tab_"+_iframe_count, name+_iframe_count, new_id );
		_iframe_count+=1;
		tabset.append_tab( tab, bg, true );
		return tab;
	}
	return undefined;
}


function merge_dl( dl_elements ){
	for( var i=1; i<dl_elements.length; i++ )
		while( dl_elements[i].hasChildNodes() )
			dl_elements[0].appendChild( dl_elements[i].removeChild(dl_elements[i].firstChild) );

	return dl_elements[0];
}

//dlエレメントを走査し、dtとddを関連付けた配列を返す。
//create_ddがfalseの場合、array[key]['dd']が空の場合がある。
//dl_elementに含まれるdtの#text要素はdlの中で固有でなければならない。
//返すarrayはdt_node.textContentをkeyとする、dt elementと、dd elementの配列。
function dl_to_array( dl_element, create_dd ){
	var array = {};
	if( ! dl_element ){ return array; }
	for( var i=0; i<dl_element.childNodes.length; i++ ){
		var dt_node = dl_element.childNodes[i];
		var dd_nodes = [];
		if( dt_node.tagName == "DT" || dt_node.tagName == "dt" ){
			var s = get_text(dt_node);
			s = s.replace(/\s$/g, ""); /*ie? 勝手に空白が入る...*/
			if( s.length > 0 ){
				if( array[s] ){
					for( var j=0; j<array[s]['dd'].length; j++ ){
						dd_nodes.push( array[s]['dd'][j] );
					}
				}
				for( var j=i+1; j<dl_element.childNodes.length; j++ ){
					var n_node = dl_element.childNodes[j];
			  		if( n_node.tagName == "DD" || n_node.tagName == "dd" ){
						dd_nodes.push( n_node );
					}
					if( n_node.tagName == "DT" || n_node.tagName == "dt" ){
						i = j-1;
						break;
					}
					i = j-1;
				}
				if( create_dd && dd_nodes.length <= 0 ){
					message( "new", 0 );
					var dd = createElement_defaultNS( "dd" );
					dd_nodes.push( dd );
					insertAfter( dl_element, dd, dl_element.childNodes[i] );
					i += 1;
				}
				message( s + ":" + dd_nodes.length, 0 );
				array[s] = { "dt":dt_node, "dd":dd_nodes };
			}
		}
	}
	return array; //一応返すが、同じ物。
}


//結構手間...
function node_to_wikifmt( node ){
	var elements = node.getElementsByTagName("a");
	for( var i=0; i<elements.length; i++ ){
		var s = "[[";
		if( elements[i].title.length > 0 ){
			s += elements[i].title;
			if( elements[i].title != get_text(elements[i]) ){
				s += "|"+get_text(elements[i]);
			}
		}
		else{
			s += elements[i].getAttribute("href",2) + " " + get_text(elements[i]); /*ie*/
		}
		s += "]]";
		elements[i].parentNode.replaceChild( document.createTextNode(s), elements[i] );
	}

	function node_to_wikifmt( node, tag, wikitag ){
		var node_list = node.getElementsByTagName(tag);
		var elements = [];
		for( var i=0; i<node_list.length; i++ ){
			elements.push(node_list[i]);
		}
		for( var i=0; i<elements.length; i++ ){
			var parent = elements[i].parentNode;
			var itr = document.createTextNode(wikitag);
			var n = parent.replaceChild( itr, elements[i] );
			while( n.hasChildNodes() ){
				var e = n.removeChild(n.firstChild)
				insertAfter( parent, e, itr );
				itr = e;
			}
			insertAfter( parent, document.createTextNode(wikitag), itr );
		}
	}
	node_to_wikifmt( node, "i", "''");
	node_to_wikifmt( node, "b", "'''");
}


function array_to_wikifmt( array, empty_dd ){
	var wiki_fmt_str = "";
	for( var key in array ){
		var value = "";

		var genre_elements = [];
		for( var i=0; i<array[key]["dd"].length; i++ ){
			var tmp = array[key]['dd'][i].cloneNode(true); //バラバラにしてから使う。
			var genres_element = tmp.getElementsByTagName("ul")[0];
			if( genres_element ){
				tmp.removeChild(genres_element);
				var elements = genres_element.getElementsByTagName("li");
				for( var i=0; i<elements.length; i++ ){
					genre_elements.push( elements[i] );
				}
			}
			node_to_wikifmt( tmp );
			value += tmp.innerHTML;
		}
		if( empty_dd || value.length > 0 || genre_elements.length>0 ){
			wiki_fmt_str += ";[[" + key + "]]:" + value + "\r\n";
		}
		for( var i=0; i<genre_elements.length; i++ ){
			var s = get_text(genre_elements[i]);
			if( s.length > 0 ){
				wiki_fmt_str += ":*" + s + "\r\n";
			}
		}
	}
	return wiki_fmt_str;
}


/****************/
//keyの文字列をidとして持つelementに対して、valで指定されたfunctionを実行する。
//styleを指定したdivの利用を想定している。
//呼びだし順にも意味があるので注意。
var func_pack = {
		   "x-config":config_func,		//設定。optsのkeyをclass名にしたdivを入れる。
		   "column-one":setup_tools,

		   "x-genre_list":genre_list,		//ジャンル分けのためのcheckboxes
		   "x-editor":create_editor,		//コメント編集のためのinput
		   "x-submit":create_upload_form,	//書き込みを行うボタン。deprecate
		   "x-upload":create_upload_form,	//書き込みを行うボタン
		   "x-update":create_update_button,	//memberの情報を更新するボタン

		   "x-view_tabset":create_content_tabset,//各種表示のためのtabset

		   "x-results":results_func,		//今までの分類結果(dlリスト)
		   "x-check_list":check_list_func,	//チェック対象のページのリスト(dl)
		   "x-members":members_func,		//他メンバーのリスト(ul)

		   "x-auto_loading_checkbox":init_auto_loading,	//check_listより後。

		   "x-red_link_list":red_link_list	//赤リンクのリスト。テスト用
		 };

function run_parts(){
	var num=0;
	for( var key in func_pack ){
		var element = document.getElementById( key );
		if( element ){
			message( "find target: "+key, 0 );
			func_pack[key](element);
			num+=1;
		}
	}
	return num;
}


} /*end of with(na_lib)

/***************export*/

} /*end of with(new_page_watcher)*/

	new_page_watcher.run_parts = run_parts;
	new_page_watcher.opts = opts;

} /*end of new_page_watcher()*/
//</pre>