mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-15 04:00:12 +01:00
1714 lines
52 KiB
C++
1714 lines
52 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is the Mozilla browser.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Netscape Communications, Inc.
|
|
* Portions created by the Initial Developer are Copyright (C) 1999
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Conrad Carlen <ccarlen@netscape.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#ifndef __CBrowserShell__
|
|
#include "CBrowserShell.h"
|
|
#endif
|
|
|
|
#include "nsCWebBrowser.h"
|
|
#include "nsIComponentManager.h"
|
|
#include "nsRepeater.h"
|
|
#include "nsString.h"
|
|
#include "nsXPIDLString.h"
|
|
#include "nsIWebBrowserChrome.h"
|
|
#include "nsIDocShell.h"
|
|
#include "nsIDocShellTreeOwner.h"
|
|
#include "nsIInterfaceRequestor.h"
|
|
#include "nsIInterfaceRequestorUtils.h"
|
|
#include "nsIWebProgressListener.h"
|
|
#include "nsIServiceManager.h"
|
|
#include "nsIClipboardCommands.h"
|
|
#include "nsIWalletService.h"
|
|
#include "nsIDOMWindow.h"
|
|
#include "nsIDOMWindowInternal.h"
|
|
#include "nsIDOMDocument.h"
|
|
#include "nsIDOMHTMLDocument.h"
|
|
#include "nsIDocument.h"
|
|
#include "nsIDOMHTMLCollection.h"
|
|
#include "nsIDOMHTMLLinkElement.h"
|
|
#include "nsIDOMHTMLAnchorElement.h"
|
|
#include "nsIDOMHTMLImageElement.h"
|
|
#include "nsIDOMNSDocument.h"
|
|
#include "nsIDOMLocation.h"
|
|
#include "nsIWebBrowserFind.h"
|
|
#include "nsIWebBrowserFocus.h"
|
|
#include "nsIWebBrowserPersist.h"
|
|
#include "nsIURI.h"
|
|
#include "nsWeakPtr.h"
|
|
#include "nsRect.h"
|
|
#include "nsReadableUtils.h"
|
|
#include "nsILocalFile.h"
|
|
#include "nsILocalFileMac.h"
|
|
#include "nsWeakReference.h"
|
|
#include "nsIChannel.h"
|
|
#include "nsIHistoryEntry.h"
|
|
#include "nsISHEntry.h"
|
|
#include "nsISHistory.h"
|
|
#include "nsIWebBrowserPrint.h"
|
|
#include "nsIMacTextInputEventSink.h"
|
|
#include "nsCRT.h"
|
|
#include "nsNetUtil.h"
|
|
#include "gfxIImageFrame.h"
|
|
#include "nsIImage.h"
|
|
|
|
// Local
|
|
#include "ApplIDs.h"
|
|
#include "CBrowserMsgDefs.h"
|
|
#include "CBrowserChrome.h"
|
|
#include "CWebBrowserCMAttachment.h"
|
|
#include "UMacUnicode.h"
|
|
#include "CHeaderSniffer.h"
|
|
#include "UCustomNavServicesDialogs.h"
|
|
|
|
// PowerPlant
|
|
#include <UModalDialogs.h>
|
|
#include <LStream.h>
|
|
#include <UNavServicesDialogs.h>
|
|
#include <LEditText.h>
|
|
#include <LCheckBox.h>
|
|
#include <UEventMgr.h>
|
|
|
|
// ToolBox
|
|
#include <InternetConfig.h>
|
|
|
|
const nsCString CBrowserShell::kEmptyCString;
|
|
nsCOMPtr<nsIDragHelperService> CBrowserShell::sDragHelper;
|
|
|
|
//*****************************************************************************
|
|
//*** CBrowserShellProgressListener
|
|
//*****************************************************************************
|
|
|
|
class CBrowserShellProgressListener : public nsIWebProgressListener,
|
|
public nsSupportsWeakReference
|
|
{
|
|
public:
|
|
CBrowserShellProgressListener(CBrowserShell* itsOwner);
|
|
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_NSIWEBPROGRESSLISTENER
|
|
|
|
void SetOwner(CBrowserShell* itsOwner)
|
|
{ mpOwner = itsOwner; }
|
|
|
|
PRBool GetIsLoading()
|
|
{ return mLoading; }
|
|
|
|
protected:
|
|
virtual ~CBrowserShellProgressListener();
|
|
|
|
protected:
|
|
CBrowserShell *mpOwner;
|
|
PRBool mLoading;
|
|
PRBool mUseRealProgFlag;
|
|
PRInt32 mFinishedRequests, mTotalRequests;
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS2(CBrowserShellProgressListener, nsIWebProgressListener, nsISupportsWeakReference)
|
|
|
|
CBrowserShellProgressListener::CBrowserShellProgressListener(CBrowserShell* itsOwner) :
|
|
mpOwner(itsOwner),
|
|
mLoading(PR_FALSE), mUseRealProgFlag(PR_FALSE),
|
|
mFinishedRequests(0), mTotalRequests(0)
|
|
{
|
|
}
|
|
|
|
CBrowserShellProgressListener::~CBrowserShellProgressListener()
|
|
{
|
|
}
|
|
|
|
NS_IMETHODIMP CBrowserShellProgressListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
|
|
{
|
|
NS_ENSURE_TRUE(mpOwner, NS_ERROR_NULL_POINTER);
|
|
|
|
if (aStateFlags & STATE_START)
|
|
{
|
|
if (aStateFlags & STATE_IS_NETWORK)
|
|
{
|
|
MsgNetStartInfo startInfo(mpOwner);
|
|
mpOwner->BroadcastMessage(msg_OnNetStartChange, &startInfo);
|
|
mLoading = true;
|
|
|
|
// Init progress vars
|
|
mUseRealProgFlag = false;
|
|
mTotalRequests = 0;
|
|
mFinishedRequests = 0;
|
|
}
|
|
if (aStateFlags & STATE_IS_REQUEST)
|
|
mTotalRequests++;
|
|
}
|
|
else if (aStateFlags & STATE_STOP)
|
|
{
|
|
if (aStateFlags & STATE_IS_REQUEST)
|
|
{
|
|
mFinishedRequests += 1;
|
|
|
|
if (!mUseRealProgFlag)
|
|
{
|
|
MsgOnProgressChangeInfo progInfo(mpOwner, mFinishedRequests, mTotalRequests);
|
|
mpOwner->BroadcastMessage(msg_OnProgressChange, &progInfo);
|
|
}
|
|
}
|
|
if (aStateFlags & STATE_IS_NETWORK)
|
|
{
|
|
MsgNetStopInfo stopInfo(mpOwner);
|
|
mpOwner->BroadcastMessage(msg_OnNetStopChange, &stopInfo);
|
|
mLoading = false;
|
|
}
|
|
}
|
|
else if (aStateFlags & STATE_TRANSFERRING)
|
|
{
|
|
|
|
if (aStateFlags & STATE_IS_DOCUMENT)
|
|
{
|
|
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
|
|
NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
|
|
nsCAutoString contentType;
|
|
channel->GetContentType(contentType);
|
|
if (contentType.EqualsLiteral("text/html"))
|
|
mUseRealProgFlag = true;
|
|
}
|
|
|
|
if (aStateFlags & STATE_IS_REQUEST)
|
|
{
|
|
if (!mUseRealProgFlag)
|
|
{
|
|
MsgOnProgressChangeInfo progInfo(mpOwner, mFinishedRequests, mTotalRequests);
|
|
mpOwner->BroadcastMessage(msg_OnProgressChange, &progInfo);
|
|
}
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP CBrowserShellProgressListener::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
|
|
{
|
|
NS_ENSURE_TRUE(mpOwner, NS_ERROR_NULL_POINTER);
|
|
|
|
if (!mUseRealProgFlag)
|
|
return NS_OK;
|
|
|
|
MsgOnProgressChangeInfo progInfo(mpOwner, aCurTotalProgress, aMaxTotalProgress);
|
|
mpOwner->BroadcastMessage(msg_OnProgressChange, &progInfo);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP CBrowserShellProgressListener::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location)
|
|
{
|
|
NS_ENSURE_TRUE(mpOwner, NS_ERROR_NULL_POINTER);
|
|
|
|
nsCAutoString spec;
|
|
|
|
if (location)
|
|
location->GetSpec(spec);
|
|
|
|
MsgLocationChangeInfo info(mpOwner, spec.get());
|
|
mpOwner->BroadcastMessage(msg_OnLocationChange, &info);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP CBrowserShellProgressListener::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage)
|
|
{
|
|
NS_ENSURE_TRUE(mpOwner, NS_ERROR_NULL_POINTER);
|
|
|
|
MsgStatusChangeInfo info(mpOwner, aStatus, aMessage);
|
|
mpOwner->BroadcastMessage(msg_OnStatusChange, &info);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP CBrowserShellProgressListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
|
|
{
|
|
NS_ENSURE_TRUE(mpOwner, NS_ERROR_NULL_POINTER);
|
|
|
|
MsgSecurityChangeInfo info(mpOwner, state);
|
|
mpOwner->BroadcastMessage(msg_OnSecurityChange, &info);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
//*** CBrowserShell: constructors/destructor
|
|
//*****************************************************************************
|
|
|
|
CBrowserShell::CBrowserShell() :
|
|
LDropArea(GetMacWindow()),
|
|
mChromeFlags(nsIWebBrowserChrome::CHROME_DEFAULT), mIsMainContent(true),
|
|
mContextMenuFlags(nsIContextMenuListener2::CONTEXT_NONE)
|
|
{
|
|
nsresult rv = CommonConstruct();
|
|
if (rv != NS_OK)
|
|
Throw_Err(NS_ERROR_GET_CODE(rv)); // If this fails, there's no reason to live anymore :(
|
|
}
|
|
|
|
|
|
CBrowserShell::CBrowserShell(const SPaneInfo &inPaneInfo,
|
|
const SViewInfo &inViewInfo,
|
|
const UInt32 inChromeFlags,
|
|
const Boolean inIsMainContent) :
|
|
LView(inPaneInfo, inViewInfo), LDropArea(GetMacWindow()),
|
|
mChromeFlags(inChromeFlags), mIsMainContent(inIsMainContent),
|
|
mContextMenuFlags(nsIContextMenuListener2::CONTEXT_NONE)
|
|
{
|
|
nsresult rv = CommonConstruct();
|
|
if (rv != NS_OK)
|
|
Throw_Err(NS_ERROR_GET_CODE(rv)); // If this fails, there's no reason to live anymore :(
|
|
}
|
|
|
|
|
|
CBrowserShell::CBrowserShell(LStream* inStream) :
|
|
LView(inStream), LDropArea(GetMacWindow()),
|
|
mContextMenuFlags(nsIContextMenuListener2::CONTEXT_NONE)
|
|
{
|
|
*inStream >> mChromeFlags;
|
|
*inStream >> mIsMainContent;
|
|
|
|
nsresult rv = CommonConstruct();
|
|
if (rv != NS_OK)
|
|
Throw_Err(NS_ERROR_GET_CODE(rv)); // If this fails, there's no reason to live anymore :(
|
|
}
|
|
|
|
|
|
CBrowserShell::~CBrowserShell()
|
|
{
|
|
if (mWebBrowser)
|
|
mWebBrowser->SetContainerWindow(nsnull);
|
|
|
|
if (mChrome)
|
|
{
|
|
mChrome->SetBrowserShell(nsnull);
|
|
NS_RELEASE(mChrome);
|
|
}
|
|
if (mProgressListener)
|
|
{
|
|
mProgressListener->SetOwner(nsnull);
|
|
NS_RELEASE(mProgressListener);
|
|
}
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP CBrowserShell::CommonConstruct()
|
|
{
|
|
nsresult rv;
|
|
|
|
mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv);
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
|
|
|
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mWebBrowser));
|
|
NS_ENSURE_TRUE(baseWin, NS_ERROR_FAILURE);
|
|
mWebBrowserAsBaseWin = baseWin;
|
|
|
|
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mWebBrowser));
|
|
NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
|
|
mWebBrowserAsWebNav = webNav;
|
|
|
|
mChrome = new CBrowserChrome(this, mChromeFlags, mIsMainContent);
|
|
NS_ENSURE_TRUE(mChrome, NS_ERROR_FAILURE);
|
|
NS_ADDREF(mChrome);
|
|
AddListener(mChrome);
|
|
mWebBrowser->SetContainerWindow(mChrome);
|
|
|
|
mProgressListener = new CBrowserShellProgressListener(this);
|
|
NS_ENSURE_TRUE(mProgressListener, NS_ERROR_FAILURE);
|
|
NS_ADDREF(mProgressListener);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
//*** CBrowserShell: LPane overrides
|
|
//*****************************************************************************
|
|
|
|
void CBrowserShell::FinishCreateSelf()
|
|
{
|
|
FocusDraw();
|
|
|
|
Rect portFrame;
|
|
CalcPortFrameRect(portFrame);
|
|
nsRect r(portFrame.left, portFrame.top, portFrame.right - portFrame.left, portFrame.bottom - portFrame.top);
|
|
|
|
nsresult rv;
|
|
|
|
mWebBrowserAsBaseWin->InitWindow(GetMacWindow(), nsnull, r.x, r.y, r.width, r.height);
|
|
mWebBrowserAsBaseWin->Create();
|
|
mEventSink = do_GetInterface(mWebBrowser);
|
|
ThrowIfNil_(mEventSink);
|
|
|
|
// Hook up our progress listener
|
|
nsWeakPtr weakling(do_GetWeakReference((nsIWebProgressListener *)mProgressListener));
|
|
rv = mWebBrowser->AddWebBrowserListener(weakling, NS_GET_IID(nsIWebProgressListener));
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Call to AddWebBrowserListener failed");
|
|
|
|
AdjustFrame();
|
|
StartRepeating();
|
|
}
|
|
|
|
|
|
void CBrowserShell::ResizeFrameBy(SInt16 inWidthDelta,
|
|
SInt16 inHeightDelta,
|
|
Boolean inRefresh)
|
|
{
|
|
LView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
|
|
AdjustFrame();
|
|
}
|
|
|
|
|
|
void CBrowserShell::MoveBy(SInt32 inHorizDelta,
|
|
SInt32 inVertDelta,
|
|
Boolean inRefresh)
|
|
{
|
|
LView::MoveBy(inHorizDelta, inVertDelta, inRefresh);
|
|
AdjustFrame();
|
|
}
|
|
|
|
|
|
void CBrowserShell::ActivateSelf()
|
|
{
|
|
EventRecord osEvent;
|
|
osEvent.what = activateEvt;
|
|
osEvent.modifiers = activeFlag;
|
|
PRBool handled = PR_FALSE;
|
|
mEventSink->DispatchEvent(&osEvent, &handled);
|
|
}
|
|
|
|
void CBrowserShell::DeactivateSelf()
|
|
{
|
|
EventRecord osEvent;
|
|
osEvent.what = activateEvt;
|
|
osEvent.modifiers = 0;
|
|
PRBool handled = PR_FALSE;
|
|
mEventSink->DispatchEvent(&osEvent, &handled);
|
|
}
|
|
|
|
void CBrowserShell::ShowSelf()
|
|
{
|
|
mWebBrowserAsBaseWin->SetVisibility(PR_TRUE);
|
|
}
|
|
|
|
|
|
void CBrowserShell::DrawSelf()
|
|
{
|
|
EventRecord osEvent;
|
|
osEvent.what = updateEvt;
|
|
PRBool handled = PR_FALSE;
|
|
mEventSink->DispatchEvent(&osEvent, &handled);
|
|
}
|
|
|
|
|
|
void CBrowserShell::ClickSelf(const SMouseDownEvent &inMouseDown)
|
|
{
|
|
if (!IsTarget())
|
|
SwitchTarget(this);
|
|
|
|
FocusDraw();
|
|
PRBool handled = PR_FALSE;
|
|
mEventSink->DispatchEvent(&const_cast<EventRecord&>(inMouseDown.macEvent), &handled);
|
|
}
|
|
|
|
|
|
void CBrowserShell::EventMouseUp(const EventRecord &inMacEvent)
|
|
{
|
|
FocusDraw();
|
|
PRBool handled = PR_FALSE;
|
|
mEventSink->DispatchEvent(&const_cast<EventRecord&>(inMacEvent), &handled);
|
|
|
|
LEventDispatcher *dispatcher = LEventDispatcher::GetCurrentEventDispatcher();
|
|
if (dispatcher)
|
|
dispatcher->UpdateMenus();
|
|
}
|
|
|
|
void CBrowserShell::AdjustMouseSelf(Point inPortPt,
|
|
const EventRecord& inMacEvent,
|
|
RgnHandle outMouseRgn)
|
|
{
|
|
Rect cursorRect = { inPortPt.h, inPortPt.v, inPortPt.h + 1, inPortPt.v + 1 };
|
|
::RectRgn(outMouseRgn, &cursorRect);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//*** CBrowserShell: LCommander overrides
|
|
//*****************************************************************************
|
|
|
|
void CBrowserShell::BeTarget()
|
|
{
|
|
nsCOMPtr<nsIWebBrowserFocus> focus(do_GetInterface(mWebBrowser));
|
|
if (focus)
|
|
focus->Activate();
|
|
}
|
|
|
|
void CBrowserShell::DontBeTarget()
|
|
{
|
|
nsCOMPtr<nsIWebBrowserFocus> focus(do_GetInterface(mWebBrowser));
|
|
if (focus)
|
|
focus->Deactivate();
|
|
}
|
|
|
|
Boolean CBrowserShell::HandleKeyPress(const EventRecord &inKeyEvent)
|
|
{
|
|
// set the QuickDraw origin
|
|
FocusDraw();
|
|
|
|
// dispatch the event
|
|
PRBool handled = PR_FALSE;
|
|
Boolean keyHandled = mEventSink->DispatchEvent(&const_cast<EventRecord&>(inKeyEvent), &handled);
|
|
|
|
return keyHandled;
|
|
}
|
|
|
|
Boolean CBrowserShell::ObeyCommand(PP_PowerPlant::CommandT inCommand, void* ioParam)
|
|
{
|
|
Boolean cmdHandled = true;
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIClipboardCommands> clipCmd;
|
|
|
|
switch (inCommand)
|
|
{
|
|
case cmd_Back:
|
|
Back();
|
|
break;
|
|
|
|
case cmd_Forward:
|
|
Forward();
|
|
break;
|
|
|
|
case cmd_Stop:
|
|
Stop();
|
|
break;
|
|
|
|
case cmd_Reload:
|
|
Reload();
|
|
break;
|
|
|
|
case cmd_SaveAs:
|
|
rv = SaveDocument(eSaveFormatHTML);
|
|
ThrowIfError_(rv);
|
|
break;
|
|
|
|
case cmd_Cut:
|
|
rv = GetClipboardHandler(getter_AddRefs(clipCmd));
|
|
if (NS_SUCCEEDED(rv))
|
|
clipCmd->CutSelection();
|
|
break;
|
|
|
|
case cmd_Copy:
|
|
rv = GetClipboardHandler(getter_AddRefs(clipCmd));
|
|
if (NS_SUCCEEDED(rv))
|
|
clipCmd->CopySelection();
|
|
break;
|
|
|
|
case cmd_Paste:
|
|
rv = GetClipboardHandler(getter_AddRefs(clipCmd));
|
|
if (NS_SUCCEEDED(rv))
|
|
clipCmd->Paste();
|
|
break;
|
|
|
|
case cmd_SelectAll:
|
|
rv = GetClipboardHandler(getter_AddRefs(clipCmd));
|
|
if (NS_SUCCEEDED(rv))
|
|
clipCmd->SelectAll();
|
|
break;
|
|
|
|
case cmd_Find:
|
|
Find();
|
|
break;
|
|
|
|
case cmd_FindNext:
|
|
FindNext();
|
|
break;
|
|
|
|
case cmd_OpenLinkInNewWindow:
|
|
case cmd_CopyLinkLocation:
|
|
{
|
|
// Get the URL from the link
|
|
ThrowIfNil_(mContextMenuInfo);
|
|
nsAutoString temp;
|
|
rv = mContextMenuInfo->GetAssociatedLink(temp);
|
|
ThrowIfError_(rv);
|
|
NS_ConvertUTF16toUTF8 urlSpec(temp);
|
|
|
|
if (inCommand == cmd_OpenLinkInNewWindow) {
|
|
nsCAutoString referrer;
|
|
rv = GetFocusedWindowURL(temp);
|
|
if (NS_SUCCEEDED(rv))
|
|
AppendUTF16toUTF8(temp, referrer);
|
|
PostOpenURLEvent(urlSpec, referrer);
|
|
}
|
|
else
|
|
UScrap::SetData(kScrapFlavorTypeText, urlSpec.get(), urlSpec.Length());
|
|
}
|
|
break;
|
|
|
|
case cmd_SaveFormData:
|
|
{
|
|
nsCOMPtr<nsIDOMWindow> domWindow;
|
|
nsCOMPtr<nsIDOMWindowInternal> domWindowInternal;
|
|
|
|
nsCOMPtr<nsIWalletService> walletService =
|
|
do_GetService(NS_WALLETSERVICE_CONTRACTID, &rv);
|
|
ThrowIfError_(rv);
|
|
rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
|
|
ThrowIfError_(rv);
|
|
domWindowInternal = do_QueryInterface(domWindow, &rv);
|
|
ThrowIfError_(rv);
|
|
PRUint32 retval;
|
|
rv = walletService->WALLET_RequestToCapture(domWindowInternal, &retval);
|
|
}
|
|
break;
|
|
|
|
case cmd_PrefillForm:
|
|
{
|
|
nsCOMPtr<nsIDOMWindow> domWindow;
|
|
nsCOMPtr<nsIDOMWindowInternal> domWindowInternal;
|
|
|
|
nsCOMPtr<nsIWalletService> walletService =
|
|
do_GetService(NS_WALLETSERVICE_CONTRACTID, &rv);
|
|
ThrowIfError_(rv);
|
|
rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
|
|
ThrowIfError_(rv);
|
|
domWindowInternal = do_QueryInterface(domWindow, &rv);
|
|
ThrowIfError_(rv);
|
|
PRBool retval;
|
|
// Don't check the result - A result of NS_ERROR_FAILURE means not to show preview dialog
|
|
rv = walletService->WALLET_Prefill(true, domWindowInternal, &retval);
|
|
}
|
|
break;
|
|
|
|
case cmd_ViewPageSource:
|
|
{
|
|
nsCAutoString currentURL;
|
|
rv = GetCurrentURL(currentURL);
|
|
ThrowIfError_(rv);
|
|
currentURL.Insert("view-source:", 0);
|
|
PostOpenURLEvent(currentURL, EmptyCString());
|
|
}
|
|
break;
|
|
|
|
case cmd_SaveLinkTarget:
|
|
{
|
|
// Get the URL from the link
|
|
ThrowIfNil_(mContextMenuInfo);
|
|
nsAutoString linkText;
|
|
rv = mContextMenuInfo->GetAssociatedLink(linkText);
|
|
ThrowIfError_(rv);
|
|
|
|
nsCOMPtr<nsIURI> linkURI;
|
|
rv = NS_NewURI(getter_AddRefs(linkURI), NS_ConvertUCS2toUTF8(linkText));
|
|
ThrowIfError_(rv);
|
|
|
|
SaveLink(linkURI);
|
|
}
|
|
break;
|
|
|
|
case cmd_SaveImage:
|
|
{
|
|
ThrowIfNil_(mContextMenuInfo);
|
|
nsCOMPtr<nsIURI> imgURI;
|
|
mContextMenuInfo->GetImageSrc(getter_AddRefs(imgURI));
|
|
ThrowIfNil_(imgURI);
|
|
|
|
SaveLink(imgURI);
|
|
}
|
|
break;
|
|
|
|
case cmd_ViewImage:
|
|
case cmd_CopyImageLocation:
|
|
{
|
|
ThrowIfNil_(mContextMenuInfo);
|
|
nsCOMPtr<nsIURI> imgURI;
|
|
mContextMenuInfo->GetImageSrc(getter_AddRefs(imgURI));
|
|
ThrowIfNil_(imgURI);
|
|
nsCAutoString temp;
|
|
rv = imgURI->GetSpec(temp);
|
|
ThrowIfError_(rv);
|
|
if (inCommand == cmd_ViewImage)
|
|
PostOpenURLEvent(temp, EmptyCString());
|
|
else
|
|
UScrap::SetData(kScrapFlavorTypeText, temp.get(), temp.Length());
|
|
}
|
|
break;
|
|
|
|
case cmd_ViewBackgroundImage:
|
|
{
|
|
ThrowIfNil_(mContextMenuInfo);
|
|
nsCOMPtr<nsIURI> uri;
|
|
rv = mContextMenuInfo->GetBackgroundImageSrc(getter_AddRefs(uri));
|
|
ThrowIfNil_(uri);
|
|
nsCAutoString temp;
|
|
rv = uri->GetSpec(temp);
|
|
ThrowIfError_(rv);
|
|
PostOpenURLEvent(temp, EmptyCString());
|
|
}
|
|
break;
|
|
|
|
case cmd_CopyImage:
|
|
{
|
|
GetClipboardHandler(getter_AddRefs(clipCmd));
|
|
if (clipCmd)
|
|
clipCmd->CopyImageContents();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
cmdHandled = LCommander::ObeyCommand(inCommand, ioParam);
|
|
break;
|
|
}
|
|
return cmdHandled;
|
|
}
|
|
|
|
|
|
void CBrowserShell::FindCommandStatus(PP_PowerPlant::CommandT inCommand,
|
|
Boolean &outEnabled, Boolean &outUsesMark,
|
|
UInt16 &outMark, Str255 outName)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsIClipboardCommands> clipCmd;
|
|
PRBool haveContent, canDo;
|
|
nsCOMPtr<nsIURI> currURI;
|
|
|
|
rv = mWebBrowserAsWebNav->GetCurrentURI(getter_AddRefs(currURI));
|
|
haveContent = NS_SUCCEEDED(rv) && currURI;
|
|
|
|
switch (inCommand)
|
|
{
|
|
case cmd_Back:
|
|
outEnabled = CanGoBack();
|
|
break;
|
|
|
|
case cmd_Forward:
|
|
outEnabled = CanGoForward();
|
|
break;
|
|
|
|
case cmd_Stop:
|
|
outEnabled = IsBusy();
|
|
break;
|
|
|
|
case cmd_Reload:
|
|
outEnabled = haveContent;
|
|
break;
|
|
|
|
case cmd_SaveAs:
|
|
outEnabled = haveContent;
|
|
break;
|
|
|
|
case cmd_Cut:
|
|
if (haveContent) {
|
|
rv = GetClipboardHandler(getter_AddRefs(clipCmd));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = clipCmd->CanCutSelection(&canDo);
|
|
outEnabled = NS_SUCCEEDED(rv) && canDo;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case cmd_Copy:
|
|
if (haveContent) {
|
|
rv = GetClipboardHandler(getter_AddRefs(clipCmd));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = clipCmd->CanCopySelection(&canDo);
|
|
outEnabled = NS_SUCCEEDED(rv) && canDo;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case cmd_Paste:
|
|
if (haveContent) {
|
|
rv = GetClipboardHandler(getter_AddRefs(clipCmd));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = clipCmd->CanPaste(&canDo);
|
|
outEnabled = NS_SUCCEEDED(rv) && canDo;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case cmd_SelectAll:
|
|
outEnabled = haveContent;
|
|
break;
|
|
|
|
case cmd_Find:
|
|
outEnabled = haveContent;
|
|
break;
|
|
|
|
case cmd_FindNext:
|
|
outEnabled = haveContent && CanFindNext();
|
|
break;
|
|
|
|
case cmd_OpenLinkInNewWindow:
|
|
outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_LINK) != 0);
|
|
break;
|
|
|
|
case cmd_ViewPageSource:
|
|
outEnabled = haveContent && ((mChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME) == 0);
|
|
break;
|
|
|
|
case cmd_ViewImage:
|
|
outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_IMAGE) != 0);
|
|
break;
|
|
|
|
case cmd_ViewBackgroundImage:
|
|
outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_BACKGROUND_IMAGE) != 0);
|
|
break;
|
|
|
|
case cmd_CopyImage:
|
|
if (haveContent) {
|
|
rv = GetClipboardHandler(getter_AddRefs(clipCmd));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = clipCmd->CanCopyImageContents(&canDo);
|
|
outEnabled = NS_SUCCEEDED(rv) && canDo;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case cmd_SaveLinkTarget:
|
|
outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_LINK) != 0);
|
|
break;
|
|
|
|
case cmd_SaveImage:
|
|
outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_IMAGE) != 0);
|
|
break;
|
|
|
|
case cmd_CopyLinkLocation:
|
|
outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_LINK) != 0);
|
|
break;
|
|
|
|
case cmd_CopyImageLocation:
|
|
outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_IMAGE) != 0);
|
|
break;
|
|
|
|
case cmd_SaveFormData:
|
|
outEnabled = haveContent && HasFormElements();
|
|
break;
|
|
|
|
case cmd_PrefillForm:
|
|
outEnabled = haveContent && HasFormElements();
|
|
break;
|
|
|
|
default:
|
|
LCommander::FindCommandStatus(inCommand, outEnabled,
|
|
outUsesMark, outMark, outName);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
//*** CBrowserShell: LPeriodical overrides
|
|
//*****************************************************************************
|
|
|
|
void CBrowserShell::SpendTime(const EventRecord& inMacEvent)
|
|
{
|
|
switch (inMacEvent.what)
|
|
{
|
|
case nullEvent:
|
|
HandleMouseMoved(inMacEvent);
|
|
break;
|
|
|
|
case osEvt:
|
|
{
|
|
// The event sink will not set the cursor if we are in the background - which is right.
|
|
// We have to feed it suspendResumeMessages for it to know
|
|
|
|
unsigned char eventType = ((inMacEvent.message >> 24) & 0x00ff);
|
|
if (eventType == suspendResumeMessage) {
|
|
PRBool handled = PR_FALSE;
|
|
mEventSink->DispatchEvent(&const_cast<EventRecord&>(inMacEvent), &handled);
|
|
}
|
|
else if (eventType == mouseMovedMessage)
|
|
HandleMouseMoved(inMacEvent);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
//*** CBrowserShell:
|
|
//*****************************************************************************
|
|
|
|
void CBrowserShell::AddAttachments()
|
|
{
|
|
// Only add a context menu attachment for full browser windows -
|
|
// not view-source and chrome dialogs.
|
|
if ((mChromeFlags & (nsIWebBrowserChrome::CHROME_TOOLBAR |
|
|
nsIWebBrowserChrome::CHROME_STATUSBAR)) != 0)
|
|
{
|
|
CWebBrowserCMAttachment *cmAttachment = new CWebBrowserCMAttachment(this);
|
|
ThrowIfNil_(cmAttachment);
|
|
cmAttachment->SetCommandList(mcmd_BrowserShellContextMenuCmds);
|
|
AddAttachment(cmAttachment);
|
|
}
|
|
}
|
|
|
|
NS_METHOD CBrowserShell::GetWebBrowser(nsIWebBrowser** aBrowser)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aBrowser);
|
|
|
|
*aBrowser = mWebBrowser;
|
|
NS_IF_ADDREF(*aBrowser);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_METHOD CBrowserShell::SetWebBrowser(nsIWebBrowser* aBrowser)
|
|
{
|
|
NS_ENSURE_ARG(aBrowser);
|
|
|
|
FocusDraw();
|
|
|
|
mWebBrowser = aBrowser;
|
|
|
|
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mWebBrowser));
|
|
NS_ENSURE_TRUE(baseWin, NS_ERROR_FAILURE);
|
|
mWebBrowserAsBaseWin = baseWin;
|
|
|
|
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mWebBrowser));
|
|
NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
|
|
mWebBrowserAsWebNav = webNav;
|
|
|
|
Rect portFrame;
|
|
CalcPortFrameRect(portFrame);
|
|
nsRect r(portFrame.left, portFrame.top, portFrame.right - portFrame.left, portFrame.bottom - portFrame.top);
|
|
|
|
mWebBrowserAsBaseWin->InitWindow(GetMacWindow(), nsnull, r.x, r.y, r.width, r.height);
|
|
mWebBrowserAsBaseWin->Create();
|
|
mEventSink = do_GetInterface(mWebBrowser);
|
|
ThrowIfNil_(mEventSink);
|
|
|
|
AdjustFrame();
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_METHOD CBrowserShell::GetWebBrowserChrome(nsIWebBrowserChrome** aChrome)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aChrome);
|
|
return mChrome->QueryInterface(NS_GET_IID(nsIWebBrowserChrome), (void **)aChrome);
|
|
}
|
|
|
|
NS_METHOD CBrowserShell::GetContentViewer(nsIContentViewer** aViewer)
|
|
{
|
|
nsCOMPtr<nsIDocShell> ourDocShell(do_GetInterface(mWebBrowser));
|
|
NS_ENSURE_TRUE(ourDocShell, NS_ERROR_FAILURE);
|
|
return ourDocShell->GetContentViewer(aViewer);
|
|
}
|
|
|
|
NS_METHOD CBrowserShell::GetFocusedWindowURL(nsAString& outURL)
|
|
{
|
|
nsCOMPtr<nsIWebBrowserFocus> wbf(do_GetInterface(mWebBrowser));
|
|
if (!wbf)
|
|
return NS_ERROR_FAILURE;
|
|
nsCOMPtr<nsIDOMWindow> domWindow;
|
|
wbf->GetFocusedWindow(getter_AddRefs(domWindow));
|
|
if (!domWindow)
|
|
mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
|
|
if (!domWindow)
|
|
return NS_ERROR_FAILURE;
|
|
nsCOMPtr<nsIDOMDocument> domDocument;
|
|
domWindow->GetDocument(getter_AddRefs(domDocument));
|
|
if (!domDocument)
|
|
return NS_ERROR_FAILURE;
|
|
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
|
|
if (!nsDoc)
|
|
return NS_ERROR_FAILURE;
|
|
nsCOMPtr<nsIDOMLocation> location;
|
|
nsDoc->GetLocation(getter_AddRefs(location));
|
|
if (!location)
|
|
return NS_ERROR_FAILURE;
|
|
return location->GetHref(outURL);
|
|
}
|
|
|
|
NS_METHOD CBrowserShell::GetPrintSettings(nsIPrintSettings** aSettings)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aSettings);
|
|
*aSettings = nsnull;
|
|
|
|
if (!mPrintSettings) {
|
|
// If we don't have print settings yet, make new ones.
|
|
nsCOMPtr<nsIWebBrowserPrint> wbPrint(do_GetInterface(mWebBrowser));
|
|
NS_ENSURE_TRUE(wbPrint, NS_ERROR_NO_INTERFACE);
|
|
wbPrint->GetGlobalPrintSettings(getter_AddRefs(mPrintSettings));
|
|
}
|
|
if (mPrintSettings) {
|
|
*aSettings = mPrintSettings;
|
|
NS_ADDREF(*aSettings);
|
|
return NS_OK;
|
|
}
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//*** CBrowserShell: Navigation
|
|
//*****************************************************************************
|
|
|
|
Boolean CBrowserShell::IsBusy()
|
|
{
|
|
return mProgressListener->GetIsLoading();
|
|
}
|
|
|
|
|
|
Boolean CBrowserShell::CanGoBack()
|
|
{
|
|
PRBool canDo;
|
|
nsresult rv;
|
|
|
|
rv = mWebBrowserAsWebNav->GetCanGoBack(&canDo);
|
|
return (NS_SUCCEEDED(rv) && canDo);
|
|
}
|
|
|
|
|
|
Boolean CBrowserShell::CanGoForward()
|
|
{
|
|
PRBool canDo;
|
|
nsresult rv;
|
|
|
|
rv = mWebBrowserAsWebNav->GetCanGoForward(&canDo);
|
|
return (NS_SUCCEEDED(rv) && canDo);
|
|
}
|
|
|
|
|
|
NS_METHOD CBrowserShell::Back()
|
|
{
|
|
nsresult rv;
|
|
|
|
if (CanGoBack())
|
|
rv = mWebBrowserAsWebNav->GoBack();
|
|
else
|
|
{
|
|
::SysBeep(5);
|
|
rv = NS_ERROR_FAILURE;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
NS_METHOD CBrowserShell::Forward()
|
|
{
|
|
nsresult rv;
|
|
|
|
if (CanGoForward())
|
|
rv = mWebBrowserAsWebNav->GoForward();
|
|
else
|
|
{
|
|
::SysBeep(5);
|
|
rv = NS_ERROR_FAILURE;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
NS_METHOD CBrowserShell::Stop()
|
|
{
|
|
return mWebBrowserAsWebNav->Stop(nsIWebNavigation::STOP_ALL);
|
|
}
|
|
|
|
NS_METHOD CBrowserShell::Reload()
|
|
{
|
|
return mWebBrowserAsWebNav->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//*** CBrowserShell: URL Loading
|
|
//*****************************************************************************
|
|
|
|
|
|
NS_METHOD CBrowserShell::LoadURL(const nsACString& urlText, const nsACString& referrer)
|
|
{
|
|
nsCOMPtr<nsIURI> referrerURI;
|
|
if (referrer.Length()) {
|
|
nsresult rv = NS_NewURI(getter_AddRefs(referrerURI), referrer);
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to make URI for referrer.");
|
|
}
|
|
return mWebBrowserAsWebNav->LoadURI(NS_ConvertUTF8toUCS2(urlText).get(),
|
|
nsIWebNavigation::LOAD_FLAGS_NONE,
|
|
referrerURI,
|
|
nsnull,
|
|
nsnull);
|
|
}
|
|
|
|
NS_METHOD CBrowserShell::GetCurrentURL(nsACString& urlText)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsIURI> currentURI;
|
|
rv = mWebBrowserAsWebNav->GetCurrentURI(getter_AddRefs(currentURI));
|
|
if (NS_FAILED(rv)) return rv;
|
|
rv = currentURI->GetSpec(urlText);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//*** CBrowserShell: URI Saving
|
|
//*****************************************************************************
|
|
|
|
// Save All As from menus
|
|
NS_METHOD CBrowserShell::SaveDocument(ESaveFormat inSaveFormat)
|
|
{
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIDOMDocument> domDocument;
|
|
rv = mWebBrowserAsWebNav->GetDocument(getter_AddRefs(domDocument));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
|
|
if (!nsDoc)
|
|
return NS_ERROR_FAILURE;
|
|
nsCOMPtr<nsIDOMLocation> location;
|
|
nsDoc->GetLocation(getter_AddRefs(location));
|
|
if (!location)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
nsAutoString docLocation;
|
|
rv = location->GetHref(docLocation);
|
|
if (NS_FAILED(rv))
|
|
return rv;
|
|
|
|
nsCOMPtr<nsIURI> documentURI;
|
|
rv = NS_NewURI(getter_AddRefs(documentURI), NS_ConvertUCS2toUTF8(docLocation));
|
|
if (NS_FAILED(rv))
|
|
return rv;
|
|
|
|
return SaveInternal(documentURI, domDocument, EmptyString(), false, inSaveFormat); // don't bypass cache
|
|
}
|
|
|
|
// Save link target
|
|
NS_METHOD CBrowserShell::SaveLink(nsIURI* inURI)
|
|
{
|
|
return SaveInternal(inURI, nsnull, EmptyString(), true, eSaveFormatHTML); // bypass cache
|
|
}
|
|
|
|
const char* const kPersistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
|
|
|
|
NS_METHOD CBrowserShell::SaveInternal(nsIURI* inURI, nsIDOMDocument* inDocument,
|
|
const nsAString& inSuggestedFilename, Boolean inBypassCache, ESaveFormat inSaveFormat)
|
|
{
|
|
nsresult rv;
|
|
// Create our web browser persist object. This is the object that knows
|
|
// how to actually perform the saving of the page (and of the images
|
|
// on the page).
|
|
nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(kPersistContractID, &rv));
|
|
if (!webPersist)
|
|
return rv;
|
|
|
|
// Make a temporary file object that we can save to.
|
|
nsCOMPtr<nsIProperties> dirService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
|
|
if (!dirService)
|
|
return rv;
|
|
nsCOMPtr<nsIFile> tmpFile;
|
|
dirService->Get("TmpD", NS_GET_IID(nsIFile), getter_AddRefs(tmpFile));
|
|
static short unsigned int tmpRandom = 0;
|
|
nsAutoString tmpNo; tmpNo.AppendInt(tmpRandom++);
|
|
nsAutoString saveFile(NS_LITERAL_STRING("-sav"));
|
|
saveFile += tmpNo;
|
|
saveFile.Append(NS_LITERAL_STRING("tmp"));
|
|
tmpFile->Append(saveFile);
|
|
|
|
// Get the post data if we're an HTML doc.
|
|
nsCOMPtr<nsIInputStream> postData;
|
|
if (inDocument) {
|
|
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mWebBrowser));
|
|
nsCOMPtr<nsISHistory> sessionHistory;
|
|
webNav->GetSessionHistory(getter_AddRefs(sessionHistory));
|
|
nsCOMPtr<nsIHistoryEntry> entry;
|
|
PRInt32 sindex;
|
|
sessionHistory->GetIndex(&sindex);
|
|
sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry));
|
|
nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(entry));
|
|
if (shEntry)
|
|
shEntry->GetPostData(getter_AddRefs(postData));
|
|
}
|
|
|
|
// when saving, we first fire off a save with a nsHeaderSniffer as a progress
|
|
// listener. This allows us to look for the content-disposition header, which
|
|
// can supply a filename, and maybe has something to do with CGI-generated
|
|
// content (?)
|
|
CHeaderSniffer* sniffer = new CHeaderSniffer(webPersist, tmpFile, inURI, inDocument, postData,
|
|
inSuggestedFilename, inBypassCache, inSaveFormat);
|
|
if (!sniffer)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
webPersist->SetProgressListener(sniffer); // owned
|
|
|
|
return webPersist->SaveURI(inURI, nsnull, nsnull, nsnull, nsnull, tmpFile);
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
//*** CBrowserShell: Text Searching
|
|
//*****************************************************************************
|
|
|
|
Boolean CBrowserShell::Find()
|
|
{
|
|
nsresult rv;
|
|
nsXPIDLString stringBuf;
|
|
PRBool findBackwards;
|
|
PRBool wrapFind;
|
|
PRBool entireWord;
|
|
PRBool matchCase;
|
|
|
|
nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mWebBrowser));
|
|
if (!finder) return FALSE;
|
|
finder->GetSearchString(getter_Copies(stringBuf));
|
|
finder->GetFindBackwards(&findBackwards);
|
|
finder->GetWrapFind(&wrapFind);
|
|
finder->GetEntireWord(&entireWord);
|
|
finder->GetMatchCase(&matchCase);
|
|
|
|
Boolean result = FALSE;
|
|
nsString searchString(stringBuf.get());
|
|
|
|
if (DoFindDialog(searchString, findBackwards, wrapFind, entireWord, matchCase))
|
|
{
|
|
PRBool didFind;
|
|
|
|
finder->SetSearchString(searchString.get());
|
|
finder->SetFindBackwards(findBackwards);
|
|
finder->SetWrapFind(wrapFind);
|
|
finder->SetEntireWord(entireWord);
|
|
finder->SetMatchCase(matchCase);
|
|
rv = finder->FindNext(&didFind);
|
|
result = (NS_SUCCEEDED(rv) && didFind);
|
|
if (!result)
|
|
::SysBeep(1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
Boolean CBrowserShell::Find(const nsAString& searchString,
|
|
Boolean findBackwards,
|
|
Boolean wrapFind,
|
|
Boolean entireWord,
|
|
Boolean matchCase)
|
|
{
|
|
nsresult rv;
|
|
Boolean result;
|
|
PRBool didFind;
|
|
|
|
nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mWebBrowser));
|
|
if (!finder) return FALSE;
|
|
|
|
finder->SetSearchString(PromiseFlatString(searchString).get());
|
|
finder->SetFindBackwards(findBackwards);
|
|
finder->SetWrapFind(wrapFind);
|
|
finder->SetEntireWord(entireWord);
|
|
finder->SetMatchCase(matchCase);
|
|
|
|
rv = finder->FindNext(&didFind);
|
|
result = (NS_SUCCEEDED(rv) && didFind);
|
|
if (!result)
|
|
::SysBeep(1);
|
|
|
|
return result;
|
|
}
|
|
|
|
Boolean CBrowserShell::CanFindNext()
|
|
{
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mWebBrowser));
|
|
if (!finder) return FALSE;
|
|
|
|
nsXPIDLString searchStr;
|
|
rv = finder->GetSearchString(getter_Copies(searchStr));
|
|
return (NS_SUCCEEDED(rv) && !searchStr.IsEmpty());
|
|
}
|
|
|
|
|
|
Boolean CBrowserShell::FindNext()
|
|
{
|
|
nsresult rv;
|
|
Boolean result;
|
|
PRBool didFind;
|
|
|
|
nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mWebBrowser));
|
|
if (!finder) return FALSE;
|
|
rv = finder->FindNext(&didFind);
|
|
result = (NS_SUCCEEDED(rv) && didFind);
|
|
if (!result)
|
|
::SysBeep(1);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP CBrowserShell::OnShowContextMenu(PRUint32 aContextFlags,
|
|
nsIContextMenuInfo *aInfo)
|
|
{
|
|
// Find our CWebBrowserCMAttachment, if any
|
|
CWebBrowserCMAttachment *aCMAttachment = nsnull;
|
|
const TArray<LAttachment*>* theAttachments = GetAttachmentsList();
|
|
|
|
if (theAttachments) {
|
|
TArrayIterator<LAttachment*> iterate(*theAttachments);
|
|
|
|
LAttachment* theAttach;
|
|
while (iterate.Next(theAttach)) {
|
|
aCMAttachment = dynamic_cast<CWebBrowserCMAttachment*>(theAttach);
|
|
if (aCMAttachment != nil)
|
|
break;
|
|
}
|
|
}
|
|
if (!aCMAttachment) {
|
|
NS_ASSERTION(PR_FALSE, "No CWebBrowserCMAttachment");
|
|
return NS_OK;
|
|
}
|
|
|
|
EventRecord macEvent;
|
|
UEventMgr::GetMouseAndModifiers(macEvent);
|
|
|
|
mContextMenuFlags = aContextFlags;
|
|
mContextMenuInfo = aInfo;
|
|
aCMAttachment->DoContextMenuClick(macEvent);
|
|
mContextMenuFlags = 0;
|
|
mContextMenuInfo = nsnull;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP CBrowserShell::OnShowTooltip(PRInt32 aXCoords,
|
|
PRInt32 aYCoords,
|
|
const PRUnichar *aTipText)
|
|
{
|
|
nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
#if TARGET_CARBON
|
|
if ((Ptr)HMDisplayTag != (Ptr)kUnresolvedCFragSymbolAddress &&
|
|
(Ptr)HMHideTag != (Ptr)kUnresolvedCFragSymbolAddress)
|
|
{
|
|
HMHelpContentRec contentRec;
|
|
Point location;
|
|
|
|
location.h = aXCoords; location.v = aYCoords;
|
|
FocusDraw();
|
|
LocalToPortPoint(location);
|
|
PortToGlobalPoint(location);
|
|
|
|
contentRec.version = kMacHelpVersion;
|
|
contentRec.absHotRect.top = contentRec.absHotRect.bottom = location.v;
|
|
contentRec.absHotRect.left = contentRec.absHotRect.right = location.h;
|
|
::InsetRect(&contentRec.absHotRect, -4, -4);
|
|
contentRec.tagSide = kHMOutsideBottomScriptAligned;
|
|
contentRec.content[kHMMinimumContentIndex].contentType = kHMCFStringContent;
|
|
contentRec.content[kHMMinimumContentIndex].u.tagCFString =
|
|
::CFStringCreateWithCharactersNoCopy(NULL, (const UniChar *)aTipText, nsCRT::strlen(aTipText), kCFAllocatorNull);
|
|
contentRec.content[kHMMaximumContentIndex].contentType = kHMNoContent;
|
|
|
|
::HMDisplayTag(&contentRec);
|
|
rv = NS_OK;
|
|
}
|
|
#endif
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP CBrowserShell::OnHideTooltip()
|
|
{
|
|
nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
#if TARGET_CARBON
|
|
if ((Ptr)HMHideTag != (Ptr)kUnresolvedCFragSymbolAddress)
|
|
{
|
|
::HMHideTag();
|
|
rv = NS_OK;
|
|
}
|
|
#endif
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
void CBrowserShell::HandleMouseMoved(const EventRecord& inMacEvent)
|
|
{
|
|
static Point lastWhere = {0, 0};
|
|
|
|
if (IsActive() && (*(long*)&lastWhere != *(long*)&inMacEvent.where))
|
|
{
|
|
FocusDraw();
|
|
PRBool handled = PR_FALSE;
|
|
mEventSink->DispatchEvent(&const_cast<EventRecord&>(inMacEvent), &handled);
|
|
lastWhere = inMacEvent.where;
|
|
}
|
|
}
|
|
|
|
|
|
void CBrowserShell::AdjustFrame()
|
|
{
|
|
FocusDraw();
|
|
|
|
Rect portFrame;
|
|
CalcPortFrameRect(portFrame);
|
|
nsRect r(portFrame.left, portFrame.top, portFrame.right - portFrame.left, portFrame.bottom - portFrame.top);
|
|
|
|
mWebBrowserAsBaseWin->SetPositionAndSize(r.x, r.y, r.width, r.height, PR_TRUE);
|
|
}
|
|
|
|
|
|
Boolean CBrowserShell::DoFindDialog(nsAString& searchText,
|
|
PRBool& findBackwards,
|
|
PRBool& wrapFind,
|
|
PRBool& entireWord,
|
|
PRBool& caseSensitive)
|
|
{
|
|
enum
|
|
{
|
|
kSearchTextEdit = FOUR_CHAR_CODE('Text'),
|
|
kCaseSensitiveCheck = FOUR_CHAR_CODE('Case'),
|
|
kWrapAroundCheck = FOUR_CHAR_CODE('Wrap'),
|
|
kSearchBackwardsCheck = FOUR_CHAR_CODE('Back'),
|
|
kEntireWordCheck = FOUR_CHAR_CODE('Entr')
|
|
};
|
|
|
|
Boolean result;
|
|
|
|
try
|
|
{
|
|
// Create stack-based object for handling the dialog box
|
|
|
|
StDialogHandler theHandler(dlog_FindDialog, this);
|
|
LWindow *theDialog = theHandler.GetDialog();
|
|
Str255 aStr;
|
|
|
|
// Set initial text for string in dialog box
|
|
|
|
CPlatformUCSConversion::GetInstance()->UCSToPlatform(searchText, aStr);
|
|
|
|
LEditText *editField = dynamic_cast<LEditText*>(theDialog->FindPaneByID(kSearchTextEdit));
|
|
editField->SetDescriptor(aStr);
|
|
theDialog->SetLatentSub(editField);
|
|
|
|
LCheckBox *caseSensCheck, *entireWordCheck, *wrapAroundCheck, *backwardsCheck;
|
|
|
|
caseSensCheck = dynamic_cast<LCheckBox*>(theDialog->FindPaneByID(kCaseSensitiveCheck));
|
|
ThrowIfNot_(caseSensCheck);
|
|
caseSensCheck->SetValue(caseSensitive ? 1 : 0);
|
|
entireWordCheck = dynamic_cast<LCheckBox*>(theDialog->FindPaneByID(kEntireWordCheck));
|
|
ThrowIfNot_(entireWordCheck);
|
|
entireWordCheck->SetValue(entireWord ? 1 : 0);
|
|
wrapAroundCheck = dynamic_cast<LCheckBox*>(theDialog->FindPaneByID(kWrapAroundCheck));
|
|
ThrowIfNot_(wrapAroundCheck);
|
|
wrapAroundCheck->SetValue(wrapFind ? 1 : 0);
|
|
backwardsCheck = dynamic_cast<LCheckBox*>(theDialog->FindPaneByID(kSearchBackwardsCheck));
|
|
ThrowIfNot_(backwardsCheck);
|
|
backwardsCheck->SetValue(findBackwards ? 1 : 0);
|
|
|
|
theDialog->Show();
|
|
|
|
while (true) // This is our modal dialog event loop
|
|
{
|
|
MessageT hitMessage = theHandler.DoDialog();
|
|
|
|
if (hitMessage == msg_Cancel)
|
|
{
|
|
result = FALSE;
|
|
break;
|
|
|
|
}
|
|
else if (hitMessage == msg_OK)
|
|
{
|
|
editField->GetDescriptor(aStr);
|
|
CPlatformUCSConversion::GetInstance()->PlatformToUCS(aStr, searchText);
|
|
|
|
caseSensitive = caseSensCheck->GetValue() ? TRUE : FALSE;
|
|
entireWord = entireWordCheck->GetValue() ? TRUE : FALSE;
|
|
wrapFind = wrapAroundCheck->GetValue() ? TRUE : FALSE;
|
|
findBackwards = backwardsCheck->GetValue() ? TRUE : FALSE;
|
|
|
|
result = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
result = FALSE;
|
|
// Don't propagate the error.
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
nsresult CBrowserShell::GetClipboardHandler(nsIClipboardCommands **aCommand)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aCommand);
|
|
|
|
nsCOMPtr<nsIClipboardCommands> clipCmd(do_GetInterface(mWebBrowser));
|
|
NS_ENSURE_TRUE(clipCmd, NS_ERROR_FAILURE);
|
|
|
|
*aCommand = clipCmd;
|
|
NS_ADDREF(*aCommand);
|
|
return NS_OK;
|
|
}
|
|
|
|
Boolean CBrowserShell::HasFormElements()
|
|
{
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIDOMWindow> domWindow;
|
|
rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
rv = domWindow->GetDocument(getter_AddRefs(domDoc));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(domDoc);
|
|
if (htmlDoc) {
|
|
nsCOMPtr<nsIDOMHTMLCollection> forms;
|
|
htmlDoc->GetForms(getter_AddRefs(forms));
|
|
if (forms) {
|
|
PRUint32 numForms;
|
|
forms->GetLength(&numForms);
|
|
return numForms > 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CBrowserShell::PostOpenURLEvent(const nsACString& url, const nsACString& referrer)
|
|
{
|
|
// Send an AppleEvent to ourselves to open a new window with the given URL
|
|
|
|
// IMPORTANT: We need to make our target address using a ProcessSerialNumber
|
|
// from GetCurrentProcess. This will cause our AppleEvent to be handled from
|
|
// the event loop. Creating and showing a new window before the context menu
|
|
// click is done being processed is fatal. If we make the target address with a
|
|
// ProcessSerialNumber in which highLongOfPSN == 0 && lowLongOfPSN == kCurrentProcess,
|
|
// the event will be dispatched to us directly and we die.
|
|
|
|
OSErr err;
|
|
ProcessSerialNumber currProcess;
|
|
StAEDescriptor selfAddrDesc;
|
|
|
|
err = ::GetCurrentProcess(&currProcess);
|
|
ThrowIfOSErr_(err);
|
|
err = ::AECreateDesc(typeProcessSerialNumber, (Ptr) &currProcess,
|
|
sizeof(currProcess), selfAddrDesc);
|
|
ThrowIfOSErr_(err);
|
|
|
|
AppleEvent getURLEvent;
|
|
err = ::AECreateAppleEvent(kInternetEventClass, kAEGetURL,
|
|
selfAddrDesc,
|
|
kAutoGenerateReturnID,
|
|
kAnyTransactionID,
|
|
&getURLEvent);
|
|
ThrowIfOSErr_(err);
|
|
|
|
const nsPromiseFlatCString& flatURL = PromiseFlatCString(url);
|
|
StAEDescriptor urlDesc(typeChar, flatURL.get(), flatURL.Length());
|
|
|
|
err = ::AEPutParamDesc(&getURLEvent, keyDirectObject, urlDesc);
|
|
if (err) {
|
|
::AEDisposeDesc(&getURLEvent);
|
|
Throw_(err);
|
|
}
|
|
if (referrer.Length() != 0) {
|
|
const nsPromiseFlatCString& flatReferrer = PromiseFlatCString(referrer);
|
|
StAEDescriptor referrerDesc(typeChar, flatReferrer.get(), flatReferrer.Length());
|
|
err = ::AEPutParamDesc(&getURLEvent, keyGetURLReferrer, referrerDesc);
|
|
if (err) {
|
|
::AEDisposeDesc(&getURLEvent);
|
|
Throw_(err);
|
|
}
|
|
}
|
|
UAppleEventsMgr::SendAppleEvent(getURLEvent);
|
|
}
|
|
|
|
|
|
void
|
|
CBrowserShell::InsideDropArea(DragReference inDragRef)
|
|
{
|
|
if ( sDragHelper ) {
|
|
PRBool dropAllowed = PR_FALSE;
|
|
sDragHelper->Tracking ( inDragRef, mEventSink, &dropAllowed );
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
CBrowserShell::EnterDropArea( DragReference inDragRef, Boolean inDragHasLeftSender)
|
|
{
|
|
sDragHelper = do_GetService ( "@mozilla.org/widget/draghelperservice;1" );
|
|
NS_ASSERTION ( sDragHelper, "Couldn't get a drag service, we're in biiig trouble" );
|
|
if ( sDragHelper )
|
|
sDragHelper->Enter ( inDragRef, mEventSink );
|
|
}
|
|
|
|
|
|
void
|
|
CBrowserShell::LeaveDropArea( DragReference inDragRef )
|
|
{
|
|
if ( sDragHelper ) {
|
|
sDragHelper->Leave ( inDragRef, mEventSink );
|
|
sDragHelper = nsnull;
|
|
}
|
|
}
|
|
|
|
|
|
Boolean
|
|
CBrowserShell::PointInDropArea(Point inGlobalPt)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
Boolean
|
|
CBrowserShell::DragIsAcceptable( DragReference inDragRef )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void
|
|
CBrowserShell::DoDragReceive( DragReference inDragRef )
|
|
{
|
|
if ( sDragHelper ) {
|
|
PRBool dragAccepted = PR_FALSE;
|
|
sDragHelper->Drop ( inDragRef, mEventSink, &dragAccepted );
|
|
}
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
OSStatus CBrowserShell::HandleUpdateActiveInputArea(
|
|
const nsAString& text,
|
|
PRInt16 script,
|
|
PRInt16 language,
|
|
PRInt32 fixLen,
|
|
const TextRangeArray * hiliteRng
|
|
)
|
|
{
|
|
nsCOMPtr<nsIMacTextInputEventSink> tieSink;
|
|
tieSink = do_QueryInterface(mEventSink);
|
|
if (!tieSink)
|
|
return eventNotHandledErr;
|
|
|
|
OSStatus err = noErr;
|
|
nsresult res = tieSink->HandleUpdateActiveInputArea( text,
|
|
script, language,
|
|
fixLen, (void*)hiliteRng,
|
|
&err);
|
|
if (noErr != err)
|
|
return err;
|
|
if (NS_FAILED(res))
|
|
return eventNotHandledErr;
|
|
return noErr;
|
|
}
|
|
|
|
OSStatus CBrowserShell::HandleUnicodeForKeyEvent(
|
|
const nsAString& text,
|
|
PRInt16 script,
|
|
PRInt16 language,
|
|
const EventRecord * keyboardEvent)
|
|
{
|
|
nsCOMPtr<nsIMacTextInputEventSink> tieSink;
|
|
tieSink = do_QueryInterface(mEventSink);
|
|
if (!tieSink)
|
|
return eventNotHandledErr;
|
|
|
|
OSStatus err = noErr;
|
|
nsresult res = tieSink->HandleUnicodeForKeyEvent( text,
|
|
script, language,
|
|
(void*)keyboardEvent,
|
|
&err);
|
|
if (noErr != err)
|
|
return err;
|
|
if (NS_FAILED(res))
|
|
return eventNotHandledErr;
|
|
return noErr;
|
|
}
|
|
|
|
OSStatus CBrowserShell::HandleOffsetToPos(
|
|
PRInt32 offset,
|
|
PRInt16 *pointX,
|
|
PRInt16 *pointY)
|
|
{
|
|
nsCOMPtr<nsIMacTextInputEventSink> tieSink;
|
|
tieSink = do_QueryInterface(mEventSink);
|
|
if (!tieSink)
|
|
return eventNotHandledErr;
|
|
|
|
OSStatus err = noErr;
|
|
nsresult res = tieSink->HandleOffsetToPos( offset, pointX, pointY, &err);
|
|
|
|
if (noErr != err)
|
|
return err;
|
|
if (NS_FAILED(res))
|
|
return eventNotHandledErr;
|
|
return noErr;
|
|
}
|
|
|
|
OSStatus CBrowserShell::HandlePosToOffset(
|
|
PRInt16 currentPointX,
|
|
PRInt16 currentPointY,
|
|
PRInt32 *offset,
|
|
PRInt16 *regionClass
|
|
)
|
|
{
|
|
nsCOMPtr<nsIMacTextInputEventSink> tieSink;
|
|
tieSink = do_QueryInterface(mEventSink);
|
|
if (!tieSink)
|
|
return eventNotHandledErr;
|
|
|
|
OSStatus err = noErr;
|
|
nsresult res = tieSink->HandlePosToOffset( currentPointX, currentPointY,
|
|
offset, regionClass, &err);
|
|
if (noErr != err)
|
|
return err;
|
|
if (NS_FAILED(res))
|
|
return eventNotHandledErr;
|
|
return noErr;
|
|
}
|
|
|
|
OSStatus CBrowserShell::HandleGetSelectedText(nsAString& selectedText)
|
|
{
|
|
nsCOMPtr<nsIMacTextInputEventSink> tieSink;
|
|
tieSink = do_QueryInterface(mEventSink);
|
|
if (!tieSink)
|
|
return eventNotHandledErr;
|
|
|
|
OSStatus err = noErr;
|
|
nsresult res = tieSink->HandleGetSelectedText( selectedText, &err);
|
|
|
|
if (noErr != err)
|
|
return err;
|
|
if (NS_FAILED(res))
|
|
return eventNotHandledErr;
|
|
return noErr;
|
|
}
|
|
|