Kanasan.JS Greasemonkey チュートリアル読書会
一時間ほど遅刻…。「参加者ブログ一覧」は止めたのかな。
http://diveintogreasemonkey.org/
- 古すぎて鵜呑みにできない。
- コードがあまり美しくない。
- しかしユーモアは素晴らしい。
@(in|ex)clude
//components/greasemonkey.js 106 domContentLoaded: function(wrappedContentWin, chromeWin) { var unsafeWin = wrappedContentWin.wrappedJSObject; var unsafeLoc = new XPCNativeWrapper(unsafeWin, "location").location; var href = new XPCNativeWrapper(unsafeLoc, "href").href; var scripts = this.initScripts(href);
//components/greasemonkey.js 210 initScripts: function(url) { function testMatch(script) { return script.enabled && script.matchesURL(url); } return GM_getConfig().getMatchingScripts(testMatch);
//chrome/chromeFiles/content/config.js 380 getMatchingScripts: function(testFunc) { return this._scripts.filter(testFunc); },
domContentLoaded
時に location.href
と比較。
//chrome/chromeFiles/content/config.js 439 Script.prototype = { matchesURL: function(url) { function test(page) { return convert2RegExp(page).test(url); } return this._includes.some(test) && !this._excludes.some(test);
それぞれ convert2RegExp
で正規表現に変換してテスト。キャッシュしてない。
//chrome/chromeFiles/content/convert2RegExp.js 3 function convert2RegExp( pattern ) {
長いので載せないが,この convert2RegExp
の中身がなかなか楽しい。
convert2RegExp('http:// *.google.* /search?*') === /^http:\/\/.*\.google\..*\/search\?.*$/i convert2RegExp('http://*.google.tld/search?*') === /^http:\/\/.*\.google.(?:demon\.co\.uk|esc\.edu\.ar|(?:c[oi]\.)? .../i
アドオンより遅い?
//components/greasemonkey.js 276 script.requires.forEach(function(req){ var contents = req.textContent; var lineCount = contents.split("\n").length; requires.push(contents); offset += lineCount; offsets.push(offset); }) script.offsets = offsets; var scriptSrc = "\n" + // error line-number calculations depend on these requires.join("\n") + "\n" + contents + "\n"; if (!script.unwrap) scriptSrc = "(function(){"+ scriptSrc +"})()"; if (!this.evalInSandbox(scriptSrc, url, sandbox, script) && script.unwrap) this.evalInSandbox("(function(){"+ scriptSrc +"})()", url, sandbox, script); // wrap anyway on early return
//components/greasemonkey.js 320 evalInSandbox: function(code, codebase, sandbox, script) { if (!(Components.utils && Components.utils.Sandbox)) { var e = new Error("Could not create sandbox."); GM_logError(e, 0, e.fileName, e.lineNumber); } else { try { // workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=307984 var lineFinder = new Error(); Components.utils.evalInSandbox(code, sandbox);
該当ページ毎にいちいち evalInSandbox
するので効率は良くない。
- 特定のページ用なら許せる。
- AutoPagerize みたいにほとんどのページで実行されるようなのはアドオンにするのが良さそうに思える。
GM_setValue(name, val)
//components/greasemonkey.js 255 sandbox.GM_setValue = GM_hitch(storage, "setValue");
//chrome/chromeFiles/content/miscapis.js 1 function GM_ScriptStorage(script) { this.prefMan = new GM_PrefManager(["scriptvals.", script.namespace, "/", script.name, "."].join("")); } GM_ScriptStorage.prototype.setValue = function(name, val) { if (!GM_apiLeakCheck("GM_setValue")) { return; } this.prefMan.setValue(name, val); };
//chrome/chromeFiles/content/prefmanager.js 11 function GM_PrefManager(startPoint) { if (!startPoint) { startPoint = ""; } startPoint = "greasemonkey." + startPoint; var pref = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService) .getBranch(startPoint);
//chrome/chromeFiles/content/prefmanager.js 65 /** * sets the named preference to the specified value. values must be strings, * booleans, or integers. */ this.setValue = function(prefName, value) {
以上を経て greasemonkey.{script.namespace}/{script.name}.{name}
に格納。