1 // option.js 2 // (2007/02/02) 3 // オプションダイアログを動的に作成/管理する 4 // pref.jsと連携するようにできてるので勝手にマージ 5 6 /** 7 * @fileOverview オプション関係を扱います。 8 */ 9 10 /** 11 * globalStorage にアクセスします。デフォルトスキンの pref.js がベースになっています。 12 * @static 13 */ 14 var SkinPref = { 15 /** スキンの名称 16 * @type String 17 */ 18 _skinName: "smorgasbord", 19 /** スキンのバージョン 20 * @type String 21 */ 22 _skinVersion: "2007/09/25 afternoon (still unstable)", 23 /** URI 24 * @type String 25 */ 26 _skinURI: "http://smorgasbord.drwatson.nobody.jp/", 27 /** メールアドレス 28 * @type String 29 */ 30 _skinMail: "\u0064\u0072\u0077\u0061\u0074\u0073\u006f\u006e\u002e\u0065\u0078\u0065\u002b\u0073\u006d\u006f\u0072\u0067\u0061\u0073\u0062\u006f\u0072\u0064\u0040\u0067\u006d\u0061\u0069\u006c\u002e\u0063\u006f\u006d", 31 /** globalStorage 32 * @type StorageList 33 */ 34 _storage: (location.href.indexOf("http://localhost", 0) == -1) ? globalStorage["127.0.0.1"] : globalStorage["localhost.localdomain"], 35 /** スキン名とキーの名前を結合して、名前を解決します。 36 * @param {String} aPrefName キー 37 * @return {String} 結果 38 */ 39 _resolvePrefName: function(aPrefName){ 40 return this._skinName + "_" + aPrefName; 41 }, 42 /** globalStorage から文字列を取得します。 43 * @param {String} aPrefName キー 44 * @return {String} aDefaultValue デフォルト値 45 * @return {String} 値 46 */ 47 getStr: function(aPrefName, aDefaultValue){ 48 var item = this._storage.getItem(this._resolvePrefName(aPrefName)); 49 if(item == null) return aDefaultValue || ""; 50 return item.value; 51 }, 52 /** globalStorage に文字列を設定します。 53 * @param {String} aPrefName キー 54 * @return {String} aValue 値 55 * @return {String} 値 56 */ 57 setStr: function(aPrefName, aValue){ 58 var value = String(aValue); 59 if (value != this.getStr(aPrefName)) 60 this._storage.setItem(this._resolvePrefName(aPrefName), value); 61 return value; 62 }, 63 /** globalStorage から数値を取得します。 64 * @param {String} aPrefName キー 65 * @return {Number} aDefaultValue デフォルト値 66 * @return {Number} 値 67 */ 68 getInt: function(aPrefName, aDefaultValue){ 69 var item = this._storage.getItem(this._resolvePrefName(aPrefName)); 70 if(item == null) return aDefaultValue || 0; 71 return parseInt(item.value); 72 }, 73 /** globalStorage に数値を設定します。 74 * @param {String} aPrefName キー 75 * @return {Number} aValue 値 76 * @return {Number} 値 77 */ 78 setInt: function(aPrefName, aValue){ 79 var value = parseInt(aValue); 80 if (value != this.getInt(aPrefName)) 81 this._storage.setItem(this._resolvePrefName(aPrefName), value); 82 return value; 83 }, 84 /** globalStorage からブール値を取得します。 85 * @param {String} aPrefName キー 86 * @return {Boolean} aDefaultValue デフォルト値 87 * @return {Boolean} 値 88 */ 89 getBool: function(aPrefName, aDefaultValue){ 90 var item = this._storage.getItem(this._resolvePrefName(aPrefName)); 91 if(item == null) return aDefaultValue || false; 92 return (item.value == "true"); 93 }, 94 /** globalStorage からブール値を取得します。 95 * @param {String} aPrefName キー 96 * @return {Boolean} aValue 値 97 * @return {Boolean} 値 98 */ 99 setBool: function(aPrefName, aValue){ 100 var value = (aValue) ? "true" : "false"; 101 if (value != String(this.getBool(aPrefName))) 102 this._storage.setItem(this._resolvePrefName(aPrefName), value); 103 return value; 104 }, 105 /** globalStorage からキーを削除します。 106 * @param {String} aPrefName キー 107 */ 108 remove: function(aPrefName){ 109 this._storage.removeItem(this._resolvePrefName(aPrefName)); 110 } 111 112 }; 113 114 /** 115 * [オプション] ダイアログを管理します。 116 * @static 117 */ 118 var dialogOptions = { 119 /** ダイアログの親要素 120 * @type element 121 */ 122 content: document.createElement("div"), 123 /** [OK] ボタンが押されたときの処理をします。*/ 124 onOK: function(){ 125 var items = document.getElementsByTagName("label"); 126 for (var i = 0; i < items.length; i++) { 127 if (items[i].className == "dialogOptionsLabel") { 128 if (items[i].firstChild.tagName == "INPUT") { 129 switch (items[i].firstChild.getAttribute("type")) { 130 case "checkbox": 131 SkinPref.setBool(items[i].firstChild.id, items[i].firstChild.checked); 132 break; 133 case "radio": 134 SkinPref.setBool(items[i].firstChild.id, items[i].firstChild.checked); 135 } 136 } else if (items[i].lastChild.tagName == "INPUT") { 137 if (items[i].lastChild.getAttribute("type") == "text") { 138 SkinPref.setStr(items[i].lastChild.id, items[i].lastChild.value); 139 } 140 } else if (items[i].lastChild.tagName == "SELECT") { 141 SkinPref.setInt(items[i].lastChild.id, items[i].lastChild.selectedIndex); 142 } 143 } 144 } 145 this.hide(); 146 }, 147 /** [キャンセル] ボタンが押されたときの処理をします。*/ 148 onCancel: function(){ 149 this.hide(); 150 }, 151 /** リサイズされたときの処理をします。*/ 152 onResize: function(){ 153 dialogOptions.content.style.left = (document.body.offsetWidth - dialogOptions.content.offsetWidth) / 2 154 dialogOptions.content.style.top = (window.innerHeight - dialogOptions.content.offsetHeight) / 2 155 var bg = document.getElementById("dialogOptionsBackground"); 156 if (bg) { 157 bg.style.width = document.body.offsetWidth; 158 bg.style.height = window.innerHeight; 159 } 160 }, 161 /** ダイアログを表示します。*/ 162 show: function(){ 163 var bg = document.createElement("div"); 164 bg.id = "dialogOptionsBackground"; 165 bg.style.width = document.body.offsetWidth; 166 bg.style.height = window.innerHeight; 167 document.body.appendChild(bg); 168 169 this.content.style.position = "fixed"; 170 this.content.style.width = 512; 171 this.content.style.visibility = "hidden" 172 this.content.style.display = "block"; 173 this.selectPage(this.content.childNodes[1].id.replace("Page_", "")); 174 this.content.style.left = (document.body.offsetWidth - this.content.offsetWidth) / 2 175 this.content.style.top = (window.innerHeight - this.content.offsetHeight) / 2 176 this.content.style.visibility = "visible"; 177 window.addEventListener("resize", dialogOptions.onResize, false); 178 }, 179 /** ダイアログを非表示にします。*/ 180 hide: function(){ 181 this.content.style.display = "none"; 182 var bg = document.getElementById("dialogOptionsBackground"); 183 if (bg) document.body.removeChild(bg); 184 window.removeEventListener("resize", dialogOptions.onResize, false); 185 }, 186 /** ダイアログのページを切り替えます。 187 * @param {String} id ページの ID 188 */ 189 selectPage: function(id){ 190 var divHeader = document.getElementById("dialogOptionsHeader"); 191 for (var i = 0; i < divHeader.childNodes.length - 1; i++) { 192 var icon = divHeader.childNodes[i]; 193 if (icon.id == "Icon_" + id) { 194 icon.className = "icon" + " " + "selected"; 195 } else { 196 icon.className = "icon"; 197 } 198 } 199 for (var i = 1; i < this.content.childNodes.length - 1; i++) { 200 var page = this.content.childNodes[i]; 201 if (page.id == "Page_" + id) { 202 page.style.display = "block"; 203 } else { 204 page.style.display = "none"; 205 } 206 } 207 if ((this.content.offsetTop + this.content.offsetHeight) > window.innerHeight) this.onResize(); 208 }, 209 /** ページを追加します。 210 * @param {String} id ID 211 * @param {String} caption キャプション 212 * @param {String} icon アイコンの URI 213 */ 214 addPage: function(id, caption, icon){ 215 if (!this.content.id) this.content.id = "dialogOptions"; 216 if (!document.getElementById("dialogOptions")) document.body.appendChild(this.content); 217 var divHeader = document.getElementById("dialogOptionsHeader"); 218 if (!divHeader) { 219 divHeader = document.createElement("div"); 220 divHeader.id = "dialogOptionsHeader"; 221 divHeader.className = "header"; 222 var divHeaderEnd = document.createElement("div"); 223 divHeaderEnd.id = "dialogOptionsHeaderEnd"; 224 divHeaderEnd.className = "null"; 225 divHeader.appendChild(divHeaderEnd); 226 this.content.appendChild(divHeader); 227 228 var p = document.createElement("p"); 229 var ok = document.createElement("input"); 230 ok.setAttribute("type", "submit"); 231 ok.setAttribute("value", "OK"); 232 ok.setAttribute("onclick", "dialogOptions.onOK()"); 233 var cancel = document.createElement("input"); 234 cancel.setAttribute("type", "button"); 235 cancel.setAttribute("value", "キャンセル"); 236 cancel.setAttribute("onclick", "dialogOptions.onCancel()"); 237 p.appendChild(ok); 238 p.appendChild(cancel); 239 this.content.appendChild(p); 240 } 241 242 var divIcon = document.createElement("div"); 243 divIcon.id = "Icon_" + id; 244 divIcon.className = "icon"; 245 divIcon.textContent = caption; 246 divIcon.style.backgroundImage = "url(" + icon + ")"; 247 divIcon.setAttribute("onclick", "dialogOptions.selectPage('" + id + "')"); 248 divHeader.insertBefore(divIcon, document.getElementById("dialogOptionsHeaderEnd")); 249 250 var divPage = document.createElement("div"); 251 divPage.id = "Page_" + id; 252 divPage.style.display = "none"; 253 this.content.insertBefore(divPage, this.content.lastChild); 254 }, 255 /** フレームを追加します。 256 * @param {String} page 追加するページの ID 257 * @param {String} id ID 258 * @param {String} caption キャプション 259 */ 260 addFrame: function(page, id, caption){ 261 var fieldset = document.createElement("fieldset"); 262 fieldset.id = "Frame_" + page + "_" + id; 263 var legend = document.createElement("legend"); 264 legend.textContent = caption; 265 fieldset.appendChild(legend); 266 fieldset.appendChild(document.createElement("ul")); 267 var divPage = document.getElementById("Page_" + page); 268 if (divPage) divPage.appendChild(fieldset); 269 }, 270 /** ラベルを追加します。 271 * @param {String} page 追加するページの ID 272 * @param {String} frame フレームの ID 273 * @param {String} id ID 274 * @param {String} caption キャプション 275 * @param {String} [level] インデントする階層 276 */ 277 addLabel: function(page, frame, id, caption, level){ 278 var parentObject = document.getElementById("Frame_" + page + "_" + frame).lastChild; 279 if (level > 0) { 280 for (var i = 1; i <= level; i++) { 281 parentObject.appendChild(document.createElement("ul")); 282 parentObject = parentObject.lastChild; 283 } 284 } 285 var li = document.createElement("li"); 286 var label = document.createElement("label"); 287 label.className = "dialogOptionsLabel"; 288 var span = document.createElement("span"); 289 span.textContent = caption; 290 label.appendChild(span); 291 li.appendChild(label); 292 parentObject.appendChild(li); 293 }, 294 /** リンクを追加します。 295 * @param {String} page 追加するページの ID 296 * @param {String} frame フレームの ID 297 * @param {String} id ID 298 * @param {String} caption キャプション 299 * @param {String} uri URI 300 * @param {Number} [level] インデントする階層 301 */ 302 addLink: function(page, frame, id, caption, uri, level){ 303 var parentObject = document.getElementById("Frame_" + page + "_" + frame).lastChild; 304 if (level > 0) { 305 for (var i = 1; i <= level; i++) { 306 parentObject.appendChild(document.createElement("ul")); 307 parentObject = parentObject.lastChild; 308 } 309 } 310 var li = document.createElement("li"); 311 var label = document.createElement("label"); 312 label.className = "dialogOptionsLabel"; 313 var a = document.createElement("a"); 314 a.setAttribute("href", uri); 315 a.setAttribute("target", "_blank"); 316 a.textContent = caption; 317 label.appendChild(a); 318 li.appendChild(label); 319 parentObject.appendChild(li); 320 }, 321 /** チェックボックスを追加します。 322 * @param {String} page 追加するページの ID 323 * @param {String} frame フレームの ID 324 * @param {String} id ID 325 * @param {String} caption キャプション 326 * @param {Boolean} defaultValue デフォルト値 327 * @param {Number} [level] インデントする階層 328 */ 329 addCheckBox: function(page, frame, id, caption, defaultValue, level){ 330 var parentObject = document.getElementById("Frame_" + page + "_" + frame).lastChild; 331 if (level > 0) { 332 for (var i = 1; i <= level; i++) { 333 parentObject.appendChild(document.createElement("ul")); 334 parentObject = parentObject.lastChild; 335 } 336 } 337 var li = document.createElement("li"); 338 var label = document.createElement("label"); 339 label.className = "dialogOptionsLabel"; 340 var input = document.createElement("input"); 341 input.setAttribute("type", "checkbox"); 342 input.id = id; 343 input.checked = SkinPref.getBool(id, defaultValue); 344 label.appendChild(input); 345 var span = document.createElement("span"); 346 span.textContent = caption; 347 label.appendChild(span); 348 li.appendChild(label); 349 parentObject.appendChild(li); 350 }, 351 /** ラジオボタンを追加します。 352 * @param {String} page 追加するページの ID 353 * @param {String} frame フレームの ID 354 * @param {String} id ID 355 * @param {String} caption キャプション 356 * @param {Boolean} defaultValue デフォルト値 357 * @param {Number} [level] インデントする階層 358 */ 359 addRadio: function(page, frame, id, caption, defaultValue, level){ 360 var parentObject = document.getElementById("Frame_" + page + "_" + frame).lastChild; 361 if (level > 0) { 362 for (var i = 1; i <= level; i++) { 363 parentObject.appendChild(document.createElement("ul")); 364 parentObject = parentObject.lastChild; 365 } 366 } 367 var li = document.createElement("li"); 368 var label = document.createElement("label"); 369 label.className = "dialogOptionsLabel"; 370 var input = document.createElement("input"); 371 input.setAttribute("type", "radio"); 372 input.setAttribute("name", frame); 373 input.id = id; 374 input.checked = SkinPref.getBool(id, defaultValue); 375 label.appendChild(input); 376 var span = document.createElement("span"); 377 span.textContent = caption; 378 label.appendChild(span); 379 li.appendChild(label); 380 parentObject.appendChild(li); 381 }, 382 /** エディットボックスを追加します。 383 * @param {String} page 追加するページの ID 384 * @param {String} frame フレームの ID 385 * @param {String} id ID 386 * @param {String} caption キャプション 387 * @param {String} defaultValue デフォルト値 388 * @param {Number} [size] サイズ 389 * @param {Number} [level] インデントする階層 390 */ 391 addEditBox: function(page, frame, id, caption, defaultValue, size, level){ 392 var parentObject = document.getElementById("Frame_" + page + "_" + frame).lastChild; 393 if (level > 0) { 394 for (var i = 1; i <= level; i++) { 395 parentObject.appendChild(document.createElement("ul")); 396 parentObject = parentObject.lastChild; 397 } 398 } 399 var li = document.createElement("li"); 400 var label = document.createElement("label"); 401 label.className = "dialogOptionsLabel"; 402 var span = document.createElement("span"); 403 span.textContent = caption; 404 label.appendChild(span); 405 var input = document.createElement("input"); 406 input.setAttribute("type", "text"); 407 input.value = SkinPref.getStr(id, defaultValue); 408 if (size) { 409 input.style.width = size + "em"; 410 } 411 input.id = id; 412 413 label.appendChild(input); 414 li.appendChild(label); 415 parentObject.appendChild(li); 416 }, 417 /** 数値のみを入力できるエディットボックスを追加します。 418 * @param {String} page 追加するページの ID 419 * @param {String} frame フレームの ID 420 * @param {String} id ID 421 * @param {String} caption キャプション 422 * @param {Number} defaultValue デフォルト値 423 * @param {Number} [size] サイズ 424 * @param {Number} [level] インデントする階層 425 */ 426 addNumberBox: function(page, frame, id, caption, defaultValue, size, level){ 427 var parentObject = document.getElementById("Frame_" + page + "_" + frame).lastChild; 428 if (level > 0) { 429 for (var i = 1; i <= level; i++) { 430 parentObject.appendChild(document.createElement("ul")); 431 parentObject = parentObject.lastChild; 432 } 433 } 434 var li = document.createElement("li"); 435 var label = document.createElement("label"); 436 label.className = "dialogOptionsLabel"; 437 var span = document.createElement("span"); 438 span.textContent = caption; 439 label.appendChild(span); 440 var input = document.createElement("input"); 441 input.setAttribute("type", "text"); 442 input.style.textAlign = "right"; 443 if (size) { 444 input.style.width = size + "em"; 445 } 446 input.id = id; 447 input.value = SkinPref.getStr(id, defaultValue); 448 input.setAttribute("onkeydown", "var i = event.keyCode; if ((i >= 96 && i <= 105) || (i >= 48 && i <= 57) || (i == 190) | (i == 8) || (i == 35) || (i == 36) ||(i == 37) || (i == 39) || (i == 46)) { return true; } return false;"); 449 input.setAttribute("onkeyup", "if (event.target.value.match(/[^0-9\.]+/)) event.target.value='';"); 450 input.setAttribute("onfocus", "if (event.target.value.match(/[^0-9\.]+/)) event.target.value='';"); 451 input.setAttribute("onblur", "if (event.target.value.match(/[^0-9\.]+/)) event.target.value='';"); 452 label.appendChild(input); 453 li.appendChild(label); 454 parentObject.appendChild(li); 455 }, 456 /** コンボボックスを追加します。 457 * @param {String} page 追加するページの ID 458 * @param {String} frame フレームの ID 459 * @param {String} id ID 460 * @param {String} caption キャプション 461 * @param {Array} value 項目 462 * @param {Number} defaultValue デフォルト値 463 * @param {Number} [size] サイズ 464 * @param {Number} [level] インデントする階層 465 */ 466 addComboBox: function(page, frame, id, caption, value, defaultValue, level){ 467 var parentObject = document.getElementById("Frame_" + page + "_" + frame).lastChild; 468 if (level > 0) { 469 for (var i = 1; i <= level; i++) { 470 parentObject.appendChild(document.createElement("ul")); 471 parentObject = parentObject.lastChild; 472 } 473 } 474 var li = document.createElement("li"); 475 var label = document.createElement("label"); 476 label.className = "dialogOptionsLabel"; 477 var span = document.createElement("span"); 478 span.textContent = caption; 479 label.appendChild(span); 480 var select = document.createElement("select"); 481 select.id = id; 482 for (var i = 0; i < value.length; i++) { 483 var option = document.createElement("option"); 484 option.textContent = value[i]; 485 option.setAttribute("value", value[i]); 486 select.appendChild(option); 487 } 488 select.selectedIndex = SkinPref.getInt(id, defaultValue); 489 label.appendChild(select); 490 li.appendChild(label); 491 parentObject.appendChild(li); 492 } 493 }; 494 495 /** [オプション] ダイアログを初期化します。*/ 496 function initOptionDialog(){ 497 dialogOptions.addPage ("General", "一般", SKIN_PATH + "img/general.png"); 498 dialogOptions.addFrame ("General", "Popup", "ポップアップ"); 499 //dialogOptions.addLabel ("General", "Popup", "labelPopup", "次のポップアップを有効にする:"); 500 dialogOptions.addCheckBox ("General", "Popup", "enableResPopup", "アンカー", true); 501 dialogOptions.addCheckBox ("General", "Popup", "enableIDPopup", "ID", true); 502 dialogOptions.addCheckBox ("General", "Popup", "enableIDPopupOnClick", "クリックしてポップアップ", false, 1); 503 dialogOptions.addCheckBox ("General", "Popup", "enableIDPopupAll", "すべてのレスを一度に表示する", false, 1); 504 dialogOptions.addCheckBox ("General", "Popup", "enableImagePopup", "画像", true); 505 dialogOptions.addComboBox ("General", "Popup", "valuePixelationMethod", "フィルタ: ", ["モザイク", "ガウスぼかし(Fx3)"], 0, 1); 506 dialogOptions.addComboBox ("General", "Popup", "valuePixelationSize", "レベル: ", ["強", "中", "弱"], 1, 1); 507 dialogOptions.addCheckBox ("General", "Popup", "enableDefaultPixelation", "デフォルトでぼかす", false, 1); 508 dialogOptions.addCheckBox ("General", "Popup", "enablePrecisePixelation", "正確にモザイク化する(遅い)", false, 1); 509 dialogOptions.addCheckBox ("General", "Popup", "enableUrlPopup", "リンク先サムネイル", true); 510 dialogOptions.addComboBox ("General", "Popup", "valueUrlPopupSize", "サイズ: ", ["大", "小"], 0, 1); 511 dialogOptions.addCheckBox ("General", "Popup", "enableVideoPopup", "動画", true); 512 dialogOptions.addCheckBox ("General", "Popup", "videoPopupAutoStart", "自動再生", true, 1); 513 dialogOptions.addCheckBox ("General", "Popup", "enableTrackBackPopup", "逆参照", true); 514 dialogOptions.addCheckBox ("General", "Popup", "enableTrackBackPopupAll", "すべてのレスを一度に表示する", false, 1); 515 516 dialogOptions.addPage ("Special", "詳細", SKIN_PATH + "img/special.png"); 517 dialogOptions.addFrame ("Special", "Link", "リンク"); 518 dialogOptions.addCheckBox ("Special", "Link", "enableNewWindow", "リンクを新しいウィンドウで開く", true); 519 dialogOptions.addCheckBox ("Special", "Link", "enableNoReferer", "リファラを送信しない", true); 520 521 dialogOptions.addFrame ("Special", "Visualisation", "視覚効果"); 522 dialogOptions.addCheckBox ("Special", "Visualisation", "enableContract", "スレッドタイトルを表示幅に合わせて省略表示する", true); 523 dialogOptions.addCheckBox ("Special", "Visualisation", "enablePopupFade", "ポップアップのフェードアウトを有効にする", true); 524 dialogOptions.addComboBox ("Special", "Visualisation", "valuePopupFadeStep", "フェードのステップ: ", new Array(0.1,0.2,0.25,0.33,0.5), 1, 1); 525 dialogOptions.addCheckBox ("Special", "Visualisation", "enableFindHighlight", "検索/抽出時に強調表示を行う", false); 526 527 dialogOptions.addFrame ("Special", "Browse", "ブラウズ"); 528 dialogOptions.addNumberBox("Special", "Browse", "valueHistoryItemCounts", "保存する履歴の件数: ", 32, 3); 529 dialogOptions.addCheckBox ("Special", "Browse", "enableHookReload", "F5 キーをフックして動的に更新を行う", true); 530 dialogOptions.addCheckBox ("Special", "Browse", "enableSmoothScroll", "スムーズスクロールを有効にする", true); 531 dialogOptions.addComboBox ("Special", "Browse", "valueSmoothScrollFrames", "フレーム数: ", new Array("最小","中","最大"), 1, 1); 532 533 dialogOptions.addFrame ("Special", "AutoPilot", "オートパイロット"); 534 dialogOptions.addCheckBox ("Special", "AutoPilot", "enableAutoReloadOnLiveThread", "実況板では自動更新をデフォルトにする", false); 535 dialogOptions.addCheckBox ("Special", "AutoPilot", "enableAutoReloadWhenInactive", "非アクティヴ時でも自動更新を強制する", false); 536 dialogOptions.addComboBox ("Special", "AutoPilot", "valueAutoReloadInterval", "自動更新の間隔: ", new Array("15 秒","30 秒","60 秒"), 1); 537 538 dialogOptions.addPage ("About", "スキン情報", "chrome://bbs2chreader/content/icon.png"); 539 dialogOptions.addFrame ("About", "Info", "このスキンについて"); 540 if (SkinPref._skinName) 541 dialogOptions.addLabel("About", "Info", "labelSkinName", SkinPref._skinName); 542 if (SkinPref._skinVersion) 543 dialogOptions.addLabel("About", "Info", "labelSkinVersion", "バージョン: " + SkinPref._skinVersion); 544 if (SkinPref._skinURI) { 545 // dialogOptions.addLabel("About", "Info", "labelSkinBlank", " "); 546 dialogOptions.addLink ("About", "Info", "labelSkinURI", SkinPref._skinURI, SkinPref._skinURI); 547 } 548 if (SkinPref._skinMail) 549 dialogOptions.addLink ("About", "Info", "labelSkinMail", SkinPref._skinMail, "mailto:" + SkinPref._skinMail); 550 551 dialogOptions.addFrame ("About", "Keymap", "キーボードショートカット"); 552 dialogOptions.addLabel ("About", "Keymap", "", "F5: 最新の情報に更新"); 553 dialogOptions.addLabel ("About", "Keymap", "", "←: 前のレスへ移動"); 554 dialogOptions.addLabel ("About", "Keymap", "", "→: 次のレスへ移動"); 555 dialogOptions.addLabel ("About", "Keymap", "", "Ctrl + Enter: 書き込む"); 556 dialogOptions.addLabel ("About", "Keymap", "", "Ctrl + Space: すべて表示"); 557 dialogOptions.addLabel ("About", "Keymap", "", "Ctrl + Alt + F: 検索/抽出"); 558 dialogOptions.addLabel ("About", "Keymap", "", "数字キー: 入力されたレス番号へスクロール"); 559 } 560 window.addEventListener("load", initOptionDialog, false); 561