home *** CD-ROM | disk | FTP | other *** search
/ PC World 2003 May / PCWorld_2003-05_cd.bin / Komunik / phoenix / chrome / comm.jar / content / communicator / contentAreaClick.js < prev    next >
Encoding:
JavaScript  |  2002-11-13  |  9.9 KB  |  268 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.  *   Alec Flett      <alecf@netscape.com>
  24.  *   Ben Goodger     <ben@netscape.com>
  25.  *   Mike Pinkerton  <pinkerton@netscape.com>
  26.  *   Blake Ross      <blakeross@telocity.com>
  27.  *
  28.  * Alternatively, the contents of this file may be used under the terms of
  29.  * either the GNU General Public License Version 2 or later (the "GPL"), or 
  30.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  31.  * in which case the provisions of the GPL or the LGPL are applicable instead
  32.  * of those above. If you wish to allow use of your version of this file only
  33.  * under the terms of either the GPL or the LGPL, and not to allow others to
  34.  * use your version of this file under the terms of the NPL, indicate your
  35.  * decision by deleting the provisions above and replace them with the notice
  36.  * and other provisions required by the GPL or the LGPL. If you do not delete
  37.  * the provisions above, a recipient may use your version of this file under
  38.  * the terms of any one of the NPL, the GPL or the LGPL.
  39.  *
  40.  * ***** END LICENSE BLOCK ***** */
  41.  
  42. /*
  43.  * - [ Dependencies ] ---------------------------------------------------------
  44.  *  utilityOverlay.js:
  45.  *    - gatherTextUnder
  46.  */
  47.  
  48.   var pref = null;
  49.   pref = Components.classes["@mozilla.org/preferences-service;1"]
  50.                    .getService(Components.interfaces.nsIPrefBranch);
  51.  
  52.   // Prefill a single text field
  53.   function prefillTextBox(target) {
  54.  
  55.     // obtain values to be used for prefilling
  56.     var walletService = Components.classes["@mozilla.org/wallet/wallet-service;1"].getService(Components.interfaces.nsIWalletService);
  57.     var value = walletService.WALLET_PrefillOneElement(window._content, target);
  58.     if (value) {
  59.  
  60.       // result is a linear sequence of values, each preceded by a separator character
  61.       // convert linear sequence of values into an array of values
  62.       var separator = value[0];
  63.       var valueList = value.substring(1, value.length).split(separator);
  64.  
  65.       target.value = valueList[0];
  66. /*
  67.  * Following code is a replacement for above line.  In the case of multiple values, it
  68.  * presents the user with a dialog containing a list from which he can select the value
  69.  * he wants.  However it is being commented out for now because of several problems, namely
  70.  *
  71.  *   1. There is no easy way to put localizable strings for the title and message of
  72.  *      the dialog without introducing a .properties file which currently doesn't exist
  73.  *   2. Using blank title and messages as shown below have a problem because a zero-length
  74.  *      title is being displayed as some garbage characters (which is why the code below
  75.  *      has a title of " " instead of "").  This is a separate bug which will have to be
  76.  *      investigated further.
  77.  *   3. The current wallet tables present alternate values for items such as shipping
  78.  *      address -- namely billing address and home address.  Up until now, these alternate
  79.  *      values have never been a problem because the preferred value is always first and is
  80.  *      all the user sees when doing a prefill.  However now he will be presented with a
  81.  *      list showing all these values and asking him to pick one, even though the wallet
  82.  *      code was clearly able to determine that he meant shipping address and not billing
  83.  *      address.
  84.  *   4. There is a relatively long delay before the dialog come up whereas values are
  85.  *      filled in quickly when no dialog is involved.
  86.  *
  87.  * Once this feature is checked in, a separate bug will be opened asking that the above
  88.  * problems be examined and this dialog turned on
  89.  
  90.       if (valueList.length == 1) {
  91.         // only one value, use it for prefilling
  92.         target.value = valueList[0];
  93.       } else {
  94.  
  95.         // more than one value, have user select the one he wants
  96.         var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
  97.         promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
  98.         var position = {};
  99.         var title = " ";
  100.         var message = "";
  101.         var ok =
  102.           promptService.select
  103.             (window, title, message, valueList.length, valueList, position)
  104.         if (ok) {
  105.           target.value = valueList[position.value];
  106.         }
  107.       }
  108.  
  109.  * End of commented out code
  110.  */
  111.     }
  112.   }
  113.   
  114.   // Called whenever the user clicks in the content area,
  115.   // except when left-clicking on links (special case)
  116.   // should always return true for click to go through
  117.   function contentAreaClick(event) 
  118.   {
  119.     var target = event.target;
  120.     var linkNode;
  121.  
  122.     var local_name = target.localName;
  123.  
  124.     if (local_name) {
  125.       local_name = local_name.toLowerCase();
  126.     }
  127.  
  128.     switch (local_name) {
  129.       case "a":
  130.       case "area":
  131.       case "link":
  132.         if (target.hasAttribute("href")) 
  133.           linkNode = target;
  134.         break;
  135.       case "input":
  136.         if ((event.target.type.toLowerCase() == "text" || event.target.type == "") // text field
  137.             && event.detail == 2 // double click
  138.             && event.button == 0 // left mouse button
  139.             && event.target.value.length == 0) { // no text has been entered
  140.           prefillTextBox(target); // prefill the empty text field if possible
  141.         }
  142.         break;
  143.       default:
  144.         linkNode = findParentNode(event.originalTarget, "a");
  145.         // <a> cannot be nested.  So if we find an anchor without an
  146.         // href, there is no useful <a> around the target
  147.         if (linkNode && !linkNode.hasAttribute("href"))
  148.           linkNode = null;
  149.         break;
  150.     }
  151.     if (linkNode) {
  152.       handleLinkClick(event, linkNode.href, linkNode);
  153.       return true;
  154.     } else {
  155.       // Try simple XLink
  156.       var href;
  157.       linkNode = target;
  158.       while (linkNode) {
  159.         if (linkNode.nodeType == Node.ELEMENT_NODE) {
  160.           href = linkNode.getAttributeNS("http://www.w3.org/1999/xlink", "href");
  161.           break;
  162.         }
  163.         linkNode = linkNode.parentNode;
  164.       }
  165.       if (href && href != "") {
  166.         href = makeURLAbsolute(target.baseURI,href);
  167.         handleLinkClick(event, href, null);
  168.         return true;
  169.       }
  170.     }
  171.     if (pref && event.button == 1 &&
  172.         !findParentNode(event.originalTarget, "scrollbar") &&
  173.         pref.getBoolPref("middlemouse.contentLoadURL")) {
  174.       if (middleMousePaste(event)) {
  175.         event.preventBubble();
  176.       }
  177.     }
  178.     return true;
  179.   }
  180.  
  181.   function openNewTabOrWindow(event, href, sendReferrer)
  182.   {
  183.     // should we open it in a new tab?
  184.     if (pref && pref.getBoolPref("browser.tabs.opentabfor.middleclick")) {
  185.       openNewTabWith(href, sendReferrer, event.shiftKey);
  186.       event.preventBubble();
  187.       return true;
  188.     }
  189.  
  190.     // should we open it in a new window?
  191.     if (pref && pref.getBoolPref("middlemouse.openNewWindow")) {
  192.       openNewWindowWith(href, sendReferrer);
  193.       event.preventBubble();
  194.       return true;
  195.     }
  196.  
  197.     // let someone else deal with it
  198.     return false;
  199.   }
  200.  
  201.   function handleLinkClick(event, href, linkNode)
  202.   {
  203.     // Make sure we are allowed to open this URL
  204.     urlSecurityCheck(href, document);
  205.  
  206.     switch (event.button) {                                   
  207.       case 0:                                                         // if left button clicked
  208.         if (event.metaKey || event.ctrlKey) {                         // and meta or ctrl are down
  209.           if (openNewTabOrWindow(event, href, true))
  210.             return true;
  211.         } 
  212.         var saveModifier = true;
  213.         if (pref) {
  214.           try {
  215.             saveModifier = pref.getBoolPref("ui.key.saveLink.shift");
  216.           }
  217.           catch(ex) {            
  218.           }
  219.         }
  220.         saveModifier = saveModifier ? event.shiftKey : event.altKey;
  221.           
  222.         if (saveModifier) {                                           // if saveModifier is down
  223.           saveURL(href, linkNode ? gatherTextUnder(linkNode) : "");
  224.           return true;
  225.         }
  226.         if (event.altKey)                                             // if alt is down
  227.           return true;                                                // do nothing
  228.         return false;
  229.       case 1:                                                         // if middle button clicked
  230.         if (openNewTabOrWindow(event, href, true))
  231.           return true;
  232.         break;
  233.     }
  234.     return false;
  235.   }
  236.  
  237.   function middleMousePaste( event )
  238.   {
  239.     var url = readFromClipboard();
  240.     if (!url)
  241.       return false;
  242.     url = getShortcutOrURI(url);
  243.     if (!url)
  244.       return false;
  245.  
  246.     // On ctrl-middleclick, open in new window or tab.  Do not send referrer.
  247.     if (event.ctrlKey)
  248.       return openNewTabOrWindow(event, url, false);
  249.  
  250.     // If ctrl wasn't down, then just load the url in the current win/tab.
  251.     if (url != "about:blank") {
  252.       gURLBar.value = url;
  253.     }
  254.     loadURI(url);
  255.     event.preventBubble();
  256.     return true;
  257.   }
  258.  
  259.   function makeURLAbsolute( base, url ) 
  260.   {
  261.     // Construct nsIURL.
  262.     var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  263.                   .getService(Components.interfaces.nsIIOService);
  264.     var baseURI  = ioService.newURI(base, null, null);
  265.  
  266.     return ioService.newURI(baseURI.resolve(url), null, null).spec;
  267.   }
  268.