/* -*- 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 * * 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 #include #include #include #include #include // ToolBox #include const nsCString CBrowserShell::kEmptyCString; nsCOMPtr 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 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 baseWin(do_QueryInterface(mWebBrowser)); NS_ENSURE_TRUE(baseWin, NS_ERROR_FAILURE); mWebBrowserAsBaseWin = baseWin; nsCOMPtr 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(inMouseDown.macEvent), &handled); } void CBrowserShell::EventMouseUp(const EventRecord &inMacEvent) { FocusDraw(); PRBool handled = PR_FALSE; mEventSink->DispatchEvent(&const_cast(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 focus(do_GetInterface(mWebBrowser)); if (focus) focus->Activate(); } void CBrowserShell::DontBeTarget() { nsCOMPtr 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(inKeyEvent), &handled); return keyHandled; } Boolean CBrowserShell::ObeyCommand(PP_PowerPlant::CommandT inCommand, void* ioParam) { Boolean cmdHandled = true; nsresult rv; nsCOMPtr 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 domWindow; nsCOMPtr domWindowInternal; nsCOMPtr 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 domWindow; nsCOMPtr domWindowInternal; nsCOMPtr 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 linkURI; rv = NS_NewURI(getter_AddRefs(linkURI), NS_ConvertUCS2toUTF8(linkText)); ThrowIfError_(rv); SaveLink(linkURI); } break; case cmd_SaveImage: { ThrowIfNil_(mContextMenuInfo); nsCOMPtr imgURI; mContextMenuInfo->GetImageSrc(getter_AddRefs(imgURI)); ThrowIfNil_(imgURI); SaveLink(imgURI); } break; case cmd_ViewImage: case cmd_CopyImageLocation: { ThrowIfNil_(mContextMenuInfo); nsCOMPtr 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 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 clipCmd; PRBool haveContent, canDo; nsCOMPtr 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(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 baseWin(do_QueryInterface(mWebBrowser)); NS_ENSURE_TRUE(baseWin, NS_ERROR_FAILURE); mWebBrowserAsBaseWin = baseWin; nsCOMPtr 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 ourDocShell(do_GetInterface(mWebBrowser)); NS_ENSURE_TRUE(ourDocShell, NS_ERROR_FAILURE); return ourDocShell->GetContentViewer(aViewer); } NS_METHOD CBrowserShell::GetFocusedWindowURL(nsAString& outURL) { nsCOMPtr wbf(do_GetInterface(mWebBrowser)); if (!wbf) return NS_ERROR_FAILURE; nsCOMPtr domWindow; wbf->GetFocusedWindow(getter_AddRefs(domWindow)); if (!domWindow) mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); if (!domWindow) return NS_ERROR_FAILURE; nsCOMPtr domDocument; domWindow->GetDocument(getter_AddRefs(domDocument)); if (!domDocument) return NS_ERROR_FAILURE; nsCOMPtr nsDoc(do_QueryInterface(domDocument)); if (!nsDoc) return NS_ERROR_FAILURE; nsCOMPtr 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 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 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 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 domDocument; rv = mWebBrowserAsWebNav->GetDocument(getter_AddRefs(domDocument)); if (NS_FAILED(rv)) return rv; nsCOMPtr nsDoc(do_QueryInterface(domDocument)); if (!nsDoc) return NS_ERROR_FAILURE; nsCOMPtr 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 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 webPersist(do_CreateInstance(kPersistContractID, &rv)); if (!webPersist) return rv; // Make a temporary file object that we can save to. nsCOMPtr dirService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); if (!dirService) return rv; nsCOMPtr 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 postData; if (inDocument) { nsCOMPtr webNav(do_QueryInterface(mWebBrowser)); nsCOMPtr sessionHistory; webNav->GetSessionHistory(getter_AddRefs(sessionHistory)); nsCOMPtr entry; PRInt32 sindex; sessionHistory->GetIndex(&sindex); sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry)); nsCOMPtr 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 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 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 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 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* theAttachments = GetAttachmentsList(); if (theAttachments) { TArrayIterator iterate(*theAttachments); LAttachment* theAttach; while (iterate.Next(theAttach)) { aCMAttachment = dynamic_cast(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(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(theDialog->FindPaneByID(kSearchTextEdit)); editField->SetDescriptor(aStr); theDialog->SetLatentSub(editField); LCheckBox *caseSensCheck, *entireWordCheck, *wrapAroundCheck, *backwardsCheck; caseSensCheck = dynamic_cast(theDialog->FindPaneByID(kCaseSensitiveCheck)); ThrowIfNot_(caseSensCheck); caseSensCheck->SetValue(caseSensitive ? 1 : 0); entireWordCheck = dynamic_cast(theDialog->FindPaneByID(kEntireWordCheck)); ThrowIfNot_(entireWordCheck); entireWordCheck->SetValue(entireWord ? 1 : 0); wrapAroundCheck = dynamic_cast(theDialog->FindPaneByID(kWrapAroundCheck)); ThrowIfNot_(wrapAroundCheck); wrapAroundCheck->SetValue(wrapFind ? 1 : 0); backwardsCheck = dynamic_cast(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 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 domWindow; rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); if (NS_SUCCEEDED(rv)) { nsCOMPtr domDoc; rv = domWindow->GetDocument(getter_AddRefs(domDoc)); if (NS_SUCCEEDED(rv)) { nsCOMPtr htmlDoc = do_QueryInterface(domDoc); if (htmlDoc) { nsCOMPtr 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 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 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 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 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 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; }