#include "CWebShell.h" #include "nsIWidget.h" #include "nsIWebShell.h" #include "nsWidgetsCID.h" #include "nsString.h" #include "nsIComponentManager.h" #include "nsRepeater.h" #include "nsIImageManager.h" #include "nsISupports.h" #include "nsIURI.h" #include "nsIDocumentLoader.h" // CWebShell: // A view that embeds a Raptor WebShell. It creates the WebShell and // dispatches the OS events to it. // IMPORTANT: // - ¥¥ root control warning ¥¥ // - Erase on Update should be off nsMacMessageSink CWebShell::mMessageSink; static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID); static NS_DEFINE_IID(kWindowCID, NS_WINDOW_CID); static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID); extern "C" void NS_SetupRegistry(); // --------------------------------------------------------------------------- // ¥ CWebShell Default Constructor [public] // --------------------------------------------------------------------------- CWebShell::CWebShell() { mURL[0] = 0; Init(); } // --------------------------------------------------------------------------- // ¥ CWebShell Stream Constructor [public] // --------------------------------------------------------------------------- CWebShell::CWebShell(LStream* inStream) : LView(inStream) { *inStream >> (StringPtr) mURL; Init(); } // --------------------------------------------------------------------------- // ¥ ~CWebShell Destructor [public] // --------------------------------------------------------------------------- CWebShell::~CWebShell() { if (mWebShell) delete mWebShell; if (mWindow) delete mWindow; } // --------------------------------------------------------------------------- // ¥ Init // --------------------------------------------------------------------------- void CWebShell::Init() { // Initialize the Registry // Note: This can go away when Auto-Registration is implemented in all the Raptor DLLs. static Boolean gFirstTime = true; if (gFirstTime) { gFirstTime = false; NS_SetupRegistry(); // this is obsolete; the Image Manager is now a service, // so will get created on demand. // nsIImageManager *manager; // NS_NewImageManager(&manager); } mWindow = nil; mWebShell = nil; mThrobber = nil; mStatusBar = nil; mLoading = false; // set the QuickDraw origin FocusDraw(); // create top-level widget nsresult rv; rv = nsComponentManager::CreateInstance(kWindowCID, nsnull, kIWidgetIID, (void**)&mWindow); if (NS_FAILED(rv)) return; nsWidgetInitData initData; Rect portRect = GetMacPort()->portRect; nsRect r(portRect.left, portRect.top, portRect.right - portRect.left, portRect.bottom - portRect.top); rv = mWindow->Create((nsNativeWidget)GetMacPort(), r, nsnull, nsnull); if (NS_FAILED(rv)) return; mWindow->Show(PR_TRUE); // create webshell rv = nsComponentManager::CreateInstance(kWebShellCID, nsnull, kIWebShellIID, (void**)&mWebShell); if (NS_FAILED(rv)) return; Rect webRect; CalcPortFrameRect(webRect); r.SetRect(webRect.left, webRect.top, webRect.right - webRect.left, webRect.bottom - webRect.top); PRBool allowPlugins = PR_FALSE; rv = mWebShell->Init(mWindow->GetNativeData(NS_NATIVE_WIDGET), r.x, r.y, r.width, r.height, nsScrollPreference_kNeverScroll, //nsScrollPreference_kAuto, allowPlugins, PR_FALSE); if (NS_FAILED(rv)) return; mWebShell->SetContainer((nsIWebShellContainer*)this); mWebShell->SetDocLoaderObserver((nsIDocumentLoaderObserver*)this); mWebShell->Show(); } // --------------------------------------------------------------------------- // ¥ FinishCreateSelf // --------------------------------------------------------------------------- void CWebShell::FinishCreateSelf() { StartRepeating(); // load the default page nsString urlString; urlString.SetString((char*)&mURL[1], mURL[0]); mWebShell->LoadURL(urlString.GetUnicode()); } // --------------------------------------------------------------------------- // ¥ ResizeFrameBy // --------------------------------------------------------------------------- void CWebShell::ResizeFrameBy( SInt16 inWidthDelta, SInt16 inHeightDelta, Boolean inRefresh) { Inherited::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh); HandleMoveOrResize(); } // --------------------------------------------------------------------------- // ¥ MoveBy // --------------------------------------------------------------------------- void CWebShell::MoveBy( SInt32 inHorizDelta, SInt32 inVertDelta, Boolean inRefresh) { Inherited::MoveBy(inHorizDelta, inVertDelta, inRefresh); HandleMoveOrResize(); } // --------------------------------------------------------------------------- // ¥ HandleMoveOrResize // --------------------------------------------------------------------------- void CWebShell::HandleMoveOrResize() { if (mWebShell && mWindow) { // set the QuickDraw origin FocusDraw(); // resize the top-level widget and the webshell Rect portRect = GetMacPort()->portRect; mWindow->Resize(portRect.right - portRect.left, portRect.bottom - portRect.top, PR_FALSE); Rect webRect; CalcPortFrameRect(webRect); nsRect r(webRect.left, webRect.top, webRect.right - webRect.left, webRect.bottom - webRect.top); mWebShell->SetBounds(r.x, r.y, r.width, r.height); } } // --------------------------------------------------------------------------- // ¥ DrawSelf // --------------------------------------------------------------------------- void CWebShell::DrawSelf() { EventRecord osEvent; osEvent.what = updateEvt; mMessageSink.DispatchOSEvent(osEvent, GetMacPort()); } // --------------------------------------------------------------------------- // ¥ ActivateSelf [protected] // --------------------------------------------------------------------------- void CWebShell::ActivateSelf() { // set the QuickDraw origin FocusDraw(); // dispatch the event EventRecord osEvent; osEvent.what = activateEvt; osEvent.modifiers = activeFlag; mMessageSink.DispatchOSEvent(osEvent, GetMacPort()); } // --------------------------------------------------------------------------- // ¥ DeactivateSelf [protected] // --------------------------------------------------------------------------- void CWebShell::DeactivateSelf() { // set the QuickDraw origin FocusDraw(); // dispatch the event EventRecord osEvent; osEvent.what = activateEvt; osEvent.modifiers = 0; mMessageSink.DispatchOSEvent(osEvent, GetMacPort()); } // --------------------------------------------------------------------------- // ¥ ClickSelf // --------------------------------------------------------------------------- void CWebShell::ClickSelf( const SMouseDownEvent &inMouseDown) { if (!IsTarget()) SwitchTarget(this); // set the QuickDraw origin FocusDraw(); // dispatch the event mMessageSink.DispatchOSEvent((EventRecord&)inMouseDown.macEvent, GetMacPort()); } // --------------------------------------------------------------------------- // ¥ EventMouseUp // --------------------------------------------------------------------------- void CWebShell::EventMouseUp( const EventRecord &inMacEvent) { // set the QuickDraw origin FocusDraw(); // dispatch the event mMessageSink.DispatchOSEvent((EventRecord&)inMacEvent, GetMacPort()); } // --------------------------------------------------------------------------- // ¥ FocusDraw // --------------------------------------------------------------------------- // Set the origin to (0, 0) and the clipRect to our port frame rect // Mostly stolen from LView::FocusDraw(). Boolean CWebShell::FocusDraw( LPane* /* inSubPane */) { // Check if revealed rect is empty Boolean revealed = (mRevealedRect.left < mRevealedRect.right); if (this != sInFocusView) { // Skip if already in focus if (EstablishPort()) { // Set current Mac Port // Set up local coordinate system // ::SetOrigin(mPortOrigin.h, mPortOrigin.v); ::SetOrigin(0, 0); // Clip to revealed area of View Rect clippingRect = mRevealedRect; // PortToLocalPoint(topLeft(clippingRect)); // PortToLocalPoint(botRight(clippingRect)); ::ClipRect(&clippingRect); sInFocusView = this; // Cache current Focus } else { SignalPStr_("\pFocus View with no GrafPort"); } } return revealed; } // --------------------------------------------------------------------------- // ¥ AdjustCursor // --------------------------------------------------------------------------- void CWebShell::AdjustCursor( Point /*inPortPt*/, const EventRecord &/*inMacEvent*/) { } // --------------------------------------------------------------------------- // ¥ DontBeTarget // --------------------------------------------------------------------------- void CWebShell::DontBeTarget() { if (mWebShell) { // set the QuickDraw origin FocusDraw(); // tell form controls that we are losing the focus mWebShell->RemoveFocus(); } } // --------------------------------------------------------------------------- // ¥ HandleKeyPress // --------------------------------------------------------------------------- Boolean CWebShell::HandleKeyPress( const EventRecord &inKeyEvent) { Boolean keyHandled = true; // set the QuickDraw origin FocusDraw(); // dispatch the event keyHandled = mMessageSink.DispatchOSEvent((EventRecord&)inKeyEvent, GetMacPort()); return keyHandled; } // --------------------------------------------------------------------------- // ¥ SpendTime // --------------------------------------------------------------------------- void CWebShell::SpendTime( const EventRecord& inMacEvent) { if (inMacEvent.what == osEvt || inMacEvent.what == nullEvent) { // set the QuickDraw origin FocusDraw(); // dispatch the event mMessageSink.DispatchOSEvent((EventRecord&)inMacEvent, GetMacPort()); } // Enable Raptor background activity // Note: This will be moved to nsMacMessageSink very soon. // The application will not have to do it anymore. Repeater::DoRepeaters(inMacEvent); if (inMacEvent.what == nullEvent) Repeater::DoIdlers(inMacEvent); } #pragma mark - // --------------------------------------------------------------------------- // ¥ Back // --------------------------------------------------------------------------- void CWebShell::Back() { if (mWebShell && (mWebShell->CanBack() == NS_OK)) mWebShell->Back(); else ::SysBeep(1); } // --------------------------------------------------------------------------- // ¥ Forward // --------------------------------------------------------------------------- void CWebShell::Forward() { if (mWebShell && (mWebShell->CanForward() == NS_OK)) mWebShell->Forward(); else ::SysBeep(1); } // --------------------------------------------------------------------------- // ¥ Forward // --------------------------------------------------------------------------- void CWebShell::Stop() { if (mWebShell && mLoading) mWebShell->Stop(); else ::SysBeep(1); } // --------------------------------------------------------------------------- // ¥ LoadURL // --------------------------------------------------------------------------- void CWebShell::LoadURL(LStr255& urlString) { if (mWebShell) { mURL = urlString; nsString nsURLString; nsURLString.SetString((char*)&mURL[1], mURL[0]); mWebShell->LoadURL(nsURLString.GetUnicode()); } else ::SysBeep(1); } // --------------------------------------------------------------------------- // ¥ DisplayStatus // --------------------------------------------------------------------------- void CWebShell::DisplayStatus(const PRUnichar* status) { if (mStatusBar) { nsAutoString statusStr = status; Str255 aStr; aStr[0] = min(statusStr.Length(), 254); statusStr.ToCString((char*)&aStr[1], aStr[0] + 1); mStatusBar->SetDescriptor(aStr); FocusDraw(); } } #pragma mark - // --------------------------------------------------------------------------- // ¥ OnProgressURLLoad // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::OnProgressURLLoad(nsIDocumentLoader* /*loader*/, nsIChannel* channel, PRUint32 aProgress, PRUint32 aProgressMax) { if (mLoading) { nsIURI* url; channel->GetURI(&url); nsAutoString urlString; if (url) { char* str; url->GetSpec(&str); urlString = str; delete[] str; NS_RELEASE(url); } urlString.Append(": progress "); urlString.Append(aProgress, 10); if (0 != aProgressMax) { urlString.Append(" (out of "); urlString.Append(aProgressMax, 10); urlString.Append(")"); } DisplayStatus(urlString.GetUnicode()); } return NS_OK; }; // --------------------------------------------------------------------------- // ¥ OnStatusURLLoad // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::OnStatusURLLoad(nsIDocumentLoader* /*loader*/, nsIChannel* /*channel*/, nsString& aMsg) { DisplayStatus(aMsg.GetUnicode()); return NS_OK; } #pragma mark - // --------------------------------------------------------------------------- // ¥ WillLoadURL // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::WillLoadURL(nsIWebShell* /*aShell*/, const PRUnichar* aURL, nsLoadType /*aReason*/) { nsAutoString url("Connecting to "); url.Append(aURL); DisplayStatus(url.GetUnicode()); return NS_OK; } // --------------------------------------------------------------------------- // ¥ BeginLoadURL // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::BeginLoadURL(nsIWebShell* /*aShell*/, const PRUnichar* aURL) { mLoading = true; if (mThrobber) mThrobber->Show(); DisplayStatus(aURL); return NS_OK; } // --------------------------------------------------------------------------- // ¥ ProgressLoadURL // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::ProgressLoadURL(nsIWebShell* /*aShell*/, const PRUnichar* /*aURL*/, PRInt32 /*aProgress*/, PRInt32 /*aProgressMax*/) { return NS_OK; } // --------------------------------------------------------------------------- // ¥ EndLoadURL // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::EndLoadURL(nsIWebShell* /*aShell*/, const PRUnichar* /*aURL*/, nsresult /*aStatus*/) { mLoading = false; if (mThrobber) mThrobber->Hide(); nsAutoString msg("Done."); DisplayStatus(msg.GetUnicode()); return NS_OK; } // --------------------------------------------------------------------------- // ¥ NewWebShell // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::NewWebShell(PRUint32 /*aChromeMask*/, PRBool /*aVisible*/, nsIWebShell *&aNewWebShell) { aNewWebShell = nsnull; return NS_ERROR_FAILURE; } // --------------------------------------------------------------------------- // ¥ FindWebShellWithName // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::FindWebShellWithName(const PRUnichar* /*aName*/, nsIWebShell*& aResult) { aResult = nsnull; return NS_ERROR_FAILURE; } // --------------------------------------------------------------------------- // ¥ ContentShellAdded // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::ContentShellAdded(nsIWebShell* /*aChildShell*/, nsIContent* /*frameNode*/) { return NS_ERROR_FAILURE; } // --------------------------------------------------------------------------- // ¥ CreatePopup // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent, PRInt32 aXPos, PRInt32 aYPos, const nsString& aPopupType, const nsString& anAnchorAlignment, const nsString& aPopupAlignment, nsIDOMWindow* aWindow, nsIDOMWindow** outPopup) { #pragma unused (aElement) #pragma unused (aPopupContent) #pragma unused (aXPos) #pragma unused (aYPos) #pragma unused (aPopupType) #pragma unused (anAnchorAlignment) #pragma unused (aPopupAlignment) #pragma unused (aWindow) *outPopup = nsnull; return NS_ERROR_FAILURE; } // --------------------------------------------------------------------------- // ¥ FocusAvailable // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::FocusAvailable(nsIWebShell* /*aFocusedWebShell*/, PRBool& aFocusTaken) { aFocusTaken = PR_FALSE; return NS_OK; } // --------------------------------------------------------------------------- // ¥ CanCreateNewWebShell // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::CanCreateNewWebShell(PRBool& aResult) { aResult = PR_FALSE; return NS_ERROR_FAILURE; } // --------------------------------------------------------------------------- // ¥ CanCreateNewWebShell // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::SetNewWebShellInfo(const nsString& /*aName*/, const nsString& /*anURL*/, nsIWebShell* /*aOpenerShell*/, PRUint32 /*aChromeMask*/, nsIWebShell** /*aNewShell*/, nsIWebShell** /*anInnerShell*/) { return NS_ERROR_FAILURE; } // --------------------------------------------------------------------------- // ¥ ChildShellAdded // --------------------------------------------------------------------------- NS_IMETHODIMP CWebShell::ChildShellAdded(nsIWebShell** /*aChildShell*/, nsIContent* /*frameNode*/) { return NS_ERROR_FAILURE; } #pragma mark - // --------------------------------------------------------------------------- // ¥ QueryInterface // --------------------------------------------------------------------------- static NS_DEFINE_IID(kIDocumentLoaderObserverIID, NS_IDOCUMENT_LOADER_OBSERVER_IID); static NS_DEFINE_IID(kIWebShellContainerIID, NS_IWEB_SHELL_CONTAINER_IID); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); NS_IMPL_ADDREF(CWebShell); NS_IMPL_RELEASE(CWebShell); nsresult CWebShell::QueryInterface(const nsIID& aIID, void** aInstancePtrResult) { NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer"); if (nsnull == aInstancePtrResult) { return NS_ERROR_NULL_POINTER; } *aInstancePtrResult = NULL; if (aIID.Equals(kIDocumentLoaderObserverIID)) { *aInstancePtrResult = (void*) ((nsIDocumentLoaderObserver*)this); NS_ADDREF_THIS(); return NS_OK; } if (aIID.Equals(kIWebShellContainerIID)) { *aInstancePtrResult = (void*) ((nsIWebShellContainer*)this); NS_ADDREF_THIS(); return NS_OK; } if (aIID.Equals(kISupportsIID)) { *aInstancePtrResult = (void*) ((nsISupports*)((nsIWebShellContainer*)this)); NS_ADDREF_THIS(); return NS_OK; } return NS_NOINTERFACE; }