File:  [mozdev] / chimera / ContentClickListener.mm
Revision 1.5: download - view: text, annotated - select for diffs - revision graph
Fri Mar 8 19:21:43 2002 UTC (17 years, 9 months ago) by hyatt
Branches: MAIN
CVS tags: HEAD
Working on option-clickto save a link.

    1: /* -*- Mode: C++; 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) 2002
   20:  * the Initial Developer. All Rights Reserved.
   21:  *
   22:  * Contributor(s):
   23:  *
   24:  * Alternatively, the contents of this file may be used under the terms of
   25:  * either the GNU General Public License Version 2 or later (the "GPL"), or 
   26:  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
   27:  * in which case the provisions of the GPL or the LGPL are applicable instead
   28:  * of those above. If you wish to allow use of your version of this file only
   29:  * under the terms of either the GPL or the LGPL, and not to allow others to
   30:  * use your version of this file under the terms of the NPL, indicate your
   31:  * decision by deleting the provisions above and replace them with the notice
   32:  * and other provisions required by the GPL or the LGPL. If you do not delete
   33:  * the provisions above, a recipient may use your version of this file under
   34:  * the terms of any one of the NPL, the GPL or the LGPL.
   35:  *
   36:  * ***** END LICENSE BLOCK ***** */
   37: 
   38: #include "nsCOMPtr.h"
   39: #include "ContentClickListener.h"
   40: #include "nsIDOMEventTarget.h"
   41: #include "nsIContent.h"
   42: #include "nsIAtom.h"
   43: #include "nsIDOMElement.h"
   44: #include "nsString.h"
   45: #include "nsUnicharUtils.h"
   46: #include "nsIPrefBranch.h"
   47: #include "nsIDOMMouseEvent.h"
   48: #include "nsEmbedAPI.h"
   49: #include "nsIDOMHTMLAnchorElement.h"
   50: #include "nsIDOMHTMLAreaElement.h"
   51: #include "nsIDOMHTMLLinkElement.h"
   52: 
   53: // Common helper routines (also used by the context menu code)
   54: #include "GeckoUtils.h"
   55: 
   56: NS_IMPL_ISUPPORTS2(ContentClickListener, nsIDOMMouseListener, nsIDOMEventListener);
   57: 
   58: ContentClickListener::ContentClickListener(id aBrowserController)
   59: :mBrowserController(aBrowserController)
   60: {
   61:   NS_INIT_ISUPPORTS();
   62: }
   63: 
   64: ContentClickListener::~ContentClickListener()
   65: {
   66: 
   67: }
   68: 
   69: NS_IMETHODIMP
   70: ContentClickListener::MouseClick(nsIDOMEvent* aEvent)
   71: {
   72:   nsCOMPtr<nsIDOMEventTarget> target;
   73:   aEvent->GetTarget(getter_AddRefs(target));
   74:   if (!target)
   75:     return NS_OK;
   76:   nsCOMPtr<nsIDOMElement> content(do_QueryInterface(target));
   77:   nsAutoString localName;
   78:   if (content)
   79:     content->GetLocalName(localName);
   80:   
   81:   nsCOMPtr<nsIDOMElement> linkContent;
   82:   ToLowerCase(localName);
   83:   nsAutoString href;
   84:   if (localName.Equals(NS_LITERAL_STRING("a")) ||
   85:       localName.Equals(NS_LITERAL_STRING("area")) ||
   86:       localName.Equals(NS_LITERAL_STRING("link"))) {
   87:     PRBool hasAttr;
   88:     content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
   89:     if (hasAttr) {
   90:       linkContent = content;
   91:       nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(linkContent));
   92:       if (anchor)
   93:         anchor->GetHref(href);
   94:       else {
   95:         nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(linkContent));
   96:         if (area)
   97:           area->GetHref(href);
   98:         else {
   99:           nsCOMPtr<nsIDOMHTMLLinkElement> link(do_QueryInterface(linkContent));
  100:           if (link)
  101:             link->GetHref(href);
  102:         }
  103:       }
  104:     }
  105:   }
  106:   else {
  107:     // XXXdwh Handle prefilling of forms (input fields) on a click.
  108:     nsCOMPtr<nsIDOMNode> curr(do_QueryInterface(target));
  109:     nsCOMPtr<nsIDOMNode> temp = curr;
  110:     temp->GetParentNode(getter_AddRefs(curr));
  111:     while (curr) {
  112:       content = do_QueryInterface(curr);
  113:       if (!content)
  114:         break;
  115:       content->GetLocalName(localName);
  116:       ToLowerCase(localName);
  117:       if (localName.Equals(NS_LITERAL_STRING("a"))) {
  118:         PRBool hasAttr;
  119:         content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
  120:         if (hasAttr) {
  121:           linkContent = content;
  122:           nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(linkContent));
  123:           if (anchor)
  124:             anchor->GetHref(href);
  125:         }
  126:         else
  127:           linkContent = nsnull; // Links can't be nested.
  128:         break;
  129:       }
  130:       
  131:       temp = curr;
  132:       temp->GetParentNode(getter_AddRefs(curr));
  133:     }
  134:   }
  135:   
  136:   // XXXdwh Handle simple XLINKs if we want to be compatible with Mozilla, but who
  137:   // really uses these anyway? :)
  138:   if (!linkContent || href.IsEmpty())
  139:     return NS_OK;
  140: 
  141:   NSString* hrefStr = [NSString stringWithCharacters: href.get() length:nsCRT::strlen(href.get())];
  142:   NSURL* urlToLoad = [NSURL URLWithString: hrefStr];
  143:   
  144:   nsCOMPtr<nsIPrefBranch> pref(do_GetService("@mozilla.org/preferences-service;1"));
  145:   if (!pref)
  146:     return NS_OK; // Something bad happened if we can't get prefs.
  147:     
  148:   PRUint16 button;
  149:   nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(aEvent));
  150:   mouseEvent->GetButton(&button);
  151:   switch (button) {
  152:     case 0: {
  153:       PRBool metaKey, shiftKey, altKey;
  154:       mouseEvent->GetMetaKey(&metaKey);
  155:       mouseEvent->GetShiftKey(&shiftKey);
  156:       mouseEvent->GetAltKey(&altKey);
  157:       if (metaKey) {
  158:         // The command key is down.  Open the link in a new window or tab.
  159:         PRBool useTab;
  160:         pref->GetBoolPref("browser.tabs.opentabfor.middleclick", &useTab);
  161:         PRBool loadInBackground;
  162:         pref->GetBoolPref("browser.tabs.loadInBackground", &loadInBackground);
  163:         if (shiftKey)
  164:           loadInBackground = !loadInBackground;
  165:         if (useTab)
  166:           [mBrowserController openNewTabWithURL: urlToLoad loadInBackground: loadInBackground];
  167:         else
  168:           [mBrowserController openNewWindowWithURL: urlToLoad loadInBackground: loadInBackground];
  169:       }
  170:       else if (altKey) {
  171:         // The user wants to save this link.
  172:         nsAutoString text;
  173:         GeckoUtils::GatherTextUnder(content, text);
  174:         
  175:       }
  176:     }
  177:   }
  178:     
  179:   return NS_OK;
  180: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>