1
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
10
* Software distributed under the License is distributed on an "AS IS" basis,
11
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
* for the specific language governing rights and limitations under the
15
* The Original Code is mozilla.org code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 1998
20
* the Initial Developer. All Rights Reserved.
23
* Blake Ross <blakeross@telocity.com>
24
* Peter Annema <disttsc@bart.nl>
26
* Alternatively, the contents of this file may be used under the terms of
27
* either the GNU General Public License Version 2 or later (the "GPL"), or
28
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
* in which case the provisions of the GPL or the LGPL are applicable instead
30
* of those above. If you wish to allow use of your version of this file only
31
* under the terms of either the GPL or the LGPL, and not to allow others to
32
* use your version of this file under the terms of the NPL, indicate your
33
* decision by deleting the provisions above and replace them with the notice
34
* and other provisions required by the GPL or the LGPL. If you do not delete
35
* the provisions above, a recipient may use your version of this file under
36
* the terms of any one of the NPL, the GPL or the LGPL.
38
* ***** END LICENSE BLOCK ***** */
40
function nsBrowserStatusHandler()
45
nsBrowserStatusHandler.prototype =
47
// Stored Status, Link and Loading values
54
QueryInterface : function(aIID)
56
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
57
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
58
aIID.equals(Components.interfaces.nsIXULBrowserWindow) ||
59
aIID.equals(Components.interfaces.nsISupports))
61
throw Components.results.NS_NOINTERFACE;
66
this.urlBar = document.getElementById("urlbar");
67
this.throbberElement = document.getElementById("navigator-throbber");
68
this.statusMeter = document.getElementById("statusbar-icon");
69
this.stopButton = document.getElementById("stop-button");
70
this.stopMenu = document.getElementById("menuitem-stop");
71
this.stopContext = document.getElementById("context-stop");
72
this.statusTextField = document.getElementById("statusbar-display");
73
this.isImage = document.getElementById("isImage");
74
this.securityButton = document.getElementById("security-button");
76
// Initialize the security button's state and tooltip text
77
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
78
this.onSecurityChange(null, null, nsIWebProgressListener.STATE_IS_INSECURE);
83
// XXXjag to avoid leaks :-/, see bug 60729
85
this.throbberElement = null;
86
this.statusMeter = null;
87
this.stopButton = null;
89
this.stopContext = null;
90
this.statusTextField = null;
92
this.securityButton = null;
95
setJSStatus : function(status)
97
this.jsStatus = status;
98
this.updateStatusField();
101
setJSDefaultStatus : function(status)
103
this.jsDefaultStatus = status;
104
this.updateStatusField();
107
setDefaultStatus : function(status)
109
this.defaultStatus = status;
110
this.updateStatusField();
113
setOverLink : function(link)
115
this.overLink = link;
116
// clear out 'Done' (or other message) on first hover
117
if (this.defaultStatus)
118
this.defaultStatus = "";
119
this.updateStatusField();
121
this.statusTextField.setAttribute('crop', 'center');
123
this.statusTextField.setAttribute('crop', 'end');
126
updateStatusField : function()
128
var text = this.overLink || this.status || this.jsStatus || this.jsDefaultStatus || this.defaultStatus;
130
// check the current value so we don't trigger an attribute change
131
// and cause needless (slow!) UI updates
132
if (this.statusTextField.label != text)
133
this.statusTextField.label = text;
136
mimeTypeIsTextBased : function(contentType)
138
return /^text\/|\+xml$/.test(contentType) ||
139
contentType == "application/x-javascript" ||
140
contentType == "application/xml" ||
141
contentType == "mozilla.application/cached-xul";
144
onLinkIconAvailable : function(aHref)
146
if (gProxyFavIcon && pref.getBoolPref("browser.chrome.site_icons")) {
147
var browser = getBrowser();
148
if (browser.userTypedValue === null)
149
gProxyFavIcon.setAttribute("src", aHref);
151
// update any bookmarks with new icon reference
152
if (!gBookmarksService)
153
gBookmarksService = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
154
.getService(Components.interfaces.nsIBookmarksService);
155
gBookmarksService.updateBookmarkIcon(browser.currentURI.spec, aHref);
159
onProgressChange : function (aWebProgress, aRequest,
160
aCurSelfProgress, aMaxSelfProgress,
161
aCurTotalProgress, aMaxTotalProgress)
163
if (aMaxTotalProgress > 0) {
164
// This is highly optimized. Don't touch this code unless
165
// you are intimately familiar with the cost of setting
166
// attrs on XUL elements. -- hyatt
167
var percentage = (aCurTotalProgress * 100) / aMaxTotalProgress;
168
this.statusMeter.value = percentage;
172
onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
174
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
175
const nsIChannel = Components.interfaces.nsIChannel;
177
if (aStateFlags & nsIWebProgressListener.STATE_START) {
178
// This (thanks to the filter) is a network start or the first
179
// stray request (the first request outside of the document load),
180
// initialize the throbber and his friends.
182
// Call start document load listeners (only if this is a network load)
183
if (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK &&
184
aRequest && aWebProgress.DOMWindow == content)
185
this.startDocumentLoad(aRequest);
187
// Turn the throbber on.
188
this.throbberElement.setAttribute("busy", "true");
190
// XXX: These need to be based on window activity...
191
this.stopButton.disabled = false;
192
this.stopMenu.removeAttribute('disabled');
193
this.stopContext.removeAttribute('disabled');
195
else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
196
if (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
198
if (aWebProgress.DOMWindow == content)
199
this.endDocumentLoad(aRequest, aStatus);
203
// This (thanks to the filter) is a network stop or the last
204
// request stop outside of loading the document, stop throbbers
205
// and progress bars and such
208
// Get the channel if the request is a channel
211
channel = aRequest.QueryInterface(nsIChannel);
216
var location = channel.URI.spec;
217
if (location != "about:blank") {
218
const kErrorBindingAborted = 0x804B0002;
219
const kErrorNetTimeout = 0x804B000E;
221
case kErrorBindingAborted:
222
msg = gNavigatorBundle.getString("nv_stopped");
224
case kErrorNetTimeout:
225
msg = gNavigatorBundle.getString("nv_timeout");
230
// If msg is false then we did not have an error (channel may have
231
// been null, in the case of a stray image load).
233
msg = gNavigatorBundle.getString("nv_done");
236
this.setDefaultStatus(msg);
238
// Disable menu entries for images, enable otherwise
239
if (content.document && this.mimeTypeIsTextBased(content.document.contentType))
240
this.isImage.removeAttribute('disabled');
242
this.isImage.setAttribute('disabled', 'true');
245
// Turn the progress meter and throbber off.
246
this.statusMeter.value = 0; // be sure to clear the progress bar
247
this.throbberElement.removeAttribute("busy");
249
// XXX: These need to be based on window activity...
250
// XXXjag: <command id="cmd_stop"/> ?
251
this.stopButton.disabled = true;
252
this.stopMenu.setAttribute('disabled', 'true');
253
this.stopContext.setAttribute('disabled', 'true');
257
onLocationChange : function(aWebProgress, aRequest, aLocation)
259
// XXX temporary hack for bug 104532.
260
// Depends heavily on setOverLink implementation
262
this.status = this.jsStatus = this.jsDefaultStatus = "";
264
this.setOverLink("");
266
var locationURI = null;
272
gURIFixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
273
.getService(Components.interfaces.nsIURIFixup);
274
// If the url has "wyciwyg://" as the protocol, strip it off.
275
// Nobody wants to see it on the urlbar for dynamically generated
277
locationURI = gURIFixup.createExposableURI(aLocation);
278
location = locationURI.spec;
281
location = aLocation.spec;
285
if (!getWebNavigation().canGoBack && location == "about:blank")
288
// Disable menu entries for images, enable otherwise
289
if (content.document && this.mimeTypeIsTextBased(content.document.contentType))
290
this.isImage.removeAttribute('disabled');
292
this.isImage.setAttribute('disabled', 'true');
294
// We should probably not do this if the value has changed since the user
296
// Update urlbar only if a new page was loaded on the primary content area
297
// Do not update urlbar if there was a subframe navigation
299
var browser = getBrowser().selectedBrowser;
300
if (aWebProgress.DOMWindow == content) {
301
// The document loaded correctly, clear the value if we should
302
if (browser.userTypedClear > 0)
303
browser.userTypedValue = null;
305
var userTypedValue = browser.userTypedValue;
306
if (userTypedValue === null) {
307
this.urlBar.value = location;
308
if (this.urlBar.value != location) {
309
this.urlBar.value = ""; // hack for bug 249322
310
this.urlBar.value = location;
312
SetPageProxyState("valid", aLocation);
314
// Setting the urlBar value in some cases causes userTypedValue to
315
// become set because of oninput, so reset it to null
316
browser.userTypedValue = null;
318
this.urlBar.value = userTypedValue;
319
SetPageProxyState("invalid", null);
322
UpdateBackForwardButtons();
324
var blank = (location == "about:blank") || (location == "");
326
//clear popupDomain accordingly so that icon will go away when visiting
327
//an unblocked site after a blocked site. note: if a popup is blocked
328
//the icon will stay as long as we are in the same domain.
331
!("popupDomain" in browser)) {
332
browser.popupDomain = null;
337
hostPort = locationURI.hostPort;
340
if (hostPort != browser.popupDomain)
341
browser.popupDomain = null;
344
var popupIcon = document.getElementById("popupIcon");
345
popupIcon.hidden = !browser.popupDomain;
348
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
350
this.status = aMessage;
351
this.updateStatusField();
354
onSecurityChange : function(aWebProgress, aRequest, aState)
356
const wpl = Components.interfaces.nsIWebProgressListener;
359
case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_HIGH:
360
this.securityButton.setAttribute("level", "high");
362
case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_LOW:
363
this.securityButton.setAttribute("level", "low");
365
case wpl.STATE_IS_BROKEN:
366
this.securityButton.setAttribute("level", "broken");
368
case wpl.STATE_IS_INSECURE:
370
this.securityButton.removeAttribute("level");
374
var securityUI = getBrowser().securityUI;
376
this.securityButton.setAttribute("tooltiptext", securityUI.tooltipText);
378
this.securityButton.removeAttribute("tooltiptext");
381
startDocumentLoad : function(aRequest)
383
// It's okay to clear what the user typed when we start
384
// loading a document. If the user types, this flag gets
385
// set to false, if the document load ends without an
386
// onLocationChange, this flag also gets set to false
387
// (so we keep it while switching tabs after failed load
388
getBrowser().userTypedClear++;
390
const nsIChannel = Components.interfaces.nsIChannel;
391
var urlStr = aRequest.QueryInterface(nsIChannel).URI.spec;
392
var observerService = Components.classes["@mozilla.org/observer-service;1"]
393
.getService(Components.interfaces.nsIObserverService);
395
observerService.notifyObservers(_content, "StartDocumentLoad", urlStr);
400
endDocumentLoad : function(aRequest, aStatus)
402
// The document is done loading, it's okay to clear
404
if (getBrowser().userTypedClear > 0)
405
getBrowser().userTypedClear--;
407
const nsIChannel = Components.interfaces.nsIChannel;
408
var urlStr = aRequest.QueryInterface(nsIChannel).originalURI.spec;
410
if (Components.isSuccessCode(aStatus))
411
dump("Document "+urlStr+" loaded successfully\n"); // per QA request
414
var e = new Components.Exception("", aStatus);
416
dump("Error loading URL "+urlStr+" : "+
417
Number(aStatus).toString(16));
423
var observerService = Components.classes["@mozilla.org/observer-service;1"]
424
.getService(Components.interfaces.nsIObserverService);
426
var notification = Components.isSuccessCode(aStatus) ? "EndDocumentLoad" : "FailDocumentLoad";
428
observerService.notifyObservers(_content, notification, urlStr);