diff -r 000000000000 -r dd21522fd290 webengine/osswebengine/WebKit/s60/webview/WebView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebKit/s60/webview/WebView.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,2390 @@ +/* +* Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. +* Copyright (C) 2006 David Smith (catfish.man@gmail.com) +* Copyright (C) 2007 Nokia +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include "config.h" +#include "../../bidi.h" +#include "brctl.h" +#include "HistoryController.h" +#include "PageView.h" +#include "SettingsContainer.h" +#include "WebFrame.h" +#include "WebFrameBridge.h" +#include "WebFrameView.h" +#include "WebView.h" +#include "WebTabbedNavigation.h" +#include "WebChromeClient.h" +#include "WebCoreGraphicsContext.h" +#include "WebContextMenuClient.h" +#include "WebEditorClient.h" +#include "WebDragClient.h" +#include "WebFrameLoaderClient.h" +#include "WebInspectorClient.h" +#include "WebFepTextEditor.h" +#include "WebSurface.h" +#include "WebCursor.h" +#include "WebFormFill.h" +#include "WebFormFillPopup.h" +#include "WebToolBarInterface.h" +#include "WebPointerEventHandler.h" +#include "WebPageScrollHandler.h" +#include "WebPopupDrawer.h" +#include "PluginSkin.h" +#include "PluginWin.h" +#include "PluginPlayer.h" + + +#include "Page.h" +#include "Settings.h" +#include "Frame.h" +#include "FrameView.h" +#include "FrameTree.h" +#include "FrameLoader.h" +#include "HistoryItem.h" +#include "EventHandler.h" +#include "ResourceRequest.h" +#include "PlatformString.h" +#include "SelectionController.h" +#include "PlatformKeyboardEvent.h" +#include "PlatformScrollbar.h" +#include "DocumentLoader.h" +#include "StaticObjectsContainer.h" +#include "ToolBar.h" +#include "Document.h" +#include "FocusController.h" +#include "WebUtil.h" +#include "WidgetExtension.h" +#include "Cache.h" +#include "RenderWidget.h" + +#include +#include +#include "WebPageZoomHandler.h" + +#include "PlatformFontCache.h" +#include "WebPageFullScreenHandler.h" +#include "eikon.hrh" +#include "WebScrollbarDrawer.h" + + +using namespace WebCore; + +const int KRepaintDelayLoading = 500*1000; // dont do repaints more often than this during loading (0.5s) +const int KRepaintDelayComplete = 100*1000; // faster updates after load so dynamic scripts etc have better frame rate (0.1s) +const int KNormalScrollRange = 60; + +const int KPanningStartSpeed = 30; +const int KPanningStartTime = 900; +const int KPanningPageScalerStart = 1300; +const int KPanningMaxSpeed = 90; +const int KPanningMaxTime = 3000; +const int KAllowSelection = 1; + +const int KScalerVisibilityTime = 1100*1000; //1.1s + +const int KCursorUpdateFrquency = 20*1000; // 20ms +const int KCursorInitialDelay = 200*1000; // 200ms +const TKeyEvent KNullKeyEvent = {0,0,0,0}; +const int KSmallPageScale = 13*13; // if the area of page is less than 169% (130%*130%) of the viewport area, it's considered to be a small page +const int KZoomLevelDelta = 10; //set 10% for each increasment + +const int KZoomLevelDefaultValue = 100; +const int KZoomLevelMaxValue = 200; +const int KZoomLevelMinValue = 10; + +const int KZoomBgRectColor = 209; +const int KZoomDefaultLevel = 8; //100% +const int defaultCacheCapacity = 256 * 1024; + +// LOCAL FUNCTION PROTOTYPES +TInt doRepaintCb( TAny* ptr ); +TInt doFepCb( TAny* ptr ); + +static WebFrame* incrementFrame(WebFrame* curr, bool forward, bool wrapFlag) +{ + Frame* coreFrame = core(curr); + return kit(forward + ? coreFrame->tree()->traverseNextWithWrap(wrapFlag) + : coreFrame->tree()->traversePreviousWithWrap(wrapFlag)); +} + + + +// ----------------------------------------------------------------------------- +// CWebKitView::NewL +// Public Class Method +// Two-phased constructor. +// ----------------------------------------------------------------------------- +WebView* WebView::NewL( + CCoeControl& parent, CBrCtl* brctl ) +{ + WebView* self = new (ELeave) WebView( brctl ); + + CleanupStack::PushL( self ); + self->ConstructL( parent ); + CleanupStack::Pop(); // self + + return self; +} + +// ----------------------------------------------------------------------------- +// CWebKitView::CWebKitView +// Private Class Method +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +WebView::WebView( CBrCtl* brctl ) : +m_brctl(brctl) +, m_isEditable(false) +, m_currentEventKey(KNullKeyEvent) +, m_scrollingSpeed(KNormalScrollRange*KZoomLevelDefaultValue/100) +, m_focusedElementType(TBrCtlDefs::EElementNone) +, m_pageScaler(NULL) +, m_pageScalerEnabled(false) +, m_inFindState(false) +, m_pageView(NULL) +, m_savedCursorPosition(KInitialOffset, KInitialOffset) +, m_findKeyword(NULL) +, m_webFormFill(NULL) +, m_fepTimer(0) +, m_isClosing(false) +, m_widgetextension(0) +, m_userAgent(NULL) +, m_pageZoomHandler(NULL) +, m_currentZoomLevel(KZoomLevelDefaultValue) +, m_lastZoomLevel(KZoomLevelMinValue) +, m_maxZoomLevel(KZoomLevelMaxValue) +, m_minZoomLevel(KZoomLevelMinValue) +, m_defaultZoomLevel(KZoomLevelDefaultValue) +, m_pageFullScreenHandler(NULL) +, m_viewIsScrolling(false) +, m_ptrbuffer(0) +, m_pluginActivated(false) +, m_showCursor(false) +, m_allowRepaints(true) +{ +} + +WebView::~WebView() +{ + // the zoom handler is a client of WebView (also owned by + // WebView--a circular dependency) so it must be deleted before + // the WebView object is destroyed because in its destructor it + // operates on the WebView object + delete m_pageZoomHandler; + m_pageZoomHandler = NULL; + + // prevent frameViews to access members when topView is + // closing down. + m_isClosing = true; + m_page->setGroupName(String()); + + if (m_fastScrollTimer) + m_fastScrollTimer->Cancel(); + delete m_fastScrollTimer; + + delete [] m_ptrbuffer; + delete m_repainttimer; + delete m_webfeptexteditor; + delete m_webcorecontext; + delete m_bitmapdevice; + delete m_page; + delete m_pageScaler; + delete m_pageView; + delete m_webFormFill; + delete m_toolbar; + delete m_toolbarinterface; + delete m_widgetextension; + delete m_webpointerEventHandler; + delete m_pageScrollHandler; + delete m_pluginplayer; + delete m_fepTimer; + delete m_popupDrawer; + delete m_tabbedNavigation; + delete m_userAgent; + delete m_pageFullScreenHandler; +} + +// ----------------------------------------------------------------------------- +// CWebKitView::ConstructL +// Private Class Method +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +void WebView::ConstructL( + CCoeControl& parent) +{ + SetContainerWindowL(parent); + + CCoeControl::MakeVisible(ETrue); + + WebFrameView *frameView = new WebFrameView(); + m_page = new Page(new WebChromeClient(this), new WebContextMenuClient(), new WebEditorClient(this), new WebDragClient(), new WebInspectorClient()); + m_page->backForwardList()->setCapacity(0); + m_page->setGroupName("com.s60.browser"); + // + WebCore::Settings* settings = m_page->settings(); + settings->setLoadsImagesAutomatically(true); + settings->setJavaScriptEnabled(true); + + settings->setMinimumFontSize(7); + settings->setMinimumLogicalFontSize(9); + settings->setDefaultFontSize(12); + settings->setDefaultFixedFontSize(12); + settings->setPluginsEnabled(true); + settings->setJavaScriptCanOpenWindowsAutomatically(true); + settings->setPluginsEnabled(true); + + m_tabbedNavigation = new WebTabbedNavigation(this); + + WebFrameBridge* bridge = new WebFrameBridge(); + bridge->initMainFrameWithPage(m_page, "", frameView); + + // Create and offscreen device and context + m_bitmapdevice = CFbsBitmapDevice::NewL( StaticObjectsContainer::instance()->webSurface()->offscreenBitmap() ); + m_webcorecontext = WebCoreGraphicsContext::NewL( m_bitmapdevice, StaticObjectsContainer::instance()->webSurface()->offscreenBitmap(), mainFrame()->frameView()); + // + m_repainttimer = CPeriodic::NewL(CActive::EPriorityHigh); + + m_webfeptexteditor = new CWebFepTextEditor(this); + + m_fastScrollTimer = CPeriodic::NewL(CActive::EPriorityHigh); + + m_dirtyZoomMode = false; + m_currentZoomLevel = StaticObjectsContainer::instance()->fontCache()->fontZoomFactor(); + m_startZoomLevel = m_currentZoomLevel; + + m_pageZoomHandler = WebPageZoomHandler::NewL( *this ); + if ( brCtl()->capabilities()&TBrCtlDefs::ECapabilityFitToScreen ) { + m_minZoomLevel = (KZoomLevelDefaultValue / m_pageZoomHandler->stepSize())*m_pageZoomHandler->stepSize(); + //could happen only if m_minZoomLevel < stepSize + if (!m_minZoomLevel) m_minZoomLevel = m_pageZoomHandler->stepSize(); + } + + // construct the zoom array from the default level + m_zoomLevelArray.Append(KZoomLevelDefaultValue); + TInt toAddZoomLevel = KZoomLevelDefaultValue + KZoomLevelDefaultValue*KZoomLevelDelta/100; + while (toAddZoomLevel <= m_maxZoomLevel) + { + // add the zoom level after default one + m_zoomLevelArray.Append(toAddZoomLevel); + toAddZoomLevel = toAddZoomLevel + toAddZoomLevel*KZoomLevelDelta/100; + } + + // now go the minimum one + toAddZoomLevel = KZoomLevelDefaultValue - KZoomLevelDefaultValue*KZoomLevelDelta/100; + while (toAddZoomLevel >= m_minZoomLevel) + { + //add the zoom level after default one + m_zoomLevelArray.Insert(toAddZoomLevel, 0); + toAddZoomLevel = toAddZoomLevel - toAddZoomLevel*KZoomLevelDelta/100; + } + + m_pageFullScreenHandler = WebPageFullScreenHandler::NewL( *this ); + + if ( m_brctl->capabilities() & TBrCtlDefs::ECapabilityWebKitLite ) { + m_pageScalerEnabled = false; + } + else { + initializePageScalerL(); + m_pageScalerEnabled = true; + } + if (m_brctl->capabilities() & TBrCtlDefs::ECapabilityAutoFormFill) { + m_webFormFill = new WebFormFill(this); + } + + // Create the PointerEventHandler + m_ptrbuffer = new TPoint[256]; + m_webpointerEventHandler = WebPointerEventHandler::NewL(this); + + // Create the ScrollHandler + m_pageScrollHandler = WebPageScrollHandler::NewL( *this ); + if (AknLayoutUtils::PenEnabled()) { + DrawableWindow()->SetPointerGrab(ETrue); + EnableDragEvents(); + } + + CUserAgent* usrAgnt = CUserAgent::NewL(); + CleanupStack::PushL( usrAgnt ); + HBufC8* userAgent8 = usrAgnt->UserAgentL(); + CleanupStack::PushL( userAgent8 ); + m_userAgent = HBufC::NewL(userAgent8->Length()); + m_userAgent->Des().Copy(userAgent8->Des()); + CleanupStack::PopAndDestroy(2); // userAgent8, usrAgnt + + MakeViewVisible(ETrue); + m_isPluginsVisible=ETrue; + CCoeControl::SetFocus(ETrue); + + cache()->setCapacities(0, 0, defaultCacheCapacity); +} + +void WebView::initializePageScalerL() +{ + TBool lowQuality = !( m_brctl->capabilities() & TBrCtlDefs::ECapabilityGraphicalHistory ); + m_pageScaler = CPageScaler::NewL( *this, EColor64K, lowQuality ); + m_pageScaler->SetVisible( EFalse ); + //update the minimap support info from page scaler + m_pageScalerEnabled = (m_pageScaler->HasOverlaySupport()); +} + + +void WebView::fepTimerFired(Timer*) +{ + CCoeEnv::Static()->SimulateKeyEventL(m_keyevent, m_eventcode); +} + +//------------------------------------------------------------------------------- +// Draw ( from CCoeControl ) +// BitBlts the offscreen bitmap to the GraphicsContext +//------------------------------------------------------------------------------- +void WebView::Draw( + const TRect& rect ) const +{ + if (m_pluginFullscreen) return; + + CWindowGc& gc = SystemGc(); + CEikBorderedControl::Draw( rect ); + + // put offscreen bitmap onto the screen + + if ( !m_dirtyZoomMode ) { + StaticObjectsContainer::instance()->webSurface()->flip( Rect().iTl, gc ); + if (m_widgetextension){ + m_widgetextension->DrawTransition(gc,StaticObjectsContainer::instance()->webSurface()->offscreenBitmap()); + } + } + else { + gc.DrawBitmap( m_destRectForZooming, StaticObjectsContainer::instance()->webSurface()->offscreenBitmap(), m_srcRectForZooming ); + + if ( m_startZoomLevel > m_currentZoomLevel) { + + TRect rectLeft( TPoint( rect.iTl.iX + m_destRectForZooming.Width() - 2, rect.iTl.iY ), + TPoint( rect.iBr )); + + TRect rectBottom( TPoint( rect.iTl.iX, rect.iTl.iY + m_destRectForZooming.Height() - 2 ), + TPoint( rect.iBr.iX + m_destRectForZooming.Width(), rect.iBr.iY )); + + + const TRgb colorTest(KZoomBgRectColor,KZoomBgRectColor,KZoomBgRectColor); + gc.SetPenColor(colorTest); + gc.SetBrushStyle( CGraphicsContext::EForwardDiagonalHatchBrush ); + gc.SetBrushColor(colorTest); + gc.DrawRect( rectLeft ); + gc.DrawRect( rectBottom ); + + } + + } + + if (m_pageScalerEnabled && m_pageScaler->Visible()) { + m_pageScaler->Draw( gc, rect ); + } + + if (m_toolbar) { + m_toolbar->Draw(); + } + + if (m_popupDrawer) + { + m_popupDrawer->drawPopup(); + } + + if (m_widgetextension){ + m_widgetextension->DrawTransition(gc,StaticObjectsContainer::instance()->webSurface()->offscreenBitmap()); + } + + +} + + +WebCore::Page* WebView::page() +{ + return m_page; +} + + +WebFrame* WebView::mainFrame() +{ + if (!m_page) + return NULL; + return kit(m_page->mainFrame()); +} + +//------------------------------------------------------------------------------- +// SyncRepaint +// Repaint the given rectangle synchronously +//------------------------------------------------------------------------------- +void WebView::syncRepaint( + const TRect& rect) +{ + m_repaints.AddRect( rect ); + syncRepaint(); +} + +void WebView::MakeVisible(TBool visible) +{ + if (visible == IsVisible()) return; + CCoeControl::MakeVisible(visible); + MakeViewVisible(visible); +} + +void WebView::MakeViewVisible(TBool visible) +{ + if ( visible ) { + // resize the offscreen surface, this is needed + // because the shared surface is changed. + StaticObjectsContainer::instance()->webSurface()->setView( this ); + m_bitmapdevice->Resize( m_offscreenrect.Size() ); + m_webcorecontext->resized(); + } + WebCursor* cursor = StaticObjectsContainer::instance()->webCursor(); + if (cursor) { + if (visible) { + cursor->setCurrentView(*this); + //Reset the iFocusedElementType to be the same as before the second window is opened. + cursor->setPosition(m_savedCursorPosition); + cursor->updatePositionAndElemType(m_savedCursorPosition); + } else + m_savedCursorPosition = cursor->position(); + cursor->cursorUpdate(visible & !AknLayoutUtils::PenEnabled()); + } + Frame* f = m_page->mainFrame(); + while ( f ) { + PassRefPtr objects = f->document()->objects(); + for (Node* n = objects->firstItem(); n; n = objects->nextItem()) { + MWebCoreObjectWidget* w = widget(n); + if (w) + w->makeVisible(visible); + } + PassRefPtr embeds = f->document()->embeds(); + for (Node* n = embeds->firstItem(); n; n = embeds->nextItem()) { + MWebCoreObjectWidget* w = widget(n); + if (w) + w->makeVisible(visible); + } + f = f->tree()->traverseNext(); + } + if ( m_pageScaler ) { + m_pageScaler->SetContainerRect(TRect(Rect().Size())); + } + if ( m_webFormFillPopup ){ + // don't show the popup if view's visibility changes. + m_webFormFillPopup->MakeVisible(EFalse); + } + + if ( visible ) { + clearOffScreenBitmap(); + syncRepaint( mainFrame()->frameView()->visibleRect() ); + } + +} + + + +void WebView::doLayout() +{ + + int zoomLevel = m_currentZoomLevel; + if(!( m_widgetextension && m_widgetextension->IsWidgetPublising())) { + zoomLevelChanged( KZoomLevelDefaultValue ); + } + Frame* f = m_page->mainFrame(); + + while ( f ) { + f->sendResizeEvent(); + f->view()->layout(); + f = f->tree()->traverseNext(); + } + // maybe it got bigger in layout? + TRect rect(m_repaints.BoundingRect()); + + TPoint p( mainFrame()->frameView()->contentPos()); + + rect.Move(-p); + + // draw to back buffer + + + if(!( m_widgetextension && m_widgetextension->IsWidgetPublising())) { + mainFrame()->frameView()->draw( *m_webcorecontext, rect ); + if ( zoomLevel < m_minZoomLevel ) zoomLevel = m_minZoomLevel; + zoomLevelChanged( zoomLevel ); + } +} +//------------------------------------------------------------------------------- +// SyncRepaint +// Repaint the current repaint region synchronously and clear it +//------------------------------------------------------------------------------- +void WebView::syncRepaint() +{ + if (m_pageScaler && m_pageScaler->FullScreenMode()) { + ScaledPageChanged(m_pageScaler->Rect(), EFalse, EFalse); + return; + } + + if (!IsVisible()) { + return; + } + + if (isPluginFullscreen()) return; + CFbsBitGc& gc = m_webcorecontext->gc(); + gc.Reset(); + + TRect viewRect( mainFrame()->frameView()->visibleRect() ); + TPoint p( mainFrame()->frameView()->contentPos()); + Frame* f = m_page->mainFrame(); + bool layoutPending = false; + while (f && !layoutPending) { + layoutPending = f->view()->layoutPending(); + f = f->tree()->traverseNext(); + } + if (!layoutPending) { + bool needsDraw = false; + m_repaints.Tidy(); + for (int i=0; iframeView()->draw( *m_webcorecontext, r ); + needsDraw = true; + } + } + + if (needsDraw){ + // blit the whole backbuffer to the screen (in Draw()) + // This could be optimized further to blit only the affected area. + // Not a big win, scrolling is the most critical case and there you + // need to blit the whole buffer anyway. + m_brctl->DrawNow(); + } + + // dont do next async repaint until KRepaintDelay + m_repaints.Clear(); + } + m_repainttimer->Cancel(); + // tot:fixme TBool complete = iWebkitControl->IsProgressComplete(); && CImageRendererFactory::Instance()->DecodeCount()==0; + + TBool complete = ETrue; + if ( !m_pageZoomHandler->isActive() && m_allowRepaints){ + m_repainttimer->Start(complete ? KRepaintDelayComplete : KRepaintDelayLoading, + 0, TCallBack( &doRepaintCb, this ) ); + } + // need to draw formfill popup here. + if (m_webFormFillPopup && m_webFormFillPopup->IsVisible()) { + m_webFormFillPopup->reDraw(); + } +} + +//------------------------------------------------------------------------------- +// DoRepaintCb +// C-style TCallback function +//------------------------------------------------------------------------------- +TInt doRepaintCb( + TAny* ptr ) +{ + static_cast(ptr)->doRepaint(); + return EFalse; +} + +//------------------------------------------------------------------------------- +// DoRepaint +// Perform a scheduled repaint +//------------------------------------------------------------------------------- +void WebView::doRepaint() +{ + // the timer must always be canceled here! + m_repainttimer->Cancel(); + + // only repaint when this view owns the surface + if ( StaticObjectsContainer::instance()->webSurface()->topView() != this ) return; + + // anything to do? + if ( !m_repaints.IsEmpty() ) { + syncRepaint( ); + } +} + +//------------------------------------------------------------------------------- +// CollectOffscreenbitmap +// Get offscreen bitmap +//------------------------------------------------------------------------------- +void WebView::collectOffscreenbitmapL(CFbsBitmap& snapshot) +{ + + (snapshot).Create(m_brctl->Size(), StaticObjectsContainer::instance()->webSurface()->displayMode()); + + CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( &snapshot); + CleanupStack::PushL(device); + + WebCoreGraphicsContext* gc = WebCoreGraphicsContext::NewL( device, &snapshot, mainFrame()->frameView()); + CleanupStack::PushL(gc); + + mainFrame()->frameView()->draw( *gc, mainFrame()->frameView()->visibleRect() ); + + CleanupStack::PopAndDestroy(2); + +} + +//------------------------------------------------------------------------------- +// ScheduleRepaint +// Schedule an asynchronous repaint +//------------------------------------------------------------------------------- +void WebView::scheduleRepaint( + const TRect& rect ) +{ + m_repaints.AddRect( rect ); + if( m_widgetextension && m_widgetextension->IsWidgetPublising()) + { +#ifdef BRDO_WRT_HS_FF + // Draw the miniview + m_brctl->brCtlLayoutObserver()->NotifyLayoutChange(EOriginTopLeft); +#endif + } + // if we are active, we'll repaint when timer fires + if( !m_repainttimer->IsActive() && !m_pageZoomHandler->isActive() && + m_allowRepaints) { + // no timer yet, repaint immediatly (but asynchronously) + m_repainttimer->Start( 0, 0, TCallBack( &doRepaintCb, this ) ); + } +} + +void WebView::pageLoadFinished() +{ + + if (m_brctl->settings() && m_brctl->settings()->getTabbedNavigation()) { + m_tabbedNavigation->initializeForPage(); + } + else { + + // Temp solution to fix a problem with scrolling large pages: + // if user starts scrolling while loading a page - at the end of the load we should not restore + // the content position from the history controller + // As of now scroll events are not passed to WebCore and this will be changed in future + // then this code should be replaces with the commented one below + + TPoint ptInit(0,0); + TPoint ptFromHistory = m_brctl->historyHandler()->historyController()->currentEntryPosition(); + TPoint ptCurr = mainFrame()->frameView()->contentPos(); + + if ( ptCurr != ptFromHistory ) { + if ( ptInit == ptCurr ) { + mainFrame()->frameView()->scrollTo(ptFromHistory); + } + else { + m_brctl->historyHandler()->historyController()->updateCurrentEntryPositionIfNeeded(); + } + } + /* + if ( !core(mainFrame())->view()->wasScrolledByUser()) + mainFrame()->frameView()->scrollTo(m_brctl->historyHandler()->historyController()->currentEntryPosition());*/ + + } + + if (FrameLoadTypeStandard == core( mainFrame())->loader()->loadType()){ + if (m_brctl->capabilities()&TBrCtlDefs::ECapabilityFitToScreen){ + updateMinZoomLevel( mainFrame()->frameView()->contentSize()); + } + } + + setHistoryLoad(false); + setRedirectWithLockedHistory(false); + + int zoomLevel = m_brctl->historyHandler()->historyController()->currentEntryZoomLevel(); + if ( zoomLevel != m_currentZoomLevel) { + m_brctl->historyHandler()->historyController()->updateCurrentEntryZoomLevelIfNeeded(); + } + if ( m_pageScaler ) { + m_pageScaler->DocumentCompleted(); + TRAP_IGNORE(m_pageScaler->DocumentChangedL()); + } + + Node* focusedNode = NULL; + Frame* focusedFrame = page()->focusController()->focusedFrame(); + + if (focusedFrame) + { + focusedNode = focusedFrame->document()->focusedNode(); + + if (focusedNode) { // based on focused element + m_focusedElementType = nodeTypeB(focusedNode, focusedFrame); + } + else { + m_focusedElementType = TBrCtlDefs::EElementNone; + } + } + else { + m_focusedElementType = TBrCtlDefs::EElementNone; + } + m_brctl->updateDefaultSoftkeys(); +} + +void WebView::updatePageScaler() +{ + if (m_brctl->capabilities() & TBrCtlDefs::ECapabilityGraphicalPage) { + TRAP_IGNORE(if (m_pageScaler) m_pageScaler->DocumentChangedL()); + } +} + +void WebView::openUrl(const TDesC& url) +{ + mainFrame()->loadRequest(WebCore::ResourceRequest(url, true)); +} + +WebCore::DOMDocument* WebView::mainFrameDocument() +{ + return mainFrame()->DOMDocument(); +} + +TBool WebView::shouldClose() +{ + Frame* coreFrame = core(mainFrame()); + if (!coreFrame) + return ETrue; + return coreFrame->shouldClose(); +} + +TBool WebView::isLoading() +{ + return m_page->mainFrame()->loader()->activeDocumentLoader()->isLoading(); +} + +TInt WebView::CountComponentControls() const +{ + int count = (m_webFormFillPopup && m_webFormFillPopup->IsVisible()) ? 1 : 0; + return count; +} + +CCoeControl* WebView::ComponentControl(TInt aIndex) const +{ + CCoeControl* rv = NULL; + + if ( aIndex == 0) + if ( m_webFormFillPopup && m_webFormFillPopup->IsVisible()) rv = m_webFormFillPopup; + + return rv; +} + +TKeyResponse WebView::OfferKeyEventL(const TKeyEvent& keyevent, TEventCode eventcode ) +{ + WebCursor* cursor = StaticObjectsContainer::instance()->webCursor(); + //hijack + if (isSynchRequestPending()) { + return EKeyWasNotConsumed; + } + if (m_toolbar) + return m_toolbar->HandleOfferKeyEventL(keyevent, eventcode); + + if (m_popupDrawer) + return m_popupDrawer->handleOfferKeyEventL(keyevent, eventcode ); + + if ( m_webFormFillPopup && m_webFormFillPopup->IsVisible() && AknLayoutUtils::PenEnabled() ) { + if (EKeyWasConsumed == m_webFormFillPopup->HandleKeyEventL(keyevent, eventcode)) { + return EKeyWasConsumed; + } + } + + bool consumed = false; + Frame* coreFrame = core(mainFrame()); + if (!coreFrame) + return EKeyWasNotConsumed; + + coreFrame = page()->focusController()->focusedOrMainFrame(); + + // edit events + if (m_isEditable) { + consumed = page()->focusController()->focusedOrMainFrame()->eventHandler()->keyEvent(PlatformKeyboardEvent(keyevent,eventcode)); + // exit input on up/down key + // EXCEPT on touch-enabled devices. We'll just consume in that case + if ( !consumed + && ( keyevent.iCode == EKeyUpArrow // North + || keyevent.iCode == EKeyRightUpArrow // Northeast + || keyevent.iCode == EStdKeyDevice11 // : Extra KeyEvent supports diagonal event simulator wedge + || keyevent.iCode == EKeyRightArrow // East + || keyevent.iCode == EKeyRightDownArrow // Southeast + || keyevent.iCode == EStdKeyDevice12 // : Extra KeyEvent supports diagonal event simulator wedge + || keyevent.iCode == EKeyDownArrow // South + || keyevent.iCode == EKeyLeftDownArrow // Southwest + || keyevent.iCode == EStdKeyDevice13 // : Extra KeyEvent supports diagonal event simulator wedge + || keyevent.iCode == EKeyLeftArrow // West + || keyevent.iCode == EKeyLeftUpArrow // Northwest + || keyevent.iCode == EStdKeyDevice10 ) ) // : Extra KeyEvent supports diagonal event simulator wedge + { + if (m_webfeptexteditor->validateTextFormat() ) { + setFocusNone(); + } else { + consumed = true; + } + } + } + + // scroll events + if (!consumed) { + switch( eventcode ) { + case EEventKeyDown: + m_currentEventKey = keyevent; + //page()->mainFrame()->setFocusedNodeIfNeeded(); + //coreFrame->eventHandler()->mousePressNode()->focus(); + + break; + case EEventKey: + if (keyevent.iScanCode != m_currentEventKey.iScanCode ) return EKeyWasNotConsumed; + // + m_currentEventKey = keyevent; + if (keyevent.iCode == EKeyDevice3) { + // pass it to webcore + TPointerEvent event; + event.iPosition = StaticObjectsContainer::instance()->webCursor()->position(); + event.iModifiers = 0; + event.iType = TPointerEvent::EButton1Down ; + coreFrame->eventHandler()->handleMousePressEvent(PlatformMouseEvent(event)); + + // mimic ccb's behavior of onFocus + Node* node = page()->focusController()->focusedOrMainFrame()->eventHandler()->mousePressNode(); + for (Node* n = node; n; n = n->parentNode()) { + if ( n->isFocusable() ) { + page()->focusController()->setFocusedNode(n, page()->focusController()->focusedOrMainFrame()); + } + } + + // Toolbar is activated on long key press only if the element + // type is EElementNone during EEventKeyDown and EEventKey. + // This prevents toolbar from popping up in DHTML pages. Also, + // toolbar is activated when the user is not in fast scroll + // mode, or in page overview mode, or on wml page. + if ( ( m_focusedElementType == TBrCtlDefs::EElementNone || + m_focusedElementType == TBrCtlDefs::EElementBrokenImage ) && + keyevent.iRepeats && !m_brctl->wmlMode() ) + { + launchToolBarL(); + } + consumed = true; + } else if ( keyevent.iCode == EKeyUpArrow // North + || keyevent.iCode == EKeyRightUpArrow // Northeast + || keyevent.iCode == EStdKeyDevice11 // : Extra KeyEvent supports diagonal event simulator wedge + || keyevent.iCode == EKeyRightArrow // East + || keyevent.iCode == EKeyRightDownArrow // Southeast + || keyevent.iCode == EStdKeyDevice12 // : Extra KeyEvent supports diagonal event simulator wedge + || keyevent.iCode == EKeyDownArrow // South + || keyevent.iCode == EKeyLeftDownArrow // Southwest + || keyevent.iCode == EStdKeyDevice13 // : Extra KeyEvent supports diagonal event simulator wedge + || keyevent.iCode == EKeyLeftArrow // West + || keyevent.iCode == EKeyLeftUpArrow // Northwest + || keyevent.iCode == EStdKeyDevice10 ) // : Extra KeyEvent supports diagonal event simulator wedge + { + if (m_brctl->settings()->getTabbedNavigation()) { + int horizontal = 0; + int vertical = 0; + switch(keyevent.iCode) + { + case EKeyUpArrow: // North + vertical = -1; + break; + + case EKeyRightUpArrow: // Northeast + case EStdKeyDevice11: // : Extra KeyEvent supports diagonal event simulator wedge + vertical = -1; + horizontal = +1; + break; + + case EKeyRightArrow: // East + horizontal = +1; + break; + + case EKeyRightDownArrow: // Southeast + case EStdKeyDevice12: // : Extra KeyEvent supports diagonal event simulator wedge + vertical = +1; + horizontal = +1; + break; + + case EKeyDownArrow: // South + vertical = +1; + break; + + case EKeyLeftDownArrow: // Southwest + case EStdKeyDevice13: // : Extra KeyEvent supports diagonal event simulator wedge + vertical = +1; + horizontal = -1; + break; + + case EKeyLeftArrow: // West + horizontal = -1; + break; + + case EKeyLeftUpArrow: // Northwest + case EStdKeyDevice10: // : Extra KeyEvent supports diagonal event simulator wedge + vertical = -1; + horizontal = -1; + break; + + default: // (Should never get here) + break; + + } + + consumed = m_tabbedNavigation->navigate(horizontal, vertical); + } + else { + // start fast scrolling + m_showCursor = true; + if (!cursor->isVisible()) { + cursor->cursorUpdate(true); + } + bool fastscroll(m_fastScrollTimer->IsActive()); + m_savedPosition = mainFrame()->frameView()->contentPos(); + cursor->scrollAndMoveCursor(keyevent.iCode, m_scrollingSpeed, fastscroll); + if (!fastscroll) { + m_fastScrollTimer->Start(KCursorInitialDelay,KCursorUpdateFrquency,TCallBack(&scrollTimerCb,this)); + m_scrollingStartTime.HomeTime(); + } + // and minimap comes on + int scrollingTime = millisecondsScrolled(); + if (!AknLayoutUtils::PenEnabled() && m_pageScalerEnabled && m_pageScaler && !isSmallPage() && + m_brctl->settings()->brctlSetting(TBrCtlDefs::ESettingsPageOverview) && + (scrollingTime > KPanningPageScalerStart || m_pageScaler->Visible())) { + m_pageScaler->SetVisibleUntil(KScalerVisibilityTime); + } + // + if (!fastscroll) { + TPointerEvent event; + event.iPosition = cursor->position(); + event.iModifiers = 0; + event.iType = TPointerEvent::EMove; + coreFrame->eventHandler()->handleMouseMoveEvent(PlatformMouseEvent(event)); + } + consumed = true; + } // if (m_brctl->settings()->getTabbedNavigation() + } else { + // activate hovered input element by just start typing + if (m_focusedElementType == TBrCtlDefs::EElementInputBox || m_focusedElementType == TBrCtlDefs::EElementSelectBox + || m_focusedElementType == TBrCtlDefs::EElementSelectMultiBox || m_focusedElementType == TBrCtlDefs::EElementTextAreaBox) { + TPointerEvent event; + event.iModifiers = 0; + event.iPosition = cursor->position(); + event.iType = TPointerEvent::EButton1Down ; + coreFrame->eventHandler()->handleMousePressEvent(PlatformMouseEvent(event)); + event.iType = TPointerEvent::EButton1Up; + coreFrame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(event)); + + + if (m_focusedElementType == TBrCtlDefs::EElementInputBox || m_focusedElementType == TBrCtlDefs::EElementTextAreaBox) { + if (!m_fepTimer) + m_fepTimer = new WebCore::Timer(this, &WebView::fepTimerFired); + + m_fepTimer->startOneShot(0.2f); + setEditable(true); + } + m_keyevent = keyevent; + m_eventcode = eventcode; + + consumed = true; + } + } + break; + case EEventKeyUp: + m_fastScrollTimer->Cancel(); + m_scrollingSpeed = KNormalScrollRange*100/scalingFactor(); + + if (viewIsFastScrolling()) { + setViewIsFastScrolling(false); + toggleRepaintTimer(true); + if (AknLayoutUtils::PenEnabled() && !inPageViewMode()) { + m_pageScrollHandler->scrollbarDrawer()->fadeScrollbar(); + } + } + m_currentEventKey = KNullKeyEvent; + if ( (keyevent.iScanCode == EStdKeyDevice3) || (keyevent.iScanCode == EStdKeyEnter) ){ + // pass it to webcore + TPointerEvent event; + if (m_focusedElementType == TBrCtlDefs::EElementInputBox || + m_focusedElementType == TBrCtlDefs::EElementTextAreaBox) + { + setEditable(true); + } + event.iPosition = cursor->position(); + event.iType = TPointerEvent::EButton1Up; + coreFrame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(event)); + consumed = true; + } + break; + } + } + + // keyevents + if (!consumed) { + consumed = coreFrame->eventHandler()->keyEvent(PlatformKeyboardEvent(keyevent,eventcode)); + if (!consumed && eventcode == EEventKey && (m_brctl->capabilities() & TBrCtlDefs::ECapabilityAccessKeys)) { + TKeyEvent ke = keyevent; + TChar c(ke.iCode); + // Not consumed by WebCore, is alphanumeric and does not have any modifier + if (c.IsAlphaDigit() && !(ke.iModifiers & (EModifierCtrl | EModifierAlt | EModifierShift))) { + ke.iModifiers = EModifierCtrl; + coreFrame->eventHandler()->keyEvent(PlatformKeyboardEvent(ke,EEventKeyDown)); + consumed = true; + } + } + } + + //setEditable(); + + return (consumed)?EKeyWasConsumed:EKeyWasNotConsumed; +} + + +void WebView::updateScrollbars(int documentHeight, int displayPosY, int documentWidth, int displayPosX) +{ + m_brctl->updateScrollbars((documentHeight * scalingFactor()) / 100, Rect().Height(), + (displayPosY * scalingFactor()) / 100, (documentWidth * scalingFactor()) / 100, Rect().Width(), + (displayPosX * scalingFactor()) / 100); +} + +void WebView::openPageViewL() +{ + // don't show pageview if we are in lite mode + if ( m_brctl->capabilities() & TBrCtlDefs::ECapabilityWebKitLite ) + return; + if (!m_pageView) { + m_pageView = CPageView::NewL(*this); + MakeVisible(EFalse); + m_savedPosition = mainFrame()->frameView()->contentPos(); + m_brctl->reportStateChanged(TBrCtlDefs::EStateThumbnailView, ETrue); + } +} + +void WebView::closePageView() +{ + if ( m_brctl->capabilities() & TBrCtlDefs::ECapabilityWebKitLite ) + return; + if (m_pageView) { + delete m_pageView; + m_pageView = 0; + MakeVisible(ETrue); + m_brctl->DrawNow(); + m_brctl->reportStateChanged(TBrCtlDefs::EStateThumbnailView, EFalse); + } +} + +void WebView::cancelPageView() +{ + if ( m_brctl->capabilities() & TBrCtlDefs::ECapabilityWebKitLite ) + return; + if (m_pageView) { + mainFrame()->frameView()->scrollTo(m_savedPosition); + closePageView(); + } +} + +//------------------------------------------------------------------------------- +// launchToolBarL +//------------------------------------------------------------------------------- +void WebView::launchToolBarL() +{ + if ( AknLayoutUtils::PenEnabled() || m_brctl->wmlMode() ) { + return; + } + + if ( !(m_brctl->capabilities() & TBrCtlDefs::ECapabilityToolBar) ) { + return; + } + + if ( !m_brctl->settings()->brctlSetting(TBrCtlDefs::ESettingsToolbarOnOff) ) { + return; + } + + delete m_toolbar; + m_toolbar = 0; + + delete m_toolbarinterface; + m_toolbarinterface = 0; + + m_toolbarinterface = new WebToolBarInterface(this); + TRAPD(leave, m_toolbar = CToolBar::NewL(*m_toolbarinterface)); + if (leave != KErrNone) + return; + + /*EnableDragEvents();*/ + + m_brctl->DrawNow(); + m_brctl->reportStateChanged(TBrCtlDefs::EStateToolBarMode, ETrue); + +} + +//------------------------------------------------------------------------------- +// closeToolBarL +//------------------------------------------------------------------------------- +void WebView::closeToolBarL() +{ + delete m_toolbar; + m_toolbar = 0; + + delete m_toolbarinterface; + m_toolbarinterface = 0; + + if (IsVisible()) + { + StaticObjectsContainer::instance()->webCursor()->cursorUpdate(ETrue); + m_brctl->DrawNow(); + } + + m_brctl->reportStateChanged(TBrCtlDefs::EStateToolBarMode, EFalse); +} + +//------------------------------------------------------------------------------- +// DrawDocumentPart ( from MPageScalerCallback ) +// +// +//------------------------------------------------------------------------------- +void WebView::DrawDocumentPart( + CFbsBitGc& aGc, + CFbsBitmap* aBitmap, + const TRect& aDocumentAreaToDraw ) +{ + TRect r( mainFrame()->frameView()->toDocCoords(aDocumentAreaToDraw) ) ; + WebCoreGraphicsContext* wcgc = 0; + TRAPD( err, wcgc = WebCoreGraphicsContext::NewL( aGc, aBitmap, mainFrame()->frameView())); + if ( err == KErrNone ) + { + // ensure all documents have valid layout + // tot:fixme + //mainFrame->LayoutRecursive(); + + TWebCoreSavedContext saved( wcgc->save() ); + + wcgc->setOrigin( -aDocumentAreaToDraw.iTl ); + wcgc->setClippingRect( aDocumentAreaToDraw ); + + // draw using bridge directly as frame::draw clips drawing to view size + mainFrame()->paintRect( *wcgc, r ); + wcgc->restore(saved); + delete wcgc; + } +} + +//------------------------------------------------------------------------------- +// DocumentViewport ( from MPageScalerCallback ) +// +// +//------------------------------------------------------------------------------- +TRect WebView::DocumentViewport() +{ + return mainFrame()->frameView()->toViewCoords(mainFrame()->frameView()->visibleRect()); +} + +//------------------------------------------------------------------------------- +// ScaledPageChanged ( from MPageScalerCallback ) +// +// +//------------------------------------------------------------------------------- +void WebView::ScaledPageChanged( + const TRect& aRect, + TBool aFullScreen, + TBool aScroll ) +{ + if (!aScroll) { + Window().Invalidate( aRect ); + } + + if ( !aScroll && aFullScreen ) + { + // update the history with new bitmap + CFbsBitmap* scaledPage = m_pageScaler->ScaledPage(); + if (scaledPage) { + // Get the browser control rect + TRAP_IGNORE( m_brctl->historyHandler()->historyController()->updateHistoryEntryThumbnailL(scaledPage)); + + m_brctl->HandleBrowserLoadEventL( TBrCtlDefs::EEventThumbnailAvailable, 0, 0 ); + } + // ignore err since we will use the default image + } +} + +//------------------------------------------------------------------------------- +// DocumentSize ( from MPageScalerCallback ) +// +// +//------------------------------------------------------------------------------- +TSize WebView::DocumentSize() +{ + return mainFrame()->frameView()->toViewCoords(mainFrame()->frameView()->contentSize()); +} + +//------------------------------------------------------------------------------- +// TouchScrolling ( from MPageScalerCallback ) +// +// +//------------------------------------------------------------------------------- +TBool WebView::TouchScrolling() +{ + return m_pageScrollHandler->touchScrolling(); +} + +CCoeControl& WebView::PageControlView() +{ + return *(m_brctl->CCoeControlParent()); +} + +void WebView::setEditable(TBool editable) +{ + Frame* frame = core(mainFrame()); + if (!frame || m_isEditable == editable) + return; + + m_isEditable = editable; + + Node* focusedNode = NULL; + Frame* focusedFrame = page()->focusController()->focusedFrame(); + + if (editable && focusedFrame) { + m_webfeptexteditor->UpdateEditingMode(); + focusedNode = focusedFrame->document()->focusedNode(); + } + else { + m_webfeptexteditor->CancelEditingMode(); + } + + WebCursor* c = StaticObjectsContainer::instance()->webCursor(); + // + if (focusedNode) + // based on focused element + m_focusedElementType = nodeTypeB(focusedNode, focusedFrame); + else { + m_focusedElementType = TBrCtlDefs::EElementNone; + + // based on cursor pos + c->updatePositionAndElemType(c->position()); + } + c->cursorUpdate(!m_isEditable); + m_brctl->updateDefaultSoftkeys(); + iCoeEnv->InputCapabilitiesChanged(); +} + +TCoeInputCapabilities WebView::InputCapabilities() const +{ + return m_webfeptexteditor->InputCapabilities(); +} + +void WebView::FocusChanged(TDrawNow aDrawNow) +{ +if (m_isPluginsVisible && !m_pluginActivated) { + Frame* coreFrame =core(mainFrame()); + MWebCoreObjectWidget* view = NULL; + TBool focus(IsFocused()); + for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { + PassRefPtr objects = frame->document()->objects(); + for (Node* n = objects->firstItem(); n; n = objects->nextItem()) { + view = widget(n); + if (view) { + static_cast(view)->viewFocusChanged(focus); + } + } + + PassRefPtr embeds = frame->document()->embeds(); + for (Node* n = embeds->firstItem(); n; n = embeds->nextItem()) { + view = widget(n); + if (view) { + static_cast(view)->viewFocusChanged(focus); + } + } + } + } + if (m_pageFullScreenHandler && m_pageFullScreenHandler->isFullScreenMode()) { + if (IsFocused()) m_pageFullScreenHandler->showEscBtnL(); + else m_pageFullScreenHandler->hideEscBtnL(); + } +} + +void WebView::SizeChanged() +{ + adjustOffscreenRect(); + // + if (mainFrame()) { + mainFrame()->frameView()->setRect(mainFrame()->frameView()->toDocCoords(Rect())); + } + if ( m_pageScaler ) + m_pageScaler->SetContainerRect(TRect(Rect().Size())); + if (m_webFormFillPopup && m_webFormFillPopup->IsVisible()) { + m_webFormFill->updatePopupView(); + } + if (m_pageFullScreenHandler) { + m_pageFullScreenHandler->SizeChanged(); + } + if (m_viewIsScrolling) { + m_pageScrollHandler->scrollbarDrawer()->redrawScrollbar(); + } +} + +TSize WebView::maxBidiSize() const +{ + return TSize((Rect().Size().iWidth-20),(Rect().Size().iHeight-20)); +} + +void WebView::clearOffScreenBitmap() +{ + m_webcorecontext->gc().Reset(); + m_webcorecontext->gc().Clear(); +} + +void WebView::scrollBuffer(TPoint to, TPoint from, TBool usecopyscroll) +{ + TRect rect(m_offscreenrect); + + TSize bufSize( rect.Size() ); + + CFbsBitGc& gc = m_webcorecontext->gc(); + gc.Reset(); + + TRect paintArea; + + int dx = from.iX - to.iX; + int dy = from.iY - to.iY; + + if (usecopyscroll && abs(dx) < bufSize.iWidth && abs(dy) < bufSize.iHeight) { + TPoint fromPt(dx<0?-dx:0, dy<0?-dy:0); + TRect fromRt(fromPt, TSize(bufSize.iWidth-abs(dx), bufSize.iHeight-abs(dy))); + TRect toRt(TPoint(fromPt.iX+dx, fromPt.iY+dy), fromRt.Size()); + + gc.CopyRect(TPoint(dx, dy), fromRt); + + RRegion region; + region.AddRect(TRect(TPoint(0, 0), bufSize)); + region.AddRect(toRt); + region.SubRect(toRt, 0); + + for (int i=0; iframeView()->toDocCoords(r); + if (mainFrame()->frameView()->isScaled()) + r.Grow(1, 1); + m_repaints.AddRect(r); + } + } + else { + TRect r(to, bufSize); + r = mainFrame()->frameView()->toDocCoords(r); + if (mainFrame()->frameView()->isScaled()) + r.Grow(1, 1); + m_repaints.AddRect(r); + } + +} + +int WebView::scalingFactor() const +{ + return m_currentZoomLevel; +} + +CPluginHandler* WebView::pluginForExtension(const WebCore::String& pluginExtension) +{ + return NULL; +} + +bool WebView::isMIMETypeRegisteredAsPlugin(const WebCore::String& MIMEType) +{ + return false; +} + +void WebView::adjustOffscreenRect() +{ + TRect rect(Rect()); + + if ( m_offscreenrect != rect ) { + m_offscreenrect = rect; + TSize bmSize = StaticObjectsContainer::instance()->webSurface()->offscreenBitmap()->SizeInPixels(); + if (bmSize.iWidth != rect.Width() || bmSize.iHeight != rect.Height()) { + m_bitmapdevice->Resize(rect.Size()); + m_webcorecontext->resized(); + } + } +} + +void WebView::autoScroll() +{ + // update scrolling speed + int milli = millisecondsScrolled(); + setViewIsFastScrolling(true); + toggleRepaintTimer(false); + m_scrollingSpeed = milli>=KPanningMaxTime ? KPanningMaxSpeed : KPanningStartSpeed+(KPanningMaxSpeed-KPanningStartSpeed)*Max(milli-KPanningStartTime,0)/KPanningMaxTime; + m_scrollingSpeed = m_scrollingSpeed*100/scalingFactor(); + TPoint scrollDelta = mainFrame()->frameView()->contentPos() - m_savedPosition; + scrollDelta.iX *= 100; + scrollDelta.iY *= 100; + if (AknLayoutUtils::PenEnabled() && !inPageViewMode()) { + m_pageScrollHandler->scrollbarDrawer()->drawScrollbar(this, scrollDelta); + } + OfferKeyEventL(m_currentEventKey, EEventKey); +} + +int WebView::millisecondsScrolled() const +{ + TTime timeNow; + timeNow.HomeTime(); + return I64INT(timeNow.MicroSecondsFrom(m_scrollingStartTime).Int64()/1000); +} + +TInt WebView::scrollTimerCb(TAny* aAny) +{ + WebView* v = static_cast(aAny); + v->autoScroll(); + return ETrue; +} + +int WebView::searchFor(const TPtrC& keyword) +{ + m_inFindState = true; + delete m_findKeyword; + m_findKeyword = NULL; + m_findKeyword = keyword.Alloc(); + if (!m_findKeyword || keyword.Length() == 0) { + WebFrame* frame = mainFrame()->findFrameWithSelection(); + if(frame) + frame->clearSelection(); + return TBrCtlDefs::EFindNoMatches; + } + m_findKeyword->Des().LowerCase(); + return search(keyword, true, true); +} + +int WebView::searchAgain(bool forward) +{ + if (!m_findKeyword) { + WebFrame* frame = mainFrame()->findFrameWithSelection(); + if(frame) { + frame->clearSelection(); + } + return TBrCtlDefs::EFindNoMatches; + } + return search(*m_findKeyword, forward, true); +} + +int WebView::search(TPtrC keyword, bool forward, bool wrapFlag) +{ + // Get the frame holding the selection, or start with the main frame + WebFrame* startFrame = mainFrame()->findFrameWithSelection(); + WebFrame* lastFrame = NULL; + if (!startFrame) { + if (StaticObjectsContainer::instance()->webCursor()) { + startFrame = StaticObjectsContainer::instance()->webCursor()->getFrameUnderCursor(); + } + else { + startFrame = mainFrame(); + } + } + WebFrame* frame = startFrame; + do { + WebFrame* nextFrame = incrementFrame(frame, forward, wrapFlag); + bool onlyOneFrame = (frame == nextFrame); + if (frame == startFrame) + lastFrame = frame; + + bool foundString = false; + // In some cases we have to search some content twice; see comment later in this method. + // We can avoid ever doing this in the common one-frame case by passing YES for wrapFlag + // here, and then bailing out before we get to the code that would search again in the + // same content. + bool wrapOnThisPass = wrapFlag && onlyOneFrame; + if (!core(frame)->isFrameSet() ) { + foundString = frame->bridge()->searchFor(keyword, forward, false, wrapOnThisPass, true); + } + if (foundString) { + if (frame != startFrame) + startFrame->clearSelection(); + return TBrCtlDefs::EFindMatch; + } + if (onlyOneFrame) { + startFrame->clearSelection(); + return TBrCtlDefs::EFindNoMatches; + } + frame = nextFrame; + } while (frame && frame != startFrame); + + // If there are multiple frames and wrapFlag is true and we've visited each one without finding a result, we still need to search in the + // first-searched frame up to the selection. However, the API doesn't provide a way to search only up to a particular point. The only + // way to make sure the entire frame is searched is to pass YES for the wrapFlag. When there are no matches, this will search again + // some content that we already searched on the first pass. In the worst case, we could search the entire contents of this frame twice. + // To fix this, we'd need to add a mechanism to specify a range in which to search. + if (wrapFlag && lastFrame) { + if (frame->bridge()->searchFor(keyword, forward, false, true, false)) + return TBrCtlDefs::EFindMatch; + } + + if(frame) { + frame->clearSelection(); + } + return TBrCtlDefs::EFindNoMatches; +} + +void WebView::exitFindState() +{ + m_inFindState = false; + delete m_findKeyword; + m_findKeyword = NULL; + WebFrame* selectedFrame = mainFrame()->findFrameWithSelection(); + selectedFrame->clearSelection(); +} + +bool WebView::isSmallPage() +{ + TSize docSize = DocumentSize(); + TSize viewSize = DocumentViewport().Size(); + return ((docSize.iWidth * docSize.iHeight*100)/(viewSize.iWidth*viewSize.iHeight) < KSmallPageScale); +} + +void WebView::willSubmitForm(FormState* formState) +{ + if (m_webFormFill) { + m_webFormFill->willSubmitForm(formState); + } +} + + +//------------------------------------------------------------------------------- +// HandlePointerBufferReadyL +// Handles Pointer Move Events +//------------------------------------------------------------------------------- +void WebView::HandlePointerBufferReadyL() +{ + memset(m_ptrbuffer,0,256*sizeof(TPoint)); + TPtr8 ptr((TUint8 *)m_ptrbuffer,256*sizeof(TPoint)); + + TInt numPnts = Window().RetrievePointerMoveBuffer(ptr); + + for (int i = 0; i < numPnts; i++) { + TPointerEvent pe; + pe.iType = TPointerEvent::EDrag; + pe.iPosition = m_ptrbuffer[i]; + m_webpointerEventHandler->HandlePointerEventL(pe); + } +} + +//------------------------------------------------------------------------------- +// HandlePointerEventL +// Handles Pointer Events +//------------------------------------------------------------------------------- +void WebView::HandlePointerEventL(const TPointerEvent& aPointerEvent) +{ + m_webpointerEventHandler->HandlePointerEventL(aPointerEvent); +} + +void WebView::notifyMetaData(String& name, String& value) +{ + if (name == "navigation") { + if (value == "tabbed") { + m_brctl->settings()->setTabbedNavigation(true); + StaticObjectsContainer::instance()->webCursor()->cursorUpdate(true); + } + } +} + +//------------------------------------------------------------------------------- +// HandleShowAnchorHref() +// Display a popup with the url of an anchor +//------------------------------------------------------------------------------- +void WebView::handleShowAnchorHrefL() +{ + HBufC* url = NULL; + IntPoint p; + WebFrame* f = frameAndPointUnderCursor(p, *this); + String urlStr = getNodeUrlAtPointInFrame(*f, p); + + if (urlStr.length() > 0) + url = urlStr.des().AllocL(); + else + User::Leave(KErrNotSupported); + + CleanupStack::PushL(url); + + + TRect elRect; + TBrCtlDefs::TBrCtlElementType elType = TBrCtlDefs::EElementNone; + WebFrame* frm = StaticObjectsContainer::instance()->webCursor()->getFrameUnderCursor(); + WebCursor* cursor = StaticObjectsContainer::instance()->webCursor(); + TPoint pt(frm->frameView()->viewCoordsInFrameCoords(cursor->position())); + StaticObjectsContainer::instance()->webCursor()->navigableNodeUnderCursor(*(frm), pt, elType, elRect); + + + TRect rect(elRect); + rect.SetRect(f->frameView()->frameCoordsInViewCoords(rect.iTl), f->frameView()->frameCoordsInViewCoords(rect.iBr)); + + TPtrC urlPtr(url->Des()); + m_popupDrawer = WebPopupDrawer::NewL(*this, urlPtr, rect); + DrawNow(); + + CleanupStack::PopAndDestroy(); // url +} + +//------------------------------------------------------------------------------- +// FocusedImageLC() +// Return the image that is under the cursor +//------------------------------------------------------------------------------- +TBrCtlImageCarrier* WebView::focusedImageLC() +{ + if (m_focusedElementType != TBrCtlDefs::EElementImageBox && m_focusedElementType != TBrCtlDefs::EElementAreaBox) { + User::Leave(KErrNotSupported); + } + TBrCtlImageCarrier* imageCarrier = NULL; + User::LeaveIfError(focusedImage(this, imageCarrier)); + CleanupStack::PushL(imageCarrier); + return imageCarrier; +} + +//------------------------------------------------------------------------------- +// LoadFocusedImageL() +// Load the image that is under the cursor +//------------------------------------------------------------------------------- +void WebView::loadFocusedImageL() +{ + // Ensure cursor is on a broken image and image loading is disabled + if (m_focusedElementType != TBrCtlDefs::EElementBrokenImage || m_brctl->settings()->brctlSetting(TBrCtlDefs::ESettingsAutoLoadImages)) { + User::Leave(KErrNotSupported); + } + loadFocusedImage(this); +} + +//------------------------------------------------------------------------------- +// RemovePopup() +// Delete the popupDrawer +//------------------------------------------------------------------------------- +void WebView::removePopup() +{ + if (m_popupDrawer) { + delete m_popupDrawer; + m_popupDrawer = NULL; + DrawNow(); + } +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +RArray* WebView::zoomLevels() +{ + return &m_zoomLevelArray; +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::setZoomLevel(int zoomLevel) +{ + m_dirtyZoomMode = false; + if (zoomLevel < KZoomLevelMinValue || + zoomLevel > m_maxZoomLevel || + zoomLevel == m_currentZoomLevel) + return; + zoomLevelChanged(zoomLevel); +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::setBitmapZoomLevel(int zoomLevel) +{ + m_zoomLevelChangedByUser = true; + WebFrameView* view = mainFrame()->frameView(); + if (!view) return; + + m_dirtyZoomMode = true; + m_isPluginsVisible = false; + mainFrame()->makeVisiblePlugins(false); + + if (zoomLevel > m_startZoomLevel) { + + // cut m_srcRectForZooming from m_offscreenrect and enlarge it to fit the view rect + + float newWidth = m_offscreenrect.Width() * zoomLevel / m_startZoomLevel; + float newHeight = m_offscreenrect.Height() * zoomLevel / m_startZoomLevel; + + newWidth = (float)(m_offscreenrect.Width() * (float)m_offscreenrect.Width()) / newWidth; + newHeight = (float)m_offscreenrect.Height() * (float)m_offscreenrect.Height() / newHeight; + + TSize docSize = DocumentSize(); + TSize viewSize = DocumentViewport().Size(); + TSize contentSize = view->contentSize(); + + + m_srcRectForZooming.iTl.iX = 0; + m_srcRectForZooming.iTl.iY = 0; + + m_srcRectForZooming.iBr.iX = newWidth; + m_srcRectForZooming.iBr.iY = newHeight; + + m_destRectForZooming = Rect(); + + } + else { + // take the whole rect and calculate new rect to fit it the rest of view rect paint gray colour + + TInt newWidth = m_offscreenrect.Width() * zoomLevel / m_startZoomLevel; + TInt newHeight = m_offscreenrect.Height() * zoomLevel / m_startZoomLevel; + + m_srcRectForZooming = m_offscreenrect; + + m_destRectForZooming.iTl.iX = 0; + m_destRectForZooming.iTl.iY = 0; + + m_destRectForZooming.iBr.iX = newWidth; + m_destRectForZooming.iBr.iY = newHeight; + } + + m_currentZoomLevel = zoomLevel; + + DrawNow(); +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::restoreZoomLevel(int zoomLevel) +{ + m_dirtyZoomMode = false; + clearOffScreenBitmap(); + zoomLevelChanged(zoomLevel); + mainFrame()->notifyPluginsOfScrolling(); + m_isPluginsVisible = false; + mainFrame()->makeVisiblePlugins(true); + m_isPluginsVisible = true; +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::resetZoomLevel(void) +{ + if( m_widgetextension && m_widgetextension->IsWidgetPublising()) { + return ; + } + if (m_historyLoad) { + int zoomLevel = m_brctl->historyHandler()->historyController()->currentEntryZoomLevel(); + if (!zoomLevel) zoomLevel = KZoomLevelDefaultValue; + if (m_currentZoomLevel != zoomLevel) { + m_currentZoomLevel = zoomLevel; + } + int minZoomLevel = m_brctl->historyHandler()->historyController()->currentEntryMinZoomLevel(); + if (!minZoomLevel) + minZoomLevel = (KZoomLevelDefaultValue/ m_pageZoomHandler->stepSize())*m_pageZoomHandler->stepSize(); + else + minZoomLevel = (minZoomLevel / m_pageZoomHandler->stepSize())*m_pageZoomHandler->stepSize(); + //could happen only if m_minZoomLevel < stepSize + if (!m_minZoomLevel) m_minZoomLevel = m_pageZoomHandler->stepSize(); + + if (m_minZoomLevel != minZoomLevel) { + m_minZoomLevel = minZoomLevel; + } + m_currentZoomLevel = zoomLevel; + //set to settings + m_brctl->settings()->setBrctlSetting(TBrCtlDefs::ESettingsCurrentZoomLevelIndex, m_currentZoomLevel); + } + else { + if (m_currentZoomLevel != KZoomLevelDefaultValue) + //set default current zoom index + { + m_currentZoomLevel = KZoomLevelDefaultValue; + //set to settings + m_brctl->settings()->setBrctlSetting(TBrCtlDefs::ESettingsCurrentZoomLevelIndex, m_currentZoomLevel); + } + } + clearOffScreenBitmap(); + m_zoomLevelChangedByUser = false; + mainFrame()->scalingFactorChanged(m_currentZoomLevel); + mainFrame()->frameView()->setRect(mainFrame()->frameView()->toDocCoords(Rect())); + m_startZoomLevel = m_currentZoomLevel; +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::updateMinZoomLevel(TSize size) +{ + int newMinZoomLevel; + if (size.iWidth && size.iHeight) { + TRect screenSize(Rect().Size()); + + float minWidth = ((float)screenSize.Width()) * 100 /(float)( size.iWidth); + float minHeight = ((float)screenSize.Height()) * 100 /(float)( size.iHeight); + + newMinZoomLevel = ( minWidth > minHeight )?minWidth:minHeight; + + if ( newMinZoomLevel < KZoomLevelMinValue ) newMinZoomLevel = KZoomLevelMinValue; + if ( newMinZoomLevel > KZoomLevelDefaultValue ) newMinZoomLevel = KZoomLevelDefaultValue; + if ( newMinZoomLevel > m_currentZoomLevel ) newMinZoomLevel = m_currentZoomLevel; + } + else { + newMinZoomLevel = KZoomLevelDefaultValue; + } + + newMinZoomLevel = (newMinZoomLevel/m_pageZoomHandler->stepSize())*m_pageZoomHandler->stepSize(); + + TBool needsUpdateArray = EFalse; + //Update the new array + if ( m_minZoomLevel!= newMinZoomLevel) + { + needsUpdateArray = ETrue; + } + + //could happen only if m_minZoomLevel < stepSize + if (!newMinZoomLevel) newMinZoomLevel = m_pageZoomHandler->stepSize(); + + if (m_minZoomLevel != newMinZoomLevel) + { + m_minZoomLevel = newMinZoomLevel; + if (m_pageZoomHandler->isActive()) { + m_pageZoomHandler->hideZoomSliderL(); + m_pageZoomHandler->showZoomSliderL(); + } + else { + UpdateZoomArray(); //for non-touch + } + } //endof if (m_minZoomLevel != newMinZoomLevel) +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::UpdateZoomArray() +{ + //only for non-touch device + if (m_pageZoomHandler->isActive()) + { + return; + } + + m_zoomLevelArray.Reset(); + + m_minZoomLevel = TInt(m_minZoomLevel/10) * 10; + m_zoomLevelArray.Append(KZoomLevelDefaultValue); + + //construct the zoom array from the default level + TInt toAddZoomLevel = KZoomLevelDefaultValue + KZoomLevelDefaultValue*KZoomLevelDelta/100; + while (toAddZoomLevel <= m_maxZoomLevel) + { + //add the zoom level after default one + m_zoomLevelArray.Append(toAddZoomLevel); + toAddZoomLevel = toAddZoomLevel + toAddZoomLevel*KZoomLevelDelta/100; + } + + //now goes the minimum one + toAddZoomLevel = KZoomLevelDefaultValue - KZoomLevelDefaultValue*KZoomLevelDelta/100; + while (toAddZoomLevel >= m_minZoomLevel) + { + //add the zoom level after default one + m_zoomLevelArray.Insert(toAddZoomLevel, 0); + toAddZoomLevel = toAddZoomLevel - toAddZoomLevel*KZoomLevelDelta/100; + } + +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::zoomLevelChanged(int newZoomLevel) +{ + int currZoomLevel = m_startZoomLevel; + m_dirtyZoomMode = false; + // instead of clearOffScreen bitmap, just reset. + m_webcorecontext->gc().Reset(); + m_currentZoomLevel = newZoomLevel; + TSize sz( m_offscreenrect.Size() ); + WebFrameView* view = mainFrame()->frameView(); + if (!view) return; + + TPoint pt( view->contentPos() ); + TSize contentSize( view->contentSize() ); + int z = m_currentZoomLevel; + if ( pt.iX * z > contentSize.iWidth * z - sz.iWidth * 100 ) + pt.iX = ( contentSize.iWidth - sz.iWidth * 100 / z ); + + if ( pt.iY * z > contentSize.iHeight * z - sz.iHeight * 100 ) + pt.iY = ( contentSize.iHeight - sz.iHeight * 100 / z ); + + if ( pt.iY < 0 ) pt.iY = 0; + if ( pt.iX < 0 ) pt.iX = 0; + + + view->setContentPos( pt ); + mainFrame()->scalingFactorChanged(z); + view->checkScrollbarVisibility(); + + TRect rect = view->rect(); + + TInt tlx = (rect.iTl.iX * currZoomLevel) / m_currentZoomLevel; + TInt tly = (rect.iTl.iY * currZoomLevel) / m_currentZoomLevel; + TInt brx = (rect.iBr.iX * currZoomLevel) / m_currentZoomLevel; + TInt bry = (rect.iBr.iY * currZoomLevel) / m_currentZoomLevel; + + // rounding + + if (( rect.iTl.iX * currZoomLevel) % m_currentZoomLevel ){ + tlx -= 1; + } + if (( rect.iTl.iY * currZoomLevel) % m_currentZoomLevel ){ + tly -= 1; + } + if ((rect.iBr.iX * currZoomLevel) % m_currentZoomLevel ){ + brx += 1; + } + if ((rect.iBr.iY * currZoomLevel) % m_currentZoomLevel ){ + bry += 1; + } + + view->setRect(TRect(tlx, tly, brx, bry)); + + // now just do a repaint, should be very fast + if ( currZoomLevel > newZoomLevel ) { + clearOffScreenBitmap(); + } + + + m_startZoomLevel = m_currentZoomLevel; + + updateScrollbars(mainFrame()->frameView()->contentSize().iHeight, mainFrame()->frameView()->contentPos().iY, + mainFrame()->frameView()->contentSize().iWidth, mainFrame()->frameView()->contentPos().iX); + + syncRepaint(view->visibleRect()); + + int zoomLevel = m_brctl->historyHandler()->historyController()->currentEntryZoomLevel(); + if (zoomLevel != m_currentZoomLevel) m_brctl->historyHandler()->historyController()->updateCurrentEntryZoomLevelIfNeeded(); +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::resetLastZoomLevelIfNeeded() +{ + if (m_lastZoomLevel == m_maxZoomLevel) + m_lastZoomLevel = 100; +} + +//----------------------------------------------------------------------------- +// setZoomLevelAdaptively() +//----------------------------------------------------------------------------- +void WebView::setZoomLevelAdaptively() +{ + int zoomLevel = KZoomLevelDefaultValue; + + // Double Tap Zooming: it toggles between default, maxiZoomLevel. + // Depending on the current zoom level: + // A. If the current is already the max, it zooms to the max + // B. If the current is bigger than/equal to the default zoom level zooms to the default, it zooms to the max + // C. Otherwise it zooms to the default level first. + // For the mobile pages, such as google.com and cnn.com, minimum zoom level equals + // to the default zoom level. Zooming is only possible between default and maximum + // zoom level, double tap only won't reach logic C + // + // For both mobile and non-mobile pages, it creates the same end user double tap + // experiences + + if (m_currentZoomLevel == m_maxZoomLevel ) { + zoomLevel = KZoomLevelDefaultValue; + } + else if (m_currentZoomLevel >= KZoomLevelDefaultValue ) { + zoomLevel = m_maxZoomLevel; + } + else { + zoomLevel = KZoomLevelDefaultValue; + } + + // move the content + WebFrameView* view = mainFrame()->frameView(); + if (!view) return; + WebCursor* cursor = StaticObjectsContainer::instance()->webCursor(); + if (cursor) { + TPoint pt = cursor->position(); + int z = zoomLevel * 100 / m_currentZoomLevel; + int xOff = (pt.iX * z / 100 - pt.iX)*100/zoomLevel; + int yOff = (pt.iY * z / 100 - pt.iY)*100/zoomLevel; + TPoint cp = view->contentPos(); + cp += TPoint(xOff, yOff); + view->setContentPos(cp); + } + + // zoom it + m_lastZoomLevel = m_currentZoomLevel; + + setZoomLevel(zoomLevel); + mainFrame()->notifyPluginsOfScrolling(); +} + +//------------------------------------------------------------------------------- +// Called when user clicks a plugin which is able to accept user input, +// this feature is only used in US build +//------------------------------------------------------------------------------- +void WebView::openPluginPlayer(PluginWin* plugin) +{ + if (!m_pluginplayer) { + PluginSkin* pluginskin = mainFrame()->focusedPlugin(); + + if ( !pluginskin || !pluginskin->isInteractive() ) return; + + // we only create the player when the plugin content is ready and + // the plugin is not allowed to interact inside html page. + if ( pluginskin->CanInteract() ) return; + + m_pluginplayer = PluginPlayer::NewL( *m_brctl, plugin ); + MakeVisible(EFalse); + m_brctl->reportStateChanged(TBrCtlDefs::EStatePluginPlayer, ETrue); + // now start playing the content + m_pluginplayer->start(); + } +} + +void WebView::setFocusNone() +{ + page()->focusController()->setFocusedNode(NULL, page()->focusController()->focusedOrMainFrame()); +} +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::closePluginPlayer() +{ + // stop playing + m_pluginplayer->stop(); + MakeVisible( ETrue ); + + delete m_pluginplayer; + m_pluginplayer = 0; + m_brctl->reportStateChanged(TBrCtlDefs::EStatePluginPlayer, EFalse); + // redraw the control + m_brctl->DrawNow(); +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +CWidgetExtension* WebView::createWidgetExtension(MWidgetCallback &aWidgetCallback) +{ + if (!m_widgetextension) { + m_widgetextension = CWidgetExtension::NewL(*this, aWidgetCallback); +#if USE(LOW_BANDWIDTH_DISPLAY) + m_page->mainFrame()->loader()->setUseLowBandwidthDisplay(false); +#endif + } + + return m_widgetextension; +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::forceLayoutAndResize(WebFrame* frame) +{ + if (frame) { + Frame* f = core(frame); + FrameView* v = f->view(); + Document* doc = f->document(); + if (v && doc) { + Node* node = doc; + while (node) { + if (node->renderer()) { + node->renderer()->setNeedsLayoutAndPrefWidthsRecalc(); + RenderStyle* style = node->renderer()->style(); + if (style) { + RenderStyle* newstyle = new (node->renderer()->renderArena()) RenderStyle(*style); + node->renderer()->setStyle(newstyle); + } + } + node = node->traverseNextNode(); + } + f->document()->recalcStyle(Node::Force); + v->setNeedsLayout(); + v->layout(); + } + } +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::showZoomSliderL() +{ + if ( !inPageViewMode()) { + m_pageZoomHandler->showZoomSliderL(); + if ( m_repainttimer->IsActive()) + { + m_repainttimer->Cancel(); + } + } + m_startZoomLevel = m_currentZoomLevel; +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::hideZoomSliderL() +{ + if ( !inPageViewMode()) { + m_pageZoomHandler->hideZoomSliderL(); + } +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::notifyZoomSliderModeChangeL( bool mode ) +{ + m_dirtyZoomMode = false; + clearOffScreenBitmap(); + zoomLevelChanged( m_currentZoomLevel ); + m_brctl->reportStateChanged(TBrCtlDefs::EStateZoomSliderMode, mode ); +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +int WebView::maxZoomLevel() +{ + return m_maxZoomLevel; +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +int WebView::minZoomLevel() +{ + return m_minZoomLevel; +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::updateZoomLevel( TBrCtlDefs::TBrCtlSettings setting, unsigned int value) +{ + switch( setting ) { + case TBrCtlDefs::ESettingsZoomLevelMax: + { + if (value != m_maxZoomLevel) + { + //maxzoomlevel is different, needs to reset the zoom + m_maxZoomLevel = value; + UpdateZoomArray(); + } + } + + break; + case TBrCtlDefs::ESettingsZoomLevelDefault: + m_scrollingSpeed = KNormalScrollRange*100/scalingFactor(); + break; + + default: + break; // should not occur + } +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::EnterFullscreenBrowsingL() +{ + if (m_pageFullScreenHandler) { + m_pageFullScreenHandler->showEscBtnL(); + StaticObjectsContainer::instance()->setFullScreenMode(true); + } +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::LeaveFullscreenBrowsingL() +{ + if (m_pageFullScreenHandler) { + m_pageFullScreenHandler->hideEscBtnL(); + StaticObjectsContainer::instance()->setFullScreenMode(false); + } +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::notifyFullscreenModeChangeL(bool mode) +{ + if (m_pageFullScreenHandler ) + m_brctl->reportStateChanged(TBrCtlDefs::EStateFullscreenBrowsing, mode ); +} + +//------------------------------------------------------------------------------- +//------------------------------------------------------------------------------- +void WebView::checkForZoomChange() +{ + zoomLevelChanged(m_currentZoomLevel); +} + + +void WebView::activateVirtualKeyboard() +{ + if (isEditable() && iCoeEnv->Fep()) { + fepTextEditor()->CancelEditingMode(); + fepTextEditor()->UpdateEditingMode(); + iCoeEnv->Fep()->HandleChangeInFocus(); + fepTextEditor()->ActivatePenInputRequest(); + } +} + +void WebView::Stop() +{ + mainFrame()->stopLoading(); +} +void WebView::synchRequestPending(bool flag) +{ + m_synchRequestPending = flag; + + // TODO - nl - Disabled for now - there's no cursor in S60 5.0 release + //WebCursor* cursor = StaticObjectsContainer::instance()->webCursor(); + + if (flag) { + m_brctl->reportStateChanged(TBrCtlDefs::EStateSynchRequestMode, ETrue); + //cursor->setWaitCursor(ETrue); + if (AknLayoutUtils::PenEnabled()) { + // Disable (block) pointer events + DrawableWindow()->SetPointerGrab(EFalse); + } + } + else { + if (AknLayoutUtils::PenEnabled()) { + // Reenable pointer events + DrawableWindow()->SetPointerGrab(ETrue); + } + //cursor->setWaitCursor(EFalse); + m_brctl->reportStateChanged(TBrCtlDefs::EStateSynchRequestMode, EFalse); + } +} + +void WebView::setHistoryLoad(bool value) { + m_historyLoad = value; +} +void WebView::setRedirectWithLockedHistory(bool value) { + m_redirectWithLockedHistory = value; +} +//------------------------------------------------------------------------------- +// Webview notifies plugins to handle play/pause of .swf files when user switches to menu/another application +//------------------------------------------------------------------------------- +void WebView::notifyPlugins(TBool focus) +{ + Frame* coreFrame =core(mainFrame()); + MWebCoreObjectWidget* view = NULL; + for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) { + PassRefPtr objects = frame->document()->objects(); + for (Node* n = objects->firstItem(); n; n = objects->nextItem()) { + view = widget(n); + if (view) { + static_cast(view)->handlePluginForeground(focus); + } + } + + PassRefPtr embeds = frame->document()->embeds(); + for (Node* n = embeds->firstItem(); n; n = embeds->nextItem()) { + view = widget(n); + if (view) { + static_cast(view)->handlePluginForeground(focus); + } + } + } +} + + +void WebView::setFastScrollingMode(bool fastScrolling) +{ + if (fastScrolling != m_viewIsFastScrolling) { + setViewIsFastScrolling (fastScrolling); + m_isPluginsVisible = false; + mainFrame()->makeVisiblePlugins(!m_viewIsFastScrolling); + m_isPluginsVisible = !m_viewIsFastScrolling; + + if (!m_viewIsFastScrolling) { + mainFrame()->notifyPluginsOfScrolling(); + } + toggleRepaintTimer(!m_viewIsFastScrolling); +} +} + +void WebView::toggleRepaintTimer(bool on) +{ + if ( m_repainttimer->IsActive()) { + m_repainttimer->Cancel(); + } + + if (on) { + m_repainttimer->Start(0, 0, TCallBack( &doRepaintCb, this ) ); + } + m_allowRepaints = on; +} + + +//----------------------------------------------------------------------------- +// setZoomCursorPosition(TBool) +// Set the cursor position while zooming, this is only for non-touch device +//----------------------------------------------------------------------------- +void WebView::setZoomCursorPosition(TBool isZoomIn) +{ + int zoomLevel = m_currentZoomLevel; + + TInt index = FindCurrentZoomIndex(m_currentZoomLevel); + if (index == -1) + { + //Shouldn't happen -- do nothing + return; + } + + if (isZoomIn && index <=m_zoomLevelArray.Count()-2) + { + index++; + zoomLevel = m_zoomLevelArray[index]; + } + else if (!isZoomIn && index > 0 ) + { + index--; + zoomLevel = m_zoomLevelArray[index]; + } + + // move the content + WebFrameView* view = mainFrame()->frameView(); + if (!view) return; + WebCursor* cursor = StaticObjectsContainer::instance()->webCursor(); + if (cursor) { + + TPoint pt = cursor->position(); + int z = zoomLevel * 100 / m_currentZoomLevel; + int xOff = (pt.iX * z / 100 - pt.iX)*100/zoomLevel; + int yOff = (pt.iY * z / 100 - pt.iY)*100/zoomLevel; + TPoint cp = view->contentPos(); + cp += TPoint(xOff, yOff); + view->setContentPos(cp); + } + //setZoomLevel(zoomLevel); + mainFrame()->notifyPluginsOfScrolling(); +} + + +// --------------------------------------------------------------------------- +// FindCurrentZoomIndex +// --------------------------------------------------------------------------- +TInt WebView::FindCurrentZoomIndex(TInt aCurrentZoomLevel) +{ + TInt aIndex = -1; + + for (aIndex=0; aIndexGetWidgetId():0; +} + +void WebView::setShowCursor(TBool showCursor) +{ + m_showCursor = showCursor; + StaticObjectsContainer::instance()->webCursor()->setCursorVisible(showCursor); +} + +// END OF FILE