webengine/osswebengine/WebKit/s60/webview/WebFepTextEditor.cpp
changeset 0 dd21522fd290
child 1 7c90e6132015
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebKit/s60/webview/WebFepTextEditor.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,1266 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   WebFepTextEditor.cpp
+*
+*/
+
+
+
+#include "config.h"
+#include "../../bidi.h"
+
+#include "WebFepTextEditor.h"
+#include "WebEditorClient.h"
+#include "WebTextFormatMask.h"
+#include "WebView.h"
+#include "WebFrame.h"
+#include "Page.h"
+#include "FocusController.h"
+
+#include "Frame.h"
+#include "Editor.h"
+#include "HtmlNames.h"
+#include "EventHandler.h"
+#include "HtmlInputElement.h"
+#include "HtmlTextAreaElement.h"
+#include "PlatformKeyboardEvent.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+
+#include <coemain.h>
+#include <eikpanic.h>
+#include <aknedsts.h>
+#include <aknutils.h>
+#include "Text.h"
+
+using namespace WebCore;
+
+static const int kInfinite = -1;
+_LIT(KBlankDesC," ");
+
+GLDEF_C void Panic(TEikPanic aPanic)
+    {
+    _LIT(KPanicCat,"WEBKIT-FEP");
+    User::Panic(KPanicCat,aPanic);
+    }
+
+// -----------------------------------------------------------------------------
+// CWebFepTextEditor
+// 
+// 
+// -----------------------------------------------------------------------------
+CWebFepTextEditor::CWebFepTextEditor(WebView* aView)
+    : m_webView(aView),
+      m_textFormatMask(NULL),
+      m_inlineEditText(NULL)
+{
+    // Set up the extended capabilities
+    TRAP_IGNORE(
+        m_ExtendedInputCapabilities = CAknExtendedInputCapabilities::NewL();
+        );
+
+    // Set alignment on m_ExtendedInputCapabilities, yes it checks if NULL
+    // The EInputEditorAlignXXX flags are defined for 5.0+ platforms
+#if defined(BRDO_BROWSER_50_FF)
+    SetAlignment( CAknExtendedInputCapabilities::EInputEditorAlignBidi );
+#endif
+	EnableCcpu(ETrue);
+}
+
+// -----------------------------------------------------------------------------
+// ~CWebFepTextEditor
+// 
+// 
+// -----------------------------------------------------------------------------
+CWebFepTextEditor::~CWebFepTextEditor()
+    {
+    delete m_state;
+    delete m_inlineEditText;
+    delete m_textFormatMask;
+    }
+
+// -----------------------------------------------------------------------------
+// CreateTextFormatMask
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::CreateTextFormatMask()
+{
+    if (!m_textFormatMask) {        
+        Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+        if (frame &&
+            frame->document() &&
+            frame->document()->focusedNode()) {                
+            RenderStyle* s = frame->document()->focusedNode()->renderStyle();      
+            if (s && 
+            	(!s->wapInputFormat().isEmpty() || s->wapInputRequired())){            
+                m_textFormatMask = new WebTextFormatMask(s->wapInputFormat(), s->wapInputRequired());
+            }
+        }
+    }
+}              
+
+// -----------------------------------------------------------------------------
+// UpdateEditingMode
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::UpdateEditingMode()
+{        
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if (frame) {
+        SelectionController* sc = frame->selectionController();
+        if (sc && sc->isContentEditable() && sc->isInPasswordField()) {       
+            
+            // Set the state as if it was the CEikSecretEditor
+            CAknEdwinState* state = static_cast<CAknEdwinState*>(State(KNullUid));  
+            if (state) {
+                state->SetFlags( EAknEditorFlagNoLRNavigation |
+                                        EAknEditorFlagLatinInputModesOnly |
+                                        EAknEditorFlagNoT9 |
+                                        EAknEditorFlagUseSCTNumericCharmap );
+
+                state->SetDefaultInputMode(EAknEditorSecretAlphaInputMode);
+                state->SetCurrentInputMode(EAknEditorSecretAlphaInputMode);
+                state->SetPermittedCases(EAknEditorLowerCase|EAknEditorUpperCase);
+                state->SetCurrentCase(EAknEditorLowerCase);    
+                state->SetPermittedInputModes(EAknEditorSecretAlphaInputMode | EAknEditorNumericInputMode);
+                state->SetDefaultCase(EAknEditorLowerCase);
+                state->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG_LATIN_ONLY);    
+                state->SetNumericKeymap(EAknEditorPlainNumberModeKeymap);
+            }
+            
+        }
+        else {       
+            
+            CreateTextFormatMask();
+            
+            TUint currentCase ( EAknEditorLowerCase ) ;
+            TUint permittedCase ( EAknEditorAllCaseModes ) ;
+            TUint inputMode( EAknEditorNullInputMode );
+            TUint permittedInputModes( EAknEditorAllInputModes );            
+            TUint flags( EAknEditorFlagDefault ); 
+            TUint numericKeyMap( EAknEditorStandardNumberModeKeymap ); 
+
+            if (GetStateFromFormatMask(currentCase, permittedCase, inputMode, permittedInputModes, flags, numericKeyMap)) {             
+                UpdateFlagsState(flags);
+                UpdateInputModeState(inputMode, permittedInputModes, numericKeyMap);
+                UpdateCaseState(currentCase, permittedCase);                 
+            }
+            else {
+                CAknEdwinState* state = static_cast<CAknEdwinState*>(State(KNullUid));  
+                if (state) {
+                    state->SetPermittedInputModes(EAknEditorAllInputModes);
+                    state->SetPermittedCases(EAknEditorAllCaseModes);//allow everything
+                }
+            }
+        }
+    }   // End of if (frame)
+}
+    
+// -----------------------------------------------------------------------------
+// CancelEditingMode
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::CancelEditingMode()
+    {        
+    delete m_textFormatMask;
+    m_textFormatMask = NULL;
+
+    delete m_inlineEditText;    
+    m_inlineEditText = NULL;    
+
+    UpdateFlagsState(EAknEditorFlagDefault);
+    UpdateInputModeState(EAknEditorNullInputMode, EAknEditorAllInputModes,EAknEditorStandardNumberModeKeymap);
+    UpdateCaseState(EAknEditorLowerCase, EAknEditorAllCaseModes);            
+    
+    CancelFepInlineEdit();
+    }
+    
+// -----------------------------------------------------------------------------
+// ActivatePenInputRequest
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::ActivatePenInputRequest()
+{ 
+    CAknEdwinState* state = static_cast<CAknEdwinState*>(State(KNullUid));                
+    if ( state ) {                    
+        TRAP_IGNORE( state->ReportAknEdStateEventL(MAknEdStateObserver::EAknActivatePenInputRequest ) );
+    }    
+}
+
+// -----------------------------------------------------------------------------
+// DeactivatePenInputRequest
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::DeactivatePenInputRequest()
+    {        
+    }
+
+// -----------------------------------------------------------------------------
+// InputCapabilities
+// 
+// 
+// -----------------------------------------------------------------------------
+TCoeInputCapabilities CWebFepTextEditor::InputCapabilities()    
+{
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if (frame) {
+        SelectionController* sc = frame->selectionController();
+        if (sc && sc->isContentEditable()) {       
+
+            // Set up the input capabilities, based on the <input> box
+            TUint caps = TCoeInputCapabilities::ENavigation;                
+            
+            if ( sc->isInPasswordField() ) {           
+                caps |= TCoeInputCapabilities::ESecretText;                            
+            }
+            else {
+             
+                CAknEdwinState* state = static_cast<CAknEdwinState*>(State(KNullUid));                
+                if ( state ) {                    
+                    if ( state->PermittedInputModes() == EAknEditorNumericInputMode ) {
+                        caps |= (TCoeInputCapabilities::EWesternNumericIntegerPositive |
+                                 TCoeInputCapabilities::EWesternNumericIntegerNegative)| 
+                                 TCoeInputCapabilities::EAllText;
+                    }        
+                    else if (  state->PermittedInputModes() == EAknEditorTextInputMode ) {            
+                        caps |= TCoeInputCapabilities::EWesternAlphabetic;
+                    }
+                    else if (  state->PermittedInputModes() == (EAknEditorTextInputMode | EAknEditorNumericInputMode) ) {            
+                        caps |= (TCoeInputCapabilities::EWesternNumericIntegerPositive |
+                                 TCoeInputCapabilities::EWesternNumericIntegerNegative |
+                                 TCoeInputCapabilities::EWesternAlphabetic);
+                    }
+                    else {
+                        caps |=  TCoeInputCapabilities::EAllText;         
+                    }            
+                }
+            }
+
+            // Set up the extended input capabilities, based on dir="rtl".
+            // EInputEditorAlignXXX flags are only valid for 5.0+ platform.
+#if defined(BRDO_BROWSER_50_FF)
+            if ( IsDirectionRTL() ) {
+                SetAlignment(CAknExtendedInputCapabilities::EInputEditorAlignRight );
+            }
+            else {
+                SetAlignment(CAknExtendedInputCapabilities::EInputEditorAlignBidi );
+            }
+#endif
+            // Set up the ObjectProvider, so ExtendedInputCapablities can be called by FEP.
+            // MObjectProvider callback method MopSupplyObject().
+            TCoeInputCapabilities inputCaps( caps, this, NULL, TUid::Uid(0x100056de), this );
+            inputCaps.SetObjectProvider( this );
+            
+            return inputCaps;
+        }
+    }
+
+    // Empty input capabilities
+    TCoeInputCapabilities emptyCaps(TCoeInputCapabilities::ENone);
+    emptyCaps.SetObjectProvider( this );
+
+    return emptyCaps;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// from MCoeFepAwareTextEditor  
+//
+
+// -----------------------------------------------------------------------------
+// StartFepInlineEditL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::StartFepInlineEditL(
+      const TDesC& aInitialInlineText,
+      TInt /*aPositionOfInsertionPointInInlineText*/,
+      TBool /*aCursorVisibility*/,
+      const MFormCustomDraw*,
+      MFepInlineTextFormatRetriever&,
+      MFepPointerEventHandlerDuringInlineEdit& /*aPointerEventHandlerDuringInlineEdit*/)
+{    
+    CCoeEnv::Static()->ForEachFepObserverCall(FepObserverHandleStartOfTransactionL);              
+    ClearInlineText();        
+    UpdateInlineText(aInitialInlineText);       
+}
+
+// -----------------------------------------------------------------------------
+// UpdateFepInlineTextL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::UpdateFepInlineTextL( const TDesC& aNewInlineText,
+								TInt /*aPositionOfInsertionPointInInlineText*/ )
+{        
+    ClearInlineText();        
+    UpdateInlineText(aNewInlineText);       
+}
+
+// -----------------------------------------------------------------------------
+// SetInlineEditingCursorVisibilityL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::SetInlineEditingCursorVisibilityL(TBool /*aCursorVisibility*/)
+{
+}
+
+// -----------------------------------------------------------------------------
+// CancelFepInlineEdit
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::CancelFepInlineEdit()
+{
+}
+
+// -----------------------------------------------------------------------------
+// DocumentLengthForFep
+// 
+// 
+// -----------------------------------------------------------------------------
+TInt CWebFepTextEditor::DocumentLengthForFep() const
+{
+    TInt length = 0;
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if (frame &&
+        frame->document() &&
+        frame->document()->focusedNode()) {
+
+        if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) {
+            HTMLInputElement* ie = static_cast<HTMLInputElement*>(frame->document()->focusedNode());
+            length = ie->value().length();
+        }
+        else if (frame->document()->focusedNode()->hasTagName(HTMLNames::textareaTag)) {
+            HTMLTextAreaElement* ie = static_cast<HTMLTextAreaElement*>(frame->document()->focusedNode());
+            length = ie->value().length();
+        }
+    }
+
+    return length;    
+}
+
+// -----------------------------------------------------------------------------
+// DocumentMaximumLengthForFep
+// 
+// 
+// -----------------------------------------------------------------------------
+TInt CWebFepTextEditor::DocumentMaximumLengthForFep() const
+{       
+    TInt length = KMaxTInt;       
+
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if (frame &&
+        frame->document() &&
+        frame->document()->focusedNode() &&
+        frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag) ) {                   
+        length = static_cast<HTMLInputElement*>(frame->document()->focusedNode())->maxLength();
+    }
+
+	// Override the length if a text format mask is set
+	if ( m_textFormatMask && m_textFormatMask->getMultitude() > 0 )
+        length = m_textFormatMask->getMultitude();
+
+    // TextArea node has no member function maxLength(), so return KMaxTInt
+    return length;
+}
+
+// -----------------------------------------------------------------------------
+// SetCursorSelectionForFepL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection)
+{    
+    // The other part of the rather hackish way to check if we are at the end of the editing field
+    // see WebEditorClient::handleKeypress
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if ( frame ) {           
+        SelectionController* sc = frame->selectionController();
+        Node* editNode = sc->base().node();
+        if ( IsTextAreaFocused() ) {
+			TInt position( aCursorSelection.iAnchorPos );
+			TInt offset( 0 );
+			if ( editNode ) {
+				editNode = findTextNodeForCurPos( editNode, position );
+				if ( aCursorSelection.iAnchorPos > position ) {
+					offset = aCursorSelection.iAnchorPos - position;
+				}
+				Position base( editNode, offset );
+				Position extent( editNode, offset );
+				sc->moveTo( base, extent, DOWNSTREAM );
+			}
+		}
+		else if ( editNode && editNode->isTextNode() ) { 
+			Position base( sc->baseNode(), aCursorSelection.iAnchorPos );
+			Position extent( sc->baseNode(), aCursorSelection.iCursorPos );
+			sc->moveTo( base, extent, DOWNSTREAM );   
+		}
+		HandleUpdateCursor();
+    }
+}
+
+// -----------------------------------------------------------------------------
+// GetCursorSelectionForFep
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const
+{
+    aCursorSelection.SetSelection(0,0);
+    
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if ( frame ) {           
+        SelectionController* sc = frame->selectionController();
+        Node* editNode = sc->base().node();
+		if ( frame && frame->document()->focusedNode() ) {
+			if ( IsTextAreaFocused() ) {
+				TInt len( 0 );
+				if ( editNode ) {
+					findPrevSiblingTextLen( editNode, len );  
+				}
+				aCursorSelection.SetSelection( sc->baseOffset() + len,
+											   sc->extentOffset() + len );
+			}
+			else {
+				aCursorSelection.SetSelection(sc->baseOffset(), sc->extentOffset());       
+			}
+		}
+	}
+}
+
+// -----------------------------------------------------------------------------
+// GetEditorContentForFep
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::GetEditorContentForFep( TDes& aEditorContent,
+												TInt aDocumentPosition,
+												TInt aLengthToRetrieve ) const
+{    
+    aEditorContent = KNullDesC;   	   // KNullDesC has length 0
+
+    if (aLengthToRetrieve == 0) {
+        return;
+    }
+        
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if (frame &&
+        frame->document() &&
+        frame->document()->focusedNode()) {
+
+        if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) {
+            HTMLInputElement* ie = static_cast<HTMLInputElement*>(frame->document()->focusedNode());
+            aEditorContent = ie->value().substring(aDocumentPosition, aLengthToRetrieve);
+        }
+        else if (frame->document()->focusedNode()->hasTagName(HTMLNames::textareaTag)) {
+            HTMLTextAreaElement* ie = static_cast<HTMLTextAreaElement*>(frame->document()->focusedNode());
+            // Convert the newline to paragraph separator, because the FEP
+            // input editors (vkb, etc) ignore newline
+            String str(ie->value().substring(aDocumentPosition, aLengthToRetrieve));
+            str.replace(EKeyLineFeed, CEditableText::EParagraphDelimiter);  
+            aEditorContent = str;        
+        }
+    }
+}
+
+// -----------------------------------------------------------------------------
+// GetFormatForFep
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::GetFormatForFep(TCharFormat& /*aFormat*/,TInt /*aDocumentPosition*/) const
+{         
+}
+
+// -----------------------------------------------------------------------------
+// GetScreenCoordinatesForFepL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::GetScreenCoordinatesForFepL(TPoint& /*aLeftSideOfBaseLine*/,
+                                                    TInt& /*aHeight*/,
+                                                    TInt& /*aAscent*/,
+                                                    TInt /*aDocumentPosition*/) const
+{    
+}
+
+// -----------------------------------------------------------------------------
+// DoCommitFepInlineEditL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::DoCommitFepInlineEditL()
+{                    
+    ClearInlineText();     
+
+    if (m_inlineEditText && DocumentLengthForFep() < DocumentMaximumLengthForFep()) {
+        Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+        if (frame){
+            frame->editor()->insertTextWithoutSendingTextEvent(String(*m_inlineEditText), false);
+        }
+    }
+    
+    //delete the m_inlineEditText since text is commited
+    delete m_inlineEditText;    
+    m_inlineEditText = NULL;    
+
+    HandleUpdateCursor();
+    UpdateEditingMode();
+}
+
+// -----------------------------------------------------------------------------
+// Extension1
+// 
+// 
+// -----------------------------------------------------------------------------
+MCoeFepAwareTextEditor_Extension1* CWebFepTextEditor::Extension1(TBool& aSetToTrue)
+{
+    aSetToTrue=ETrue;
+    return STATIC_CAST(MCoeFepAwareTextEditor_Extension1*, this);
+}
+
+// -----------------------------------------------------------------------------
+// MCoeFepAwareTextEditor_Reserved_2
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::MCoeFepAwareTextEditor_Reserved_2()
+{
+}
+           
+////////////////////////////////////////////////////////////////////////////////
+// from MCoeFepAwareTextEditor_Extension1
+
+// -----------------------------------------------------------------------------
+// SetStateTransferingOwnershipL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::SetStateTransferingOwnershipL(CState* aState, TUid /*aTypeSafetyUid*/)
+{
+    delete m_state;
+    m_state = aState;    
+}
+
+// -----------------------------------------------------------------------------
+// State
+// 
+// 
+// -----------------------------------------------------------------------------
+MCoeFepAwareTextEditor_Extension1::CState* CWebFepTextEditor::State(TUid /*aTypeSafetyUid*/)
+{
+    if (!m_state) {
+        CAknEdwinState* state = new CAknEdwinState();
+        state->SetObjectProvider(m_webView);
+        m_state = state;
+        }
+    return m_state;
+}
+
+// -----------------------------------------------------------------------------
+// StartFepInlineEditL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::StartFepInlineEditL(
+        TBool& aSetToTrue, 
+        const TCursorSelection& aCursorSelection, 
+        const TDesC& aInitialInlineText, 
+        TInt aPositionOfInsertionPointInInlineText, 
+        TBool aCursorVisibility, 
+        const MFormCustomDraw* aCustomDraw, 
+        MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, 
+        MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit)
+{
+    aSetToTrue=ETrue;
+    SetCursorSelectionForFepL(aCursorSelection);
+    StartFepInlineEditL(aInitialInlineText, aPositionOfInsertionPointInInlineText, aCursorVisibility, aCustomDraw, aInlineTextFormatRetriever, aPointerEventHandlerDuringInlineEdit);
+}
+
+// -----------------------------------------------------------------------------
+// SetCursorType
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::SetCursorType(TBool& /*aSetToTrue*/, const TTextCursor& /*aTextCursor*/)
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// from TCoeInputCapabilities::MCoeFepSpecificExtensions
+
+// -----------------------------------------------------------------------------
+// IsValidCharacter
+// 
+// 
+// -----------------------------------------------------------------------------
+TBool CWebFepTextEditor::IsValidCharacter(TInt aChar)
+{
+     return ETrue;
+}
+ 
+////////////////////////////////////////////////////////////////////////////////
+// from MObjectProvider
+
+// -----------------------------------------------------------------------------
+// MopSupplyObject
+// Fep Manager will call us to get pointers to our bits. We currently support
+// returning our ExtendedInputCapabilities.
+// -----------------------------------------------------------------------------
+TTypeUid::Ptr CWebFepTextEditor::MopSupplyObject(TTypeUid aId)
+{
+    if ( aId.iUid == CAknExtendedInputCapabilities::ETypeId )
+    {
+        return aId.MakePtr( m_ExtendedInputCapabilities );
+    }
+
+    return aId.Null();
+}
+ 
+
+////////////////////////////////////////////////////////////////////////////////
+// New public methods
+//
+
+// -----------------------------------------------------------------------------
+// UpdateFlagsState
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::UpdateFlagsState(TUint flags)
+{    
+    CAknEdwinState* state = static_cast<CAknEdwinState*>(State(KNullUid));        
+    
+    if ( IsTextAreaFocused() ) {
+    	// If in a TextArea, allow "enter" key presses to be newline/paragraph
+    	state->SetFlags( flags | EAknEditorFlagUseSCTNumericCharmap 
+    					 | EAknEditorFlagAllowEntersWithScrollDown );
+    	}
+    else {
+        state->SetFlags(flags | EAknEditorFlagUseSCTNumericCharmap);
+    	}
+    
+    state->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateFlagsUpdate);
+}
+
+// -----------------------------------------------------------------------------
+// UpdateInputModeState
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::UpdateInputModeState(TUint inputMode, TUint permittedInputModes, TUint numericKeyMap)
+{  
+
+    CAknEdwinState* state = static_cast<CAknEdwinState*>(State(KNullUid));        
+    
+    if (permittedInputModes != EAknEditorNumericInputMode) {
+        EVariantFlag variant = AknLayoutUtils::Variant();
+        if (variant == EApacVariant) {
+              permittedInputModes |= EAknEditorTextInputMode |
+              EAknEditorHalfWidthTextInputMode | EAknEditorFullWidthTextInputMode |
+              EAknEditorKatakanaInputMode | EAknEditorFullWidthKatakanaInputMode |
+              EAknEditorHiraganaKanjiInputMode | EAknEditorHiraganaInputMode;
+            
+        }
+    }
+    
+    state->SetDefaultInputMode(inputMode);             
+    state->SetCurrentInputMode(inputMode);    
+    state->SetPermittedInputModes(permittedInputModes);                 
+    state->SetNumericKeymap(static_cast<TAknEditorNumericKeymap>(numericKeyMap));
+
+    state->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateInputModeUpdate);        
+
+}
+
+// -----------------------------------------------------------------------------
+// UpdateCaseState
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::UpdateCaseState(TUint currentCase, TUint permittedCase)
+{    
+    CAknEdwinState* state = static_cast<CAknEdwinState*>(State(KNullUid));        
+
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if (frame){
+
+        if (frame->editor()->canEditRichly()) {
+            state->SetDefaultCase(EAknEditorTextCase);                    
+        }
+        else {
+            state->SetDefaultCase(currentCase);
+            state->SetCurrentCase(currentCase);
+            state->SetPermittedCases(permittedCase);        
+        }    
+    }
+    
+    state->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate);        
+}
+
+// -----------------------------------------------------------------------------
+// HandleUpdateCursor
+//
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::HandleUpdateCursor()
+{
+    // ReportAknEdStateEventL, for events see aknedstsobs.h
+    // MAknEdStateObserver::EAknCursorPositionChanged 
+    
+    CAknEdwinState* state = static_cast<CAknEdwinState*>(State(KNullUid));                
+    if ( state ) {                    
+        TRAP_IGNORE( state->ReportAknEdStateEventL( MAknEdStateObserver::EAknCursorPositionChanged ) );
+    }
+}
+
+// -----------------------------------------------------------------------------
+// GetStateFromFormatMask
+// 
+// 
+// -----------------------------------------------------------------------------
+bool CWebFepTextEditor::GetStateFromFormatMask(TUint& currentCase,
+                                                TUint& permittedCase,
+                                                TUint& inputMode,
+                                                TUint& permittedInputModes,
+                                                TUint& flags,
+                                                TUint& numericKeyMap)
+{
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();    
+    if (frame && m_textFormatMask) {
+    
+        TInt cursorpos = DocumentLengthForFep();        
+        TInputFormatMaskType fm = m_textFormatMask->getInputFormatMaskType(frame, cursorpos);        
+
+        switch( fm ) {
+            case ELeUpSymPuc:       //A any upper case letter or symbolic
+                flags = EAknEditorFlagNoT9 | EAknEditorFlagFixedCase;
+                currentCase = EAknEditorUpperCase; 
+                permittedCase = EAknEditorUpperCase;                                    
+                inputMode = EAknEditorTextInputMode;
+                permittedInputModes = EAknEditorTextInputMode;
+            break;
+            case ELeLoSymPuc:       //a any lower case letter or symbolic
+                flags = EAknEditorFlagNoT9 | EAknEditorFlagFixedCase;
+                currentCase = EAknEditorLowerCase;
+                permittedCase= EAknEditorLowerCase;                        
+                inputMode = EAknEditorTextInputMode;
+                permittedInputModes= EAknEditorTextInputMode;
+            break;
+            case ELeUpNumSymPuc:    //X any upper case, number or symbolic
+                flags = EAknEditorFlagNoT9 | EAknEditorFlagFixedCase;
+                currentCase = EAknEditorUpperCase;
+                permittedCase= EAknEditorUpperCase;                        
+                inputMode = EAknEditorTextInputMode;
+                permittedInputModes= EAknEditorTextInputMode;
+            break;
+            case ELeLoNumSymPuc:    //x any lower case, number or symbolic
+                flags = EAknEditorFlagNoT9 | EAknEditorFlagFixedCase;
+                currentCase = EAknEditorLowerCase;
+                permittedCase= EAknEditorLowerCase;
+                inputMode = EAknEditorTextInputMode;
+                permittedInputModes= EAknEditorTextInputMode | EAknEditorNumericInputMode;
+            break;
+            case EAnyLow:           //m any lower character can be changed to upper
+                currentCase = EAknEditorLowerCase;
+                permittedCase= EAknEditorAllCaseModes;
+                inputMode = EAknEditorTextInputMode;
+                permittedInputModes= EAknEditorAllInputModes;
+            break;          
+            case EAnyUpper:         //M any upper character can be changed to lower
+                currentCase = EAknEditorUpperCase; 
+                permittedCase= EAknEditorAllCaseModes;
+                inputMode = EAknEditorTextInputMode;
+                permittedInputModes= EAknEditorAllInputModes;
+            break;
+            case ENumSymPuc:        //n any number or symbolic
+                flags = EAknEditorFlagNoT9;
+                currentCase = EAknEditorUpperCase;
+                permittedCase = EAknEditorAllCaseModes;
+                inputMode = EAknEditorNumericInputMode;    
+                permittedInputModes= EAknEditorAllInputModes;        
+            break;
+            case ENumChar:          //N any number
+                flags = EAknEditorFlagNoT9;
+                currentCase = EAknEditorUpperCase;
+                permittedCase = EAknEditorAllCaseModes;
+                inputMode = EAknEditorNumericInputMode;    
+                permittedInputModes= EAknEditorNumericInputMode;   
+            break;
+            case EStatic:           
+                return EFalse;
+            break;
+            case ENoFormat: 
+                return EFalse;
+            break;                    
+            default:
+            return EFalse;        
+        }    
+        
+        return ETrue;                
+    }
+
+    return EFalse;                
+}
+
+// -----------------------------------------------------------------------------
+// validateTextFormat
+// 
+// 
+// -----------------------------------------------------------------------------
+bool CWebFepTextEditor::validateTextFormat()
+{
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if (!frame || !frame->document()->focusedNode())
+        return true;
+
+    RenderStyle* s = frame->document()->focusedNode()->renderStyle();      
+    if (!m_textFormatMask) {            
+        return true;
+    }
+        
+    Node* n = frame->document()->focusedNode();
+    if (n->hasTagName(HTMLNames::inputTag)) {
+        HTMLInputElement* input = static_cast<HTMLInputElement*>(n);
+        WebTextFormatMask::ErrorBlock eb;
+        CSSStyleDeclaration* style = input->style();
+        ExceptionCode ec = 0;     
+        
+        String inputColor = style->getPropertyValue(CSS_PROP_COLOR); 
+        if ( inputColor.lower() != "red" )
+        {
+            m_inputTextColor = inputColor; 
+        }
+        
+        if (!m_textFormatMask->checkText(input->value(), eb)) {
+            style->setProperty(CSS_PROP_COLOR, "red", false, ec);
+            return false;
+        }
+        else 
+        {
+            style->setProperty(CSS_PROP_COLOR, m_inputTextColor, false, ec);
+            CancelEditingMode();
+            return true; 
+        }
+    }
+    else if ( n->hasTagName(HTMLNames::textareaTag)) {
+        CancelEditingMode();
+    }
+    
+    return true;
+}
+
+// -----------------------------------------------------------------------------
+// IsDirectionRTL
+// Walk through the DOM and find if the focus node or a parent (table, html,
+// body, etc) has dir attribute set to RTL.
+// -----------------------------------------------------------------------------
+TBool CWebFepTextEditor::IsDirectionRTL()
+{
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if ( frame &&
+         frame->document() &&
+         frame->document()->focusedNode() ) {
+
+        Node* node = frame->document()->focusedNode();
+        RenderStyle* renderStyle = node->renderStyle();
+        if ( renderStyle ) {
+            TextDirection txtDir = renderStyle->direction();
+            if ( txtDir == RTL ) {
+                return ETrue;
+            }
+        }
+    }
+
+    return EFalse;
+}
+
+#if defined(BRDO_BROWSER_50_FF)
+// -----------------------------------------------------------------------------
+// SetAlignment
+// The EInputEditorAlignXXX flags are only supported in 5.0+ platforms
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::SetAlignment(CAknExtendedInputCapabilities::TInputCapabilities aAlignment)
+{
+    if ( !m_ExtendedInputCapabilities ) {
+        return;
+    }
+    
+    // Clear the old alignment
+    TUint capabilities = m_ExtendedInputCapabilities->Capabilities();
+    capabilities &= ~( CAknExtendedInputCapabilities::KAknEditorAlignMask );
+
+    // Set the new alignment
+    capabilities |= aAlignment;
+    m_ExtendedInputCapabilities->SetCapabilities( capabilities );
+}
+#endif
+
+// -----------------------------------------------------------------------------
+// UpdateInlineText
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::UpdateInlineText(const TDesC& aText)
+{                
+    delete m_inlineEditText;    
+    m_inlineEditText = NULL;    
+    
+    if (DocumentLengthForFep() >= DocumentMaximumLengthForFep()) 
+        return;
+
+    m_inlineEditText = aText.Alloc();      
+    
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    
+    if (!frame)
+        return;
+    
+    
+    RenderStyle* r = NULL;
+    if ( Node *n  = frame->selectionController()->selection().start().node() ) {
+        r = n->renderStyle();
+    }
+      
+    bool textSecurity = r && r->textSecurity() != TSNONE;
+
+    RefPtr<CSSMutableStyleDeclaration> oldStyle;
+    if (textSecurity) {    
+        oldStyle = frame->typingStyle();
+        RefPtr<CSSMutableStyleDeclaration> style = new CSSMutableStyleDeclaration;
+        style->setProperty(CSS_PROP__WEBKIT_TEXT_SECURITY, CSS_VAL_NONE);
+        frame->computeAndSetTypingStyle(style.get(), EditActionTyping);
+    }
+        
+    frame->editor()->insertTextWithoutSendingTextEvent(String(*m_inlineEditText), false);
+        
+    if (textSecurity) {
+        if (oldStyle)
+            frame->setTypingStyle(oldStyle.get());
+        else
+            frame->clearTypingStyle();
+    }
+}
+
+// -----------------------------------------------------------------------------
+// ClearInlineText
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::ClearInlineText()
+{
+    TInt oldlen = m_inlineEditText ? m_inlineEditText->Length() : 0;
+
+    TKeyEvent keyEvent = { EKeyBackspace, EKeyBackspace, 0, 0 };    
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    if (frame) {    
+        while ( oldlen-- ) {
+            frame->editor()->deleteWithDirection(SelectionController::BACKWARD,
+                                                 CharacterGranularity, false, true);
+        }
+    }
+}
+
+// -----------------------------------------------------------------------------
+// IsTextAreaFocused
+// 
+// 
+// -----------------------------------------------------------------------------
+bool CWebFepTextEditor::IsTextAreaFocused() const
+{
+    Frame* frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    return ( frame && frame->document()->focusedNode() &&
+    		 frame->document()->focusedNode()->hasTagName(HTMLNames::textareaTag));
+}
+
+// -----------------------------------------------------------------------------
+// CcpuIsFocused
+// 
+// 
+// -----------------------------------------------------------------------------
+TBool CWebFepTextEditor::CcpuIsFocused() const
+{
+    return ETrue;
+}
+    
+// -----------------------------------------------------------------------------
+// CcpuCanCut
+// 
+// 
+// -----------------------------------------------------------------------------
+TBool CWebFepTextEditor::CcpuCanCut() const
+{
+    TCursorSelection selection;
+    GetCursorSelectionForFep(selection);    
+    return selection.Length();
+}
+
+// -----------------------------------------------------------------------------
+// CcpuCutL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::CcpuCutL()
+{
+    PlaceDataOnClipboardL();
+    TCursorSelection selection;
+    GetCursorSelectionForFep(selection);    
+}
+    
+// -----------------------------------------------------------------------------
+// CcpuCanCopy
+// 
+// 
+// -----------------------------------------------------------------------------
+TBool CWebFepTextEditor::CcpuCanCopy() const
+{
+    TCursorSelection selection;
+    GetCursorSelectionForFep(selection);    
+    return selection.Length();
+}
+    
+// -----------------------------------------------------------------------------
+// CcpuCopyL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::CcpuCopyL()
+{
+    PlaceDataOnClipboardL();
+}
+    
+// -----------------------------------------------------------------------------
+// CcpuCanPaste
+// 
+// 
+// -----------------------------------------------------------------------------
+TBool CWebFepTextEditor::CcpuCanPaste() const
+{
+    TRAPD(err, DoCcpuCanPasteL());
+    return err == KErrNone;
+}
+    
+// -----------------------------------------------------------------------------
+// CcpuPasteL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::CcpuPasteL() 
+{
+    RetrieveDataFromClipboardL();   
+}
+        
+// -----------------------------------------------------------------------------
+// DoCcpuCanPasteL
+// 
+// 
+// -----------------------------------------------------------------------------
+void  CWebFepTextEditor::DoCcpuCanPasteL() const
+{
+    CClipboard* cb=CClipboard::NewForReadingL(CCoeEnv::Static()->FsSession());
+    CleanupStack::PushL(cb);
+    TStreamId streamId=cb->StreamDictionary().At(KClipboardUidTypePlainText);
+    if (streamId==KNullStreamId)
+        User::Leave(KErrNotFound);
+    CleanupStack::PopAndDestroy(); // allowedChars, cb
+}    
+    
+// -----------------------------------------------------------------------------
+// PlaceDataOnClipboardL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::PlaceDataOnClipboardL()
+{
+    CancelFepInlineEdit();
+    CClipboard* cb=CClipboard::NewForWritingLC(CCoeEnv::Static()->FsSession());
+    CopyToStoreL(cb->Store(),cb->StreamDictionary());
+    cb->CommitL();
+    CleanupStack::PopAndDestroy();
+}
+
+// -----------------------------------------------------------------------------
+// CopyToStoreL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::CopyToStoreL(CStreamStore& aStore,CStreamDictionary& aDict)
+{
+	if ( DocumentLengthForFep()== 0)
+		return ;
+    TCursorSelection selection;
+    GetCursorSelectionForFep(selection);
+	
+	HBufC* buf = HBufC::NewLC(512);
+	TPtr ptr(buf->Des());
+			
+    GetEditorContentForFep(ptr,0,DocumentLengthForFep());
+    CPlainText* text = CPlainText::NewL(CPlainText::EFlatStorage);	
+	
+	text->InsertL(0,*buf);	
+	text->CopyToStoreL(aStore, aDict, selection.LowerPos(), selection.Length());
+	
+	delete text;
+    CleanupStack::PopAndDestroy();	
+}
+
+// -----------------------------------------------------------------------------
+// RetrieveDataFromClipboardL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::RetrieveDataFromClipboardL()
+{
+    m_webView->fepTextEditor()->CancelFepInlineEdit();
+    CClipboard* cb=NULL;
+    TRAPD(err,cb=CClipboard::NewForReadingL(CCoeEnv::Static()->FsSession()));
+    CleanupStack::PushL(cb);
+    User::LeaveIfError(err);
+    TStreamId streamId=cb->StreamDictionary().At(KClipboardUidTypePlainText);
+    PasteFromStoreL(cb->Store(), cb->StreamDictionary());
+    CleanupStack::PopAndDestroy();  // cb    
+}
+        
+// -----------------------------------------------------------------------------
+// PasteFromStoreL
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::PasteFromStoreL(CStreamStore& aStore,CStreamDictionary& aDict)
+{
+    //Read the content into Text
+    CancelFepInlineEdit();
+    TStreamId streamId=aDict.At(KClipboardUidTypePlainText);
+    TCursorSelection selection;
+    GetCursorSelectionForFep(selection);
+    const TInt cursorPos=selection.LowerPos();
+    
+	HBufC* buf1 = HBufC::NewLC(512);
+	TPtr ptr1(buf1->Des());
+	
+	CPlainText* text = CPlainText::NewL(CPlainText::EFlatStorage);	
+	
+    GetEditorContentForFep(ptr1,0,DocumentLengthForFep());    
+    
+    text->InsertL(0,*buf1);
+        
+    TInt charPasted = text->PasteFromStoreL(aStore,aDict,cursorPos);
+    
+    HBufC* buf = HBufC::NewLC(512);
+    TPtr ptr(buf->Des());
+    text->Extract(ptr,cursorPos,charPasted);      
+    
+    //remove Paragraph Delimiter
+    TInt position = ptr.Mid(0).LocateReverse(TChar(CEditableText::EParagraphDelimiter));
+    while (position != KErrNotFound ){
+        ptr.Delete( position, 1 );
+        position = ptr.Left(position).LocateReverse(TChar(CEditableText::EParagraphDelimiter));
+        }           
+    
+    Frame* frame = m_webView->page()->mainFrame();
+	frame = m_webView->page()->focusController()->focusedOrMainFrame();
+    frame->editor()->insertTextWithoutSendingTextEvent(String(ptr), false);
+    
+    delete text;
+    CleanupStack::PopAndDestroy(2);
+}
+
+// -----------------------------------------------------------------------------
+// EnableCcpu
+// 
+// 
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::EnableCcpu(TBool aSupport)
+{
+    CAknEdwinState* edwinState = static_cast<CAknEdwinState*>(this->State(KNullUid));
+    if(aSupport)
+        {
+        edwinState->SetCcpuState(this);    
+        }
+    else
+        {
+        edwinState->SetCcpuState(NULL);
+        }       
+}
+
+// -----------------------------------------------------------------------------
+// findPrevSiblingTextLen
+// 
+// Walk the previous text nodes and add up the len of each text node, so we can
+// calculate the total length from first text node to current text node cursor
+// position.
+// NOTES:
+// 1. Each "inserted" newline creates a new node.
+// 2. Text area's with newline characters prepopulated (not "entered" by users,
+//    but in the original html) do not create separate nodes.
+// -----------------------------------------------------------------------------
+void CWebFepTextEditor::findPrevSiblingTextLen(Node* aNode, TInt& aLen) const
+{
+	String str;
+	while ( aNode ) {
+		aNode = aNode->previousSibling();
+		if ( aNode && aNode->isTextNode() ) {
+			WebCore::Text* text = (WebCore::Text*)aNode;
+			str = text->data();
+			aLen +=  str.length();
+		}
+	}
+}
+
+// -----------------------------------------------------------------------------
+// findTextNodeCurPos
+//
+// Returns the text node that contains the current text (cursor) position and
+// returns the summed length (aPos) of all the text nodes before the current
+// text node.
+// NOTE: The length (aPos) doesn't include the current text node's length.
+// -----------------------------------------------------------------------------
+Node* CWebFepTextEditor::findTextNodeForCurPos(Node* aNode, TInt& aPos) const
+{
+	// Get the first text node
+	Node* firstTextNode = NULL;
+	Node* retNode = aNode;
+	while ( aNode ) {
+		firstTextNode = aNode;
+		aNode = aNode->previousSibling();
+	}
+
+	TInt len( 0 );
+	String str;
+	aNode = firstTextNode;
+	for ( ; aNode; aNode=aNode->nextSibling() ) {
+		if ( aNode && aNode->isTextNode() ) {
+			WebCore::Text* aText = (WebCore::Text*)aNode;
+			str = aText->data();
+			len +=  str.length();
+			if ( len >= aPos ) {
+				// We found the text node at aPos, calculate the length of all
+				// previous text nodes
+				retNode = aNode;
+				aPos = len - str.length();
+				break;
+			}
+		}
+	}
+
+	return retNode;
+}