~ubuntu-branches/ubuntu/hardy/foxyproxy/hardy-updates

« back to all changes in this revision

Viewing changes to components/foxyproxy.js

  • Committer: Bazaar Package Importer
  • Author(s): Sasa Bodiroza
  • Date: 2008-04-09 13:55:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080409135500-x7u28czocbidxpmg
Tags: 2.7.2-0ubuntu1
* New upstream release. (LP: #212875)
* Improved packaging to make use of xpi.mk
* debian/control: 
  - Updated Maintainer field according to DebianMaintainerField spec
  - s/IceWeasel/Firefox/ in description
* debian/copyright: 
  - Updated copyright years
  - Updated packaging copyright
  - Added notice about xpi.mk packaging
  - Getting the source differs for this upload, added notice
* install.rdf: Bumped maxVersion to 3.0.*

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
2
  FoxyProxy
3
 
  Copyright (C) 2006, 2007 Eric H. Jung and LeahScape, Inc.
 
3
  Copyright (C) 2006-2008 Eric H. Jung and LeahScape, Inc.
4
4
  http://foxyproxy.mozdev.org/
5
5
  eric.jung@yahoo.com
6
6
 
7
7
  This source code is released under the GPL license,
8
8
  available in the LICENSE file at the root of this installation
9
9
  and also online at http://www.gnu.org/licenses/gpl.txt
10
 
All Rights Reserved. U.S. PATENT PENDING.
11
10
**/
12
11
 
13
12
// See http://forums.mozillazine.org/viewtopic.php?t=308369
14
13
 
15
14
// Don't const the next line anymore because of the generic reg code
16
15
var CI = Components.interfaces, CC = Components.classes, CR = Components.results, gFP;
17
 
    
 
16
 
 
17
// Get attribute from node if it exists, otherwise return |def|.
 
18
// No exceptions, no errors, no null returns.
18
19
const gGetSafeAttr = function(n, name, def) {
19
20
        return n ? (n.hasAttribute(name) ? n.getAttribute(name) : def) : def;
20
21
};
 
22
// Boolean version of GetSafe
21
23
const gGetSafeAttrB = function(n, name, def) {
22
24
        return n ? (n.hasAttribute(name) ? n.getAttribute(name)=="true" : def) : def;
23
25
};
28
30
  gObsSvc = CC["@mozilla.org/observer-service;1"].getService(CI.nsIObserverService),
29
31
        gBroadcast = function(subj, topic, data) {
30
32
    var bool = CC["@mozilla.org/supports-PRBool;1"].createInstance(CI.nsISupportsPRBool);
31
 
                bool.data = subj;               
 
33
                bool.data = subj;
32
34
                var d;
33
35
                if (typeof(data) == "string") {
34
36
            var d = CC["@mozilla.org/supports-string;1"].createInstance(CI.nsISupportsString);
37
39
          else {
38
40
                data && (d = data.QueryInterface(CI.nsISupports));
39
41
          }
40
 
          gObsSvc.notifyObservers(bool, topic, d);    
41
 
        };
42
 
        
 
42
          gObsSvc.notifyObservers(bool, topic, d);
 
43
};
 
44
const exceptionSchemes = ['feed'];
 
45
 
 
46
var self;
 
47
var fileProtocolHandler = CC["@mozilla.org/network/protocol;1?name=file"].createInstance(CI["nsIFileProtocolHandler"]);
 
48
if ("undefined" != typeof(__LOCATION__)) {
 
49
  // preferred way
 
50
  self = __LOCATION__;
 
51
}
 
52
else {
 
53
  self = fileProtocolHandler.getFileFromURLSpec(Components.Exception().filename);
 
54
}
 
55
var dir = self.parent; // the directory this file is in
 
56
var loader = CC["@mozilla.org/moz/jssubscript-loader;1"].createInstance(CI["mozIJSSubScriptLoader"]);
 
57
try {
 
58
  var filePath = dir.clone();
 
59
  filePath.append("superadd.js");
 
60
  loader.loadSubScript(fileProtocolHandler.getURLSpecFromFile(filePath));
 
61
}
 
62
catch (e) {
 
63
  dump("Error loading superadd.js\n");
 
64
  throw(e);
 
65
}
 
66
 
43
67
// l is for lulu...
44
68
function foxyproxy() {this.wrappedJSObject = this;}
45
69
 
46
70
foxyproxy.prototype = {
47
71
        PFF : " ",
48
 
  _mode : "patterns",
 
72
  _mode : "disabled",
49
73
  _selectedProxy : null,
50
74
  _selectedTabIndex : 0,
51
75
  _proxyDNS : false,
52
76
  _initialized : false,
53
77
  _toolsMenu : true,
54
 
  _contextMenu : true, 
 
78
  _contextMenu : true,
55
79
  _toolsMenuNode : null,
56
80
  _contextMenuNode : null,
57
81
  _advancedMenus : false,
 
82
  _previousMode : "patterns",
58
83
  autoadd : null,
59
84
  quickadd : null,
60
 
  
 
85
 
61
86
        QueryInterface: function(aIID) {
62
 
                if(!aIID.equals(CI.nsISupports) && !aIID.equals(CI.nsIObserver) && !aIID.equals(CI.nsISupportsWeakReference))
63
 
                        throw CR.NS_ERROR_NO_INTERFACE;                 
 
87
                if(!aIID.equals(CI.nsISupports) && !aIID.equals(CI.nsIObserver) && !aIID.equals(CI.nsISupportsWeakReference)) {
 
88
                        throw CR.NS_ERROR_NO_INTERFACE;
 
89
          }
64
90
                return this;
65
91
        },
66
 
        
67
 
        __registration: function() {
68
 
                return ({topics: ["app-startup", "xpcom-shutdown"],
69
 
                        observerName: "foxyproxy_catobserver",
70
 
                  contractId: "@leahscape.org/foxyproxy/service;1",
71
 
                        classId: Components.ID("{46466e13-16ab-4565-9924-20aac4d98c82}"),
72
 
                        constructor: foxyproxy,
73
 
                        className: "FoxyProxy Core"});
74
 
        },              
75
92
 
76
93
        observe: function(subj, topic, data) {
77
94
                switch(topic) {
78
95
                        case "app-startup":
79
 
                                gObsSvc.addObserver(this, "quit-application", false);                           
 
96
                                gObsSvc.addObserver(this, "quit-application", false);
80
97
                                gObsSvc.addObserver(this, "domwindowclosed", false);
81
98
                                //gObsSvc.addObserver(this, "http-on-modify-request", false);
82
99
                                this._loadStrings();
83
100
                                break;
84
 
                        case "domwindowclosed":   
 
101
                        case "domwindowclosed":
85
102
                          // Did the last browser window close? It could be that the DOM inspector, JS console,
86
103
                          // or the non-last browser window just closed. In that case, don't close FoxyProxy.
87
104
                    var wm = CC["@mozilla.org/appshell/window-mediator;1"].getService(CI.nsIWindowMediator);
88
 
                    var win = wm.getMostRecentWindow("navigator:browser");
89
 
                    if (!win) {                                           
 
105
                    var win = wm.getMostRecentWindow("navigator:browser") || wm.getMostRecentWindow("Songbird:Main");
 
106
                    if (!win) {
90
107
                                  this.closeAppWindows("foxyproxy", wm);
91
108
                                  this.closeAppWindows("foxyproxy-quickadd", wm);
92
109
                                  this.closeAppWindows("foxyproxy-options", wm);
100
117
                        //case "http-on-modify-request":
101
118
                                //dump("subj: " + aSubject + "\n");
102
119
                                //dump("topic: " + aTopic + "\n");
103
 
                                //dump(" data: " + aData + "\n");                               
 
120
                                //dump(" data: " + aData + "\n");
104
121
                                //var hChannel = subj.QueryInterface(Components.interfaces.nsIHttpChannel);
105
122
                                //var tab = this.moo(hChannel);
106
123
//                              if (!tab) dump("tab not found for " + hChannel.name + "\n");
107
124
                                //dump("tab " + (tab?"found":"not found") + "\n");
108
 
                                //break;                                                        
 
125
                                //break;
109
126
/*
110
127
biesi>  what you could actually do is this:
111
128
        <biesi> observe http-on-modify-request
116
133
        <grimholtz>     ok but how does the response get into the right window?
117
134
        <biesi> ah right
118
135
        <biesi> forgot to mention that part
119
 
        <biesi> with help of nsIURILoader::openURI*/                                    
120
 
                          
 
136
        <biesi> with help of nsIURILoader::openURI*/
 
137
 
121
138
                }
122
139
        },
123
140
 
125
142
          var req = CC["@mozilla.org/xmlextras/xmlhttprequest;1"].
126
143
            createInstance(CI.nsIXMLHttpRequest);
127
144
          req.open("GET", "chrome://foxyproxy/content/strings.xml", false);
128
 
          req.send(null);  
129
 
          this.strings._entities = new Array();      
 
145
          req.send(null);
 
146
          this.strings._entities = new Array();
130
147
          for (var i=0,e=req.responseXML.getElementsByTagName("i18n"); i<e.length; i++)  {
131
148
            var attrs = e.item(i).attributes;
132
149
            this.strings._entities[attrs.getNamedItem("id").nodeValue] = attrs.getNamedItem("value").nodeValue;
133
150
          }
134
151
        },
135
 
        
136
 
        closeAppWindows: function(type, wm) {   
 
152
 
 
153
        closeAppWindows: function(type, wm) {
137
154
                var wm = CC["@mozilla.org/appshell/window-mediator;1"].getService(CI.nsIWindowMediator);
138
155
                var e = wm.getEnumerator(type);
139
156
    while (e.hasMoreElements()) {
140
157
        e.getNext().close();
141
158
    }
142
159
        },
143
 
                
 
160
 
144
161
        init : function() {
145
162
          if (!this._initialized) {
146
163
            this._initialized = true; // because @mozilla.org/file/directory_service;1 isn't available in init()
147
164
            gFP = this;
148
165
 
149
 
                this.autoadd = new SuperAdd("autoadd");
150
 
                  this.quickadd = new QuickAdd("quickadd");   
151
 
                this.autoadd.init(this.getMessage("autoadd.pattern.label"), this);                
 
166
                this.autoadd = new SuperAdd();
 
167
                  this.quickadd = new QuickAdd();
 
168
                this.autoadd.init(this.getMessage("autoadd.pattern.label"), this);
152
169
                  this.quickadd.init(this.getMessage("quickadd.pattern.label"), this);
153
 
                                                            
 
170
 
154
171
      var req = CC["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(CI.nsIXMLHttpRequest);
155
172
      var settingsURI = this.getSettingsURI("uri-string");
156
 
      req.open("GET", settingsURI, false); 
 
173
      req.open("GET", settingsURI, false);
157
174
      req.send(null);
158
 
      var doc = req.responseXML, docElem = doc.documentElement;
159
 
      if (docElem.nodeName == "parsererror") {
160
 
        this.alert(null, this.getMessage("settings.error"));
161
 
        // TODO: prompt user to overwrite?
 
175
      var doc = req.responseXML;
 
176
      if (!doc || doc.documentElement.nodeName == "parsererror") {
 
177
        this.alert(null, this.getMessage("settings.error.2", [settingsURI, settingsURI]));
162
178
        this.writeSettings(settingsURI);
163
179
      }
164
180
      else
165
 
        this.fromDOM(doc, docElem);
166
 
                
 
181
        this.fromDOM(doc, doc.documentElement);
 
182
 
167
183
            /*
168
184
                        <menu id="foxyproxy-context-menu-1" label="&foxyproxy.label;"
169
 
                      tooltiptext="&foxyproxy.tooltip;" accesskey="&foxyproxy.accesskey;" class="menu-iconic foxyproxybutton-small"> 
 
185
                      tooltiptext="&foxyproxy.tooltip;" accesskey="&foxyproxy.accesskey;" class="menu-iconic foxyproxybutton-small">
170
186
                      <menupopup id="foxyproxy-contextmenu-popup"
171
187
                          onpopupshowing="foxyproxy.onPopupShowing(this, event);"
172
188
                          onpopuphiding="foxyproxy.onPopupHiding();"/>
173
 
                    </menu>         
 
189
                    </menu>
174
190
            */
175
191
 
176
 
                        var doc = CC["@mozilla.org/xml/xml-document;1"].createInstance(CI.nsIDOMDocument);          
 
192
                        var doc = CC["@mozilla.org/xml/xml-document;1"].createInstance(CI.nsIDOMDocument);
177
193
            this._contextMenuNode = doc.createElement("menu");
178
 
            this._contextMenuNode.setAttribute("id", "foxyproxy-context-menu-1");           
179
 
            this._contextMenuNode.setAttribute("label", "&foxyproxy.label;");               
180
 
            this._contextMenuNode.setAttribute("tooltiptext", "&foxyproxy.tooltip;");               
181
 
            this._contextMenuNode.setAttribute("accesskey", "&foxyproxy.accesskey;");                       
182
 
            this._contextMenuNode.setAttribute("class", "menu-iconic foxyproxybutton-small");                    
 
194
            this._contextMenuNode.setAttribute("id", "foxyproxy-context-menu-1");
 
195
            this._contextMenuNode.setAttribute("label", "&foxyproxy.label;");
 
196
            this._contextMenuNode.setAttribute("tooltiptext", "&foxyproxy.tooltip;");
 
197
            this._contextMenuNode.setAttribute("accesskey", "&foxyproxy.accesskey;");
 
198
            this._contextMenuNode.setAttribute("class", "menu-iconic foxyproxybutton-small");
183
199
            var menupopup2 = doc.createElement("menupopup");
184
200
            menupopup2.setAttribute("id", "foxyproxy-contextmenu-popup");
185
 
            menupopup2.setAttribute("onpopupshowing", "foxyproxy.onPopupShowing(this, event);");            
186
 
            menupopup2.setAttribute("onpopuphiding", "foxyproxy.onPopupHiding();");         
187
 
            this._contextMenuNode.appendChild(menupopup2);                  
 
201
            menupopup2.setAttribute("onpopupshowing", "foxyproxy.onPopupShowing(this, event);");
 
202
            menupopup2.setAttribute("onpopuphiding", "foxyproxy.onPopupHiding();");
 
203
            this._contextMenuNode.appendChild(menupopup2);
188
204
    }
189
205
        },
190
206
 
191
207
        get contextMenuNode() {
192
208
                return this._contextMenuNode.cloneNode(true);
193
 
        },      
 
209
        },
194
210
 
195
211
  get mode() { return this._mode; },
196
212
  setMode : function(mode, writeSettings, init) {
197
 
          // Possible modes are: patterns, _proxy_id_ (for "Use proxy xyz for all URLs), random, roundrobin, disabled  
 
213
          // Possible modes are: patterns, _proxy_id_ (for "Use proxy xyz for all URLs), random, roundrobin, disabled, previous.
 
214
    // Note that "previous" isn't used anywhere but this method: it is translated into the previous mode then broadcasted.
 
215
    if (mode == "previous") {
 
216
      if (this.mode == "disabled")
 
217
        mode = this.previousMode;
 
218
      else
 
219
        mode = "disabled";
 
220
    }
 
221
    this._previousMode = this.mode;
 
222
    this._mode = mode;
198
223
          this._selectedProxy = null; // todo: really shouldn't do this in case something tries to load right after this instruction
199
224
    for (var i=0,len=this.proxies.length; i<len; i++) {
200
 
      if (mode == this.proxies.item(i).id) {
201
 
        this._selectedProxy = this.proxies.item(i);        
202
 
        this.proxies.item(i).enabled = true; // ensure it's enabled
 
225
      var proxy = this.proxies.item(i);
 
226
      if (mode == proxy.id) {
 
227
        this._selectedProxy = proxy;
 
228
        proxy.enabled = true; // ensure it's enabled
203
229
      }
204
 
                this.proxies.item(i).handleTimer();     // Leave this after "this.proxies.item(i).enabled = true" !
 
230
                proxy.handleTimer();    // Leave this after "proxy.enabled = true" !
 
231
                proxy.shouldLoadPAC() && proxy.autoconf.loadPAC();
205
232
    }
206
 
    this._mode = mode;
207
233
    this.toggleFilter(mode != "disabled");
208
 
    if (init) return;    
 
234
    mode=="disabled" && this.loadDefaultPAC();
 
235
    if (init) return;
209
236
    writeSettings && this.writeSettings();
210
237
          gBroadcast(this.autoadd._enabled, "foxyproxy-mode-change", this._mode);
211
238
  },
212
239
 
 
240
  loadDefaultPAC : function() {
 
241
    // User has disabled FoxyProxy, so Firefox network.proxy.* preferences will be used.
 
242
    // If Firefox is configured to use a PAC file, we need to force that PAC file to load.
 
243
    // Firefox won't load it automatically except on startup and after
 
244
    // network.proxy.autoconfig_retry_* seconds. Rather than make the user wait for that,
 
245
    //  we load the PAC file now.
 
246
    var networkPrefs = this.getPrefsService("network.proxy."), usingPAC;
 
247
    try {
 
248
      usingPAC = networkPrefs.getIntPref("type") == 2; // isn't there a const for this?
 
249
    }
 
250
    catch(e) {
 
251
      dump("FoxyProxy: network.proxy.type doesn't exist or can't be read\n");
 
252
    }
 
253
    if (usingPAC) {
 
254
      // Don't use nsPIProtocolProxyService. From its comments: "[nsPIProtocolProxyService] exists purely as a
 
255
      // hack to support the configureFromPAC method used by the preference panels in the various apps. Those
 
256
      // apps need to be taught to just use the preferences API to "reload" the PAC file. Then, at that point,
 
257
      // we can eliminate this interface completely."
 
258
 
 
259
      // var pacURL = networkPrefs.getCharPref("autoconfig_url");
 
260
      // var pps = Components.classes["@mozilla.org/network/protocol-proxy-service;1"]
 
261
        //.getService(Components.interfaces.nsPIProtocolProxyService);
 
262
      // pps.configureFromPAC(pacURL);
 
263
 
 
264
      // Instead, change the prefs--the proxy service is observing and will reload the PAC
 
265
      networkPrefs.setIntPref("type", 1);
 
266
      networkPrefs.setIntPref("type", 2);
 
267
    }
 
268
  },
 
269
 
213
270
  /**
214
271
   * This assumes mode order is:
215
272
   * patterns, proxy1, ..., lastresort, random, roundrobin, disabled
221
278
                }
222
279
                else if (this._mode == "disabled") {
223
280
                        this.setMode("patterns", true);
224
 
                }               
 
281
                }
225
282
                else if (this._mode == "patterns") {
226
283
                        var p = this.proxies.item(0);
227
284
                        (!p || !p.enabled || !p.includeInCycle) && (p = _getNextInCycle(this.proxies.item(0).id));
228
 
                        this.setMode(p?p.id:"disabled", true);                  
 
285
                        this.setMode(p?p.id:"disabled", true);
229
286
                }
230
 
                else {  
 
287
                else {
231
288
                        var p = _getNextInCycle(this._mode);
232
289
                        this.setMode(p?p.id:"disabled", true);
233
290
                }
234
291
                function _getNextInCycle(start) {
235
292
                        for (var p=self.proxies.getNextById(start); p && !p.includeInCycle; p = self.proxies.getNextById(p.id));
236
 
                        return p;               
 
293
                        return p;
237
294
                }
238
295
        },
239
 
        
 
296
 
240
297
  toggleFilter : function(enabled) {
241
298
    var ps = CC["@mozilla.org/network/protocol-proxy-service;1"]
242
299
      .getService(CI.nsIProtocolProxyService);
243
300
    ps.unregisterFilter(this); // safety - always remove first
244
301
    enabled && ps.registerFilter(this, 0);
245
 
  },  
 
302
  },
246
303
 
247
304
  applyFilter : function(ps, uri, proxy) {
248
 
  
249
305
        function _err(fp, info, extInfo) {
250
306
                var def = fp.proxies.item(fp.proxies.length-1);
251
307
      mp = gMatchingProxyFactory(def, null, spec, "err", extInfo?extInfo:info);
252
 
                        fp.notifier.alert(info, fp.getMessage("see.log"));      
253
 
            return def; // Failsafe: use lastresort proxy if nothing else was chosen    
 
308
                        fp.notifier.alert(info, fp.getMessage("see.log"));
 
309
            return def; // Failsafe: use lastresort proxy if nothing else was chosen
254
310
        }
255
 
        
 
311
 
256
312
    try {
 
313
      if (exceptionSchemes[uri.scheme]) return;
257
314
        var spec = uri.spec;
258
315
      var mp = this.applyMode(spec);
259
316
      var ret = mp.proxy.getProxy(spec, uri.host, mp);
260
317
      return ret ? ret : _err(this, this.getMessage("route.error"));
261
318
    }
262
319
    catch (e) {
263
 
      dump("applyFilter: " + e + "\n");   
 
320
      dump("applyFilter: " + e + "\n");
264
321
      return _err(this, this.getMessage("route.exception", [""]), this.getMessage("route.exception", [": " + e]));
265
322
    }
266
323
    finally {
267
 
                        gObsSvc.notifyObservers(mp.proxy, "foxyproxy-throb", null);        
268
 
            this.logg.add(mp);                
 
324
                        gObsSvc.notifyObservers(mp.proxy, "foxyproxy-throb", null);
 
325
            this.logg.add(mp);
269
326
    }
270
 
  },    
271
 
  
 
327
  },
 
328
 
272
329
        getPrefsService : function(str) {
273
330
    return CC["@mozilla.org/preferences-service;1"].
274
331
      getService(CI.nsIPrefService).getBranch(str);
275
332
  },
276
 
  
 
333
 
277
334
  // Returns settings URI in desired form
278
335
  getSettingsURI : function(type) {
279
336
    var o = null;
280
337
    try {
281
338
      o = this.getPrefsService("extensions.foxyproxy.").getCharPref("settings");
282
339
    }
283
 
    catch(e) {}
 
340
    catch(e) {
 
341
      dump("FoxyProxy: Unable to read preference extensions.foxyproxy.settings in getSettingsURI(). Checking for new installation.\n");
 
342
      try {
 
343
            // The first time FP runs, "firstrun" does not exist (i.e., null || false). Subsequent times, "firstrun" == true.
 
344
            // In other words, this pref is improperly named for its purpose. Better name is "notfirstrun".      
 
345
        var f = this.getPrefsService("extensions.foxyproxy.").getBoolPref("firstrun");
 
346
        if (f != null) {
 
347
          this.alert(null, this.getMessage("preferences.read.error.warning", ["extensions.foxyproxy.settings", "getSettingsURI()"]) + " " + 
 
348
            this.getMessage("preferences.read.error.fatal"));
 
349
        }
 
350
      }
 
351
      catch(ex) {}      
 
352
    }
284
353
    if (o) {
285
354
      o == this.PFF && (o = this.getDefaultPath());
286
355
      var file = this.transformer(o, CI.nsIFile);
287
 
      // Does it exist?      
 
356
      // Does it exist?
288
357
      if (!file.exists()) {
289
358
        this.writeSettings(file);
290
359
      }
301
370
    try {
302
371
          this.writeSettings(o2);
303
372
          // Only update the preference if writeSettings() succeeded
304
 
      this.getPrefsService("extensions.foxyproxy.").setCharPref("settings", o==this.PFF ? this.PFF : o2);         
 
373
      this.getPrefsService("extensions.foxyproxy.").setCharPref("settings", o==this.PFF ? this.PFF : o2);
305
374
    }
306
375
    catch(e) {
307
376
      this.alert(this, this.getMessage("error") + ":\n\n" + e);
309
378
    return o==this.PFF ? this.PFF : o2;
310
379
  },
311
380
 
312
 
  isUsingPFF : function() {
313
 
    return this.getPrefsService("extensions.foxyproxy.").getCharPref("settings") == this.PFF;
314
 
  },
315
 
  
316
 
  
317
381
  alert : function(wnd, str) {
318
382
    CC["@mozilla.org/embedcomp/prompt-service;1"].getService(CI.nsIPromptService)
319
383
      .alert(null, this.getMessage("foxyproxy"), str);
320
 
  },  
 
384
  },
321
385
 
322
386
  getDefaultPath : function() {
323
387
    var file = CC["@mozilla.org/file/local;1"].createInstance(CI.nsILocalFile);
324
388
    var dir = CC["@mozilla.org/file/directory_service;1"].getService(CI.nsIProperties).get("ProfD", CI.nsILocalFile);
325
389
    file.initWithPath(dir.path);
326
 
    file.appendRelativePath("foxyproxy.xml"); 
327
 
    return file; 
 
390
    file.appendRelativePath("foxyproxy.xml");
 
391
    return file;
328
392
  },
329
393
 
330
394
  // Convert |o| from:
343
407
    const handler = CC["@mozilla.org/network/io-service;1"].
344
408
              getService(CI.nsIIOService).getProtocolHandler("file").
345
409
              QueryInterface(CI.nsIFileProtocolHandler);
346
 
    
 
410
 
347
411
    switch(desiredType) {
348
412
      case "uri-string":
349
413
        switch(typeof(o)) {
363
427
          case "object":
364
428
            if (o instanceof CI.nsIFile) return o.path;
365
429
            if (o instanceof CI.nsIURI) return handler.getFileFromURLSpec(o.spec).path;
366
 
            return null; // unknown type                                
 
430
            return null; // unknown type
367
431
        }
368
432
      case CI.nsIFile:
369
433
        switch(typeof(o)) {
373
437
          case "object":
374
438
            if (o instanceof CI.nsIFile) return o;
375
439
            if (o instanceof CI.nsIURI) return handler.getFileFromURLSpec(o.spec);
376
 
            return null; // unknown type            
 
440
            return null; // unknown type
377
441
        }
378
442
      case CI.nsIURI:
379
443
        var ios = CC["@mozilla.org/network/io-service;1"].getService(CI.nsIIOService);
384
448
          case "object":
385
449
            if (o instanceof CI.nsIFile) return handler.newFileURI(o);
386
450
            if (o instanceof CI.nsIURI) return o;
387
 
            return null; // unknown type          
 
451
            return null; // unknown type
388
452
        }
389
453
    }
390
 
        
 
454
 
391
455
  },
392
 
    // Create nsIFile from a string
 
456
 
 
457
  // Create nsIFile from a string
393
458
  createFile : function(str) {
394
459
    var f = CC["@mozilla.org/file/local;1"].createInstance(CI.nsILocalFile);
395
460
    f.initWithPath(str);
396
461
    return f;
397
462
  },
398
 
  
 
463
 
399
464
  writeSettings : function(o) {
400
 
    !o && (o = gFP.getPrefsService("extensions.foxyproxy.").getCharPref("settings"));
401
 
    o = gFP.transformer(o, CI.nsIFile);
402
 
    var foStream = CC["@mozilla.org/network/file-output-stream;1"].
403
 
      createInstance(CI.nsIFileOutputStream);
404
 
    foStream.init(o, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
405
 
    foStream.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", 39);
406
 
    CC["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(CI.nsIDOMSerializer)
407
 
      .serializeToStream(gFP.toDOM(), foStream, "UTF-8");    
408
 
    //foStream.write(str, str.length);
409
 
    foStream.close();  
 
465
    /*try {
 
466
      throw new Error("e");
 
467
    }
 
468
    catch (e) {dump (e.stack + "\n");}*/
 
469
    if (!o) {
 
470
      try {
 
471
        o = gFP.getPrefsService("extensions.foxyproxy.").getCharPref("settings");
 
472
      }
 
473
      catch(e) {
 
474
        this.alert(null, this.getMessage("preferences.read.error.warning", ["extensions.foxyproxy.settings", "writeSettings()"]));
 
475
        o = this.getDefaultPath();
 
476
      }
 
477
    }
 
478
    try {
 
479
      var o2 = gFP.transformer(o, CI.nsIFile);
 
480
      var foStream = CC["@mozilla.org/network/file-output-stream;1"].
 
481
        createInstance(CI.nsIFileOutputStream);
 
482
      foStream.init(o2, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
 
483
      foStream.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", 39);
 
484
      CC["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(CI.nsIDOMSerializer)
 
485
        .serializeToStream(gFP.toDOM(), foStream, "UTF-8");
 
486
      //foStream.write(str, str.length);
 
487
      foStream.close();
 
488
    }
 
489
    catch(ex) {
 
490
      this.alert(null, this.getMessage("settings.error.3", [o]));    
 
491
    }
410
492
  },
411
 
  
 
493
 
412
494
  get proxyDNS() { return this._proxyDNS; },
413
495
  set proxyDNS(p) {
414
496
    this._proxyDNS = p;
430
512
  get toolsMenu() { return this._toolsMenu; },
431
513
  set toolsMenu(e) {
432
514
    this._toolsMenu = e;
433
 
                gBroadcast(e, "foxyproxy-toolsmenu");  
 
515
                gBroadcast(e, "foxyproxy-toolsmenu");
434
516
    this.writeSettings();
435
 
  },   
 
517
  },
436
518
 
437
519
  get contextMenu() { return this._contextMenu; },
438
520
  set contextMenu(e) {
440
522
                gBroadcast(e, "foxyproxy-contextmenu");
441
523
    this.writeSettings();
442
524
  },
443
 
  
 
525
 
444
526
  get advancedMenus() { return this._advancedMenus; },
445
527
  set advancedMenus(i) {
446
528
    this._advancedMenus = i;
447
529
    this.writeSettings();
448
530
  },
449
 
      
 
531
 
 
532
  get previousMode() { return this._previousMode; },
 
533
  set previousMode(p) {
 
534
    this._previousMode = p;
 
535
    this.writeSettings();
 
536
  },
 
537
 
450
538
  /**
451
539
   * Return a MatchingProxy instance.
452
540
   */
453
541
  applyMode : function(spec) {
454
542
    var matchingProxy;
455
543
    switch (this.mode) {
456
 
      case "random":   
 
544
      case "random":
457
545
                                //matchingProxy = this.proxies.getRandom(spec, this.random._includeDirect, this.random._includeDisabled);
458
546
        //break;
459
 
      case "patterns":     
 
547
      case "patterns":
460
548
              matchingProxy = this.proxies.getMatches(spec);
461
549
        break;
462
 
                        case "roundrobin":         
 
550
                        case "roundrobin":
463
551
                                break;
464
 
      default:   
465
 
              matchingProxy = gMatchingProxyFactory(this._selectedProxy, null, spec, "ded");      
 
552
      default:
 
553
              matchingProxy = gMatchingProxyFactory(this._selectedProxy, null, spec, "ded");
466
554
        break;
467
555
    }
468
556
    return matchingProxy;
469
557
  },
470
 
  
 
558
 
471
559
  restart : function() {
472
560
                CC["@mozilla.org/toolkit/app-startup;1"].getService(CI.nsIAppStartup)
473
561
                .quit(CI.nsIAppStartup.eForceQuit|CI.nsIAppStartup.eRestart);
475
563
 
476
564
        fromDOM : function(doc, node) {
477
565
                this.statusbar.fromDOM(doc);
478
 
                this.toolbar.fromDOM(doc);              
479
 
                this.logg.fromDOM(doc); 
480
 
                this._proxyDNS = node.getAttribute("proxyDNS") == "true";
481
 
                this._toolsMenu = node.hasAttribute("toolsMenu") ?
482
 
                        node.getAttribute("toolsMenu") == "true" : true; // new for 2.0                         
483
 
                this._contextMenu = node.hasAttribute("contextMenu") ?
484
 
                        node.getAttribute("contextMenu") == "true" : true; // new for 2.0
485
 
                this._advancedMenus = node.hasAttribute("advancedMenus") ?
486
 
                        node.getAttribute("advancedMenus") == "true" : false; // new for 2.3--default to false if it doesn't exist
487
 
                                                
488
 
                this._selectedTabIndex = node.getAttribute("selectedTabIndex") || "0";
489
 
                this.proxies.fromDOM(doc, this);      
490
 
                this.setMode(node.hasAttribute("enabledState") ?
491
 
                        (node.getAttribute("enabledState") == "" ? "patterns" : node.getAttribute("enabledState")) :
492
 
                        node.getAttribute("mode"), false, true); // renamed to mode in 2.0
 
566
                this.toolbar.fromDOM(doc);
 
567
                this.logg.fromDOM(doc);
 
568
                this._proxyDNS = gGetSafeAttrB(node, "proxyDNS", false);
 
569
                this._toolsMenu = gGetSafeAttrB(node, "toolsMenu", true); // new for 2.0
 
570
                this._contextMenu = gGetSafeAttrB(node, "contextMenu", true); // new for 2.0
 
571
                this._advancedMenus = gGetSafeAttrB(node, "advancedMenus", false); // new for 2.3--default to false if it doesn't exist
 
572
                this._selectedTabIndex = gGetSafeAttr(node, "selectedTabIndex", "0");
 
573
                var mode = node.hasAttribute("enabledState") ?
 
574
                        (node.getAttribute("enabledState") == "" ? "disabled" : node.getAttribute("enabledState")) :
 
575
                        node.getAttribute("mode"); // renamed to mode in 2.0
 
576
        this._previousMode = gGetSafeAttr(node, "previousMode", "patterns");
 
577
                this.proxies.fromDOM(mode, doc, this);
 
578
                this.setMode(mode, false, true);
493
579
                this.random.fromDOM(doc, this);
494
 
    this.autoadd.fromDOM(doc);  
495
 
    this.quickadd.fromDOM(doc); 
 
580
    this.autoadd.fromDOM(doc);
 
581
    this.quickadd.fromDOM(doc);
496
582
    this.warnings.fromDOM(doc);
497
583
        },
498
 
        
 
584
 
499
585
        toDOM : function() {
500
 
                var doc = CC["@mozilla.org/xml/xml-document;1"].createInstance(CI.nsIDOMDocument);      
501
 
    var e = doc.createElement("foxyproxy");    
 
586
                var doc = CC["@mozilla.org/xml/xml-document;1"].createInstance(CI.nsIDOMDocument);
 
587
    var e = doc.createElement("foxyproxy");
502
588
    e.setAttribute("mode", this._mode);
503
589
    e.setAttribute("selectedTabIndex", this._selectedTabIndex);
504
590
    e.setAttribute("proxyDNS", this._proxyDNS);
505
 
    e.setAttribute("toolsMenu", this._toolsMenu);    
506
 
    e.setAttribute("contextMenu", this._contextMenu);   
507
 
    e.setAttribute("advancedMenus", this._advancedMenus);        
508
 
    e.appendChild(this.random.toDOM(doc));   
 
591
    e.setAttribute("toolsMenu", this._toolsMenu);
 
592
    e.setAttribute("contextMenu", this._contextMenu);
 
593
    e.setAttribute("advancedMenus", this._advancedMenus);
 
594
    e.setAttribute("previousMode", this._previousMode);
 
595
    e.appendChild(this.random.toDOM(doc));
509
596
    e.appendChild(this.statusbar.toDOM(doc));
510
 
    e.appendChild(this.toolbar.toDOM(doc));    
 
597
    e.appendChild(this.toolbar.toDOM(doc));
511
598
    e.appendChild(this.logg.toDOM(doc));
512
 
    e.appendChild(this.warnings.toDOM(doc));       
513
 
    e.appendChild(this.autoadd.toDOM(doc));  
514
 
    e.appendChild(this.quickadd.toDOM(doc));     
515
 
    e.appendChild(this.proxies.toDOM(doc));       
 
599
    e.appendChild(this.warnings.toDOM(doc));
 
600
    e.appendChild(this.autoadd.toDOM(doc));
 
601
    e.appendChild(this.quickadd.toDOM(doc));
 
602
    e.appendChild(this.proxies.toDOM(doc));
516
603
    return e;
517
 
        },  
518
 
        
519
 
  
 
604
        },
 
605
 
 
606
 
520
607
  ///////////////// random \\\\\\\\\\\\\\\\\\\\\\
521
 
        
 
608
 
522
609
        random : {
523
610
        _includeDirect : false,
524
 
        _includeDisabled : false,       
 
611
        _includeDisabled : false,
525
612
 
526
613
          get includeeDirect() { return this._includeDirect; },
527
614
          set includeeDirect(e) {
528
615
            this._includeDirect = e;
529
616
            gFP.writeSettings();
530
 
          },    
 
617
          },
531
618
 
532
619
          get includeDisabled() { return this._includeDisabled; },
533
620
          set includeDisabled(e) {
534
621
            this._includeDisabled = e;
535
622
            gFP.writeSettings();
536
623
          },
537
 
        
 
624
 
538
625
                toDOM : function(doc) {
539
626
                        var e = doc.createElement("random");
540
 
                        e.setAttribute("includeDirect", this._includeDirect);           
541
 
                        e.setAttribute("includeDisabled", this._includeDisabled);                               
 
627
                        e.setAttribute("includeDirect", this._includeDirect);
 
628
                        e.setAttribute("includeDisabled", this._includeDisabled);
542
629
                  return e;
543
630
                },
544
 
                
 
631
 
545
632
                fromDOM : function(doc) {
546
633
      var node = doc.getElementsByTagName("random")[0];
547
634
      if (node) { // because this is new for 2.0
548
635
        this._includeDirect = node.getAttribute("includeDirect") == "true";
549
 
        this._includeDisabled = node.getAttribute("includeDisabled") == "true";         
 
636
        this._includeDisabled = node.getAttribute("includeDisabled") == "true";
550
637
                        }
551
638
                }
552
639
        },
553
 
        
 
640
 
554
641
  ///////////////// proxies \\\\\\\\\\\\\\\\\\\\\\
555
642
 
556
643
  proxies : {
572
659
    get length() {
573
660
      return this.list.length;
574
661
    },
575
 
    
 
662
 
576
663
    getProxyById : function(id) {
577
664
      var a = this.list.filter(function(e) {return e.id == this;}, id);
578
665
      return a?a[0]:null;
579
666
    },
580
 
    
 
667
 
581
668
    getIndexById : function(id) {
582
669
        var len=this.length;
583
670
        for (var i=0; i<len; i++) {
585
672
        }
586
673
        return -1;
587
674
    },
588
 
        
589
 
    fromDOM : function(doc, fp) {
 
675
 
 
676
    fromDOM : function(mode, doc, fp) {
590
677
      var last = null;
591
678
      for (var i=0,proxyElems=doc.getElementsByTagName("proxy"); i<proxyElems.length; i++) {
592
679
        var p = CC["@leahscape.org/foxyproxy/proxy;1"].createInstance(CI.nsISupports).wrappedJSObject;
593
 
        p.fromDOM(proxyElems[i]);
 
680
        p.fromDOM(proxyElems[i], mode);
594
681
        if (!last && proxyElems[i].getAttribute("lastresort") == "true")
595
682
          last = p;
596
683
        else
615
702
        this.list.push(last); // ensures it really IS last
616
703
        fp.writeSettings();
617
704
                }
618
 
                this.lastresort = last;                 
 
705
                this.lastresort = last;
619
706
    },
620
 
    
 
707
 
621
708
    toDOM : function(doc) {
622
709
                        var proxiesElem=doc.createElement("proxies");
623
710
      for (var i=0; i<this.list.length; i++) {
625
712
      }
626
713
      return proxiesElem;
627
714
    },
628
 
    
629
 
    item : function(i) { 
 
715
 
 
716
    item : function(i) {
630
717
      return this.list[i];
631
718
    },
632
 
    
 
719
 
633
720
    remove : function(idx) {
634
721
      this.maintainIntegrity(this.list[idx], true, false, false);
635
722
      for (var i=0, temp=[]; i<this.list.length; i++) {
640
727
              this.list.push(temp[i]);
641
728
            }
642
729
    },
643
 
    
 
730
 
644
731
    move : function(idx, direction) {
645
732
      var newIdx = idx + (direction=="up"?-1:1);
646
733
      if (newIdx < 0 || newIdx > this.list.length-1) return false;
647
 
      var temp = this.list[idx]; 
 
734
      var temp = this.list[idx];
648
735
      this.list[idx] = this.list[newIdx];
649
736
      this.list[newIdx] = temp;
650
737
      return true;
651
738
    },
652
 
    
 
739
 
653
740
    getMatches : function(uriStr) {
654
741
                        for (var i=0, aMatch; i<this.list.length; i++) {
655
742
                                if (this.list[i]._enabled && (aMatch = this.list[i].isMatch(uriStr))) {
659
746
      // Failsafe: use lastresort proxy if nothing else was chosen
660
747
      return gMatchingProxyFactory(this.lastresort, this.lastresort.matches[0], uriStr, "pat");
661
748
    },
662
 
    
 
749
 
663
750
    getRandom : function(uriStr, includeDirect, includeDisabled) {
664
751
      var isDirect = true, isDisabled = true, r, cont, maxTries = this.list.length*10;
665
752
      do {
666
 
        r = Math.floor(Math.random()*this.list.length); // Thanks Andrew @ http://www.shawnolson.net/a/789/   
667
 
        dump(r+"\n");     
 
753
        r = Math.floor(Math.random()*this.list.length); // Thanks Andrew @ http://www.shawnolson.net/a/789/
 
754
        dump(r+"\n");
668
755
        cont = (!includeDirect && this.list[r].mode == "direct") ||
669
756
                (!includeDisabled && !this.list[r]._enabled);
670
757
         dump("cont="+cont+"\n");
672
759
      if (maxTries == 0) {
673
760
        return this.lastresort;
674
761
      }
675
 
      return gMatchingProxyFactory(this.list[r], null, uriStr, "rand");   
 
762
      return gMatchingProxyFactory(this.list[r], null, uriStr, "rand");
676
763
    },
677
764
 
678
765
                getNextById : function(curId) {
679
766
                  var idx = this.getIndexById(curId);
680
 
                  if (idx==-1) return null;     
 
767
                  if (idx==-1) return null;
681
768
            for (var i=idx+1,len=this.length; i<len; i++) {
682
 
              if (this.list[i]._enabled) {      
 
769
              if (this.list[i]._enabled) {
683
770
                return this.list[i];
684
771
              }
685
772
            }
686
 
      return null; // at end; do not wrap.                  
 
773
      return null; // at end; do not wrap.
687
774
                },
688
 
                
 
775
 
689
776
    uniqueRandom : function() {
690
777
      var unique = true, r;
691
778
      do {
695
782
      } while (!unique);
696
783
      return r;
697
784
    },
698
 
    
 
785
 
699
786
    maintainIntegrity : function(proxy, isBeingDeleted, isBeingDisabled, isBecomingDIRECT) {
700
787
      var updateViews;
701
788
      // Handle foxyproxy "mode"
706
793
                updateViews = true;
707
794
              }
708
795
            }
 
796
      if (isBeingDeleted) {
 
797
        // If the proxy set for "previousMode" is being deleted, change "previousMode"
 
798
        if (gFP.previousMode == proxy.id)
 
799
          gFP.previousMode = "patterns";
 
800
      }
 
801
 
709
802
            // Handle AutoAdd & QuickAdd (superadd)
710
803
            if (gFP.autoadd.maintainIntegrity(proxy.id, isBeingDeleted) && !updateViews) {
711
804
                updateViews = true;
716
809
 
717
810
      // updateViews() with false, false (do not write settings and do not update log view--settings were just written when the properties themselves were updated
718
811
      updateViews && gBroadcast(null, "foxyproxy-updateviews");
719
 
    }    
 
812
    }
720
813
  },
721
 
  
 
814
 
722
815
  ///////////////// logg \\\\\\\\\\\\\\\\\\\\\\\\\\\
723
816
  logg : {
724
817
    owner : null,
725
818
    _maxSize : 500,
726
 
    _elements : new Array(this._maxSize),    
 
819
    _elements : new Array(this._maxSize),
727
820
    _end : 0,
728
821
    _start : 0,
729
822
    _full : false,
730
823
    enabled : false,
731
 
    _templateHeader : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title></title><link rel=\"icon\" href=\"http://foxyproxy.mozdev.org/favicon.ico\"/><link rel=\"shortcut icon\" href=\"http://foxyproxy.mozdev.org/favicon.ico\"/><link rel=\"stylesheet\" href=\"http://foxyproxy.mozdev.org/styles/log.css\" type=\"text/css\"/></head><body><table class=\"log-table\"><thead><tr><td class=\"heading\">${timestamp-heading}</td><td class=\"heading\">${url-heading}</td><td class=\"heading\">${proxy-name-heading}</td><td class=\"heading\">${proxy-notes-heading}</td><td class=\"heading\">${pattern-name-heading}</td><td class=\"heading\">${pattern-heading}</td><td class=\"heading\">${pattern-type-heading}</td><td class=\"heading\">${pattern-color-heading}</td><td class=\"heading\">${pac-result-heading}</td><td class=\"heading\">${error-msg-heading}</td></tr></thead><tfoot><tr><td/></tr></tfoot><tbody>",    
732
 
    _templateFooter : "</tbody></table></body></html>", 
733
 
    _templateRow : "<tr><td class=\"timestamp\">${timestamp}</td><td class=\"url\"><a href=\"${url}\">${url}</a></td><td class=\"proxy-name\">${proxy-name}</td><td class=\"proxy-notes\">${proxy-notes}</td><td class=\"pattern-name\">${pattern-name}</td><td class=\"pattern\">${pattern}</td><td class=\"pattern-type\">${pattern-type}</td><td class=\"pattern-color\">${pattern-color}</td><td class=\"pac-result\">${pac-result}</td><td class=\"error-msg\">${error-msg}</td></tr>",         
 
824
    _templateHeader : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title></title><link rel=\"icon\" href=\"http://foxyproxy.mozdev.org/favicon.ico\"/><link rel=\"shortcut icon\" href=\"http://foxyproxy.mozdev.org/favicon.ico\"/><link rel=\"stylesheet\" href=\"http://foxyproxy.mozdev.org/styles/log.css\" type=\"text/css\"/></head><body><table class=\"log-table\"><thead><tr><td class=\"heading\">${timestamp-heading}</td><td class=\"heading\">${url-heading}</td><td class=\"heading\">${proxy-name-heading}</td><td class=\"heading\">${proxy-notes-heading}</td><td class=\"heading\">${pattern-name-heading}</td><td class=\"heading\">${pattern-heading}</td><td class=\"heading\">${pattern-case-heading}</td><td class=\"heading\">${pattern-type-heading}</td><td class=\"heading\">${pattern-color-heading}</td><td class=\"heading\">${pac-result-heading}</td><td class=\"heading\">${error-msg-heading}</td></tr></thead><tfoot><tr><td/></tr></tfoot><tbody>",
 
825
    _templateFooter : "</tbody></table></body></html>",
 
826
    _templateRow : "<tr><td class=\"timestamp\">${timestamp}</td><td class=\"url\"><a href=\"${url}\">${url}</a></td><td class=\"proxy-name\">${proxy-name}</td><td class=\"proxy-notes\">${proxy-notes}</td><td class=\"pattern-name\">${pattern-name}</td><td class=\"pattern\">${pattern}</td><td class=\"pattern-case\">${pattern-case}</td><td class=\"pattern-type\">${pattern-type}</td><td class=\"pattern-color\">${pattern-color}</td><td class=\"pac-result\">${pac-result}</td><td class=\"error-msg\">${error-msg}</td></tr>",
734
827
    _timeformat : null,
735
 
          _months : null,         
736
 
          _days : null,     
 
828
          _months : null,
 
829
          _days : null,
737
830
          _noURLs : false,
738
831
          noURLsMessage : null,
739
832
 
745
838
                    gFP.getMessage("months.long.3"), gFP.getMessage("months.long.4"), gFP.getMessage("months.long.5"),
746
839
                    gFP.getMessage("months.long.6"), gFP.getMessage("months.long.7"), gFP.getMessage("months.long.8"),
747
840
                    gFP.getMessage("months.long.9"), gFP.getMessage("months.long.10"), gFP.getMessage("months.long.11"),
748
 
                    gFP.getMessage("months.long.12")];      
 
841
                    gFP.getMessage("months.long.12")];
749
842
                  this._days = [gFP.getMessage("days.long.1"), gFP.getMessage("days.long.2"),
750
843
                    gFP.getMessage("days.long.3"), gFP.getMessage("days.long.4"), gFP.getMessage("days.long.5"),
751
844
                    gFP.getMessage("days.long.6"), gFP.getMessage("days.long.7")];
752
 
                    
 
845
 
753
846
                  // Now deserialize...
754
847
      var node = doc.getElementsByTagName("logg")[0];
755
848
      this.enabled = node.getAttribute("enabled") == "true";
757
850
              node.getAttribute("maxSize") : 500; // new for 2.0
758
851
                        if (node.hasAttribute("header-v2")) {
759
852
                                this._templateHeader = node.getAttribute("header-v2");
760
 
                        }                               
 
853
                        }
761
854
                        if (node.hasAttribute("footer-v2")) {
762
855
                                this._templateFooter = node.getAttribute("footer-v2");
763
856
                        }
767
860
                  this._noURLs = node.hasAttribute("noURLs") ? node.getAttribute("noURLs") == "true" : false; // new for 2.3
768
861
            this.clear();
769
862
    },
770
 
    
 
863
 
771
864
    toDOM : function(doc) {
772
865
      var e = doc.createElement("logg");
773
866
      e.setAttribute("enabled", this.enabled);
775
868
      e.setAttribute("noURLs", this._noURLs);
776
869
      e.setAttribute("header", this._templateHeader);
777
870
      e.setAttribute("row", this._templateRow);
778
 
      e.setAttribute("footer", this._templateFooter);      
 
871
      e.setAttribute("footer", this._templateFooter);
779
872
      return e;
780
873
    },
781
 
        
 
874
 
782
875
    toHTML : function() {
783
876
            // Doing the heading substitution here (over and over again instead of once in fromDOM()) permits users to switch locales w/o having to restart FF and
784
877
            // the changes take effect immediately in FoxyProxy.
785
 
            var self = this, sz = this.length, ret = this._templateHeader.replace(/\${timestamp-heading}|\${url-heading}|\${proxy-name-heading}|\${proxy-notes-heading}|\${pattern-name-heading}|\${pattern-heading}|\${pattern-type-heading}|\${pattern-color-heading}|\${pac-result-heading}|\${error-msg-heading}/gi,
 
878
            var self = this, sz = this.length, ret = this._templateHeader.replace(/\${timestamp-heading}|\${url-heading}|\${proxy-name-heading}|\${proxy-notes-heading}|\${pattern-name-heading}|\${pattern-heading}|\${pattern-case-heading}|\${pattern-type-heading}|\${pattern-color-heading}|\${pac-result-heading}|\${error-msg-heading}/gi,
786
879
                function($0) {
787
880
                                        switch($0) {
788
881
                                                case "${timestamp-heading}": return gFP.getMessage("foxyproxy.tab.logging.timestamp.label");
789
882
                                                case "${url-heading}": return gFP.getMessage("foxyproxy.tab.logging.url.label");
790
883
                                                case "${proxy-name-heading}": return gFP.getMessage("foxyproxy.proxy.name.label");
791
 
                                                case "${proxy-notes-heading}": return gFP.getMessage("foxyproxy.proxy.notes.label");                    
792
 
                                                case "${pattern-name-heading}": return gFP.getMessage("foxyproxy.pattern.name.label");                  
793
 
                                                case "${pattern-heading}": return gFP.getMessage("foxyproxy.pattern.label");                                                                                                                                                                    
 
884
                                                case "${proxy-notes-heading}": return gFP.getMessage("foxyproxy.proxy.notes.label");
 
885
                                                case "${pattern-name-heading}": return gFP.getMessage("foxyproxy.pattern.name.label");
 
886
                                                case "${pattern-heading}": return gFP.getMessage("foxyproxy.pattern.label");
 
887
                        case "${pattern-case-heading}": return gFP.getMessage("foxyproxy.casesensitive.label");
794
888
                                                case "${pattern-type-heading}": return gFP.getMessage("foxyproxy.pattern.type.label");
795
 
                                                case "${pattern-color-heading}": return gFP.getMessage("foxyproxy.whitelist.blacklist.label");                                                                                                                                                                                                                                                                  
796
 
                                                case "${pac-result-heading}": return gFP.getMessage("foxyproxy.pac.result.label");                                                                                                      
797
 
                                                case "${error-msg-heading}": return gFP.getMessage("foxyproxy.error.msg.label");                                                                                                        
 
889
                                                case "${pattern-color-heading}": return gFP.getMessage("foxyproxy.whitelist.blacklist.label");
 
890
                                                case "${pac-result-heading}": return gFP.getMessage("foxyproxy.pac.result.label");
 
891
                                                case "${error-msg-heading}": return gFP.getMessage("foxyproxy.error.msg.label");
798
892
                        }
799
893
                }
800
894
            );
809
903
                    case "\"": return "&quot;";
810
904
                  }
811
905
                }
812
 
              ); 
813
 
            };                              
 
906
              );
 
907
            };
814
908
                        for (var i=0; i<sz; i++) {
815
 
                                ret += self._templateRow.replace(/\${timestamp}|\${url}|\${proxy-name}|\${proxy-notes}|\${pattern-name}|\${pattern}|\${pattern-type}|\${pattern-color}|\${pac-result}|\${error-msg}/gi,
 
909
                                ret += self._templateRow.replace(/\${timestamp}|\${url}|\${proxy-name}|\${proxy-notes}|\${pattern-name}|\${pattern}|\${pattern-case}|\${pattern-type}|\${pattern-color}|\${pac-result}|\${error-msg}/gi,
816
910
                                        function($0) {
817
911
                                                switch($0) {
818
912
                                                        case "${timestamp}": return _xmlEncode(self.format(self.item(i).timestamp));
819
913
                                                        case "${url}": return _xmlEncode(self.item(i).uri);
820
 
                                                        case "${proxy-name}": return _xmlEncode(self.item(i).proxyName);                                                        
821
 
                                                        case "${proxy-notes}": return _xmlEncode(self.item(i).proxyNotes);                                                                                                              
822
 
                                                        case "${pattern-name}": return _xmlEncode(self.item(i).matchName);                                                                                                              
823
 
                                                        case "${pattern}": return _xmlEncode(self.item(i).matchPattern);                                                                                                                                                                        
 
914
                                                        case "${proxy-name}": return _xmlEncode(self.item(i).proxyName);
 
915
                                                        case "${proxy-notes}": return _xmlEncode(self.item(i).proxyNotes);
 
916
                                                        case "${pattern-name}": return _xmlEncode(self.item(i).matchName);
 
917
                                                        case "${pattern}": return _xmlEncode(self.item(i).matchPattern);
 
918
                            case "${pattern-case}": return _xmlEncode(self.item(i).caseSensitive);
824
919
                                                        case "${pattern-type}": return _xmlEncode(self.item(i).matchType);
825
920
                                                        case "${pattern-color}": return _xmlEncode(self.item(i).whiteBlack);
826
 
                                                        case "${pac-result}": return _xmlEncode(self.item(i).pacResult);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
827
 
                                                        case "${error-msg}": return _xmlEncode(self.item(i).errMsg);                                                                                                    
 
921
                                                        case "${pac-result}": return _xmlEncode(self.item(i).pacResult);
 
922
                                                        case "${error-msg}": return _xmlEncode(self.item(i).errMsg);
828
923
                                                }
829
924
                                        }
830
 
                          ); 
 
925
                          );
831
926
                        }
832
927
                        return ret + this._templateFooter;
833
928
    },
837
932
            d = new Date(d);
838
933
            if (!d.valueOf())
839
934
              return ' ';
840
 
                        var self = this;              
841
 
            return this._timeformat.replace(/yyyy|mmmm|mmm|mm|dddd|ddd|dd|hh|HH|nn|ss|zzz|a\/p/gi, 
 
935
                        var self = this;
 
936
            return this._timeformat.replace(/yyyy|mmmm|mmm|mm|dddd|ddd|dd|hh|HH|nn|ss|zzz|a\/p/gi,
842
937
              function($1) {
843
938
                switch ($1) {
844
939
                  case 'yyyy': return d.getFullYear();
849
944
                  case 'ddd':  return self._days[d.getDay()].substr(0, 3);
850
945
                  case 'dd':   return zf(d.getDate(), 2);
851
946
                  case 'hh':   return zf(((h = d.getHours() % 12) ? h : 12), 2);
852
 
                  case 'HH':   return zf(d.getHours(), 2);          
 
947
                  case 'HH':   return zf(d.getHours(), 2);
853
948
                  case 'nn':   return zf(d.getMinutes(), 2);
854
949
                  case 'ss':   return zf(d.getSeconds(), 2);
855
 
                  case 'zzz':  return zf(d.getSeconds(), 3);          
 
950
                  case 'zzz':  return zf(d.getSeconds(), 3);
856
951
                  case 'a/p':  return d.getHours() < 12 ? 'AM' : 'PM';
857
952
                }
858
953
              }
859
954
            );
860
955
                  // My own zero-fill fcn, not Tor 2k's. Assumes (n==2 || n == 3) && c<=n.
861
 
                  function zf(c, n) { c=""+c; return c.length == 1 ? (n==2?'0'+c:'00'+c) : (c.length == 2 ? (n==2?c:'0'+c) : c); }          
 
956
                  function zf(c, n) { c=""+c; return c.length == 1 ? (n==2?'0'+c:'00'+c) : (c.length == 2 ? (n==2?c:'0'+c) : c); }
862
957
          },
863
 
    
 
958
 
864
959
    get length() {
865
960
      var size = 0;
866
961
      if (this._end < this._start) {
872
967
      }
873
968
      return size;
874
969
    },
875
 
    
 
970
 
876
971
    get maxSize() {
877
972
      return this._maxSize;
878
973
    },
879
 
    
 
974
 
880
975
    set maxSize(m) {
881
976
      this._maxSize = m;
882
977
      this.clear();
883
 
        gFP.writeSettings();      
 
978
        gFP.writeSettings();
884
979
    },
885
980
 
886
981
    get noURLs() {
887
982
      return this._noURLs;
888
983
    },
889
 
    
 
984
 
890
985
    set noURLs(m) {
891
986
      this._noURLs = m;
892
987
        gFP.writeSettings();
893
988
    },
894
 
    
 
989
 
895
990
    get templateHeader() {
896
991
      return this._templateHeader;
897
992
    },
898
 
    
 
993
 
899
994
    set templateHeader(t) {
900
995
      this._templateHeader = t;
901
996
        gFP.writeSettings();
902
 
    }, 
 
997
    },
903
998
 
904
999
    get templateFooter() {
905
1000
      return this._templateFooter;
906
1001
    },
907
 
    
 
1002
 
908
1003
    set templateFooter(t) {
909
1004
      this._templateFooter = t;
910
1005
        gFP.writeSettings();
911
 
    },   
 
1006
    },
912
1007
 
913
1008
    get templateRow() {
914
1009
      return this._templateRow;
915
1010
    },
916
 
    
 
1011
 
917
1012
    set templateRow(t) {
918
1013
      this._templateRow = t;
919
1014
        gFP.writeSettings();
920
 
    },        
921
 
    
 
1015
    },
 
1016
 
922
1017
    clear : function() {
923
1018
      this._full = false;
924
1019
      this._end = this._start = 0;
925
1020
      //this._elements.forEach(function(element, index, array) {array[index] = null;});
926
1021
      this._elements = new Array(this._maxSize);
927
1022
    },
928
 
    
 
1023
 
929
1024
    scrub : function() {
930
1025
      // Remove sensitive data (urls)
931
1026
                        var self=this;
932
1027
                        this._elements.forEach(function(element, index, array) {array[index].uri = self.noURLsMessage;});
933
1028
    },
934
 
  
 
1029
 
935
1030
    add : function(o) {
936
1031
      if (!this.enabled) return;
937
1032
      this.length == this._maxSize && this._remove();
939
1034
      this._end >= this._maxSize && (this._end = 0);
940
1035
      this._end == this._start && (this._full = true);
941
1036
    },
942
 
  
 
1037
 
943
1038
    item : function(idx) {
944
1039
      return this.length == 0 ? null : this._elements[idx];
945
1040
    },
946
 
  
 
1041
 
947
1042
    _remove : function() {
948
1043
      if (this.length == 0)
949
1044
        return;
950
1045
      var element = this._elements[this._start];
951
 
  
 
1046
 
952
1047
      if (element) {
953
1048
        this._elements[this._start++] = null;
954
1049
        this._start >= this._maxSize && (this._start = 0);
959
1054
 
960
1055
  ///////////////// notifier \\\\\\\\\\\\\\\\\\\\\\\\\\\
961
1056
  // Thanks for the inspiration: InfoRSS extension (Didier Ernotte, 2005)
962
 
  notifier : {    
 
1057
  notifier : {
963
1058
        alerts : function() {
964
1059
      try {
965
 
        return CC["@mozilla.org/alerts-service;1"].getService(CI.nsIAlertsService);  
 
1060
        return CC["@mozilla.org/alerts-service;1"].getService(CI.nsIAlertsService);
966
1061
      }
967
1062
      catch(e) {return null;}
968
1063
        }(),
969
 
                        
970
 
    alert : function(title, text) {   
 
1064
 
 
1065
    alert : function(title, text) {
971
1066
      if (this.alerts)
972
1067
        this.alerts.showAlertNotification("chrome://foxyproxy/content/images/foxyproxy-nocopy.gif", title, text, false, "", null);
973
1068
      else {
974
1069
        (!this.timer && (this.timer = CC["@mozilla.org/timer;1"].createInstance(CI.nsITimer)));
975
1070
        this.timer.cancel();
976
1071
                    var wm = CC["@mozilla.org/appshell/window-mediator;1"].getService(CI.nsIWindowMediator);
977
 
                    var win = wm.getMostRecentWindow("navigator:browser");
 
1072
                    var win = wm.getMostRecentWindow("navigator:browser") || wm.getMostRecentWindow("Songbird:Main");
978
1073
                    try {
979
 
                            var doc = win.parent.document;            
 
1074
                            var doc = win.parent.document;
980
1075
                this.tooltip = doc.getElementById("foxyproxy-popup");
981
1076
                this._removeChildren(this.tooltip);
982
1077
                        var grid = doc.createElement("grid");
983
1078
                        grid.setAttribute("flex", "1");
984
1079
                        this.tooltip.appendChild(grid);
985
 
            
 
1080
 
986
1081
                        var columns = doc.createElement("columns");
987
 
                        columns.appendChild(doc.createElement("column"));               
 
1082
                        columns.appendChild(doc.createElement("column"));
988
1083
                        grid.appendChild(columns);
989
 
            
 
1084
 
990
1085
                        var rows = doc.createElement("rows");
991
1086
                        grid.appendChild(rows);
992
1087
                this._makeHeaderRow(doc, title, rows);
993
1088
                this._makeRow(doc, "", rows);
994
1089
                this._makeRow(doc, text, rows);
995
1090
                this.tooltip.showPopup(doc.getElementById("status-bar"), -1, -1, "tooltip", "topright","bottomright");
996
 
                                        this.timer.initWithCallback(this, 5000, CI.nsITimer.TYPE_ONE_SHOT);                                     
 
1091
                                        this.timer.initWithCallback(this, 5000, CI.nsITimer.TYPE_ONE_SHOT);
997
1092
              }
998
1093
              catch (e) { dump(e);/* in case win, win.parent, win.parent.document, tooltip, etc. don't exist */ gFP.alert(null, text);}
999
1094
      }
1000
1095
    },
1001
 
    
 
1096
 
1002
1097
    notify : function() {
1003
1098
        this.tooltip.hidePopup();
1004
1099
    },
1005
1100
 
1006
1101
    _makeHeaderRow : function(doc, col, gridRows) {
1007
1102
                var label = doc.createElement("label");
1008
 
                label.setAttribute("value", col);      
 
1103
                label.setAttribute("value", col);
1009
1104
      label.setAttribute("style", "font-weight: bold; text-decoration: underline; color: blue;");
1010
 
      gridRows.appendChild(label);    
 
1105
      gridRows.appendChild(label);
1011
1106
    },
1012
 
    
 
1107
 
1013
1108
    _makeRow : function(doc, col1, gridRows) {
1014
1109
                var gridRow = doc.createElement("row");
1015
1110
                var label = doc.createElement("label");
1016
 
                label.setAttribute("value", col1);    
 
1111
                label.setAttribute("value", col1);
1017
1112
                gridRow.appendChild(label);
1018
 
                gridRows.appendChild(gridRow);  
 
1113
                gridRows.appendChild(gridRow);
1019
1114
    },
1020
 
      
 
1115
 
1021
1116
    _removeChildren : function(node) {
1022
1117
      if (node && node.firstChild) {
1023
1118
        node.removeChild(node.firstChild);
1024
1119
        this._removeChildren(node);
1025
1120
      }
1026
 
    }    
 
1121
    }
1027
1122
  },
1028
 
  
 
1123
 
1029
1124
  ///////////////// statusbar \\\\\\\\\\\\\\\\\\\\\
1030
1125
  statusbar : {
1031
1126
    _iconEnabled : true,
1032
 
    _textEnabled : true, 
 
1127
    _textEnabled : true,
1033
1128
    _leftClick : "options",
1034
1129
    _middleClick : "cycle",
1035
 
    _rightClick : "contextmenu", 
1036
 
        
 
1130
    _rightClick : "contextmenu",
 
1131
    _width : 0,
 
1132
 
1037
1133
    toDOM : function(doc) {
1038
1134
      var e = doc.createElement("statusbar");
1039
1135
      e.setAttribute("icon", this._iconEnabled); // new for 2.3 (used to be just "enabled")
1040
 
      e.setAttribute("text", this._textEnabled); // new for 2.3 (used to be just "enabled")     
1041
 
                        e.setAttribute("left", this._leftClick); // new for 2.5          
1042
 
                        e.setAttribute("middle", this._middleClick); // new for 2.5                     
1043
 
                        e.setAttribute("right", this._rightClick); // new for 2.5                                               
 
1136
      e.setAttribute("text", this._textEnabled); // new for 2.3 (used to be just "enabled")
 
1137
      e.setAttribute("left", this._leftClick); // new for 2.5
 
1138
            e.setAttribute("middle", this._middleClick); // new for 2.5
 
1139
      e.setAttribute("right", this._rightClick); // new for 2.5
 
1140
      e.setAttribute("width", this._width); // new for 2.6.3
1044
1141
      return e;
1045
1142
    },
1046
 
    
 
1143
 
1047
1144
    fromDOM : function(doc) {
1048
1145
      var n = doc.getElementsByTagName("statusbar")[0];
1049
 
                        this._iconEnabled = gGetSafeAttrB(n, "icon", true);
 
1146
      this._iconEnabled = gGetSafeAttrB(n, "icon", true);
1050
1147
            this._textEnabled = gGetSafeAttrB(n, "text", true);
1051
1148
                this._leftClick = gGetSafeAttr(n, "left", "options");
1052
1149
                this._middleClick = gGetSafeAttr(n, "middle", "cycle");
1053
 
                this._rightClick = gGetSafeAttr(n, "right", "contextmenu");             
 
1150
                this._rightClick = gGetSafeAttr(n, "right", "contextmenu");
 
1151
      this._width = gGetSafeAttr(n, "width", 0);      
1054
1152
    },
1055
 
    
 
1153
 
1056
1154
    get iconEnabled() { return this._iconEnabled; },
1057
1155
    set iconEnabled(e) {
1058
1156
      this._iconEnabled = e;
1059
1157
      gFP.writeSettings();
1060
 
                        gBroadcast(e, "foxyproxy-statusbar-icon");  
1061
 
      e && gFP.setMode(gFP.mode, false, false);          
 
1158
                        gBroadcast(e, "foxyproxy-statusbar-icon");
 
1159
      e && gFP.setMode(gFP.mode, false, false); // todo: why is this here? can it be removed? it forces PAC to reload
1062
1160
    },
1063
 
    
 
1161
 
1064
1162
    get textEnabled() { return this._textEnabled; },
1065
1163
    set textEnabled(e) {
1066
1164
      this._textEnabled = e;
1067
1165
      gFP.writeSettings();
1068
1166
                        gBroadcast(e, "foxyproxy-statusbar-text");
1069
 
      e && gFP.setMode(gFP.mode, false, false);          
1070
 
    },    
 
1167
      e && gFP.setMode(gFP.mode, false, false);  // todo: why is this here? can it be removed? it forces PAC to reload
 
1168
    },
1071
1169
 
1072
1170
    get leftClick() { return this._leftClick; },
1073
1171
    set leftClick(e) {
1074
1172
      this._leftClick = e;
1075
1173
      gFP.writeSettings();
1076
 
    },     
 
1174
    },
1077
1175
 
1078
1176
    get middleClick() { return this._middleClick; },
1079
1177
    set middleClick(e) {
1080
1178
      this._middleClick = e;
1081
1179
      gFP.writeSettings();
1082
1180
    },
1083
 
        
 
1181
 
1084
1182
    get rightClick() { return this._rightClick; },
1085
1183
    set rightClick(e) {
1086
1184
      this._rightClick = e;
1087
1185
      gFP.writeSettings();
1088
 
    }              
1089
 
  },  
1090
 
  
 
1186
    },
 
1187
    
 
1188
    get width() { return this._width; },
 
1189
    set width(e) {
 
1190
      e = parseInt(e);
 
1191
      if (isNaN(e)) e = 0;
 
1192
      this._width = e;
 
1193
      gFP.writeSettings();
 
1194
      gBroadcast(e, "foxyproxy-statusbar-width");
 
1195
    }
 
1196
  },
 
1197
 
1091
1198
  ///////////////// toolbar \\\\\\\\\\\\\\\\\\\\\
1092
 
  toolbar : {  
 
1199
  toolbar : {
1093
1200
    _leftClick : "options",
1094
1201
    _middleClick : "cycle",
1095
 
    _rightClick : "contextmenu", 
1096
 
        
 
1202
    _rightClick : "contextmenu",
 
1203
 
1097
1204
    toDOM : function(doc) {
1098
1205
      var e = doc.createElement("toolbar");
1099
 
                        e.setAttribute("left", this._leftClick); // new for 2.5          
1100
 
                        e.setAttribute("middle", this._middleClick); // new for 2.5                     
1101
 
                        e.setAttribute("right", this._rightClick); // new for 2.5                                               
 
1206
                        e.setAttribute("left", this._leftClick); // new for 2.5
 
1207
                        e.setAttribute("middle", this._middleClick); // new for 2.5
 
1208
                        e.setAttribute("right", this._rightClick); // new for 2.5
1102
1209
      return e;
1103
1210
    },
1104
 
    
 
1211
 
1105
1212
    fromDOM : function(doc) {
1106
1213
      var n = doc.getElementsByTagName("toolbar")[0];
1107
1214
                this._leftClick = gGetSafeAttr(n, "left", "options");
1108
1215
                this._middleClick = gGetSafeAttr(n, "middle", "cycle");
1109
 
                this._rightClick = gGetSafeAttr(n, "right", "contextmenu");             
 
1216
                this._rightClick = gGetSafeAttr(n, "right", "contextmenu");
1110
1217
    },
1111
 
    
 
1218
 
1112
1219
    get leftClick() { return this._leftClick; },
1113
1220
    set leftClick(e) {
1114
1221
      this._leftClick = e;
1115
 
      gFP.writeSettings();  
1116
 
    },     
 
1222
      gFP.writeSettings();
 
1223
    },
1117
1224
 
1118
1225
    get middleClick() { return this._middleClick; },
1119
1226
    set middleClick(e) {
1120
1227
      this._middleClick = e;
1121
1228
      gFP.writeSettings();
1122
1229
    },
1123
 
        
 
1230
 
1124
1231
    get rightClick() { return this._rightClick; },
1125
1232
    set rightClick(e) {
1126
1233
      this._rightClick = e;
1127
1234
      gFP.writeSettings();
1128
 
    }          
1129
 
  },  
1130
 
  
1131
 
  ///////////////// strings \\\\\\\\\\\\\\\\\\\\\       
 
1235
    }
 
1236
  },
 
1237
 
 
1238
  ///////////////// strings \\\\\\\\\\\\\\\\\\\\\
1132
1239
  getMessage : function(msg, ar) {
1133
1240
    try {
1134
1241
      return this.strings.getMessage(msg, ar);
1137
1244
      dump(e);
1138
1245
      this.alert(null, "Error reading string resource: " + msg); // Do not localize!
1139
1246
    }
1140
 
  },  
1141
 
  
 
1247
  },
 
1248
 
1142
1249
  strings : {
1143
1250
    _sbs : CC["@mozilla.org/intl/stringbundle;1"]
1144
1251
      .getService(CI.nsIStringBundleService)
1145
 
      .createBundle("chrome://foxyproxy/locale/foxyproxy.properties"),    
 
1252
      .createBundle("chrome://foxyproxy/locale/foxyproxy.properties"),
1146
1253
    _entities : null,
1147
 
    
 
1254
 
1148
1255
    getMessage : function(msg, ar) {
1149
1256
      return ar ? this._sbs.formatStringFromName(msg, ar, ar.length) :
1150
1257
        (this._entities[msg] ? this._entities[msg] : this._sbs.GetStringFromName(msg));
1156
1263
    get noWildcards() { return this._noWildcards; },
1157
1264
    set noWildcards(e) {
1158
1265
      this._noWildcards = e;
1159
 
      gFP.writeSettings();          
 
1266
      gFP.writeSettings();
1160
1267
    },
1161
 
    
 
1268
 
1162
1269
    toDOM : function(doc) {
1163
1270
      var e = doc.createElement("warnings"); // new for 2.3
1164
 
      e.setAttribute("no-wildcards", this._noWildcards); 
 
1271
      e.setAttribute("no-wildcards", this._noWildcards);
1165
1272
      return e;
1166
1273
    },
1167
 
    
 
1274
 
1168
1275
    fromDOM : function(doc) {
1169
1276
      var node = doc.getElementsByTagName("warnings")[0];
1170
1277
      node && (this._noWildcards = node.getAttribute("no-wildcards") == "true");
1171
 
    },  
1172
 
  }
 
1278
    },
 
1279
  },
 
1280
        classID: Components.ID("{46466e13-16ab-4565-9924-20aac4d98c82}"),
 
1281
        contractID: "@leahscape.org/foxyproxy/service;1",
 
1282
        classDescription: "FoxyProxy Core"
 
1283
};
 
1284
 
 
1285
var gXpComObjects = [foxyproxy];
 
1286
var gCatObserverName = "foxyproxy_catobserver";
 
1287
var gCatContractId = foxyproxy.prototype.contractID;
 
1288
 
 
1289
 
 
1290
function NSGetModule(compMgr, fileSpec) {
 
1291
        gModule._catObserverName = gCatObserverName;
 
1292
        gModule._catContractId = gCatContractId;
 
1293
 
 
1294
        for (var i in gXpComObjects)
 
1295
                gModule._xpComObjects[i] = new gFactoryHolder(gXpComObjects[i]);
 
1296
 
 
1297
        return gModule;
 
1298
}
 
1299
 
 
1300
function gFactoryHolder(aObj) {
 
1301
        this.CID        = aObj.prototype.classID;
 
1302
        this.contractID = aObj.prototype.contractID;
 
1303
        this.className  = aObj.prototype.classDescription;
 
1304
        this.factory =
 
1305
        {
 
1306
                createInstance: function(aOuter, aIID)
 
1307
                {
 
1308
                        if (aOuter)
 
1309
                                throw CR.NS_ERROR_NO_AGGREGATION;
 
1310
 
 
1311
                        return (new this.constructor).QueryInterface(aIID);
 
1312
                }
 
1313
        };
 
1314
 
 
1315
        this.factory.constructor = aObj;
 
1316
}
 
1317
var gModule = {
 
1318
        registerSelf: function (aComponentManager, aFileSpec, aLocation, aType) {
 
1319
                aComponentManager.QueryInterface(CI.nsIComponentRegistrar);
 
1320
                for (var key in this._xpComObjects)
 
1321
                {
 
1322
                        var obj = this._xpComObjects[key];
 
1323
                        aComponentManager.registerFactoryLocation(obj.CID, obj.className,
 
1324
                        obj.contractID, aFileSpec, aLocation, aType);
 
1325
                }
 
1326
 
 
1327
                var catman = CC["@mozilla.org/categorymanager;1"].getService(CI.nsICategoryManager);
 
1328
                catman.addCategoryEntry("app-startup", this._catObserverName, this._catContractId, true, true);
 
1329
                catman.addCategoryEntry("xpcom-shutdown", this._catObserverName, this._catContractId, true, true);
 
1330
        },
 
1331
 
 
1332
        unregisterSelf: function(aCompMgr, aFileSpec, aLocation) {
 
1333
                var catman = CC["@mozilla.org/categorymanager;1"].getService(CI.nsICategoryManager);
 
1334
                catman.deleteCategoryEntry("app-startup", this._catObserverName, true);
 
1335
                catman.deleteCategoryEntry("xpcom-shutdown", this._catObserverName, true);
 
1336
 
 
1337
                aComponentManager.QueryInterface(CI.nsIComponentRegistrar);
 
1338
                for (var key in this._xpComObjects)
 
1339
                {
 
1340
                        var obj = this._xpComObjects[key];
 
1341
                        aComponentManager.unregisterFactoryLocation(obj.CID, aFileSpec);
 
1342
                }
 
1343
        },
 
1344
 
 
1345
        getClassObject: function(aComponentManager, aCID, aIID) {
 
1346
                if (!aIID.equals(CI.nsIFactory))
 
1347
                        throw CR.NS_ERROR_NOT_IMPLEMENTED;
 
1348
 
 
1349
                for (var key in this._xpComObjects)
 
1350
                {
 
1351
                        if (aCID.equals(this._xpComObjects[key].CID))
 
1352
                                return this._xpComObjects[key].factory;
 
1353
                }
 
1354
 
 
1355
                throw CR.NS_ERROR_NO_INTERFACE;
 
1356
        },
 
1357
 
 
1358
        canUnload: function(aComponentManager) { return true; },
 
1359
 
 
1360
        _xpComObjects: {},
 
1361
        _catObserverName: null,
 
1362
        _catContractId: null
1173
1363
};
 
 
b'\\ No newline at end of file'