home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 97 / CD-ROM 97 / CD-ROM 97.iso / internet / ghostzilla / ghsetup.exe / chrome / comm.jar / content / navigator / nsBrowserStatusHandler.js < prev    next >
Encoding:
Text File  |  2002-04-10  |  14.3 KB  |  432 lines

  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
  4.  *
  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/
  9.  *
  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
  13.  * License.
  14.  *
  15.  * The Original Code is mozilla.org code.
  16.  *
  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.
  21.  *
  22.  * Contributor(s):
  23.  *   Blake Ross <blakeross@telocity.com>
  24.  *   Peter Annema <disttsc@bart.nl>
  25.  *
  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.
  37.  *
  38.  * ***** END LICENSE BLOCK ***** */
  39.  
  40. const NS_ERROR_MODULE_NETWORK = 2152398848;
  41. const NS_NET_STATUS_READ_FROM = NS_ERROR_MODULE_NETWORK + 8;
  42. const NS_NET_STATUS_WROTE_TO  = NS_ERROR_MODULE_NETWORK + 9;
  43.  
  44.  
  45. function nsBrowserStatusHandler()
  46. {
  47.   this.init();
  48. }
  49.  
  50. nsBrowserStatusHandler.prototype =
  51. {
  52.   userTyped :
  53.   {
  54.     _value : false,
  55.     browser : null,
  56.  
  57.     get value() {
  58.       if (this.browser != getBrowser().mCurrentBrowser)
  59.         this._value = false;
  60.       
  61.       return this._value;
  62.     },
  63.  
  64.     set value(aValue) {
  65.       if (this._value != aValue) {
  66.         this._value = aValue;
  67.         this.browser = aValue ? getBrowser().mCurrentBrowser : null;
  68.       }
  69.  
  70.       return aValue;
  71.     }
  72.   },
  73.  
  74.   useRealProgressFlag : false,
  75.   totalRequests : 0,
  76.   finishedRequests : 0,
  77.  
  78.   // Stored Status, Link and Loading values
  79.   status : "",
  80.   defaultStatus : "",
  81.   jsStatus : "",
  82.   jsDefaultStatus : "",
  83.   overLink : "",
  84.   startTime : 0,
  85.  
  86.   statusTimeoutInEffect : false,
  87.  
  88.   hideAboutBlank : true,
  89.  
  90.   QueryInterface : function(aIID)
  91.   {
  92.     if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
  93.         aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
  94.         aIID.equals(Components.interfaces.nsIXULBrowserWindow) ||
  95.         aIID.equals(Components.interfaces.nsISupports))
  96.       return this;
  97.     throw Components.results.NS_NOINTERFACE;
  98.   },
  99.  
  100.   init : function()
  101.   {
  102.     // XXXjag is this still needed? It's currently just ""
  103.     this.defaultStatus = gNavigatorBundle.getString("defaultStatus");
  104.  
  105.     this.urlBar          = document.getElementById("urlbar");
  106.     this.throbberElement = document.getElementById("navigator-throbber");
  107.     this.statusMeter     = document.getElementById("statusbar-icon");
  108.     this.stopButton      = document.getElementById("stop-button");
  109.     this.stopMenu        = document.getElementById("menuitem-stop");
  110.     this.stopContext     = document.getElementById("context-stop");
  111.     this.statusTextField = document.getElementById("statusbar-display");
  112.     this.isImage         = document.getElementById("isImage");
  113.     this.securityButton  = document.getElementById("security-button");
  114.  
  115.     // Initialize the security button's state and tooltip text
  116.     const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
  117.     this.onSecurityChange(null, null, nsIWebProgressListener.STATE_IS_INSECURE);
  118.   },
  119.  
  120.   destroy : function()
  121.   {
  122.     // XXXjag to avoid leaks :-/, see bug 60729
  123.     this.urlBar          = null;
  124.     this.throbberElement = null;
  125.     this.statusMeter     = null;
  126.     this.stopButton      = null;
  127.     this.stopMenu        = null;
  128.     this.stopContext     = null;
  129.     this.statusTextField = null;
  130.     this.isImage         = null;
  131.     this.securityButton  = null;
  132.     this.userTyped       = null;
  133.   },
  134.  
  135.   setJSStatus : function(status)
  136.   {
  137.     this.jsStatus = status;
  138.     this.updateStatusField();
  139.   },
  140.  
  141.   setJSDefaultStatus : function(status)
  142.   {
  143.     this.jsDefaultStatus = status;
  144.     this.updateStatusField();
  145.   },
  146.  
  147.   setDefaultStatus : function(status)
  148.   {
  149.     this.defaultStatus = status;
  150.     this.updateStatusField();
  151.   },
  152.  
  153.   setOverLink : function(link, b)
  154.   {
  155.     this.overLink = link;
  156.     this.updateStatusField();
  157.     if (link)
  158.       this.statusTextField.setAttribute('crop', 'center');
  159.     else
  160.       this.statusTextField.setAttribute('crop', 'end');
  161.   },
  162.  
  163.   updateStatusField : function()
  164.   {
  165.     var text = this.overLink || this.status || this.jsStatus || this.jsDefaultStatus || this.defaultStatus;
  166.  
  167.     // check the current value so we don't trigger an attribute change
  168.     // and cause needless (slow!) UI updates
  169.     if (this.statusTextField.label != text)
  170.       this.statusTextField.label = text;
  171.   },
  172.  
  173.   mimeTypeIsTextBased : function(contentType)
  174.   {
  175.     return /^text\/|\+xml$/.test(contentType) ||
  176.            contentType == "application/x-javascript" ||
  177.            contentType == "application/xml" ||
  178.            contentType == "mozilla.application/cached-xul";
  179.   },
  180.  
  181.   onLinkIconAvailable : function(aHref) {
  182.     if (gProxyFavIcon && pref.getBoolPref("browser.chrome.site_icons"))
  183.     {
  184.       gProxyFavIcon.setAttribute("src", aHref);
  185.  
  186.       // update any bookmarks with new icon reference
  187.       if (!gBookmarksService)
  188.         gBookmarksService = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
  189.                                       .getService(Components.interfaces.nsIBookmarksService);
  190.       gBookmarksService.updateBookmarkIcon(this.urlBar.value, aHref);
  191.     }
  192.   },
  193.  
  194.   onProgressChange : function (aWebProgress, aRequest,
  195.                                aCurSelfProgress, aMaxSelfProgress,
  196.                                aCurTotalProgress, aMaxTotalProgress)
  197.   {
  198.     if (!this.useRealProgressFlag && aRequest)
  199.       return;
  200.  
  201.     if (aMaxTotalProgress > 0) {
  202.       // This is highly optimized.  Don't touch this code unless
  203.       // you are intimately familiar with the cost of setting
  204.       // attrs on XUL elements. -- hyatt
  205.       var percentage = (aCurTotalProgress * 100) / aMaxTotalProgress;
  206.       this.statusMeter.value = percentage;
  207.     } 
  208.   },
  209.  
  210.   onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
  211.   {  
  212.     //ignore local/resource:/chrome: files
  213.     if (aStatus == NS_NET_STATUS_READ_FROM || aStatus == NS_NET_STATUS_WROTE_TO)
  214.       return;
  215.  
  216.     const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
  217.     const nsIChannel = Components.interfaces.nsIChannel;
  218.     var ctype;
  219.     if (aStateFlags & nsIWebProgressListener.STATE_START) {
  220.       if (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
  221.         // Remember when loading commenced.
  222.         this.startTime = (new Date()).getTime();
  223.  
  224.         if (aRequest && aWebProgress.DOMWindow == content)
  225.           this.startDocumentLoad(aRequest);
  226.  
  227.         // Turn the throbber on.
  228.         this.throbberElement.setAttribute("busy", true);
  229.  
  230.         // XXX: These need to be based on window activity...
  231.         this.stopButton.disabled = false;
  232.         this.stopMenu.removeAttribute('disabled');
  233.         this.stopContext.removeAttribute('disabled');
  234.  
  235.         // Initialize the progress stuff...
  236.         this.useRealProgressFlag = false;
  237.         this.totalRequests = 0;
  238.         this.finishedRequests = 0;
  239.       }
  240.  
  241.       if (aStateFlags & nsIWebProgressListener.STATE_IS_REQUEST) {
  242.         this.totalRequests += 1;
  243.       }
  244.     }
  245.     else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
  246.       if (aStateFlags & nsIWebProgressListener.STATE_IS_REQUEST) {
  247.         this.finishedRequests += 1;
  248.         if (!this.useRealProgressFlag)
  249.           this.onProgressChange(null, null, 0, 0, this.finishedRequests, this.totalRequests);
  250.       }
  251.       if (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
  252.         if (aRequest) {
  253.           if (aWebProgress.DOMWindow == content)
  254.             this.endDocumentLoad(aRequest, aStatus);
  255.  
  256.           var location = aRequest.QueryInterface(nsIChannel).URI.spec;
  257.           var msg = "";
  258.           if (location != "about:blank") {
  259.             // Record page loading time.
  260.             var elapsed = ((new Date()).getTime() - this.startTime) / 1000;
  261.             msg = gNavigatorBundle.getString("nv_done");
  262.             msg = msg.replace(/%elapsed%/, elapsed);
  263.           }
  264.           this.status = "";
  265.           this.setDefaultStatus(msg);
  266.           try {
  267.             ctype = aRequest.QueryInterface(nsIChannel).contentType;
  268.             if (this.mimeTypeIsTextBased(ctype)) 
  269.               this.isImage.removeAttribute('disabled');
  270.             else
  271.               this.isImage.setAttribute('disabled', 'true');
  272.           }
  273.           catch (e) {}
  274.         }
  275.  
  276.         // Turn the progress meter and throbber off.
  277.         this.statusMeter.value = 0;  // be sure to clear the progress bar
  278.         this.throbberElement.removeAttribute("busy");
  279.  
  280.         // XXX: These need to be based on window activity...
  281.         // XXXjag: <command id="cmd_stop"/> ?
  282.         this.stopButton.disabled = true;
  283.         this.stopMenu.setAttribute('disabled', 'true');
  284.         this.stopContext.setAttribute('disabled', 'true');
  285.  
  286.       }
  287.     }
  288.     else if (aStateFlags & nsIWebProgressListener.STATE_TRANSFERRING) {
  289.       if (aStateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT) {
  290.         ctype = aRequest.QueryInterface(nsIChannel).contentType;
  291.  
  292.         if (ctype != "text/html")
  293.           this.useRealProgressFlag = true;
  294.       }
  295.  
  296.       if (aStateFlags & nsIWebProgressListener.STATE_IS_REQUEST) {
  297.         if (!this.useRealProgressFlag)
  298.           this.onProgressChange(null, null, 0, 0, this.finishedRequests, this.totalRequests);
  299.       }
  300.     }
  301.   },
  302.  
  303.   onLocationChange : function(aWebProgress, aRequest, aLocation)
  304.   {
  305.     this.setOverLink("", null);
  306.  
  307.     var location = aLocation.spec;
  308.  
  309.     if (this.hideAboutBlank) {
  310.       this.hideAboutBlank = false;
  311.       if (location == "about:blank")
  312.         location = "";
  313.     }
  314.  
  315.     // Disable menu entries for images, enable otherwise
  316.     if (this.mimeTypeIsTextBased(content.document.contentType))
  317.       this.isImage.removeAttribute('disabled');
  318.     else
  319.       this.isImage.setAttribute('disabled', 'true');
  320.  
  321.     // We should probably not do this if the value has changed since the user
  322.     // searched
  323.     // Update urlbar only if a new page was loaded on the primary content area
  324.     // Do not update urlbar if there was a subframe navigation
  325.  
  326.     if (aWebProgress.DOMWindow == content) {
  327.       if (!this.userTyped.value) {
  328.         // If the url has "wyciwyg://" as the protocol, strip it off.
  329.         // Nobody wants to see it on the urlbar for dynamically generated
  330.         // pages. 
  331.         if (/^\s*wyciwyg:\/\/\d+\//.test(location))
  332.           location = RegExp.rightContext;
  333.         this.urlBar.value = location;
  334.         // the above causes userTyped.value to become true, reset it
  335.         this.userTyped.value = false;
  336.       }
  337.  
  338.       SetPageProxyState("valid", aLocation);
  339.     }
  340.     UpdateBackForwardButtons();
  341.   },
  342.  
  343.   onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
  344.   {
  345.     //ignore local/resource:/chrome: files
  346.     if (aStatus == NS_NET_STATUS_READ_FROM || aStatus == NS_NET_STATUS_WROTE_TO)
  347.       return;
  348.  
  349.     this.status = aMessage;
  350.  
  351.     if (!this.statusTimeoutInEffect) {
  352.       this.statusTimeoutInEffect = true;
  353.       this.updateStatusField();
  354.       setTimeout(function(aClosure) { aClosure.updateStatusField();
  355.                                       aClosure.statusTimeoutInEffect = false; },
  356.                  400, this);
  357.     }
  358.   },
  359.  
  360.   onSecurityChange : function(aWebProgress, aRequest, aState)
  361.   {
  362.     const wpl = Components.interfaces.nsIWebProgressListener;
  363.  
  364.     switch (aState) {
  365.       case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_HIGH:
  366.         this.securityButton.setAttribute("level", "high");
  367.         break;
  368.       case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_LOW:
  369.         this.securityButton.setAttribute("level", "low");
  370.         break;
  371.       case wpl.STATE_IS_BROKEN:
  372.         this.securityButton.setAttribute("level", "broken");
  373.         break;
  374.       case wpl.STATE_IS_INSECURE:
  375.       default:
  376.         this.securityButton.removeAttribute("level");
  377.         break;
  378.     }
  379.  
  380.     var securityUI = getBrowser().securityUI;
  381.     if (securityUI)
  382.       this.securityButton.setAttribute("tooltiptext", securityUI.tooltipText);
  383.     else
  384.       this.securityButton.removeAttribute("tooltiptext");
  385.   },
  386.  
  387.   startDocumentLoad : function(aRequest)
  388.   {
  389.     // Reset so we can see if the user typed after the document load
  390.     // starting and the location changing.
  391.     this.userTyped.value = false;
  392.  
  393.     const nsIChannel = Components.interfaces.nsIChannel;
  394.     var urlStr = aRequest.QueryInterface(nsIChannel).URI.spec;
  395.     var observerService = Components.classes["@mozilla.org/observer-service;1"]
  396.                                     .getService(Components.interfaces.nsIObserverService);
  397.     try {
  398.       observerService.notifyObservers(_content, "StartDocumentLoad", urlStr);
  399.     } catch (e) {
  400.     }
  401.   },
  402.  
  403.   endDocumentLoad : function(aRequest, aStatus)
  404.   {
  405.     const nsIChannel = Components.interfaces.nsIChannel;
  406.     var urlStr = aRequest.QueryInterface(nsIChannel).originalURI.spec;
  407.  
  408.     if (Components.isSuccessCode(aStatus))
  409.       dump("Document "+urlStr+" loaded successfully\n"); // per QA request
  410.     else {
  411.       // per QA request
  412.       var e = new Components.Exception("", aStatus);
  413.       var name = e.name;
  414.       dump("Error loading URL "+urlStr+" : "+
  415.            Number(aStatus).toString(16));
  416.       if (name)
  417.            dump(" ("+name+")");
  418.       dump('\n'); 
  419.     }
  420.  
  421.     var observerService = Components.classes["@mozilla.org/observer-service;1"]
  422.                                     .getService(Components.interfaces.nsIObserverService);
  423.  
  424.     var notification = Components.isSuccessCode(aStatus) ? "EndDocumentLoad" : "FailDocumentLoad";
  425.     try {
  426.       observerService.notifyObservers(_content, notification, urlStr);
  427.     } catch (e) {
  428.     }
  429.   }
  430. }
  431.  
  432.