GM_option

support tool for UserConfig.(library)

当前为 2015-04-29 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/9507/49221/GM_option.js

  1. // ==UserScript==
  2. // @name GM_option
  3. // @namespace https://greasyfork.org/ja/scripts/9507
  4. // @homepageURL https://greasyfork.org/ja/scripts/9507
  5. // @license http://creativecommons.org/licenses/by-nc-sa/4.0/
  6. // @include http://*
  7. // @include https://*
  8. // @include file:*
  9. // @copyright Noi & Noisys & NoiSystem & NoiProject
  10. // @author noi
  11. // @description support tool for UserConfig.(library)
  12. // @version 1.03
  13. // @grant GM_registerMenuCommand
  14. // @grant GM_setValue
  15. // @grant GM_getValue
  16. // @grant GM_deleteValue
  17. // @grant GM_log
  18. // ==/UserScript==
  19.  
  20. /*************************************************************************
  21. [about]
  22.  
  23. This script is the library to make a setting screen.
  24. I made this support tool in order to make more easily.
  25.  
  26. *************************************************************************
  27. [How to use]
  28.  
  29. Sample code is end of this Script.
  30. Plz test it.
  31.  
  32.  
  33. If savedata is none....?
  34. <first start-up or no savedata or parameter(HTML tag) changed>
  35. This script make GM_option window and save default.
  36. <next time>
  37. This script never make GM_option window without running open-function.
  38.  
  39. <@grant>----------------------------------------------
  40. you need to add @grant.
  41. // @grant GM_setValue
  42. // @grant GM_getValue
  43. // @grant GM_deleteValue
  44. // @grant GM_registerMenuCommand
  45.  
  46. GM_setValue and GM_getValue and GM_deleteValue is required.
  47. GM_registerMenuCommand is optional.
  48.  
  49.  
  50. <start function>----------------------------------------------
  51. GM_option.open(String,String,HashArray);
  52.  
  53. first String is HTML Tag(header ex: style or script or etc...)
  54. second String is HTML Tag(document.body).
  55. third HashArray is optional,it's messages for dialog.
  56.  
  57. Message List
  58. 'save' - when click save button.
  59. 'reset' - when click reset button.(discard changes)
  60. 'clear' - when click clear button.(delete savedata)
  61. 'delete' - when click del button.(delete multiple)
  62.  
  63.  
  64. <user function>--------------------------------------
  65. At first,get user's settings.
  66. GM_option.get();
  67.  
  68. return hashArray(Associative array).
  69.  
  70.  
  71. <HTML tag>-------------------------------------------
  72. use form inputs.
  73. 'name' is save-key.
  74. 'value' is save-data.
  75.  
  76. ex)
  77. HTML tag is...
  78. <input type="text" name="this_is_Key" value="this_is_Data" />
  79.  
  80. Save Data is...
  81. {"this_is_Key":"this_is_Data"}
  82.  
  83.  
  84. <multiple text>--------------------------------------
  85. 'name' is ****_multiple9999.(required)
  86. 9999 is number of array.(required)
  87. 'value' is default.(optional)
  88. 'defArray' is default array.(optional)
  89. <button id="this_is_required"> is addButton.(required)
  90.  
  91. ex)
  92. HTML tag is...
  93. <input type="text" name="freeName_multiple2" value="data1" /> <input type="text" name="freeName_multiple2" value="data2" /> <button id="addButton">add</button>
  94.  
  95. Save Data is...
  96. {"freeName_multiple2":[["data1","data2"],["data3","data4"], and more ]}
  97. "data3" and "data4" are input by user.
  98.  
  99. ex2)
  100. HTML tag is...
  101. <input type="text" name="freeName_multiple2" defArray="data1-2,data1-3,data1-4" value="data1-1" /> <input type="text" name="freeName_multiple2" defArray="data2-2,data2-3,data2-4" value="data2-1" /> <button id="addButton">add</button>
  102.  
  103. Save Data is...
  104. {"freeName_multiple2":[["data1-1","data2-1"],["data1-2","data2-2"],["data1-3","data2-3"],["data1-4","data2-4"],["data1-5","data2-5"], and more ]}
  105. "data1-5" and "data2-5" are input by user.
  106.  
  107. ## caution ##
  108. If elements's 'name' are same, defArray are same array.length.
  109.  
  110. <select-multiple(HTML5)>----------------------------
  111. selected is checked.(optional)
  112.  
  113. ex)
  114. HTML tag is...
  115. <select name="selectName" multiple size=5>
  116. <option name="optionName1" value="data1" >item1</option>
  117. <option name="optionName2" value="data2" selected>item2</option>
  118. <option name="optionName3" value="data3" >item3</option>
  119. <option name="optionName4" value="data4" selected>item4</option>
  120. <option name="optionName5" value="data5" >item5</option>
  121.  
  122. Save Data is...
  123. {"selectName":"{\"data2\":true,\"data4\":true}"}
  124.  
  125. To use...
  126. var userSettings = GM_option.get();
  127. var selectArray = JSON.parse(userSettings['selectName']);
  128.  
  129.  
  130. <addEventListener>----------------------------------
  131. 'GM_option_loaded'
  132.  
  133. this event is dispatched...
  134. when made GM_option frame (@first start-up)
  135. when loaded User's Settings from GM_getValue (@next time)
  136.  
  137. ex)
  138. window.addEventListener('GM_option_loaded',userFunction,false);
  139.  
  140.  
  141. <access GM_option document>----------------------------------
  142. GM_option.frame
  143. GM_option.doc
  144.  
  145. ex)
  146. var frame = GM_option.frame;
  147. var doc = GM_option.doc.head;
  148. var head = GM_option.doc.body;
  149. var form = GM_option.doc.opForm;
  150.  
  151.  
  152. <other function>----------------------------------
  153. after GM_option opened
  154. GM_option.show(); - show GM_option
  155. GM_option.close(); - hide GM_option
  156. GM_option.save(); - save settings & reload
  157. GM_option.reset(); - discard changes
  158. GM_option.clear(); - delete SaveData & reload
  159.  
  160.  
  161. *************************************************************************
  162. [history]
  163.  
  164. 04/30/2015 - v1.03 add:sandbox
  165. 04/29/2015 - v1.01 add:第二引数(body)に変更があった場合は変更箇所の初期値を保存する。初期値配列の指定方法追加。
  166. 04/29/2015 - v1.01 fix:入力欄でENTERキーを押すとaddボタンを押した時と同じ動作をするバグ。第一引数(head)にスクリプトタグを指定しても動作しないバグ修正。resetボタン修正
  167. 04/26/2015 - v1.0 release
  168. *************************************************************************/
  169.  
  170. var GM_option = {
  171. init: function(){
  172. GM_option.defScroll = window.onscroll; //save default scroll
  173. var head = GM_option.head;
  174. var htmlText = GM_option.htmlText;
  175.  
  176. //iframe
  177. var obj = GM_option.frame = window.document.createElement('iframe');
  178. obj.id = 'GM_option';
  179. obj.srcdoc = '<head>' + GM_option.head + '</head><body style="background:white;">' + GM_option.htmlText + '</body>';
  180. obj.setAttribute('style','position:fixed;top:0;left:0;right:0;bottom:0; margin:auto; z-index:999999;width:calc(100% - 40px);height:calc(100% - 60px); max-height:90%; max-width:90%; overflow:auto; visibility:hidden; border:none;');
  181. obj.sandbox = "allow-same-origin";
  182. document.body.appendChild(obj);
  183.  
  184. obj.addEventListener('load', GM_option.make(head,htmlText) ,false);
  185. },
  186. open: function(head,htmlText,msgArray){
  187. GM_option.get();
  188. if(htmlText) GM_option.htmlTextCheck(htmlText);
  189.  
  190. var oType = Object.prototype.toString.call(htmlText).slice(8, -1);
  191. if(!htmlText && htmlText != 'String' && !htmlText.match(/\<.*?\>/)){
  192. alert('second parameter(htmltext) is not correct.');
  193. return;
  194. }
  195. if(!GM_option.event){
  196. GM_option.event = document.createEvent('HTMLEvents');
  197. GM_option.event.initEvent('GM_option_loaded', true, false);
  198.  
  199. GM_option.msgArray = msgArray;
  200. }
  201.  
  202. if(!GM_option.makeFlg && GM_option.saveData){
  203. GM_option.makeFlg = true;
  204. window.dispatchEvent(GM_option.event);
  205. return;
  206. }
  207.  
  208. GM_option.head = head || '';
  209. GM_option.htmlText = htmlText = [
  210. '<form name="opForm" action="javascript:void(0);" onSubmit="return false;">',
  211. '<table id="opTable" style="padding:20px;height:98%;width:98%;"><tr><td align="center" valign="middle">',
  212. htmlText,
  213. '<span id="consol">',
  214. '<input type="button" id="saveConfig" value="save" title="save option" /> ',
  215. '<input type="button" id="resetConfig" value="reset" title="Revert To Last Save" /> ',
  216. '<input type="button" id="clearConfig" value="clear" title="clear userSettings" /> ',
  217. '<button id="closeConfig" title="close option window">close</button>',
  218. '</span>',
  219. '</td></tr></table></form>'
  220. ].join('');
  221.  
  222. if(htmlText && (!GM_option.frame || !GM_option.layer)) GM_option.init();
  223. GM_option.show();
  224. },
  225. make: function() { return function(){
  226. var head = GM_option.head;
  227. var htmlText = GM_option.htmlText;
  228.  
  229. this.removeEventListener("load", GM_option.make(head,htmlText) ,false);
  230.  
  231. var opDoc = GM_option.doc = this.contentDocument;
  232.  
  233. //close
  234. var closeButton = opDoc.getElementById('closeConfig');
  235. closeButton.addEventListener('click',GM_option.close,false);
  236.  
  237. //save
  238. var saveButton = opDoc.getElementById('saveConfig');
  239. saveButton.addEventListener('click',GM_option.save,false);
  240.  
  241. //clear
  242. var defaultButton = opDoc.getElementById('clearConfig');
  243. defaultButton.addEventListener('click',GM_option.clear,false);
  244.  
  245. //reset
  246. var resetButton = opDoc.getElementById('resetConfig');
  247. resetButton.addEventListener('click',GM_option.reset,false);
  248.  
  249. GM_option.load(); //デフォルト読み込み
  250. if(!GM_option.saveData || GM_option.htmlChangeFlg) GM_option.save();
  251.  
  252. //layer
  253. var layer = GM_option.layer = window.document.createElement('div');
  254. layer.id = 'opLayer';
  255. layer.setAttribute('style','position:fixed; top:0px; left:0px; width:100%; height:100%; background-color:black; z-index:5000; opacity:0.7;');
  256. document.body.appendChild(layer);
  257. layer.addEventListener('click', GM_option.close,false);
  258.  
  259. window.addEventListener('beforeunload', function() {
  260. window.removeEventListener("beforeunload", arguments.callee,false);
  261. layer.removeEventListener('click', GM_option.close,false);
  262. closeButton.removeEventListener('click',GM_option.close,false);
  263. saveButton.removeEventListener('click',GM_option.save,false);
  264. defaultButton.removeEventListener('click',GM_option.clear,false);
  265. resetButton.removeEventListener('click',GM_option.reset,false);
  266.  
  267. GM_option.remove();
  268. },false);
  269.  
  270. if(GM_option.makeFlg) GM_option.show();
  271. else{
  272. GM_option.load();
  273. GM_option.close();
  274. window.dispatchEvent(GM_option.event);
  275. }
  276. GM_option.makeFlg = true;
  277.  
  278. opDoc = style = head = htmlText = null;
  279. }},
  280. show: function(){
  281. if(!GM_option.frame || !GM_option.layer) return;
  282. GM_option.scrollStop(true);
  283. GM_option.frame.style.visibility = 'visible';
  284. GM_option.layer.style.visibility = 'visible';
  285. },
  286. save: function(clickFlg){
  287. if(clickFlg){
  288. var txt = 'Do you want to save?(ok:reload)';
  289. if(GM_option.msgArray) txt = GM_option.msgArray['save'] || txt;
  290. if(confirm(txt) == false) return
  291. }
  292.  
  293. var userData = GM_option.get();
  294. var form = GM_option.doc.opForm;
  295. var array={};
  296. var multiArray = {};
  297. for(var i=0,j=form.length;i<j;i++){
  298. var obj = form[i];
  299. var name =obj.name;
  300. if(!name) continue;
  301. switch(obj.type){
  302. case 'checkbox':
  303. if(obj.checked)array[name] = true;
  304. else array[name] = false;
  305. continue;
  306. case 'radio':
  307. if(obj.checked)array[name] = obj.value;
  308. continue;
  309. case 'text':
  310. if(!name.match(/_multiple(\d+)$/)){
  311. array[name] = obj.value;
  312. continue;
  313. }else{
  314. var num = RegExp.$1;
  315. if(!array[name])array[name] = [];
  316. var arrayNum = array[name].length - 1;
  317. if(arrayNum < 0) arrayNum = 0;
  318.  
  319. if(!array[name][arrayNum]) array[name][arrayNum] = [];
  320. if(array[name][arrayNum].length < num) array[name][arrayNum].push(obj.value);
  321. else{
  322. arrayNum++;
  323. if(!array[name][arrayNum]) array[name].push([]);
  324. array[name][arrayNum].push(obj.value);
  325. }
  326.  
  327. if(!obj.hasAttribute('defArray') || (userData && userData[name])) continue;
  328.  
  329. if(!multiArray[name]) multiArray[name] = [];
  330. multiArray[name].push(obj.getAttribute('defArray'));
  331.  
  332. continue;
  333. }
  334. continue;
  335. case 'select-one':
  336. var opt = obj.getElementsByTagName('option');
  337. for(var op=0,opLength=opt.length;op<opLength;op++){
  338. var optObj = opt[op];
  339. if(optObj.selected){ array[name] = optObj.value; break;}
  340. }
  341. continue;
  342. case 'select-multiple':
  343. var opt = obj.getElementsByTagName('option');
  344. var tmpArray = {};
  345. for(var op=0,opLength=opt.length;op<opLength;op++){
  346. var optObj = opt[op];
  347. if(optObj.selected) tmpArray[optObj.value] = true;
  348. }
  349. array[name] = JSON.stringify(tmpArray);
  350. continue;
  351. default:
  352.  
  353. array[name] = obj.value;
  354. continue;
  355. }
  356. }
  357. //example) multiArray is {"textTest5_5_multiple3":["aa,22,33,44","bb,44,55,66","cc,88,99,00"]}
  358. //want to change "textTest5_5_multiple3" to "textTest5_5_multiple3":[["dataA","Multi test2","Multi testA"],["aa","bb","cc"],["22","44","88"],["33","55","99"],["44","66","00"]]
  359. for(var key in multiArray){
  360. var num = parseInt(key.replace(/.*_multiple(\d+)$/,"$1"));
  361. var multiList = multiArray[key];
  362. for(var i=0,j=multiList.length;i<j;i++){
  363. var multiData = multiList[i].split(',');
  364. for(var x=0,y=multiData.length;x<y;x++){
  365. var next = x+1;
  366. if(!array[key][next]) array[key][next] = [];
  367. array[key][next][i] = multiData[x];
  368. }
  369. }
  370. }
  371.  
  372. GM_option.saveData = JSON.stringify(array);
  373.  
  374. GM_setValue('opData',GM_option.saveData);
  375. if(clickFlg) location.reload();
  376. },
  377. //discard changes
  378. reset: function(){
  379. var txt = 'discard changes?';
  380. if(GM_option.msgArray) txt = GM_option.msgArray['reset'] || txt;
  381. if(confirm(txt) == false) return;
  382.  
  383. var dels = GM_option.doc.getElementsByClassName('delSpans');
  384. for (var i = dels.length-1; i >= 0; i--) {
  385. dels[i].parentNode.removeChild(dels[i]);
  386. }
  387. GM_option.doc.opForm.reset();
  388. GM_option.load();
  389.  
  390. },
  391. //delete SaveData
  392. clear: function(){
  393. var txt = 'delete settings?(ok:reload)';
  394. if(GM_option.msgArray) txt = GM_option.msgArray['clear'] || txt;
  395. if(confirm(txt) == false) return;
  396.  
  397. GM_deleteValue('opData');
  398. GM_option.close();
  399. location.reload();;
  400. },
  401. //delete line for Multiple
  402. deleteLine: function(e){
  403. var txt = 'delete this line?';
  404. if(GM_option.msgArray) txt = GM_option.msgArray['delete'] || txt;
  405. if(confirm(txt) == false) return;
  406.  
  407. e.target.removeEventListener("click", arguments.callee,false);
  408. e.target.parentNode.parentNode.removeChild(e.target.parentNode);
  409. },
  410. //GM_option.saveData is String,return object Array
  411. get: function(){
  412. if(GM_option.saveData) return JSON.parse(GM_option.saveData);
  413. if(!GM_getValue('opData')) return undefined;
  414.  
  415. GM_option.saveData = GM_getValue('opData');
  416. return JSON.parse(GM_option.saveData);
  417. },
  418. //set data
  419. load: function(){
  420. var userSet = GM_option.get();
  421. if(userSet == undefined) return;
  422. var form = GM_option.doc.opForm;
  423. var lastName = "";
  424. var cntMulti = 0;
  425. var multipleArray = {};
  426.  
  427. for(var i=0,j=form.length;i<j;i++){
  428. var obj = form[i];
  429. var name = obj.name;
  430. var userData = userSet[name];
  431. if(userData == undefined) continue;
  432. switch(obj.type){
  433. case 'checkbox':
  434. if(userData)obj.setAttribute('checked',true);
  435. else obj.removeAttribute('checked');
  436. continue;
  437. case 'radio':
  438. if(obj.value == userData)obj.setAttribute('checked',true);
  439. else obj.removeAttribute('checked');
  440. continue;
  441. case 'textarea':
  442. obj.innerHTML = obj.value = userData;
  443. continue;
  444. case 'text':
  445. if(!name.match(/_multiple(\d+)$/)){
  446. obj.setAttribute('value',userData);
  447. continue;
  448. }else{
  449. var num = RegExp.$1;
  450. if(lastName != name){
  451. lastName = name;
  452. cntMulti = 0;
  453. }
  454.  
  455.  
  456. obj.setAttribute('value',userData[Math.floor(cntMulti / num)][cntMulti % num]);
  457.  
  458. cntMulti++;
  459.  
  460. if(num == cntMulti){
  461. var addObj = obj.parentNode.getElementsByTagName('button');
  462. if(!addObj[0]){
  463. alert('addButton is nothing for multiple select.');
  464. GM_option.remove();
  465. return;
  466. }
  467. var id = addObj[0].id;
  468. GM_option.addMultiple(name,num,id);
  469. j = form.length;
  470. }
  471.  
  472.  
  473. continue;
  474. }
  475. continue;
  476. case 'select-one':
  477. var opt = obj.getElementsByTagName('option');
  478. for(var op=0,opLength=opt.length;op<opLength;op++){
  479. var optObj = opt[op];
  480. if(optObj.value == userData) optObj.setAttribute('selected',true);
  481. else optObj.removeAttribute('selected');
  482. }
  483. continue;
  484. case 'select-multiple':
  485. var tmpArray = JSON.parse(userData);
  486. var opt = obj.getElementsByTagName('option');
  487. for(var op=0,opLength=opt.length;op<opLength;op++){
  488. var optObj = opt[op];
  489. if(tmpArray[optObj.value]) optObj.setAttribute('selected',true);
  490. else optObj.removeAttribute('selected');
  491. }
  492. continue;
  493. default:
  494. obj.setAttribute('value',userData);
  495. continue;
  496. }
  497. }
  498. },
  499. close: function(){
  500. GM_option.scrollStop(false);
  501. if(!GM_option.frame) return;
  502.  
  503. GM_option.frame.style.visibility = 'hidden';
  504. if(!GM_option.layer) return;
  505. GM_option.layer.style.visibility = 'hidden';
  506. },
  507. remove: function(){
  508. if(GM_option.frame) document.body.removeChild(GM_option.frame);
  509. if(GM_option.layer) document.body.removeChild(GM_option.layer);
  510. GM_option = null;
  511. },
  512. scrollStop: function(stopFlg){
  513. GM_option.scrollY = document.documentElement.scrollTop || document.body.scrollTop;
  514.  
  515. if(stopFlg) window.onscroll = function () { window.scrollTo(0, GM_option.scrollY); };
  516. else window.onscroll = GM_option.defScroll;
  517. },
  518. //make line for Multiple
  519. addLine: function(obj,txt,addID){
  520. var num = parseInt(obj.getAttribute('num')) || 0;
  521. var strID = addID + '_delItem' + num;
  522. if(GM_option.doc.getElementById(strID)) return false;
  523. obj.parentNode.insertAdjacentHTML('beforeend',txt + '<button id="' + strID + '">del</button></span>');
  524.  
  525. //del button
  526. var delButton = GM_option.doc.getElementById(strID);
  527. delButton.addEventListener('click',GM_option.deleteLine,true);
  528. window.addEventListener('beforeunload', function() {
  529. window.removeEventListener("beforeunload", arguments.callee,false);
  530. delButton.removeEventListener('click',GM_option.deleteLine,true);
  531. },false);
  532.  
  533.  
  534. obj.setAttribute('num',num + 1);
  535. return true;
  536. },
  537. //Multiple main
  538. addMultiple: function(name,num,addID){
  539. var addButton = GM_option.doc.getElementById(addID);
  540. var strTxt = '<span class="delSpans"><br>';
  541. for(var x=0;x<num;x++){
  542. strTxt += '<input type="text" name="' + name + '" /> ';
  543. }
  544.  
  545. //addEvent
  546. if(!addButton.hasAttribute('num')){
  547. var addEvent = function(e){
  548. GM_option.addLine(e.target,strTxt,addID);
  549. };
  550. addButton.addEventListener('mouseup',addEvent,false);
  551. window.addEventListener('beforeunload', function() {
  552. window.removeEventListener("beforeunload", arguments.callee,false);
  553. addButton.removeEventListener('click',addEvent,false);
  554. },false);
  555. }
  556.  
  557. //addInput(複数選択肢)
  558. var testArray = GM_option.get()[name];
  559. addButton.setAttribute('num',1);
  560. for(var i=1,j=testArray.length;i<j;i++){
  561. if(!GM_option.addLine(addButton,strTxt,addID)) break;
  562. }
  563. },
  564. htmlTextCheck: function(htmlText){
  565. var txt = GM_getValue('htmlText');
  566. if(!txt || (txt && txt != htmlText)){
  567. GM_setValue('htmlText',htmlText);
  568. if(!txt) return;
  569. GM_option.saveData = null;
  570. GM_option.htmlChangeFlg = true;
  571. }
  572. }
  573. };
  574.  
  575.  
  576.  
  577. //sample code
  578. /*********************************************************************************************************************
  579.  
  580.  
  581. //sample header(ex:style, script etc...)
  582. const strHeader = [
  583. '<style id ="cfgCSS" type="text/css">',
  584. '#cfgTable{ border: solid #ccc 1px; border-spacing:0; border-radius:6px 6px 0 0; -webkit-border-radius:6px 6px 0 0; box-shadow: 0 1px 1px #ccc; -webkit-box-shadow: 0 1px 1px #ccc; }',
  585. '#cfgTable tr:hover{ transition: all 0.1s ease-in-out; background:#fbf8e9; -webkit-transition: all 0.1s ease-in-out; }',
  586. '#cfgTable th, #cfgTable td{ border-left: 1px solid #ccc; border-top: 1px solid #ccc; vertical-align: top; white-space: nowrap; padding: 3px; }',
  587. '#cfgTable th{ color: #151; background: #E3F6E7;}',
  588. '#cfgTitle, #cfgTable th:first-child, #cfgTable td:first-child { border-left: none;}',
  589. '#cfgTable tr:first-child th:first-child{ border-top: none; color: #151; border-bottom: 3px solid #036; background: #A0D0A0; padding: 6px; }',
  590. '#cfgTable label{ padding:1px 5px 2px 5px; }',
  591. '#cfgTable label:hover{ background:#ada; }',
  592. '</style>'
  593. ].join('');
  594.  
  595.  
  596. //sample HTML
  597. var strHTML = [
  598. '<table id="cfgTable" align="center">',
  599. '<thead>',
  600. '<tr>',
  601. '<th id="cfgTitle" colspan=2>Config Title</th>',
  602. '</tr>',
  603. '<tr>',
  604. '<th>Settings</th>',
  605. '<th>Select</th>',
  606. '</tr>',
  607. '</thead>',
  608. '<tbody>',
  609. '<tr>',
  610. '<td>',
  611. 'checkbox test',
  612. '</td>',
  613. '<td>',
  614. '<input type="checkbox" id="flg1" name="check1" checked />',
  615. '<label for="flg1">check1</label>',
  616. '<input type="checkbox" id="flg2" name="check2" />',
  617. '<label for="flg2">check2</label>',
  618. '<input type="checkbox" id="flg3" name="check3" />',
  619. '<label for="flg3">check3</label>',
  620. '</td>',
  621. '</tr>',
  622. '<tr>',
  623. '<td>',
  624. 'radiobutton test1',
  625. '</td>',
  626. '<td>',
  627. '<input type="radio" id="firstOn" name="radio1" value=true checked />',
  628. '<label for="firstOn">on</label>',
  629. '<input type="radio" id="firstOff" name="radio1" value=false />',
  630. '<label for="firstOff">off</label>',
  631. '</td>',
  632. '</tr>',
  633. '<tr>',
  634. '<td>',
  635. 'radiobutton test2',
  636. '</td>',
  637. '<td>',
  638. '<input type="radio" id="secondOn" name="radio2" value="1" />',
  639. '<label for="secondOn">type1</label>',
  640. '<input type="radio" id="secondOff" name="radio2" value="2" checked />',
  641. '<label for="secondOff">type2</label>',
  642. '</td>',
  643. '</tr>',
  644. '<tr>',
  645. '<td>text(inline) test</td>',
  646. '<td>',
  647. '<input type="text" name="textTest1" value="input text" />',
  648. '</td>',
  649. '</tr>',
  650. '<tr>',
  651. '<td>textarea test</td>',
  652. '<td>',
  653. '<textarea name="textarea">textarea test\rthis\ris\rsample\rdata</textarea>',
  654. '</td>',
  655. '</tr>',
  656. '<tr>',
  657. '<td>text(inline) for Multiple test</td>',
  658. '<td>',
  659. '<input type="text" name="textTest3_multiple1" value="test" /> <button id="addItem">add</button>',
  660. '</td>',
  661. '</tr>',
  662. '<tr>',
  663. '<td>text(inline) for Multiple test1</td>',
  664. '<td>',
  665. '<input type="text" name="textTest3_3_multiple1" defArray="BB,CC,DD" value="AA" /> <button id="addItem1">add</button>',
  666. '</td>',
  667. '</tr>',
  668. '<tr>',
  669. '<td>text(inline) for Multiple test2</td>',
  670. '<td>',
  671. '<input type="text" name="textTest4_multiple2" value="data1" /> <input type="text" name="textTest4_multiple2" value="Multi test" /> <button id="addItem2">add</button>',
  672. '</td>',
  673. '</tr>',
  674. '<tr>',
  675. '<td>text(inline) for Multiple test3</td>',
  676. '<td>',
  677. '<input type="text" name="textTest5_multiple3" value="dataA" /> <input type="text" name="textTest5_multiple3" value="Multi test2" /> <input type="text" name="textTest5_multiple3" value="Multi testA" /> <button id="addItem3">add</button>',
  678. '</td>',
  679. '</tr>',
  680. '<tr>',
  681. '<td>text(inline) for Multiple test4</td>',
  682. '<td>',
  683. '<input type="text" name="textTest5_5_multiple3" defArray="aa,22,33,44" value="dataA" /> <input type="text" name="textTest5_5_multiple3" defArray="bb,44,55,66" value="Multi test2" /> <input type="text" name="textTest5_5_multiple3" defArray="cc,88,99,00" value="Multi testA" /> <button id="addItem4">add</button>',
  684. '</td>',
  685. '</tr>',
  686. '<tr>',
  687. '<td>select option test</td>',
  688. '<td>',
  689. '<select name="select">',
  690. '<option name="nameop1" value="op1">item1</option>',
  691. '<option name="nameop2" value="op2" selected>item2</option>',
  692. '<option name="nameop3" value="op3">item3</option>',
  693. '</select>',
  694. '</td>',
  695. '</tr>',
  696. '<tr>',
  697. '<td>select option test2</td>',
  698. '<td>',
  699. '<select name="select2" size=5>',
  700. '<option name="nameopA" value="opA">itemA</option>',
  701. '<option name="nameopB" value="opB" selected>itemB</option>',
  702. '<option name="nameopC" value="opC">itemC</option>',
  703. '<option name="nameopD" value="opE">itemE</option>',
  704. '<option name="nameopE" value="opF">itemF</option>',
  705. '</select>',
  706. '</td>',
  707. '</tr>',
  708. '<tr>',
  709. '<td>select option test3 multiple</td>',
  710. '<td>',
  711. '<select name="select3" multiple size=5>',
  712. '<option name="nameopAA" value="opAA">itemAA</option>',
  713. '<option name="nameopBB" value="opBB" selected>itemBB</option>',
  714. '<option name="nameopCC" value="opCC">itemCC</option>',
  715. '<option name="nameopDD" value="opEE" selected>itemEE</option>',
  716. '<option name="nameopEE" value="opFF">itemFF</option>',
  717. '</select>',
  718. '</td>',
  719. '</tr>',
  720. '</tbody>',
  721. '</table>',
  722. ].join('');
  723.  
  724.  
  725.  
  726.  
  727. //userFunction(sample)
  728. var userConfig = function(){
  729. var options = GM_option.get(); //load userConfig Data(hashArray)
  730.  
  731. //example
  732. var strTxt = "";
  733. var check1 = options['check1'];
  734. strTxt += 'check1:' + check1 + '\n';
  735.  
  736. var check2 = options['check2'];
  737. strTxt += 'check2:' + check2 + '\n';
  738.  
  739. var check3 = options['check3'];
  740. strTxt += 'check3:' + check3 + '\n';
  741.  
  742. var radio1 = options['radio1'];
  743. if(radio1 == 'true') strTxt += 'radio1:on\n';
  744. else strTxt += 'radio1:off\n';
  745.  
  746. var radio2 = options['radio2'];
  747. strTxt += 'radio2:' + radio2 + '\n';
  748.  
  749. var textTest1 = options['textTest1'];
  750. strTxt += 'textTest1:' + textTest1 + '\n';
  751.  
  752. var textarea = options['textarea'];
  753. textarea = textarea.split('\n');
  754. for(var i=0,j=textarea.length;i<j;i++){
  755. strTxt += 'textarea[' + i + ']:' + textarea[i] + '\n';
  756. }
  757.  
  758. var expand = function(text){
  759. var obj = eval(text);
  760. for(var i=0,j=obj.length;i<j;i++){
  761. var objTemp = obj[i];
  762. for(var x=0,y=objTemp.length;x<y;x++){
  763. strTxt += text + '[' + i + '][' + x + ']:' + objTemp[x] + '\n';
  764. }
  765. }
  766. };
  767.  
  768. var textTest3_multiple1 = options['textTest3_multiple1'];
  769. expand('textTest3_multiple1');
  770.  
  771.  
  772. var textTest3_3_multiple1 = options['textTest3_3_multiple1'];
  773. expand('textTest3_3_multiple1');
  774.  
  775. var textTest4_multiple2 = options['textTest4_multiple2'];
  776. expand('textTest4_multiple2');
  777.  
  778.  
  779. var textTest5_multiple3 = options['textTest5_multiple3'];
  780. expand('textTest5_multiple3');
  781.  
  782. var textTest5_5_multiple3 = options['textTest5_5_multiple3'];
  783. expand('textTest5_5_multiple3');
  784.  
  785. var select = options['select'];
  786. strTxt += 'select:' + select + '\n';
  787.  
  788. var select2 = options['select2'];
  789. strTxt += 'select2:' + select2 + '\n';
  790.  
  791. var select3 = JSON.parse(options['select3']);
  792. for(var key in select3){
  793. strTxt += 'select3:' + key + '\n';
  794. }
  795.  
  796. alert(strTxt);
  797.  
  798.  
  799. //make OpenButton(sample)
  800. var openButton = document.createElement('button');
  801. openButton.id = 'openButton';
  802. openButton.innerHTML = 'click here!(open GM_option)';
  803. openButton.style = 'position:fixed;top:0;left:0;right:0;bottom:0;margin:auto; height:100px;';
  804. document.body.appendChild(openButton);
  805. var openConfig = function(){
  806. GM_option.open(strHeader,strHTML);
  807. }
  808. openButton.addEventListener('click', openConfig,false);
  809.  
  810. window.addEventListener('beforeunload', function() {
  811. window.removeEventListener("beforeunload", arguments.callee,false);
  812. openButton.removeEventListener('click',openConfig,false);
  813. userConfig = null;
  814. },false);
  815. }
  816.  
  817. //optional messages
  818. var msgArray = {
  819. 'save':'save?(ok:reload)',
  820. 'reset':'discard changes?(load savedata)',
  821. 'clear':'delete your settings?(ok:reload)',
  822. 'delete':'delete this line?(Don\'t forget to save.)',
  823. };
  824. window.addEventListener('GM_option_loaded',userConfig,false); //userFunction
  825. GM_option.open(strHeader,strHTML,msgArray); //load
  826.  
  827. //script menu
  828. GM_registerMenuCommand('Open GM_option',function(){
  829. GM_option.open(strHeader,strHTML,msgArray);
  830. });
  831.  
  832.  
  833.  
  834. window.addEventListener('beforeunload', function() {
  835. window.removeEventListener("beforeunload", arguments.callee,false);
  836. window.removeEventListener('GM_option_loaded',userConfig,false);
  837. },false);
  838.  
  839.  
  840.  
  841. *********************************************************************************************************************/