summaryrefslogtreecommitdiffstats
path: root/WebKit/android/nav
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android/nav')
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp215
-rw-r--r--WebKit/android/nav/CacheBuilder.h39
-rw-r--r--WebKit/android/nav/CachedDebug.h23
-rw-r--r--WebKit/android/nav/CachedFrame.cpp76
-rw-r--r--WebKit/android/nav/CachedFrame.h11
-rw-r--r--WebKit/android/nav/CachedHistory.cpp2
-rw-r--r--WebKit/android/nav/CachedHistory.h2
-rw-r--r--WebKit/android/nav/CachedInput.cpp68
-rw-r--r--WebKit/android/nav/CachedInput.h79
-rw-r--r--WebKit/android/nav/CachedNode.cpp60
-rw-r--r--WebKit/android/nav/CachedNode.h69
-rw-r--r--WebKit/android/nav/CachedNodeType.h25
-rw-r--r--WebKit/android/nav/CachedPrefix.h2
-rw-r--r--WebKit/android/nav/CachedRoot.cpp36
-rw-r--r--WebKit/android/nav/CachedRoot.h9
-rw-r--r--WebKit/android/nav/FindCanvas.cpp2
-rw-r--r--WebKit/android/nav/FindCanvas.h3
-rw-r--r--WebKit/android/nav/SelectText.cpp91
-rw-r--r--WebKit/android/nav/SelectText.h6
-rw-r--r--WebKit/android/nav/WebView.cpp672
20 files changed, 888 insertions, 602 deletions
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index 4acf598..784c3aa 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -42,6 +42,7 @@
#include "HTMLNames.h"
#include "HTMLOptionElement.h"
#include "HTMLSelectElement.h"
+#include "HTMLTextAreaElement.h"
#include "InlineTextBox.h"
#include "KURL.h"
#include "PluginView.h"
@@ -93,14 +94,11 @@ Frame* CacheBuilder::FrameAnd(const CacheBuilder* cacheBuilder) {
#if DUMP_NAV_CACHE
static bool hasEventListener(Node* node, const AtomicString& eventType) {
- const RegisteredEventListenerVector& listeners = node->eventListeners();
- size_t size = listeners.size();
- for (size_t i = 0; i < size; ++i) {
- const RegisteredEventListener& r = *listeners[i];
- if (r.eventType() == eventType)
- return true;
- }
- return false;
+ if (!node->isElementNode())
+ return false;
+ Element* element = static_cast<Element*>(node);
+ EventListener* listener = element->getAttributeEventListener(eventType);
+ return 0 != listener;
}
#define DEBUG_BUFFER_SIZE 256
@@ -143,7 +141,9 @@ void CacheBuilder::Debug::flush() {
break;
len++;
}
- while (mBuffer[len] == '\\' || mBuffer[len] == '"')
+ while (len > 0 && mBuffer[len - 1] == '\\')
+ len--;
+ while (mBuffer[len] == '"')
len++;
}
const char* prefix = mPrefix;
@@ -349,8 +349,11 @@ void CacheBuilder::Debug::groups() {
} while ((node = node->traverseNextNode()) != NULL);
int focusIndex = -1;
if (atLeastOne == false) {
- DUMP_NAV_LOGD("#define TEST%s_RECTS NULL\n", name);
- DUMP_NAV_LOGD("static int TEST%s_RECT_COUNT = 0; // no focusable nodes\n", name);
+ DUMP_NAV_LOGD("static DebugTestNode TEST%s_RECTS[] = {\n"
+ "{{0, 0, 0, 0}, \"\", 0, -1, \"\", {0, 0, 0, 0}, false, 0}\n"
+ "};\n\n", name);
+ DUMP_NAV_LOGD("static int TEST%s_RECT_COUNT = 1;"
+ " // no focusable nodes\n", name);
DUMP_NAV_LOGD("#define TEST%s_RECTPARTS NULL\n", name);
} else {
node = doc;
@@ -435,6 +438,7 @@ void CacheBuilder::Debug::groups() {
snprintf(scratch, sizeof(scratch), ", {%d, %d, %d, %d}, %s"
", %d},",absB.x(), absB.y(), absB.width(), absB.height(),
renderer->hasOverflowClip() ? "true" : "false", tabindex);
+ // TODO: add renderer->style()->visibility()
print(scratch);
} else
print(", {0, 0, 0, 0}, false, 0},");
@@ -547,7 +551,7 @@ void CacheBuilder::Debug::groups() {
int contentsHeight = layer->height();
DUMP_NAV_LOGD("static int TEST%s_FOCUS = %d;\n", name, focusIndex);
DUMP_NAV_LOGD("static int TEST%s_WIDTH = %d;\n", name, contentsWidth);
- DUMP_NAV_LOGD("static int TEST%s_HEIGHT = %d;\n", name, contentsHeight);
+ DUMP_NAV_LOGD("static int TEST%s_HEIGHT = %d;\n\n", name, contentsHeight);
}
bool CacheBuilder::Debug::isFocusable(Node* node) {
@@ -721,7 +725,7 @@ void CacheBuilder::Debug::wideString(const String& str) {
CacheBuilder::CacheBuilder()
{
- mAllowableTypes = ALL_CACHEDNODETYPES;
+ mAllowableTypes = ALL_CACHEDNODE_BITS;
#ifdef DUMP_NAV_CACHE_USING_PRINTF
gNavCacheLogFile = NULL;
#endif
@@ -756,14 +760,9 @@ void CacheBuilder::adjustForColumns(const ClipColumnTracker& track,
// Checks if a node has one of event listener types.
bool CacheBuilder::NodeHasEventListeners(Node* node, AtomicString* eventTypes, int length) {
- const RegisteredEventListenerVector& listeners = node->eventListeners();
- size_t size = listeners.size();
- for (size_t i = 0; i < size; ++i) {
- const RegisteredEventListener& r = *listeners[i];
- for (int j = 0; j < length; ++j) {
- if (r.eventType() == eventTypes[j])
- return true;
- }
+ for (int i = 0; i < length; ++i) {
+ if (!node->getEventListeners(eventTypes[i]).isEmpty())
+ return true;
}
return false;
}
@@ -825,6 +824,16 @@ void CacheBuilder::buildCache(CachedRoot* root)
setData((CachedFrame*) root);
}
+static Node* ParentWithChildren(Node* node)
+{
+ Node* parent = node;
+ while ((parent = parent->parentNode())) {
+ if (parent->childNodeCount() > 1)
+ return parent;
+ }
+ return 0;
+}
+
static Node* OneAfter(Node* node)
{
Node* parent = node;
@@ -900,6 +909,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
cachedFrame->add(cachedParentNode);
Node* node = parent;
int cacheIndex = 1;
+ int textInputIndex = 0;
Node* focused = doc->focusedNode();
if (focused)
cachedRoot->setFocusBounds(focused->getRect());
@@ -918,8 +928,6 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
lastChildIndex = last->mCachedNodeIndex;
last = &tracker.last();
}
- if (node == last->mParentLastChild)
- last->mParentLastChild = NULL;
do {
const ClipColumnTracker* lastClip = &clipTracker.last();
if (node != lastClip->mLastChild)
@@ -946,7 +954,8 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
cachedFrame->addFrame(cachedChild);
cachedNode.init(node);
cachedNode.setIndex(cacheIndex++);
- cachedNode.setChildFrameIndex(childFrameIndex);
+ cachedNode.setDataIndex(childFrameIndex);
+ cachedNode.setType(FRAME_CACHEDNODETYPE);
#if DUMP_NAV_CACHE
cachedNode.mDebug.mNodeIndex = nodeIndex;
cachedNode.mDebug.mParentGroupIndex = Debug::ParentIndex(
@@ -986,29 +995,23 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
bool computeCursorRings = false;
bool hasClip = false;
bool hasMouseOver = false;
- bool isAnchor = false;
- bool isArea = node->hasTagName(HTMLNames::areaTag);
- bool isPassword = false;
- bool isTextArea = false;
- bool isTextField = false;
- bool isRtlText = false;
bool isUnclipped = false;
bool isFocus = node == focused;
bool takesFocus = false;
- bool wantsKeyEvents = false;
- int maxLength = -1;
- int textSize = 12;
int columnGap = 0;
TextDirection direction = LTR;
- String name;
String exported;
CachedNodeType type = NORMAL_CACHEDNODETYPE;
+ CachedInput cachedInput;
IntRect bounds;
IntRect absBounds;
+ IntRect originalAbsBounds;
WTF::Vector<IntRect>* columns = NULL;
- if (isArea) {
+ if (node->hasTagName(HTMLNames::areaTag)) {
+ type = AREA_CACHEDNODETYPE;
HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node);
bounds = getAreaRect(area);
+ originalAbsBounds = bounds;
bounds.move(globalOffsetX, globalOffsetY);
absBounds = bounds;
isUnclipped = true; // FIXME: areamaps require more effort to detect
@@ -1021,6 +1024,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
// some common setup
absBounds = nodeRenderer->absoluteBoundingBoxRect();
+ originalAbsBounds = absBounds;
absBounds.move(globalOffsetX, globalOffsetY);
hasClip = nodeRenderer->hasOverflowClip();
@@ -1028,7 +1032,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
bounds = absBounds;
isUnclipped = true;
takesFocus = true;
- wantsKeyEvents = true;
+ type = PLUGIN_CACHEDNODETYPE;
goto keepNode;
}
if (nodeRenderer->isRenderBlock()) {
@@ -1052,11 +1056,11 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
clip.mHasClip = hasClip;
clip.mDirection = direction;
if (columns != NULL) {
- const IntRect& oRect = ((RenderBox*)nodeRenderer)->overflowRect(true);
+ const IntRect& oRect = ((RenderBox*)nodeRenderer)->visibleOverflowRect();
clip.mBounds.move(oRect.x(), oRect.y());
}
}
- if (node->isTextNode() && mAllowableTypes != NORMAL_CACHEDNODETYPE) {
+ if (node->isTextNode() && mAllowableTypes != NORMAL_CACHEDNODE_BITS) {
if (last->mSomeParentTakesFocus) // don't look at text inside focusable node
continue;
CachedNodeType checkType;
@@ -1072,7 +1076,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
DUMP_NAV_LOGD("%s\n", buffer);
}
#endif
- type = (CachedNodeType) checkType;
+ type = checkType;
// !!! test ! is the following line correctly needed for frames to work?
cachedNode.init(node);
const ClipColumnTracker& clipTrack = clipTracker.last();
@@ -1095,19 +1099,34 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
goto keepTextNode;
}
if (node->hasTagName(WebCore::HTMLNames::inputTag)) {
- HTMLInputElement* input = (HTMLInputElement*) node;
- if (input->inputType() == HTMLInputElement::FILE)
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
+ HTMLInputElement::InputType inputType = input->inputType();
+ if (input->isTextField()) {
+ type = TEXT_INPUT_CACHEDNODETYPE;
+ cachedInput.init();
+ cachedInput.setFormPointer(input->form());
+ cachedInput.setIsTextField(true);
+ exported = input->value().threadsafeCopy();
+ cachedInput.setMaxLength(input->maxLength());
+ cachedInput.setInputType(inputType);
+ // If this does not need to be threadsafe, we can use crossThreadString().
+ // See http://trac.webkit.org/changeset/49160.
+ cachedInput.setName(input->name().string().threadsafeCopy());
+ // can't detect if this is drawn on top (example: deviant.com login parts)
+ isUnclipped = isTransparent;
+ } else if (inputType == HTMLInputElement::HIDDEN)
continue;
- isTextField = input->isTextField();
- if (isTextField)
- wantsKeyEvents = true;
- isPassword = input->inputType() == HTMLInputElement::PASSWORD;
- maxLength = input->maxLength();
- name = input->name().string().copy();
- isUnclipped = isTransparent; // can't detect if this is drawn on top (example: deviant.com login parts)
- } else if (node->hasTagName(HTMLNames::textareaTag))
- isTextArea = wantsKeyEvents = true;
- else if (node->hasTagName(HTMLNames::aTag)) {
+ } else if (node->hasTagName(HTMLNames::textareaTag)) {
+ cachedInput.init();
+ type = TEXT_INPUT_CACHEDNODETYPE;
+ HTMLTextAreaElement* area = static_cast<HTMLTextAreaElement*>(node);
+ cachedInput.setFormPointer(area->form());
+ // Although technically it is not an HTMLInputElement, and therefore
+ // has no InputType, this one is the most appropriate.
+ cachedInput.setInputType(HTMLInputElement::TEXT);
+ cachedInput.setIsTextField(false);
+ exported = area->value().threadsafeCopy();
+ } else if (node->hasTagName(HTMLNames::aTag)) {
const HTMLAnchorElement* anchorNode =
(const HTMLAnchorElement*) node;
if (!anchorNode->isFocusable() && !HasTriggerEvent(node))
@@ -1115,32 +1134,31 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
if (node->disabled())
continue;
hasMouseOver = NodeHasEventListeners(node, &eventNames().mouseoverEvent, 1);
- isAnchor = true;
+ type = ANCHOR_CACHEDNODETYPE;
KURL href = anchorNode->href();
if (!href.isEmpty() && !WebCore::protocolIsJavaScript(href.string()))
// Set the exported string for all non-javascript anchors.
- exported = href.string().copy();
+ exported = href.string().threadsafeCopy();
}
- if (isTextField || isTextArea) {
+ if (type == TEXT_INPUT_CACHEDNODETYPE) {
RenderTextControl* renderText =
static_cast<RenderTextControl*>(nodeRenderer);
if (isFocus)
cachedRoot->setSelection(renderText->selectionStart(), renderText->selectionEnd());
- exported = renderText->text().copy();
// FIXME: Would it be better to use (float) size()?
// FIXME: Are we sure there will always be a style and font, and it's correct?
RenderStyle* style = nodeRenderer->style();
if (style) {
isUnclipped |= !style->hasAppearance();
- textSize = style->fontSize();
- isRtlText = style->direction() == RTL ||
- style->textAlign() == WebCore::RIGHT ||
- style->textAlign() == WebCore::WEBKIT_RIGHT;
+ cachedInput.setTextSize(style->fontSize());
+ cachedInput.setIsRtlText(style->direction() == RTL
+ || style->textAlign() == WebCore::RIGHT
+ || style->textAlign() == WebCore::WEBKIT_RIGHT);
}
}
takesFocus = true;
bounds = absBounds;
- if (!isAnchor) {
+ if (type != ANCHOR_CACHEDNODETYPE) {
bool isFocusable = node->isKeyboardFocusable(NULL) ||
node->isMouseFocusable() || node->isFocusable();
if (isFocusable == false) {
@@ -1174,43 +1192,38 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
continue;
}
const IntRect& parentClip = clipTrack.mBounds;
- if (hasClip == false && isAnchor)
+ if (hasClip == false && type == ANCHOR_CACHEDNODETYPE)
clip = parentClip;
else
clip.intersect(parentClip);
hasClip = true;
}
- if (hasClip && !clip.isEmpty() && cachedNode.clip(clip) == false) {
- cachedNode.setBounds(clip);
- cachedNode.cursorRings().append(clip);
- isUnclipped = true;
+ if (hasClip) {
+ if (clip.isEmpty())
+ continue; // skip this node if clip prevents all drawing
+ else if (cachedNode.clip(clip) == false)
+ continue; // skip this node if outside of the clip
}
cachedNode.setNavableRects();
- cachedNode.setChildFrameIndex(-1);
cachedNode.setExport(exported);
cachedNode.setHasCursorRing(hasCursorRing);
cachedNode.setHasMouseOver(hasMouseOver);
cachedNode.setHitBounds(absBounds);
cachedNode.setIndex(cacheIndex);
- cachedNode.setIsAnchor(isAnchor);
- cachedNode.setIsArea(isArea);
cachedNode.setIsFocus(isFocus);
- cachedNode.setIsPassword(isPassword);
- cachedNode.setIsRtlText(isRtlText);
- cachedNode.setIsTextArea(isTextArea);
- cachedNode.setIsTextField(isTextField);
cachedNode.setIsTransparent(isTransparent);
cachedNode.setIsUnclipped(isUnclipped);
- cachedNode.setMaxLength(maxLength);
- cachedNode.setName(name);
+ cachedNode.setOriginalAbsoluteBounds(originalAbsBounds);
cachedNode.setParentIndex(last->mCachedNodeIndex);
- if (last->mParentLastChild == NULL)
- last->mParentLastChild = OneAfter(node->parentNode()->lastChild());
- cachedNode.setParentGroup(last->mParentLastChild);
+ cachedNode.setParentGroup(ParentWithChildren(node));
cachedNode.setTabIndex(tabIndex);
- cachedNode.setTextSize(textSize);
cachedNode.setType(type);
- cachedNode.setWantsKeyEvents(wantsKeyEvents);
+ if (type == TEXT_INPUT_CACHEDNODETYPE) {
+ cachedFrame->add(cachedInput);
+ cachedNode.setDataIndex(textInputIndex);
+ textInputIndex++;
+ } else
+ cachedNode.setDataIndex(-1);
#if DUMP_NAV_CACHE
cachedNode.mDebug.mNodeIndex = nodeIndex;
cachedNode.mDebug.mParentGroupIndex = Debug::ParentIndex(
@@ -1228,7 +1241,6 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
Tracker& working = tracker.last();
working.mCachedNodeIndex = lastIndex;
working.mLastChild = OneAfter(lastChild);
- working.mParentLastChild = OneAfter(node->parentNode()->lastChild());
last = &tracker.at(tracker.size() - 2);
working.mSomeParentTakesFocus = last->mSomeParentTakesFocus | takesFocus;
}
@@ -1672,9 +1684,7 @@ CacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars
// is that suggested this fix.
// if (s->mWordCount == 0 && s->mContinuationNode)
// return FOUND_NONE;
- s->mBases[s->mWordCount] = baseChars;
- s->mWords[s->mWordCount] = chars - s->mNumberCount;
- s->mStarts[s->mWordCount] = s->mCurrentStart;
+ s->newWord(baseChars, chars);
if (WTF::isASCIILower(ch) && s->mNumberCount == 0)
s->mFirstLower = chars;
s->mNumberCount = 0;
@@ -1722,9 +1732,7 @@ CacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars
s->mNumberWords >>= ++shift;
if (s->mBases[0] != s->mBases[shift]) // if we're past the original node, bail
break;
- memmove(s->mBases, &s->mBases[shift], (sizeof(s->mBases) / sizeof(s->mBases[0]) - shift) * sizeof(s->mBases[0]));
- memmove(s->mWords, &s->mWords[shift], (sizeof(s->mWords) / sizeof(s->mWords[0]) - shift) * sizeof(s->mWords[0]));
- memmove(s->mStarts, &s->mStarts[shift], (sizeof(s->mStarts) / sizeof(s->mStarts[0]) - shift) * sizeof(s->mStarts[0]));
+ s->shiftWords(shift);
s->mStartResult = s->mWords[0] - s->mStarts[0];
s->mWordCount -= shift;
// FIXME: need to adjust lineCount to account for discarded delimiters
@@ -1771,9 +1779,7 @@ CacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars
continue;
if (s->mWordCount == 0 && s->mContinuationNode)
return FOUND_NONE;
- s->mBases[s->mWordCount] = baseChars;
- s->mWords[s->mWordCount] = chars;
- s->mStarts[s->mWordCount] = s->mCurrentStart;
+ s->newWord(baseChars, chars);
s->mNumberWords |= 1 << s->mWordCount;
s->mUnparsed = true;
}
@@ -1796,9 +1802,7 @@ CacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars
case SECOND_HALF:
if (WTF::isASCIIAlpha(ch)) {
if (s->mLetterCount == 0) {
- s->mBases[s->mWordCount] = baseChars;
- s->mWords[s->mWordCount] = chars;
- s->mStarts[s->mWordCount] = s->mCurrentStart;
+ s->newWord(baseChars, chars);
s->mWordCount++;
}
s->mLetterCount++;
@@ -1917,9 +1921,7 @@ CacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars
s->mZipDelimiter = true;
else {
if (s->mLetterCount == 0) {
- s->mBases[s->mWordCount] = baseChars;
- s->mWords[s->mWordCount] = chars;
- s->mStarts[s->mWordCount] = s->mCurrentStart;
+ s->newWord(baseChars, chars);
s->mUnparsed = true;
}
++s->mLetterCount;
@@ -1990,7 +1992,8 @@ CacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars
goto nextTest;
abbr = true;
}
- letter = test[testIndex];
+ letter = &test[testIndex] < s->mEnds[wordsIndex] ?
+ test[testIndex] : ' ';
if (WTF::isASCIIAlpha(letter) == false && WTF::isASCIIDigit(letter) == false) {
if (s->mNumberWords != 0) {
int shift = 0;
@@ -2031,9 +2034,7 @@ CacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars
s->mNumberWords >>= ++shift;
if (s->mBases[0] != s->mBases[shift])
return FOUND_NONE;
- memmove(s->mBases, &s->mBases[shift], (sizeof(s->mBases) / sizeof(s->mBases[0]) - shift) * sizeof(s->mBases[0]));
- memmove(s->mWords, &s->mWords[shift], (sizeof(s->mWords) / sizeof(s->mWords[0]) - shift) * sizeof(s->mWords[0]));
- memmove(s->mStarts, &s->mStarts[shift], (sizeof(s->mStarts) / sizeof(s->mStarts[0]) - shift) * sizeof(s->mStarts[0]));
+ s->shiftWords(shift);
s->mStartResult = s->mWords[0] - s->mStarts[0];
s->mWordCount -= shift;
s->mProgress = ADDRESS_LINE;
@@ -2431,7 +2432,7 @@ bool CacheBuilder::isFocusableText(NodeWalk* walk, bool more, Node* node,
CachedNodeType* type, String* exported) const
{
Text* textNode = static_cast<Text*>(node);
- StringImpl* string = textNode->string();
+ StringImpl* string = textNode->dataImpl();
const UChar* baseChars = string->characters();
// const UChar* originalBase = baseChars;
int length = string->length();
@@ -2462,9 +2463,9 @@ bool CacheBuilder::isFocusableText(NodeWalk* walk, bool more, Node* node,
baseStart = start;
for (CachedNodeType checkType = ADDRESS_CACHEDNODETYPE;
checkType <= PHONE_CACHEDNODETYPE;
- checkType = (CachedNodeType) (checkType << 1))
+ checkType = static_cast<CachedNodeType>(checkType + 1))
{
- if ((checkType & mAllowableTypes) == 0)
+ if ((1 << (checkType - 1) & mAllowableTypes) == 0)
continue;
InlineTextBox* inlineTextBox = baseInline;
FindState findState;
@@ -2536,7 +2537,7 @@ bool CacheBuilder::isFocusableText(NodeWalk* walk, bool more, Node* node,
exported->truncate(0);
do {
Text* tempText = static_cast<Text*>(temp);
- StringImpl* string = tempText->string();
+ StringImpl* string = tempText->dataImpl();
int end = tempText == walk->mFinalNode ?
walk->mEnd : string->length();
exported->append(String(string->substring(
@@ -2596,7 +2597,7 @@ bool CacheBuilder::isFocusableText(NodeWalk* walk, bool more, Node* node,
} while (renderer == NULL);
baseInline = renderer->firstTextBox();
} while (baseInline == NULL);
- string = nextNode->string();
+ string = nextNode->dataImpl();
baseChars = string->characters();
inlineTextBox = baseInline;
start = inlineTextBox->start();
@@ -2606,7 +2607,7 @@ bool CacheBuilder::isFocusableText(NodeWalk* walk, bool more, Node* node,
tryNextCheckType:
node = textNode;
baseInline = saveInline;
- string = textNode->string();
+ string = textNode->dataImpl();
baseChars = string->characters();
}
if (foundBetter) {
@@ -2865,7 +2866,7 @@ bool CacheBuilder::ConstructTextRect(Text* textNode,
{
RenderText* renderText = (RenderText*) textNode->renderer();
EVisibility vis = renderText->style()->visibility();
- StringImpl* string = textNode->string();
+ StringImpl* string = textNode->dataImpl();
const UChar* chars = string->characters();
FloatPoint pt = renderText->localToAbsolute();
do {
diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h
index 35bd623..ff395d3 100644
--- a/WebKit/android/nav/CacheBuilder.h
+++ b/WebKit/android/nav/CacheBuilder.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -77,19 +77,20 @@ public:
FOUND_COMPLETE
};
CacheBuilder();
- void allowAllTextDetection() { mAllowableTypes = ALL_CACHEDNODETYPES; }
+ void allowAllTextDetection() { mAllowableTypes = ALL_CACHEDNODE_BITS; }
void buildCache(CachedRoot* root);
static bool ConstructPartRects(Node* node, const IntRect& bounds,
IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result);
Node* currentFocus() const;
- void disallowAddressDetection() { mAllowableTypes = (CachedNodeType) (
- mAllowableTypes & ~ADDRESS_CACHEDNODETYPE); }
- void disallowEmailDetection() { mAllowableTypes = (CachedNodeType) (
- mAllowableTypes & ~EMAIL_CACHEDNODETYPE); }
- void disallowPhoneDetection() { mAllowableTypes = (CachedNodeType) (
- mAllowableTypes & ~PHONE_CACHEDNODETYPE); }
+ void disallowAddressDetection() { mAllowableTypes = (CachedNodeBits) (
+ mAllowableTypes & ~ADDRESS_CACHEDNODE_BIT); }
+ void disallowEmailDetection() { mAllowableTypes = (CachedNodeBits) (
+ mAllowableTypes & ~EMAIL_CACHEDNODE_BIT); }
+ void disallowPhoneDetection() { mAllowableTypes = (CachedNodeBits) (
+ mAllowableTypes & ~PHONE_CACHEDNODE_BIT); }
static FoundState FindAddress(const UChar* , unsigned length, int* start,
int* end, bool caseInsensitive);
+ static IntRect getAreaRect(const HTMLAreaElement* area);
static void GetGlobalOffset(Frame* , int* x, int * y);
static void GetGlobalOffset(Node* , int* x, int * y);
static bool validNode(Frame* startFrame, void* framePtr, void* nodePtr);
@@ -126,7 +127,6 @@ private:
BoundsPart mPart;
WTF::Vector<BoundsPart> mParts;
char mStore[NAVIGATION_MAX_PHONE_LENGTH + 1];
- CachedNodeType mStoreType;
int mPartIndex;
Node* mNode;
Node* mFinalNode;
@@ -146,6 +146,7 @@ private:
const UChar* mZipStart;
const UChar* mBases[16]; // FIXME: random guess, maybe too small, maybe too big
const UChar* mWords[16];
+ const UChar* mEnds[16];
const UChar* mStarts[16]; // text is not necessarily contiguous
const char* mStates;
int mEndWord;
@@ -165,6 +166,22 @@ private:
bool mInitialized;
bool mContinuationNode;
bool mCaseInsensitive;
+ void shiftWords(int shift) {
+ memmove(mBases, &mBases[shift], (sizeof(mBases) /
+ sizeof(mBases[0]) - shift) * sizeof(mBases[0]));
+ memmove(mWords, &mWords[shift], (sizeof(mWords) /
+ sizeof(mWords[0]) - shift) * sizeof(mWords[0]));
+ memmove(mEnds, &mEnds[shift], (sizeof(mEnds) /
+ sizeof(mEnds[0]) - shift) * sizeof(mEnds[0]));
+ memmove(mStarts, &mStarts[shift], (sizeof(mStarts) /
+ sizeof(mStarts[0]) - shift) * sizeof(mStarts[0]));
+ }
+ void newWord(const UChar* baseChars, const UChar* chars) {
+ mBases[mWordCount] = baseChars;
+ mWords[mWordCount] = chars;
+ mEnds[mWordCount] = mEnd;
+ mStarts[mWordCount] = mCurrentStart;
+ }
};
struct ClipColumnTracker {
IntRect mBounds;
@@ -183,7 +200,6 @@ private:
int mCachedNodeIndex;
int mTabIndex;
Node* mLastChild;
- Node* mParentLastChild;
bool mSomeParentTakesFocus;
};
void adjustForColumns(const ClipColumnTracker& track,
@@ -212,7 +228,6 @@ private:
static Frame* FrameAnd(CacheBuilder* focusNav);
static Frame* FrameAnd(const CacheBuilder* focusNav);
static CacheBuilder* Builder(Frame* );
- static IntRect getAreaRect(const HTMLAreaElement* area);
static Frame* HasFrame(Node* );
static bool HasOverOrOut(Node* );
static bool HasTriggerEvent(Node* );
@@ -225,7 +240,7 @@ private:
bool setData(CachedFrame* );
Node* tryFocus(Direction direction);
Node* trySegment(Direction direction, int mainStart, int mainEnd);
- CachedNodeType mAllowableTypes;
+ CachedNodeBits mAllowableTypes;
#if DUMP_NAV_CACHE
public:
class Debug {
diff --git a/WebKit/android/nav/CachedDebug.h b/WebKit/android/nav/CachedDebug.h
index 3127112..3dbe5ef 100644
--- a/WebKit/android/nav/CachedDebug.h
+++ b/WebKit/android/nav/CachedDebug.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,21 +26,9 @@
#ifndef CachedDebug_H
#define CachedDebug_H
-#ifndef DUMP_NAV_CACHE
-#ifdef NDEBUG
#define DUMP_NAV_CACHE 0
-#else
-#define DUMP_NAV_CACHE 1
-#endif
-#endif
-
-#ifndef DEBUG_NAV_UI
-#ifdef NDEBUG
#define DEBUG_NAV_UI 0
-#else
-#define DEBUG_NAV_UI 1
-#endif
-#endif
+#define DEBUG_NAV_UI_VERBOSE 0
#if DEBUG_NAV_UI
#define DBG_NAV_LOG(message) LOGD("%s %s", __FUNCTION__, message)
@@ -49,10 +37,15 @@
#else
#define DBG_NAV_LOG(message) ((void)0)
#define DBG_NAV_LOGD(format, ...) ((void)0)
-#define DBG_NAV_LOGD_THROTTLE(format, ...) ((void)0)
#define DEBUG_NAV_UI_LOGD(...) ((void)0)
#endif
+#if DEBUG_NAV_UI_VERBOSE
+#define DBG_NAV_LOGV(format, ...) LOGD("%s " format, __FUNCTION__, __VA_ARGS__)
+#else
+#define DBG_NAV_LOGV(format, ...) ((void)0)
+#endif
+
#if DUMP_NAV_CACHE != 0 && !defined DUMP_NAV_CACHE_USING_PRINTF && defined NDEBUG
#define DUMP_NAV_CACHE_USING_PRINTF
#endif
diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp
index 955a439..299dc53 100644
--- a/WebKit/android/nav/CachedFrame.cpp
+++ b/WebKit/android/nav/CachedFrame.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -402,7 +402,7 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect,
int dx = testCenter.x() - center.x();
int dy = testCenter.y() - center.y();
int distance = dx * dx + dy * dy;
- if ((!*inside && testInside) || *best > distance) {
+ if ((!*inside && testInside) || *best >= distance) {
*best = distance;
*inside = testInside;
result = test;
@@ -441,14 +441,18 @@ const CachedFrame* CachedFrame::findBestFrameAt(int x, int y) const
}
const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect,
- int* best, const CachedFrame** framePtr, int* x, int* y) const
+ const CachedFrame** framePtr, int* x, int* y) const
{
- const CachedNode* result = NULL;
- int rectWidth = rect.width();
- WebCore::IntPoint center = WebCore::IntPoint(rect.x() + (rectWidth >> 1),
- rect.y() + (rect.height() >> 1));
mRoot->setupScrolledBounds();
- for (const CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) {
+ for (const CachedFrame* frame = mCachedFrames.end() - 1;
+ frame != mCachedFrames.begin() - 1; frame--) {
+ const CachedNode* frameResult = frame->findBestHitAt(rect,
+ framePtr, x, y);
+ if (NULL != frameResult)
+ return frameResult;
+ }
+ for (const CachedNode* test = mCachedNodes.end() - 1;
+ test != mCachedNodes.begin() - 1; test--) {
if (test->disabled())
continue;
const WebCore::IntRect& testRect = test->hitBounds();
@@ -459,29 +463,19 @@ const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect,
testData.mMouseBounds = testData.mNodeBounds = testRect;
if (mRoot->maskIfHidden(&testData) == true)
continue;
- const WebCore::IntRect& bounds = testData.mMouseBounds;
- WebCore::IntPoint testCenter = WebCore::IntPoint(bounds.x() +
- (bounds.width() >> 1), bounds.y() + (bounds.height() >> 1));
- int dx = testCenter.x() - center.x();
- int dy = testCenter.y() - center.y();
- int distance = dx * dx + dy * dy;
- if (*best <= distance)
- continue;
- *best = distance;
- result = test;
- *framePtr = this;
- const WebCore::IntRect& cursorRect = test->cursorRings().at(0);
- *x = cursorRect.x() + (cursorRect.width() >> 1);
- *y = cursorRect.y() + (cursorRect.height() >> 1);
- }
- for (const CachedFrame* frame = mCachedFrames.begin();
- frame != mCachedFrames.end(); frame++) {
- const CachedNode* frameResult = frame->findBestHitAt(rect, best,
- framePtr, x, y);
- if (NULL != frameResult)
- result = frameResult;
+ for (unsigned i = 0; i < test->cursorRings().size(); i++) {
+ const WebCore::IntRect& cursorRect = test->cursorRings().at(i);
+ if (cursorRect.intersects(rect)) {
+ WebCore::IntRect intersection(cursorRect);
+ intersection.intersect(rect);
+ *x = intersection.x() + (intersection.width() >> 1);
+ *y = intersection.y() + (intersection.height() >> 1);
+ *framePtr = this;
+ return test;
+ }
+ }
}
- return result;
+ return NULL;
}
void CachedFrame::findClosest(BestData* bestData, Direction originalDirection,
@@ -687,7 +681,7 @@ int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, Bes
// return REJECT_TEST;
// }
void* par = cursor ? cursor->parentGroup() : NULL;
- testData.mCursorChild = test->parentGroup() == par;
+ testData.mCursorChild = par ? test->parentGroup() == par : false;
#if 0 // not debugged
if (cursor && cursor->hasMouseOver() && test->hasMouseOver() == false &&
cursor->bounds().contains(test->bounds()))
@@ -753,7 +747,7 @@ int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, Bes
int CachedFrame::framePartCommon(BestData& testData,
const CachedNode* test, BestData* bestData, const CachedNode* cursor) const
{
- if (cursor && testData.mNodeBounds.contains(cursor->bounds())) {
+ if (cursor && testData.mNodeBounds.contains(cursor->bounds()) && !test->wantsKeyEvents()) {
testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR);
return REJECT_TEST;
}
@@ -911,8 +905,8 @@ const CachedNode* CachedFrame::nextTextField(const CachedNode* start,
= frame->nextTextField(0, framePtr, includeTextAreas);
if (node)
return node;
- } else if (test->isTextField()
- || (includeTextAreas && test->isTextArea())) {
+ } else if (test->isTextField(this)
+ || (includeTextAreas && test->isTextInput())) {
if (framePtr)
*framePtr = this;
return test;
@@ -1144,7 +1138,7 @@ bool CachedFrame::BestData::setDownDirection(const CachedHistory* history)
int inNavBottom = navBounds.bottom() - mNodeBounds.bottom();
setNavInclusion(testRight - navBounds.right(), navBounds.x() - testX);
bool subsumes = navBounds.height() > 0 && inOrSubsumesNav();
- if (inNavTop <= 0 && inNavBottom <= 0 && subsumes) {
+ if (inNavTop <= 0 && inNavBottom <= 0 && subsumes && !mNode->wantsKeyEvents()) {
mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR);
return REJECT_TEST;
}
@@ -1184,7 +1178,7 @@ bool CachedFrame::BestData::setLeftDirection(const CachedHistory* history)
int inNavLeft = mNodeBounds.x() - navBounds.x();
setNavInclusion(navBounds.y() - testY, testBottom - navBounds.bottom());
bool subsumes = navBounds.width() > 0 && inOrSubsumesNav();
- if (inNavLeft <= 0 && inNavRight <= 0 && subsumes) {
+ if (inNavLeft <= 0 && inNavRight <= 0 && subsumes && !mNode->wantsKeyEvents()) {
mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR);
return REJECT_TEST;
}
@@ -1224,7 +1218,7 @@ bool CachedFrame::BestData::setRightDirection(const CachedHistory* history)
int inNavRight = navBounds.right() - mNodeBounds.right();
setNavInclusion(testBottom - navBounds.bottom(), navBounds.y() - testY);
bool subsumes = navBounds.width() > 0 && inOrSubsumesNav();
- if (inNavLeft <= 0 && inNavRight <= 0 && subsumes) {
+ if (inNavLeft <= 0 && inNavRight <= 0 && subsumes && !mNode->wantsKeyEvents()) {
mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR);
return REJECT_TEST;
}
@@ -1264,7 +1258,7 @@ bool CachedFrame::BestData::setUpDirection(const CachedHistory* history)
int inNavTop = mNodeBounds.y() - navBounds.y();
setNavInclusion(navBounds.x() - testX, testRight - navBounds.right());
bool subsumes = navBounds.height() > 0 && inOrSubsumesNav();
- if (inNavTop <= 0 && inNavBottom <= 0 && subsumes) {
+ if (inNavTop <= 0 && inNavBottom <= 0 && subsumes && !mNode->wantsKeyEvents()) {
mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR);
return REJECT_TEST;
}
@@ -1332,8 +1326,12 @@ void CachedFrame::Debug::print() const
DEBUG_PRINT_RECT("//", VIEW, mViewBounds);
DUMP_NAV_LOGD("// CachedNode mCachedNodes={ // count=%d\n", b->mCachedNodes.size());
for (CachedNode* node = b->mCachedNodes.begin();
- node != b->mCachedNodes.end(); node++)
+ node != b->mCachedNodes.end(); node++) {
node->mDebug.print();
+ const CachedInput* input = b->textInput(node);
+ if (input)
+ input->mDebug.print();
+ }
DUMP_NAV_LOGD("// }; // end of nodes\n");
DUMP_NAV_LOGD("// CachedFrame mCachedFrames={ // count=%d\n", b->mCachedFrames.size());
for (CachedFrame* child = b->mCachedFrames.begin();
diff --git a/WebKit/android/nav/CachedFrame.h b/WebKit/android/nav/CachedFrame.h
index fcfddb8..7a00539 100644
--- a/WebKit/android/nav/CachedFrame.h
+++ b/WebKit/android/nav/CachedFrame.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,6 +26,7 @@
#ifndef CachedFrame_H
#define CachedFrame_H
+#include "CachedInput.h"
#include "CachedNode.h"
#include "IntRect.h"
#include "SkFixed.h"
@@ -66,6 +67,7 @@ public:
CURSOR_SET = 0
};
CachedFrame() {}
+ void add(CachedInput& input) { mCachedTextInputs.append(input); }
void add(CachedNode& node) { mCachedNodes.append(node); }
void addFrame(CachedFrame& child) { mCachedFrames.append(child); }
bool checkVisited(const CachedNode* , CachedFrame::Direction ) const;
@@ -83,7 +85,7 @@ public:
int* y, bool checkForHidden) const;
const CachedFrame* findBestFrameAt(int x, int y) const;
const CachedNode* findBestHitAt(const WebCore::IntRect& ,
- int* best, const CachedFrame** , int* x, int* y) const;
+ const CachedFrame** , int* x, int* y) const;
void finishInit();
CachedFrame* firstChild() { return mCachedFrames.begin(); }
const CachedFrame* firstChild() const { return mCachedFrames.begin(); }
@@ -123,6 +125,10 @@ public:
void setFocusIndex(int index) { mFocusIndex = index; }
void setLocalViewBounds(const WebCore::IntRect& bounds) { mLocalViewBounds = bounds; }
int size() { return mCachedNodes.size(); }
+ const CachedInput* textInput(const CachedNode* node) const {
+ return node->isTextInput() ? &mCachedTextInputs[node->textInputIndex()]
+ : 0;
+ }
const CachedNode* validDocument() const;
protected:
struct BestData {
@@ -206,6 +212,7 @@ protected:
WebCore::IntRect mViewBounds;
WTF::Vector<CachedNode> mCachedNodes;
WTF::Vector<CachedFrame> mCachedFrames;
+ WTF::Vector<CachedInput> mCachedTextInputs;
void* mFrame; // WebCore::Frame*, used only to compare pointers
CachedFrame* mParent;
int mCursorIndex;
diff --git a/WebKit/android/nav/CachedHistory.cpp b/WebKit/android/nav/CachedHistory.cpp
index 7aca1ad..47a560c 100644
--- a/WebKit/android/nav/CachedHistory.cpp
+++ b/WebKit/android/nav/CachedHistory.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/nav/CachedHistory.h b/WebKit/android/nav/CachedHistory.h
index 1ae62b9..302da4e 100644
--- a/WebKit/android/nav/CachedHistory.h
+++ b/WebKit/android/nav/CachedHistory.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/nav/CachedInput.cpp b/WebKit/android/nav/CachedInput.cpp
new file mode 100644
index 0000000..924bbca
--- /dev/null
+++ b/WebKit/android/nav/CachedInput.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CachedPrefix.h"
+#include "CachedInput.h"
+
+namespace android {
+
+#if DUMP_NAV_CACHE
+
+#define DEBUG_PRINT_BOOL(field) \
+ DUMP_NAV_LOGD("// bool " #field "=%s;\n", b->field ? "true" : "false")
+
+CachedInput* CachedInput::Debug::base() const {
+ CachedInput* nav = (CachedInput*) ((char*) this - OFFSETOF(CachedInput, mDebug));
+ return nav;
+}
+
+static void printWebCoreString(const char* label,
+ const WebCore::String& string) {
+ char scratch[256];
+ size_t index = snprintf(scratch, sizeof(scratch), label);
+ const UChar* ch = string.characters();
+ while (ch && *ch && index < sizeof(scratch)) {
+ UChar c = *ch++;
+ if (c < ' ' || c >= 0x7f) c = ' ';
+ scratch[index++] = c;
+ }
+ DUMP_NAV_LOGD("%.*s\"\n", index, scratch);
+}
+
+void CachedInput::Debug::print() const
+{
+ CachedInput* b = base();
+ printWebCoreString("// char* mName=\"", b->mName);
+ DUMP_NAV_LOGD("// void* mForm=%p;", b->mForm);
+ DUMP_NAV_LOGD("// int mMaxLength=%d;\n", b->mMaxLength);
+ DUMP_NAV_LOGD("// int mTextSize=%d;\n", b->mTextSize);
+ DUMP_NAV_LOGD("// int mInputType=%d;\n", b->mInputType);
+ DEBUG_PRINT_BOOL(mIsRtlText);
+ DEBUG_PRINT_BOOL(mIsTextField);
+}
+
+#endif
+
+}
diff --git a/WebKit/android/nav/CachedInput.h b/WebKit/android/nav/CachedInput.h
new file mode 100644
index 0000000..42cadf1
--- /dev/null
+++ b/WebKit/android/nav/CachedInput.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CachedInput_H
+#define CachedInput_H
+
+#include "CachedDebug.h"
+#include "HTMLInputElement.h"
+#include "PlatformString.h"
+
+namespace android {
+
+class CachedInput {
+public:
+ CachedInput() {
+ // Initiaized to 0 in its array, so nothing to do in the
+ // constructor
+ }
+ void* formPointer() const { return mForm; }
+ void init() {
+ bzero(this, sizeof(CachedInput));
+ mName = WebCore::String();
+ }
+ WebCore::HTMLInputElement::InputType inputType() const { return mInputType; }
+ bool isRtlText() const { return mIsRtlText; }
+ bool isTextField() const { return mIsTextField; }
+ int maxLength() const { return mMaxLength; };
+ const WebCore::String& name() const { return mName; }
+ void setFormPointer(void* form) { mForm = form; }
+ void setInputType(WebCore::HTMLInputElement::InputType type) { mInputType = type; }
+ void setIsRtlText(bool isRtlText) { mIsRtlText = isRtlText; }
+ void setIsTextField(bool isTextField) { mIsTextField = isTextField; }
+ void setMaxLength(int maxLength) { mMaxLength = maxLength; }
+ void setName(const WebCore::String& name) { mName = name; }
+ void setTextSize(int textSize) { mTextSize = textSize; }
+ int textSize() const { return mTextSize; }
+private:
+ void* mForm;
+ WebCore::String mName;
+ int mMaxLength;
+ int mTextSize;
+ WebCore::HTMLInputElement::InputType mInputType;
+ bool mIsRtlText : 1;
+ bool mIsTextField : 1;
+#if DUMP_NAV_CACHE
+public:
+ class Debug {
+public:
+ CachedInput* base() const;
+ void print() const;
+ } mDebug;
+#endif
+};
+
+}
+
+#endif
diff --git a/WebKit/android/nav/CachedNode.cpp b/WebKit/android/nav/CachedNode.cpp
index cab1f15..58ada58 100644
--- a/WebKit/android/nav/CachedNode.cpp
+++ b/WebKit/android/nav/CachedNode.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -76,6 +76,16 @@ bool CachedNode::clip(const WebCore::IntRect& bounds)
return Clip(bounds, &mBounds, &mCursorRing);
}
+void CachedNode::cursorRingBounds(WebCore::IntRect* bounds) const
+{
+ int partMax = mNavableRects;
+ ASSERT(partMax > 0);
+ *bounds = mCursorRing[0];
+ for (int partIndex = 1; partIndex < partMax; partIndex++)
+ bounds->unite(mCursorRing[partIndex]);
+ bounds->inflate(CURSOR_RING_HIT_TEST_RADIUS);
+}
+
#define OVERLAP 3
void CachedNode::fixUpCursorRects(const CachedRoot* root)
@@ -194,17 +204,6 @@ tryAgain:
} while (again);
}
-
-void CachedNode::cursorRingBounds(WebCore::IntRect* bounds) const
-{
- int partMax = mNavableRects;
- ASSERT(partMax > 0);
- *bounds = mCursorRing[0];
- for (int partIndex = 1; partIndex < partMax; partIndex++)
- bounds->unite(mCursorRing[partIndex]);
- bounds->inflate(CURSOR_RING_HIT_TEST_RADIUS);
-}
-
void CachedNode::hideCursor(CachedFrame* parent)
{
if (isFrame()) {
@@ -218,12 +217,17 @@ void CachedNode::init(WebCore::Node* node)
{
bzero(this, sizeof(CachedNode));
mExport = WebCore::String();
- mName = WebCore::String();
mNode = node;
- mParentIndex = mChildFrameIndex = -1;
+ mParentIndex = mDataIndex = -1;
mType = android::NORMAL_CACHEDNODETYPE;
}
+bool CachedNode::isTextField(const CachedFrame* frame) const
+{
+ const CachedInput* input = frame->textInput(this);
+ return input ? input->isTextField() : false;
+}
+
void CachedNode::move(int x, int y)
{
mBounds.move(x, y);
@@ -306,6 +310,11 @@ const char* CachedNode::Debug::type(android::CachedNodeType t) const
case ADDRESS_CACHEDNODETYPE: return "ADDRESS"; break;
case EMAIL_CACHEDNODETYPE: return "EMAIL"; break;
case PHONE_CACHEDNODETYPE: return "PHONE"; break;
+ case ANCHOR_CACHEDNODETYPE: return "ANCHOR"; break;
+ case AREA_CACHEDNODETYPE: return "AREA"; break;
+ case FRAME_CACHEDNODETYPE: return "FRAME"; break;
+ case PLUGIN_CACHEDNODETYPE: return "PLUGIN"; break;
+ case TEXT_INPUT_CACHEDNODETYPE: return "INPUT"; break;
default: return "???";
}
}
@@ -316,13 +325,11 @@ void CachedNode::Debug::print() const
char scratch[256];
size_t index = snprintf(scratch, sizeof(scratch), "// char* mExport=\"");
const UChar* ch = b->mExport.characters();
- while (ch && *ch && index < sizeof(scratch))
- scratch[index++] = *ch++;
- DUMP_NAV_LOGD("%.*s\"\n", index, scratch);
- index = snprintf(scratch, sizeof(scratch), "// char* mName=\"");
- ch = b->mName.characters();
- while (ch && *ch && index < sizeof(scratch))
- scratch[index++] = *ch++;
+ while (ch && *ch && index < sizeof(scratch)) {
+ UChar c = *ch++;
+ if (c < ' ' || c >= 0x7f) c = ' ';
+ scratch[index++] = c;
+ }
DUMP_NAV_LOGD("%.*s\"\n", index, scratch);
DEBUG_PRINT_RECT(mBounds);
DEBUG_PRINT_RECT(mHitBounds);
@@ -335,12 +342,10 @@ void CachedNode::Debug::print() const
DUMP_NAV_LOGD("// };\n");
DUMP_NAV_LOGD("// void* mNode=%p; // (%d) \n", b->mNode, mNodeIndex);
DUMP_NAV_LOGD("// void* mParentGroup=%p; // (%d) \n", b->mParentGroup, mParentGroupIndex);
- DUMP_NAV_LOGD("// int mChildFrameIndex=%d;\n", b->mChildFrameIndex);
+ DUMP_NAV_LOGD("// int mDataIndex=%d;\n", b->mDataIndex);
DUMP_NAV_LOGD("// int mIndex=%d;\n", b->mIndex);
- DUMP_NAV_LOGD("// int mMaxLength=%d;\n", b->mMaxLength);
DUMP_NAV_LOGD("// int mNavableRects=%d;\n", b->mNavableRects);
DUMP_NAV_LOGD("// int mParentIndex=%d;\n", b->mParentIndex);
- DUMP_NAV_LOGD("// int mTextSize=%d;\n", b->mTextSize);
DUMP_NAV_LOGD("// int mTabIndex=%d;\n", b->mTabIndex);
DUMP_NAV_LOGD("// Condition mCondition=%s;\n", condition(b->mCondition));
DUMP_NAV_LOGD("// Type mType=%s;\n", type(b->mType));
@@ -349,22 +354,15 @@ void CachedNode::Debug::print() const
DEBUG_PRINT_BOOL(mFixedUpCursorRects);
DEBUG_PRINT_BOOL(mHasCursorRing);
DEBUG_PRINT_BOOL(mHasMouseOver);
- DEBUG_PRINT_BOOL(mIsAnchor);
- DEBUG_PRINT_BOOL(mIsArea);
DEBUG_PRINT_BOOL(mIsCursor);
DEBUG_PRINT_BOOL(mIsFocus);
DEBUG_PRINT_BOOL(mIsHidden);
DEBUG_PRINT_BOOL(mIsParentAnchor);
- DEBUG_PRINT_BOOL(mIsPassword);
- DEBUG_PRINT_BOOL(mIsRtlText);
- DEBUG_PRINT_BOOL(mIsTextArea);
- DEBUG_PRINT_BOOL(mIsTextField);
DEBUG_PRINT_BOOL(mIsTransparent);
DEBUG_PRINT_BOOL(mIsUnclipped);
DEBUG_PRINT_BOOL(mLast);
DEBUG_PRINT_BOOL(mUseBounds);
DEBUG_PRINT_BOOL(mUseHitBounds);
- DEBUG_PRINT_BOOL(mWantsKeyEvents);
DUMP_NAV_LOGD("\n");
}
diff --git a/WebKit/android/nav/CachedNode.h b/WebKit/android/nav/CachedNode.h
index 2efbaf7..a433a47 100644
--- a/WebKit/android/nav/CachedNode.h
+++ b/WebKit/android/nav/CachedNode.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -62,6 +62,7 @@ public:
IN_UMBRA,
IN_WORKING,
LEFTMOST,
+ NOT_ENCLOSING_CURSOR,
OVERLAP_OR_EDGE_FURTHER,
PREFERRED, // better overlap measure
SECOND_CHANCE_END = PREFERRED, // must be last in list
@@ -73,7 +74,6 @@ public:
HIGHER_TAB_INDEX,
IN_CURSOR,
IN_CURSOR_CHILDREN,
- NOT_ENCLOSING_CURSOR,
NOT_CURSOR_NODE,
OUTSIDE_OF_BEST, // containership
OUTSIDE_OF_ORIGINAL, // containership
@@ -86,7 +86,7 @@ public:
const WebCore::IntRect& bounds() const { return mBounds; }
WebCore::IntRect* boundsPtr() { return &mBounds; }
- int childFrameIndex() const { return mChildFrameIndex; }
+ int childFrameIndex() const { return isFrame() ? mDataIndex : -1; }
void clearCondition() const { mCondition = NOT_REJECTED; }
void clearCursor(CachedFrame* );
static bool Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner,
@@ -94,131 +94,112 @@ public:
bool clip(const WebCore::IntRect& );
bool clippedOut() { return mClippedOut; }
void cursorRingBounds(WebCore::IntRect* ) const;
+ WTF::Vector<WebCore::IntRect>& cursorRings() { return mCursorRing; }
+ const WTF::Vector<WebCore::IntRect>& cursorRings() const { return mCursorRing; }
bool disabled() const { return mDisabled; }
const CachedNode* document() const { return &this[-mIndex]; }
void fixUpCursorRects(const CachedRoot* root);
- WTF::Vector<WebCore::IntRect>& cursorRings() { return mCursorRing; }
- const WTF::Vector<WebCore::IntRect>& cursorRings() const { return mCursorRing; }
const WebCore::IntRect& getBounds() const { return mBounds; }
void getBounds(WebCore::IntRect* bounds) const { *bounds = mBounds; }
const WebCore::String& getExport() const { return mExport; }
- bool hasCursorRing() const { return !mIsHidden && mHasCursorRing; }
+ bool hasCursorRing() const { return mHasCursorRing; }
bool hasMouseOver() const { return mHasMouseOver; }
void hideCursor(CachedFrame* );
const WebCore::IntRect& hitBounds() const { return mHitBounds; }
int index() const { return mIndex; }
void init(WebCore::Node* node);
- bool isAnchor() const { return mIsAnchor; }
+ bool isAnchor() const { return mType == ANCHOR_CACHEDNODETYPE; }
bool isCursor() const { return mIsCursor; }
- bool isArea() const { return mIsArea; }
+ bool isArea() const { return mType == AREA_CACHEDNODETYPE; }
bool isFocus() const { return mIsFocus; }
- bool isFrame() const { return mChildFrameIndex >= 0 ; }
+ bool isFrame() const { return mType == FRAME_CACHEDNODETYPE; }
+ bool isHidden() const { return mIsHidden; }
bool isNavable(const WebCore::IntRect& clip) const {
return clip.intersects(mBounds);
}
- bool isPassword() const { return mIsPassword; }
- bool isPlugin() const {
- return mWantsKeyEvents && !mIsTextArea && !mIsTextField;
+ bool isPlugin() const { return mType == PLUGIN_CACHEDNODETYPE; }
+ bool isSyntheticLink() const {
+ return mType >= ADDRESS_CACHEDNODETYPE && mType <= PHONE_CACHEDNODETYPE;
}
- bool isRtlText() const { return mIsRtlText; }
- bool isTextArea() const { return mIsTextArea; }
- bool isTextField() const { return mIsTextField; }
+ bool isTextField(const CachedFrame*) const;
+ bool isTextInput() const { return mType == TEXT_INPUT_CACHEDNODETYPE; }
bool isTransparent() const { return mIsTransparent; }
bool isUnclipped() const { return mIsUnclipped; }
- int maxLength() const { return mMaxLength; };
void move(int x, int y);
- const WebCore::String& name() const { return mName; }
int navableRects() const { return mNavableRects; }
void* nodePointer() const { return mNode; }
bool noSecondChance() const { return mCondition > SECOND_CHANCE_END; }
+ const WebCore::IntRect& originalAbsoluteBounds() const {
+ return mOriginalAbsoluteBounds; }
const CachedNode* parent() const { return document() + mParentIndex; }
void* parentGroup() const { return mParentGroup; }
int parentIndex() const { return mParentIndex; }
bool partRectsContains(const CachedNode* other) const;
void reset();
void setBounds(const WebCore::IntRect& bounds) { mBounds = bounds; }
- void setChildFrameIndex(int index) { mChildFrameIndex = index; }
void setClippedOut(bool clipped) { mClippedOut = clipped; }
void setCondition(Condition condition) const { mCondition = condition; }
+ void setDataIndex(int index) { mDataIndex = index; }
void setDisabled(bool disabled) { mDisabled = disabled; }
void setExport(const WebCore::String& exported) { mExport = exported; }
void setHasCursorRing(bool hasRing) { mHasCursorRing = hasRing; }
void setHasMouseOver(bool hasMouseOver) { mHasMouseOver = hasMouseOver; }
void setHitBounds(const WebCore::IntRect& bounds) { mHitBounds = bounds; }
+ void setOriginalAbsoluteBounds(const WebCore::IntRect& bounds) {
+ mOriginalAbsoluteBounds = bounds; }
void setIndex(int index) { mIndex = index; }
- void setIsAnchor(bool isAnchor) { mIsAnchor = isAnchor; }
- void setIsArea(bool isArea) { mIsArea = isArea; }
void setIsCursor(bool isCursor) { mIsCursor = isCursor; }
void setIsFocus(bool isFocus) { mIsFocus = isFocus; }
void setIsParentAnchor(bool isAnchor) { mIsParentAnchor = isAnchor; }
- void setIsPassword(bool isPassword) { mIsPassword = isPassword; }
- void setIsRtlText(bool isRtlText) { mIsRtlText = isRtlText; }
- void setIsTextArea(bool isTextArea) { mIsTextArea = isTextArea; }
- void setIsTextField(bool isTextField) { mIsTextField = isTextField; }
void setIsTransparent(bool isTransparent) { mIsTransparent = isTransparent; }
void setIsUnclipped(bool unclipped) { mIsUnclipped = unclipped; }
void setLast() { mLast = true; }
- void setMaxLength(int maxLength) { mMaxLength = maxLength; }
- void setName(const WebCore::String& name) { mName = name; }
void setNavableRects() { mNavableRects = mCursorRing.size(); }
void setParentGroup(void* group) { mParentGroup = group; }
void setParentIndex(int parent) { mParentIndex = parent; }
void setTabIndex(int index) { mTabIndex = index; }
- void setTextSize(int textSize) { mTextSize = textSize; }
void setType(CachedNodeType type) { mType = type; }
- void setWantsKeyEvents(bool wantsKeys) { mWantsKeyEvents = wantsKeys; }
void show() { mIsHidden = false; }
int tabIndex() const { return mTabIndex; }
+ int textInputIndex() const { return isTextInput() ? mDataIndex : -1; }
const CachedNode* traverseNextNode() const { return mLast ? NULL : &this[1]; }
- int textSize() const { return mTextSize; }
- CachedNodeType type() const { return mType; }
bool useBounds() const { return mUseBounds; }
bool useHitBounds() const { return mUseHitBounds; }
- bool wantsKeyEvents() const { return mWantsKeyEvents; }
+ bool wantsKeyEvents() const { return isTextInput() || isPlugin(); }
private:
WebCore::String mExport;
- WebCore::String mName;
WebCore::IntRect mBounds;
WebCore::IntRect mHitBounds;
+ WebCore::IntRect mOriginalAbsoluteBounds;
WTF::Vector<WebCore::IntRect> mCursorRing;
void* mNode; // WebCore::Node*, only used to match pointers
void* mParentGroup; // WebCore::Node*, only used to match pointers
- int mChildFrameIndex; // set to -1 if node is not a frame
+ int mDataIndex; // child frame if a frame; input data index; or -1
int mIndex; // index of itself, to find first in array (document)
- int mMaxLength;
int mNavableRects; // FIXME: could be bitfield once I limit max number of rects
int mParentIndex;
- int mTextSize;
int mTabIndex;
mutable Condition mCondition : 5; // why the node was not chosen on the first pass
- CachedNodeType mType : 3;
+ CachedNodeType mType : 4;
bool mClippedOut : 1;
bool mDisabled : 1;
bool mFixedUpCursorRects : 1;
bool mHasCursorRing : 1;
bool mHasMouseOver : 1;
- bool mIsAnchor : 1;
- bool mIsArea : 1;
bool mIsCursor : 1;
bool mIsFocus : 1;
bool mIsHidden : 1;
bool mIsParentAnchor : 1;
- bool mIsPassword : 1;
- bool mIsRtlText : 1;
- bool mIsTextArea : 1;
- bool mIsTextField : 1;
bool mIsTransparent : 1;
bool mIsUnclipped : 1;
bool mLast : 1; // true if this is the last node in a group
bool mUseBounds : 1;
bool mUseHitBounds : 1;
- bool mWantsKeyEvents : 1; // true for nodes like plugins
#ifdef BROWSER_DEBUG
public:
WebCore::Node* webCoreNode() const { return (WebCore::Node*) mNode; }
bool mDisplayMeasure;
mutable bool mInCompare;
- // mutable int mCondition;
int mSideDistance;
int mSecondSide;
#endif
diff --git a/WebKit/android/nav/CachedNodeType.h b/WebKit/android/nav/CachedNodeType.h
index 07346ac..21e2d40 100644
--- a/WebKit/android/nav/CachedNodeType.h
+++ b/WebKit/android/nav/CachedNodeType.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -29,11 +29,24 @@
namespace android {
enum CachedNodeType {
- NORMAL_CACHEDNODETYPE = 0,
- ADDRESS_CACHEDNODETYPE = 1,
- EMAIL_CACHEDNODETYPE = 2,
- PHONE_CACHEDNODETYPE = 4,
- ALL_CACHEDNODETYPES = 7
+ NORMAL_CACHEDNODETYPE,
+ ADDRESS_CACHEDNODETYPE,
+ EMAIL_CACHEDNODETYPE,
+ PHONE_CACHEDNODETYPE,
+ ANCHOR_CACHEDNODETYPE,
+ AREA_CACHEDNODETYPE,
+ FRAME_CACHEDNODETYPE,
+ PLUGIN_CACHEDNODETYPE,
+ TEXT_INPUT_CACHEDNODETYPE
+};
+
+enum CachedNodeBits {
+ NORMAL_CACHEDNODE_BITS = 0,
+ ADDRESS_CACHEDNODE_BIT = 1 << (ADDRESS_CACHEDNODETYPE - 1),
+ EMAIL_CACHEDNODE_BIT = 1 << (EMAIL_CACHEDNODETYPE - 1),
+ PHONE_CACHEDNODE_BIT = 1 << (PHONE_CACHEDNODETYPE - 1),
+ ALL_CACHEDNODE_BITS = ADDRESS_CACHEDNODE_BIT | EMAIL_CACHEDNODE_BIT
+ | PHONE_CACHEDNODE_BIT
};
}
diff --git a/WebKit/android/nav/CachedPrefix.h b/WebKit/android/nav/CachedPrefix.h
index b466771..b682288 100644
--- a/WebKit/android/nav/CachedPrefix.h
+++ b/WebKit/android/nav/CachedPrefix.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp
index 38417b1..d9669bd 100644
--- a/WebKit/android/nav/CachedRoot.cpp
+++ b/WebKit/android/nav/CachedRoot.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,6 +26,7 @@
#include "CachedPrefix.h"
#include "android_graphics.h"
#include "CachedHistory.h"
+#include "CachedInput.h"
#include "CachedNode.h"
#include "SkBitmap.h"
#include "SkBounder.h"
@@ -755,14 +756,17 @@ bool CachedRoot::checkRings(const WTF::Vector<WebCore::IntRect>& rings,
return ringCheck.success();
}
-CachedRoot::ImeAction CachedRoot::cursorTextFieldAction() const
+CachedRoot::ImeAction CachedRoot::currentTextFieldAction() const
{
- const CachedFrame* cursorFrame;
- const CachedNode* cursor = currentCursor(&cursorFrame);
- if (!cursor) {
- // Error case. The cursor has no action, because there is no node under
- // the cursor
- return FAILURE;
+ const CachedFrame* currentFrame;
+ const CachedNode* current = currentCursor(&currentFrame);
+ if (!current || !current->isTextInput()) {
+ // Although the cursor is not on a textfield, a textfield may have
+ // focus. Find the action for that textfield.
+ current = currentFocus(&currentFrame);
+ if (!current || !current->isTextInput())
+ // Error case. No cursor and no focus.
+ return FAILURE;
}
const CachedNode* firstTextfield = nextTextField(0, 0, false);
if (!firstTextfield) {
@@ -770,9 +774,13 @@ CachedRoot::ImeAction CachedRoot::cursorTextFieldAction() const
return FAILURE;
}
// Now find the next textfield/area starting with the cursor
- if (cursorFrame->nextTextField(cursor, 0, true)) {
- // There is a textfield/area after the cursor, so the textfield under
- // the cursor should have the NEXT action
+ const CachedFrame* potentialFrame;
+ const CachedNode* potentialNext
+ = currentFrame->nextTextField(current, &potentialFrame, true);
+ if (potentialNext && currentFrame->textInput(current)->formPointer()
+ == potentialFrame->textInput(potentialNext)->formPointer()) {
+ // There is a textfield/area after the cursor in the same form,
+ // so the textfield under the cursor should have the NEXT action
return NEXT;
}
// If this line is reached, we know that the textfield under the cursor is
@@ -792,7 +800,7 @@ const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect,
DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(),
node == NULL ? NULL : node->nodePointer());
if (node == NULL) {
- node = findBestHitAt(rect, &best, framePtr, x, y);
+ node = findBestHitAt(rect, framePtr, x, y);
DBG_NAV_LOGD("node=%d (%p)", node == NULL ? 0 : node->index(),
node == NULL ? NULL : node->nodePointer());
}
@@ -844,9 +852,9 @@ int CachedRoot::getBlockLeftEdge(int x, int y, float scale) const
const CachedFrame* frame;
int fx, fy;
const CachedNode* node = findAt(rect, &frame, &fx, &fy, true);
- if (node && (node->isTextArea() || node->isTextField() || node->isPlugin())) {
+ if (node && node->wantsKeyEvents()) {
DBG_NAV_LOGD("x=%d (%s)", node->bounds().x(),
- node->isTextArea() || node->isTextField() ? "text" : "plugin");
+ node->isTextInput() ? "text" : "plugin");
return node->bounds().x();
}
int halfW = (int) (mViewBounds.width() * scale * 0.5f);
diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h
index 123e7d2..5fdf8df 100644
--- a/WebKit/android/nav/CachedRoot.h
+++ b/WebKit/android/nav/CachedRoot.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -52,11 +52,12 @@ public:
void checkForJiggle(int* ) const;
bool checkRings(const WTF::Vector<WebCore::IntRect>& rings,
const WebCore::IntRect& bounds) const;
- WebCore::IntPoint cursorLocation() const;
// This method returns the desired ImeAction for the textfield where the
- // mouse cursor currently is. If the mouse cursor is not on a textfield,
+ // mouse cursor currently is, or where the focus is if there is no mouse
+ // cursor. If the mouse cursor is not on a textfield,
// it will return FAILURE
- ImeAction cursorTextFieldAction() const;
+ ImeAction currentTextFieldAction() const;
+ WebCore::IntPoint cursorLocation() const;
int documentHeight() { return mContents.height(); }
int documentWidth() { return mContents.width(); }
const CachedNode* findAt(const WebCore::IntRect& , const CachedFrame** ,
diff --git a/WebKit/android/nav/FindCanvas.cpp b/WebKit/android/nav/FindCanvas.cpp
index 24b0129..1465b91 100644
--- a/WebKit/android/nav/FindCanvas.cpp
+++ b/WebKit/android/nav/FindCanvas.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
diff --git a/WebKit/android/nav/FindCanvas.h b/WebKit/android/nav/FindCanvas.h
index 5d79b4c..d357a2a 100644
--- a/WebKit/android/nav/FindCanvas.h
+++ b/WebKit/android/nav/FindCanvas.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -204,4 +204,3 @@ private:
};
#endif // Find_Canvas_h
-
diff --git a/WebKit/android/nav/SelectText.cpp b/WebKit/android/nav/SelectText.cpp
index 7bdbf14..d8b184a 100644
--- a/WebKit/android/nav/SelectText.cpp
+++ b/WebKit/android/nav/SelectText.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -22,6 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#define LOG_TAG "webcoreglue"
#include "CachedPrefix.h"
@@ -34,14 +35,17 @@
#include "SkPoint.h"
#include "SkRect.h"
#include "SkRegion.h"
+#include "SkUtils.h"
class CommonCheck : public SkBounder {
public:
CommonCheck() : mMatrix(NULL), mPaint(NULL) {}
- virtual void setUp(const SkPaint& paint, const SkMatrix& matrix, SkScalar y) {
+ virtual void setUp(const SkPaint& paint, const SkMatrix& matrix, SkScalar y,
+ const void* text) {
mMatrix = &matrix;
mPaint = &paint;
+ mText = static_cast<const uint16_t*>(text);
mY = y;
mBase = mBottom = mTop = INT_MAX;
}
@@ -80,10 +84,11 @@ public:
protected:
const SkMatrix* mMatrix;
const SkPaint* mPaint;
+ const uint16_t* mText;
+ SkScalar mY;
int mBase;
int mBottom;
int mTop;
- SkScalar mY;
};
class FirstCheck : public CommonCheck {
@@ -161,6 +166,8 @@ public:
full.fRight = mLast.fLeft;
}
mSelectRegion->op(full, SkRegion::kUnion_Op);
+ DBG_NAV_LOGD("MultilineBuilder full=(%d,%d,r=%d,b=%d)",
+ full.fLeft, full.fTop, full.fRight, full.fBottom);
mLast = full;
mLastBase = base();
if (mStart == mEnd)
@@ -177,6 +184,66 @@ protected:
bool mCapture;
};
+class TextExtractor : public CommonCheck {
+public:
+ TextExtractor(const SkRegion& region) : mSelectRegion(region),
+ mSkipFirstSpace(true) { // don't start with a space
+ }
+
+ virtual void setUp(const SkPaint& paint, const SkMatrix& matrix, SkScalar y,
+ const void* text) {
+ INHERITED::setUp(paint, matrix, y, text);
+ SkPaint charPaint = paint;
+ charPaint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
+ mMinSpaceWidth = charPaint.measureText(" ", 1) * 3 / 4;
+ }
+
+ virtual bool onIRect(const SkIRect& rect, uint16_t glyphID) {
+ SkIRect full;
+ full.set(rect.fLeft, top(), rect.fRight, bottom());
+ if (mSelectRegion.contains(full)) {
+ if (!mSkipFirstSpace
+ && ((mLast.fTop < top() && mLast.fBottom < top() + 2)
+ || (mLast.fLeft < rect.fLeft // glyphs are LTR
+ && mLast.fRight + mMinSpaceWidth < rect.fLeft))) {
+ DBG_NAV_LOGD("TextExtractor [%02x] append space", glyphID);
+ *mSelectText.append() = ' ';
+ } else
+ mSkipFirstSpace = false;
+ DBG_NAV_LOGD("TextExtractor [%02x] append full=(%d,%d,r=%d,b=%d)",
+ glyphID, full.fLeft, full.fTop, full.fRight, full.fBottom);
+ SkUnichar uni;
+ SkPaint utfPaint = *mPaint;
+ utfPaint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
+ utfPaint.glyphsToUnichars(&glyphID, 1, &uni);
+ if (uni) {
+ uint16_t chars[2];
+ size_t count = SkUTF16_FromUnichar(uni, chars);
+ *mSelectText.append() = chars[0];
+ if (count == 2)
+ *mSelectText.append() = chars[1];
+ }
+ mLast = full;
+ } else
+ DBG_NAV_LOGD("TextExtractor [%02x] skip full=(%d,%d,r=%d,b=%d)",
+ glyphID, full.fLeft, full.fTop, full.fRight, full.fBottom);
+ return false;
+ }
+
+ WebCore::String text() {
+ return WebCore::String(mSelectText.begin(), mSelectText.count());
+ }
+
+protected:
+ const SkRegion& mSelectRegion;
+ SkTDArray<uint16_t> mSelectText;
+ SkIRect mLast;
+ SkScalar mMinSpaceWidth;
+ bool mSkipFirstSpace;
+private:
+ typedef CommonCheck INHERITED;
+};
+
class TextCanvas : public SkCanvas {
public:
@@ -217,14 +284,14 @@ public:
virtual void drawText(const void* text, size_t byteLength, SkScalar x,
SkScalar y, const SkPaint& paint) {
- mBounder.setUp(paint, getTotalMatrix(), y);
+ mBounder.setUp(paint, getTotalMatrix(), y, text);
SkCanvas::drawText(text, byteLength, x, y, paint);
}
virtual void drawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint) {
- mBounder.setUp(paint, getTotalMatrix(), constY);
+ mBounder.setUp(paint, getTotalMatrix(), constY, text);
SkCanvas::drawPosTextH(text, byteLength, xpos, constY, paint);
}
@@ -261,3 +328,17 @@ SkIRect CopyPaste::findClosest(const SkPicture& picture, const SkIRect& area,
_check.offsetBounds(area.fLeft, area.fTop);
return _check.bestBounds();
}
+
+WebCore::String CopyPaste::text(const SkPicture& picture, const SkIRect& area,
+ const SkRegion& region) {
+ SkRegion copy = region;
+ copy.translate(-area.fLeft, -area.fTop);
+ const SkIRect& bounds = copy.getBounds();
+ DBG_NAV_LOGD("area=(%d, %d, %d, %d) region=(%d, %d, %d, %d)",
+ area.fLeft, area.fTop, area.fRight, area.fBottom,
+ bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
+ TextExtractor extractor(copy);
+ TextCanvas checker(&extractor, picture, area);
+ checker.drawPicture(const_cast<SkPicture&>(picture));
+ return extractor.text();
+}
diff --git a/WebKit/android/nav/SelectText.h b/WebKit/android/nav/SelectText.h
index b991198..32d8311 100644
--- a/WebKit/android/nav/SelectText.h
+++ b/WebKit/android/nav/SelectText.h
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,6 +26,8 @@
#ifndef SELECT_TEXT_H
#define SELECT_TEXT_H
+#include "PlatformString.h"
+
class SkPicture;
struct SkIRect;
struct SkIPoint;
@@ -37,6 +39,8 @@ public:
const SkIRect& selStart, const SkIRect& selEnd, SkRegion* region);
static SkIRect findClosest(const SkPicture& , const SkIRect& area,
int x, int y);
+ static WebCore::String text(const SkPicture& , const SkIRect& area,
+ const SkRegion& );
};
#endif
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 6f01fec..8931d72 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -13,7 +13,7 @@
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -28,16 +28,20 @@
#include <config.h>
#include "android_graphics.h"
+#include "AndroidAnimation.h"
#include "AndroidLog.h"
#include "AtomicString.h"
#include "CachedFrame.h"
#include "CachedNode.h"
#include "CachedRoot.h"
+#include "CString.h"
#include "FindCanvas.h"
#include "Frame.h"
#include "GraphicsJNI.h"
+#include "HTMLInputElement.h"
#include "IntPoint.h"
#include "IntRect.h"
+#include "LayerAndroid.h"
#include "Node.h"
#include "PlatformGraphicsContext.h"
#include "PlatformString.h"
@@ -95,19 +99,19 @@ enum FrameCachePermission {
};
struct JavaGlue {
- jobject m_obj;
+ jweak m_obj;
jmethodID m_clearTextEntry;
jmethodID m_overrideLoading;
- jmethodID m_sendPluginState;
jmethodID m_scrollBy;
+ jmethodID m_sendMoveFocus;
jmethodID m_sendMoveMouse;
jmethodID m_sendMoveMouseIfLatest;
jmethodID m_sendMotionUp;
+ jmethodID m_domChangedFocus;
jmethodID m_getScaledMaxXScroll;
jmethodID m_getScaledMaxYScroll;
jmethodID m_getVisibleRect;
jmethodID m_rebuildWebTextView;
- jmethodID m_displaySoftKeyboard;
jmethodID m_viewInvalidate;
jmethodID m_viewInvalidateRect;
jmethodID m_postInvalidateDelayed;
@@ -124,19 +128,19 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl)
{
jclass clazz = env->FindClass("android/webkit/WebView");
// m_javaGlue = new JavaGlue;
- m_javaGlue.m_obj = adoptGlobalRef(env, javaWebView);
+ m_javaGlue.m_obj = env->NewWeakGlobalRef(javaWebView);
m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)Z");
m_javaGlue.m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V");
m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V");
- m_javaGlue.m_sendPluginState = GetJMethod(env, clazz, "sendPluginState", "(I)V");
+ m_javaGlue.m_sendMoveFocus = GetJMethod(env, clazz, "sendMoveFocus", "(II)V");
m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V");
m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "(Z)V");
m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIII)V");
+ m_javaGlue.m_domChangedFocus = GetJMethod(env, clazz, "domChangedFocus", "()V");
m_javaGlue.m_getScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I");
m_javaGlue.m_getScaledMaxYScroll = GetJMethod(env, clazz, "getScaledMaxYScroll", "()I");
m_javaGlue.m_getVisibleRect = GetJMethod(env, clazz, "sendOurVisibleRect", "()Landroid/graphics/Rect;");
m_javaGlue.m_rebuildWebTextView = GetJMethod(env, clazz, "rebuildWebTextView", "()V");
- m_javaGlue.m_displaySoftKeyboard = GetJMethod(env, clazz, "displaySoftKeyboard", "(Z)V");
m_javaGlue.m_viewInvalidate = GetJMethod(env, clazz, "viewInvalidate", "()V");
m_javaGlue.m_viewInvalidateRect = GetJMethod(env, clazz, "viewInvalidate", "(IIII)V");
m_javaGlue.m_postInvalidateDelayed = GetJMethod(env, clazz,
@@ -163,10 +167,6 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl)
m_matches = 0;
m_hasCurrentLocation = false;
m_isFindPaintSetUp = false;
- m_pluginReceivesEvents = false; // initialization is the only time this
- // variable should be set directly, all
- // other changes should be made through
- // setPluginReceivesEvents(bool)
}
~WebView()
@@ -174,7 +174,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl)
if (m_javaGlue.m_obj)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->DeleteGlobalRef(m_javaGlue.m_obj);
+ env->DeleteWeakGlobalRef(m_javaGlue.m_obj);
m_javaGlue.m_obj = 0;
}
delete m_frameCacheUI;
@@ -215,12 +215,7 @@ void clearTextEntry()
{
DEBUG_NAV_UI_LOGD("%s", __FUNCTION__);
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_clearTextEntry);
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_clearTextEntry);
checkException(env);
}
@@ -419,7 +414,6 @@ void drawMatches(SkCanvas* canvas)
void resetCursorRing()
{
m_followedLink = false;
- setPluginReceivesEvents(false);
m_viewImpl->m_hasCursorBounds = false;
}
@@ -434,12 +428,12 @@ void drawCursorRing(SkCanvas* canvas)
const CachedFrame* frame;
const CachedNode* node = root->currentCursor(&frame);
if (!node) {
- DBG_NAV_LOG("!node");
+ DBG_NAV_LOGV("%s", "!node");
resetCursorRing();
return;
}
- if (!node->hasCursorRing()) {
- DBG_NAV_LOG("!node->hasCursorRing()");
+ if (node->isHidden()) {
+ DBG_NAV_LOG("node->isHidden()");
m_viewImpl->m_hasCursorBounds = false;
return;
}
@@ -484,16 +478,14 @@ void drawCursorRing(SkCanvas* canvas)
" bounds=(%d,%d,w=%d,h=%d)", node->index(), node->nodePointer(),
bounds.x(), bounds.y(), bounds.width(), bounds.height());
m_followedLink = false;
- setPluginReceivesEvents(false);
return;
}
+ if (!node->hasCursorRing() || (node->isPlugin() && node->isFocus()))
+ return;
CursorRing::Flavor flavor = CursorRing::NORMAL_FLAVOR;
if (!isButton) {
- flavor = node->type() != NORMAL_CACHEDNODETYPE ?
- CursorRing::FAKE_FLAVOR : CursorRing::NORMAL_FLAVOR;
- if (m_pluginReceivesEvents && node->isPlugin()) {
- return;
- }
+ flavor = node->isSyntheticLink()
+ ? CursorRing::FAKE_FLAVOR : CursorRing::NORMAL_FLAVOR;
if (m_followedLink) {
flavor = static_cast<CursorRing::Flavor>
(flavor + CursorRing::NORMAL_ANIMATING);
@@ -501,13 +493,12 @@ void drawCursorRing(SkCanvas* canvas)
#if DEBUG_NAV_UI
const WebCore::IntRect& ring = (*rings)[0];
DBG_NAV_LOGD("cursorNode=%d (nodePointer=%p) flavor=%s rings=%d"
- " (%d, %d, %d, %d) pluginReceivesEvents=%s isPlugin=%s",
+ " (%d, %d, %d, %d) isPlugin=%s",
node->index(), node->nodePointer(),
flavor == CursorRing::FAKE_FLAVOR ? "FAKE_FLAVOR" :
flavor == CursorRing::NORMAL_ANIMATING ? "NORMAL_ANIMATING" :
flavor == CursorRing::FAKE_ANIMATING ? "FAKE_ANIMATING" : "NORMAL_FLAVOR",
rings->size(), ring.x(), ring.y(), ring.width(), ring.height(),
- m_pluginReceivesEvents ? "true" : "false",
node->isPlugin() ? "true" : "false");
#endif
}
@@ -541,9 +532,8 @@ bool cursorIsTextInput(FrameCachePermission allowNewer)
DBG_NAV_LOG("!cursor");
return false;
}
- DBG_NAV_LOGD("%s",
- cursor->isTextArea() || cursor->isTextField() ? "true" : "false");
- return cursor->isTextArea() || cursor->isTextField();
+ DBG_NAV_LOGD("%s", cursor->isTextInput() ? "true" : "false");
+ return cursor->isTextInput();
}
void cursorRingBounds(WebCore::IntRect* bounds)
@@ -609,7 +599,7 @@ void fixCursor()
CachedRoot* getFrameCache(FrameCachePermission allowNewer)
{
if (!m_viewImpl->m_updatedFrameCache) {
- DBG_NAV_LOG("!m_viewImpl->m_updatedFrameCache");
+ DBG_NAV_LOGV("%s", "!m_viewImpl->m_updatedFrameCache");
return m_frameCacheUI;
}
if (allowNewer == DontAllowNewer && m_viewImpl->m_lastGeneration < m_generation) {
@@ -619,6 +609,7 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer)
}
DBG_NAV_LOGD("%s", "m_viewImpl->m_updatedFrameCache == true");
bool hadCursor = m_frameCacheUI && m_frameCacheUI->currentCursor();
+ const CachedNode* oldFocus = m_frameCacheUI ? m_frameCacheUI->currentFocus() : 0;
m_viewImpl->gFrameCacheMutex.lock();
delete m_frameCacheUI;
delete m_navPictureUI;
@@ -629,6 +620,19 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer)
m_viewImpl->m_navPictureKit = 0;
m_viewImpl->gFrameCacheMutex.unlock();
fixCursor();
+ if (oldFocus && m_frameCacheUI) {
+ const CachedNode* newFocus = m_frameCacheUI->currentFocus();
+ if (newFocus && oldFocus->nodePointer() != newFocus->nodePointer()
+ && oldFocus->isTextInput() && newFocus->isTextInput()
+ && newFocus != m_frameCacheUI->currentCursor()) {
+ // The focus has changed. We may need to update things.
+ LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_domChangedFocus);
+ checkException(env);
+ }
+ }
if (hadCursor && (!m_frameCacheUI || !m_frameCacheUI->currentCursor()))
viewInvalidate(); // redraw in case cursor ring is still visible
return m_frameCacheUI;
@@ -638,12 +642,7 @@ int getScaledMaxXScroll()
{
LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return 0;
- int result = env->CallIntMethod(obj.get(), m_javaGlue.m_getScaledMaxXScroll);
+ int result = env->CallIntMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getScaledMaxXScroll);
checkException(env);
return result;
}
@@ -652,12 +651,7 @@ int getScaledMaxYScroll()
{
LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return 0;
- int result = env->CallIntMethod(obj.get(), m_javaGlue.m_getScaledMaxYScroll);
+ int result = env->CallIntMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getScaledMaxYScroll);
checkException(env);
return result;
}
@@ -666,12 +660,7 @@ void getVisibleRect(WebCore::IntRect* rect)
{
LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- jobject jRect = env->CallObjectMethod(obj.get(), m_javaGlue.m_getVisibleRect);
+ jobject jRect = env->CallObjectMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getVisibleRect);
checkException(env);
int left = (int) env->GetIntField(jRect, m_javaGlue.m_rectLeft);
checkException(env);
@@ -738,7 +727,7 @@ void updateCursorBounds(const CachedRoot* root, const CachedFrame* cachedFrame,
LOG_ASSERT(cachedNode, "updateCursorBounds: cachedNode cannot be null");
LOG_ASSERT(cachedFrame, "updateCursorBounds: cachedFrame cannot be null");
m_viewImpl->gCursorBoundsMutex.lock();
- m_viewImpl->m_hasCursorBounds = cachedNode->hasCursorRing();
+ m_viewImpl->m_hasCursorBounds = !cachedNode->isHidden();
// If m_viewImpl->m_hasCursorBounds is false, we never look at the other
// values, so do not bother setting them.
if (m_viewImpl->m_hasCursorBounds) {
@@ -758,7 +747,6 @@ void updateCursorBounds(const CachedRoot* root, const CachedFrame* cachedFrame,
/* returns true if the key had no effect (neither scrolled nor changed cursor) */
bool moveCursor(int keyCode, int count, bool ignoreScroll)
{
- setPluginReceivesEvents(false);
CachedRoot* root = getFrameCache(AllowNewer);
if (!root) {
DBG_NAV_LOG("!root");
@@ -843,21 +831,6 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll)
return result;
}
-bool pluginEatsNavKey()
-{
- CachedRoot* root = getFrameCache(DontAllowNewer);
- if (!root) {
- DBG_NAV_LOG("!root");
- return false;
- }
- const CachedNode* cursor = root->currentCursor();
- DBG_NAV_LOGD("cursor=%p isPlugin=%s pluginReceivesEvents=%s",
- cursor, cursor && cursor->isPlugin() ? "true" : "false",
- m_pluginReceivesEvents ? "true" : "false");
- // FIXME: check to see if plugin wants keys
- return cursor && cursor->isPlugin() && m_pluginReceivesEvents;
-}
-
void notifyProgressFinished()
{
DBG_NAV_LOGD("cursorIsTextInput=%d", cursorIsTextInput(DontAllowNewer));
@@ -929,36 +902,31 @@ void setNavBounds(const WebCore::IntRect& rect)
root->rootHistory()->setNavBounds(rect);
}
-/**
- * This function is only to be called by WebTextView, when there is a motion up
- * on an already focused text input. Unlike motionUp which may change our
- * cursor, it simply passes the click, so it can change the selection.
- * Variables are in content space, relative to the page.
- */
-void textInputMotionUp(int x, int y)
+
+
+const CachedNode* m_cacheHitNode;
+const CachedFrame* m_cacheHitFrame;
+
+bool pointInNavCache(int x, int y, int slop)
{
- const CachedRoot* root = getFrameCache(DontAllowNewer);
- if (!root) {
- return;
- }
- const CachedFrame* frame;
- const CachedNode* node = root->currentCursor(&frame);
- if (node) {
- sendMotionUp(static_cast<WebCore::Frame*>(frame->framePointer()),
- static_cast<WebCore::Node*>(node->nodePointer()), x, y);
- }
+ CachedRoot* root = getFrameCache(AllowNewer);
+ if (!root)
+ return false;
+ IntRect rect = IntRect(x - slop, y - slop, slop * 2, slop * 2);
+ int rx, ry;
+ return (m_cacheHitNode = findAt(root, rect, &m_cacheHitFrame, &rx, &ry));
}
bool motionUp(int x, int y, int slop)
{
bool pageScrolled = false;
m_followedLink = false;
- const CachedFrame* frame;
- WebCore::IntRect rect = WebCore::IntRect(x - slop, y - slop, slop * 2, slop * 2);
+ IntRect rect = IntRect(x - slop, y - slop, slop * 2, slop * 2);
int rx, ry;
CachedRoot* root = getFrameCache(AllowNewer);
if (!root)
- return false;
+ return 0;
+ const CachedFrame* frame = 0;
const CachedNode* result = findAt(root, rect, &frame, &rx, &ry);
if (!result) {
DBG_NAV_LOGD("no nodes found root=%p", root);
@@ -974,30 +942,27 @@ bool motionUp(int x, int y, int slop)
0, x, y);
viewInvalidate();
clearTextEntry();
- setPluginReceivesEvents(false);
return pageScrolled;
}
DBG_NAV_LOGD("CachedNode:%p (%d) x=%d y=%d rx=%d ry=%d", result,
result->index(), x, y, rx, ry);
- setNavBounds(WebCore::IntRect(rx, ry, 1, 1));
+ WebCore::IntRect navBounds = WebCore::IntRect(rx, ry, 1, 1);
+ setNavBounds(navBounds);
+ root->rootHistory()->setMouseBounds(navBounds);
updateCursorBounds(root, frame, result);
root->setCursor(const_cast<CachedFrame*>(frame),
const_cast<CachedNode*>(result));
- updatePluginReceivesEvents();
- CachedNodeType type = result->type();
- if (type == NORMAL_CACHEDNODETYPE) {
+ bool syntheticLink = result->isSyntheticLink();
+ if (!syntheticLink) {
sendMotionUp(
- frame ? (WebCore::Frame*) frame->framePointer() : 0,
- result ? (WebCore::Node*) result->nodePointer() : 0, rx, ry);
+ (WebCore::Frame*) frame->framePointer(),
+ (WebCore::Node*) result->nodePointer(), rx, ry);
}
viewInvalidate();
- if (result->isTextField() || result->isTextArea()) {
- rebuildWebTextView();
- displaySoftKeyboard(true);
- } else {
+ if (!result->isTextInput()) {
clearTextEntry();
setFollowedLink(true);
- if (type != NORMAL_CACHEDNODETYPE)
+ if (syntheticLink)
overrideUrlLoading(result->getExport());
}
return pageScrolled;
@@ -1014,13 +979,9 @@ int getBlockLeftEdge(int x, int y, float scale)
void overrideUrlLoading(const WebCore::String& url)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
jstring jName = env->NewString((jchar*) url.characters(), url.length());
- env->CallVoidMethod(obj.get(), m_javaGlue.m_overrideLoading, jName);
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_overrideLoading, jName);
env->DeleteLocalRef(jName);
}
@@ -1031,35 +992,6 @@ void setFindIsUp(bool up)
m_hasCurrentLocation = false;
}
-void setPluginReceivesEvents(bool value)
-{
- if (value == m_pluginReceivesEvents)
- return;
-
- //send message to plugin in webkit
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_sendPluginState,
- value ? kGainFocus_PluginState : kLoseFocus_PluginState);
- checkException(env);
- m_pluginReceivesEvents = value;
-}
-
-void updatePluginReceivesEvents()
-{
- CachedRoot* root = getFrameCache(DontAllowNewer);
- if (!root)
- return;
- const CachedNode* cursor = root->currentCursor();
- setPluginReceivesEvents(cursor && cursor->isPlugin());
- DBG_NAV_LOGD("m_pluginReceivesEvents=%s cursor=%p", m_pluginReceivesEvents
- ? "true" : "false", cursor);
-}
-
void setFollowedLink(bool followed)
{
if ((m_followedLink = followed) != false) {
@@ -1096,20 +1028,15 @@ void moveSelection(int x, int y, bool extendSelection)
m_selEnd.fLeft, m_selEnd.fTop, m_selEnd.fRight, m_selEnd.fBottom);
}
-const SkRegion& getSelection()
+const String getSelection()
{
- return m_selRegion;
-}
-
-void drawSelection(SkCanvas* canvas, float scale, int offset, int x, int y,
- bool extendSelection)
-{
- if (!extendSelection) {
- drawSelectionArrow(canvas, scale, x, y - offset);
- } else {
- drawSelectionRegion(canvas);
- drawSelectionPointer(canvas, scale, offset, x, y, false);
- }
+ WebCore::IntRect r;
+ getVisibleRect(&r);
+ SkIRect area;
+ area.set(r.x(), r.y(), r.right(), r.bottom());
+ String result = CopyPaste::text(*m_navPictureUI, area, m_selRegion);
+ DBG_NAV_LOGD("text=%s", result.latin1().data());
+ return result;
}
void drawSelectionRegion(SkCanvas* canvas)
@@ -1131,46 +1058,31 @@ void drawSelectionRegion(SkCanvas* canvas)
canvas->drawPath(path, paint);
}
-void drawSelectionPointer(SkCanvas* canvas, float scale, int offset,
- int x, int y, bool gridded)
+void drawSelectionPointer(SkCanvas* canvas, float scale, int x, int y, bool ex)
{
SkPath path;
- getSelectionCaret(&path);
+ if (ex)
+ getSelectionCaret(&path);
+ else
+ getSelectionArrow(&path);
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
paint.setColor(SK_ColorBLACK);
SkPixelXorXfermode xorMode(SK_ColorWHITE);
- paint.setXfermode(&xorMode);
- int sc = canvas->save();
- canvas->scale(scale, scale);
- canvas->translate(0, -SkIntToScalar(offset));
- if (gridded) {
- bool useLeft = x <= (m_selStart.fLeft + m_selStart.fRight) >> 1;
- canvas->translate(SkIntToScalar(useLeft ? m_selStart.fLeft :
- m_selStart.fRight), SkIntToScalar(m_selStart.fTop));
- } else
- canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
- canvas->drawPath(path, paint);
- canvas->restoreToCount(sc);
-}
-
-void drawSelectionArrow(SkCanvas* canvas, float scale, int x, int y)
-{
- SkPath path;
- getSelectionArrow(&path);
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kStroke_Style);
- paint.setColor(SK_ColorBLACK);
- paint.setStrokeWidth(SK_Scalar1 * 2);
+ if (ex)
+ paint.setXfermode(&xorMode);
+ else
+ paint.setStrokeWidth(SK_Scalar1 * 2);
int sc = canvas->save();
canvas->scale(scale, scale);
canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
canvas->drawPath(path, paint);
- paint.setStyle(SkPaint::kFill_Style);
- paint.setColor(SK_ColorWHITE);
- canvas->drawPath(path, paint);
+ if (!ex) {
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setColor(SK_ColorWHITE);
+ canvas->drawPath(path, paint);
+ }
canvas->restoreToCount(sc);
}
@@ -1188,26 +1100,29 @@ void getSelectionCaret(SkPath* path)
{
SkScalar height = SkIntToScalar(m_selStart.fBottom - m_selStart.fTop);
SkScalar dist = height / 4;
- path->lineTo(0, height);
- SkScalar bottom = height + dist;
- path->lineTo(-dist, bottom);
- SkScalar edge = bottom - SK_Scalar1/2;
- path->moveTo(-dist, edge);
- path->lineTo(dist, edge);
- path->moveTo(dist, bottom);
- path->lineTo(0, height);
+ path->moveTo(0, -height / 2);
+ path->rLineTo(0, height);
+ path->rLineTo(-dist, dist);
+ path->rMoveTo(0, -SK_Scalar1/2);
+ path->rLineTo(dist * 2, 0);
+ path->rMoveTo(0, SK_Scalar1/2);
+ path->rLineTo(-dist, -dist);
+}
+
+void sendMoveFocus(WebCore::Frame* framePtr, WebCore::Node* nodePtr)
+{
+ DBG_NAV_LOGD("framePtr=%p nodePtr=%p", framePtr, nodePtr);
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_sendMoveFocus, (jint) framePtr, (jint) nodePtr);
+ checkException(env);
}
void sendMoveMouse(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y)
{
DBG_NAV_LOGD("framePtr=%p nodePtr=%p x=%d y=%d", framePtr, nodePtr, x, y);
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_sendMoveMouse,
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMoveMouse,
(jint) framePtr, (jint) nodePtr, x, y);
checkException(env);
}
@@ -1216,29 +1131,20 @@ void sendMoveMouseIfLatest(bool disableFocusController)
{
LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_sendMoveMouseIfLatest, disableFocusController);
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_sendMoveMouseIfLatest, disableFocusController);
checkException(env);
}
void sendMotionUp(
WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y)
{
- m_viewImpl->m_touchGeneration = m_viewImpl->m_generation = ++m_generation;
+ m_viewImpl->m_touchGeneration = ++m_generation;
DBG_NAV_LOGD("m_generation=%d framePtr=%p nodePtr=%p x=%d y=%d",
m_generation, framePtr, nodePtr, x, y);
LOG_ASSERT(m_javaGlue.m_obj, "A WebView was not associated with this WebViewNative!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_sendMotionUp,
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMotionUp,
m_generation, (jint) framePtr, (jint) nodePtr, x, y);
checkException(env);
}
@@ -1307,12 +1213,7 @@ bool scrollBy(int dx, int dy)
LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return false;
- bool result = env->CallBooleanMethod(obj.get(),
+ bool result = env->CallBooleanMethod(m_javaGlue.object(env).get(),
m_javaGlue.m_scrollBy, dx, dy, true);
checkException(env);
return result;
@@ -1349,62 +1250,30 @@ bool hasFocusNode()
void rebuildWebTextView()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_rebuildWebTextView);
- checkException(env);
-}
-
-void displaySoftKeyboard(bool isTextView)
-{
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(),
- m_javaGlue.m_displaySoftKeyboard, isTextView);
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_rebuildWebTextView);
checkException(env);
}
void viewInvalidate()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_viewInvalidate);
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_viewInvalidate);
checkException(env);
}
void viewInvalidateRect(int l, int t, int r, int b)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_viewInvalidateRect, l, r, t, b);
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_viewInvalidateRect, l, r, t, b);
checkException(env);
}
void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_postInvalidateDelayed,
- delay, bounds.x(), bounds.y(), bounds.right(), bounds.bottom());
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_postInvalidateDelayed,
+ delay, bounds.x(), bounds.y(), bounds.right(), bounds.bottom());
checkException(env);
}
@@ -1420,7 +1289,6 @@ private: // local state for WebView
int m_generation; // associate unique ID with sent kit focus to match with ui
SkPicture* m_navPictureUI;
bool m_followedLink;
- bool m_pluginReceivesEvents;
SkMSec m_ringAnimationEnd;
// Corresponds to the same-named boolean on the java side.
bool m_heightCanMeasure;
@@ -1453,6 +1321,29 @@ static jstring WebCoreStringToJString(JNIEnv *env, WebCore::String string)
return ret;
}
+static int nativeCacheHitFramePointer(JNIEnv *env, jobject obj)
+{
+ return reinterpret_cast<int>(GET_NATIVE_VIEW(env, obj)
+ ->m_cacheHitFrame->framePointer());
+}
+
+static jobject nativeCacheHitNodeBounds(JNIEnv *env, jobject obj)
+{
+ WebCore::IntRect bounds = GET_NATIVE_VIEW(env, obj)
+ ->m_cacheHitNode->originalAbsoluteBounds();
+ jclass rectClass = env->FindClass("android/graphics/Rect");
+ jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V");
+ jobject rect = env->NewObject(rectClass, init, bounds.x(),
+ bounds.y(), bounds.right(), bounds.bottom());
+ return rect;
+}
+
+static int nativeCacheHitNodePointer(JNIEnv *env, jobject obj)
+{
+ return reinterpret_cast<int>(GET_NATIVE_VIEW(env, obj)
+ ->m_cacheHitNode->nodePointer());
+}
+
static void nativeClearCursor(JNIEnv *env, jobject obj)
{
WebView* view = GET_NATIVE_VIEW(env, obj);
@@ -1485,6 +1376,14 @@ static const CachedNode* getCursorNode(JNIEnv *env, jobject obj)
return root ? root->currentCursor() : 0;
}
+static const CachedNode* getCursorNode(JNIEnv *env, jobject obj,
+ const CachedFrame** frame)
+{
+ WebView* view = GET_NATIVE_VIEW(env, obj);
+ CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
+ return root ? root->currentCursor(frame) : 0;
+}
+
static const CachedNode* getFocusCandidate(JNIEnv *env, jobject obj)
{
WebView* view = GET_NATIVE_VIEW(env, obj);
@@ -1504,6 +1403,19 @@ static const CachedNode* getFocusNode(JNIEnv *env, jobject obj)
return root ? root->currentFocus() : 0;
}
+static const CachedInput* getInputCandidate(JNIEnv *env, jobject obj)
+{
+ WebView* view = GET_NATIVE_VIEW(env, obj);
+ CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
+ if (!root)
+ return 0;
+ const CachedFrame* frame;
+ const CachedNode* cursor = root->currentCursor(&frame);
+ if (!cursor || !cursor->wantsKeyEvents())
+ cursor = root->currentFocus(&frame);
+ return cursor ? frame->textInput(cursor) : 0;
+}
+
static jboolean nativeCursorMatchesFocus(JNIEnv *env, jobject obj)
{
const CachedNode* cursor = getCursorNode(env, obj);
@@ -1562,16 +1474,10 @@ static bool nativeCursorIsAnchor(JNIEnv *env, jobject obj)
return node ? node->isAnchor() : false;
}
-static bool nativeCursorIsPlugin(JNIEnv *env, jobject obj)
-{
- const CachedNode* node = getCursorNode(env, obj);
- return node ? node->isPlugin() : false;
-}
-
static bool nativeCursorIsTextInput(JNIEnv *env, jobject obj)
{
const CachedNode* node = getCursorNode(env, obj);
- return node ? node->isTextField() || node->isTextArea() : false;
+ return node ? node->isTextInput() : false;
}
static jobject nativeCursorText(JNIEnv *env, jobject obj)
@@ -1608,6 +1514,86 @@ static void nativeDrawMatches(JNIEnv *env, jobject obj, jobject canv)
view->drawMatches(canvas);
}
+static void nativeDrawLayers(JNIEnv *env, jobject obj,
+ jint layer, jfloat scrollX, jfloat scrollY,
+ jfloat scale, jobject canv)
+{
+ if (!env)
+ return;
+ if (!layer)
+ return;
+ if (!canv)
+ return;
+
+#if USE(ACCELERATED_COMPOSITING)
+ LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer);
+ SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv);
+ if (canvas)
+ layerImpl->paintOn(scrollX, scrollY, scale, canvas);
+#endif
+}
+
+static void nativeUpdateLayers(JNIEnv *env, jobject obj,
+ jint layer, jint updates)
+{
+ if (!env)
+ return;
+ if (!layer)
+ return;
+ if (!updates)
+ return;
+
+#if USE(ACCELERATED_COMPOSITING)
+ Vector<RefPtr<AndroidAnimationValue> >* updatesImpl =
+ reinterpret_cast<Vector<RefPtr<AndroidAnimationValue> >* >(updates);
+ if (updatesImpl) {
+ for (unsigned int i = 0; i < updatesImpl->size(); i++)
+ (updatesImpl->at(i))->apply();
+ delete updatesImpl;
+ }
+#endif
+}
+
+static bool nativeLayersHaveAnimations(JNIEnv *env, jobject obj, jint layer)
+{
+ if (!env)
+ return false;
+ if (!layer)
+ return false;
+#if USE(ACCELERATED_COMPOSITING)
+ LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer);
+ return layerImpl->hasAnimations();
+#else
+ return false;
+#endif
+}
+
+static int nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj, jint layer)
+{
+ if (!env)
+ return 0;
+ if (!layer)
+ return 0;
+#if USE(ACCELERATED_COMPOSITING)
+ LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer);
+ return reinterpret_cast<int>(layerImpl->evaluateAnimations());
+#else
+ return 0;
+#endif
+}
+
+static void nativeDestroyLayer(JNIEnv *env, jobject obj, jint layer)
+{
+ if (!env)
+ return;
+ if (!layer)
+ return;
+#if USE(ACCELERATED_COMPOSITING)
+ LayerAndroid* layerImpl = reinterpret_cast<LayerAndroid*>(layer);
+ delete layerImpl;
+#endif
+}
+
static void nativeDrawCursorRing(JNIEnv *env, jobject obj, jobject canv)
{
SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv);
@@ -1623,8 +1609,8 @@ static void nativeDrawCursorRing(JNIEnv *env, jobject obj, jobject canv)
view->drawCursorRing(canvas);
}
-static void nativeDrawSelection(JNIEnv *env, jobject obj,
- jobject canv, jfloat scale, jint offset, jint x, jint y, bool ex)
+static void nativeDrawSelectionPointer(JNIEnv *env, jobject obj,
+ jobject canv, jfloat scale, jint x, jint y, bool ex)
{
SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, canv);
if (!canv) {
@@ -1636,7 +1622,7 @@ static void nativeDrawSelection(JNIEnv *env, jobject obj,
DBG_NAV_LOG("!view");
return;
}
- view->drawSelection(canvas, scale, offset, x, y, ex);
+ view->drawSelectionPointer(canvas, scale, x, y, ex);
}
static void nativeDrawSelectionRegion(JNIEnv *env, jobject obj, jobject canv)
@@ -1668,42 +1654,49 @@ static jobject nativeImageURI(JNIEnv *env, jobject obj, jint x, jint y)
return ret;
}
-static bool nativeFocusCandidateIsPassword(JNIEnv *env, jobject obj)
+static jint nativeFocusCandidateFramePointer(JNIEnv *env, jobject obj)
{
- const CachedNode* node = getFocusCandidate(env, obj);
- return node ? node->isPassword() : false;
+ WebView* view = GET_NATIVE_VIEW(env, obj);
+ CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
+ if (!root)
+ return 0;
+ const CachedFrame* frame = 0;
+ const CachedNode* cursor = root->currentCursor(&frame);
+ if (!cursor || !cursor->wantsKeyEvents())
+ (void) root->currentFocus(&frame);
+ return reinterpret_cast<int>(frame ? frame->framePointer() : 0);
}
-static bool nativeFocusCandidateIsRtlText(JNIEnv *env, jobject obj)
+static bool nativeFocusCandidateIsPassword(JNIEnv *env, jobject obj)
{
- const CachedNode* node = getFocusCandidate(env, obj);
- return node ? node->isRtlText() : false;
+ const CachedInput* input = getInputCandidate(env, obj);
+ return input && input->inputType() == WebCore::HTMLInputElement::PASSWORD;
}
-static bool nativeFocusCandidateIsTextField(JNIEnv *env, jobject obj)
+static bool nativeFocusCandidateIsRtlText(JNIEnv *env, jobject obj)
{
- const CachedNode* node = getFocusCandidate(env, obj);
- return node ? node->isTextField() : false;
+ const CachedInput* input = getInputCandidate(env, obj);
+ return input ? input->isRtlText() : false;
}
static bool nativeFocusCandidateIsTextInput(JNIEnv *env, jobject obj)
{
const CachedNode* node = getFocusCandidate(env, obj);
- return node ? node->isTextField() || node->isTextArea() : false;
+ return node ? node->isTextInput() : false;
}
static jint nativeFocusCandidateMaxLength(JNIEnv *env, jobject obj)
{
- const CachedNode* node = getFocusCandidate(env, obj);
- return node ? node->maxLength() : false;
+ const CachedInput* input = getInputCandidate(env, obj);
+ return input ? input->maxLength() : false;
}
static jobject nativeFocusCandidateName(JNIEnv *env, jobject obj)
{
- const CachedNode* node = getFocusCandidate(env, obj);
- if (!node)
+ const CachedInput* input = getInputCandidate(env, obj);
+ if (!input)
return 0;
- const WebCore::String& name = node->name();
+ const WebCore::String& name = input->name();
return env->NewString((jchar*)name.characters(), name.length());
}
@@ -1737,8 +1730,49 @@ static jobject nativeFocusCandidateText(JNIEnv *env, jobject obj)
static jint nativeFocusCandidateTextSize(JNIEnv *env, jobject obj)
{
- const CachedNode* node = getFocusCandidate(env, obj);
- return node ? node->textSize() : 0;
+ const CachedInput* input = getInputCandidate(env, obj);
+ return input ? input->textSize() : 0;
+}
+
+enum type {
+ NONE = -1,
+ NORMAL_TEXT_FIELD = 0,
+ TEXT_AREA = 1,
+ PASSWORD = 2,
+ SEARCH = 3,
+ EMAIL = 4,
+ NUMBER = 5,
+ TELEPHONE = 6,
+ URL = 7
+};
+
+static int nativeFocusCandidateType(JNIEnv *env, jobject obj)
+{
+ const CachedInput* input = getInputCandidate(env, obj);
+ if (!input) return NONE;
+ if (!input->isTextField()) return TEXT_AREA;
+ switch (input->inputType()) {
+ case HTMLInputElement::PASSWORD:
+ return PASSWORD;
+ case HTMLInputElement::SEARCH:
+ return SEARCH;
+ case HTMLInputElement::EMAIL:
+ return EMAIL;
+ case HTMLInputElement::NUMBER:
+ return NUMBER;
+ case HTMLInputElement::TELEPHONE:
+ return TELEPHONE;
+ case HTMLInputElement::URL:
+ return URL;
+ default:
+ return NORMAL_TEXT_FIELD;
+ }
+}
+
+static bool nativeFocusIsPlugin(JNIEnv *env, jobject obj)
+{
+ const CachedNode* node = getFocusNode(env, obj);
+ return node ? node->isPlugin() : false;
}
static jint nativeFocusNodePointer(JNIEnv *env, jobject obj)
@@ -1782,10 +1816,10 @@ static jint nativeTextGeneration(JNIEnv *env, jobject obj)
return root ? root->textGeneration() : 0;
}
-static void nativeTextInputMotionUp(JNIEnv *env, jobject obj, int x, int y)
+static bool nativePointInNavCache(JNIEnv *env, jobject obj,
+ int x, int y, int slop)
{
- WebView* view = GET_NATIVE_VIEW(env, obj);
- view->textInputMotionUp(x, y);
+ return GET_NATIVE_VIEW(env, obj)->pointInNavCache(x, y, slop);
}
static bool nativeMotionUp(JNIEnv *env, jobject obj,
@@ -1823,18 +1857,13 @@ static void nativeRecordButtons(JNIEnv* env, jobject obj, bool hasFocus,
view->nativeRecordButtons(hasFocus, pressed, invalidate);
}
-static void nativeSetFindIsDown(JNIEnv *env, jobject obj)
+static void nativeSetFindIsUp(JNIEnv *env, jobject obj)
{
WebView* view = GET_NATIVE_VIEW(env, obj);
LOG_ASSERT(view, "view not set in %s", __FUNCTION__);
view->setFindIsUp(false);
}
-static void nativeUpdatePluginReceivesEvents(JNIEnv *env, jobject obj)
-{
- GET_NATIVE_VIEW(env, obj)->updatePluginReceivesEvents();
-}
-
static void nativeSetFollowedLink(JNIEnv *env, jobject obj, bool followed)
{
WebView* view = GET_NATIVE_VIEW(env, obj);
@@ -1937,7 +1966,7 @@ static void nativeUpdateCachedTextfield(JNIEnv *env, jobject obj, jstring update
if (!root)
return;
const CachedNode* cachedFocusNode = root->currentFocus();
- if (!cachedFocusNode || (!cachedFocusNode->isTextField() && !cachedFocusNode->isTextArea()))
+ if (!cachedFocusNode || !cachedFocusNode->isTextInput())
return;
WebCore::String webcoreString = to_string(env, updatedText);
(const_cast<CachedNode*>(cachedFocusNode))->setExport(webcoreString);
@@ -1969,11 +1998,13 @@ static void nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj)
CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
if (!root)
return;
- const CachedNode* cursor = root->currentCursor();
- if (!cursor)
+ const CachedNode* current = root->currentCursor();
+ if (!current)
+ current = root->currentFocus();
+ if (!current)
return;
const CachedFrame* frame;
- const CachedNode* next = root->nextTextField(cursor, &frame, true);
+ const CachedNode* next = root->nextTextField(current, &frame, true);
if (!next)
return;
const WebCore::IntRect& bounds = next->bounds();
@@ -1981,12 +2012,11 @@ static void nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj)
view->updateCursorBounds(root, frame, next);
root->setCursor(const_cast<CachedFrame*>(frame),
const_cast<CachedNode*>(next));
- WebCore::IntPoint pos;
- root->getSimulatedMousePosition(&pos);
- view->sendMoveMouse(static_cast<WebCore::Frame*>(frame->framePointer()),
- static_cast<WebCore::Node*>(next->nodePointer()), pos.x(), pos.y());
+ view->sendMoveFocus(static_cast<WebCore::Frame*>(frame->framePointer()),
+ static_cast<WebCore::Node*>(next->nodePointer()));
view->scrollRectOnScreen(bounds.x(), bounds.y(), bounds.right(),
bounds.bottom());
+ view->getWebViewCore()->m_moveGeneration++;
}
static jint nativeTextFieldAction(JNIEnv *env, jobject obj)
@@ -1995,7 +2025,7 @@ static jint nativeTextFieldAction(JNIEnv *env, jobject obj)
CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
if (!root)
return static_cast<jint>(CachedRoot::FAILURE);
- return static_cast<jint>(root->cursorTextFieldAction());
+ return static_cast<jint>(root->currentTextFieldAction());
}
static int nativeMoveGeneration(JNIEnv *env, jobject obj)
@@ -2013,16 +2043,12 @@ static void nativeMoveSelection(JNIEnv *env, jobject obj, int x, int y, bool ex)
view->moveSelection(x, y, ex);
}
-static bool nativePluginEatsNavKey(JNIEnv *env, jobject obj)
-{
- return GET_NATIVE_VIEW(env, obj)->pluginEatsNavKey();
-}
-
static jobject nativeGetSelection(JNIEnv *env, jobject obj)
{
WebView* view = GET_NATIVE_VIEW(env, obj);
LOG_ASSERT(view, "view not set in %s", __FUNCTION__);
- return GraphicsJNI::createRegion(env, new SkRegion(view->getSelection()));
+ String selection = view->getSelection();
+ return env->NewString((jchar*)selection.characters(), selection.length());
}
#ifdef ANDROID_DUMP_DISPLAY_TREE
@@ -2066,6 +2092,12 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl)
* JNI registration
*/
static JNINativeMethod gJavaWebViewMethods[] = {
+ { "nativeCacheHitFramePointer", "()I",
+ (void*) nativeCacheHitFramePointer },
+ { "nativeCacheHitNodeBounds", "()Landroid/graphics/Rect;",
+ (void*) nativeCacheHitNodeBounds },
+ { "nativeCacheHitNodePointer", "()I",
+ (void*) nativeCacheHitNodePointer },
{ "nativeClearCursor", "()V",
(void*) nativeClearCursor },
{ "nativeCreate", "(I)V",
@@ -2082,8 +2114,6 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeCursorIntersects },
{ "nativeCursorIsAnchor", "()Z",
(void*) nativeCursorIsAnchor },
- { "nativeCursorIsPlugin", "()Z",
- (void*) nativeCursorIsPlugin },
{ "nativeCursorIsTextInput", "()Z",
(void*) nativeCursorIsTextInput },
{ "nativeCursorPosition", "()Landroid/graphics/Point;",
@@ -2098,10 +2128,20 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeDestroy },
{ "nativeDrawCursorRing", "(Landroid/graphics/Canvas;)V",
(void*) nativeDrawCursorRing },
+ { "nativeDestroyLayer", "(I)V",
+ (void*) nativeDestroyLayer },
+ { "nativeLayersHaveAnimations", "(I)Z",
+ (void*) nativeLayersHaveAnimations },
+ { "nativeEvaluateLayersAnimations", "(I)I",
+ (void*) nativeEvaluateLayersAnimations },
+ { "nativeDrawLayers", "(IFFFLandroid/graphics/Canvas;)V",
+ (void*) nativeDrawLayers },
+ { "nativeUpdateLayers", "(II)V",
+ (void*) nativeUpdateLayers },
{ "nativeDrawMatches", "(Landroid/graphics/Canvas;)V",
(void*) nativeDrawMatches },
- { "nativeDrawSelection", "(Landroid/graphics/Canvas;FIIIZ)V",
- (void*) nativeDrawSelection },
+ { "nativeDrawSelectionPointer", "(Landroid/graphics/Canvas;FIIZ)V",
+ (void*) nativeDrawSelectionPointer },
{ "nativeDrawSelectionRegion", "(Landroid/graphics/Canvas;)V",
(void*) nativeDrawSelectionRegion },
{ "nativeDumpDisplayTree", "(Ljava/lang/String;)V",
@@ -2110,12 +2150,12 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeFindAll },
{ "nativeFindNext", "(Z)V",
(void*) nativeFindNext },
+ { "nativeFocusCandidateFramePointer", "()I",
+ (void*) nativeFocusCandidateFramePointer },
{ "nativeFocusCandidateIsPassword", "()Z",
(void*) nativeFocusCandidateIsPassword },
{ "nativeFocusCandidateIsRtlText", "()Z",
(void*) nativeFocusCandidateIsRtlText },
- { "nativeFocusCandidateIsTextField", "()Z",
- (void*) nativeFocusCandidateIsTextField },
{ "nativeFocusCandidateIsTextInput", "()Z",
(void*) nativeFocusCandidateIsTextInput },
{ "nativeFocusCandidateMaxLength", "()I",
@@ -2130,11 +2170,15 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeFocusCandidateText },
{ "nativeFocusCandidateTextSize", "()I",
(void*) nativeFocusCandidateTextSize },
+ { "nativeFocusCandidateType", "()I",
+ (void*) nativeFocusCandidateType },
+ { "nativeFocusIsPlugin", "()Z",
+ (void*) nativeFocusIsPlugin },
{ "nativeFocusNodePointer", "()I",
(void*) nativeFocusNodePointer },
{ "nativeGetCursorRingBounds", "()Landroid/graphics/Rect;",
(void*) nativeGetCursorRingBounds },
- { "nativeGetSelection", "()Landroid/graphics/Region;",
+ { "nativeGetSelection", "()Ljava/lang/String;",
(void*) nativeGetSelection },
{ "nativeHasCursorNode", "()Z",
(void*) nativeHasCursorNode },
@@ -2146,8 +2190,6 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeImageURI },
{ "nativeInstrumentReport", "()V",
(void*) nativeInstrumentReport },
- { "nativeTextInputMotionUp", "(II)V",
- (void*) nativeTextInputMotionUp },
{ "nativeMotionUp", "(III)Z",
(void*) nativeMotionUp },
{ "nativeMoveCursor", "(IIZ)Z",
@@ -2158,14 +2200,14 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeMoveGeneration },
{ "nativeMoveSelection", "(IIZ)V",
(void*) nativeMoveSelection },
- { "nativePluginEatsNavKey", "()Z",
- (void*) nativePluginEatsNavKey },
+ { "nativePointInNavCache", "(III)Z",
+ (void*) nativePointInNavCache },
{ "nativeRecordButtons", "(ZZZ)V",
(void*) nativeRecordButtons },
{ "nativeSelectBestAt", "(Landroid/graphics/Rect;)V",
(void*) nativeSelectBestAt },
- { "nativeSetFindIsDown", "()V",
- (void*) nativeSetFindIsDown },
+ { "nativeSetFindIsUp", "()V",
+ (void*) nativeSetFindIsUp },
{ "nativeSetFollowedLink", "(Z)V",
(void*) nativeSetFollowedLink },
{ "nativeSetHeightCanMeasure", "(Z)V",
@@ -2178,8 +2220,6 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeUpdateCachedTextfield },
{ "nativeGetBlockLeftEdge", "(IIF)I",
(void*) nativeGetBlockLeftEdge },
- { "nativeUpdatePluginReceivesEvents", "()V",
- (void*) nativeUpdatePluginReceivesEvents }
};
int register_webview(JNIEnv* env)