Back to index

lightning-sunbird  0.9+nobinonly
nsAEGetURLSuiteHandler.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Simon Fraser <sfraser@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 
00040 #include "nsMemory.h"
00041 
00042 #include "nsWindowUtils.h"
00043 #include "nsAETokens.h"
00044 
00045 #include "nsAEGetURLSuiteHandler.h"
00046 #include "nsCommandLineServiceMac.h"
00047 
00048 #include "nsCOMPtr.h"
00049 #include "nsIServiceManager.h"
00050 #include "nsIWindowMediator.h"
00051 #include "nsIXULWindow.h"
00052 
00053 #include "nsIURI.h"
00054 #include "nsNetUtil.h"
00055 
00056 using namespace nsWindowUtils;
00057 
00058 
00059 /*----------------------------------------------------------------------------
00060        AEGetURLSuiteHandler 
00061        
00062 ----------------------------------------------------------------------------*/
00063 AEGetURLSuiteHandler::AEGetURLSuiteHandler()
00064 {
00065 }
00066 
00067 /*----------------------------------------------------------------------------
00068        ~AEGetURLSuiteHandler 
00069        
00070 ----------------------------------------------------------------------------*/
00071 AEGetURLSuiteHandler::~AEGetURLSuiteHandler()
00072 {
00073 }
00074 
00075 
00076 /*----------------------------------------------------------------------------
00077        HandleGetURLSuiteEvent 
00078        
00079 ----------------------------------------------------------------------------*/
00080 void AEGetURLSuiteHandler::HandleGetURLSuiteEvent(const AppleEvent *appleEvent, AppleEvent *reply)
00081 {
00082        OSErr         err = noErr;
00083        
00084        AEEventID            eventID;
00085        OSType        typeCode;
00086        Size                 actualSize    = 0L;
00087        
00088        // Get the event ID
00089        err = AEGetAttributePtr(appleEvent,       keyEventIDAttr, 
00090                                                                typeType, 
00091                                                                &typeCode, 
00092                                                                (Ptr)&eventID, 
00093                                                                sizeof(eventID), 
00094                                                                &actualSize);
00095        ThrowIfOSErr(err);
00096        
00097        try
00098        {
00099               switch (eventID)
00100               {
00101                      case kGetURLEvent:
00102                             HandleGetURLEvent(appleEvent, reply);
00103                             break;
00104                             
00105                      default:
00106                             ThrowOSErr(errAEEventNotHandled);
00107                             break;
00108               }
00109        }
00110        catch (OSErr catchErr)
00111        {
00112               PutReplyErrorNumber(reply, catchErr);
00113               throw;
00114        }
00115        catch ( ... )
00116        {
00117               PutReplyErrorNumber(reply, paramErr);
00118               throw;
00119        }
00120 }
00121 
00122 
00123 /*----------------------------------------------------------------------------
00124        HandleGetURLEvent 
00125        
00126 ----------------------------------------------------------------------------*/
00127 void AEGetURLSuiteHandler::HandleGetURLEvent(const AppleEvent *appleEvent, AppleEvent *reply)
00128 {
00129        StAEDesc             directParameter;
00130        WindowPtr            targetWindow = NULL;
00131        OSErr                       err;
00132        
00133        // extract the direct parameter (an object specifier)
00134        err = ::AEGetKeyDesc(appleEvent, keyDirectObject, typeWildCard, &directParameter);
00135        ThrowIfOSErr(err);
00136 
00137        // we need to look for other parameters, to do with destination etc.
00138        long          dataSize = directParameter.GetDataSize();
00139        char*  urlString = (char *)nsMemory::Alloc(dataSize + 1);
00140        ThrowIfNil(urlString);      
00141        directParameter.GetCString(urlString, dataSize + 1);
00142 
00143        // bail if it is a chrome URL for security reasons (bug 305374)
00144         // Don't use nsIURI because xpcom may not be running
00145         CFURLRef url = ::CFURLCreateWithBytes(nsnull, (UInt8*)urlString,
00146                                               dataSize,
00147                                               kCFStringEncodingUTF8,
00148                                               nsnull);
00149         if (!url)
00150           return;
00151 
00152         CFStringRef scheme = ::CFURLCopyScheme(url);
00153         ::CFRelease(url);
00154         if (!scheme)
00155           return;
00156 
00157         CFComparisonResult isChrome = ::CFStringCompare(scheme, CFSTR("chrome"),
00158                                                         kCFCompareCaseInsensitive);
00159         ::CFRelease(scheme);
00160 
00161         if (isChrome == kCFCompareEqualTo)
00162           return;
00163 
00164        // get the destination window, if applicable
00165        StAEDesc             openInWindowDesc;
00166        err = ::AEGetKeyDesc(appleEvent, kInsideWindowParameter, typeObjectSpecifier, &openInWindowDesc);
00167        if (err != errAEDescNotFound)
00168        {
00169               // resolve the object specifier into a token record
00170               StAEDesc             tokenDesc;
00171               err = ::AEResolve(&openInWindowDesc, kAEIDoMinimum, &tokenDesc);
00172               ThrowIfOSErr(err);
00173               
00174               ConstAETokenDesc     tokenContainer(&tokenDesc);
00175               targetWindow = tokenContainer.GetWindowPtr();           
00176        }
00177 
00178   // if the AE didn't specify a target, try to dispatch to the frontmost
00179   // window. there user prefs for determining the actual target window
00180   // will be respected.
00181   if ( targetWindow )
00182     LoadURLInWindow(targetWindow, urlString);
00183   else {
00184     nsCOMPtr<nsIXULWindow> xulwindow;
00185     nsCOMPtr<nsIWindowMediator> mediator (
00186                                 do_GetService(NS_WINDOWMEDIATOR_CONTRACTID) );
00187     if ( mediator ) {
00188       nsCOMPtr<nsISimpleEnumerator> windowEnum;
00189       mediator->GetZOrderXULWindowEnumerator(
00190                   NS_LITERAL_STRING("navigator:browser").get(),
00191                   PR_TRUE, getter_AddRefs(windowEnum));
00192       if ( windowEnum ) {
00193         nsCOMPtr<nsISupports> windowSupports;
00194         windowEnum->GetNext(getter_AddRefs(windowSupports));
00195         xulwindow = do_QueryInterface(windowSupports);
00196       }
00197     }
00198     if ( xulwindow )
00199       LoadURLInXULWindow(xulwindow, urlString);
00200     else
00201       LoadURLInWindow(nsnull, urlString);
00202   }
00203 
00204        nsMemory::Free(urlString);  
00205 }
00206