home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 March / PCWorld_2005-03_cd.bin / komunikace / kmeleon / kmeleon09.exe / comm.jar / content / navigator / nsBrowserStatusHandler.js < prev    next >
Text File  |  2004-10-22  |  16KB  |  434 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. function nsBrowserStatusHandler()
  41. {
  42.   this.init();
  43. }
  44.  
  45. nsBrowserStatusHandler.prototype =
  46. {
  47.   // Stored Status, Link and Loading values
  48.   status : "",
  49.   defaultStatus : "",
  50.   jsStatus : "",
  51.   jsDefaultStatus : "",
  52.   overLink : "",
  53.  
  54.   QueryInterface : function(aIID)
  55.   {
  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))
  60.       return this;
  61.     throw Components.results.NS_NOINTERFACE;
  62.   },
  63.  
  64.   init : function()
  65.   {
  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");
  75.  
  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);
  79.   },
  80.  
  81.   destroy : function()
  82.   {
  83.     // XXXjag to avoid leaks :-/, see bug 60729
  84.     this.urlBar          = null;
  85.     this.throbberElement = null;
  86.     this.statusMeter     = null;
  87.     this.stopButton      = null;
  88.     this.stopMenu        = null;
  89.     this.stopContext     = null;
  90.     this.statusTextField = null;
  91.     this.isImage         = null;
  92.     this.securityButton  = null;
  93.   },
  94.  
  95.   setJSStatus : function(status)
  96.   {
  97.     this.jsStatus = status;
  98.     this.updateStatusField();
  99.   },
  100.  
  101.   setJSDefaultStatus : function(status)
  102.   {
  103.     this.jsDefaultStatus = status;
  104.     this.updateStatusField();
  105.   },
  106.  
  107.   setDefaultStatus : function(status)
  108.   {
  109.     this.defaultStatus = status;
  110.     this.updateStatusField();
  111.   },
  112.  
  113.   setOverLink : function(link)
  114.   {
  115.     this.overLink = link;
  116.     // clear out 'Done' (or other message) on first hover
  117.     if (this.defaultStatus)
  118.       this.defaultStatus = "";
  119.     this.updateStatusField();
  120.     if (link)
  121.       this.statusTextField.setAttribute('crop', 'center');
  122.     else
  123.       this.statusTextField.setAttribute('crop', 'end');
  124.   },
  125.  
  126.   updateStatusField : function()
  127.   {
  128.     var text = this.overLink || this.status || this.jsStatus || this.jsDefaultStatus || this.defaultStatus;
  129.  
  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;
  134.   },
  135.  
  136.   mimeTypeIsTextBased : function(contentType)
  137.   {
  138.     return /^text\/|\+xml$/.test(contentType) ||
  139.            contentType == "application/x-javascript" ||
  140.            contentType == "application/xml" ||
  141.            contentType == "mozilla.application/cached-xul";
  142.   },
  143.  
  144.   onLinkIconAvailable : function(aHref)
  145.   {
  146.     if (gProxyFavIcon && pref.getBoolPref("browser.chrome.site_icons")) {
  147.       var browser = getBrowser();
  148.       if (browser.userTypedValue === null)
  149.         gProxyFavIcon.setAttribute("src", aHref);
  150.  
  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);
  156.     }
  157.   },
  158.  
  159.   onProgressChange : function (aWebProgress, aRequest,
  160.                                aCurSelfProgress, aMaxSelfProgress,
  161.                                aCurTotalProgress, aMaxTotalProgress)
  162.   {
  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;
  169.     } 
  170.   },
  171.  
  172.   onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
  173.   {  
  174.     const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
  175.     const nsIChannel = Components.interfaces.nsIChannel;
  176.     var ctype;
  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.
  181.  
  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);
  186.  
  187.       // Turn the throbber on.
  188.       this.throbberElement.setAttribute("busy", "true");
  189.  
  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');
  194.     }
  195.     else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
  196.       if (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
  197.         if (aRequest) {
  198.           if (aWebProgress.DOMWindow == content)
  199.             this.endDocumentLoad(aRequest, aStatus);
  200.         }
  201.       }
  202.  
  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
  206.       if (aRequest) {
  207.         var msg = "";
  208.         // Get the channel if the request is a channel
  209.         var channel;
  210.         try {
  211.           channel = aRequest.QueryInterface(nsIChannel);
  212.         }
  213.         catch(e) { };
  214.  
  215.         if (channel) {
  216.           var location = channel.URI.spec;
  217.           if (location != "about:blank") {
  218.             const kErrorBindingAborted = 0x804B0002;
  219.             const kErrorNetTimeout = 0x804B000E;
  220.             switch (aStatus) {
  221.               case kErrorBindingAborted:
  222.                 msg = gNavigatorBundle.getString("nv_stopped");
  223.                 break;
  224.               case kErrorNetTimeout:
  225.                 msg = gNavigatorBundle.getString("nv_timeout");
  226.                 break;
  227.             }
  228.           }
  229.         }
  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).
  232.         if (!msg) {
  233.           msg = gNavigatorBundle.getString("nv_done");
  234.         }
  235.         this.status = "";
  236.         this.setDefaultStatus(msg);
  237.         
  238.         // Disable menu entries for images, enable otherwise
  239.         if (content.document && this.mimeTypeIsTextBased(content.document.contentType))
  240.           this.isImage.removeAttribute('disabled');
  241.         else
  242.           this.isImage.setAttribute('disabled', 'true');
  243.       }
  244.  
  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");
  248.  
  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');
  254.     }
  255.   },
  256.  
  257.   onLocationChange : function(aWebProgress, aRequest, aLocation)
  258.   {
  259.     // XXX temporary hack for bug 104532.
  260.     // Depends heavily on setOverLink implementation
  261.     if (!aRequest)
  262.       this.status = this.jsStatus = this.jsDefaultStatus = "";
  263.  
  264.     this.setOverLink("");
  265.  
  266.     var locationURI = null;
  267.     var location = "";    
  268.  
  269.     if (aLocation) {
  270.       try {
  271.         if (!gURIFixup)
  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
  276.         // pages.
  277.         locationURI = gURIFixup.createExposableURI(aLocation);
  278.         location = locationURI.spec;
  279.       }
  280.       catch(ex) {
  281.         location = aLocation.spec;
  282.       }
  283.     }
  284.  
  285.     if (!getWebNavigation().canGoBack && location == "about:blank")
  286.       location = "";
  287.  
  288.     // Disable menu entries for images, enable otherwise
  289.     if (content.document && this.mimeTypeIsTextBased(content.document.contentType))
  290.       this.isImage.removeAttribute('disabled');
  291.     else
  292.       this.isImage.setAttribute('disabled', 'true');
  293.  
  294.     // We should probably not do this if the value has changed since the user
  295.     // searched
  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
  298.  
  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;
  304.  
  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;
  311.         }
  312.         SetPageProxyState("valid", aLocation);
  313.  
  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;
  317.       } else {
  318.         this.urlBar.value = userTypedValue;
  319.         SetPageProxyState("invalid", null);
  320.       }
  321.     }
  322.     UpdateBackForwardButtons();
  323.  
  324.     var blank = (location == "about:blank") || (location == "");
  325.  
  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.    
  329.  
  330.     if (blank ||
  331.         !("popupDomain" in browser)) {
  332.       browser.popupDomain = null;
  333.     }
  334.     else {
  335.       var hostPort = "";
  336.       try {
  337.         hostPort = locationURI.hostPort;
  338.       }
  339.       catch(ex) { }
  340.       if (hostPort != browser.popupDomain)
  341.         browser.popupDomain = null;
  342.     }
  343.  
  344.     var popupIcon = document.getElementById("popupIcon");
  345.     popupIcon.hidden = !browser.popupDomain;
  346.   },
  347.  
  348.   onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
  349.   {
  350.     this.status = aMessage;
  351.     this.updateStatusField();
  352.   },
  353.  
  354.   onSecurityChange : function(aWebProgress, aRequest, aState)
  355.   {
  356.     const wpl = Components.interfaces.nsIWebProgressListener;
  357.  
  358.     switch (aState) {
  359.       case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_HIGH:
  360.         this.securityButton.setAttribute("level", "high");
  361.         break;
  362.       case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_LOW:
  363.         this.securityButton.setAttribute("level", "low");
  364.         break;
  365.       case wpl.STATE_IS_BROKEN:
  366.         this.securityButton.setAttribute("level", "broken");
  367.         break;
  368.       case wpl.STATE_IS_INSECURE:
  369.       default:
  370.         this.securityButton.removeAttribute("level");
  371.         break;
  372.     }
  373.  
  374.     var securityUI = getBrowser().securityUI;
  375.     if (securityUI)
  376.       this.securityButton.setAttribute("tooltiptext", securityUI.tooltipText);
  377.     else
  378.       this.securityButton.removeAttribute("tooltiptext");
  379.   },
  380.  
  381.   startDocumentLoad : function(aRequest)
  382.   {
  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++;
  389.  
  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);
  394.     try {
  395.       observerService.notifyObservers(_content, "StartDocumentLoad", urlStr);
  396.     } catch (e) {
  397.     }
  398.   },
  399.  
  400.   endDocumentLoad : function(aRequest, aStatus)
  401.   {
  402.     // The document is done loading, it's okay to clear
  403.     // the value again.
  404.     if (getBrowser().userTypedClear > 0)
  405.       getBrowser().userTypedClear--;
  406.  
  407.     const nsIChannel = Components.interfaces.nsIChannel;
  408.     var urlStr = aRequest.QueryInterface(nsIChannel).originalURI.spec;
  409.  
  410.     if (Components.isSuccessCode(aStatus))
  411.       dump("Document "+urlStr+" loaded successfully\n"); // per QA request
  412.     else {
  413.       // per QA request
  414.       var e = new Components.Exception("", aStatus);
  415.       var name = e.name;
  416.       dump("Error loading URL "+urlStr+" : "+
  417.            Number(aStatus).toString(16));
  418.       if (name)
  419.            dump(" ("+name+")");
  420.       dump('\n'); 
  421.     }
  422.  
  423.     var observerService = Components.classes["@mozilla.org/observer-service;1"]
  424.                                     .getService(Components.interfaces.nsIObserverService);
  425.  
  426.     var notification = Components.isSuccessCode(aStatus) ? "EndDocumentLoad" : "FailDocumentLoad";
  427.     try {
  428.       observerService.notifyObservers(_content, notification, urlStr);
  429.     } catch (e) {
  430.     }
  431.   }
  432. }
  433.  
  434.