home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 2004 September / APC0409D1.iso / f_looks / files / adblock-0.5-dev.xpi / chrome / adblock.jar / content / adblock.js < prev    next >
Encoding:
JavaScript  |  2004-06-28  |  44.2 KB  |  1,040 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Adblock for Mozilla.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Henrik Aasted Sorensen.
  18.  * Portions created by the Initial Developer are Copyright (C) 2002
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  * Henrik Aasted Sorensen
  23.  * Stefan Kinitz
  24.  * Wladimir Palant
  25.  * rue
  26.  *
  27.  * ***** END LICENSE BLOCK ***** */
  28.  
  29. // Bool: did adblock successfully load (set by adblock.xul) -- global var.
  30. var Loaded;
  31. // Bool: is adblock enabled (set by pref-observer) -- global var.
  32. var Enabled;
  33. // Bool: quickblock background-images (set by pref-observer) -- global var.
  34. var QuickblockBackground;
  35.  
  36. // binary array-search -- returns lowest-matching element if found; false otherwise
  37. // -- Requires a SORTED array
  38. //  -- note: sorting with a compareFunction defines ordering -> return: zero::unchanged, pos::first value, neg::second value
  39. function abBinSearchArray(array, searchItem) {
  40.     var low = 0;
  41.     var high = this.length-1;
  42.     var searchPoint = 0;
  43.     var match = false;
  44.     while ((high-low > 1) && !match) {
  45.         searchPoint = Math.floor((high-low)/2+low);
  46.         if (array[pos] == searchItem)
  47.             match = array[searchPoint];
  48.         else {
  49.             if (searchItem < array[curr]) high = searchPoint;
  50.             else {
  51.                 if (searchItem > array[curr]) low = searchPoint;
  52.             }
  53.         }
  54.     } 
  55.     return match;
  56. }
  57.  
  58.  
  59. // Status element drag-n-drop
  60. var abDrag = function(evt) {
  61.     clearTimeout(window.abDragCleanup);
  62.     if (!adblockStatusDrag.statusbar.abDrag) {
  63.         adblockStatusDrag.statusbar.setAttribute("abdrag", true); // css takes care of stylin'
  64.         adblockStatusDrag.statusbar.abDrag = true; }
  65.     //adblockStatusDrag.showBorders();
  66.     /*window.addEventListener("dragexit", function(evt, session) { 
  67.             if (adblockStatusDrag.statusbar.abDrag)
  68.                 adblockStatusDrag.scheduleCleanup();
  69.         }, true);*/
  70.  
  71.     // these are lost after the drop
  72.     if (!evt.target.dragLoaded) {
  73.         evt.target.dragLoaded = true;
  74.         evt.target.addEventListener("mouseup", function() { setTimeout('adblockStatusDrag.dragCleanup();',5); }, true); }
  75.     
  76.     var modEvt = { originalTarget:evt.originalTarget, target:evt.target, preventBubble:function(){} };
  77.     evt.preventBubble();
  78.     setTimeout(function(modEvt) {nsDragAndDrop.startDrag(modEvt, adblockStatusDrag);}, 50, modEvt);
  79. };
  80. var adblockStatusDrag = {
  81.     load: function() {
  82.         var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
  83.         loader.loadSubScript('chrome://global/content/nsDragAndDrop.js');
  84.         loader.loadSubScript('chrome://global/content/nsTransferable.js');
  85.         dragEnter = function(evt) { nsDragAndDrop.dragEnter(evt, adblockStatusDrag); };
  86.         dragOver = function(evt) { nsDragAndDrop.dragOver(evt, adblockStatusDrag); }; // required for drop
  87.         dragDrop = function(evt) { nsDragAndDrop.drop(evt, adblockStatusDrag); };
  88.         dragExit = function(evt) { nsDragAndDrop.dragExit(evt, adblockStatusDrag); };
  89.         dragCleanup = function() { adblockStatusDrag.dragCleanup(); };
  90.         
  91.         // adblock status-element
  92.         this.status = document.getElementById("adblock-status");
  93.         this.status.addEventListener("draggesture", abDrag, true);
  94.         
  95.         // statusbar
  96.         this.statusbar = document.getElementById("status-bar");
  97.         var child = this.statusbar.firstChild, x = 0, defaultDropArray = new Array();
  98.         while (child) {
  99.             if (child != this.status) {
  100.                 if (!child.id) {
  101.                     var newId = "statusbarpanel-noID"+x;
  102.                     while (document.getElementById(newId)) newId += "x"+x;
  103.                     child.id = newId;
  104.                     child.setAttribute("persist", new String("id" + (child.persist ? " "+child.persist : "")) );
  105.                     x++; }
  106.                 if (child.childNodes.length == 0 && document.getAnonymousNodes(child).length == 0)
  107.                     child.setAttribute("abnochildren", true);
  108.                 child.addEventListener("dragenter", dragEnter, true);
  109.                 child.addEventListener("dragover", dragOver, true);
  110.                 child.addEventListener("dragdrop", dragDrop, true);
  111.                 //child.addEventListener("dragexit", dragExit, true);
  112.             }
  113.             defaultDropArray.unshift(child.id);
  114.             child = child.nextSibling;
  115.         }
  116.         // global
  117.         window.addEventListener("dragexit", dragExit, true);
  118.         return defaultDropArray; // so our load-call (prefObserver) can Right-align against these, by default
  119.     },
  120.  
  121.     /* statusbar drag-notifier */
  122.     onDragStart: function (evt, transferData, action) {
  123.         transferData.data = new TransferData();
  124.         transferData.data.addDataForFlavour("adblock-status-id", this.status.id);
  125.     },
  126.     
  127.     /* statusbar drag-listener */
  128.     getSupportedFlavours: function () {
  129.         var flavours = new FlavourSet();
  130.         flavours.appendFlavour("adblock-status-id");
  131.         return flavours;
  132.     },
  133.     onDragEnter: function(evt, session) { /*"mouseover"*/ 
  134.         if (session.sourceNode == this.status) this.showBorders();
  135.         //logfile(unlimitedListObject(session)); 
  136.     },
  137.     onDragOver: function (evt, flavour, session) { /*"mousemove"*/
  138.         /*evt.target.setAttribute("style", "-moz-outline: #AB0000 dotted 2px !important");*/ 
  139.     },
  140.     xxcanDrop: function(evt, mDragSession) { return true; },
  141.     // whoa- there can be ABSOLUTELY NO DELAYS INLINE: no throw(), alert(), etc.
  142.     onDrop: function (evt, dropdata, session) {
  143.         this.scheduleCleanup();
  144.         var parent = this.statusbar;
  145.         var prev = evt.target;
  146.         while (prev.nodeName.toLowerCase() != "statusbarpanel") prev = prev.parentNode;
  147.         var midPointCoord = prev.boxObject.x + (prev.boxObject.width/2); // the offset + midpoint
  148.         midPointCoord += !prev.previousSibling ? (prev.boxObject.width/4) // + additional quarter-coverage for left-most panel
  149.                 : (!prev.nextSibling ? (-prev.boxObject.width/4) : 0); // - less quarter-coverage for right-most panel
  150.         if (evt.clientX < midPointCoord)
  151.             prev = prev.previousSibling;
  152.         var next = (!prev) ?
  153.                 parent.firstChild : (prev.nextSibling != this.status) ? 
  154.                         prev.nextSibling : prev.nextSibling.nextSibling;
  155.         
  156.         prevString = new Array();
  157.         for (var i=0, children=parent.childNodes; i<children.length && children[i]!=next; i++)
  158.             if (children[i].id && children[i] != this.status
  159.                     && children[i].boxObject.width != 0  // ignore undisplayed elements
  160.                     || children[i].boxObject.x+(0.75*children[i].boxObject.width) > (this.statusbar.boxObject.width/2)) // offset+.75width is over the statusbar midpoint
  161.                 prevString.push(children[i].id);
  162.         
  163.         prevString = prevString.reverse().join(",");
  164.         //adblockPrefObserver.Branch.setCharPref("statusdrop", prevString); // pref-observer will relocate element
  165.         var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  166.         var adblockBranch = "adblock.";
  167.         var Branch = prefService.getBranch(adblockBranch);
  168.         Branch.setCharPref("statusdrop", prevString); // pref-observer will relocate element
  169.         prefService.savePrefFile(null); // save the prefs to disk
  170.     },
  171.     onDragExit: function(evt, session) { /*"mouseout"*/ 
  172.         if (session.sourceNode == this.status) this.scheduleCleanup();
  173.         //logfile(unlimitedListObject(session)); 
  174.     },
  175.     showBorders: function() {
  176.         clearTimeout(window.abDragCleanup);
  177.         if (!this.statusbar.abDrag) {
  178.             this.statusbar.setAttribute("abdrag", true); // css takes care of stylin'
  179.             this.statusbar.abDrag = true; }
  180.     },
  181.     scheduleCleanup: function(evt) {
  182.         clearTimeout(window.abDragCleanup);
  183.         window.abDragCleanup = setTimeout('adblockStatusDrag.dragCleanup();',700);
  184.     },
  185.     dragCleanup: function(debug) {
  186.         this.statusbar.setAttribute("abdrag", false);
  187.         this.statusbar.abDrag = false;
  188.         //setTimeout("throw('exit: "+debug+"');", 0);
  189.     }
  190. };
  191.  
  192.  
  193. // Preferences observer object; implements nsIObserver
  194. var adblockPrefObserver = {
  195.     // Called on window-load
  196.     load: function() {
  197.         window.removeEventListener("load", abLoad, true); // remove startup-check -- only run once
  198.         
  199.         // load component
  200.         if (typeof(Components.classes["@mozilla.org/adblock;1"]) == 'undefined') {
  201.             var appShell = Components.classes["@mozilla.org/appshell/appShellService;1"].getService(Components.interfaces.nsIAppShellService);
  202.             var hiddenWnd = appShell.hiddenDOMWindow;
  203.             //wnd.setTimeout('Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader).loadSubScript("chrome://adblock/content/component.js")', 0);
  204.             Components.classes["@mozilla.org/moz/jssubscript-loader;1"].createInstance(Components.interfaces.mozIJSSubScriptLoader).loadSubScript("chrome://adblock/content/component.js", hiddenWnd);
  205.             Loaded = true; } // we should use an array in the hidden-window to set this when *really* loaded
  206.         else Loaded = true;
  207.  
  208.         var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  209.         observerService.notifyObservers(null, "Adblock-LoadAPIConstants", null); // copy the apiConstants to the hidden-window, in case we loaded from the root-component
  210.  
  211.         window.document.AdblockQuickblocked = false;                                // initialize quickblock tag -- *before* pref-observer
  212.         window.document.addEventListener("popupshown", adblockSetContext, true);     // sets the context-menu items
  213.         window.document.addEventListener("adblock-pageblock", adblockPageBlockListener, true);     // sets the url / uri for pageblocked tabs
  214.         
  215.         // the global arrays for flashblocking -- tracks our overlay divs 
  216.         //  -- some pages don't correctly return these with the 'getElementsByTagName' method
  217.         window.flashblockOverlayArray = new Object(); // the global hash-table of of corresponding flashblock-overlays
  218.         window.flashblockCounter = 0; // global counter for the identifying the flashblock-overlayed browsers -- starts at zero, never looks back -!
  219.  
  220.         var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  221.         this.adblockBranch = "adblock.";
  222.         this.Branch = prefService.getBranch(this.adblockBranch);
  223.         
  224.         this.windowInit = false;
  225.         this.statusElement = null, this.statusText = null;
  226.         this.mainRe =     /^adblock\.(enabled|quickblock|quickblockbackground|statusdrop)/;
  227.  
  228.         var pref = prefService.getBranch(null); // preferences root node
  229.         this.pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  230.         this.pbi.addObserver(this.adblockBranch, this, true); // keep this last, in case we hit an error.
  231.         this.observe(null, null, null);
  232.     },
  233.     
  234.     // nsISupports interface implementation -- for weak-reference by pref-observer service
  235.     QueryInterface: function(iid) {
  236.         if (!iid.equals(Components.interfaces.nsISupports)
  237.                 && !iid.equals(Components.interfaces.nsISupportsWeakReference)
  238.                 && !iid.equals(Components.interfaces.nsIObserver)) {
  239.             dump("Adblock Window Pref-Observer factory object: QI unknown interface: " + iid + "\n");
  240.             throw Components.results.NS_ERROR_NO_INTERFACE; }
  241.         return this;
  242.     },
  243.     
  244.     // removes the observer-object from service -- called when the window is no longer open
  245.     removeObserver: function() {
  246.         this.pbi.removeObserver(this.adblockBranch, this);
  247.         delete this;
  248.     },
  249.     
  250.     // observer-function
  251.     /* subject: [wrapped nsISupports :: nsIPrefBranch], nsIPrefBranchInternal
  252.        topic: "changed"*/
  253.     observe: function(subject, topic, prefName) {
  254.         
  255.         // if we don't have a valid window (closed)
  256.         if ( !(typeof(document) == 'object' && document) ) {
  257.             this.removeObserver(); // remove the observer..
  258.             return; } // ..and don't continue
  259.         
  260.         // on window-init, OR a status-critical pref change
  261.         if (!this.windowInit || this.mainRe.test(prefName)) {
  262.             
  263.             /* Globals and Status-Element */
  264.             // Create status-element pointers
  265.             if (!this.windowInit) {
  266.                 this.statusElement = document.getElementById("adblock-status");
  267.                 this.statusText = document.getAnonymousNodes(this.statusElement)[1];
  268.                 this.defaultDropArray = window.adblockStatusDrag.load(); // load drag-listeners + default right-alignment
  269.             }
  270.             
  271.             // Status drag-insertion
  272.             if (!this.windowInit || prefName == "adblock.statusdrop") {
  273.                 if (this.Branch.prefHasUserValue("statusdrop"))
  274.                     var dropArray = this.Branch.getCharPref("statusdrop").split(",");
  275.                 else dropArray = this.defaultDropArray;
  276.                 //else dropArray = "statusbar-updates,progressmeter-statusbar,statusbarpanel-progress,page-theme-button,page-report-button,security-button,privacy-button,offline-status,popupIcon,statusbar-display,component-bar".split(",");
  277.                 var dropPoint = null;
  278.                 while (dropArray.length>0 && !dropPoint)
  279.                     dropPoint = document.getElementById(dropArray.shift());
  280.                 var parent = this.statusElement.parentNode;
  281.                 var next = (!dropPoint) ? 
  282.                         parent.firstChild : (dropPoint.nextSibling != this.statusElement) ? 
  283.                                 dropPoint.nextSibling : this.statusElement.nextSibling;
  284.                 
  285.                 this.statusElement.removeEventListener("draggesture", abDrag, true);
  286.                 if (next) parent.insertBefore(parent.removeChild(this.statusElement), next);
  287.                 else parent.appendChild(parent.removeChild(this.statusElement));
  288.                 this.statusElement.addEventListener("draggesture", abDrag, true);
  289.                 this.statusElement.dragLoaded = false;
  290.                 
  291.                 this.statusText = document.getAnonymousNodes(this.statusElement)[1]; // element is rebound on insertion
  292.                 if (this.windowInit) this.observe(null, null, "adblock.enabled"); // we have to reload the status-text
  293.             }
  294.             
  295.             // Enabled / Disabled
  296.             if (!this.windowInit || prefName == "adblock.enabled") {
  297.                 Enabled = (!this.Branch.prefHasUserValue("enabled") || this.Branch.getBoolPref("enabled")); // default:true
  298.                 if (!Loaded) { this.statusText.value = "Unloaded"; this.statusElement.setAttribute("status", "unloaded"); }
  299.                 else if (!Enabled) { this.statusText.value = "Disabled"; this.statusElement.setAttribute("status", "notlistening"); }
  300.                 else { this.statusText.value = "Adblock"; this.statusElement.setAttribute("status", "enabled"); } }
  301.     
  302.             // Quickblock
  303.             if (!this.windowInit || prefName == "adblock.quickblock") {
  304.                 if (this.Branch.prefHasUserValue("quickblock") 
  305.                         && this.Branch.getPrefType("quickblock") == Components.interfaces.nsIPrefBranch.PREF_BOOL)
  306.                     var quickLevel = this.Branch.getBoolPref("quickblock") ? "partial" : "off"; // convert old bool-type pref to new
  307.                 else quickLevel = this.Branch.prefHasUserValue("quickblock") ? this.Branch.getCharPref("quickblock") : "partial"; // default:partial
  308.                 this.statusElement.setAttribute("quickblock", quickLevel); 
  309.                 loadQuickblock(quickLevel); }
  310.             
  311.             // QuickblockBackground
  312.             if (!this.windowInit || prefName == "adblock.quickblockbackground")
  313.                 QuickblockBackground = (this.Branch.prefHasUserValue("quickblockbackground") && this.Branch.getBoolPref("quickblockbackground")); // default:false
  314.             
  315.             // window-init
  316.             if (!this.windowInit) {
  317.                 // disable conflicting key-bindings
  318.                 var conflictingKeys, adblockKeys = ["b", "a", "f", "p", "k"];
  319.                 for (var n = 0 ; n < adblockKeys.length ; n++) {
  320.                     conflictingKeys = document.getElementsByAttribute("key", adblockKeys[n]);
  321.                     for (var q = 0 ; q < conflictingKeys.length ; q++)
  322.                         if (!( /adblock/.test(conflictingKeys[q].getAttribute("id")) ) && conflictingKeys[q].hasAttribute("modifiers"))
  323.                             if (/accel/.test(conflictingKeys[q].getAttribute("modifiers")) && /shift/.test(conflictingKeys[q].getAttribute("modifiers")) )
  324.                                 conflictingKeys[q].parentNode.removeChild(conflictingKeys[q]);
  325.                 }
  326.                 
  327.                 // flag as initialized
  328.                 this.windowInit = true;
  329.             }
  330.         }
  331.         
  332.         
  333.     }
  334. };
  335.  
  336. // runs the pref-observer once, by changing a dummy-pref 
  337. //  -- called by the status-element's binding 'onconstruct' (adblock.xml)
  338. function initAdblockPrefObserver() {
  339.     try {
  340.         var prefObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  341.         var Branch = prefObj.getBranch("adblock.");
  342.         var tempPref = (Branch.prefHasUserValue("observer")) ? Branch.getCharPref("observer") : "-"; // default:'-'      :P
  343.  
  344.         switch (tempPref) {
  345.             case "-": 
  346.                 Branch.setCharPref("observer", "*");
  347.                 break;
  348.             case "*":
  349.                 Branch.setCharPref("observer", "-");
  350.                 break;
  351.         }
  352.     } catch(e) {}
  353. }
  354.  
  355. // toggles the adblock-enable pref -- enabling / disabling blocking
  356. function toggleAdblockEnable() {
  357.     if (!Loaded) return;
  358.     var prefObj, Branch;
  359.     
  360.     if (Enabled)
  361.         try {
  362.             prefObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  363.             Branch = prefObj.getBranch("adblock.");
  364.             Branch.setBoolPref("enabled", false);
  365.         } 
  366.         catch(e) { alert("Adblock could not be disabled:\n\n" + e); }
  367.     else
  368.         try {
  369.             prefObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  370.             Branch = prefObj.getBranch("adblock.");
  371.             Branch.setBoolPref("enabled", true);
  372.         } 
  373.         catch(e) { alert("Adblock could not be enabled:\n\n" + e); }
  374. }
  375.  
  376.  
  377. // Checks an element and its children recursively for an attribute.
  378. function adblockFindAttribute(element, name) {
  379.     if (element.hasAttribute(name)) {
  380.         return element.getAttribute(name);
  381.     }
  382.     
  383.     if (element.hasChildNodes()) {
  384.         for (var i = 0 ; i < element.childNodes.length ; i++) {
  385.             var res = adblockFindAttribute(element.childNodes[i], name);
  386.             if (res != false) 
  387.                 return res;
  388.         }
  389.     }
  390.     
  391.     return false; // Didn't find it! 
  392. }
  393.  
  394. // sets the url / uri for pageblocked tabs
  395. function adblockPageBlockListener(evt) {
  396.     var pageElementLocal = evt.target;
  397.     var browsers = window.getBrowser().browsers; // the .getBrowser method resolves tabbed vs. non-tabbed modes -- otherwise, we'd just get .browsers directly
  398.  
  399.     // contentWindow: local window  -  contentDocument: local document
  400.     for (var i = 0, match = false; i < browsers.length &! match; i++) {
  401.         try { if (browsers[i].contentDocument == pageElementLocal.ownerDocument)  match = browsers[i]; } // end loop
  402.         catch(e) {alert("Adblock: unable to access browsers[" + i + "].contentWindow:\n\n" + e);}
  403.     }
  404.     if (!match) return;
  405.     
  406.     //match.webNavigation.stop(Components.interfaces.nsIWebNavigation.STOP_ALL); // no further loading
  407.     var curHistory = match.webNavigation.sessionHistory;
  408.     var blockedURL = pageElementLocal.adblockURI.spec; // the url we blocked
  409.     
  410.     // if a different page was already loaded
  411.     if (curHistory.index == -1 || curHistory.getEntryAtIndex(curHistory.index, false).URI.spec != blockedURL) {
  412.         var ioService = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
  413.         var newEntry = Components.classes['@mozilla.org/browser/session-history-entry;1'].createInstance(Components.interfaces.nsISHEntry);
  414.         var newURI = ioService.newURI(blockedURL, null, null);
  415.         var origIndex = curHistory.index;
  416.         var title = "Adblocked: "+pageElementLocal.adblockURI.host.replace(/^www\./, "");
  417.         newEntry.SetURI(newURI);
  418.         newEntry.SetTitle(title);
  419.         curHistory.QueryInterface(Components.interfaces.nsISHistoryInternal);
  420.         curHistory.addEntry(newEntry, true); // add a history-item for the unblocked-page
  421.         curHistory.index = origIndex++;
  422.         //alert(origIndex+" "+curHistory.index);
  423.         //match.webNavigation.gotoIndex(origIndex+1);
  424.         
  425.         //match.contentDocument.title = "Adblocked: "+title;
  426.     }
  427.     
  428.     //match.currentURI.spec = pageElementLocal.adblockURI.spec; // initialize the blocked-uri, so the urlbar displays proper on tab-switch
  429.     if (match == window.getBrowser().selectedBrowser) gURLBar.value = pageElementLocal.adblockURI.spec; // set the urlbar manually, if this is the current browser
  430. }
  431.  
  432. // sets quickblock pref -- pref-observer catches this
  433. function toggleQuickblockEnable() {
  434.     try {
  435.         var prefObj = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  436.         var Branch = prefObj.getBranch("adblock.");
  437.     } catch(e) { alert("Quickblock could not be toggled:\n\n" + e); return; }
  438.     
  439.     if (Branch.prefHasUserValue("quickblock") 
  440.             && Branch.getPrefType("quickblock") == Components.interfaces.nsIPrefBranch.PREF_BOOL) {
  441.         var quickLevel = Branch.getBoolPref("quickblock") ? "partial" : "off"; // convert old bool-type pref to new
  442.         Branch.deleteBranch("quickblock"); }
  443.     else quickLevel = Branch.prefHasUserValue("quickblock") ? Branch.getCharPref("quickblock") : "partial"; // default:partial
  444.     
  445.     var nextLevel;
  446.     switch (quickLevel) {
  447.         case "off": 
  448.             nextLevel = "partial"; 
  449.             break;
  450.         case "partial": 
  451.             nextLevel = "full"; 
  452.             break;
  453.         case "full": 
  454.             nextLevel = "off"; 
  455.             break; 
  456.     }
  457.     Branch.setCharPref("quickblock", nextLevel); // set the pref
  458. }
  459.  
  460. // loads appropriate level of quickblock -- called by pref-observer
  461. function loadQuickblock(quickLevel) {
  462.  
  463.     switch (quickLevel) {
  464.         case "full":
  465.             if (typeof(window._Quickblock) != 'undefined') break; // the listeners are already attached, from 'partial'
  466.         case "partial":
  467.             window.document.addEventListener("dblclick", adblockQuickblock, true); // disable link-clicks..
  468.             window.document.addEventListener("click", adblockQuickblock, true); // ..and again
  469.             window.document.addEventListener("mousedown", adblockQuickblock, true); // quickblock listener
  470.             break
  471.         case "off":
  472.             window.document.removeEventListener("mousedown", adblockQuickblock, true); // remove listener
  473.             window.document.removeEventListener("click", adblockQuickblock, true);
  474.             window.document.removeEventListener("dblclick", adblockQuickblock, true);
  475.             try{ 
  476.                 window.document.removeEventListener("mousemove", adblockQuickblock, true);
  477.                 window.document.removeEventListener("mouseup", adblockQuickblock, true);
  478.             } catch(e) {}
  479.             break;
  480.     }
  481.  
  482.     window._Quickblock = quickLevel; // store the level, so quickblock-listeners know what to do
  483. }
  484.  
  485. // intercepts mouse-clicks and hides the dom-elements beneath
  486. function adblockQuickblock(evt) {
  487.     var evType = evt.type, evButton = evt.button, evShift = evt.shiftKey, evCount = evt.detail;
  488.     var fullBlock = (window._Quickblock == "full") ? true : false; // bool: trap single-clicks too?
  489.     var item = evt.originalTarget;
  490.     var itemContainer = evt.target;
  491.     var deepItem = evt.explicitOriginalTarget;
  492.     var deepReplacement, deepStyle, itemTag, tagRe;
  493.     
  494.     // if quickdrag is ending (mouseup), or the event is new (mouse left the window-area while dragging)
  495.     //   ..disable quickdrag and return
  496.     if (window._Quickdrag && (evType == "mouseup" || evType == "mousedown" || (evType == "mousemove" &! evShift))) {
  497.         delete window._Quickdrag;
  498.         window.document.removeEventListener("mousemove", adblockQuickblock, true);
  499.         window.document.removeEventListener("mouseup", adblockQuickblock, true);
  500.         return;
  501.     }
  502.     
  503.     // from here on, only shifted / non-form-submission events matter -- evCount registers at max for form-submission keypresses
  504.     if (!evShift || (evType == "click" && evCount > 3)) 
  505.         return; 
  506.     
  507.     // if this is a webpage-element -- for now, all xul-elements remain unblocked (because of window-scrollbars)
  508.     if ((item != itemContainer) && (item.ownerDocument.baseURI) && (item.prefix != "xul")) {
  509.     
  510.         // if we shift-(double)clicked ( +~ drag)
  511.         if ( ((evType == "dblclick" || (evType == "click" && fullBlock) || (evType == "mousedown" && (evCount > 1 || fullBlock) ))  
  512.                 && evButton == 0)
  513.                 || evType == "mousemove" || evType == "mouseup") {
  514.             evt.preventDefault(); // prevents tripping the context-menu
  515.             evt.stopPropagation(); // prevents launching hyperlinks
  516.             evt.preventBubble(); // ditto ?
  517.             evt.preventCapture(); // double-ditto ?
  518.             
  519.             // if we didn't doubleclick
  520.             if ((evType == "click" || evType == "mousedown") && evCount < 2)
  521.                 return;
  522.     
  523.             if (evType == "mouseup") {
  524.                 window.document.removeEventListener("mousemove", adblockQuickblock, true);
  525.                 window.document.removeEventListener("mouseup", adblockQuickblock, true);
  526.                 return; } // ignore further movement, after cancelling
  527.             
  528.             if (evType != "click" && evType != "dblclick") {
  529.                 if (evType == "mousedown" &! window.Quickdrag) { // if quickdrag isn't activated, make it so
  530.                     window._Quickdrag = true;
  531.                     window.document.addEventListener("mousemove", adblockQuickblock, true);
  532.                     window.document.addEventListener("mouseup", adblockQuickblock, true);
  533.                 }
  534.                 
  535.                 if (item.tagName) itemTag = item.tagName.toLowerCase();
  536.                 else itemTag = item.nodeName.toLowerCase();
  537.                 
  538.                 // background-image removal
  539.                 if (QuickblockBackground) adblockQuickBackground(item, itemTag);
  540.                 
  541.                 // element hiding
  542.                 adblockQuickElement(deepItem, item, itemTag);
  543.             }
  544.         }
  545.  
  546.     }
  547. }
  548.  
  549. // removes background-images from an element and all parent-table elements above it
  550. //  -- for quickblock
  551. function adblockQuickBackground(item, itemTag) {
  552.     var itemTest, tableItem, tableItemLast, tableChildRe, tableRe;
  553.     var parentNode1 = false, parentNode2 = false, parentNode3 = false;
  554.     var domDocNode = Components.interfaces.nsIDOMNode.DOCUMENT_NODE;
  555.  
  556.     tableChildRe = /td|tr/;
  557.     itemTest = tableChildRe.test(itemTag);
  558.     if (!itemTest && item.parentNode) { // failed; if there's a parent
  559.         /*
  560.         parentNode1 = tableChildRe.test(item.parentNode);
  561.         if (!parentNode1 && item.parentNode.parentNode) { // failed; if there's a grandparent
  562.             parentNode2 = tableChildRe.test(item.parentNode.parentNode);
  563.             if (!parentNode2 && item.parentNode.parentNode.parentNode)
  564.                 parentNode3 = tableChildRe.test(item.parentNode.parentNode.parentNode); //failed; if there's a great-grandparent
  565.         }
  566.         */
  567.     }
  568.     if ((itemTest || parentNode1 || parentNode2 || parentNode3) && (item.nodeType != domDocNode)) {
  569.         tableItemLast = item, tableItem = item;
  570.         tableRe = new RegExp("table");
  571.         while ( ! tableRe.test(tableItemLast.nodeName.toLowerCase())) { // crawl to the tabletop :P
  572.             //tableItem.setAttribute("QuickblockTableBackground", document.defaultView.getComputedStyle(tableItem, null).getPropertyValue("background-image"));
  573.             tableItem.style.setProperty("background-image", "none", "important"); // kill parent-tableitem's background-image
  574.             if (tableItem.hasAttribute("background")) tableItem.removeAttribute("background");
  575.             if (!tableItem.parentNode || tableItem.parentNode.nodeType == domDocNode) break;
  576.             tableItemLast = tableItem, tableItem = tableItem.parentNode;
  577.         }
  578.         // kill parent-table's parent-container background-image (*whew*)
  579.         tableItem.style.setProperty("background-image", "none", "important"); 
  580.         if (tableItem.hasAttribute("background")) tableItem.removeAttribute("background");
  581.     }
  582.     else {
  583.         //if (document.defaultView.getComputedStyle(item, null).backgroundImage != "none") // <- fails
  584.         item.style.setProperty("background-image", "none", "important"); // kill parent-table-container's background-image
  585.         if (item.hasAttribute("background")) item.removeAttribute("background");
  586.     }
  587. }
  588.  
  589. // quick-hides an element
  590. function adblockQuickElement(deepItem, item, itemTag) {
  591.     var tagRe;
  592.     
  593.     if (itemTag == "area") {
  594.         disableMapArea(item); // let adblock handle area-maps..
  595.         return; // ..don't continue
  596.     }
  597.     tagRe = new RegExp("table|tbody|tr|td|div|span|form|body|html|ul|ol|dl"); // ,"i" to make case-insensitive -- removed for speed
  598.     if ( ! tagRe.test(itemTag)) { // don't hide block elements..
  599.             item.style.visibility = "hidden";
  600.     }
  601.     else { // ..rather, hide what they contain                
  602.         if (item != deepItem) { // if there's a deeper node (usually text)
  603.             if (deepItem.setAttribute) {
  604.                 deepItem.style.visibility = "hidden"; // hide directly, if possible                
  605.             }
  606.             else // text has no setAttribute-method..
  607.                 deepItem.parentNode.style.setProperty("visibility", "hidden", "important"); // ..so hide the parent
  608.         }
  609.     }
  610. }
  611.  
  612. // toggles the object-override -- ("flashblocking")
  613. function toggleObjectOverride() {
  614.     var selectedPage = document.getElementById("content").selectedBrowser;
  615.     var page = document.getElementById("content").contentDocument;
  616.     var pageElement = page.documentElement;
  617.     var flashblockPosition;
  618.     
  619.     if (typeof(page.oncontextmenu) != 'undefined') delete page.oncontextmenu; // <- thehulk.com :P
  620.     
  621.     if (pageElement) {
  622.         if (pageElement.hasAttribute("AdblockFlashblocked")) {
  623.             objectRemoveOverride(page); // removes all overrides registered in the global array
  624.             flashblockPosition = pageElement.getAttribute("flashblockPosition");
  625.             delete flashblockOverlayArray[flashblockPosition]; // remove our entry from global flashblock hashtable
  626.             pageElement.removeAttribute("flashblockPosition");
  627.             delete page.onunload;
  628.             pageElement.removeAttribute("AdblockFlashblocked");
  629.         }
  630.         else {
  631.             pageElement.setAttribute("AdblockFlashblocked", true); // tags the page as "flashblocked" :)
  632.             page.onunload = "objectRemoveOverride(this)"; // unloads flashblock on page-close -- so the global hashtable doesn't fill up
  633.             flashblockPosition = new String("smooth" + flashblockCounter); // converts the unique-index to a string for our hashtable
  634.             flashblockCounter++; // increment the unique-index counter -- to keep it unique
  635.             flashblockOverlayArray[flashblockPosition] = new Array(); // initializes the global flashblock overlay array
  636.             pageElement.setAttribute("flashblockPosition", flashblockPosition); // stores the array-position in the document-element
  637.             objCheckFrames(page, "override"); // checks frames -- adds the overrides
  638.         }
  639.     }
  640.     else 
  641.         return; // no documentElement == no flashblock
  642. }
  643.  
  644.  
  645. // catches all frames / iframes for object-overriding -- requires a page/element
  646. function objCheckFrames(page, conditional) {
  647.     var itemFrames = page.getElementsByTagName("frame");
  648.     var itemiFrames = page.getElementsByTagName("iframe");
  649.     var frame, iframe;
  650.     
  651.     if (itemFrames.length > 0)    
  652.         for (var f = 0 ; f < itemFrames.length ; f++) {
  653.             frame = itemFrames[f].contentDocument;
  654.             objCheckFrames(frame, conditional); // recursion for frames
  655.         }
  656.  
  657.     if (itemiFrames.length > 0)
  658.         for (var g = 0 ; g < itemiFrames.length ; g++) {
  659.             iframe = itemiFrames[g].contentDocument;
  660.             objCheckFrames(iframe, conditional); // recursion for iframes
  661.         }
  662.         
  663.     // if we have a valid page, override it
  664.     if (page.hasChildNodes() && page.defaultView)
  665.         switch (conditional) {
  666.             case "override":
  667.                 //alert("overriding");
  668.                 objectOverride(page); // check the page itself
  669.                 break;
  670.             /* // DEPRECATED: this whole switch is unneeded now
  671.             case "remove":
  672.                 //alert("removing");
  673.                 objectRemoveOverride(page);
  674.                 break;
  675.             */
  676.         }
  677. }
  678.  
  679. // overlays all object's / embeds with a configurable div -- requires a page/element
  680. //  -- overrides their "native" menus
  681. function objectOverride(page) {
  682.     var rawObjects = page.getElementsByTagName("object");
  683.     var objects = new Array();
  684.     var objectEmbeds = new Array();
  685.     var rawEmbeds = page.getElementsByTagName("embed");
  686.     var embeds = new Array();
  687.     var applets = page.getElementsByTagName("applet");
  688.     var possibleTags = ["objects", "object-embeds", "embeds", "applets"];
  689.     var itemArray = new Array();
  690.     var childDiv, childDivTitle;
  691.     var childTable, childTableRow, childTableData, childSpan;
  692.     var x, y;
  693.     var currentOffset, topmostFrame, flashblockPosition;
  694.     
  695.     // if we're in a frame/iframe, we'll need to get the flashblockPosition from our base document
  696.     if (page.defaultView.frameElement) {
  697.         topmostFrame = page.defaultView.frameElement;
  698.         // break out of nested frames/iframes
  699.         while (topmostFrame.ownerDocument.defaultView.frameElement)
  700.             topmostFrame = topmostFrame.ownerDocument.defaultView.frameElement;
  701.         flashblockPosition = topmostFrame.ownerDocument.documentElement.getAttribute("flashblockPosition");
  702.     }
  703.     else flashblockPosition = page.documentElement.getAttribute("flashblockPosition");
  704.     
  705.             
  706.     // for each object, get its child-embed (if it has one), since only this carries correct width / height attributes
  707.     for (var t = 0; t < rawObjects.length ; t++) {
  708.         var children = rawObjects[t].getElementsByTagName("embed");
  709.         if (children.length > 0)
  710.             for (var c = 0; c < children.length; c++)
  711.                 objectEmbeds.push(children[c]); // add child to our embed-array
  712.         else
  713.             objects.push(rawObjects[t]); // assume it's blockable if there's no child-embed
  714.     }
  715.     
  716.     // check that our embed-list doesn't contain duplicates of *OBJECT-embeds* -- (we *should* just 'pop' the array, yo)
  717.     for (var s = 0; s < rawEmbeds.length ; s++) {
  718.         // fail-safe check for parentnode -- shouldn't ever fail
  719.         if (rawEmbeds[s].parentNode)
  720.             if (rawEmbeds[s].parentNode.tagName.toLowerCase() != "object")
  721.                 embeds.push(rawEmbeds[s]); // add any non-Object-embeds to our "accepted" array
  722.     }
  723.     
  724.     // creates and adds the div-overlays for objects and raw-embeds
  725.     for (var u = 0 ; u < possibleTags.length ; u++) {
  726.         
  727.         switch (possibleTags[u]) {
  728.             case "objects":
  729.                 itemArray = objects;
  730.                 childDivTitle = "AdblockObjectDiv";
  731.                 break;
  732.             case "object-embeds":
  733.                 itemArray = objectEmbeds;
  734.                 childDivTitle = "AdblockObjectDiv";
  735.                 break;
  736.             case "embeds":
  737.                 itemArray = embeds;
  738.                 childDivTitle = "AdblockEmbedDiv";
  739.                 break;
  740.             case "applets":
  741.                 itemArray = applets;
  742.                 childDivTitle = "AdblockAppletDiv";
  743.                 break;
  744.         }
  745.         
  746.         for (var w = 0 ; w < itemArray.length; w++)
  747.             if (itemArray[w] != null && itemArray[w].style.display != "none" && itemArray[w].style.visibility != "hidden") {
  748.                 x = itemArray[w].offsetLeft;
  749.                 y = itemArray[w].offsetTop;
  750.         
  751.                 // if the item is contained by parent elements, add their position in too
  752.                 currentOffset = itemArray[w];
  753.                 while (currentOffset.offsetParent) {
  754.                     x += currentOffset.offsetParent.offsetLeft;
  755.                     y += currentOffset.offsetParent.offsetTop;
  756.                     currentOffset = currentOffset.offsetParent; // increment the conditional, for while-loop
  757.                 }
  758.                                 
  759.                 if (itemArray[w].previousSibling && itemArray[w].previousSibling.attributes
  760.                             && (
  761.                                 itemArray[w].previousSibling.hasAttribute("AdblockObjectDiv") || 
  762.                                 itemArray[w].previousSibling.hasAttribute("AdblockEmbedDiv")  ||
  763.                                 itemArray[w].previousSibling.hasAttribute("AdblockAppletDiv")
  764.                             ) 
  765.                         )
  766.                         childDiv = itemArray[w].previousSibling; // we already had an overlay-div
  767.                     else {
  768.                         childDiv = page.createElement("div"); // create our div-overlay
  769.                         childDiv.innerHTML = '<table style="width: 100%; height: 100%;"><tr valign="middle"><td ' + childDivTitle + '="true"><span  ' + childDivTitle + '="true" style="display: block; text-align: center; vertical-align: middle; background-color: #FFFFFF; color: #777788; font-family: Arial, Helvetica, Sans-serif; font-size: large; font-style: italic; font-variant: small-caps; border-color: #000099; border-width: 2pt 0pt 2pt 0pt; border-style: dashed none dashed none; padding: 2pt 0pt 2pt 0pt; overflow: hidden; clip: rect(auto auto auto auto); xtext-overflow: elipsis; width: 100%;">Flashblock</span></td></tr></table>';
  770.                         childDiv.setAttribute("width", itemArray[w].offsetWidth + "px");
  771.                         childDiv.setAttribute("height", itemArray[w].offsetHeight + "px");
  772.                         childDiv.setAttribute("style", "display: block; overflow: hidden; text-overflow: elipsis; background-color: #FFDFBF; border-color: #999999; border-width: 1px; border-style: solid; position: absolute; width: " + itemArray[w].offsetWidth + "px; height: " + itemArray[w].offsetHeight + "px; left: " + x + "px; top: " + y + "px; z-index: 900; visibility: visible;");
  773.                         childDiv.setAttribute(childDivTitle, true);
  774.                         childDiv.addEventListener("click", onOverlayClick, true);
  775.                         /* 
  776.                          * we're now dealing with child-embeds individually
  777.                          */
  778.                         itemArray[w].style.visibility = "hidden"; // hide the embedded item
  779.                         itemArray[w].parentNode.insertBefore(childDiv, itemArray[w]); // append our overlay
  780.                         flashblockOverlayArray[flashblockPosition].push(childDiv); // the global pointer, so we can remove *all* overlays later -- stupid abcnews.com
  781.                         itemArray[w]._AdblockOverlay = childDiv;
  782.                     }
  783.             }
  784.     }
  785. }
  786.  
  787.  
  788. // removes the div-overlay for all objects / embeds
  789. function objectRemoveOverride(page) {
  790.     var flashblockPosition;
  791.     var divOverlays;
  792.     var flashblockedItem;
  793.     var parentNode;
  794.     
  795.     // if we're in a frame/iframe, we'll need to get the flashblockPosition from our base document
  796.     if (page.defaultView.frameElement) {
  797.         var topmostFrame = page.defaultView.frameElement;
  798.         while (topmostFrame.ownerDocument.defaultView.frameElement)
  799.             topmostFrame = topmostFrame.ownerDocument.defaultView.frameElement;
  800.         flashblockPosition = topmostFrame.ownerDocument.documentElement.getAttribute("flashblockPosition");
  801.     }
  802.     else flashblockPosition = page.documentElement.getAttribute("flashblockPosition");
  803.     
  804.     divOverlays = flashblockOverlayArray[flashblockPosition];
  805.  
  806.     for (var u = 0 ; u < divOverlays.length ; u++) {
  807.         if (divOverlays[u].parentNode) parentNode = divOverlays[u].parentNode;
  808.         else parentNode = divOverlays[u].ownerDocument;
  809.         flashblockedItem = divOverlays[u].nextSibling;
  810.         parentNode.removeChild(divOverlays[u]); // <- don't remove until *after* we get it's 'nextSibling' -- duh!
  811.         flashblockedItem.style.visibility = "visible";
  812.     }
  813. }
  814.  
  815. // Event handler, Flashblock-Overlay has been clicked
  816. function onOverlayClick(event) {
  817.     var target = event.target;
  818.     
  819.     // break out of the overlay and get our target
  820.     while (target.nodeName.toLowerCase() != "div")
  821.         target = target.parentNode;
  822.     target = target.nextSibling;
  823.  
  824.     itemFilterDialog(false, target);
  825. }
  826.  
  827.  
  828. // reveals context menu-items as needed
  829. function adblockSetContext(evt) {
  830.     if (evt.target.id != "contentAreaContextMenu") return;
  831.  
  832.     var target = gContextMenu.target;
  833.     //var menuSeparator = document.getElementById("adblock-separator-menuitem");
  834.     //var propertyMenuItem = document.getElementById("context-metadata"); // 'Properties' element-id under mozilla 1.3.1
  835.     var frameFilter = document.getElementById("adblock-iframe-menuitem");
  836.     var frameLevel = 0;
  837.     
  838.     // iframe depth-counter
  839.     var topmostFrame = target.ownerDocument.defaultView.frameElement;
  840.     if (topmostFrame)
  841.         if (topmostFrame.nodeName.toLowerCase() == "iframe") {
  842.             frameLevel = 1; // depth-counter -- begins with current
  843.             while (topmostFrame.ownerDocument.defaultView.frameElement) {
  844.                 topmostFrame = topmostFrame.ownerDocument.defaultView.frameElement;
  845.                 if (topmostFrame.tagName.toLowerCase() == "iframe")
  846.                     frameLevel++; // only for iframes, increment the counter -- we crawl up all frames
  847.             }
  848.             if (frameLevel > 1) frameFilter.label = "Adblock iFrame (" + frameLevel + " deep)";
  849.             else frameFilter.label = "Adblock iFrame";
  850.         }
  851.     
  852.     // reveal relevant item(s)    
  853.     gContextMenu.showItem('adblock-iframe-menuitem', (frameLevel > 0));
  854.     gContextMenu.showItem('adblock-image-menuitem', (target.nodeName.toLowerCase() == "img"));
  855.     gContextMenu.showItem('adblock-maparea-menuitem', (target.nodeName.toLowerCase() == "area"));
  856.     gContextMenu.showItem('adblock-object-menuitem', (target.hasAttribute && target.hasAttribute("AdblockObjectDiv") ));
  857.     gContextMenu.showItem('adblock-embed-menuitem', (target.hasAttribute && target.hasAttribute("AdblockEmbedDiv") ));
  858.     gContextMenu.showItem('adblock-applet-menuitem', (target.hasAttribute && target.hasAttribute("AdblockAppletDiv") ));
  859.     
  860. }
  861.  
  862.  
  863. // disables a map-area, so we can click on the content beneath it
  864. function disableMapArea(areaItem) {
  865.     if (!areaItem) areaItem = gContextMenu.target;
  866.     
  867.     areaItem.setAttribute("AdblockDisabled", true);
  868.     
  869.     if (areaItem.hasAttribute("coords")) {
  870.         areaItem.setAttribute("AdblockCoords", areaItem.getAttribute("coords"));
  871.         areaItem.removeAttribute("coords");
  872.     }
  873.     //areaItem.style.display = "none"; // UNNEEDED: this has the side-effect of hiding items underneath -- removing the 'coords' is enough
  874. }
  875.  
  876. // get the target node for an overlay
  877. function getOverlayTarget(target) {
  878.     while (target.nodeName.toLowerCase() != "div")
  879.         target = target.parentNode;
  880.     target = target.nextSibling;
  881.     return target;
  882. }
  883.  
  884. // pops a filter dialog on right-click
  885. function itemFilterDialog(isFrame, targetNode) {
  886.     if (typeof(targetNode) != 'undefined' && targetNode) var node = targetNode;
  887.     else node = gContextMenu.target;
  888.     // if the target is a frame / iframe
  889.     if (typeof(isFrame) != 'undefined' && isFrame)
  890.         node = node.ownerDocument.defaultView.frameElement;
  891.     var page = node.ownerDocument; // -ownerDocument -! (ps: iframes don't register a parentNode from within them)
  892.     var data = node._AdblockData;
  893.  
  894.     // passes the target item to the dialogue via window.argument[1] -- allows the item to be refiltered on 'accept'
  895.     var dialogHandle = window.openDialog("chrome://adblock/content/addfilterdialog.xul","Add filter", "chrome,modal,centerscreen", data[0].spec, node);
  896. }
  897.  
  898. // pops a filter window for "All Block-able Items.."
  899. function filterAllDialog(filterAll) {
  900.     var currentPageElement = document.getElementById("content").contentDocument.defaultView.top;
  901.     var flashblocked = document.getElementById("content").contentDocument.documentElement.hasAttribute("AdblockFlashblocked");
  902.  
  903.     // passes the root-Element to the dialogue via window.argument[0] -- allows page to be refiltered on 'accept'
  904.     //var filterAllWindow = window.open("chrome://adblock/content/filterall.xul", "adblockableItems", "chrome,centerscreen,resizable", currentPageElement);
  905.     //filterAllWindow.focus();
  906.     window.openDialog("chrome://adblock/content/filterall.xul", "adblockableItems", "chrome,centerscreen,resizable", currentPageElement);
  907. }
  908.  
  909.  
  910. // Open the settings window.
  911. function adblockSettings() {
  912.     var settingsHandle = window.open("chrome://adblock/content/settings.xul", "adblockPreferences", "chrome,resizable,centerscreen,close=no");
  913.     settingsHandle.focus();
  914. }
  915.  
  916.  
  917.  
  918.     
  919. /*
  920.        Open flags 
  921.        #define PR_RDONLY       0x01
  922.        #define PR_WRONLY       0x02
  923.        #define PR_RDWR         0x04
  924.        #define PR_CREATE_FILE  0x08
  925.        #define PR_APPEND       0x10
  926.        #define PR_TRUNCATE     0x20
  927.        #define PR_SYNC         0x40
  928.        #define PR_EXCL         0x80
  929.     
  930.     ** File modes ....
  931.     **
  932.     ** CAVEAT: 'mode' is currently only applicable on UNIX platforms.
  933.     ** The 'mode' argument may be ignored by PR_Open on other platforms.
  934.     **
  935.     **   00400   Read by owner.
  936.     **   00200   Write by owner.
  937.     **   00100   Execute (search if a directory) by owner.
  938.     **   00040   Read by group.
  939.     **   00020   Write by group.
  940.     **   00010   Execute by group.
  941.     **   00004   Read by others.
  942.     **   00002   Write by others
  943.     **   00001   Execute by others.
  944.     **
  945.     
  946.     //init the output stream with realistic options.  420 are the file
  947.     //options.. .funny huh!  
  948.         outputStream.init( file, 0x04 | 0x08, 420, 0 );
  949.  
  950. */
  951.  
  952.  
  953. /*
  954.  * Debug-routines
  955.  */
  956.  
  957. // status message
  958. function debugmsg(str) { window.defaultStatus=str; }
  959.  
  960. // lists everything in an object -- Useful debug-function.
  961. function listObject(obj, s) {
  962.     var res = "List: " + obj + "\n";
  963.     for(var list in obj) {        
  964.         if (list.indexOf(s) != -1)
  965.             res += list + ", ";
  966.     }
  967.         
  968.     alert(res); }
  969.  
  970. // lists items in an object, 
  971. function invListObject(obj, s) {
  972.     var res = "List: " + obj + "\n";
  973.     for(var list in obj) {        
  974.         if (list.indexOf(s) == -1)
  975.             res += list + ", ";
  976.     }
  977.         
  978.     alert(res); }
  979.  
  980. // basic alerts
  981. function alertMsg1(eventX) { alert("1 :: event: " + eventX); }
  982. function alertMsg2(eventX) { alert("2 :: event: " + eventX); }
  983.  
  984. // lists everything in an object -- unlimited
  985. function unlimitedListObject(obj) {
  986.     var res = "List: " + obj + "\n\n";
  987.     for(var list in obj)    
  988.         res += list + ": " + eval("obj."+list) + "\n"; //+ " -- " + (eval("obj."+list))?(eval("obj."+list+".nodeName")):null + "\n";
  989.         
  990.     return res + "--\n\n";
  991. }
  992.  
  993. // appends a given string to unique 'logfile.txt'
  994. function logfile(logString) {
  995.     var streamOut = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
  996.     var dirService = Components.classes['@mozilla.org/file/directory_service;1'].getService(Components.interfaces.nsIProperties);
  997.     var logFile = dirService.get("UChrm", Components.interfaces.nsIFile);// lxr.mozilla.org/seamonkey/source/xpcom/io/nsAppDirectoryServiceDefs.h
  998.     logFile.append("logfile.txt"); // "appends" the file-string to our dir file-obj
  999.     logFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666); // uniquely name file
  1000.     
  1001.     // if the file is writable, append logString
  1002.     if (logFile.isWritable()) {
  1003.         streamOut.init(logFile, 0x02, 0x200, null);
  1004.         //streamOut.flush();
  1005.         streamOut.write(logString, logString.length);
  1006.         streamOut.close(); }
  1007. }
  1008.  
  1009. // Creates a text-listing for an item's nested node structure, n-layers deep -- very useful debug tool
  1010. function listChildNodesX(itemN, depthX) {
  1011.     if (!itemN.hasChildNodes) return null;
  1012.     if (itemN.hasChildNodes()) {
  1013.     
  1014.         var itemlengthN = itemN.childNodes.length
  1015.         var prefixcharsX = '- - ';
  1016.         var prefixstringX = ' ';
  1017.         var cnodesL = ' ';
  1018.         
  1019.         // if this is our first recursion-call, 'depthX' wont be an array yet
  1020.         if (!depthX[1])
  1021.             depthX = [0, depthX]; // define iteration counter and recursion limit
  1022.  
  1023.         // sets appropriate indentation, multiplying the prefix-string by our current depth
  1024.         for (var v = 0 ; v < depthX[0] ; v++)
  1025.             prefixstringX += prefixcharsX;
  1026.         
  1027.         cnodesL += ' :' + itemlengthN + '\n'; // prints the number of childnodes for this depth
  1028.         
  1029.         for (var w = 0 ; w < itemlengthN ; w++) {
  1030.             cnodesL += prefixstringX + w + '. ' + itemN.childNodes.item(w);
  1031.             if (itemN.childNodes.item(w).hasChildNodes()) {
  1032.                 if (depthX[0] < depthX[1]) {
  1033.                     depthX[0]++;
  1034.                     cnodesL += listChildNodesX(itemN.childNodes.item(w), depthX); }
  1035.             }
  1036.             else cnodesL += '\n';
  1037.         }
  1038.     }
  1039.     return cnodesL;
  1040. }