summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/android
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/android')
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp143
-rw-r--r--Source/WebKit/android/jni/WebViewCore.h25
2 files changed, 137 insertions, 31 deletions
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index 1c8d0d0..0030621 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -80,6 +80,7 @@
#include "HitTestRequest.h"
#include "HitTestResult.h"
#include "InlineTextBox.h"
+#include "KeyboardEvent.h"
#include "MemoryUsage.h"
#include "NamedNodeMap.h"
#include "Navigator.h"
@@ -441,7 +442,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
#endif
m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V");
m_javaGlue->m_selectAt = GetJMethod(env, clazz, "selectAt", "(II)V");
- m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(ILjava/lang/String;II)V");
+ m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(ILjava/lang/String;IZZLjava/lang/String;III)V");
m_javaGlue->m_updateMatchCount = GetJMethod(env, clazz, "updateMatchCount", "(IILjava/lang/String;)V");
env->DeleteLocalRef(clazz);
@@ -534,7 +535,7 @@ CacheBuilder& WebViewCore::cacheBuilder()
WebCore::Node* WebViewCore::currentFocus()
{
- return m_mainFrame->document()->focusedNode();
+ return focusedFrame()->document()->focusedNode();
}
void WebViewCore::recordPicture(SkPicture* picture)
@@ -1752,7 +1753,8 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
{
// We need to agressively check to see if this is an empty selection to prevent
// accidentally entering text selection mode
- if (!selection.isRange() || !comparePositions(selection.start(), selection.end()))
+ bool isCaret = selection.isCaret();
+ if (selection.isNone() || (!selection.isContentEditable() && isCaret))
return 0;
RefPtr<Range> range = selection.firstRange();
@@ -1761,7 +1763,8 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
if (!startContainer || !endContainer)
return 0;
- if (startContainer == endContainer && range->startOffset() == range->endOffset())
+ if (!isCaret && startContainer == endContainer
+ && range->startOffset() == range->endOffset())
return 0;
SelectText* selectTextContainer = new SelectText();
@@ -1769,35 +1772,56 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
IntRect startHandle;
IntRect endHandle;
- Node* stopNode = range->pastLastNode();
- for (Node* node = range->firstNode(); node != stopNode; node = node->traverseNextNode()) {
- RenderObject* r = node->renderer();
- if (!r || !r->isText() || r->style()->visibility() != VISIBLE)
- continue;
- RenderText* renderText = toRenderText(r);
- int startOffset = node == startContainer ? range->startOffset() : 0;
- int endOffset = node == endContainer ? range->endOffset() : numeric_limits<int>::max();
+ if (isCaret) {
+ // Caret selection
+ Position start = selection.start();
+ Node* node = start.anchorNode();
LayerAndroid* layer = 0;
int layerId = platformLayerIdFromNode(node, &layer);
- Vector<IntRect> rects;
- renderText->absoluteRectsForRange(rects, startOffset, endOffset, true);
- if (rects.size()) {
- IntPoint offset;
- layerToAbsoluteOffset(layer, offset);
- endHandle = rects[rects.size() - 1];
- endHandle.move(-offset.x(), -offset.y());
- selectTextContainer->setCaretLayerId(SelectText::EndHandle, layerId);
- if (startHandle.isEmpty()) {
- startHandle = rects[0];
- startHandle.move(-offset.x(), -offset.y());
- selectTextContainer->setCaretLayerId(SelectText::StartHandle, layerId);
+ selectTextContainer->setCaretLayerId(SelectText::EndHandle, layerId);
+ selectTextContainer->setCaretLayerId(SelectText::StartHandle, layerId);
+ IntPoint layerOffset;
+ layerToAbsoluteOffset(layer, layerOffset);
+ RenderObject* r = node->renderer();
+ RenderText* renderText = toRenderText(r);
+ int caretOffset;
+ InlineBox* inlineBox;
+ start.getInlineBoxAndOffset(DOWNSTREAM, inlineBox, caretOffset);
+ startHandle = renderText->localCaretRect(inlineBox, caretOffset);
+ FloatPoint absoluteOffset = renderText->localToAbsolute(startHandle.location());
+ startHandle.setX(absoluteOffset.x() - layerOffset.x());
+ startHandle.setY(absoluteOffset.y() - layerOffset.y());
+ endHandle = startHandle;
+ } else {
+ // Selected range
+ Node* stopNode = range->pastLastNode();
+ for (Node* node = range->firstNode(); node != stopNode; node = node->traverseNextNode()) {
+ RenderObject* r = node->renderer();
+ if (!r || !r->isText() || r->style()->visibility() != VISIBLE)
+ continue;
+ RenderText* renderText = toRenderText(r);
+ int startOffset = node == startContainer ? range->startOffset() : 0;
+ int endOffset = node == endContainer ? range->endOffset() : numeric_limits<int>::max();
+ LayerAndroid* layer = 0;
+ int layerId = platformLayerIdFromNode(node, &layer);
+ Vector<IntRect> rects;
+ renderText->absoluteRectsForRange(rects, startOffset, endOffset, true);
+ if (rects.size()) {
+ IntPoint offset;
+ layerToAbsoluteOffset(layer, offset);
+ endHandle = rects[rects.size() - 1];
+ endHandle.move(-offset.x(), -offset.y());
+ selectTextContainer->setCaretLayerId(SelectText::EndHandle, layerId);
+ if (startHandle.isEmpty()) {
+ startHandle = rects[0];
+ startHandle.move(-offset.x(), -offset.y());
+ selectTextContainer->setCaretLayerId(SelectText::StartHandle, layerId);
+ }
}
+ selectTextContainer->addHighlightRegion(layer, rects, frameOffset);
}
- selectTextContainer->addHighlightRegion(layer, rects, frameOffset);
}
- IntRect caretRect;
- int layerId;
selectTextContainer->setBaseFirst(selection.isBaseFirst());
// Squish the handle rects
@@ -1830,7 +1854,7 @@ void WebViewCore::selectText(int startX, int startY, int endX, int endY)
IntPoint endPoint = convertGlobalContentToFrameContent(IntPoint(endX, endY));
VisiblePosition endPosition(visiblePositionForContentPoint(endPoint));
- if (startPosition.isNull() || endPosition.isNull() || startPosition == endPosition)
+ if (startPosition.isNull() || endPosition.isNull())
return;
// Ensure startPosition is before endPosition
@@ -1859,7 +1883,9 @@ void WebViewCore::selectText(int startX, int startY, int endX, int endY)
}
VisibleSelection selection(startPosition, endPosition);
- if (selection.isRange() && sc->shouldChangeSelection(selection))
+ // Only allow changes between caret positions or to text selection.
+ bool selectChangeAllowed = (!selection.isCaret() || sc->isCaret());
+ if (selectChangeAllowed && sc->shouldChangeSelection(selection))
sc->setSelection(selection);
}
@@ -3500,6 +3526,46 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
return handled;
}
+WebViewCore::InputType WebViewCore::getInputType(Node* node)
+{
+ WebCore::RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return WebViewCore::NONE;
+ if (renderer->isTextArea())
+ return WebViewCore::TEXT_AREA;
+
+ if (node->hasTagName(WebCore::HTMLNames::inputTag)) {
+ HTMLInputElement* htmlInput = static_cast<HTMLInputElement*>(node);
+ if (htmlInput->isPasswordField())
+ return WebViewCore::PASSWORD;
+ if (htmlInput->isSearchField())
+ return WebViewCore::SEARCH;
+ if (htmlInput->isEmailField())
+ return WebViewCore::EMAIL;
+ if (htmlInput->isNumberField())
+ return WebViewCore::NUMBER;
+ if (htmlInput->isTelephoneField())
+ return WebViewCore::TELEPHONE;
+ if (htmlInput->isTextField())
+ return WebViewCore::NORMAL_TEXT_FIELD;
+ }
+
+ if (node->isContentEditable())
+ return WebViewCore::TEXT_AREA;
+
+ return WebViewCore::NONE;
+}
+
+bool WebViewCore::isSpellCheckEnabled(Node* node)
+{
+ bool isEnabled = true;
+ if (node->isElementNode()) {
+ WebCore::Element* element = static_cast<WebCore::Element*>(node);
+ isEnabled = element->isSpellCheckingEnabled();
+ }
+ return isEnabled;
+}
+
void WebViewCore::initEditField(Node* node)
{
String text = getInputText(node);
@@ -3511,9 +3577,22 @@ void WebViewCore::initEditField(Node* node)
if (!javaObject.get())
return;
m_textGeneration = 0;
+ InputType inputType = getInputType(node);
+ Document* document = node->document();
+ PlatformKeyboardEvent tab(AKEYCODE_TAB, 0, 0, false, false, false, false);
+ PassRefPtr<KeyboardEvent> tabEvent =
+ KeyboardEvent::create(tab, document->defaultView());
+ Node* nextFocus = document->nextFocusableNode(node, tabEvent.get());
+ bool isNextText = isTextInput(nextFocus);
+ bool spellCheckEnabled = isSpellCheckEnabled(node);
+ String label = requestLabel(document->frame(), node);
jstring fieldText = wtfStringToJstring(env, text, true);
+ jstring labelText = wtfStringToJstring(env, text, false);
+ SelectText* selectText = createSelectText(focusedFrame()->selection()->selection());
env->CallVoidMethod(javaObject.get(), m_javaGlue->m_initEditField,
- reinterpret_cast<int>(node), fieldText, start, end);
+ reinterpret_cast<int>(node), fieldText, inputType,
+ spellCheckEnabled, isNextText, labelText, start, end,
+ reinterpret_cast<int>(selectText));
checkException(env);
}
@@ -3868,7 +3947,7 @@ void WebViewCore::updateTextSelection()
SelectText* selectText = createSelectText(focusedFrame()->selection()->selection());
env->CallVoidMethod(javaObject.get(),
m_javaGlue->m_updateTextSelection, reinterpret_cast<int>(focusNode),
- start, end, m_textGeneration, selectText);
+ start, end, m_textGeneration, reinterpret_cast<int>(selectText));
checkException(env);
}
@@ -4354,6 +4433,8 @@ void WebViewCore::findNextOnPage(bool forward)
m_activeMatch = selection.firstRange();
m_mainFrame->document()->markers()->setMarkersActive(
m_activeMatch.get(), true);
+ m_mainFrame->selection()->revealSelection(
+ ScrollAlignment::alignCenterIfNeeded, true);
}
updateMatchCount();
}
diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h
index 0532742..38bde58 100644
--- a/Source/WebKit/android/jni/WebViewCore.h
+++ b/Source/WebKit/android/jni/WebViewCore.h
@@ -639,6 +639,18 @@ namespace android {
// internal functions
private:
+ enum InputType {
+ NONE = -1,
+ NORMAL_TEXT_FIELD = 0,
+ TEXT_AREA = 1,
+ PASSWORD = 2,
+ SEARCH = 3,
+ EMAIL = 4,
+ NUMBER = 5,
+ TELEPHONE = 6,
+ URL = 7,
+ };
+
#ifndef DISABLE_NAVCACHE
CacheBuilder& cacheBuilder();
#endif
@@ -684,6 +696,19 @@ namespace android {
* current contents and selection.
*/
void initEditField(Node* node);
+
+ /**
+ * Gets the input type a Node. NONE is returned if it isn't an
+ * input field.
+ */
+ InputType getInputType(Node* node);
+
+ /**
+ * If node is an input field, the spellcheck value for the
+ * field is returned. Otherwise true is returned.
+ */
+ static bool isSpellCheckEnabled(Node* node);
+
/**
* Returns the offsets of the selection area for both normal text
* fields and content editable fields. start and end are modified