namespace WebKit {
+#if ENABLE(TIZEN_ISF_PORT)
+const unsigned InputMethodContextEfl::maxContextSize = 10;
+#endif
+
InputMethodContextEfl::InputMethodContextEfl(EwkViewImpl* viewImpl, PassOwnPtr<Ecore_IMF_Context> context)
: m_viewImpl(viewImpl)
, m_context(context)
, m_focused(false)
#if ENABLE(TIZEN_ISF_PORT)
+ , m_contextID(0)
, m_useInputMethod(false)
, m_state(ECORE_IMF_INPUT_PANEL_STATE_HIDE)
, m_inputPickerType(-1)
#endif
{
+#if !ENABLE(TIZEN_ISF_PORT)
ASSERT(context);
-#if ENABLE(TIZEN_ISF_PORT)
- initializeIMFContext(m_context.get(), ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL);
-#else
ecore_imf_context_event_callback_add(m_context.get(), ECORE_IMF_CALLBACK_PREEDIT_CHANGED, onIMFPreeditSequenceChanged, this);
ecore_imf_context_event_callback_add(m_context.get(), ECORE_IMF_CALLBACK_COMMIT, onIMFInputSequenceComplete, this);
#endif
#endif
#if ENABLE(TIZEN_ISF_PORT)
-void InputMethodContextEfl::initializeIMFContext(Ecore_IMF_Context* context, Ecore_IMF_Input_Panel_Layout layout)
+void InputMethodContextEfl::initializeIMFContext(Ecore_IMF_Context* context, Ecore_IMF_Input_Panel_Layout layout, int layoutVariation)
{
ecore_imf_context_input_panel_enabled_set(context, false);
ecore_imf_context_input_panel_event_callback_add(context, ECORE_IMF_INPUT_PANEL_STATE_EVENT, onIMFInputPanelStateChanged, this);
ecore_imf_context_event_callback_add(context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, onIMFDeleteSurrounding, this);
ecore_imf_context_event_callback_add(context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, onIMFPreeditSequenceChanged, this);
ecore_imf_context_event_callback_add(context, ECORE_IMF_CALLBACK_COMMIT, onIMFInputSequenceComplete, this);
- ecore_imf_context_input_panel_layout_set(m_context.get(), layout);
+
+ ecore_imf_context_input_panel_layout_set(context, layout);
+ if (layoutVariation >= 0)
+ ecore_imf_context_input_panel_layout_variation_set(context, layoutVariation);
}
void InputMethodContextEfl::setUseInputMethod(bool use)
updateTextInputState();
}
-Ecore_IMF_Input_Panel_Layout InputMethodContextEfl::layoutType(const String& type)
+PassOwnPtr<Ecore_IMF_Context> InputMethodContextEfl::takeContext(uintptr_t contextID)
{
- if (type == "number")
- return ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER;
- else if (type == "email")
- return ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL;
+ size_t i = m_contextList.size();
+ while (i > 0) {
+ --i;
+ if (m_contextList[i].first == contextID) {
+ PassOwnPtr<Ecore_IMF_Context> context = m_contextList[i].second.release();
+ m_contextList.remove(i);
+ return context;
+ }
+ }
+
+ return PassOwnPtr<Ecore_IMF_Context>();
+}
+
+void InputMethodContextEfl::setIMFContext(const EditorState& editor)
+{
+ const String& type = editor.inputMethodHints;
+ Ecore_IMF_Input_Panel_Layout layout;
+ int layoutVariation = -1;
+
+ if (type == "number") {
+ layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY;
+ layoutVariation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_NORMAL;
+ } else if (type == "signedNumber") {
+ layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY;
+ layoutVariation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED;
+ } else if (type == "decimalNumber") {
+ layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY;
+ layoutVariation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_DECIMAL;
+ } else if (type == "signedDecimalNumber") {
+ layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY;
+ layoutVariation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED_AND_DECIMAL;
+ } else if (type == "email")
+ layout = ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL;
else if (type == "url")
- return ECORE_IMF_INPUT_PANEL_LAYOUT_URL;
+ layout = ECORE_IMF_INPUT_PANEL_LAYOUT_URL;
else if (type == "tel")
- return ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER;
+ layout = ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER;
else if (type == "password")
- return ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD;
+ layout = ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD;
else
- return ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
-}
+ layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
-void InputMethodContextEfl::setIMFContext(Ecore_IMF_Input_Panel_Layout layout, const String& type)
-{
- if (m_contextList.contains(layout)) {
- revertIMFContext();
- m_context = m_contextList.take(layout);
- } else if (!m_context || ecore_imf_context_input_panel_layout_get(m_context.get()) != layout) {
- OwnPtr<Ecore_IMF_Context> context = createIMFContext(evas_object_evas_get(m_viewImpl->view()));
- if (m_context)
- revertIMFContext();
- m_context = context.release();
- initializeIMFContext(m_context.get(), layout);
+ OwnPtr<Ecore_IMF_Context> context;
+ if (m_contextID == editor.inputMethodContextID)
+ context = m_context.release();
+ else
+ context = takeContext(editor.inputMethodContextID);
+
+ if (!context) {
+ context = createIMFContext(evas_object_evas_get(m_viewImpl->view()));
+ initializeIMFContext(context.get(), layout, layoutVariation);
}
+ revertIMFContext();
+ m_context = context.release();
+ m_contextID = editor.inputMethodContextID;
+
if (type == "password" || type == "plugin")
ecore_imf_context_prediction_allow_set(m_context.get(), false);
else
if (!m_context)
return;
+ if (m_contextList.size() >= maxContextSize)
+ m_contextList.remove(0);
+
PassOwnPtr<Ecore_IMF_Context> imfContext = m_context.release();
- int layout = ecore_imf_context_input_panel_layout_get(imfContext.get());
- m_contextList.add(layout, imfContext);
+ m_contextList.append(std::make_pair(m_contextID, imfContext));
+ m_contextID = 0;
}
void InputMethodContextEfl::resetIMFContext()
void InputMethodContextEfl::showIMFContext(const EditorState& editor)
{
- Ecore_IMF_Input_Panel_Layout layout = layoutType(editor.inputMethodHints);
-
- if (isShow() && layout == ecore_imf_context_input_panel_layout_get(m_context.get()))
+ if (isShow() && m_contextID == editor.inputMethodContextID)
return;
Ewk_Settings* settings = ewk_view_settings_get(m_viewImpl->view());
return;
}
- setIMFContext(layout, editor.inputMethodHints);
+ setIMFContext(editor);
if (!hasFocus) {
m_focused = true;
return false;
}
+void InputMethodContextEfl::removeIMFContext(uintptr_t contextID)
+{
+ if (m_contextID == contextID)
+ hideIMFContext();
+
+ takeContext(contextID);
+}
+
#endif
}
public:
static PassOwnPtr<InputMethodContextEfl> create(EwkViewImpl* viewImpl, Evas* canvas)
{
+#if ENABLE(TIZEN_ISF_PORT)
+ OwnPtr<Ecore_IMF_Context> context;
+#else
OwnPtr<Ecore_IMF_Context> context = createIMFContext(canvas);
if (!context)
return nullptr;
+#endif
return adoptPtr(new InputMethodContextEfl(viewImpl, context.release()));
}
void resetIMFContext();
void hideIMFContext();
bool isIMEPostion(int, int);
+ void removeIMFContext(uintptr_t);
#endif
private:
static void onIMFPreeditSequenceChanged(void* data, Ecore_IMF_Context*, void* eventInfo);
#if ENABLE(TIZEN_ISF_PORT)
- void initializeIMFContext(Ecore_IMF_Context*, Ecore_IMF_Input_Panel_Layout);
+ void initializeIMFContext(Ecore_IMF_Context*, Ecore_IMF_Input_Panel_Layout, int);
static void onIMFInputPanelStateChanged(void*, Ecore_IMF_Context*, int);
static void onIMFInputPanelGeometryChanged(void*, Ecore_IMF_Context*, int);
static Eina_Bool onIMFRetrieveSurrounding(void*, Ecore_IMF_Context*, char**, int*);
static void onIMFDeleteSurrounding(void*, Ecore_IMF_Context*, void*);
- Ecore_IMF_Input_Panel_Layout layoutType(const String&);
- void setIMFContext(Ecore_IMF_Input_Panel_Layout, const String&);
+ PassOwnPtr<Ecore_IMF_Context> takeContext(uintptr_t);
+ void setIMFContext(const EditorState&);
void revertIMFContext();
void showIMFContext(const EditorState&);
void destroyIMFContextList();
bool m_focused;
#if ENABLE(TIZEN_ISF_PORT)
- HashMap<int, OwnPtr<Ecore_IMF_Context> > m_contextList;
+ static const unsigned maxContextSize;
+
+ Vector<std::pair<uintptr_t, OwnPtr<Ecore_IMF_Context> > > m_contextList;
+ uintptr_t m_contextID;
bool m_useInputMethod;
int m_state;
WebCore::IntRect m_imeRect;
result.shouldIgnoreCompositionSelectionChange = frame->editor()->ignoreCompositionSelectionChange();
#if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION) || ENABLE(TIZEN_ISF_PORT)
- Element* selectionRoot = frame->selection()->rootEditableElementOrDocumentElement();
- if (!selectionRoot)
+ Element* rootEditableElement = frame->selection()->rootEditableElement();
+ if (!rootEditableElement)
return result;
- result.editorRect = frame->view()->contentsToWindow(selectionRoot->getPixelSnappedRect());
+ result.editorRect = frame->view()->contentsToWindow(rootEditableElement->getPixelSnappedRect());
if (result.editorRect.maxX() <= 0 || result.editorRect.maxY() <= 0)
result.isContentEditable = false;
#endif
#if ENABLE(TIZEN_ISF_PORT)
- Node* hostNode = selectionRoot->shadowAncestorNode();
- if (result.isContentEditable) {
+ if (!result.shouldIgnoreCompositionSelectionChange && result.isContentEditable) {
+ result.inputMethodContextID = reinterpret_cast<uintptr_t>(rootEditableElement);
+
+ Node* hostNode = rootEditableElement->shadowHost();
+ if (!hostNode)
+ hostNode = rootEditableElement;
+
HTMLTextFormControlElement* formControl = toTextFormControl(hostNode);
if (formControl) {
- result.inputMethodHints = formControl->type();
+ const AtomicString& type = formControl->type();
+
+ if (type == "number" && formControl->hasTagName(HTMLNames::inputTag)) {
+ StepRange stepRange = static_cast<HTMLInputElement*>(formControl)->createStepRange(RejectAny);
+ bool needsSigned = stepRange.minimum().isNegative();
+ bool needsDecimal = (stepRange.step().floor() != stepRange.step());
+
+ if (needsSigned && needsDecimal)
+ result.inputMethodHints = "signedDecimalNumber";
+ else if (needsSigned)
+ result.inputMethodHints = "signedNumber";
+ else if (needsDecimal)
+ result.inputMethodHints = "decimalNumber";
+ else
+ result.inputMethodHints = "number";
+ } else
+ result.inputMethodHints = type;
+
result.surroundingText = formControl->value();
}