Commits

os0x  committed 34715f2

fix options

  • Participants
  • Parent commits ab732a5

Comments (0)

Files changed (7)

 	}
 };
 TabUtils.actions_with_connection = {
-	get_title_list:function(tab, connection){
+	get_title_list:function(tab, sendResponse){
 		chrome.tabs.getAllInWindow(null,function(tabs){
-			connection.postMessage({
+			sendResponse({
 				title:tabs.map(function(_tab){
 					return {text:_tab.title,selected:tab.id === _tab.id,id:_tab.id,favicon:tab.favIconUrl};
 				})

File background.html

 		if (v > bv) return true
 	});
 }
-if (this.localStorage) {
+function initializer(){
 	if (localStorage.Keyconfig) {
 		Keyconfig = JSON.parse(localStorage.Keyconfig);
 	} else {
 	} else {
 		localStorage.SiteStatus = JSON.stringify(SiteStatus);
 	}
+	Object.keys(Keyconfig).forEach(function(k,i){
+		if (!/_actions$/.test(k)) {
+			//keyactions[k] = Keyconfig[k];
+		} else {
+			config_update(k);
+		}
+	});
 }
 get_manifest(function(manifest){
 	this.Manifest = manifest;
 	Keyconfig.version = default_keyconfig.version = manifest.version;
-	KC.update();
+	config_save();
 });
 window.onunload = function(){
 	if (!localStorage.Keyconfig) {
 		localStorage.Keyconfig = JSON.stringify(Keyconfig);
 	}
 };
+function config_update(prefix) {
+	var actions = Keyconfig[prefix + 'actions'] || Keyconfig[prefix], _actions = [];
+	Object.keys(actions).forEach(function(k){
+		_actions.push({key:String(k),input:'',length:String(k).split(' ').length,action:actions[k]});
+	});
+	_actions.sort(function(a,b){return b.length - a.length;});
+	keyactions[prefix + '_map'] = _actions;
+}
+function config_save(prefix) {
+	localStorage.Keyconfig = JSON.stringify(Keyconfig);
+}
+var keyactions = {};
 this.KC = {
-	change:function(newkey, oldkey, prefix) {
-		var act = Keyconfig[prefix + 'actions'][oldkey];
-		delete Keyconfig[prefix + 'actions'][oldkey];
-		Keyconfig[prefix + 'actions'][newkey] = act;
-		localStorage.Keyconfig = JSON.stringify(Keyconfig);
-	},
-	set:function(key, act, prefix, args) {
-		Keyconfig[prefix + 'actions'][key] = {name:act,args:args || []};
-		localStorage.Keyconfig = JSON.stringify(Keyconfig);
-	},
-	del:function(key,prefix) {
-		delete Keyconfig[prefix + 'actions'][key];
-		localStorage.Keyconfig = JSON.stringify(Keyconfig);
-	},
-	arg_set:function(key, act, prefix) {
-		if (Keyconfig[prefix + 'actions'][key]) {
-			Keyconfig[prefix + 'actions'][key] = act;
-			localStorage.Keyconfig = JSON.stringify(Keyconfig);
-		}
-	},
-	update:function() {
-		localStorage.Keyconfig = JSON.stringify(Keyconfig);
-	},
 	action_names:[
 		{
 			group:'None',
 			group:'Tabs',
 			actions:[
 				{name:"open new tab",args:[]},
-				{name:"open new tab background",args:[]},
+				{name:"open new tab background",args:[],and:true},
 				{name:"open blank tab",args:[]},
-				{name:"open blank tab background",args:[]},
+				{name:"open blank tab background",args:[],and:true},
 				{name:"open #1 in new tab", args:[{type:'URL'},{type:'NAME'}]},
-				{name:"open #1 in new tab background", args:[{type:'URL'},{type:'NAME'}]},
+				{name:"open #1 in new tab background", args:[{type:'URL'},{type:'NAME'}],and:true},
 				{name:"close this tab",args:[]},
-				{name:"close other tabs",args:[]},
-				{name:"close right tabs",args:[]},
-				{name:"close left tabs",args:[]}
+				{name:"close other tabs",args:[],and:true},
+				{name:"close right tabs",args:[],and:true},
+				{name:"close left tabs",args:[],and:true}
 			]
 		},
 		{
 		{
 			group:'Scroll',
 			actions:[
-				{name:"scroll up",args:[]},
-				{name:"scroll down",args:[]},
-				{name:"scroll right",args:[]},
-				{name:"scroll left",args:[]},
-				{name:"scroll down half page",args:[]},
-				{name:"scroll up half page",args:[]},
-				{name:"scroll down full page",args:[]},
-				{name:"scroll up full page",args:[]},
-				{name:"scroll to top",args:[]},
-				{name:"scroll to bottom",args:[]}
+				{name:"scroll up",args:[],and:true},
+				{name:"scroll down",args:[],and:true},
+				{name:"scroll right",args:[],and:true},
+				{name:"scroll left",args:[],and:true},
+				{name:"scroll down half page",args:[],and:true},
+				{name:"scroll up half page",args:[],and:true},
+				{name:"scroll down full page",args:[],and:true},
+				{name:"scroll up full page",args:[],and:true},
+				{name:"scroll to top",args:[],and:true},
+				{name:"scroll to bottom",args:[],and:true}
 			]
 		},
 		{
 		{
 			group:'Focus',
 			actions:[
-				{name:"blur focus",args:[]},
-				{name:"focus first text input",args:[]},
-				{name:"navigate form elements forward",args:[]},
-				{name:"navigate form elements backward",args:[]},
-				{name:"hit a hint",args:[]}
+				{name:"blur focus",args:[],and:true},
+				{name:"focus first text input",args:[],and:true},
+				{name:"navigate form elements forward",args:[],and:true},
+				{name:"navigate form elements backward",args:[],and:true},
+				{name:"hit a hint",args:[],and:true}
 			]
 		},
 		{
 		{
 			group:'Clipboard',
 			actions:[
-				{name:"copy url",args:[]},
-				{name:"copy url and title",args:[]},
-				{name:"copy url and title as html",args:[]},
+				{name:"copy url",args:[],and:true},
+				{name:"copy url and title",args:[],and:true},
+				{name:"copy url and title as html",args:[],and:true},
 				{
 					name:"copy url and title by custom tag #1",
 					args:[
 							type:'NAME',
 							default_value:'with target'
 						}
-					]
+					],
+					and:true
 				}
 			]
 		},
 			group:'Others',
 			actions:[
 				{name:"Keyconfig",args:[]},
-				{name:"normal mode",args:[]},
-				{name:"limited mode",args:[]}
+				{name:"normal mode",args:[],and:true},
+				{name:"limited mode",args:[],and:true}
 			]
 		}
 	],
 		}
 	]
 };
+initializer();
 KC.action_names_hash = {};
 KC.vim_action_names_hash = {};
 
 		if (!act.args) {
 			act.args = [];
 		}
-		KC[groups + '_hash'][action_group.group + '::' + act.name] = act;
+		KC[groups + '_hash'][act.name] = act;
 		var action = chrome.i18n.getMessage('action_name_' + act.name.replace(/\W/g,'_'));
 		return (action || act.name).replace(/#1/,'...');
 	});
 		}
 		return;
 	} else if(message.init) {
-		var _message = {conf:Keyconfig};
+		var _message = {actions:keyactions,keyconfig:Keyconfig};
 		if (message.location && message.location.host) {
 			if (SiteStatus[message.location.host]) {
 				_message.default_set = SiteStatus[message.location.host];
 	} else {
 		sendResponse({});
 	}
-	var tab = con.tab;
+	var tab = sender.tab;
 	if (message.action === 'copy'){
 		clipNode.value = String(message.message).replace();
 		clipNode.select();
 	} else if (TabUtils.actions[message]) {
 		TabUtils.actions[message](tab);
 	} else if (TabUtils.actions_with_connection[message]) {
-		TabUtils.actions_with_connection[message](tab, con);
+		TabUtils.actions_with_connection[message](tab, sendResponse);
 	} else if (message.action && MainActions.actions[message.action]) {
 		message.sendResponse = sendResponse;
 		message.sender = sender;

File chrome_keyconfig.js

 	});
 }
 KeyConfig = {
-	init : function(config,default_set){
+	init : function(config,actions,default_set){
 		KeyConfig.config = config;
-		KeyConfig.useVim = config.chrome_vim;
+		KeyConfig.actions = actions;
 		if (config.antiAutoFocus) {
 			var elem = document.activeElement;
 			if (elem) {
 				},true);
 			}
 		}
-		if (KeyConfig.useVim) {
+		if (config.chrome_vim) {
 			document.documentElement.addEventListener('focus',function(evt){
 				var target = evt.target;
 				if ('selectionStart' in target && target.disabled !== true) {
 				}
 			},true);
 		}
-		KeyConfig.normal_actions = config.normal_actions;
-		KeyConfig.limited_actions = config.limited_actions;
-		KeyConfig.vim_normal_actions = config.vim_normal_actions;
-		KeyConfig.vim_insert_actions = config.vim_insert_actions;
-		var normal_actions = [], limited_actions = [];
-		var vim_normal_actions = [], vim_insert_actions = [];
-		Object.keys(config.normal_actions).forEach(function(k){
-			normal_actions.push({key:String(k),input:'',length:String(k).split(' ').length});
-		});
-		Object.keys(config.limited_actions).forEach(function(k){
-			limited_actions.push({key:String(k),input:'',length:String(k).split(' ').length});
-		});
-		Object.keys(config.vim_normal_actions).forEach(function(k){
-			vim_normal_actions.push({key:String(k),input:'',length:String(k).split(' ').length});
-		});
-		Object.keys(config.vim_insert_actions).forEach(function(k){
-			vim_insert_actions.push({key:String(k),input:'',length:String(k).split(' ').length});
-		});
-		normal_actions.sort(function(a,b){return b.length - a.length;});
-		limited_actions.sort(function(a,b){return b.length - a.length;});
-		vim_normal_actions.sort(function(a,b){return b.length - a.length;});
-		vim_insert_actions.sort(function(a,b){return b.length - a.length;});
-		KeyConfig._normal_actions = normal_actions;
-		KeyConfig._limited_actions = limited_actions;
-		KeyConfig._vim_normal_actions = vim_normal_actions;
-		KeyConfig._vim_insert_actions = vim_insert_actions;
 		KeyConfig.actionSet = default_set || 'normal_actions';
 		KeyConfig.vimActionSet = 'vim_' + config.vim_default_mode + '_actions';
 		KeyConfig.timesBuf = '';
 			return;
 		}
 		var target = evt.target;
-		//var actionset = KeyConfig.actionSet;
 		var isTextedit = false;
 		if ('selectionStart' in target && target.disabled !== true) {
 			try {
 				var s = target.selectionStart;
-				if (KeyConfig.useVim) {
+				if (KeyConfig.config.chrome_vim) {
 					if (KeyConfig.vimActionSet === 'vim_normal_actions') {
 						evt.preventDefault();
 					}
 		if (/^\d+$/.test(key)) {
 			KeyConfig.timesBuf += key;
 		}
-		var fired = KeyConfig['_' + actionset].some(function(keyset, i ){
+		var fired = KeyConfig.actions[actionset+'_map'].some(function(keyset, i ){
 			if (fired) {
 				keyset.input = '';
 			} else if (keyset.input) {
 				keyset.input += ' ' + key;
 				if (keyset.input === keyset.key) {
 					Notify.append(' ' + key);
-					var res = KeyConfig.fireAction(actionset, keyset.input, isTextedit, evt, target);
+					var res = KeyConfig.fireAction(keyset, isTextedit, evt, target);
 					if (res !== false) evt.preventDefault();
 					keyset.input = '';
 					fired = true;
 				} else if (keyset.key.indexOf(keyset.input) === 0) {
 					Notify.append(' ' + key);
 					matched = true;
-					return true;
+					//return true;
 				} else {
 					keyset.input = '';
 				}
 				}
 				Notify.simple(t + keyset.input);
 				if (keyset.input === keyset.key) {
-					var res = KeyConfig.fireAction(actionset, keyset.input, isTextedit, evt, target);
+					var res = KeyConfig.fireAction(keyset, isTextedit, evt, target);
 					if (res !== false) evt.preventDefault();
 					keyset.input = '';
 					KeyConfig.times = 1;
 		}
 		return fired;
 	},
-	fireAction : function(actionset, key, isTextedit, evt, target){
-		var act = KeyConfig[actionset][key];
+	fireAction : function(keyset, isTextedit, evt, target, _act){
+		var act = _act || keyset.action;
 		Notify.append(' :: ' + act.name.replace(/#(\d+)/g,function(_,_1){return act.args[_1]||'';}));
 		var action = isTextedit ? VIM_ACTION[act.name] : ACTION[act.name];
+		var result = true;
 		if (typeof action === 'function') {
-			return action({config:KeyConfig.config, key:key, action:act, times:KeyConfig._times||KeyConfig.times||1, event:evt, target:target});
+			result = action({config:KeyConfig.config, key:keyset.key, action:act, times:KeyConfig._times||KeyConfig.times||1, event:evt, target:target});
 		} else {
 			var ev = document.createEvent('Event');
 			ev.initEvent(act.name, true, false);
-			ev.key = key;
+			ev.key = keyset.key;
 			ev.action = act;
 			ev.times = KeyConfig._times||KeyConfig.times||1;
 			ev.target = target;
 			document.dispatchEvent(ev);
-			return true;
 		}
+		if(act.and){
+			result = KeyConfig.fireAction(keyset, isTextedit, evt, target, act.and);
+		}
+		return result;
 	}
 };
 function ResponseHandler(message){
 	if (!message) return;
-	if (message.conf) {
+	if (message.keyconfig) {
 		if (message.LDRize) {
 			var siteinfo = message.LDRize, inited;
 			document.addEventListener('DOMContentLoaded', function(){
 					inited = true;
 				}
 			}, false);
-			LDRize.isSmoothScroll = message.conf.smooth_scroll;
-			message.conf.normal_actions['p'] = {name:'LDRize::pin',args:[]};
-			message.conf.normal_actions['v'] = {name:'LDRize::view',args:[]};
-			message.conf.normal_actions['o'] = {name:'LDRize::open',args:[]};
+			LDRize.isSmoothScroll = message.keyconfig.smooth_scroll;
+			message.actions.normal_actions_map.push({key:'p',input:'',length:1,action:{name:'LDRize::pin',args:[]}});
+			message.actions.normal_actions_map.push({key:'v',input:'',length:1,action:{name:'LDRize::view',args:[]}});
+			message.actions.normal_actions_map.push({key:'o',input:'',length:1,action:{name:'LDRize::open',args:[]}});
 		}
-		KeyConfig.init(message.conf,message.default_set);
+		KeyConfig.init(message.keyconfig,message.actions,message.default_set);
 	}
 	if (message.action && ResponseManager[message.action]) {
 		ResponseManager[message.action](message.data);

File manifest.json

   "permissions": [ "bookmarks", "tabs", "http://ss-o.net/" , "http://wedata.net/"],
   "update_url": "http://ss-o.net/chrome_extension/ChromeKeyconfig/updates.xml",
   "options_page": "options_page.html",
-  "version": "1.10.5"
+  "version": "1.11.0"
 }

File option_page.css

-body{
-width:800px;
-color:#222222;
-font-family: Arial, Helvetica, sans-serif;
-}
-body, ul, li{
-margin:0;
-padding:0;
-}
-body {
--webkit-box-orient:vertical;
--webkit-box-direction:normal;
-}
-section.content > ul{
-list-style-type:none;
-overflow:auto;
-}
-section.content > ul > li{
-margin-bottom:20px;
-}
-dt,dd{
-margin:0px;
-}
-section.content div > dl > dd{
-margin-bottom:20px;
-}
-section.content{
-display:block;
-padding:10px;
-}
-#filter_list input[type='text']{
-width:300px;
-}
-div.box > dl{
-overflow:auto;
-width:386px;
-}
-#menu_tabs{
-display:block;
-z-index:100;
-padding:0 0 0 1px;
-}
-#menu_tabs li{
-display:inline-block;
-margin:0px;
-padding:0px;
-}
-#menu_tabs li a{
-color:black;
-text-decoration:none;
-display: inline-block;
-background: -webkit-gradient(linear, left top, left bottom, from(#F2F2F2), to(#CFCFCF), color-stop(0.5, #EBEBEB), color-stop(0.5, #DDDDDD));
-padding: 6px 12px;
-border:1px solid #898C95;
-font-size:13px;
-position:relative;
-margin:0 0 1px -1px;
-}
-#menu_tabs li a.active{
-background:white;
-border-bottom:1px solid white;
-z-index:100;
-}
-span.key,
-kbd.key{
-display:inline-block;
-background:#334455;
-color:#eeeeee;
-padding:6px;
-border:2px solid black;
--webkit-border-radius:4px;
-font-size:x-large;
-font-weight:bold;
-}
-input.key{
-font-size:x-large;
-font-weight:bold;
-color:#333333;
-background:#ffffff;
-border-radius:3px;
-}
-button.impt{
-background: -webkit-gradient(linear, left top, left bottom, from(#ffffcc), to(#ffff99));
-}
-button.impt[disabled]{
-background:#ffffff;
-}
-dt.disabled .key,
-li.disabled .key{
-background:#cccccc;
-border:2px solid #bbbbbb;
-}
-#container{
-width:800px;
-overflow:hidden;
-z-index:10;
-border:1px solid #999999;
-}
-#container #inner_container{
-vertical-align:top;
-}
-#inner_container section{
-vertical-align:top;
-display:inline-block;
-margin:0;
-white-space:normal;
-width:778px;
-}
-section > div > fieldset{
-display:inline-block;
-border:1px solid #99ccff;
--webkit-border-radius:4px;
-padding:1px 4px;
-margin:3px;
-}
-optgroup{
-background:#333333;
-color:#ffffff;
-}
-optgroup > option{
-color:#000000;
-}
-.content > .box{
-display:inline-block;
-vertical-align:top;
-}
-.content > .box > h3{
-margin:0px;
-padding:0 10px;
-}
-#about dl{
-margin:30px;
-}
-#about dl dd{
-margin:10px 0 20px 50px;
-}
+/*汎用定義*/
+body{
+color:#222222;
+font-family: Arial, Helvetica, sans-serif;
+}
+body, ol, ul, li, section, div, button,dt,dd{
+margin:0;
+padding:0;
+}
+ul{
+list-style-type:none;
+}
+p{
+line-height:1.5;
+margin:0.5em 0;
+}
+/*タブメニュー*/
+#menu_tabs{
+display:block;
+z-index:100;
+padding:0 0 0 1px;
+}
+#menu_tabs li{
+display:inline-block;
+}
+#menu_tabs li a{
+color:black;
+text-decoration:none;
+display: inline-block;
+background: -webkit-gradient(linear, left top, left bottom,
+    from(#fff), to(#ccc), color-stop(0.5, #eee), color-stop(0.5, #ddd));
+padding: 6px 12px;
+border:1px solid #898C95;
+font-size:13px;
+position:relative;
+margin:0 0 1px -1px;
+}
+#menu_tabs li a.active{
+background:white;
+border-bottom:1px solid white;
+z-index:100;
+}
+/*タイトル*/
+h1{
+background: -webkit-gradient(linear, left top, left bottom, from(#333), to(#999));
+font-size:small;
+border-top-left-radius:4px;
+border-top-right-radius:4px;
+margin:0px;
+padding:3px 8px;
+color:white;
+text-shadow: 3px 3px 3px black;
+line-height:1.4;
+}
+/*メインコンテンツ*/
+#container{
+z-index:10;
+border-top:1px solid #999;
+padding:10px;
+margin-top:-2px;
+}
+#container > section{
+display:none;
+}
+#container > section div.mainbox{
+display:-webkit-box;
+width:100%;
+}
+#container > section div.box{
+width:50%;
+}
+#about dl{
+margin:20px;
+}
+#about dl dd{
+margin:10px 0 20px 50px;
+}
 #config_text{
-width:98%;
-height:300px;
-}
-#advanced .margin{
-margin:60px 0 0 0;
-}
-input:not([type="text"]),button,label{
-cursor:pointer;
-}
-button{
--webkit-appearance: button;
-background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(white), to(#DDD));
-border: 1px solid #999;
-border-bottom-left-radius: 2px 2px;
-border-bottom-right-radius: 2px 2px;
-border-top-left-radius: 2px 2px;
-border-top-right-radius: 2px 2px;
-margin: 0.2em;
+width:98%;
+height:300px;
+}
+#advanced .margin{
+margin:60px 0 0 0;
+}
+input:not([type="text"]),button,label{
+cursor:pointer;
+}
+button{
+-webkit-appearance: button;
+background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(white), to(#DDD));
+border: 1px solid #999;
+border-bottom-left-radius: 2px 2px;
+border-bottom-right-radius: 2px 2px;
+border-top-left-radius: 2px 2px;
+border-top-right-radius: 2px 2px;
+margin: 0.2em;
 padding: 0px 5px;
-}
-button:hover:not([disabled]){
-background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ffffff), to(#99ccff));
-}
-button[disabled]{
-cursor:default;
-}
-section.content > p.Mousewheel{
-margin-left:2em;
-}
-#AccelerationValue{
-min-width:4em;
-width:4em;
-}
-input.input_button{
-font-size:110%;
-min-width:5em;
-max-width:10em;
-min-height:2em;
-background:#ffffff;
-border-top:#999999 2px solid;
-border-left:#999999 2px solid;
-border-right:#cccccc 1px solid;
-border-bottom:#cccccc 1px solid;
+}
+button:hover:not([disabled]){
+background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ffffff), to(#99ccff));
+}
+button[disabled]{
+cursor:default;
+}
+input.input_button{
+font-size:110%;
+min-width:5em;
+/*max-width:10em;*/
+min-height:2em;
+background:#ffffff;
+border-top:#999999 2px solid;
+border-left:#999999 2px solid;
+border-right:#cccccc 1px solid;
+border-bottom:#cccccc 1px solid;
+}
+button.myact{
+padding:0.6em 2em;
+font-size:95%;
+}
+button.action_btn{
+padding:0.3em 1em;
 }
 .field_action button{
 font-size:large;
 width:90%;
 padding:0.4em;
-}
-#cover{
-position:fixed;
-background-color:rgba(128,128,128,0.9);
-z-index:10000;
-top:0px;
-left:0px;
-display:none;
-text-align:center;
-}
-#cover button{
-font-size:large;
-margin:1em;
 }
 #action_result{
 min-height:40px;
 display:inline-block;
 min-width:60px;
 }
+.box dl{
+margin:10px;
+}
 .box dl dt{
 padding:.3em .2em;
 border-top:#cccccc 1px solid;
 border-bottom:#cccccc 1px solid;
 border-left:#cccccc 1px solid;
 border-right:#cccccc 1px solid;
-}
+}
+#cover{
+background-color:rgba(128,128,128,0.9);
+position:fixed;
+top:10%;
+left:10%;
+bottom:10%;
+right:10%;
+overflow:auto;
+display:none;
+}
+#cover > ul{
+display:none;
+}
+#cover li.group{
+display:inline-block;
+vertical-align:top;
+padding:6px;
+margin:5px;
+background:rgba(255,255,255,0.2);
+border-radius:6px;
+}
+#cover li.act{
+display:block;
+}
+#cover > ul h3{
+display:inline-block;
+background:rgba(255,255,255,0.5);
+color:#333;
+border-radius:9px;
+margin:0.2em;
+padding:0.2em;
+}
+.cover #action_names_list{
+display:block;
+}
+/*
+.cover h1,
+.cover #menu_tabs,
+.cover #container{
+display:none;
+}
+*/
+.cover #cover{
+display:block;
+}
+var handleEvent = KeyConfig.handleEvent;
+KeyConfig.handleEvent = function(evt){
+	if (evt.target.className !== 'input_button' ) {
+		handleEvent.call(this,evt);
+	}
+};
+BackGround = chrome.extension.getBackgroundPage();
+Config = BackGround.Keyconfig;
+keyactions = BackGround.keyactions;
+KC = BackGround.KC;
+config_update = BackGround.config_update;
+config_save = BackGround.config_save;
+function L10N(){
+	chrome.i18n.getAcceptLanguages(function(langs){
+		if (langs.indexOf('ja') < 0 ) {
+			document.querySelector('#menu_tabs > li.news').style.display = 'none';
+		}
+	});
+	var elems = document.querySelectorAll('*[class^="MSG_"]');
+	Array.prototype.forEach.call(elems, function(node){
+		var key = node.className.match(/MSG_(\w+)/)[1];
+		var message = chrome.i18n.getMessage(key);
+		if (message) node.textContent = message;
+	});
+}
+L10N();
+
+$X('//input[@type="checkbox"]').forEach(function(input){
+	var id = input.id;
+	input.checked = !!Config[id];
+	input.addEventListener('click',function(){
+		Config[id] = input.checked;
+		localStorage.Config = JSON.stringify(Config);
+	},false);
+});
+$X('id("vim_actions")//input[@name="vim_default_mode"]').forEach(function(radio){
+	var val = radio.value;
+	if (val === Config.vim_default_mode) {
+		radio.checked = true;
+	}
+	radio.addEventListener('click',function(){
+		Config.vim_default_mode = radio.value;
+		config_save();
+	},false);
+});
+$X('id("vim_actions")//input[starts-with(@id,"vimcolor_")]').forEach(function(input){
+	var ids = input.id.split('_'), mode = ids[1], item = ids[2];
+	input.value = Config.vim_color_config[mode][item];
+	input.addEventListener('change',function(){
+		Config.vim_color_config[mode][item] = input.value;
+		config_save();
+	},false);
+});
+
+document.getElementById('ldrize').addEventListener('click',function(){
+	if (this.checked) {
+		BackGround.LDRize();
+	} else {
+		BackGround.LDRize.Siteinfo= void 0;
+		delete BackGround.LDRize.Siteinfo;
+	}
+},false);
+
+var menu_tabs = document.getElementById('menu_tabs');
+var container = document.getElementById('container');
+var vim_actions = document.getElementById('vim_actions');
+var vimtab = $X('id("menu_tabs")/li[@class="vim_actions"]')[0];
+document.getElementById('chrome_vim').addEventListener('click',toggle_vim_conf,false);
+function toggle_vim_conf(e){
+	if (e.target.checked) {
+		vim_actions.style.visibility = 'visible';
+		vimtab.style.display = 'inline-block';
+	} else {
+		vim_actions.style.visibility = 'hidden';
+		vimtab.style.display = 'none';
+	}
+}
+toggle_vim_conf({target:document.getElementById('chrome_vim')});
+
+document.getElementById('ExtensionVersion').textContent = BackGround.Manifest.version;
+
+utils = {
+	'action_names':list_create('action_names'),
+	'vim_action_names':list_create('vim_action_names')
+};
+function list_create(name){
+	var root = document.getElementById(name + '_list');
+	var filter = function(){};
+	root.addEventListener('click',function(evt){
+		if (evt.target === root) {
+			document.documentElement.className = '';
+		}
+	},false);
+	KC[name].forEach(function(group){
+		var opts = document.createElement('li');
+		var h3 = document.createElement('h3');
+		opts.className = 'group';
+		h3.textContent = group.label || group.group;
+		opts.appendChild(h3);
+		var optg = document.createElement('ul');
+		opts.appendChild(optg);
+		group.actions.forEach(function(Act, i){
+			var opt = document.createElement('li');
+			opt.className = 'act';
+			var btn = document.createElement('button');
+			btn.className = 'action_btn';
+			var action = chrome.i18n.getMessage('action_name_' + Act.name.replace(/\W/g,'_'));
+			btn.textContent = action || Act.name;
+			opt.appendChild(btn);
+			optg.appendChild(opt);
+			btn.addEventListener('click',function(evt){
+				filter(evt.target, Act, group);
+			},false);
+		});
+		root.appendChild(opts);
+	});
+	return function(action, btn, callback){
+		//console.log(action);
+		//root.parentNode.style.height = document.documentElement.clientHeight + 'px';
+		document.documentElement.className = 'cover';
+		//root.style.display = 'block';
+		filter = function(_btn, Act, group){
+			btn.textContent = _btn.textContent;
+			//root.style.display = 'none';
+			action.name = Act.name;
+			callback(Act, group);
+			document.documentElement.className = '';
+			//document.documentElement.style.overflow = 'auto';
+		}
+	}
+}
+
+var ActionConfig = function(prefix, ActionNames){
+	var action_list = document.getElementById(prefix + 'action_list');
+	var append_action = document.getElementById(prefix + 'append_action');
+	var action_text = document.getElementById(prefix + 'action_text');
+	var actions = Config[prefix + 'actions'];
+
+
+	var ActionKeys = Object.keys(actions);
+	var Actions = ActionKeys.sort().map(function(k){
+		var act=actions[k];
+		return {action:act, key:k};
+	}).map(create_action);
+	function create_action(act, i) {
+		var Act = KC[ActionNames+'_hash'][act.action.name];
+		var dt = document.createElement('dt');
+		dt.innerHTML = '<span class="lt">Key:</span>';
+		var _key = document.createElement('input');
+		_key.type = 'button';
+		_key.className = 'input_button';
+		_key.value = act.key;
+		var changed = false;
+		_key.addEventListener('focus',function(evt){
+			if (!changed) _key.value = ' ';
+		},true);
+		_key.addEventListener('click',function(evt){
+			_key.focus();
+		},true);
+		_key.addEventListener('blur',function(evt){
+			if (_key.value === ' ') {
+				_key.value = act.key;
+				save.disabled = true;
+			} else {
+				//save.disabled = false;
+			}
+		},true);
+		_key.addEventListener('keydown',function(evt){
+			evt.preventDefault();
+			evt.stopPropagation();
+			var key = get_key(evt);
+			if (!key || /^(Meta|Shift|Control|Alt)$/.test(key)) {
+				return;
+			}
+			if (changed) {
+				_key.value += ' ' + key;
+			} else {
+				_key.value = key;
+			}
+			if (actions[_key.value]) {
+				return;
+			}
+			changed = true;
+			save.disabled = false;
+			save.focus();
+		},true);
+		var save = document.createElement('button');
+		save.disabled = true;
+		save.className = 'impt';
+		save.addEventListener('click',function(evt){
+			var old_key = act.key;
+			var new_key = _key.value;
+			if (old_key !== new_key && new_key) {
+				act.key = new_key;
+				//KC.change(new_key, old_key, prefix)
+				var act = Config[prefix + 'actions'][old_key];
+				delete Config[prefix + 'actions'][old_key];
+				Config[prefix + 'actions'][new_key] = act;
+				localStorage.Keyconfig = JSON.stringify(Config);
+				config_update(prefix + 'actions');
+				save.disabled = true;
+				changed = false;
+			}
+		},false);
+		save.textContent = 'save';
+		var reset = document.createElement('button');
+		reset.addEventListener('click',function(evt){
+			_key.value = act.key;
+			save.disabled = true;
+			changed = false;
+		},false);
+		reset.textContent = 'reset';
+		dt.appendChild(_key);
+		dt.appendChild(save);
+		dt.appendChild(reset);
+		action_list.insertBefore(dt, act.point);
+		act.list = dt;
+
+		var and = false;
+		var dd = document.createElement('dd');
+		var args_list;
+		var args = [];
+		function set_arg(_act, action, point){
+			args_list = document.createElement('ul');
+			var args = [];
+			_act.args.forEach(function(_arg, i){
+				var _i = i+1;
+				var _li = document.createElement('li');
+				_li.innerHTML = '<span class="lt">' + _arg.type + ':</span>';
+				var arg;
+				if (_arg.type === 'custom tag') {
+					arg = document.createElement('textarea');
+				} else if (_arg.type === 'hidden') {
+					arg = document.createElement('input');
+					arg.type = 'hidden';
+				} else {
+					arg = document.createElement('input');
+					arg.type = 'text';
+					if (_arg.type === 'KEY') {
+						arg.maxLength = 1;
+					}
+				}
+				if (action.args[i] !== void 0) {
+					arg.value = action.args[i];
+				} else if (_arg.default_value !== void 0) {
+					arg.value = _arg.default_value;
+				}
+				arg.addEventListener('change',function(){
+					args[i] = arg.value;
+					if (Config[prefix + 'actions'][act.key]) {
+						Config[prefix + 'actions'][act.key] = {name:_act.name, args:args, and:and};
+						localStorage.Keyconfig = JSON.stringify(Config);
+					}
+					config_update(prefix + 'actions');
+				},false);
+				arg.setAttribute('placeholder', _arg.type);
+				_li.appendChild(arg);
+				args_list.appendChild(_li);
+				args.push(arg.value || '');
+			});
+			point.insertBefore(args_list, point.firstChild);
+			return args;
+		}
+		function del_arg(point){
+			if (args_list) {
+				args_list.parentNode.removeChild(args_list);
+				args_list = null;
+			}
+		}
+		var span = document.createElement('span');
+		span.className = 'lt';
+		span.textContent = 'Action:';
+		dd.appendChild(span);
+		var action = document.createElement('button');
+		action.className = 'myact';
+		var name = chrome.i18n.getMessage('action_name_' + act.action.name.replace(/\W/g,'_'));
+		action.textContent = name || act.action.name;
+		dd.appendChild(action);
+		action.addEventListener('click',function(evt){
+			utils[ActionNames](act.action, action,function(Act, group){
+				del_arg();
+				if (Act.args.length) {
+					args = set_arg(Act, act.action, dd);
+				}
+				//var _and = and.map(function(a){return {name:a.name,args:a.args}});
+				//var _and = {name:}
+				save_action(act.key, Act.name, prefix, args, false);
+			});
+		},false);
+		var del = document.createElement('button');
+		del.textContent = 'Del';
+		del.addEventListener('click',function(){
+			action.disabled = !action.disabled;
+			if (action.disabled) {
+				delete Config[prefix + 'actions'][act.key];
+				localStorage.Keyconfig = JSON.stringify(Config);
+				config_update(prefix + 'actions');
+				del.textContent = 'Undo';
+				dt.className = 'disabled';
+				dd.className = 'disabled';
+			} else {
+				save_action(act.key, action.value, prefix, args, and);
+				del.textContent = 'Del';
+				dt.className = '';
+				dd.className = '';
+			}
+		});
+		dd.appendChild(del);
+		if (act.action.args && act.action.args.length) {
+			if (Act) {
+				args = set_arg(Act, act.action, dd);
+			}
+		}
+		action_list.insertBefore(dd, act.point);
+		//if (act.action.and) {
+		//	andActAdd({}, act.action, {action:act.action.and});
+		//} else if (Act && Act.and){
+		//	andActAdd({}, act.action);
+		//}
+		function andActDel(And){
+			if (And && And._dd) {
+				And._dd.parentNode.removeChild(And._dd);
+				delete And._dd;
+			} else if (and.dd) {
+				and.dd.parentNode.removeChild(and.dd);
+				delete and.dd;
+			}
+		}
+		act.dlist = dd;
+		if (act.focus) {
+			action.focus();
+		}
+		return act;
+	}
+	var timer;
+	action_text.addEventListener('focus',function(evt){
+		if (action_text.value === 'type key here') {
+			action_text.value = ' ';
+		}
+		timer = setTimeout(function(){
+			append_action.focus();
+		},3000);
+	},true);
+	action_text.addEventListener('click',function(evt){
+		action_text.focus();
+	},true);
+	action_text.addEventListener('blur',function(evt){
+		if (action_text.value === ' ') {
+			action_text.value = 'type key here';
+			append_action.disabled = true;
+		} else {
+			append_action.disabled = false;
+		}
+	},true);
+	append_action.disabled = true;
+	action_text.addEventListener('keydown',function(evt){
+		evt.preventDefault();
+		evt.stopPropagation();
+		var key = get_key(evt);
+		if (!key || /^(Meta|Shift|Control|Alt)$/.test(key)) {
+			return;
+		}
+		if (action_text.value !== ' ') {
+			action_text.value += ' ' + key;
+		} else {
+			action_text.value = key;
+		}
+		append_action.disabled = false;
+		clearTimeout(timer);
+		timer = setTimeout(function(){
+			append_action.focus();
+		},3000);
+	},true);
+	append_action.addEventListener('click',function(){
+		var key = action_text.value;
+		if (!key) {
+			action_text.focus();
+			return;
+		}
+		if (ActionKeys.indexOf(key) !== -1) {
+			var i = ActionKeys.indexOf(key);
+			var ac = Actions[i].dlist.querySelector('button.myact');
+			if (ac) ac.focus();
+			return;
+		}
+		ActionKeys.push(key);
+		ActionKeys.sort();
+		var index = ActionKeys.indexOf(key);
+		var point = (Actions[index] || {}).list;
+		var act = {key:key,focus:true,point:point,action:{name:'no action',args:[]}};
+		Actions = Actions.slice(0, index).concat([act], Actions.slice(index));
+		create_action(act, index);
+		save_action(act.key, act.action.name, prefix);
+		action_text.value ='type key here';
+		append_action.disabled = true;
+	});
+	function save_action(key, act, prefix, args, and){
+		Config[prefix + 'actions'][key] = {name:act,args:args || [], and:and};
+		localStorage.Keyconfig = JSON.stringify(Config);
+		config_update(prefix + 'actions');
+	}
+};
+
+ActionConfig('normal_', 'action_names');
+ActionConfig('limited_', 'action_names');
+ActionConfig('vim_normal_', 'vim_action_names');
+ActionConfig('vim_insert_', 'vim_action_names');
+
+var config_text = document.getElementById('config_text');
+var export_conf = document.getElementById('export_conf');
+export_conf.addEventListener('click',function(){
+	config_text.value = JSON.stringify(Config, null, 2);
+},false);
+var import_conf = document.getElementById('import_conf');
+import_conf.addEventListener('click',function(){
+	if (!config_text.value){
+		return;
+	}
+	try {
+		JSON.parse(config_text.value);
+	} catch (e) {
+		alert('インポートに失敗しました。正しいJSONではありません。');
+		return;
+	}
+	var conf = JSON.parse(config_text.value);
+	if (
+		typeof conf.normal_actions === 'object' &&
+		typeof conf.limited_actions === 'object'
+	) {
+		if (conf.version !== BackGround.Manifest.version) {
+			if (!confirm('設定がExportされた際のバージョンと現在の使用しているバージョンが異なるため、正常にインポートできない可能性があります。現在の設定をバックアップしてから続行することを推奨します。\n続行しますか?')){
+				return;
+			}
+		}
+		var _keyconfig = Config;
+		try {
+			Config = conf;
+			BackGround.Keyconfig = Config;
+			localStorage.Keyconfig = JSON.stringify(Config);
+			BackGround.initializer();
+		} catch (e) {
+			alert('インポートに失敗しました。');
+			BackGround.Keyconfig = _keyconfig;
+			config_save();
+			return;
+		}
+		alert('正常にインポートできました。新しい設定を再読み込みします。');
+		location.reload();
+	}
+},false);
+var reset_all = document.getElementById('reset_all');
+reset_all.addEventListener('click',function(){
+	if (confirm('Are sure you want to delete this config? There is NO undo!')) {
+		Config = JSON.parse(BackGround.default_keyconfig);
+		BackGround.Keyconfig = Config;
+		config_save();
+		location.reload();
+	}
+},false);
+
+
+var sections = $X('id("container")/section[contains(@class, "content")]');
+var btns = $X('id("menu_tabs")/li/a');
+var default_title = document.title;
+window.addEventListener('hashchange',function(evt){
+	var hash = location.hash;
+	btns.forEach(function(btn, i){
+		btn.className = (!hash && !i) || (btn.hash === hash) ? 'active' : '';
+	});
+	sections.forEach(function(sc, i){
+		sc.style.display = (!hash && !i) || ('#'+sc.id === hash) ? 'block' : 'none';
+	});
+	document.title = default_title + hash;
+	window.scrollBy(0, -1000);
+},false);
+if (location.hash && sections.some(function(section, i){
+		if ('#' + section.id === location.hash) {
+			btns.forEach(function(btn){btn.className = '';})
+			btns[i].className = 'active';
+			section.style.display = 'block';
+			document.title = default_title + location.hash;
+			return true;
+		}
+	})) {
+} else {
+	sections[0].style.display = 'block';
+	document.title = default_title + '#' + sections[0].id;
+}

File options_page.html

 <!DOCTYPE html>
 <html>
-<head>
 <meta charset="utf-8">
-<title>ChromeKeyconfig</title>
-<!--<link href="chrome-native-look.css" rel="stylesheet" type="text/css" />-->
-<script type="text/javascript" src="x.js"></script>
-<script type="text/javascript" src="tween2.js"></script>
-<script type="text/javascript" src="get_key.js"></script>
-<script type="text/javascript" src="chrome_keyconfig.js"></script>
+<title class="MSG_option_title">Chrome Keyconfig</title>
 <link href="option_page.css" rel="stylesheet" type="text/css">
-<body>
+<script src="x.js"></script>
+<script src="tween2.js"></script>
+<script src="get_key.js"></script>
+<script src="chrome_keyconfig.js"></script>
+<h1 class="MSG_option_title">Chrome Keyconfig</h1>
 <ul class="tabs" id="menu_tabs">
-	<li class="basics"><a href="#basics" class="active"><span>Basics</span></a>
-	<li class="actions"><a href="#actions"><span>Actions</span></a>
-	<li class="vim_actions"><a href="#vim_actions"><span>Vim Actions</span></a>
-	<li class="advanced"><a href="#advanced"><span>Advanced</span></a>
-	<li class="news"><a href="#news"><span>News</span></a>
-	<li class="about"><a href="#about"><span>About</span></a>
+	<li class="basics">
+		<a href="#basics" class="active"><span>Basics</span></a>
+	<li class="actions">
+		<a href="#actions"><span>Actions</span></a>
+	<li class="vim_actions">
+		<a href="#vim_actions"><span>Vim Actions</span></a>
+	<li class="advanced">
+		<a href="#advanced"><span>Advanced</span></a>
+	<li class="news">
+		<a href="#news"><span>News</span></a>
+	<li class="about">
+		<a href="#about"><span>About</span></a>
 </ul>
 <div id="container">
-<div id="inner_container">
 <section id="basics" class="content">
 	<p><input type="checkbox" id="smooth_scroll"><label for="smooth_scroll">Smooth Scroll</label></p>
 	<p><input type="checkbox" id="ldrize"><label for="ldrize">LDRize</label></p>
 	<p><input type="checkbox" id="antiAutoFocus"><label for="antiAutoFocus">Anti autofocus</label></p>
 </section>
 <section id="actions" class="content">
-	<div class="box">
-		<h3>Actions for normal mode</h3>
-		<fieldset>
-			<input type="button" id="normal_action_text" value="type key here" class="input_button">
-			<button id="normal_append_action">Add</button>
-			<button onclick="normal_action_text.value=' ';normal_action_text.focus();">Reset</button>
-		</fieldset>
-		<dl id="normal_action_list">
-		</dl>
-	</div>
-	<div class="box">
-		<h3>Actions for limited mode</h3>
-		<fieldset>
-			<input type="button" id="limited_action_text" value="type key here" class="input_button">
-			<button id="limited_append_action">Add</button>
-			<button onclick="limited_action_text.value=' ';limited_action_text.focus();">Reset</button>
-		</fieldset>
-		<dl id="limited_action_list">
-		</dl>
+	<div class="mainbox">
+		<div class="box">
+			<h3>Actions for normal mode</h3>
+			<fieldset>
+				<input type="button" id="normal_action_text" value="type key here" class="input_button">
+				<button id="normal_append_action">Add</button>
+				<button onclick="normal_action_text.value=' ';normal_action_text.focus();">Reset</button>
+			</fieldset>
+			<dl id="normal_action_list">
+			</dl>
+		</div>
+		<div class="box">
+			<h3>Actions for limited mode</h3>
+			<fieldset>
+				<input type="button" id="limited_action_text" value="type key here" class="input_button">
+				<button id="limited_append_action">Add</button>
+				<button onclick="limited_action_text.value=' ';limited_action_text.focus();">Reset</button>
+			</fieldset>
+			<dl id="limited_action_list">
+			</dl>
+		</div>
 	</div>
 </section>
 <section id="vim_actions" class="content">
 		<label for="vimcolor_insert_background">background color</label><input type="text" id="vimcolor_insert_background">
 		<label for="vimcolor_insert_text">text color</label><input type="text" id="vimcolor_insert_text">
 	</p>
-	<div class="box">
-		<h3>Actions for normal mode</h3>
-		<fieldset>
-			<input type="button" id="vim_normal_action_text" value="type key here" class="input_button">
-			<button id="vim_normal_append_action">Add</button>
-			<button onclick="vim_normal_action_text.value=' ';vim_normal_action_text.focus();">Reset</button>
-		</fieldset>
-		<dl id="vim_normal_action_list">
-		</dl>
-	</div>
-	<div class="box">
-		<h3>Actions for insert mode</h3>
-		<fieldset>
-			<input type="button" id="vim_insert_action_text" value="type key here" class="input_button">
-			<button id="vim_insert_append_action">Add</button>
-			<button onclick="vim_insert_action_text.value=' ';vim_insert_action_text.focus();">Reset</button>
-		</fieldset>
-		<dl id="vim_insert_action_list">
-		</dl>
+	<div class="mainbox">
+		<div class="box">
+			<h3>Actions for normal mode</h3>
+			<fieldset>
+				<input type="button" id="vim_normal_action_text" value="type key here" class="input_button">
+				<button id="vim_normal_append_action">Add</button>
+				<button onclick="vim_normal_action_text.value=' ';vim_normal_action_text.focus();">Reset</button>
+			</fieldset>
+			<dl id="vim_normal_action_list">
+			</dl>
+		</div>
+		<div class="box">
+			<h3>Actions for insert mode</h3>
+			<fieldset>
+				<input type="button" id="vim_insert_action_text" value="type key here" class="input_button">
+				<button id="vim_insert_append_action">Add</button>
+				<button onclick="vim_insert_action_text.value=' ';vim_insert_action_text.focus();">Reset</button>
+			</fieldset>
+			<dl id="vim_insert_action_list">
+			</dl>
+		</div>
 	</div>
 </section>
 <section id="advanced" class="content">
 <section id="news" class="content">
 	<ul>
 	<li>
+	<h4>2011/04/14 09:57</h4>
+	<p>オプションページが正常に表示されない問題を修正など。</p>
+	</li>
+	<li>
 	<h4>2010/02/20 11:01</h4>
 	<p>Hit a Hintでフォーカスできない要素があった問題を修正しました(Thx! <a href="http://twitter.com/yu_sakasaki/status/9361555808">@yu_sakasaki</a>)</p>
 	</li>
 </section>
 <section id="about" class="content">
 	<dl>
-		<dt>Name:<dt>
-		<dd><a href="http://ss-o.net/chrome_extension/" target="_blank">Chrome Keyconfig</a></dd>
-		<dt>Version:<dt>
-		<dd>ver <span id="ExtensionVersion"></span></dd>
-		<dt>Author:<dt>
-		<dd><a href="http://ss-o.net/" target="_blank">os0x</a>, <a href="http://my.opera.com/edvakf/blog/" target="_blank">edvakf</a>, <a href="http://rails2u.com/" target="_blank">Yuichi Tateno</a></dd>
-		<dt>License:<dt>
-		<dd><a href="http://creativecommons.org/licenses/MIT/" target="_blank">The MIT license</a></dd>
+		<dt>Name:
+		<dd><a href="http://ss-o.net/chrome_extension/" target="_blank">Chrome Keyconfig</a>
+		<dt>Version:
+		<dd>ver <span id="ExtensionVersion"></span>
+		<dt>Author:
+		<dd><a href="http://ss-o.net/" target="_blank">os0x</a>, <a href="http://my.opera.com/edvakf/blog/" target="_blank">edvakf</a>, <a href="http://rails2u.com/" target="_blank">Yuichi Tateno</a>
+		<dt>License:
+		<dd><a href="http://creativecommons.org/licenses/MIT/" target="_blank">The MIT license</a>
 	</dl>
 </section>
 </div>
+<div id="cover">
+	<ul id="action_names_list"></ul>
+	<ul id="vim_action_names_list"></ul>
 </div>
-<script>
-window.onload = function(){
-	setTimeout(__onload, 100);
-};
-function __onload(){
-var handleEvent = KeyConfig.handleEvent;
-KeyConfig.handleEvent = function(evt){
-	if (evt.target.className !== 'input_button' ) {
-		handleEvent.call(this,evt);
-	}
-};
-BackGround = chrome.extension.getBackgroundPage();
-Keyconfig = BackGround.Keyconfig;
-KC = BackGround.KC;
-chrome.i18n.getAcceptLanguages(function(langs){
-	if (langs.indexOf('ja') < 0 ) {
-		document.querySelector('#menu_tabs > li.news').style.display = 'none';
-	}
-});
-var labels = document.querySelectorAll('label')
-for (var i = 0; i < labels.length; i++){
-	var message = chrome.i18n.getMessage('options_' + labels[i].htmlFor);
-	if (message) {
-		labels[i].innerHTML = message;
-	}
-}
-
-var WIDTH = 800;
-var HEIGHT = Math.max(window.innerHeight - 100, 500);
-
-$X('/html/body/div/div/section/p/input[@type="checkbox"]').forEach(function(box){
-	var id = box.id;
-	var val = Keyconfig[id];
-	if (val === true || val === false) {
-		box.checked = val;
-	} else {
-		//return;
-	}
-	box.addEventListener('click',function(){
-		if (box.checked) {
-			Keyconfig[id] = true;
-		} else {
-			Keyconfig[id] = false;
-		}
-		KC.update();
-	},false);
-});
-$X('id("vim_actions")//input[@name="vim_default_mode"]').forEach(function(radio){
-	var val = radio.value;
-	if (val === Keyconfig.vim_default_mode) {
-		radio.checked = true;
-	}
-	radio.addEventListener('click',function(){
-		Keyconfig.vim_default_mode = radio.value;
-		KC.update();
-	},false);
-});
-$X('id("vim_actions")//input[starts-with(@id,"vimcolor_")]').forEach(function(input){
-	var ids = input.id.split('_'), mode = ids[1], item = ids[2];
-	input.value = Keyconfig.vim_color_config[mode][item];
-	input.addEventListener('change',function(){
-		Keyconfig.vim_color_config[mode][item] = input.value;
-		KC.update();
-	},false);
-});
-
-document.getElementById('ldrize').addEventListener('click',function(){
-	if (this.checked) {
-		BackGround.LDRize();
-	} else {
-		BackGround.LDRize.Siteinfo= void 0;
-		delete BackGround.LDRize.Siteinfo;
-	}
-},false);
-
-var vim_actions = document.getElementById('vim_actions');
-var vimtab = $X('id("menu_tabs")/li[@class="vim_actions"]')[0];
-document.getElementById('chrome_vim').addEventListener('click',toggle_vim_conf,false);
-function toggle_vim_conf(e){
-	if (e.target.checked) {
-		vim_actions.style.visibility = 'visible';
-		vimtab.style.display = 'inline-block';
-	} else {
-		vim_actions.style.visibility = 'hidden';
-		vimtab.style.display = 'none';
-	}
-}
-toggle_vim_conf({target:document.getElementById('chrome_vim')});
-
-document.getElementById('ExtensionVersion').textContent = BackGround.Manifest.version;
-
-var ActionConfig = function(prefix, ActionNames){
-	var action_list = document.getElementById(prefix + 'action_list');
-	var append_action = document.getElementById(prefix + 'append_action');
-	var action_text = document.getElementById(prefix + 'action_text');
-	var actions = Keyconfig[prefix + 'actions'];
-	var ActionKeys = [];
-	for (var k in actions) ActionKeys.push(k);
-	var Actions = ActionKeys.sort().map(function(k){
-		var act=actions[k];
-		return {key:k,name:act.name,args:act.args};
-	}).map(create_action);
-	function create_action(act, i) {
-		var dt = document.createElement('dt');
-		var dd = document.createElement('dd');
-		dt.innerHTML = '<span class="lt">Key:</span>';
-		var _key = document.createElement('input');
-		_key.type = 'button';
-		_key.className = 'input_button';
-		_key.value = act.key;
-		var changed = false;
-		_key.addEventListener('focus',function(evt){
-			if (!changed) _key.value = ' ';
-		},true);
-		_key.addEventListener('click',function(evt){
-			_key.focus();
-		},true);
-		_key.addEventListener('blur',function(evt){
-			if (_key.value === ' ') {
-				_key.value = act.key;
-				save.disabled = true;
-			} else {
-				//save.disabled = false;
-			}
-		},true);
-		_key.addEventListener('keydown',function(evt){
-			evt.preventDefault();
-			evt.stopPropagation();
-			var key = get_key(evt);
-			if (!key || /^(Meta|Shift|Control|Alt)$/.test(key)) {
-				return;
-			}
-			if (changed) {
-				_key.value += ' ' + key;
-			} else {
-				_key.value = key;
-			}
-			if (actions[_key.value]) {
-				return;
-			}
-			changed = true;
-			save.disabled = false;
-			save.focus();
-		},true);
-		var save = document.createElement('button');
-		save.disabled = true;
-		save.className = 'impt';
-		save.addEventListener('click',function(evt){
-			var old_key = act.key;
-			var new_key = _key.value;
-			if (old_key !== new_key && new_key) {
-				act.key = new_key;
-				KC.change(new_key, old_key, prefix)
-				save.disabled = true;
-				changed = false;
-			}
-		},false);
-		save.textContent = 'save';
-		var reset = document.createElement('button');
-		reset.addEventListener('click',function(evt){
-			_key.value = act.key;
-			save.disabled = true;
-			changed = false;
-		},false);
-		reset.textContent = 'reset';
-		dt.appendChild(_key);
-		dt.appendChild(save);
-		dt.appendChild(reset);
-		var action = document.createElement('select');
-		var args_list;
-		KC[ActionNames].forEach(function(group){
-			var optg = document.createElement('optgroup');
-			optg.setAttribute('label', group.label || group.group);
-			group.actions.forEach(function(_act, i){
-				var opt = document.createElement('option');
-				opt.value = group.group + '::' + _act.name;
-				opt.textContent = (group.labels && group.labels[i]) || _act.name;
-				if (_act.name === act.name) {
-					if (_act.args.length) {
-						set_arg(_act);
-					}
-					opt.selected = true;
-				}
-				optg.appendChild(opt);
-			});
-			action.appendChild(optg);
-		});
-		function set_arg(_act){
-			args_list = document.createElement('ul');
-			var args = [];
-			_act.args.forEach(function(_arg, i){
-				var _i = i+1;//, KEY = act.key;
-				var _li = document.createElement('li');
-				_li.innerHTML = '<span class="lt">' + _arg.type + ':</span>';
-				var arg;
-				if (_arg.type === 'custom tag') {
-					arg = document.createElement('textarea');
-				} else if (_arg.type === 'hidden') {
-					arg = document.createElement('input');
-					arg.type = 'hidden';
-				} else {
-					arg = document.createElement('input');
-					arg.type = 'text';
-					if (_arg.type === 'KEY') {
-						arg.maxLength = 1;
-					}
-				}
-				if (act.args[i] !== void 0) {
-					arg.value = act.args[i];
-				} else if (_arg.default_value !== void 0) {
-					arg.value = _arg.default_value;
-				}
-				arg.addEventListener('change',function(){
-					args[i] = arg.value;
-					KC.arg_set(act.key, {name:_act.name, args:args}, prefix);
-				},false);
-				arg.setAttribute('placeholder', _arg.type);
-				_li.appendChild(arg);
-				args_list.appendChild(_li);
-				args.push(arg.value || '');
-			});
-			dd.insertBefore(args_list, dd.firstChild);
-			return args;
-		}
-		function del_arg(){
-			if (args_list) {
-				dd.removeChild(args_list);
-				args_list = null;
-			}
-		}
-		action.addEventListener('change',function(e){
-			del_arg();
-			var _act = KC[ActionNames+'_hash'][action.value], args;
-			if (_act.args.length) {
-				args = set_arg(_act);
-			}
-			act.name = action.value;
-			act.label = chrome.i18n.getMessage('action_name_' + act.name.replace(/\W/g,'_'));
-			KC.set(act.key, _act.name, prefix, args);
-		},false);
-		var span = document.createElement('span');
-		span.className = 'lt';
-		span.textContent = 'Action:';
-		dd.appendChild(span);
-		dd.appendChild(action);
-		if (act.key.indexOf('#') !== 0) {
-			var del = document.createElement('button');
-			del.textContent = 'Del';
-			del.addEventListener('click',function(){
-				action.disabled = !action.disabled;
-				if (action.disabled) {
-					KC.del(act.key, prefix);
-					del.textContent = 'Undo';
-					dt.className = 'disabled';
-					dd.className = 'disabled';
-				} else {
-					KC.set(act.key, action.value, prefix);
-					del.textContent = 'Del';
-					dt.className = '';
-					dd.className = '';
-				}
-			});
-			dd.appendChild(del);
-		} else {
-			_key.textContent = act.key.slice(1);
-		}
-		action_list.insertBefore(dt, act.point);
-		action_list.insertBefore(dd, act.point);
-		act.list = dt;
-		act.dlist = dd;
-		if (act.focus) {
-			action.focus();
-		}
-		return act;
-	}
-	action_text.addEventListener('focus',function(evt){
-		if (action_text.value === 'type key here') {
-			action_text.value = ' ';
-		}
-	},true);
-	action_text.addEventListener('click',function(evt){
-		action_text.focus();
-	},true);
-	action_text.addEventListener('blur',function(evt){
-		if (action_text.value === ' ') {
-			action_text.value = 'type key here';
-			append_action.disabled = true;
-		} else {
-			append_action.disabled = false;
-		}
-	},true);
-	append_action.disabled = true;
-	action_text.addEventListener('keydown',function(evt){
-		evt.preventDefault();
-		evt.stopPropagation();
-		var key = get_key(evt);
-		if (!key || /^(Meta|Shift|Control|Alt)$/.test(key)) {
-			return;
-		}
-		if (action_text.value !== ' ') {
-			action_text.value += ' ' + key;
-		} else {
-			action_text.value = key;
-		}
-		append_action.disabled = false;
-		append_action.focus();
-	},true);
-	append_action.addEventListener('click',function(){
-		var key = action_text.value;
-		if (!key) {
-			action_text.focus();
-			return;
-		}
-		if (ActionKeys.indexOf(key) !== -1) {
-			var i = ActionKeys.indexOf(key);
-			var s = Actions[i].dlist.getElementsByTagName('select')[0];
-			if (s) s.focus();
-			return;
-		}
-		ActionKeys.push(key);
-		ActionKeys.sort();
-		var index = ActionKeys.indexOf(key);
-		var point = (Actions[index] || {}).list;
-		var act = {key:key,focus:true,point:point,name:'no action',args:[]};
-		Actions = Actions.slice(0, index).concat([act], Actions.slice(index));
-		create_action(act, index);
-		KC.set(act.key, act.name, prefix);
-		action_text.value ='type key here';
-		append_action.disabled = true;
-	});
-};
-
-ActionConfig('normal_', 'action_names');
-ActionConfig('limited_', 'action_names');
-ActionConfig('vim_normal_', 'vim_action_names');
-ActionConfig('vim_insert_', 'vim_action_names');
-
-var config_text = document.getElementById('config_text');
-var export_conf = document.getElementById('export_conf');
-export_conf.addEventListener('click',function(){
-	config_text.value = JSON.stringify(Keyconfig, null, 2);
-},false);
-var import_conf = document.getElementById('import_conf');
-import_conf.addEventListener('click',function(){
-	if (!config_text.value){
-		return;
-	}
-	try {
-		JSON.parse(config_text.value);
-	} catch (e) {
-		alert('インポートに失敗しました。正しいJSONではありません。');
-		return;
-	}
-	var conf = JSON.parse(config_text.value);
-	if (
-		typeof conf.normal_actions === 'object' &&
-		typeof conf.limited_actions === 'object'
-	) {
-		if (conf.version !== BackGround.Manifest.version) {
-			if (!confirm('設定がExportされた際のバージョンと現在の使用しているバージョンが異なるため、正常にインポートできない可能性があります。現在の設定をバックアップしてから続行することを推奨します。\n続行しますか?')){
-				return;
-			}
-		}
-		var _keyconfig = Keyconfig;
-		try {
-			Keyconfig = conf;
-			BackGround.Keyconfig = Keyconfig;
-			KC.update();
-		} catch (e) {
-			alert('インポートに失敗しました。');
-			BackGround.Keyconfig = _keyconfig;
-			KC.update();
-			return;
-		}
-		alert('正常にインポートできました。新しい設定を再読み込みします。');
-		location.reload();
-	}
-},false);
-var reset_all = document.getElementById('reset_all');
-reset_all.addEventListener('click',function(){
-	if (confirm('Are sure you want to delete this config? There is NO undo!')) {
-		Keyconfig = JSON.parse(BackGround.default_keyconfig);
-		BackGround.Keyconfig = Keyconfig;
-		KC.update();
-		location.reload();
-	}
-},false);
-
-
-var sections = $X('/html/body/div/div/section[contains(@class, "content")]');
-var inner_container = document.getElementById('inner_container');
-var container = document.getElementById('container');
-inner_container.style.width = sections.length * (WIDTH+20) + 'px';
-//inner_container.style.height = HEIGHT + 'px';
-//container.style.height = HEIGHT + 'px';
-container.style.marginTop = '-2px';
-sections.forEach(function(section, _i){
-	section.style.visibility = 'hidden';
-	section.style.height = '100px';
-});
-var btns = $X('id("menu_tabs")/li/a');
-var default_title = document.title;
-btns.forEach(function(btn, i, btns){
-	btn.addEventListener('click',function(evt){
-		evt.preventDefault();
-		btns.forEach(function(btn){btn.className = '';})
-		btn.className = 'active';
-		sections[i].style.visibility = 'visible';
-		sections[i].style.height = 'auto';
-		new Tween(inner_container.style, {marginLeft:{to:i * -WIDTH,tmpl:'$#px'},time:0.2,onComplete:function(){
-				document.title = default_title + btn.hash;
-				location.hash = btn.hash;
-				window.scrollBy(0, -1000);
-				sections.forEach(function(section, _i){
-					if (i !== _i) {
-						section.style.visibility = 'hidden';
-						section.style.height = '100px';
-					}
-				});
-			}});
-	}, false);
-});
-if (location.hash) {
-	sections.some(function(section, i){
-		if ('#' + section.id === location.hash) {
-			btns.forEach(function(btn){btn.className = '';})
-			btns[i].className = 'active';
-			inner_container.style.marginLeft = -WIDTH * i + 'px';
-			section.style.visibility = 'visible';
-			section.style.height = 'auto';
-			document.title = default_title + location.hash;
-		}
-	});
-} else {
-	sections[0].style.height = 'auto';
-	sections[0].style.visibility = 'visible';
-	document.title = default_title + '#' + sections[0].id;
-}
-};
-</script>
+<script src="options.js"></script>
 </body>
 </html>