home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 March / PCWorld_2005-03_cd.bin / komunikace / kmeleon / kmeleon09.exe / comm.jar / content / communicator / contentAreaClick.js < prev    next >
Text File  |  2004-10-22  |  11KB  |  299 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.   function hrefForClickEvent(event)
  115.   {
  116.     var target = event.target;
  117.     var linkNode;
  118.  
  119.     var local_name = target.localName;
  120.  
  121.     if (local_name) {
  122.       local_name = local_name.toLowerCase();
  123.     }
  124.     
  125.     var isKeyPress = (event.type == "keypress");
  126.  
  127.     switch (local_name) {
  128.       case "a":
  129.       case "area":
  130.       case "link":
  131.         if (target.hasAttribute("href")) 
  132.           linkNode = target;
  133.         break;
  134.       case "input":
  135.         if ((event.target.type == "text") // text field
  136.             && !isKeyPress       // not a key event
  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.     var href;
  152.     if (linkNode) {
  153.       href = new XPCNativeWrapper(linkNode, "href").href;
  154.     } else {
  155.       // Try simple XLink
  156.       linkNode = target;
  157.       while (linkNode) {
  158.         if (linkNode.nodeType == Node.ELEMENT_NODE) {
  159.           var wrapper = new XPCNativeWrapper(linkNode, "getAttributeNS()");
  160.           href = wrapper.getAttributeNS("http://www.w3.org/1999/xlink", "href");
  161.           break;
  162.         }
  163.         linkNode = linkNode.parentNode;
  164.       }
  165.       if (href && href != "") {
  166.         var baseURI = new XPCNativeWrapper(linkNode, "baseURI").baseURI;
  167.         href = makeURLAbsolute(baseURI, href);
  168.       }
  169.     }
  170.     return href;
  171.   }
  172.  
  173.   // Called whenever the user clicks in the content area,
  174.   // except when left-clicking on links (special case)
  175.   // should always return true for click to go through
  176.   function contentAreaClick(event) 
  177.   {
  178.     if (!event.isTrusted) {
  179.       return true;
  180.     }
  181.  
  182.     var isKeyPress = (event.type == "keypress");
  183.     var href = hrefForClickEvent(event);
  184.     if (href) {
  185.       if (isKeyPress) {
  186.         openNewTabWith(href, true, event.shiftKey);
  187.         event.preventBubble();
  188.       }
  189.       else {
  190.         handleLinkClick(event, href, null);
  191.       }
  192.       return true;
  193.     }
  194.  
  195.     if (pref && !isKeyPress && event.button == 1 &&
  196.         !findParentNode(event.originalTarget, "scrollbar") &&
  197.         pref.getBoolPref("middlemouse.contentLoadURL")) {
  198.       if (middleMousePaste(event)) {
  199.         event.preventBubble();
  200.       }
  201.     }
  202.     return true;
  203.   }
  204.  
  205.   function openNewTabOrWindow(event, href, sendReferrer)
  206.   {
  207.     // should we open it in a new tab?
  208.     if (pref && pref.getBoolPref("browser.tabs.opentabfor.middleclick")) {
  209.       openNewTabWith(href, sendReferrer, event.shiftKey);
  210.       event.preventBubble();
  211.       return true;
  212.     }
  213.  
  214.     // should we open it in a new window?
  215.     if (pref && pref.getBoolPref("middlemouse.openNewWindow")) {
  216.       openNewWindowWith(href, sendReferrer);
  217.       event.preventBubble();
  218.       return true;
  219.     }
  220.  
  221.     // let someone else deal with it
  222.     return false;
  223.   }
  224.  
  225.   function handleLinkClick(event, href, linkNode)
  226.   {
  227.     // Make sure we are allowed to open this URL
  228.     urlSecurityCheck(href, document);
  229.  
  230.     switch (event.button) {                                   
  231.       case 0:                                                         // if left button clicked
  232.         if (event.metaKey || event.ctrlKey) {                         // and meta or ctrl are down
  233.           if (openNewTabOrWindow(event, href, true))
  234.             return true;
  235.         } 
  236.         var saveModifier = true;
  237.         if (pref) {
  238.           try {
  239.             saveModifier = pref.getBoolPref("ui.key.saveLink.shift");
  240.           }
  241.           catch(ex) {            
  242.           }
  243.         }
  244.         saveModifier = saveModifier ? event.shiftKey : event.altKey;
  245.           
  246.         if (saveModifier) {                                           // if saveModifier is down
  247.           saveURL(href, linkNode ? gatherTextUnder(linkNode) : "");
  248.           return true;
  249.         }
  250.         if (event.altKey)                                             // if alt is down
  251.           return true;                                                // do nothing
  252.         return false;
  253.       case 1:                                                         // if middle button clicked
  254.         if (openNewTabOrWindow(event, href, true))
  255.           return true;
  256.         break;
  257.     }
  258.     return false;
  259.   }
  260.  
  261.   function middleMousePaste( event )
  262.   {
  263.     var url = readFromClipboard();
  264.     if (!url)
  265.       return false;
  266.     url = getShortcutOrURI(url);
  267.  
  268.     // On ctrl-middleclick, open in new window or tab.  Do not send referrer.
  269.     if (event.ctrlKey) {
  270.       // fix up our pasted URI in case it is malformed.
  271.       const nsIURIFixup = Components.interfaces.nsIURIFixup;
  272.       if (!gURIFixup)
  273.         gURIFixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
  274.                               .getService(nsIURIFixup);
  275.  
  276.       url = gURIFixup.createFixupURI(url, nsIURIFixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI).spec;
  277.  
  278.       return openNewTabOrWindow(event, url, false);
  279.     }
  280.  
  281.     // If ctrl wasn't down, then just load the url in the current win/tab.
  282.     if (url != "about:blank") {
  283.       gURLBar.value = url;
  284.     }
  285.     loadURI(url);
  286.     event.preventBubble();
  287.     return true;
  288.   }
  289.  
  290.   function makeURLAbsolute( base, url ) 
  291.   {
  292.     // Construct nsIURL.
  293.     var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  294.                   .getService(Components.interfaces.nsIIOService);
  295.     var baseURI  = ioService.newURI(base, null, null);
  296.  
  297.     return ioService.newURI(baseURI.resolve(url), null, null).spec;
  298.   }
  299.