diff options
author | George Mount <mount@google.com> | 2012-05-09 11:36:51 -0700 |
---|---|---|
committer | George Mount <mount@google.com> | 2012-05-14 11:24:49 -0700 |
commit | 406da428774aa12dbabb663814e0558942765133 (patch) | |
tree | 93b8f7d4f6daf1f26f159d22b920b868f3ebec03 /Source | |
parent | 768f585255d1754fce9009daa7c68eab4e1fc7d1 (diff) | |
download | external_webkit-406da428774aa12dbabb663814e0558942765133.zip external_webkit-406da428774aa12dbabb663814e0558942765133.tar.gz external_webkit-406da428774aa12dbabb663814e0558942765133.tar.bz2 |
Change selection to work with left/right instead of base/extent.
Bug 5859620
Use the LTR/RTL content of the text selection to determine
which handle is left and which is right. This simplifies
text selection logic slightly and helps make RTL text
selection handles work properly.
Framework Change: Ib88ed2327182ba5b47b3e41584cbe944d05c8ada
Change-Id: I3362c5034ce08ce1517a86882c13b78aff35fe3f
Diffstat (limited to 'Source')
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.cpp | 108 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.h | 13 | ||||
-rw-r--r-- | Source/WebKit/android/nav/SelectText.cpp | 14 | ||||
-rw-r--r-- | Source/WebKit/android/nav/SelectText.h | 24 | ||||
-rw-r--r-- | Source/WebKit/android/nav/WebView.cpp | 10 |
5 files changed, 68 insertions, 101 deletions
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 1fe4a1d..ede8b69 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -1550,10 +1550,46 @@ void WebViewCore::layerToAbsoluteOffset(const LayerAndroid* layer, IntPoint& off } } +void WebViewCore::setSelectionCaretInfo(SelectText* selectTextContainer, + const WebCore::Position& pos, const IntPoint& frameOffset, + SelectText::HandleId handleId, int offset, EAffinity affinity) +{ + Node* node = pos.anchorNode(); + LayerAndroid* layer = 0; + int layerId = platformLayerIdFromNode(node, &layer); + selectTextContainer->setCaretLayerId(handleId, layerId); + IntPoint layerOffset; + layerToAbsoluteOffset(layer, layerOffset); + RenderObject* r = node->renderer(); + RenderText* renderText = toRenderText(r); + int caretOffset; + InlineBox* inlineBox; + pos.getInlineBoxAndOffset(affinity, inlineBox, caretOffset); + IntRect caretRect = renderText->localCaretRect(inlineBox, caretOffset); + FloatPoint absoluteOffset = renderText->localToAbsolute(caretRect.location()); + caretRect.setX(absoluteOffset.x() - layerOffset.x() + offset); + caretRect.setY(absoluteOffset.y() - layerOffset.y()); + caretRect.move(-frameOffset.x(), -frameOffset.y()); + selectTextContainer->setCaretRect(handleId, caretRect); + selectTextContainer->setTextRect(handleId, + positionToTextRect(pos, affinity)); +} + +bool WebViewCore::isLtr(const Position& position) +{ + InlineBox* inlineBox = 0; + int caretOffset = 0; + position.getInlineBoxAndOffset(DOWNSTREAM, inlineBox, caretOffset); + bool isLtr; + if (inlineBox) + isLtr = inlineBox->isLeftToRightDirection(); + else + isLtr = position.primaryDirection() == LTR; + return isLtr; +} + 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 bool isCaret = selection.isCaret(); if (selection.isNone() || (!selection.isContentEditable() && isCaret)) return 0; @@ -1568,33 +1604,24 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) && range->startOffset() == range->endOffset()) return 0; - SelectText* selectTextContainer = new SelectText(); IntPoint frameOffset = convertGlobalContentToFrameContent(IntPoint()); - - IntRect startHandle; - IntRect endHandle; + SelectText* selectTextContainer = new SelectText(); if (isCaret) { - // Caret selection - Position start = selection.start(); - Node* node = start.anchorNode(); - LayerAndroid* layer = 0; - int layerId = platformLayerIdFromNode(node, &layer); - 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(selection.affinity(), 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; + setSelectionCaretInfo(selectTextContainer, selection.start(), frameOffset, + SelectText::LeftHandle, 0, selection.affinity()); + setSelectionCaretInfo(selectTextContainer, selection.start(), frameOffset, + SelectText::RightHandle, 0, selection.affinity()); } else { - // Selected range + bool ltr = isLtr(selection.start()); + Position left = ltr ? selection.start() : selection.end(); + Position right = ltr ? selection.end() : selection.start(); + int leftOffset = isLtr(left) ? 0 : -1; + int rightOffset = isLtr(right) ? 0 : -1; + setSelectionCaretInfo(selectTextContainer, left, frameOffset, + SelectText::LeftHandle, leftOffset, selection.affinity()); + setSelectionCaretInfo(selectTextContainer, right, frameOffset, + SelectText::RightHandle, rightOffset, selection.affinity()); + Node* stopNode = range->pastLastNode(); for (Node* node = range->firstNode(); node != stopNode; node = node->traverseNextNode()) { RenderObject* r = node->renderer(); @@ -1607,39 +1634,10 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) 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->setBaseFirst(selection.isBaseFirst()); - - // Squish the handle rects - startHandle.setWidth(1); - endHandle.move(endHandle.width() - 1, 0); - endHandle.setWidth(1); - startHandle.move(-frameOffset.x(), -frameOffset.y()); - selectTextContainer->setCaretRect(SelectText::StartHandle, startHandle); - endHandle.move(-frameOffset.x(), -frameOffset.y()); - selectTextContainer->setCaretRect(SelectText::EndHandle, endHandle); - selectTextContainer->setText(range->text()); - selectTextContainer->setTextRect(SelectText::StartHandle, - positionToTextRect(selection.start(), selection.affinity())); - selectTextContainer->setTextRect(SelectText::EndHandle, - positionToTextRect(selection.end(), selection.affinity())); - return selectTextContainer; } diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index c8b10d8..a3c1e7c 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -45,6 +45,7 @@ #include "WebRequestContext.h" #include "android_npapi.h" #include "VisiblePosition.h" +#include "SelectText.h" #include <jni.h> #include <androidfw/KeycodeLabels.h> @@ -105,7 +106,6 @@ namespace android { class ListBoxReply; class AndroidHitTestResult; - class SelectText; class WebCoreReply : public WebCoreRefObject { public: @@ -590,11 +590,6 @@ namespace android { static void layerToAbsoluteOffset(const WebCore::LayerAndroid* layer, WebCore::IntPoint& offset); - /** - * Returns a text position at a given coordinate. - */ - WebCore::VisiblePosition visiblePositionForWindowPoint(int x, int y); - // Retrieves the current locale from system properties void getLocale(String& language, WTF::String& region); @@ -730,6 +725,11 @@ namespace android { bool selectWordAroundPosition(WebCore::Frame* frame, WebCore::VisiblePosition pos); SelectText* createSelectText(const WebCore::VisibleSelection&); + void setSelectionCaretInfo(SelectText* selectTextContainer, + const WebCore::Position& position, + const WebCore::IntPoint& frameOffset, + SelectText::HandleId handleId, int offset, + EAffinity affinity); static int getMaxLength(WebCore::Node* node); static WTF::String getFieldName(WebCore::Node* node); static bool isAutoCompleteEnabled(WebCore::Node* node); @@ -737,6 +737,7 @@ namespace android { WebCore::LayerAndroid* layer); static WebCore::IntRect positionToTextRect(const WebCore::Position& position, WebCore::EAffinity affinity); + static bool isLtr(const WebCore::Position& position); // called from constructor, to add this to a global list static void addInstance(WebViewCore*); diff --git a/Source/WebKit/android/nav/SelectText.cpp b/Source/WebKit/android/nav/SelectText.cpp index 22c67bc..7ce32c3 100644 --- a/Source/WebKit/android/nav/SelectText.cpp +++ b/Source/WebKit/android/nav/SelectText.cpp @@ -144,17 +144,3 @@ void ReverseBidi(UChar* chars, int len) { } -namespace android { - -SelectText::HandleId SelectText::mapId(HandleId id) -{ - if (id == StartHandle || id == EndHandle) - return id; - if (isBaseFirst()) - return (HandleId) (id - 2); - if (id == BaseHandle) - return EndHandle; - return StartHandle; -} - -} diff --git a/Source/WebKit/android/nav/SelectText.h b/Source/WebKit/android/nav/SelectText.h index 50bc82e..aaaf3bb 100644 --- a/Source/WebKit/android/nav/SelectText.h +++ b/Source/WebKit/android/nav/SelectText.h @@ -35,32 +35,24 @@ namespace android { class SelectText : public RegionLayerDrawExtra { public: enum HandleId { - StartHandle = 0, - EndHandle = 1, - BaseHandle = 2, - ExtentHandle = 3, + LeftHandle = 0, + RightHandle = 1, }; - IntRect& caretRect(HandleId id) { return m_caretRects[mapId(id)]; } - void setCaretRect(HandleId id, const IntRect& rect) { m_caretRects[mapId(id)] = rect; } - IntRect& textRect(HandleId id) { return m_textRects[mapId(id)]; } - void setTextRect(HandleId id, const IntRect& rect) { m_textRects[mapId(id)] = rect; } - int caretLayerId(HandleId id) { return m_caretLayerId[mapId(id)]; } - void setCaretLayerId(HandleId id, int layerId) { m_caretLayerId[mapId(id)] = layerId; } - - bool isBaseFirst() const { return m_baseIsFirst; } - void setBaseFirst(bool isFirst) { m_baseIsFirst = isFirst; } + IntRect& caretRect(HandleId id) { return m_caretRects[id]; } + void setCaretRect(HandleId id, const IntRect& rect) { m_caretRects[id] = rect; } + IntRect& textRect(HandleId id) { return m_textRects[id]; } + void setTextRect(HandleId id, const IntRect& rect) { m_textRects[id] = rect; } + int caretLayerId(HandleId id) { return m_caretLayerId[id]; } + void setCaretLayerId(HandleId id, int layerId) { m_caretLayerId[id] = layerId; } void setText(const String& text) { m_text = text.threadsafeCopy(); } String& getText() { return m_text; } private: - HandleId mapId(HandleId id); - IntRect m_caretRects[2]; IntRect m_textRects[2]; int m_caretLayerId[2]; - bool m_baseIsFirst; String m_text; }; diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index a78392b..09e808b 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -1199,14 +1199,6 @@ static jint nativeGetHandleLayerId(JNIEnv *env, jobject obj, jint nativeView, return layerId; } -static jboolean nativeIsBaseFirst(JNIEnv *env, jobject obj, jint nativeView) -{ - WebView* webview = reinterpret_cast<WebView*>(nativeView); - SelectText* select = static_cast<SelectText*>( - webview->getDrawExtra(WebView::DrawExtrasSelection)); - return select ? select->isBaseFirst() : false; -} - static void nativeMapLayerRect(JNIEnv *env, jobject obj, jint nativeView, jint layerId, jobject rect) { @@ -1298,8 +1290,6 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeSetTextSelection }, { "nativeGetHandleLayerId", "(IILandroid/graphics/Point;Landroid/webkit/QuadF;)I", (void*) nativeGetHandleLayerId }, - { "nativeIsBaseFirst", "(I)Z", - (void*) nativeIsBaseFirst }, { "nativeMapLayerRect", "(IILandroid/graphics/Rect;)V", (void*) nativeMapLayerRect }, { "nativeSetHwAccelerated", "(IZ)I", |