mirror of
https://github.com/elkowar/dots-of-war.git
synced 2024-12-25 21:52:23 +00:00
846 lines
32 KiB
JavaScript
846 lines
32 KiB
JavaScript
|
/* :::::::: Sub-Script/Overlay Loader v3.0.60mod no bind version ::::::::::::::: */
|
||
|
|
||
|
// automatically includes all files ending in .uc.xul and .uc.js from the profile's chrome folder
|
||
|
|
||
|
// New Features:
|
||
|
// supports Greasemonkey-style metadata for userChrome scripts and overlays
|
||
|
// supports a "main" shortcut for the main browser window in include/exclude lines
|
||
|
// supports regexes in the include/exclude lines
|
||
|
// scripts without metadata will run only on the main browser window, for backwards compatibility
|
||
|
//
|
||
|
// 1.Including function of UCJS_loader.
|
||
|
// 2.Compatible with Fx2 and Fx3.0b5pre
|
||
|
// 3.Cached script data (path, leafname, regex)
|
||
|
// 4.Support window.userChrome_js.loadOverlay(overlay [,observer]) //
|
||
|
// Modified by Alice0775
|
||
|
//
|
||
|
// Date 2019/12/11 01:30 fix 72 revert the code for sidebar, use "load" in config.js(2019/12/11 01:30),
|
||
|
// Date 2019/08/11 21:30 fix 70.0a1 Bug 1551344 - Remove XULDocument code
|
||
|
// Date 2019/05/21 08:30 fix 69.0a1 Bug 1534407 - Enable browser.xhtml by default, Bug 1551320 - Replace all CreateElement calls in XUL documents with CreateXULElement
|
||
|
// Date 2018/08/10 01:30 fix 63.0a1
|
||
|
// Date 2018/08/02 19:30 for userChrome.xml
|
||
|
// Date 2018/05/30 18:00 ALWAYSEXECUTE .uc.js
|
||
|
// Date 2018/05/06 22:00 fix wrong commit
|
||
|
// Date 2018/05/06 22:00 remove workaround for editBookmarkPanel
|
||
|
// Date 2018/03/21 08:00 revert USE_0_63_FOLDER
|
||
|
// Date 2018/03/20 21:00 editBookmarkPanel etc Bug 1444228 - Remove editBookmarkOverlay.xul
|
||
|
// Date 2015/06/28 13:00 about:preferences#privacy etc
|
||
|
// Date 2014/12/28 19:00 workaround loading xul on second browser
|
||
|
// Date 2014/12/13 21:00 remove a debug log
|
||
|
// Date 2014/12/13 21:00 allow to load scripts into about: in dialog
|
||
|
// Date 2014/12/13 21:00 require userchrome.js-0.8.014121301-Fx31.xpi
|
||
|
// Date 2014/06/07 21:00 skip about:blank
|
||
|
// Date 2014/06/07 19:00 turn off experiment by default
|
||
|
// Date 2014/06/04 12:00 fixed possibility of shutdown crash Bug 1016875
|
||
|
// Date 2014/05/19 00:00 delay 0, experiment
|
||
|
// Date 2013/10/06 00:00 allow to load scripts into about:xxx
|
||
|
// Date 2013/09/13 00:00 Bug 856437 Remove Components.lookupMethod, remove REPLACEDOCUMENTOVERLAY
|
||
|
// Date 2012/04/19 23:00 starUIをbindを使うように
|
||
|
// Date 2012/04/19 21:00 starUI元に戻した
|
||
|
// Date 2012/02/04 00:00 due to bug 726444 Implement the Downloads Panel.
|
||
|
// Date 2012/02/04 00:00 due to bug 726440
|
||
|
// Date 2011/11/19 15:30 REPLACECACHE 追加 Bug 648125
|
||
|
// Date 2011/09/30 13:40 fix bug 640158
|
||
|
// Date 2011/09/30 13:00 fix bug 640158
|
||
|
// Date 2011/04/07 00:00 hackVersion
|
||
|
// Date 2010/10/10 00:00 Bug 377498 mozIJSSubscriptLoader::loadSubScript charset 入ったけどメタデータ // @charset UTF-8 としとけばUTF-8で読み込む
|
||
|
// Date 2010/03/31 00:00 XULDocumentのみに適用
|
||
|
// Date 2010/03/11 17:30 debugbuildで動かない場合がある件に対応。
|
||
|
// Date 2010/02/28 13:00 ↓が直っているので元に戻した。
|
||
|
// Date 2009/08/06 00:00 tree_style_tab-0.8.2009073102があるとxulのdocument.overlayが出来なくなる件に対応
|
||
|
// Date 2009/05/23 00:00 userChrome.js0.8.1実験中 v3.0.25mod
|
||
|
// Date 2009/04/13 00:00 overlayのobserveの処理変更 v3.0.24mod
|
||
|
// Date 2009/03/10 00:00 例外トラップ
|
||
|
// Date 2009/02/15 15:00 chromehiddenなwindow(popup等)の場合にロードするかどうかを指定できるようにした。
|
||
|
// Date 2008/12/29 06:00 面倒だからdocument.overlayを置き換えるようにした。
|
||
|
// Date 2008/12/27 18:00 Webpanelにchromeを読み込んだときのエラーが出るのを修正(thanks 音吉)
|
||
|
// Date 2008/09/16 00 00 面倒だからFirefox3 の場合はeditBookmarkOverlay.xulは先読みするように修正
|
||
|
// Date 2008/08/28 00 00 なぜか0.8.0+を使っている人がいたので, それに対応
|
||
|
// Date 2008/08/26 23:50 08/26 18:00 以降 Fx2で動かなくなったようなので, 直した
|
||
|
// Date 2008/08/26 22:00 v3.0.11modで動かないなら,これ以降のものも動かないよ。たぶん
|
||
|
// Date 2008/08/26 18:00 Fx3のStarUIをなんとかして欲しいな。
|
||
|
// Date 2008/08/18 04:00 AUTOREMOVEBOM = trueなら文字コード自動判定するようにした。
|
||
|
// Date 2008/08/16 15:00 BOMを自動的に取り除くかどうか指定できるようにした
|
||
|
// Date 2008/07/29 23:00 なんかバグあったかも
|
||
|
// Date 2008/07/25 00:00 USE_0_63_FOLDERおよびFORCESORTSCRIPTがtrueの場合は, フォルダも名順でソートするようにした
|
||
|
// Date 2008/07/14 01:00 typo, regression
|
||
|
// Date 2008/07/14 00:00 typo, regression
|
||
|
// Date 2008/07/13 22:00 サイドバーweb-panelsにchromeウインドウを読み込んだ場合に対応
|
||
|
// Date 2008/03/23 12:00 80氏のフォルダ規則に対応, 0.8modバージョンにも対応
|
||
|
//
|
||
|
|
||
|
;(function () {
|
||
|
"use strict"
|
||
|
// -- config --
|
||
|
const EXCLUDE_CHROMEHIDDEN = false //chromehiddenなwindow(popup等)ではロード: しないtrue, する[false]
|
||
|
const USE_0_63_FOLDER = true //0.63のフォルダ規則を使う[true], 使わないfalse
|
||
|
const FORCESORTSCRIPT = false //強制的にスクリプトをファイル名順でソートするtrue, しない[false]
|
||
|
const AUTOREMOVEBOM = false //BOMを自動的に, 取り除く:true, 取り除かない[false](元ファイルは.BOMとして残る)
|
||
|
const REPLACECACHE = true //スクリプトの更新日付によりキャッシュを更新する: true , しない:[false]
|
||
|
//=====================USE_0_63_FOLDER = falseの時===================
|
||
|
var UCJS = new Array("UCJSFiles", "userContent", "userMenu") //UCJS Loader 仕様を適用 (NoScriptでfile:///を許可しておく)
|
||
|
var arrSubdir = new Array(
|
||
|
"",
|
||
|
"xul",
|
||
|
"TabMixPlus",
|
||
|
"withTabMixPlus",
|
||
|
"SubScript",
|
||
|
"UCJSFiles",
|
||
|
"userCrome.js.0.8",
|
||
|
"userContent",
|
||
|
"userMenu"
|
||
|
) //スクリプトはこの順番で実行される
|
||
|
//===================================================================
|
||
|
const ALWAYSEXECUTE = ["rebuild_userChrome.uc.xul", "rebuild_userChrome.uc.js"] //常に実行するスクリプト
|
||
|
var INFO = true
|
||
|
var BROWSERCHROME = "chrome://browser/content/browser.xhtml" //Firfox
|
||
|
//"chrome://browser/content/browser.xul"; //Firfox
|
||
|
//var BROWSERCHROME = "chrome://navigator/content/navigator.xul"; //SeaMonkey:
|
||
|
// -- config --
|
||
|
/* USE_0_63_FOLDER true の時
|
||
|
* chrome直下およびchrome/xxx.uc 内の *.uc.js および *.uc.xul
|
||
|
* chrome/xxx.xul 内の *.uc.js , *.uc.xul および *.xul
|
||
|
* chrome/xxx.ucjs 内の *.uc.js は 特別に UCJS Loader 仕様を適用(NoScriptでfile:///を許可しておく)
|
||
|
*/
|
||
|
|
||
|
/* USE_0.63_FOLDER false の時
|
||
|
*[ フォルダは便宜上複数のフォルダに分けているだけで任意。 下のarrSubdirで指定する ]
|
||
|
*[ UCJS Loaderを適用するフォルダをUCJSで指定する ]
|
||
|
プロファイル-+-chrome-+-userChrome.js(このファイル)
|
||
|
+-*.uc.jsまたは*.uc.xul群
|
||
|
|
|
||
|
+-SubScript--------+-*.uc.jsまたは*.uc.xul群
|
||
|
|
|
||
|
+-UCJSFiles--------+-*.uc.jsまたは*.uc.xul群
|
||
|
| (UCJS_loaderでしか動かないもの JavaScript Version 1.7/日本語)
|
||
|
|
|
||
|
+-xul--------------+-*.xul, *.uc.xulおよび付随File
|
||
|
|
|
||
|
+-userCrome.js.0.8-+-*.uc.jsまたは*.uc.xul群 (綴りが変なのはなぜかって? )
|
||
|
*/
|
||
|
|
||
|
//chrome/aboutでないならスキップ
|
||
|
if (!/^(chrome:|about:)/i.test(location.href)) return
|
||
|
if (/^(about:(blank|newtab|home))/i.test(location.href)) return
|
||
|
//コモンダイアログに対するオーバーレイが今のところ無いので時間短縮のためスキップすることにした
|
||
|
if (location.href == "chrome://global/content/commonDialog.xul") return
|
||
|
if (location.href == "chrome://global/content/alerts/alert.xul") return
|
||
|
if (/\.html?$/i.test(location.href)) return
|
||
|
window.userChrome_js = {
|
||
|
USE_0_63_FOLDER: USE_0_63_FOLDER,
|
||
|
UCJS: UCJS,
|
||
|
arrSubdir: arrSubdir,
|
||
|
FORCESORTSCRIPT: FORCESORTSCRIPT,
|
||
|
ALWAYSEXECUTE: ALWAYSEXECUTE,
|
||
|
AUTOREMOVEBOM: AUTOREMOVEBOM,
|
||
|
INFO: INFO,
|
||
|
BROWSERCHROME: BROWSERCHROME,
|
||
|
EXCLUDE_CHROMEHIDDEN: EXCLUDE_CHROMEHIDDEN,
|
||
|
REPLACECACHE: REPLACECACHE,
|
||
|
|
||
|
get hackVersion() {
|
||
|
delete this.hackVersion
|
||
|
return (this.hackVersion = "0.8")
|
||
|
//拡張のバージョン違いを吸収
|
||
|
this.baseUrl = /^(chrome:\/\/\S+\/content\/)\S+/i.test(Error().fileName).$1
|
||
|
if (!/^(chrome:\/\/\S+\/content\/)\S+/i.test(Error().fileName)) {
|
||
|
} else if (
|
||
|
Error().fileName.indexOf("chrome://uc_js/content/uc_js.xul") > -1 ||
|
||
|
"chrome://userchrome_js_cache/content/userChrome.js" == Error().fileName
|
||
|
) {
|
||
|
//0.8.0+ or 0.7
|
||
|
return (this.hackVersion = "0.8+")
|
||
|
} else if (Error().fileName.indexOf("chrome://browser/content/browser.xul -> ") == 0) {
|
||
|
return (this.hackVersion = "0.8.1")
|
||
|
} else {
|
||
|
return (this.hackVersion = "0.8mod")
|
||
|
}
|
||
|
},
|
||
|
|
||
|
//スクリプトデータを作成
|
||
|
getScripts: function () {
|
||
|
const Cc = Components.classes
|
||
|
const Ci = Components.interfaces
|
||
|
const ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService)
|
||
|
const fph = ios.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler)
|
||
|
const ds = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties)
|
||
|
var Start = new Date().getTime()
|
||
|
//getdir
|
||
|
if (this.USE_0_63_FOLDER) {
|
||
|
var o = [""]
|
||
|
this.UCJS = []
|
||
|
this.arrSubdir = []
|
||
|
var workDir = ds.get("UChrm", Ci.nsIFile)
|
||
|
var dir = workDir.directoryEntries
|
||
|
while (dir.hasMoreElements()) {
|
||
|
var file = dir.getNext().QueryInterface(Ci.nsIFile)
|
||
|
if (!file.isDirectory()) continue
|
||
|
var dirName = file.leafName
|
||
|
if (/(uc|xul|ucjs)$/i.test(dirName)) {
|
||
|
o.push(dirName)
|
||
|
if (/ucjs$/i.test(dirName)) {
|
||
|
this.UCJS.push(dirName)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (this.FORCESORTSCRIPT) {
|
||
|
o.sort(cmp_name)
|
||
|
}
|
||
|
;[].push.apply(this.arrSubdir, o)
|
||
|
}
|
||
|
|
||
|
var that = this
|
||
|
var mediator = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(
|
||
|
Components.interfaces.nsIWindowMediator
|
||
|
)
|
||
|
if (mediator.getMostRecentWindow("navigator:browser")) var mainWindowURL = that.BROWSERCHROME
|
||
|
else if (mediator.getMostRecentWindow("mail:3pane"))
|
||
|
var mainWindowURL = "chrome://messenger/content/messenger.xul"
|
||
|
|
||
|
this.dirDisable = restoreState(getPref("userChrome.disable.directory", "str", "").split(","))
|
||
|
this.scriptDisable = restoreState(getPref("userChrome.disable.script", "str", "").split(","))
|
||
|
this.scripts = []
|
||
|
this.overlays = []
|
||
|
|
||
|
var findNextRe = /^\/\/ @(include|exclude)[ \t]+(\S+)/gm
|
||
|
this.directory = { name: [], UCJS: [], enable: [] }
|
||
|
for (var i = 0, len = this.arrSubdir.length; i < len; i++) {
|
||
|
var s = [],
|
||
|
o = []
|
||
|
try {
|
||
|
var dir = this.arrSubdir[i] == "" ? "root" : this.arrSubdir[i]
|
||
|
this.directory.name.push(dir)
|
||
|
this.directory.UCJS.push(checkUCJS(dir))
|
||
|
|
||
|
var workDir = ds.get("UChrm", Ci.nsIFile)
|
||
|
workDir.append(this.arrSubdir[i])
|
||
|
var files = workDir.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator)
|
||
|
var istream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
|
||
|
Ci.nsIFileInputStream
|
||
|
)
|
||
|
while (files.hasMoreElements()) {
|
||
|
var file = files.getNext().QueryInterface(Ci.nsIFile)
|
||
|
if (
|
||
|
/\.uc\.js$|\.uc\.xul$/i.test(file.leafName) ||
|
||
|
(/\.xul$/i.test(file.leafName) && /\xul$/i.test(this.arrSubdir[i]))
|
||
|
) {
|
||
|
var script = getScriptData(
|
||
|
this.AUTOREMOVEBOM ? deleteBOMreadFile(file) : readFile(file, true),
|
||
|
file
|
||
|
)
|
||
|
script.dir = dir
|
||
|
if (/\.uc\.js$/i.test(script.filename)) {
|
||
|
script.ucjs = checkUCJS(script.file.path)
|
||
|
s.push(script)
|
||
|
} else {
|
||
|
script.xul = '<?xul-overlay href="' + script.url + '"?>\n'
|
||
|
o.push(script)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} catch (e) {}
|
||
|
if (this.FORCESORTSCRIPT) {
|
||
|
s.sort(cmp_fname)
|
||
|
o.sort(cmp_fname)
|
||
|
}
|
||
|
;[].push.apply(this.scripts, s)
|
||
|
;[].push.apply(this.overlays, o)
|
||
|
}
|
||
|
this.debug("Parsing getScripts: " + (new Date().getTime() - Start) + "msec")
|
||
|
|
||
|
//nameを比較する関数
|
||
|
function cmp_name(a, b) {
|
||
|
if (a.toLowerCase() == b.toLowerCase()) return a < b ? -1 : 1
|
||
|
else return a.toLowerCase() < b.toLowerCase() ? -1 : 1
|
||
|
}
|
||
|
function cmp_fname(a, b) {
|
||
|
return cmp_name(a.filename, b.filename)
|
||
|
}
|
||
|
|
||
|
//UCJSローダ必要か
|
||
|
function checkUCJS(aPath) {
|
||
|
for (var i = 0, len = that.UCJS.length; i < len; i++) {
|
||
|
if (aPath.indexOf(that.UCJS[i], 0) > -1) return true
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
//メタデータ収集
|
||
|
function getScriptData(aContent, aFile) {
|
||
|
var charset, description
|
||
|
var header = (aContent.match(
|
||
|
/^\/\/ ==UserScript==[ \t]*\n(?:.*\n)*?\/\/ ==\/UserScript==[ \t]*\n/m
|
||
|
) || [""])[0]
|
||
|
var match,
|
||
|
rex = { include: [], exclude: [] }
|
||
|
while ((match = findNextRe.exec(header))) {
|
||
|
rex[match[1]].push(
|
||
|
match[2]
|
||
|
.replace(/^main$/i, mainWindowURL)
|
||
|
.replace(/\W/g, "\\$&")
|
||
|
.replace(/\\\*/g, ".*?")
|
||
|
)
|
||
|
}
|
||
|
if (rex.include.length == 0) rex.include.push(mainWindowURL)
|
||
|
var exclude = rex.exclude.length > 0 ? "(?!" + rex.exclude.join("$|") + "$)" : ""
|
||
|
|
||
|
match = header.match(/\/\/ @charset\b(.+)\s*/i)
|
||
|
charset = ""
|
||
|
//try
|
||
|
if (match) charset = match.length > 0 ? match[1].replace(/^\s+/, "") : ""
|
||
|
|
||
|
match = header.match(/\/\/ @description\b(.+)\s*/i)
|
||
|
description = ""
|
||
|
//try
|
||
|
if (match) description = match.length > 0 ? match[1].replace(/^\s+/, "") : ""
|
||
|
//}catch(e){}
|
||
|
if (description == "" || !description) description = aFile.leafName
|
||
|
var url = fph.getURLSpecFromFile(aFile)
|
||
|
|
||
|
return {
|
||
|
filename: aFile.leafName,
|
||
|
file: aFile,
|
||
|
url: url,
|
||
|
//namespace: "",
|
||
|
charset: charset,
|
||
|
description: description,
|
||
|
//code: aContent.replace(header, ""),
|
||
|
regex: new RegExp("^" + exclude + "(" + (rex.include.join("|") || ".*") + ")$", "i"),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//スクリプトファイル読み込み
|
||
|
function readFile(aFile, metaOnly) {
|
||
|
if (typeof metaOnly == "undefined") metaOnly = false
|
||
|
var stream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
|
||
|
Ci.nsIFileInputStream
|
||
|
)
|
||
|
stream.init(aFile, 0x01, 0, 0)
|
||
|
var cvstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(
|
||
|
Ci.nsIConverterInputStream
|
||
|
)
|
||
|
cvstream.init(
|
||
|
stream,
|
||
|
"UTF-8",
|
||
|
1024,
|
||
|
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER
|
||
|
)
|
||
|
var content = "",
|
||
|
data = {}
|
||
|
while (cvstream.readString(4096, data)) {
|
||
|
content += data.value
|
||
|
if (metaOnly && content.indexOf("// ==/UserScript==") > 0) break
|
||
|
}
|
||
|
cvstream.close()
|
||
|
return content.replace(/\r\n?/g, "\n")
|
||
|
}
|
||
|
|
||
|
//スクリプトファイル文字コード変換読み込み
|
||
|
function deleteBOMreadFile(aFile) {
|
||
|
var UI = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(
|
||
|
Components.interfaces.nsIScriptableUnicodeConverter
|
||
|
)
|
||
|
UI.charset = "UTF-8"
|
||
|
var bytes = readBinary(aFile)
|
||
|
try {
|
||
|
if (bytes.length > 3 && bytes.substring(0, 3) == String.fromCharCode(239, 187, 191)) {
|
||
|
aFile.copyTo(null, aFile.leafName + ".BOM")
|
||
|
bytes = bytes.substring(3, bytes.length)
|
||
|
writeFile(aFile, bytes)
|
||
|
return UI.ConvertToUnicode(bytes).replace(/\r\n?/g, "\n")
|
||
|
}
|
||
|
var charset = getCharset(bytes)
|
||
|
//window.userChrome_js.debug(aFile.leafName + " " +charset);
|
||
|
if (charset == "UTF-8" || charset == "us-ascii") {
|
||
|
return UI.ConvertToUnicode(bytes).replace(/\r\n?/g, "\n")
|
||
|
} else {
|
||
|
UI.charset = charset
|
||
|
aFile.copyTo(null, aFile.leafName + "." + UI.charset)
|
||
|
bytes = UI.ConvertToUnicode(bytes)
|
||
|
UI.charset = "UTF-8"
|
||
|
writeFile(aFile, UI.ConvertFromUnicode(bytes))
|
||
|
return bytes.replace(/\r\n?/g, "\n")
|
||
|
}
|
||
|
} catch (ex) {
|
||
|
return readFile(aFile)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//バイナリ読み込み
|
||
|
function readBinary(aFile) {
|
||
|
var istream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(
|
||
|
Components.interfaces.nsIFileInputStream
|
||
|
)
|
||
|
istream.init(aFile, -1, -1, false)
|
||
|
|
||
|
var bstream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(
|
||
|
Components.interfaces.nsIBinaryInputStream
|
||
|
)
|
||
|
bstream.setInputStream(istream)
|
||
|
return bstream.readBytes(bstream.available())
|
||
|
}
|
||
|
|
||
|
//バイナリ書き込み
|
||
|
function writeFile(aFile, aData) {
|
||
|
var foStream = Components.classes[
|
||
|
"@mozilla.org/network/file-output-stream;1"
|
||
|
].createInstance(Components.interfaces.nsIFileOutputStream)
|
||
|
// ファイル追記の際は、0x02 | 0x10 を使う
|
||
|
foStream.init(aFile, 0x02 | 0x08 | 0x20, parseInt(664, 8), 0) // write, create, truncate
|
||
|
foStream.write(aData, aData.length)
|
||
|
foStream.close()
|
||
|
return aData
|
||
|
}
|
||
|
|
||
|
//文字コードを得る
|
||
|
function getCharset(str) {
|
||
|
function charCode(str) {
|
||
|
if (/\x1B\x24(?:[\x40\x42]|\x28\x44)/.test(str)) return "ISO-2022-JP"
|
||
|
if (/[\x80-\xFE]/.test(str)) {
|
||
|
var buf = RegExp.lastMatch + RegExp.rightContext
|
||
|
if (
|
||
|
/[\xC2-\xFD][^\x80-\xBF]|[\xC2-\xDF][\x80-\xBF][^\x00-\x7F\xC2-\xFD]|[\xE0-\xEF][\x80-\xBF][\x80-\xBF][^\x00-\x7F\xC2-\xFD]/.test(
|
||
|
buf
|
||
|
)
|
||
|
)
|
||
|
return /[\x80-\xA0]/.test(buf) ? "Shift_JIS" : "EUC-JP"
|
||
|
if (/^(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])+$/.test(buf))
|
||
|
return "Shift_JIS"
|
||
|
if (/[\x80-\xA0]/.test(buf)) return "UTF-8"
|
||
|
return "EUC-JP"
|
||
|
} else return "us-ascii"
|
||
|
}
|
||
|
|
||
|
var charset = charCode(str)
|
||
|
if (charset == "UTF-8" || charset == "us-ascii") return charset
|
||
|
|
||
|
//判定に失敗している場合があるので, 再チェック (鈍くさ);
|
||
|
var UI = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(
|
||
|
Components.interfaces.nsIScriptableUnicodeConverter
|
||
|
)
|
||
|
try {
|
||
|
UI.charset = "UTF-8"
|
||
|
if (str === UI.ConvertFromUnicode(UI.ConvertToUnicode(str))) return "UTF-8"
|
||
|
} catch (ex) {}
|
||
|
try {
|
||
|
UI.charset = charset
|
||
|
if (str === UI.ConvertFromUnicode(UI.ConvertToUnicode(str))) return charset
|
||
|
} catch (ex) {}
|
||
|
return "UTF-8"
|
||
|
}
|
||
|
|
||
|
//prefを読み込み
|
||
|
function getPref(aPrefString, aPrefType, aDefault) {
|
||
|
var xpPref = Components.classes["@mozilla.org/preferences-service;1"].getService(
|
||
|
Components.interfaces.nsIPrefService
|
||
|
)
|
||
|
try {
|
||
|
switch (aPrefType) {
|
||
|
case "complex":
|
||
|
return xpPref.getComplexValue(aPrefString, Components.interfaces.nsILocalFile)
|
||
|
break
|
||
|
case "str":
|
||
|
return unescape(xpPref.getCharPref(aPrefString).toString())
|
||
|
break
|
||
|
case "int":
|
||
|
return xpPref.getIntPref(aPrefString)
|
||
|
break
|
||
|
case "bool":
|
||
|
default:
|
||
|
return xpPref.getBoolPref(aPrefString)
|
||
|
break
|
||
|
}
|
||
|
} catch (e) {}
|
||
|
return aDefault
|
||
|
}
|
||
|
|
||
|
//pref文字列変換
|
||
|
function restoreState(a) {
|
||
|
try {
|
||
|
var sd = []
|
||
|
for (var i = 0, max = a.length; i < max; ++i) sd[unescape(a[i])] = true
|
||
|
return sd
|
||
|
} catch (e) {
|
||
|
return []
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
getLastModifiedTime: function (aScriptFile) {
|
||
|
if (this.REPLACECACHE) {
|
||
|
return aScriptFile.lastModifiedTime
|
||
|
}
|
||
|
return ""
|
||
|
},
|
||
|
|
||
|
//window.userChrome_js.loadOverlay
|
||
|
shutdown: false,
|
||
|
overlayWait: 0,
|
||
|
overlayUrl: [],
|
||
|
loadOverlay: function (url, observer, doc) {
|
||
|
window.userChrome_js.overlayUrl.push([url, observer, doc])
|
||
|
if (!window.userChrome_js.overlayWait)
|
||
|
window.userChrome_js.load(++window.userChrome_js.overlayWait)
|
||
|
},
|
||
|
|
||
|
load: function () {
|
||
|
if (!window.userChrome_js.overlayUrl.length) return --window.userChrome_js.overlayWait
|
||
|
var [url, aObserver, doc] = this.overlayUrl.shift()
|
||
|
if (!!aObserver && typeof aObserver == "function") {
|
||
|
aObserver.observe = aObserver
|
||
|
}
|
||
|
if (!doc) doc = document
|
||
|
if (!(doc instanceof XULDocument)) return 0
|
||
|
var observer = {
|
||
|
observe: function (subject, topic, data) {
|
||
|
if (topic == "xul-overlay-merged") {
|
||
|
//XXX We just caused localstore.rdf to be re-applied (bug 640158)
|
||
|
if ("retrieveToolbarIconsizesFromTheme" in window) retrieveToolbarIconsizesFromTheme()
|
||
|
if (!!aObserver && typeof aObserver.observe == "function") {
|
||
|
try {
|
||
|
aObserver.observe(subject, topic, data)
|
||
|
} catch (ex) {
|
||
|
window.userChrome_js.error(url, ex)
|
||
|
}
|
||
|
}
|
||
|
if ("userChrome_js" in window) window.userChrome_js.load()
|
||
|
}
|
||
|
},
|
||
|
QueryInterface: function (aIID) {
|
||
|
if (
|
||
|
!aIID.equals(Components.interfaces.nsISupports) &&
|
||
|
!aIID.equals(Components.interfaces.nsIObserver)
|
||
|
)
|
||
|
throw Components.results.NS_ERROR_NO_INTERFACE
|
||
|
return this
|
||
|
},
|
||
|
}
|
||
|
//if (this.INFO) this.debug("document.loadOverlay: " + url);
|
||
|
try {
|
||
|
if (window.userChrome_js.shutdown) return
|
||
|
doc.loadOverlay(url, observer)
|
||
|
} catch (ex) {
|
||
|
window.userChrome_js.error(url, ex)
|
||
|
}
|
||
|
return 0
|
||
|
},
|
||
|
|
||
|
//xulを読み込む
|
||
|
runOverlays: function (doc) {
|
||
|
try {
|
||
|
var dochref = doc.location.href.replace(/#.*$/, "")
|
||
|
} catch (e) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var overlay
|
||
|
|
||
|
for (var m = 0, len = this.overlays.length; m < len; m++) {
|
||
|
overlay = this.overlays[m]
|
||
|
if (
|
||
|
this.ALWAYSEXECUTE.indexOf(overlay.filename) < 0 &&
|
||
|
(!!this.dirDisable["*"] ||
|
||
|
!!this.dirDisable[overlay.dir] ||
|
||
|
!!this.scriptDisable[overlay.filename])
|
||
|
)
|
||
|
continue
|
||
|
|
||
|
// decide whether to run the script
|
||
|
if (overlay.regex.test(dochref)) {
|
||
|
if (this.INFO) this.debug("loadOverlay: " + overlay.filename)
|
||
|
this.loadOverlay(overlay.url + "?" + this.getLastModifiedTime(overlay.file), null, doc)
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
//uc.jsを読み込む
|
||
|
runScripts: function (doc) {
|
||
|
try {
|
||
|
var dochref = doc.location.href.replace(/#.*$/, "")
|
||
|
} catch (e) {
|
||
|
return
|
||
|
}
|
||
|
if (!(/*doc instanceof XULDocument ||*/ (doc instanceof HTMLDocument))) return
|
||
|
|
||
|
var script, aScript, url
|
||
|
const Cc = Components.classes
|
||
|
const Ci = Components.interfaces
|
||
|
const maxJSVersion = (function getMaxJSVersion() {
|
||
|
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].getService(
|
||
|
Components.interfaces.nsIXULAppInfo
|
||
|
)
|
||
|
var versionChecker = Components.classes[
|
||
|
"@mozilla.org/xpcom/version-comparator;1"
|
||
|
].getService(Components.interfaces.nsIVersionComparator)
|
||
|
|
||
|
// Firefox 3.5 and higher supports 1.8.
|
||
|
if (versionChecker.compare(appInfo.version, "3.5") >= 0) {
|
||
|
return "1.8"
|
||
|
}
|
||
|
// Firefox 2.0 and higher supports 1.7.
|
||
|
if (versionChecker.compare(appInfo.version, "2.0") >= 0) {
|
||
|
return "1.7"
|
||
|
}
|
||
|
|
||
|
// Everything else supports 1.6.
|
||
|
return "1.6"
|
||
|
})()
|
||
|
|
||
|
for (var m = 0, len = this.scripts.length; m < len; m++) {
|
||
|
script = this.scripts[m]
|
||
|
if (
|
||
|
this.ALWAYSEXECUTE.indexOf(script.filename) < 0 &&
|
||
|
(!!this.dirDisable["*"] ||
|
||
|
!!this.dirDisable[script.dir] ||
|
||
|
!!this.scriptDisable[script.filename])
|
||
|
)
|
||
|
continue
|
||
|
if (!script.regex.test(dochref)) continue
|
||
|
if (script.ucjs) {
|
||
|
//for UCJS_loader
|
||
|
if (this.INFO) this.debug("loadUCJSSubScript: " + script.filename)
|
||
|
aScript = doc.createElementNS("http://www.w3.org/1999/xhtml", "script")
|
||
|
aScript.type = "application/javascript; version=" + maxJSVersion.toString().substr(0, 3)
|
||
|
aScript.src = script.url + "?" + this.getLastModifiedTime(script.file)
|
||
|
try {
|
||
|
doc.documentElement.appendChild(aScript)
|
||
|
} catch (ex) {
|
||
|
this.error(script.filename, ex)
|
||
|
}
|
||
|
} else {
|
||
|
//Not for UCJS_loader
|
||
|
if (this.INFO) this.debug("loadSubScript: " + script.filename)
|
||
|
try {
|
||
|
if (script.charset)
|
||
|
Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
||
|
.getService(Ci.mozIJSSubScriptLoader)
|
||
|
.loadSubScript(
|
||
|
script.url + "?" + this.getLastModifiedTime(script.file),
|
||
|
doc.defaultView,
|
||
|
script.charset
|
||
|
)
|
||
|
else
|
||
|
Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
||
|
.getService(Ci.mozIJSSubScriptLoader)
|
||
|
.loadSubScript(
|
||
|
script.url + "?" + this.getLastModifiedTime(script.file),
|
||
|
doc.defaultView
|
||
|
)
|
||
|
} catch (ex) {
|
||
|
this.error(script.filename, ex)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
debug: function (aMsg) {
|
||
|
Components.classes["@mozilla.org/consoleservice;1"]
|
||
|
.getService(Components.interfaces.nsIConsoleService)
|
||
|
.logStringMessage(aMsg)
|
||
|
},
|
||
|
|
||
|
error: function (aMsg, err) {
|
||
|
const CONSOLE_SERVICE = Components.classes["@mozilla.org/consoleservice;1"].getService(
|
||
|
Components.interfaces.nsIConsoleService
|
||
|
)
|
||
|
var error = Components.classes["@mozilla.org/scripterror;1"].createInstance(
|
||
|
Components.interfaces.nsIScriptError
|
||
|
)
|
||
|
if (typeof err == "object")
|
||
|
error.init(
|
||
|
aMsg + "\n" + err.name + " : " + err.message,
|
||
|
err.fileName || null,
|
||
|
null,
|
||
|
err.lineNumber,
|
||
|
null,
|
||
|
2,
|
||
|
err.name
|
||
|
)
|
||
|
else error.init(aMsg + "\n" + err + "\n", null, null, null, null, 2, null)
|
||
|
CONSOLE_SERVICE.logMessage(error)
|
||
|
},
|
||
|
}
|
||
|
|
||
|
//少しでも速くするためスクリプトデータの再利用
|
||
|
var prefObj = Components.classes["@mozilla.org/preferences-service;1"].getService(
|
||
|
Components.interfaces.nsIPrefService
|
||
|
)
|
||
|
try {
|
||
|
var pref = prefObj.getBoolPref("userChrome.enable.reuse")
|
||
|
} catch (e) {
|
||
|
var pref = true
|
||
|
}
|
||
|
|
||
|
var that = window.userChrome_js
|
||
|
window.addEventListener(
|
||
|
"unload",
|
||
|
function () {
|
||
|
that.shutdown = true
|
||
|
},
|
||
|
false
|
||
|
)
|
||
|
|
||
|
window.xxdebug = that.debug
|
||
|
//that.debug(typeof that.getScriptsDone);
|
||
|
if (pref) {
|
||
|
//現在のメインウィンドウは一度もuserChrome.jsのスクリプトで初期化されていない?
|
||
|
if (!that.getScriptsDone) {
|
||
|
//Firefox or Thunderbard?
|
||
|
var mediator = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(
|
||
|
Components.interfaces.nsIWindowMediator
|
||
|
)
|
||
|
if (mediator.getMostRecentWindow("navigator:browser")) var windowType = "navigator:browser"
|
||
|
else if (mediator.getMostRecentWindow("mail:3pane")) var windowType = "mail:3pane"
|
||
|
var enumerator = mediator.getEnumerator(windowType)
|
||
|
//他の身内のメインウィンドウではどうかな?
|
||
|
while (enumerator.hasMoreElements()) {
|
||
|
var win = enumerator.getNext()
|
||
|
//身内のメインウインドウは初期状態でない?
|
||
|
if (win.userChrome_js && win.userChrome_js.getScriptsDone) {
|
||
|
//オブジェクトはたぶんこのウインドウのを複製すりゃいいんじゃぁないかな
|
||
|
that.UCJS = win.userChrome_js.UCJS
|
||
|
that.arrSubdir = win.userChrome_js.arrSubdir
|
||
|
that.scripts = win.userChrome_js.scripts
|
||
|
that.overlays = win.userChrome_js.overlays
|
||
|
that.dirDisable = win.userChrome_js.dirDisable
|
||
|
that.scriptDisable = win.userChrome_js.scriptDisable
|
||
|
that.getScriptsDone = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!that.getScriptsDone) {
|
||
|
if (that.INFO) that.debug("getScripts")
|
||
|
that.getScripts()
|
||
|
that.getScriptsDone = true
|
||
|
} else {
|
||
|
if (that.INFO) that.debug("skip getScripts")
|
||
|
}
|
||
|
|
||
|
var href = location.href
|
||
|
var doc = document
|
||
|
|
||
|
//Bug 330458 Cannot dynamically load an overlay using document.loadOverlay
|
||
|
//until a previous overlay is completely loaded
|
||
|
|
||
|
if (that.INFO) that.debug("load " + href)
|
||
|
|
||
|
//chromehiddenならロードしない
|
||
|
if (
|
||
|
location.href === that.BROWSERCHROME &&
|
||
|
that.EXCLUDE_CHROMEHIDDEN &&
|
||
|
document.documentElement.getAttribute("chromehidden") != ""
|
||
|
)
|
||
|
return
|
||
|
|
||
|
if (typeof gBrowser != undefined) {
|
||
|
that.runScripts(doc)
|
||
|
setTimeout(
|
||
|
function (doc) {
|
||
|
that.runOverlays(doc)
|
||
|
},
|
||
|
0,
|
||
|
doc
|
||
|
)
|
||
|
} else {
|
||
|
setTimeout(
|
||
|
function (doc) {
|
||
|
that.runScripts(doc)
|
||
|
setTimeout(
|
||
|
function (doc) {
|
||
|
that.runOverlays(doc)
|
||
|
},
|
||
|
0,
|
||
|
doc
|
||
|
)
|
||
|
},
|
||
|
0,
|
||
|
doc
|
||
|
)
|
||
|
}
|
||
|
|
||
|
//Sidebar for Trunc
|
||
|
if (location.href != that.BROWSERCHROME) return
|
||
|
window.document.addEventListener(
|
||
|
"load",
|
||
|
function (event) {
|
||
|
if (!event.originalTarget.location) return
|
||
|
if (/^(about:(blank|newtab|home))/i.test(event.originalTarget.location.href)) return
|
||
|
if (!/^(about:|chrome:)/.test(event.originalTarget.location.href)) return
|
||
|
var doc = event.originalTarget
|
||
|
var href = doc.location.href
|
||
|
if (that.INFO) that.debug("load Sidebar " + href)
|
||
|
setTimeout(
|
||
|
function (doc) {
|
||
|
that.runScripts(doc)
|
||
|
setTimeout(
|
||
|
function (doc) {
|
||
|
that.runOverlays(doc)
|
||
|
},
|
||
|
0,
|
||
|
doc
|
||
|
)
|
||
|
},
|
||
|
0,
|
||
|
doc
|
||
|
)
|
||
|
if (href != "chrome://browser/content/web-panels.xul") return
|
||
|
if (!window.document.getElementById("sidebar")) return
|
||
|
var sidebarWindow = window.document.getElementById("sidebar").contentWindow
|
||
|
if (sidebarWindow) {
|
||
|
loadInWebpanel.init(sidebarWindow)
|
||
|
}
|
||
|
},
|
||
|
true
|
||
|
)
|
||
|
|
||
|
var loadInWebpanel = {
|
||
|
sidebarWindow: null,
|
||
|
init: function (sidebarWindow) {
|
||
|
this.sidebarWindow = sidebarWindow
|
||
|
this.sidebarWindow.document
|
||
|
.getElementById("web-panels-browser")
|
||
|
.addEventListener("load", this, true)
|
||
|
this.sidebarWindow.addEventListener("unload", this, false)
|
||
|
},
|
||
|
handleEvent: function (event) {
|
||
|
switch (event.type) {
|
||
|
case "unload":
|
||
|
this.uninit(event)
|
||
|
break
|
||
|
case "load":
|
||
|
this.load(event)
|
||
|
break
|
||
|
}
|
||
|
},
|
||
|
uninit: function (event) {
|
||
|
this.sidebarWindow.document
|
||
|
.getElementById("web-panels-browser")
|
||
|
.removeEventListener("load", this, true)
|
||
|
this.sidebarWindow.removeEventListener("unload", this, false)
|
||
|
},
|
||
|
load: function (event) {
|
||
|
var doc = event.originalTarget
|
||
|
var href = doc.location.href
|
||
|
if (!/^chrome:/.test(href)) return
|
||
|
if (that.INFO) that.debug("load Webpanel " + href)
|
||
|
setTimeout(
|
||
|
function (doc) {
|
||
|
that.runScripts(doc)
|
||
|
setTimeout(
|
||
|
function (doc) {
|
||
|
that.runOverlays(doc)
|
||
|
},
|
||
|
0,
|
||
|
doc
|
||
|
)
|
||
|
},
|
||
|
0,
|
||
|
doc
|
||
|
)
|
||
|
},
|
||
|
}
|
||
|
})()
|