diff options
Diffstat (limited to 'WebKit/android/nav/CacheBuilder.cpp')
| -rw-r--r-- | WebKit/android/nav/CacheBuilder.cpp | 209 |
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; |
