ããã¯ãFirefoxãšSeaMonkeyã®ãã©ã€ããŒãã¿ãæ¡åŒµæ©èœã«é¢ãããã®ã§ããå®è£ ã®è©³çŽ°-å ·äœçã«ã¯ãããšãåèµ·åãå¿ èŠãšããªãæ¡åŒµæ©èœïŒäžè¬ã«restartless ïŒã§ãã
æ¡åŒµæ©èœã¯ãå±¥æŽãä¿åãããªããã©ã€ããŒãã¿ããè¿œå ããCookieã®åå¥ã®ã»ããã䜿çšãããŸãã
æ®å¿µãªãããç°¡åãªæ¹æ³ã§èšè¿°ããããšãããšãã¡ã€ã³ãããã¯ããå€ãã®æ³šææ£æŒ«ã«ãªããŸãããã®ãããåºåã¯æ¡åŒµæ©èœã®èšè¿°ã«é¢ããäžçš®ã®å¯ãéãã§ããã äžæ¹ãæ°ãæ£ããããšãªããããããã¹ãŠå¿ èŠãšããªããªã£ã人ã«ã®ã¿æ確ã«ãªããŸãã
ããé¢åã§ãããè«ççãªé åºã§ã ãããããæ確ã§ããããšãé¡ã£ãŠããŸãã
ãããããæ¡åŒµæ©èœã¯Gecko 20ã«è¿œå ããããŠã£ã³ããŠã¢ãŒãïŒãŸãã¯ããã§ã®ãŠã£ã³ããŠããšã®å€ææ¹æ³ïŒã®åãªãã¢ããªã³ã§ãããšããäºå®ããéå§ããå¿ èŠããããŸãã
ãããã®å éšçãªå€æŽããªããã°ãäœãèµ·ãããŸããã§ããã
ãããŠå€ãã®å€æŽããããŸããïŒã ãã°463027 ã¯1646ã®ãã°ã«äŸåããŠããŸããã
幞ããªããšã«ããã©ã€ããŒããŠã£ã³ããŠã®ã¿ãåãåã£ããšããŠãããŠã£ã³ããŠå šäœã ãã§ãªããåã ã®ã¿ãïŒåã ã®ã¿ãã®ã³ã³ãã³ãïŒã®ãã©ã€ãã·ãŒãå€æŽããããšãæåŸ ããŠãå éšã§å€ãã®ããšãè¡ãããŠããŸãã
ããã¯ã人éã®èšèã§è¡šçŸããå Žåã§ãã äžè¬çã«ãèªåã®èšèã§äœãã説æã§ããªãå Žåã¯ãç解ãçåèŠããå¿ èŠããããŸãã ãã®ãããå èïŒè¡æ¶²ãè žãããã«ã¯ïŒãçŽæãããŠããŸããããç§ã¯ã·ã³ãã«ã§æé ãªäŸ¡æ Œã®ãã®ããå§ããŸãã
ãããŠãã·ã³ãã«ã§ç解ããããã®ã¯ãåãŠã£ã³ããŠ*ã«nsILoadContextã€ã³ã¿ãŒãã§ã€ã¹ïŒããã¥ã¡ã³ãåãããŠããªããã³ã¡ã³ãä»ãã®ãœãŒã¹ã³ãŒãã®ã¿ããããšããæå³ïŒããããçŸåšusePrivateBrowsingããããã£ããããšããäºå®ã§ãã ãããŠãæãéèŠãªããšãšããŠãä»ã®ãã¹ãŠã®ã³ãŒãã¯ãã®ããããã£ã®å€ãèæ ®ããŸãã ãããã£ãŠããã¹ãŠã®æ±ãäœæ¥ã¯ç§ãã¡ã®ããã«è¡ãããŸããïŒæ£çŽã«èšããšãæ®å¿µãªããããã¹ãŠã§ã¯ãããŸããïŒã
*å®éã«ã¯ãèŠãã以äžã®ãŠã£ã³ããŠããããŸãããã®å Žåããã¹ãŠã®JavaScriptããã°ã©ããŒã«éŠŽæã¿ã®ãããŠã£ã³ããŠãªããžã§ã¯ããæå³ããŸã ã åãã©ãŠã¶ãŠã£ã³ããŠã«ã¯ãã®ãããªãªããžã§ã¯ããããããã®äžã«ã¯å®éã®DOMããªãŒãæã€ããŸãç¥ãããŠããªãããã¥ã¡ã³ãããããŸãã 次ã«ãåã¿ãã§ãç¬èªã®ãŠã£ã³ããŠãããã¥ã¡ã³ããããã³DOMããªãŒãåããHTML iframeã«éåžžã«ãã䌌ãXULãã©ãŠã¶ãæ¥ç¶ãããŸãã
äžè¬çã«ã¯ãäžåºŠèŠãã»ããè¯ãã§ãïŒ DOMã€ã³ã¹ãã¯ã¿ãŒã䜿çšããŠãã®æ§é å šäœãã©ã€ãã§èŠãããšãã§ããŸãïŒåçã«äœããã®çš®é¡ã®æ瀺ããããŸãããŸãã¯ã ã«ã¹ã¿ã ãã¿ã³ãšå±æ§ã€ã³ã¹ãã¯ã¿ãŒãã¿ã³ãé 眮ã§ããŸãã ïŒ
ããã«ãäŸãã°ãåãXULãã©ãŠã¶ãŒããããŸãïŒ
ã€ãŸããã¿ã¹ã¯ã¯ãã¿ãå ã®<browser>ã«é¢é£ãããã®ããnsILoadContextã€ã³ã¿ãŒãã§ã€ã¹ãèŠæ±ããusePrivateBrowsingãfalseã«åãæ¿ããŸãã
ä»ã®2ã€ã®ã€ã³ã¿ãŒãã§ãŒã¹ã ã€ãŸã nsISupports.QueryInterfaceïŒïŒããã³nsIInterfaceRequestor.getInterfaceïŒïŒã ã ç© forããæ åœããŸãã
ãã ãããã®å Žåã¯ãã§ã«é¢åãèŠãŠãããå®æãããªãœãŒã¹ ã¢ãžã¥ãŒã«ã«ã€ããŠç¥ãããšãã§ãã䟿å©ãªèšäºã ãŠã£ã³ããŠããšã®ãã©ã€ããŒããã©ãŠãžã³ã°ã®ãµããŒã ãããããŸãã
privacyContextFromWindow: function pbu_privacyContextFromWindow(aWindow) { return aWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsILoadContext); },
ãã ããå¥ã®åŸ®åŠãªç¹ããããŸãïŒusePrivateBrowsingããããã£ã®å€ãå€æŽãããšããšã©ãŒã³ã³ãœãŒã«ã«æžã蟌ã¿ãŸã
èŠåïŒusePrivateBrowsingå±æ§ãèšå®ã§ããã®ã¯å éšã³ãŒãã®ã¿ã§ã
ããã¯Bug 800193-nsILoadContext.usePrivateBrowsingããããã£ãèªã¿åãå°çšã«ããŸãã 幞ããçµæãšããŠãåé¡ã¯ãã®èŠåã«éå®ãããŸãã
ãããã£ãŠãã¿ãã«ã¢ã¿ããããããŠã£ã³ããŠãªããžã§ã¯ããååŸããå¿ èŠããããŸãã
äžè¬çã«gBrowser.getBrowserForTabïŒtabïŒããããŸããã
<method name="getBrowserForTab"> <parameter name="aTab"/> <body> <![CDATA[ return aTab.linkedBrowser; ]]> </body> </method>
ããã«ããã®ã¢ãããŒãã¯å€ãã®å Žæã§äœ¿çšãããŠããŸãããææžåãããŠããªãããã§ãã
ãã®ãããïŒæ£çŽãªãšããããŸã ã¿ãèªäœã¯ãããŸããããåŸã§è©³ãã説æããŸãïŒ XULãã©ãŠã¶ãŒã¿ããžã®ãªã³ã¯ããããŸãããã®ã¿ãã«ã¯ããã©ãŠã¶ãŒã§å¿ èŠãªDOMãŠã£ã³ããŠãåç §ããcontentWindowããããã£ããããŸãã
ãããã£ãŠã次ã®ããã«ãªããŸãã
var tab = ... // , Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); var privacyContext = PrivateBrowsingUtils.privacyContextFromWindow(tab.linkedBrowser.contentWindow); privacyContext.usePrivateBrowsing = true; //
ãã©ã€ããŒãã¿ãããããã©ããã確èªãããã©ã€ãã·ãŒã¢ãŒããåãæ¿ããããšãã§ããã®ã§ãã¿ãèªäœãåŠçããŸãã
ãŸãããã©ã€ããŒãã¿ããéããŸãã
ã¿ããéãããã®gBrowser.addTabïŒïŒããããŸããã埮åŠãªç¹ããããŸãïŒæåã«ã¿ããéããŠãããã©ã€ããŒãã¢ãŒãããªã³ã«ãããšãã¿ãå ã®ãã©ãŠã¶ãŒã¯åæåããæéãããããªã³ã¯ã¯é²èŠ§å±¥æŽã«ä¿åãããŸããããCookieã¯ãã©ã€ããŒãã«äœ¿çšãããŸããã
ãããçºçããçç±ãç解ããã«ã¯ããœãŒã¹ã³ãŒãã確èªããå¿ èŠããããŸãã
<method name="addTab"> <parameter name="aURI"/> <parameter name="aReferrerURI"/> <parameter name="aCharset"/> <parameter name="aPostData"/> <parameter name="aOwner"/> <parameter name="aAllowThirdPartyFixup"/> <body> <![CDATA[ ... // Dispatch a new tab notification. We do this once we're // entirely done, so that things are in a consistent state // even if the event listener opens or closes tabs. var evt = document.createEvent("Events"); evt.initEvent("TabOpen", true, false); t.dispatchEvent(evt); if (uriIsNotAboutBlank) { ... try { b.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset, aPostData); } catch (ex) { Cu.reportError(ex); } }
幞ããªããšã«ãçç±ã衚瀺ãããã ãã§ãªãïŒb.loadURIWithFlagsïŒïŒã«ããããŠã³ããŒãã®éå§ïŒã解決çããããŸãïŒ TabOpenãçæããã€ãã³ãã䜿çšã§ããŸã-ããŠã³ããŒããéå§ããçŽåã«éç¥ãå±ããŸãã
ãããŠãããã§ã³ãŒãã¯ãã§ã«ç§ãã¡ãæãã»ã©éæã§ã¯ãããŸããã åºæ¬çãªèãæ¹ã¯æ¬¡ã®ãšããã§ãã
window.addEventListener("TabOpen", function waitForTab(e) { window.removeEventListener(e.type, waitForTab, false); var tab = e.originalTarget; // e.target SeaMonkey makeTabPrivate(tab); }, false); gBrowser.selectedTab = gBrowser.addTab(); //
åæã«ã event.originalTargetã¯event.targetãšã¯ç°ãªããåŸè ãšã¯ç°ãªãã XBLã䜿çšããŠäœæãããå¿åããŒããåç §ã§ããŸãïŒSeaMonkeyã«ã¯<tabbrowser> 'aã®ç¬èªã®å®è£ ããããŸãïŒã
ããŠãä»ã¯ãã©ã€ããŒãã¿ãã1ã€ãããŸãã
äœããã®åœ¢ã§ä»ã®ãã®ããèŠèŠçã«åé¢ããå¿ èŠããããŸãã ãããè¡ãã«ã¯ãprivateTab-isPrivate = "true"å±æ§ãã¿ãã«è¿œå ããã¹ã¿ã€ã«ã§å€èŠ³ãå€æŽããŸãã
ããã§ãä»ã®æ¡åŒµæ©èœãšã®æœåšçãªè¡çªãåé¿ããå¿ èŠãããããšã«æ³šæããããšãéèŠã§ãããã¹ãŠã®ã¯ã©ã¹ãå±æ§ããã®ä»ã®ãšã³ãã£ãã£ïŒãã®å Žåã¯ãprivateTab-ãïŒã«æ確ãªãã¬ãã£ãã¯ã¹ãè¿œå ããã ãã§ãã
æ°ãæ£ããªãããã«ãã¹ã¿ã€ã«ã«ã€ããŠç°¡åã«èª¬æããŸãïŒ nsIStyleSheetService.loadAndRegisterSheetïŒïŒã䜿çšãããŸãã ãã®å Žåãã¹ã¿ã€ã«ã¯äžè¬ã«ãã¹ãŠã®ãŠã£ã³ããŠã«é©çšãããããã @ -moz-documentã§ã¹ã¿ã€ã«ãå¶éããããšããå§ãããŸã ã
ãã ãããã©ã€ããŒãã¿ãããã¯ãæ°ããã¿ããŸãã¯ãŠã£ã³ããŠãéãããšãã§ããŸãã ãããã®æ°ããã¿ããšãŠã£ã³ããŠã¯ãã©ã€ããŒãã®ãŸãŸã«ããŠãã ããïŒ
2ã€ã®æ¹æ³ããããŸãã
æåã®æ¹æ³ã¯ãäœããã®æ¹æ³ã§ã¿ããéãæ©èœã®ãã¹ãŠãŸãã¯äžéšããªãŒããŒã©ã€ãããããšã§ãã ã©ãããŒãäœæããïŒè¯ãæ¹æ³ïŒããevalããããé©çšã§ããŸãïŒããå€ãã®ãªãã·ã§ã³ããããŸãããåŸã§ããŒã«ããã¯ããã®ã¯ããå°é£ã§ããããã®æ¹æ³ã¯ãå§ãããŸããïŒã
äžè¬ã«ãããããšã©ãããŒã®ãã£ã³ã»ã«ã§ã¯ããã¹ãŠãããã»ã©åçŽã§ã¯ãããŸãããå¥ã®æ¡åŒµæ©èœã¯ããªã³ãšãªãã®éã«ç¬èªã®ãããã課ãããšãã§ããŸãïŒåèµ·åã¯äžèŠã§ãïŒïŒã ãããŠããã®æ¡åŒµæ©èœãevalããããè¡ããšãã©ãããŒããããå£ããŸã-ã³ãŒããå€æŽãããŸããã
ããªãã¯ã¯æ¬¡ã®ãšããã§ããã©ãããŒé¢æ°ã®toStringïŒïŒããã³toSourceïŒïŒã¡ãœãããåå®çŸ©ããïŒã€ãŸããã©ãããŒãå€æŽãããå ã®é¢æ°ã®ããã«èŠããããïŒå ŽåããµãŒãããŒãã£ã®ãããã¯ã»ãšãã©ã®å ŽåããŸãåäœããŸãã ãããä»ã圌ãã¯ç§ãã¡ãåæããç§ãã¡ã¯ãã¹ãŠãå ã©ããã«æ»ãå¿ èŠããããŸãã ãããããããã®ãªããã®ããããŸããïŒ ãããŠãé¢æ°ã®èšæ¶ãããå€ã«ããŒã«ããã¯ãããšããã®åŸã«ããããé©çšãããã¹ãŠã®æ¡åŒµæ©èœã解é€ãããŸãã
ããããããã§ã«ã³ãã³ã°ãããããšãã§ããŸãïŒé¢æ°ãå€æŽãããšããã³ãŒãã«ã°ããŒãã«ïŒå€æŽãå¿ èŠãšããé¢æ°ãææãããŠã£ã³ããŠã«é¢é£ããïŒé¢æ°ãžã®åŒã³åºããè¿œå ãããµãŒãããŒãã£ã®ç·šéãèŠã€ãã£ãå Žåãæé ããããšãå¯èœã«ãªããŸã
ãããã©ãããŒã䜿çšããããã®ãããªçŽããããã·ã£ãŒãããºã ã次ã«ç€ºããŸãã ãããã«ãããšæãããŸãã ã ã³ãŒãã¯è¯ããããŸããã
æãåçŽãªã±ãŒã¹ã§ã¯ã次ã®ããšãããããŸãã
ã¡ã€ã³ã³ãŒãïŒå ã®ãªãŒããŒã©ã€ãtoStringïŒïŒ/ toSourceïŒïŒãèŠããŠãæ¬è³ªã瀺ãããã«çç¥ããŠããŸãïŒïŒ
var orig = someObject.someMethod; var patch = window["privateTabMod::someObject.someMethod"] = function() { // - }; someObject.someMethod = function wrapped() { if(patch.apply(this, arguments)) return undefined; return orig.apply(this, arguments); };
ãã¡ãããããã§ã¯ãä»ã®å Žæã§äœ¿çšã§ããååã§ã°ããŒãã«ããããã£ããŠã£ã³ããŠã«äœæããããšãéèŠã§ãã
åæã«ãtoStringïŒïŒ/ toSourceïŒïŒãåå®çŸ©ããããããè¿ããŸãïŒ
function wrapped() { if(window["privateTabMod::someObject.someMethod"].apply(this, arguments)) return; // }
次ã«ãããããããŒã«ããã¯ããå¿ èŠãããå Žåãèšæ¶ãããå€æŽæžã¿é¢æ°ãsomeObject.someMethodã®çŸåšã®å€ãšæ¯èŒããŸãã äžèŽããå Žåã¯ãsomeObject.someMethodãèšæ¶ãããŠããå ã®é¢æ°ã«å€æŽããç°ãªãå Žåã¯ããŠã£ã³ããŠ["privateTabMod :: someObject.someMethod"]ã空ã®é¢æ°ã«å€æŽããŸãã
ãã®ãããªé·ãåŸéã
ãããŠãã¯ããevalãããã«æ ¹æ¬çãªåé¡ã¯äœããããŸãããæã«ã¯ä»ã«æ¹æ³ããªãå ŽåããããŸãã
ãã ããã©ãããŒã䜿çšã§ããå Žåã¯ãã©ãããŒã䜿çšããå¿ èŠãããããšãç解ããå¿ èŠããããŸãã ããã¯ã€ã³ã¿ãŒããªã¿ãŒã«ãã£ãŠããæé©åãããè©äŸ¡ããããäœæãããµãŒãããŒãã£ã®ã³ãŒãã®ã¿ããããç Žãããšãã§ããŸãã
ããã§ã¯ããã¡ããã圌ã®é ãã€ããã§éããè ãæ¯ãæãæ¥ãŸããããæåã«ãããåŸ ã£ãŠèªãã§ããæ¹ãè¯ãã§ãïŒ
ãŠã©ãžããŒã«ã»ãã©ã³ãã«ãããšã¯ã¹ãã³ã·ã§ã³ã§evalïŒïŒã䜿çšãã5ã€ã®ééã£ãçç±
evalãä»ã®ããã¯ã»ã©çµ¶å¯Ÿã«å±éºã§ã¯ãªããšèšãçç±ãšãä»ã®ããã¯ã® 代ããã«evalïŒïŒã䜿çšããŠããçç±ã¯äœã§ããïŒ YUKIãPiroãããã·
èŠããã«ãã©ãããŒã¯eval-patchesãå£ãïŒæã«ã¯ããããªãã§ã¯ã§ããªãïŒããã¡ããšããeval-patchesã¯ä»ã®ããããã©ãããŒãå£ããŸããã ã¯ããããã¯æœåšçã«ã¯ããã«å±éºã§ãããå±éºã§ã-ããã¯ãŸã£ããåãå ¥ããããªããšããæå³ã§ã¯ãããŸããã
ãããŠãäžè¬çã«ããããªãã§ã§ããå Žåã¯ããã®ãã¹ãéžæããå¿ èŠããããŸã-競åãæãå°ãªãã§ãã
ãã¡ãããããŸããŸãªæ¡åŒµæ©èœãšã®äºææ§ã«å¯ŸåŠããå¿ èŠããªãå Žåã¯ã ãããŠãçµå±ã®ãšããããã¹ãŠã®æ¡åŒµæ©èœãçãããçŽæ¥ãã§ããããã§ã¯ãããŸããã
ãã®å Žåãè«ççãªå¹æã¯ãããŸããããéåžžã«ç°¡åãªæ¹æ³ããããŸãã以åã¯ãTabOpenã€ãã³ããªã¹ããŒã䜿çšããŠãåæåãããŠããªãã¿ããååŸããŠããŸããã ããã§ãåãããšãã§ããŸããã¿ããéãããšãã«ã çŸåšã®ã¿ãã®ãã©ã€ãã·ãŒã確ââèªãããã©ã€ããŒãã®å Žåã¯æ°ããã¿ãããã©ã€ããŒãã«ããŸãã
äžè¬ã«ãWindowsã§ãåæ§ã§ãïŒæ°ãããŠã£ã³ããŠã§ãªã³ã¯ãéããåŸãopenerããããã£ãèšå®ãããŠããªããããwindow.openerã®çœ®æãæåã§ååŸããå¿ èŠããããŸãïŒã芪ãŠã£ã³ããŠã®ã¢ã¯ãã£ããªã¿ãã®ãã©ã€ãã·ãŒã確ââèªããŸãã
ãããããã®æ¡åŒµæ©èœã¯ãŸã ã¿ãã«é¢ãããã®ãªã®ã§ãç¹ã«åèµ·åã®ãªãæ¡åŒµæ©èœã§éããŠãããŠã£ã³ããŠã远跡ããããšã«ã€ããŠããã€ãã®èšèãèšãããã®ã§ã詳现ãªãã§è¡ãããšãã§ããŸãã
ãã®ããããã§ã«ãã©ã€ããŒãã¿ããéãããšãã§ããããããéããã®ããã¹ãŠãã©ã€ããŒãã§ãã
äž»ãªäœæ¥ã¯èåŸã«ãããå¿«é©ãªãã®ãå§ãŸãããããããŠãŒã¶ããªãã£ãæ§ç¯ãããŸãã ãããŠãæã«ã¯ãããã®ããããªããšã¯ã¡ã€ã³ã³ãŒããããã¯ããã«å€ããªããŸãã
ãŸããã»ãã·ã§ã³ã®ä¿åãšãã®ä»ã®åèµ·åããããŸãã ã¿ãã¯ãã©ã€ããŒãã®ãŸãŸã«ããŠãã ããã
ãããè¡ãããã«ããªã«ããªã®ç¬éãšnsISessionStoreã€ã³ã¿ãŒãã§ã€ã¹ã远跡ããSSTabRestoringã€ãã³ãããããŸãããã®ã€ãã³ãã«ã¯persistTabAttributeïŒïŒã¡ãœãããå¿ èŠã§ãã
ãããŠããã¹ãŠãç°¡åã§ããã¿ãã埩å ãããšãã以åã«èšå®ãããprivateTab-isPrivateå±æ§ã®ååšã確èªããå¿ èŠããããŸãã ããå Žåã¯ãã¿ãããã©ã€ããŒãã«ããŸãã
ãã¡ãããããã¯ãã¹ãŠãšã¯ã»ã©é ããã®ã§ã-ããã¹ãŠãã¯ãã§ã«2100è¡ãè¶ ããŠãããèŠãç®ãããã¯ããã«äºçŽ°ãªããšããããŸã-ãŠã£ã³ããŠã¿ã€ãã«ã®å€æŽãšãã¡ãã¥ãŒãé衚瀺ã®å Žåã®ã¢ããªã±ãŒã·ã§ã³ãã¿ã³ïŒèµ€ãã¢ããªãã¿ã³ïŒã®äž¡æ¹ã®å€æŽãã¡ã€ã³ãŠã£ã³ããŠã®DOMããªãŒã®ã«ãŒãããŒãã«ããprivatebrowsingmodeå±æ§ã®Firefoxã¹ã¿ã€ã«ãå€æŽããŸãïŒãç°ãªãã¡ãã¥ãŒã«ã¢ã€ãã ãè¿œå ããããŒããŒãã·ã§ãŒãã«ãããåŠçãïŒãããŠçµã¿èŸŒã¿ã®XULããŒã¯æ±ºããŠåèµ·åããŸããïŒããã©ãã°ã¢ã³ãããããããŸãïŒãªã³ã¯ããã«ã§ããŸãïŒãã©ã€ããŒãã¿ãïŒïŒãããã³ãã©ã€ããŒãã¿ãéã§ã¿ãããã©ãã°ã§ããªã éçã®çªïŒããã³ãããïŒïŒããããŠ...ããªãã¯äœãèŠããŠããŸããã
ããããç§ãã¡ã¯æéãã€ãŸãèªè ã®æéã倧åã«ããŠããŸã
ã¿ããããã£ãã®ã§ïŒã«ã¹ã¿ã ãã¿ã³æ¡åŒµæ©èœãŸãã¯çµã¿èŸŒã¿ããŒã«ã䜿çšããŠæ¡åŒµæ©èœãäœæããã«ãaboutïŒã§devtools.chrome.enabled = trueã«èšå®ããWebéçºãèµ·å-ã·ã³ãã«ãªJavaScriptãšãã£ã¿ãŒïŒã¹ã¯ã©ããããããShift + F4-ç°å¢-ãã©ãŠã¶ãŒïŒãæ¡åŒµæ©èœã«ç©äºãå ¥ããŸãã
ãããã2100è¡ã¯æªãäŸã§ãã ãããŠãã¢ãžã¥ãŒã«ã«ã«ããããããšã¯å¯èœã ããã§ãïŒããããã«ããããŸããããããŸã§ã®ãšãããã«ããã¯è¿œå ã®ã³ãŒãã®å±±ã«ã€ãªããããšãå€æããŠããŸãïŒããããŠåçŽãªããšãå§ããããã«å¿ èŠãªæå°éã®è¡ã倱ãããããã§ãã
ããã§ã¯ãããåçŽãªäŸãèŠãŠã¿ãŸãããïŒ Tree Style Tab Tweaker ïŒ å¿µã®ããããªã³ã¯ãç¹å®ã®ããŒãžã§ã³ã«ã€ãªããå Žåãããã§ãªãå Žåã¯æéãšãšãã«èšãã¿ãŸãïŒã
äžè¬çã«ããTweakerãã¯å€§å£°ã§èšãããŸãã ããã¯ã åé¡ïŒ384ã«å¯ŸããŠãã® ãä¿®æ£ãïŒãããã«æ¹åïŒãå®è£ ãã[ ããªãŒã¹ã¿ã€ã«]ã¿ãã® åé¡ã§ãã äžçªäžã®è¡ã¯ã芪ã¿ããéãããšãéããã¿ãããããŒã®ã¿ãã«çœ®ãæããããŠã¿ãéå±€ãä¿åãããããšã§ãã
ãããããã§ãããããããªãããããã¯äž»èŠãªãã€ã³ãã远跡ããã®ãç°¡åã§ãã
ãŸããã¯ã©ã·ãã¯ãªinstall.rdfãå¿ èŠã§ã ãããããªããšäœãæ©èœããŸãããã ãã©ã°ã¯ ã <emïŒbootstrap> true </ emïŒbootstrap> ãã§ãã
ãããŠãinstall.rdfã®æšªã«ããbootstrap.jsãã¡ã€ã«ã
ããã«ããããã¯ãã¹ãŠéåžžã®ZIPã¢ãŒã«ã€ãã«ããã±ãŒãžåãããŠããŸãããæ¡åŒµåã¯xpiã§ãã ãããŠããã ãã§ãïŒ ããŠãããã¯æ£ããã³ãŒãããã§ã«æžãããŠãããšãã§ãã
bootstrap.jsãã¡ã€ã«ã¯ããã©ãŠã¶ããªã³ããªããèµ·åãããšãã«ã¢ããªã³ãããŒãžã£ãåŒã³åºãç¹å¥ãªæ©èœãå¿ ã決å®ããå¿ èŠããããŸãã
ãããŠãæ¡åŒµæ©èœã¯ããèªäœã§ãã¹ãŠãå®è¡ããå¿ èŠããããŸãïŒãŠã£ã³ããŠããã£ãããããããã§äœããå®è¡ãããã®åŸãã¯ãªãŒã³ã¢ããããå¿ èŠããããŸãã
ã¡ãªã¿ã«ãããã¯éåžžã«æ²ããããšã§ãããªããªãããããã®æäœãç°¡çŽ åããAPIããªãããã§ãïŒãŸã æåŸ ããŠããŸããïŒã
ãã ããããã§ã¯äºçŽãå¿ èŠã§ããJetpackïŒå¥åã¢ããªã³SDKïŒããããŸã ã ã©ãããŠåœŒãããªãã®ïŒ å人çã«ã¯ãç§ã«ãšã£ãŠã¯ç°¡åã§ãã å€ããå°ãªãã銎æã¿ã®ããã€ã³ã¿ãŒãã§ãŒã¹ãä»ã®APIããããã®ã¯ãæ°ãããã®ïŒãããŠæããã«ãããéå®çãªãã®ïŒãåŠã¶ããããã£ãšç°¡åã§ãã ãŸãããœãŒã¹ã³ãŒãã«ã¯å€ãã®æœè±¡åãå«ãŸããŠãããããããã¥ã¡ã³ãã«åŸã£ãŠã®ã¿æ£åžžã«äœæ¥ã§ããŸãïŒãããŠãé ããªãå ŽåãããããªãŒãã³ãœãŒã¹ã§ãïŒã ããã«ãJetpackã«ã¯è€éãªæ¡åŒµæ©èœã衚瀺ãããªãããšã瀺åãããŠããŸãã ãã ããæ¡åŒµæ©èœãäœæããçµéšããªãå Žåã¯ãããããã¢ããªã³SDKã䜿çšããæ¹ãç°¡åã§ãã
ããããæäœã«æ»ããŸãã
ã¹ã¿ãŒãã¢ããïŒïŒããã³ã·ã£ããããŠã³ïŒïŒé¢æ°ã®ã¿ã䜿çšããŸãã
ååã瀺ãããã«ãæ¡åŒµæ©èœã®èµ·åæã«startupïŒïŒãåŒã³åºãããŸã-ãã©ãŠã¶ãèµ·åããå Žåã§ããã€ã³ã¹ããŒã«/èµ·åããå Žåã§ããçç±ã¯2çªç®ã®åŒæ°ãšããŠæž¡ãããŸãã
ãªã³ã«ãããšãåŠçããå¿ èŠããããŠã£ã³ããŠãæ¢ã«éããŠããå ŽåããããŸãã ãã®ããã«nsIWindowMediator.getEnumeratorïŒïŒãããã䜿çšäŸããããŸã ã
çµæã¯ç°¡åã§ãïŒ
// : Components.utils.import("resource://gre/modules/Services.jsm"); // ... var ws = Services.wm.getEnumerator("navigator:browser"); while(ws.hasMoreElements()) this.initWindow(ws.getNext(), reason);
åæã«ããnavigatorïŒbrowserãã¯ãã¡ã€ã³ãã©ãŠã¶ãŒãŠã£ã³ããŠã®ã«ãŒãããŒãïŒ XULãŠã£ã³ã㊠ïŒã®windowtypeå±æ§ã®å€ã§ãã åãDOMã€ã³ã¹ãã¯ã¿ãŒã䜿çšããŠè¡šç€ºã§ããŸãã
ãããã£ãŠãinitWindowïŒïŒã¯ããŠã£ã³ããŠãžã®ãªã³ã¯ãšã€ã³ã¯ã«ãŒãã®çç±ãåãåããŸãã
ãããããããã¯ãã§ã«éããŠãããŠã£ã³ããŠã«ãããŸãã-æ°ãããŠã£ã³ããŠã®äœæãšæ¢åã®ãŠã£ã³ããŠã®ã¯ããŒãºã远跡ããå¿ èŠããããŸãïŒèªåèªèº«ãã¯ãªãŒã³ã¢ããããŠæŽªæ°Žãèµ·ãããªãããïŒã
ãããè¡ãã«ã¯ã nsIWindowWatcher.registerNotificationïŒïŒã¡ãœããã䜿çšããŸãã
åæã«ã nsIObserverã€ã³ã¿ãŒãã§ãŒã¹ãå®è£ ããé¢æ°ãšãªããžã§ã¯ãã®äž¡æ¹ãã¢ã©ãŒããåä¿¡ã§ããŸãã åŸè ã®æ¹ã䟿å©ã§ããåå空éãªããžã§ã¯ããåç §ããŠãæ£ããthisãååŸããŸãã
ç¹°ãè¿ããŸãããServices.jsmã¢ãžã¥ãŒã«ã䜿çšããŸãã
Services.ww.registerNotification(this);
ããã§ããªããžã§ã¯ãã®observeïŒãµããžã§ã¯ãããããã¯ãããŒã¿ïŒã¡ãœããã¯ããŠã£ã³ããŠã®ãªãŒãã³ïŒãããã¯ã®ãdomwindowopenedãïŒããã³ã¯ããŒãºïŒãdomwindowclosedãïŒã«é¢ããéç¥ãåãåããŸãã
ãã ãããdomwindowopenedãéç¥ãåãåã£ãæç¹ã§ã¯ãwindow.location.hrefãã©ã®ãããªçš®é¡ã®ãŠã£ã³ããŠã§ããããããããŸããããããã£ãŠããŠã£ã³ããŠãããŒãããããŸã§åŸ ã€å¿ èŠããããŸãã
observe: function(subject, topic, data) { if(topic == "domwindowopened") // subject - subject.addEventListener("load", this, false); ...
ããã§ã¯ãããªãã¯ã䜿çšããŠæ£ããthisãäŒããŸããã€ãã³ããªã¹ããŒã¯ã EventListenerã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ãããªããžã§ã¯ãã«ããããšãã§ãããããã€ãã³ããçºçãããšãæž¡ããããªããžã§ã¯ãã®handleEventïŒã€ãã³ãïŒã¡ãœãããåŒã³åºãããŸãã
ãããŠãããŒãããããŠã£ã³ããŠã§ãå Žæãšãå¿ èŠãªãŠã£ã³ããŠã®ã¿ãå埩åŠçããããã«äœ¿çšããã®ãšåãwindowtypeãæ¢ã«èŠã€ããããšãã§ããŸãã
ãããã£ãŠãå¿ èŠãªwindowtype ã§ãŠã£ã³ããŠã®ééãåŠçããŸãã
ãããŠãéãããšãã«ãªã³ã«ããéãããšãã«ãããã«ããã ãã§ãã
ãã®å Žåã è¿œå ããå¿ èŠãããã®ã¯ TabClosââeã€ãã³ããªã¹ããŒã®ã¿ã§ãã
window.addEventListener("TabClose", this, false);
ã€ãã³ããçºçãããšãhandleEventïŒïŒ-> tabClosââeHandlerïŒïŒã¯æ©èœããŸããããã§ã«ã¿ãã䜿çšããŸããã
次ã«ããã©ãŠã¶ãŒããªããåé€ãæŽæ°ããŸãã¯éãããšãshutdownïŒïŒé¢æ°ãåŒã³åºããã windowsObserver.destroyïŒïŒãæ©èœããŸããæ¢ã«éããŠãããã¹ãŠã®ãŠã£ã³ããŠã®åæãšã¢ã©ãŒãã®ç¡å¹åã¯æ¢ã«ããç¥ãããŠããŸãã
ããã§ããã¹ãŠã¯ãšãŠãç°¡åã§ãã å°é£ã¯ãå¥åŠãªãã®ãžã®æ¬²æ±ãçãããšãã«å§ãŸããŸãã ããšãã°ãã«ã¹ã¿ã ãã¿ã³ãè¿œå ããããã®APIããããŸããããã®ããããã¹ãŠã®åèµ·åäžèŠã®æ¡åŒµæ©èœã§å®æçãªãµã€ã¯ãªã³ã°ãå©çšã§ããŸãã
ãããããäž»ãªé£ããã¯ãã°ããŒãã«ãªããžã§ã¯ãããŠã£ã³ããŠã§ã¯ãªãããšã§ãããã®ããããŠã£ã³ããŠãã³ãã©ãŒãäœæããå¿ èŠããããŸãïŒäžèŠèŠãç®ã»ã©æªããã®ã§ã¯ãããŸããããããã¿ã€ãããããŸãïŒã ãåŠçäžã®ã€ãã³ãã®ãªããžã§ã¯ããããŠã£ã³ããŠãååŸããŸãã
ããããããã ãã§ãã ãã®ã¿ã€ãã«ã®ãªãã¹ããªãŒã ãèªããããšãé¡ã£ãŠããŸãã ããããæ®å¿µãªãããèŠåºãã¯çœ®ãããããããŸããã§ãããç§ã¯ããã¹ããèªåã«ä»»ããªããã°ãªããŸããã§ããã