summaryrefslogtreecommitdiffstats
path: root/WebKit/android/nav/CacheBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android/nav/CacheBuilder.cpp')
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp209
1 files changed, 162 insertions, 47 deletions
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index f69b23d..1d53721 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -26,6 +26,7 @@
#include "CachedPrefix.h"
#include "CachedNode.h"
#include "CachedRoot.h"
+#include "ColumnInfo.h"
#include "Document.h"
#include "EventListener.h"
#include "EventNames.h"
@@ -412,7 +413,7 @@ void CacheBuilder::Debug::groups() {
comma(scratch);
Element* element = static_cast<Element*>(node);
if (node->isElementNode() && element->hasID())
- wideString(element->getIDAttribute());
+ wideString(element->getIdAttribute());
else if (node->isTextNode()) {
#if 01 // set to one to abbreviate text that can be omitted from the address detection code
if (rect.isEmpty() && node->textContent().length() > 100) {
@@ -469,22 +470,50 @@ void CacheBuilder::Debug::groups() {
}
}
}
- count++;
- newLine();
-#if USE(ACCELERATED_COMPOSITING)
- if (renderer && layer) {
+ if (renderer) {
+ RenderStyle* style = renderer->style();
+ snprintf(scratch, sizeof(scratch), "// renderStyle:"
+ " visibility=%s hasBackGround=%d"
+ " tapHighlightColor().alpha()=0x%02x"
+ " isTransparent()=%s",
+ style->visibility() == HIDDEN ? "HIDDEN" : "VISIBLE",
+ renderer->hasBackground(), style->tapHighlightColor().alpha(),
+ renderer->isTransparent() ? "true" : "false");
+ newLine();
+ print(scratch);
+ RenderBlock* renderBlock = static_cast<RenderBlock*>(renderer);
+ if (renderer->isRenderBlock() && renderBlock->hasColumns()) {
+ const RenderBox* box = static_cast<RenderBox*>(renderer);
+ const IntRect& oRect = box->visibleOverflowRect();
+ snprintf(scratch, sizeof(scratch), "// renderBlock:"
+ " columnCount=%d columnGap=%d direction=%d"
+ " hasOverflowClip=%d overflow=(%d,%d,w=%d,h=%d)",
+ renderBlock->columnInfo()->columnCount(), renderBlock->columnGap(),
+ renderBlock->style()->direction(), renderer->hasOverflowClip(),
+ oRect.x(), oRect.y(), oRect.width(), oRect.height());
+ newLine();
+ print(scratch);
+ }
+ }
+ #if USE(ACCELERATED_COMPOSITING)
+ if (renderer && renderer->hasLayer()) {
+ RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
RenderLayerBacking* back = layer->backing();
GraphicsLayerAndroid* grLayer = static_cast
<GraphicsLayerAndroid*>(back ? back->graphicsLayer() : 0);
LayerAndroid* aLayer = grLayer ? grLayer->contentLayer() : 0;
const SkPicture* pict = aLayer ? aLayer->picture() : 0;
+ const IntRect& r = renderer->absoluteBoundingBoxRect();
snprintf(scratch, sizeof(scratch), "// layer:%p back:%p"
- " gLayer:%p aLayer:%p pict:%p", layer, back, grLayer,
- aLayer, pict);
- print(scratch);
+ " gLayer:%p aLayer:%p pict:%p r:(%d,%d,w=%d,h=%d)",
+ layer, back, grLayer, aLayer, pict, r.x(), r.y(),
+ r.width(), r.height());
newLine();
- }
-#endif
+ print(scratch);
+ }
+ #endif
+ count++;
+ newLine();
} while ((node = node->traverseNextNode()) != NULL);
DUMP_NAV_LOGD("}; // focusables = %d\n", count - 1);
DUMP_NAV_LOGD("\n");
@@ -553,7 +582,7 @@ void CacheBuilder::Debug::groups() {
mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d",
0 /*textBox->spaceAdd()*/, textBox->start(), 0 /*textBox->textPos()*/);
mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d, %d",
- textBox->x(), textBox->y(), textBox->width(), textBox->height());
+ textBox->x(), textBox->y(), textBox->logicalWidth(), textBox->logicalHeight());
int baseline = textBox->renderer()->style(textBox->isFirstLineStyle())->font().ascent();
mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d }, // %d ",
baseline, ++rectIndex);
@@ -754,16 +783,18 @@ CacheBuilder::CacheBuilder()
}
void CacheBuilder::adjustForColumns(const ClipColumnTracker& track,
- CachedNode* node, IntRect* bounds)
+ CachedNode* node, IntRect* bounds, RenderBlock* renderer)
{
+ if (!renderer->hasColumns())
+ return;
int x = 0;
int y = 0;
int tx = track.mBounds.x();
int ty = track.mBounds.y();
int columnGap = track.mColumnGap;
- size_t limit = track.mColumns->size();
+ size_t limit = track.mColumnInfo->columnCount();
for (size_t index = 0; index < limit; index++) {
- IntRect column = track.mColumns->at(index);
+ IntRect column = renderer->columnRectAt(track.mColumnInfo, index);
column.move(tx, ty);
IntRect test = *bounds;
test.move(x, y);
@@ -841,6 +872,7 @@ bool CacheBuilder::AnyIsClick(Node* node)
void CacheBuilder::buildCache(CachedRoot* root)
{
Frame* frame = FrameAnd(this);
+ mPictureSetDisabled = false;
BuildFrame(frame, frame, root, (CachedFrame*) root);
root->finishInit(); // set up frame parent pointers, child pointers
setData((CachedFrame*) root);
@@ -878,7 +910,7 @@ static Node* OneAfter(Node* node)
static bool checkForPluginViewThatWantsFocus(RenderObject* renderer) {
if (renderer->isWidget()) {
Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
- if (widget && (widget->isPluginView() || widget->isPluginWidget())) {
+ if (widget && (widget->isPluginView() || widget->isPluginViewBase())) {
// check if this plugin really wants key events (TODO)
return true;
}
@@ -888,7 +920,7 @@ static bool checkForPluginViewThatWantsFocus(RenderObject* renderer) {
#if USE(ACCELERATED_COMPOSITING)
static void AddLayer(CachedFrame* frame, size_t index, const IntPoint& location,
- int id)
+ const IntPoint& scroll, int id)
{
DBG_NAV_LOGD("frame=%p index=%d loc=(%d,%d) id=%d", frame, index,
location.x(), location.y(), id);
@@ -896,11 +928,41 @@ static void AddLayer(CachedFrame* frame, size_t index, const IntPoint& location,
cachedLayer.reset();
cachedLayer.setCachedNodeIndex(index);
cachedLayer.setOffset(location);
+ cachedLayer.setScrollOffset(scroll);
cachedLayer.setUniqueId(id);
frame->add(cachedLayer);
}
#endif
+static int FindColorIndex(WTF::Vector<CachedColor>& colorTracker,
+ const CachedColor& cachedColor)
+{
+ CachedColor* work = colorTracker.begin() - 1;
+ CachedColor* end = colorTracker.end();
+ while (++work < end) {
+ if (*work == cachedColor)
+ return work - colorTracker.begin();
+ }
+ int result = colorTracker.size();
+ colorTracker.grow(result + 1);
+ CachedColor& newColor = colorTracker.last();
+ newColor = cachedColor;
+ return result;
+}
+
+static void InitColor(CachedColor* color)
+{
+ color->setFillColor(RenderStyle::initialRingFillColor());
+ color->setInnerWidth(RenderStyle::initialRingInnerWidth());
+ color->setOuterWidth(RenderStyle::initialRingOuterWidth());
+ color->setOutset(RenderStyle::initialRingOutset());
+ color->setPressedInnerColor(RenderStyle::initialRingPressedInnerColor());
+ color->setPressedOuterColor(RenderStyle::initialRingPressedOuterColor());
+ color->setRadius(RenderStyle::initialRingRadius());
+ color->setSelectedInnerColor(RenderStyle::initialRingSelectedInnerColor());
+ color->setSelectedOuterColor(RenderStyle::initialRingSelectedOuterColor());
+}
+
// when new focus is found, push it's parent on a stack
// as long as more focii are found with the same (grand) parent, note it
// (which only requires retrieving the last parent on the stack)
@@ -928,6 +990,8 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
bzero(clipTracker.data(), sizeof(ClipColumnTracker));
WTF::Vector<TabIndexTracker> tabIndexTracker(1); // sentinel
bzero(tabIndexTracker.data(), sizeof(TabIndexTracker));
+ WTF::Vector<CachedColor> colorTracker(1);
+ InitColor(colorTracker.data());
#if DUMP_NAV_CACHE
char* frameNamePtr = cachedFrame->mDebug.mFrameName;
Builder(frame)->mDebug.frameName(frameNamePtr, frameNamePtr +
@@ -943,16 +1007,18 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
#if DUMP_NAV_CACHE
cachedParentNode.mDebug.mNodeIndex = nodeIndex;
#endif
+ cachedFrame->add(colorTracker[0]);
cachedFrame->add(cachedParentNode);
Node* node = parent;
int cacheIndex = 1;
+ int colorIndex = 0; // assume no special css ring colors
+ const void* lastStyleDataPtr = 0;
int textInputIndex = 0;
Node* focused = doc->focusedNode();
if (focused)
cachedRoot->setFocusBounds(focused->getRect());
int globalOffsetX, globalOffsetY;
GetGlobalOffset(frame, &globalOffsetX, &globalOffsetY);
- IntPoint bodyPos = IntPoint(0, 0);
while (walk.mMore || (node = node->traverseNextNode()) != NULL) {
#if DUMP_NAV_CACHE
nodeIndex++;
@@ -1028,21 +1094,25 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
RenderStyle* style = nodeRenderer->style();
if (style->visibility() == HIDDEN)
continue;
- isTransparent = style->hasBackground() == false;
+ isTransparent = nodeRenderer->hasBackground() == false;
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
hasCursorRing = style->tapHighlightColor().alpha() > 0;
#endif
#if USE(ACCELERATED_COMPOSITING)
if (nodeRenderer->hasLayer()) {
TrackLayer(layerTracker, nodeRenderer, lastChild,
- globalOffsetX - bodyPos.x(), globalOffsetY - bodyPos.y());
+ globalOffsetX, globalOffsetY);
size_t size = tracker.size();
- const LayerAndroid* layer = layerTracker.last().mLayer;
+ LayerAndroid* layer = layerTracker.last().mLayer;
if (layer) {
int id = layer->uniqueId();
- IntPoint loc = nodeRenderer->
- absoluteBoundingBoxRect().location();
+ const RenderLayer* renderLayer =
+ layerTracker.last().mRenderLayer;
+ IntPoint loc(SkScalarRound(layer->getPosition().fX),
+ SkScalarRound(layer->getPosition().fY));
loc.move(globalOffsetX, globalOffsetY);
+ IntPoint scroll(renderLayer->scrollXOffset(),
+ renderLayer->scrollYOffset());
// if this is a child of a CachedNode, add a layer
size_t limit = cachedFrame->layerCount() == 0 ? 0 :
cachedFrame->lastLayer()->cachedNodeIndex();
@@ -1058,7 +1128,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
CachedNode* trackedNode = cachedFrame->getIndex(index);
trackedNode->setIsInLayer(true);
trackedNode->setIsUnclipped(true);
- AddLayer(cachedFrame, index, loc, id);
+ AddLayer(cachedFrame, index, loc, scroll, id);
}
}
}
@@ -1077,11 +1147,12 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
TextDirection direction = LTR;
String exported;
CachedNodeType type = NORMAL_CACHEDNODETYPE;
+ CachedColor cachedColor;
CachedInput cachedInput;
IntRect bounds;
IntRect absBounds;
IntRect originalAbsBounds;
- WTF::Vector<IntRect>* columns = NULL;
+ ColumnInfo* columnInfo = NULL;
if (node->hasTagName(HTMLNames::areaTag)) {
type = AREA_CACHEDNODETYPE;
HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node);
@@ -1102,9 +1173,16 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
originalAbsBounds = absBounds;
absBounds.move(globalOffsetX, globalOffsetY);
hasClip = nodeRenderer->hasOverflowClip();
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ if (nodeRenderer->hasLayer()) {
+ const LayerAndroid* layer = layerTracker.last().mLayer;
+ if (layer && layer->contentIsScrollable())
+ hasClip = false;
+ }
+#endif
- if (node->hasTagName(HTMLNames::bodyTag))
- bodyPos = originalAbsBounds.location();
+ if (node->hasTagName(HTMLNames::canvasTag))
+ mPictureSetDisabled = true;
if (checkForPluginViewThatWantsFocus(nodeRenderer)) {
bounds = absBounds;
isUnclipped = true;
@@ -1112,27 +1190,32 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
type = PLUGIN_CACHEDNODETYPE;
goto keepNode;
}
+ // Only use the root contentEditable element
+ if (node->isContentEditable() && !node->parent()->isContentEditable()) {
+ bounds = absBounds;
+ takesFocus = true;
+ type = CONTENT_EDITABLE_CACHEDNODETYPE;
+ goto keepNode;
+ }
if (nodeRenderer->isRenderBlock()) {
RenderBlock* renderBlock = (RenderBlock*) nodeRenderer;
if (renderBlock->hasColumns()) {
- columns = renderBlock->columnRects();
-#ifdef ANDROID_EXPOSE_COLUMN_GAP
+ columnInfo = renderBlock->columnInfo();
columnGap = renderBlock->columnGap();
-#endif
direction = renderBlock->style()->direction();
}
}
- if ((hasClip != false || columns != NULL) && lastChild) {
+ if ((hasClip != false || columnInfo != NULL) && lastChild) {
clipTracker.grow(clipTracker.size() + 1);
ClipColumnTracker& clip = clipTracker.last();
clip.mBounds = absBounds;
clip.mLastChild = OneAfter(lastChild);
clip.mNode = node;
- clip.mColumns = columns;
+ clip.mColumnInfo = columnInfo;
clip.mColumnGap = columnGap;
clip.mHasClip = hasClip;
clip.mDirection = direction;
- if (columns != NULL) {
+ if (columnInfo != NULL) {
const IntRect& oRect = ((RenderBox*)nodeRenderer)->visibleOverflowRect();
clip.mBounds.move(oRect.x(), oRect.y());
}
@@ -1177,7 +1260,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
}
if (node->hasTagName(WebCore::HTMLNames::inputTag)) {
HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
- HTMLInputElement::InputType inputType = input->inputType();
+ HTMLInputElement::DeprecatedInputType inputType = input->deprecatedInputType();
if (input->isTextField()) {
type = TEXT_INPUT_CACHEDNODETYPE;
cachedInput.init();
@@ -1216,6 +1299,8 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
if (!href.isEmpty() && !WebCore::protocolIsJavaScript(href.string()))
// Set the exported string for all non-javascript anchors.
exported = href.string().threadsafeCopy();
+ } else if (node->hasTagName(HTMLNames::selectTag)) {
+ type = SELECT_CACHEDNODETYPE;
}
if (type == TEXT_INPUT_CACHEDNODETYPE) {
RenderTextControl* renderText =
@@ -1262,6 +1347,28 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
globalOffsetX, globalOffsetY, &cachedNode.mCursorRing) == false)
continue;
keepTextNode:
+ if (nodeRenderer) { // area tags' node->renderer() == 0
+ RenderStyle* style = nodeRenderer->style();
+ const void* styleDataPtr = style->ringData();
+ // to save time, see if we're pointing to the same style data as before
+ if (lastStyleDataPtr != styleDataPtr) {
+ lastStyleDataPtr = styleDataPtr;
+ cachedColor.setFillColor(style->ringFillColor());
+ cachedColor.setInnerWidth(style->ringInnerWidth());
+ cachedColor.setOuterWidth(style->ringOuterWidth());
+ cachedColor.setOutset(style->ringOutset());
+ cachedColor.setPressedInnerColor(style->ringPressedInnerColor());
+ cachedColor.setPressedOuterColor(style->ringPressedOuterColor());
+ cachedColor.setRadius(style->ringRadius());
+ cachedColor.setSelectedInnerColor(style->ringSelectedInnerColor());
+ cachedColor.setSelectedOuterColor(style->ringSelectedOuterColor());
+ int oldSize = colorTracker.size();
+ colorIndex = FindColorIndex(colorTracker, cachedColor);
+ if (colorIndex == oldSize)
+ cachedFrame->add(cachedColor);
+ }
+ } else
+ colorIndex = 0;
IntRect clip = hasClip ? bounds : absBounds;
size_t clipIndex = clipTracker.size();
if (clipTracker.last().mNode == node)
@@ -1269,7 +1376,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
while (--clipIndex > 0) {
const ClipColumnTracker& clipTrack = clipTracker.at(clipIndex);
if (clipTrack.mHasClip == false) {
- adjustForColumns(clipTrack, &cachedNode, &absBounds);
+ adjustForColumns(clipTrack, &cachedNode, &absBounds, static_cast<RenderBlock*>(nodeRenderer));
continue;
}
const IntRect& parentClip = clipTrack.mBounds;
@@ -1291,17 +1398,22 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
LayerAndroid* layer = layerTracker.last().mLayer;
if (layer) {
const IntRect& layerClip = layerTracker.last().mBounds;
- if (!layerClip.isEmpty() && !cachedNode.clip(layerClip)) {
+ const RenderLayer* renderLayer = layerTracker.last().mRenderLayer;
+ if (!layer->contentIsScrollable() && !layerClip.isEmpty() &&
+ !cachedNode.clip(layerClip)) {
DBG_NAV_LOGD("skipped on layer clip %d", cacheIndex);
continue; // skip this node if outside of the clip
}
isInLayer = true;
isUnclipped = true; // assume that layers do not have occluded nodes
+ IntPoint scroll(renderLayer->scrollXOffset(),
+ renderLayer->scrollYOffset());
AddLayer(cachedFrame, cachedFrame->size(), layerClip.location(),
- layer->uniqueId());
+ scroll, layer->uniqueId());
}
#endif
cachedNode.setNavableRects();
+ cachedNode.setColorIndex(colorIndex);
cachedNode.setExport(exported);
cachedNode.setHasCursorRing(hasCursorRing);
cachedNode.setHasMouseOver(hasMouseOver);
@@ -2680,7 +2792,8 @@ bool CacheBuilder::isFocusableText(NodeWalk* walk, bool more, Node* node,
do {
do {
do {
- node = node->traverseNextNode();
+ if (node)
+ node = node->traverseNextNode();
if (node == NULL || node->hasTagName(HTMLNames::aTag)
|| node->hasTagName(HTMLNames::inputTag)
|| node->hasTagName(HTMLNames::textareaTag)) {
@@ -2727,10 +2840,10 @@ tryNextCheckType:
exported->replace(index, 1, escapedComma);
} break;
case EMAIL_CACHEDNODETYPE:
- exported->insert(WebCore::String("mailto:"), 0);
+ exported->insert(WTF::String("mailto:"), 0);
break;
case PHONE_CACHEDNODETYPE:
- exported->insert(WebCore::String("tel:"), 0);
+ exported->insert(WTF::String("tel:"), 0);
break;
default:
break;
@@ -2803,7 +2916,8 @@ void CacheBuilder::TrackLayer(WTF::Vector<LayerTracker>& layerTracker,
layerTracker.grow(layerTracker.size() + 1);
LayerTracker& indexTracker = layerTracker.last();
indexTracker.mLayer = aLayer;
- indexTracker.mBounds = nodeRenderer->absoluteBoundingBoxRect();
+ indexTracker.mRenderLayer = layer;
+ indexTracker.mBounds = IntRect(FloatRect(aLayer->bounds()));
indexTracker.mBounds.move(offsetX, offsetY);
indexTracker.mLastChild = lastChild ? OneAfter(lastChild) : 0;
DBG_NAV_LOGD("layer=%p [%d] bounds=(%d,%d,w=%d,h=%d)", aLayer,
@@ -2921,18 +3035,18 @@ bool CacheBuilder::ConstructPartRects(Node* node, const IntRect& bounds,
EVisibility vis = renderer->style()->visibility();
if (vis == HIDDEN)
continue;
+ bool hasClip = renderer->hasOverflowClip();
+ size_t clipIndex = clipTracker.size();
+ IntRect clipBounds = IntRect(0, 0, INT_MAX, INT_MAX);
+ if (hasClip || --clipIndex > 0) {
+ clipBounds = hasClip ? renderer->absoluteBoundingBoxRect() :
+ clipTracker.at(clipIndex).mBounds; // x, y fixup done by ConstructTextRect
+ }
if (test->isTextNode()) {
RenderText* renderText = (RenderText*) renderer;
InlineTextBox *textBox = renderText->firstTextBox();
if (textBox == NULL)
continue;
- bool hasClip = renderer->hasOverflowClip();
- size_t clipIndex = clipTracker.size();
- IntRect clipBounds = IntRect(0, 0, INT_MAX, INT_MAX);
- if (hasClip || --clipIndex > 0) {
- clipBounds = hasClip ? renderer->absoluteBoundingBoxRect() :
- clipTracker.at(clipIndex).mBounds; // x, y fixup done by ConstructTextRect
- }
if (ConstructTextRect((Text*) test, textBox, 0, INT_MAX,
x, y, focusBounds, clipBounds, result) == false) {
return false;
@@ -2941,6 +3055,7 @@ bool CacheBuilder::ConstructPartRects(Node* node, const IntRect& bounds,
}
if (test->hasTagName(HTMLNames::imgTag)) {
IntRect bounds = test->getRect();
+ bounds.intersect(clipBounds);
if (AddPartRect(bounds, x, y, result, focusBounds) == false)
return false;
continue;