--- a/webengine/osswebengine/WebKit/s60/webview/WebView.cpp Fri Jul 03 15:54:40 2009 +0100
+++ b/webengine/osswebengine/WebKit/s60/webview/WebView.cpp Thu Aug 27 07:44:59 2009 +0300
@@ -97,9 +97,10 @@
#include "WebPageFullScreenHandler.h"
#include "eikon.hrh"
#include "WebScrollbarDrawer.h"
-
+#include "EventNames.h"
using namespace WebCore;
+using namespace EventNames;
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)
@@ -193,6 +194,7 @@
, m_ptrbuffer(0)
, m_showCursor(false)
, m_allowRepaints(true)
+, m_prevEditMode(false)
{
}
@@ -536,7 +538,8 @@
// draw to back buffer
-
+ if(m_widgetextension && !IsVisible())
+ return;
if(!( m_widgetextension && m_widgetextension->IsWidgetPublising())) {
mainFrame()->frameView()->draw( *m_webcorecontext, rect );
if ( zoomLevel < m_minZoomLevel ) zoomLevel = m_minZoomLevel;
@@ -579,7 +582,8 @@
}
layoutPending = false;
}
- if (!layoutPending) {
+
+ if ( !layoutPending || !isLoading()) {
bool needsDraw = false;
m_repaints.Tidy();
for (int i=0; i<m_repaints.Count(); ++i) {
@@ -654,26 +658,29 @@
//-------------------------------------------------------------------------------
void WebView::collectOffscreenbitmapL(CFbsBitmap& snapshot)
{
- if ( snapshot.Handle() == 0) {
- // Create bitmap only once
- (snapshot).Create(m_brctl->Size(), StaticObjectsContainer::instance()->webSurface()->displayMode());
+ if( m_widgetextension && m_widgetextension->IsWidgetPublising()) {
+ if ( snapshot.Handle() == 0) {
+ // Create bitmap only once
+ (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);
+
+ if( snapshot.Handle() != 0 ) {
+ // Clear previous offscreen bitmap
+ // frameView->draw might clear the bitmap.
+ gc->gc().Clear();
+ }
+ if (snapshot.SizeInPixels()!=m_brctl->Size()) {
+ snapshot.Resize(m_brctl->Size());
+ }
+ mainFrame()->frameView()->draw( *gc, mainFrame()->frameView()->visibleRect() );
+
+ CleanupStack::PopAndDestroy(2);
}
- CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( &snapshot);
- CleanupStack::PushL(device);
-
- WebCoreGraphicsContext* gc = WebCoreGraphicsContext::NewL( device, &snapshot, mainFrame()->frameView());
- CleanupStack::PushL(gc);
-
- if( snapshot.Handle() != 0 ){
- // Clear previous offscreen bitmap
- // frameView->draw might clear the bitmap.
- gc->gc().Clear();
- } else if (snapshot.SizeInPixels()!=m_brctl->Size()){
- snapshot.Resize(m_brctl->Size());
- }
- mainFrame()->frameView()->draw( *gc, mainFrame()->frameView()->visibleRect() );
-
- CleanupStack::PopAndDestroy(2);
}
@@ -827,17 +834,21 @@
bool WebView::isNaviKey(const TKeyEvent& keyevent)
{
return ( keyevent.iCode == EKeyUpArrow // North
+ || keyevent.iCode == EStdKeyUpArrow // :
|| keyevent.iCode == EKeyRightUpArrow // Northeast
- || keyevent.iCode == EStdKeyDevice11 // : Extra KeyEvent supports diagonal event simulator wedge
+ || keyevent.iCode == EStdKeyDevice11 // :
|| keyevent.iCode == EKeyRightArrow // East
+ || keyevent.iCode == EStdKeyRightArrow // :
|| keyevent.iCode == EKeyRightDownArrow // Southeast
- || keyevent.iCode == EStdKeyDevice12 // : Extra KeyEvent supports diagonal event simulator wedge
+ || keyevent.iCode == EStdKeyDevice12 // :
|| keyevent.iCode == EKeyDownArrow // South
+ || keyevent.iCode == EStdKeyDownArrow // :
|| keyevent.iCode == EKeyLeftDownArrow // Southwest
- || keyevent.iCode == EStdKeyDevice13 // : Extra KeyEvent supports diagonal event simulator wedge
+ || keyevent.iCode == EStdKeyDevice13 // :
|| keyevent.iCode == EKeyLeftArrow // West
+ || keyevent.iCode == EStdKeyLeftArrow // :
|| keyevent.iCode == EKeyLeftUpArrow // Northwest
- || keyevent.iCode == EStdKeyDevice10);
+ || keyevent.iCode == EStdKeyDevice10 ); // :
}
bool WebView::handleEditable(const TKeyEvent& keyevent, TEventCode eventcode, Frame* frame )
@@ -908,11 +919,38 @@
}
}
+bool WebView::needDeactivateEditable(const TKeyEvent& keyevent, TEventCode eventcode)
+{
+ bool upOrDown = ((keyevent.iCode == EKeyDevice3) ||
+ (keyevent.iCode == EKeyUpArrow) ||
+ (keyevent.iCode == EStdKeyUpArrow) ||
+ (keyevent.iCode == EKeyRightUpArrow) ||
+ (keyevent.iCode == EKeyDownArrow) ||
+ (keyevent.iCode == EStdKeyDownArrow) ||
+ (keyevent.iCode == EKeyLeftDownArrow));
+ bool inEditState = (m_isEditable && (m_focusedElementType == TBrCtlDefs::EElementActivatedInputBox));
+ bool isSelectBoxActive = (m_focusedElementType == TBrCtlDefs::EElementSelectBox);
+ bool deactivateInputBox = (inEditState && upOrDown);
+ bool deactivateSelectBox = (isSelectBoxActive && isNaviKey(keyevent));
+
+ return deactivateInputBox || deactivateSelectBox;
+}
+
+
+bool WebView::deactivateEditable()
+{
+ setFocusNone();
+ m_prevEditMode = true;
+ setEditable( EFalse );
+ return true;
+}
+
bool WebView::handleEventKeyL(const TKeyEvent& keyevent, TEventCode eventcode, Frame* frame)
{
WebCursor* cursor = StaticObjectsContainer::instance()->webCursor();
bool consumed = false;
-
+ bool tabbedNavigation = (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed);
+ bool navigationNone = (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeNone);
TKeyEvent oldKeyEvent(m_currentEventKey);
oldKeyEvent.iCode = keyevent.iCode;
TEventCode oldKeyCode = m_currentEventCode;
@@ -920,20 +958,26 @@
m_currentEventKey = keyevent;
m_currentEventCode = eventcode;
- if (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeNone) {
+ if (navigationNone) {
consumed = handleInputElement(keyevent, eventcode, frame);
if (!consumed)
consumed = sendKeyEventToEngine(keyevent, eventcode, frame);
}
else {
- if (keyevent.iCode == EKeyDevice3) {
- // pass it to webcore
- sendMouseEventToEngine(TPointerEvent::EButton1Down,
- cursor->position(), frame);
-
- // mimic ccb's behavior of onFocus
+ if (needDeactivateEditable(keyevent, eventcode)) {
+ consumed = deactivateEditable();
+ handleKeyNavigation(keyevent, eventcode, frame);
+ }
+ else if (keyevent.iCode == EKeyDevice3) {
+ sendMouseEventToEngine(TPointerEvent::EButton1Down,
+ cursor->position(), frame);
+ // mimic ccb's behavior of onFocus
setFocusedNode(frame);
-
+ if (oldKeyCode == EEventKeyDown &&
+ (m_focusedElementType != TBrCtlDefs::EElementActivatedInputBox)){
+ sendKeyEventToEngine(oldKeyEvent, EEventKeyDown, frame);
+ }
+
// 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,
@@ -947,32 +991,50 @@
consumed = true;
}
else if (isNaviKey(keyevent)) {
-
- if (oldKeyCode == EEventKeyDown){
- // Keydown event is automatically generated before each keypress event, but in this case
- // we don't send a keypress event, so send a keydown event explicitly.
- downEventConsumed = sendKeyEventToEngine(oldKeyEvent, EEventKeyDown, frame);
- }
-
-
- if (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed) {
- consumed = downEventConsumed || handleTabbedNavigation(keyevent, eventcode);
- }
- else {
- consumed = handleKeyNavigation(keyevent, eventcode, frame);
- }
+ consumed = handleNaviKeyEvent(oldKeyEvent, oldKeyCode, frame);
} // if (m_brctl->settings()->getNavigationType()
else { // Not an arrow key..
// activate hovered input element by just start typing
- consumed = handleInputElement(keyevent, eventcode, frame);
+ consumed = !m_isEditable && handleInputElement(keyevent, eventcode, frame);
}
- if (!consumed && !(m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed && isNaviKey(keyevent))) {
+ if (!consumed && !(tabbedNavigation && isNaviKey(keyevent))) {
consumed = sendKeyEventToEngine(keyevent, eventcode, frame);
}
}
return consumed;
}
+bool WebView::handleNaviKeyEvent(const TKeyEvent& keyevent, TEventCode eventcode, Frame* frame)
+{
+ bool downEventConsumed = false;
+ bool consumed = false;
+ bool tabbedNavigation = (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed);
+ /*
+ * For each platform keyDown event EventHandler::keEvent() generates
+ * keydown and keypress.
+ * For keypress event we need a char code and since we don't
+ * have it at the time of EEventKeyDown we pospond it until EEventKey
+ * and send it here.
+ */
+ if (eventcode == EEventKeyDown){
+ downEventConsumed = sendKeyEventToEngine(keyevent, EEventKeyDown, frame);
+ }
+
+ if (m_isEditable && !downEventConsumed && m_webfeptexteditor->validateTextFormat()) {
+ setFocusNone();
+ }
+
+ if (tabbedNavigation) {
+ consumed = downEventConsumed || handleTabbedNavigation(m_currentEventKey, m_currentEventCode);
+ }
+ else {
+ consumed = (!m_isEditable && //avoid showing the cursor when we are in the input box
+ handleKeyNavigation(keyevent, eventcode, frame)) ||
+ downEventConsumed;
+ }
+ return consumed;
+}
+
bool WebView::handleInputElement(const TKeyEvent& keyevent, TEventCode eventcode, Frame* frame)
{
@@ -984,16 +1046,18 @@
}
else if (m_focusedElementType == TBrCtlDefs::EElementSelectBox ||
m_focusedElementType == TBrCtlDefs::EElementSelectMultiBox) {
- if (m_brctl->settings()->getNavigationType() != SettingsContainer::NavigationTypeNone || keyevent.iCode == EKeyDevice3) {
+ if (m_brctl->settings()->getNavigationType() != SettingsContainer::NavigationTypeNone ||
+ keyevent.iCode == EKeyDevice3) {
sendMousedEvent = true;
}
}
if (sendMousedEvent) {
sendMouseEventToEngine(TPointerEvent::EButton1Down, cursor->position(), frame);
sendMouseEventToEngine(TPointerEvent::EButton1Up, cursor->position(), frame);
-
- if (m_focusedElementType == TBrCtlDefs::EElementInputBox ||
- m_focusedElementType == TBrCtlDefs::EElementTextAreaBox) {
+
+ if (m_focusedElementType == TBrCtlDefs::EElementInputBox ||
+ m_focusedElementType == TBrCtlDefs::EElementTextAreaBox ||
+ m_focusedElementType == TBrCtlDefs::EElementActivatedInputBox) {
if (!m_fepTimer) {
m_fepTimer = new WebCore::Timer<WebView>(this, &WebView::fepTimerFired);
}
@@ -1020,8 +1084,11 @@
if (!cursor->isVisible()) {
cursor->cursorUpdate(true);
}
-
- m_savedPosition = mainFrame()->frameView()->contentPos();
+
+ if(!pageView()) {
+ m_savedPosition = mainFrame()->frameView()->contentPos();
+ }
+
cursor->scrollAndMoveCursor(keyevent.iCode, m_scrollingSpeed, fastscroll);
updateScrollbars();
if (!fastscroll) {
@@ -1059,26 +1126,29 @@
int vertical = 0;
switch(keyevent.iCode) {
case EKeyUpArrow: // North
+ case EStdKeyUpArrow: // :
vertical = -1;
break;
case EKeyRightUpArrow: // Northeast
- case EStdKeyDevice11: // : Extra KeyEvent supports diagonal event simulator wedge
+ case EStdKeyDevice11: // :
vertical = -1;
horizontal = +1;
break;
case EKeyRightArrow: // East
+ case EStdKeyRightArrow: // :
horizontal = +1;
break;
case EKeyRightDownArrow: // Southeast
- case EStdKeyDevice12: // : Extra KeyEvent supports diagonal event simulator wedge
+ case EStdKeyDevice12: // :
vertical = +1;
horizontal = +1;
break;
case EKeyDownArrow: // South
+ case EStdKeyDownArrow: // :
vertical = +1;
break;
@@ -1089,6 +1159,7 @@
break;
case EKeyLeftArrow: // West
+ case EStdKeyLeftArrow: // :
horizontal = -1;
break;
@@ -1124,26 +1195,47 @@
}
}
m_pageScrollHandler->scrollbarDrawer()->fadeScrollbar(delay);
-
- if ( (keyevent.iScanCode == EStdKeyDevice3) ||
+ TKeyEvent correctedKeyEvent(keyevent);
+ correctedKeyEvent.iCode = correctKeyCode();
+ TEventCode eventCodeUp = eventcode;
+ TEventCode eventCodeDown = EEventKeyDown;
+ //If we adjusted iCode we have to reset it to 0 after we
+ //create PlatformKeyEventSymbian when we send the key event.
+ //Otherwise the character will be drawn twice - by fep editor and by
+ //WebEditorClient. These two custom eventcodes serves as indicator that
+ //PlatformKeyEventSymbian::m_symbianEvent.iCode nee to be reset to 0.
+ if (correctedKeyEvent.iCode != m_currentEventKey.iCode) {
+ eventCodeDown = (TEventCode)(EEventUser + 1);
+ eventCodeUp = (TEventCode)(EEventUser + 2);
+ }
+
+ if ( (keyevent.iScanCode == EStdKeyDevice3) ||
(keyevent.iScanCode == EStdKeyEnter) ) {
- // pass it to webcore
-
- if (m_focusedElementType == TBrCtlDefs::EElementInputBox ||
- m_focusedElementType == TBrCtlDefs::EElementTextAreaBox) {
- setEditable(true);
+ // pass it to webcore
+
+ if (( m_focusedElementType == TBrCtlDefs::EElementInputBox ||
+ m_focusedElementType == TBrCtlDefs::EElementTextAreaBox) &&
+ m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed ) {
+ if (!m_prevEditMode) {
+ setEditable(true);
+ }
+ else {
+ m_prevEditMode = false;
+ }
}
if (m_brctl->settings()->getNavigationType() != SettingsContainer::NavigationTypeNone) {
- sendMouseEventToEngine(TPointerEvent::EButton1Up, cursor->position(), frame);
+ if (!sendKeyEventToEngine(correctedKeyEvent, eventcode, frame)) {
+ sendMouseEventToEngine(TPointerEvent::EButton1Up, cursor->position(), frame);
+ }
consumed = true;
}
}
if (!consumed) {
-
- TKeyEvent correctedKeyEvent(keyevent);
- correctedKeyEvent.iCode = m_currentEventKey.iCode;
- sendKeyEventToEngine(correctedKeyEvent, eventcode, frame);
+ if (m_currentEventCode == EEventKeyDown) {
+ sendKeyEventToEngine(correctedKeyEvent, eventCodeDown, frame);
+ }
+ sendKeyEventToEngine(correctedKeyEvent, eventCodeUp, frame);
}
m_currentEventKey = KNullKeyEvent;
m_currentEventCode = EEventNull;
@@ -1151,11 +1243,55 @@
}
-bool WebView::sendKeyEventToEngine(const TKeyEvent& keyevent,
+TUint WebView::correctKeyCode()
+{
+ TUint code = m_currentEventKey.iCode;
+ // if fep editor was invoked then it consume TKeyEvent and as
+ // result we have KeyEvent.iCode == 0. So we assume here that
+ // if element is editable and no iCode in KeyEvent then fep editor
+ // already put the right character into the input area and we can get
+ // the correct iCode from the last entered char.
+ if (m_isEditable && !m_currentEventKey.iCode && m_webfeptexteditor) {
+ TInt len = m_webfeptexteditor->DocumentLengthForFep();
+ if (len > 0) {
+ TBuf<2> data;
+ m_webfeptexteditor->GetEditorContentForFep(data, len - 1, 1);
+ if (data.Length() > 0) {
+ code = data[0];
+ }
+ }
+ }
+
+ return code;
+}
+
+bool WebView::sendKeyEventToEngine(const TKeyEvent& keyevent,
TEventCode eventcode, Frame* frame)
{
+ bool tabbedNavigation = (m_brctl->settings()->getNavigationType() == SettingsContainer::NavigationTypeTabbed);
+ Node* targetNode = frame->document()->focusedNode();
+ bool hasOnKeyDown = false;
+ bool hasOnKeyUp = false;
+ bool hasOnKeyPress = false;
+
+ for (Node* n = targetNode; n; n = n->parentNode()) {
+ EventTargetNode* tnode = static_cast<EventTargetNode*>(n);
+ hasOnKeyDown = tnode->getHTMLEventListener(keydownEvent);
+ hasOnKeyUp = tnode->getHTMLEventListener(keyupEvent);
+ hasOnKeyPress = tnode->getHTMLEventListener(keypressEvent);
+ if (hasOnKeyDown || hasOnKeyUp || hasOnKeyPress) {
+ break;
+ }
+ }
+
+
+ if (!m_isEditable && !(hasOnKeyDown || hasOnKeyUp || hasOnKeyPress)) {
+ frame->document()->setFocusedNode(NULL);
+ }
bool consumed = frame->eventHandler()->keyEvent(PlatformKeyboardEvent(keyevent,eventcode));
- if (!consumed && eventcode == EEventKey &&
+ frame->document()->setFocusedNode(targetNode);
+
+ if (!consumed && eventcode == EEventKey &&
(m_brctl->capabilities() & TBrCtlDefs::ECapabilityAccessKeys)) {
TKeyEvent ke = keyevent;
TChar c(ke.iCode);
@@ -1195,27 +1331,19 @@
if (!coreFrame)
return EKeyWasNotConsumed;
coreFrame = page()->focusController()->focusedOrMainFrame();
-
- // edit events
- if (m_isEditable) {
- consumed = handleEditable(keyevent, eventcode, coreFrame);
+
+ switch( eventcode ) {
+ case EEventKeyDown:
+ handleEventKeyDown(keyevent, eventcode, coreFrame);
+ break;
+ case EEventKey:
+ consumed = handleEventKeyL(keyevent, eventcode, coreFrame);
+ break;
+ case EEventKeyUp:
+ consumed = handleEventKeyUp(keyevent, eventcode, coreFrame);
+ break;
}
-
- // scroll events
- if (!consumed) {
- switch( eventcode ) {
- case EEventKeyDown:
- handleEventKeyDown(keyevent, eventcode, coreFrame);
- break;
- case EEventKey:
- if (keyevent.iScanCode != m_currentEventKey.iScanCode ) return EKeyWasNotConsumed;
- consumed = handleEventKeyL(keyevent, eventcode, coreFrame);
- break;
- case EEventKeyUp:
- consumed = handleEventKeyUp(keyevent, eventcode, coreFrame);
- break;
- }
- }
+
return (consumed) ? EKeyWasConsumed : EKeyWasNotConsumed;
}
@@ -1235,12 +1363,7 @@
scrollDelta.iX *= 100;
scrollDelta.iY *= 100;
if (!inPageViewMode()) {
- if (scrollDelta.iX == 0 && scrollDelta.iY == 0) {
- m_pageScrollHandler->scrollbarDrawer()->drawScrollbar(this);
- }
- else {
- m_pageScrollHandler->scrollbarDrawer()->drawScrollbar(this, scrollDelta);
- }
+ m_pageScrollHandler->scrollbarDrawer()->drawScrollbar(this, scrollDelta);
}
}
@@ -1254,6 +1377,7 @@
m_pageView = CPageView::NewL(*this);
MakeVisible(EFalse);
m_savedPosition = mainFrame()->frameView()->contentPos();
+ m_pageViewStartPosition = m_savedPosition;
m_brctl->reportStateChanged(TBrCtlDefs::EStateThumbnailView, ETrue);
}
}
@@ -1276,7 +1400,7 @@
if ( m_brctl->capabilities() & TBrCtlDefs::ECapabilityWebKitLite )
return;
if (m_pageView) {
- mainFrame()->frameView()->scrollTo(m_savedPosition);
+ mainFrame()->frameView()->scrollTo(m_pageViewStartPosition);
closePageView();
}
}
@@ -1545,6 +1669,8 @@
r.Grow(1, 1);
m_repaints.AddRect(r);
}
+
+ region.Close();
}
else {
TRect r(to, bufSize);