18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright 2006, The Android Open Source Project
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  * Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  * Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
163298a7d84b96ade73c6b170671711a8f2792ae59Steve Block * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CachedPrefix.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CachedNode.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CachedRoot.h"
29c3109bb2893308e202242b132d7d912bb9799e43Iain Merrick#include "ColumnInfo.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "EventListener.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventNames.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoaderClientAndroid.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameTree.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//#include "GraphicsContext.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLAreaElement.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLImageElement.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLInputElement.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLMapElement.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLOptionElement.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLSelectElement.h"
468601da30c7a307f6ca8a2b15688480cc1e8251c9Leon Scroggins#include "HTMLTextAreaElement.h"
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "InlineTextBox.h"
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "KURL.h"
491a8ec29fc0211a6b5c53a8cd9ce20be5e630b005Patrick Scott#include "LayerAndroid.h"
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PluginView.h"
518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RegisteredEventListener.h"
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderImage.h"
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderInline.h"
54f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark#include "RenderLayerBacking.h"
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderListBox.h"
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderSkinCombo.h"
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTextControl.h"
581dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott#include "RenderView.h"
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderWidget.h"
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkCanvas.h"
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkPoint.h"
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Text.h"
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebCoreFrameBridge.h"
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebCoreViewBridge.h"
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Widget.h"
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/unicode/Unicode.h>
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef DUMP_NAV_CACHE_USING_PRINTF
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FILE* gNavCacheLogFile = NULL;
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    android::Mutex gWriteLogMutex;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CacheBuilder.h"
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define MINIMUM_FOCUSABLE_WIDTH 3
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define MINIMUM_FOCUSABLE_HEIGHT 3
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define MAXIMUM_FOCUS_RING_COUNT 32
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace android {
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCacheBuilder* CacheBuilder::Builder(Frame* frame) {
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return &((FrameLoaderClientAndroid*) frame->loader()->client())->getCacheBuilder();
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFrame* CacheBuilder::FrameAnd(CacheBuilder* cacheBuilder) {
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FrameLoaderClientAndroid* loader = (FrameLoaderClientAndroid*)
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ((char*) cacheBuilder - OFFSETOF(FrameLoaderClientAndroid, m_cacheBuilder));
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return loader->getFrame();
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFrame* CacheBuilder::FrameAnd(const CacheBuilder* cacheBuilder) {
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FrameLoaderClientAndroid* loader = (FrameLoaderClientAndroid*)
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ((char*) cacheBuilder - OFFSETOF(FrameLoaderClientAndroid, m_cacheBuilder));
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return loader->getFrame();
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9782f247bdbb98dd80c44209d87692c650c3704617Patrick ScottCacheBuilder::LayerTracker::~LayerTracker() {
981dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott    // Check for a stacking context to prevent a crash in layers without a
991dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott    // parent.
1001dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott    if (mRenderLayer && mRenderLayer->stackingContext())
10182f247bdbb98dd80c44209d87692c650c3704617Patrick Scott        // Restore the scroll position of the layer.  Does not affect layers
10282f247bdbb98dd80c44209d87692c650c3704617Patrick Scott        // without overflow scroll as the layer will not be scrolled.
1039bbecbe38e6249c7b1c0874e80503f6162f13613Ben Murdoch        mRenderLayer->scrollToOffset(mScroll.x(), mScroll.y());
10482f247bdbb98dd80c44209d87692c650c3704617Patrick Scott}
1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if DUMP_NAV_CACHE
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic bool hasEventListener(Node* node, const AtomicString& eventType) {
1093efa919a7f16fdb717e393f501c50d4844ffaed5Cary Clark    if (!node->isElementNode())
1103efa919a7f16fdb717e393f501c50d4844ffaed5Cary Clark        return false;
1113efa919a7f16fdb717e393f501c50d4844ffaed5Cary Clark    Element* element = static_cast<Element*>(node);
1123efa919a7f16fdb717e393f501c50d4844ffaed5Cary Clark    EventListener* listener = element->getAttributeEventListener(eventType);
1133efa919a7f16fdb717e393f501c50d4844ffaed5Cary Clark    return 0 != listener;
1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define DEBUG_BUFFER_SIZE 256
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define DEBUG_WRAP_SIZE 150
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define DEBUG_WRAP_MAX 170
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFrame* CacheBuilder::Debug::frameAnd() const {
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CacheBuilder* nav = (CacheBuilder*) ((char*) this - OFFSETOF(CacheBuilder, mDebug));
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return CacheBuilder::FrameAnd(nav);
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::attr(const AtomicString& name, const AtomicString& value) {
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (name.isNull() || name.isEmpty() || value.isNull() || value.isEmpty())
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    uChar(name.characters(), name.length(), false);
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    print("=");
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wideString(value.characters(), value.length(), false);
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    print(" ");
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::comma(const char* str) {
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    print(str);
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    print(", ");
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::flush() {
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int len;
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int limit = mIndex;
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (limit < DEBUG_WRAP_SIZE)
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (limit < DEBUG_WRAP_MAX)
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            len = limit;
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            limit = DEBUG_WRAP_MAX;
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            len = DEBUG_WRAP_SIZE;
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (len < limit) {
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                char test = mBuffer[len];
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (test < '/' || (test > '9' && test < 'A') || (test > 'Z' && test  < 'a') || test > 'z')
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                len++;
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
156b72d8281f4bbdb36f2d4a57c71fd266c41399c21Cary Clark            while (len > 0 && mBuffer[len - 1] == '\\')
157b72d8281f4bbdb36f2d4a57c71fd266c41399c21Cary Clark                len--;
158b72d8281f4bbdb36f2d4a57c71fd266c41399c21Cary Clark            while (mBuffer[len] == '"')
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                len++;
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const char* prefix = mPrefix;
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (prefix[0] == '\"') {
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // see if we're inside a quote
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int quoteCount = 0;
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (int index = 0; index < len; index++) {
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (mBuffer[index] == '\\') {
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    index++;
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (mBuffer[index] == '\n') {
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    quoteCount = 0;
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (mBuffer[index] == '"')
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    quoteCount++;
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if ((quoteCount & 1) == 0)
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                prefix = "\n";
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("%.*s", len, mBuffer);
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int copy = mIndex - len;
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        strcpy(mBuffer, prefix);
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        memcpy(&mBuffer[strlen(prefix)], &mBuffer[len], copy);
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mIndex = strlen(prefix) + copy;
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while (true);
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::frameName(char*& namePtr, const char* max) const {
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   if (namePtr >= max)
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   Frame* frame = frameAnd();
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   Frame* parent = frame->tree()->parent();
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   if (parent)
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Builder(parent)->mDebug.frameName(namePtr, max);
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& name = frame->tree()->name();
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (name.length() == 0)
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned index = 0;
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (name.startsWith(AtomicString("opener")))
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        index = 6;
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (; index < name.length(); index++) {
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char ch = name[index];
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ch <= ' ')
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ch = '_';
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (WTF::isASCIIAlphanumeric(ch) || ch == '_')
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *namePtr++  = ch;
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::frames() {
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = frameAnd();
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Document* doc = frame->document();
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (doc == NULL)
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool top = frame->tree()->parent() == NULL;
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (top) {
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef DUMP_NAV_CACHE_USING_PRINTF
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gWriteLogMutex.lock();
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(gNavCacheLogFile == NULL);
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gNavCacheLogFile = fopen(NAV_CACHE_LOG_FILE, "a");
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        groups();
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* child = frame->tree()->firstChild();
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hasChild = child != NULL;
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (top && hasChild)
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("\nnamespace TEST_SPACE {\n\n");
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Builder(child)->mDebug.frames();
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = child->tree()->nextSibling();
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasChild) {
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = frame->tree()->firstChild();
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (child) {
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            char childName[256];
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            char* childNamePtr = childName;
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Builder(child)->mDebug.frameName(childNamePtr, childNamePtr + sizeof(childName) - 1);
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *childNamePtr = '\0';
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child == frame->tree()->firstChild())
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                DUMP_NAV_LOGD("DebugTestFrameGroup TEST%s_GROUP[] = {\n", childName);
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Frame* next = child->tree()->nextSibling();
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Document* doc = child->document();
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (doc != NULL) {
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                RenderObject* renderer = doc->renderer();
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (renderer != NULL) {
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    RenderLayer* layer = renderer->enclosingLayer();
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (layer != NULL) {
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("{ ");
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("TEST%s_RECTS, ", childName);
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("TEST%s_RECT_COUNT, ", childName);
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("TEST%s_RECTPARTS, ", childName);
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("TEST%s_BOUNDS,\n", childName);
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("TEST%s_WIDTH, ", childName);
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("TEST%s_HEIGHT,\n", childName);
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("0, 0, 0, 0,\n");
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("TEST%s_FOCUS, ", childName);
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        Frame* grandChild = child->tree()->firstChild();
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                         if (grandChild) {
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            char grandChildName[256];
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            char* grandChildNamePtr = grandChildName;
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            Builder(grandChild)->mDebug.frameName(grandChildNamePtr,
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                grandChildNamePtr + sizeof(grandChildName) - 1);
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            *grandChildNamePtr = '\0';
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            DUMP_NAV_LOGD("TEST%s_GROUP, ", grandChildName);
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            DUMP_NAV_LOGD("sizeof(TEST%s_GROUP) / sizeof(DebugTestFrameGroup), ", grandChildName);
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        } else
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            DUMP_NAV_LOGD("NULL, 0, ");
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("\"%s\"\n", childName);
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("}%c\n", next ? ',' : ' ');
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child = next;
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("};\n");
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (top) {
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasChild)
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            DUMP_NAV_LOGD("\n}  // end of namespace\n\n");
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char name[256];
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char* frameNamePtr = name;
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        frameName(frameNamePtr, frameNamePtr + sizeof(name) - 1);
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *frameNamePtr = '\0';
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("DebugTestFrameGroup TEST%s_GROUP = {\n", name);
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_RECTS, ", name);
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_RECT_COUNT, ", name);
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_RECTPARTS, ", name);
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_BOUNDS,\n", name);
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_WIDTH, ", name);
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_HEIGHT,\n", name);
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_MAX_H, ", name);
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_MIN_H, ", name);
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_MAX_V, ", name);
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_MIN_V,\n", name);
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("TEST%s_FOCUS, ", name);
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasChild) {
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            child = frame->tree()->firstChild();
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            char childName[256];
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            char* childNamePtr = childName;
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Builder(child)->mDebug.frameName(childNamePtr, childNamePtr + sizeof(childName) - 1);
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *childNamePtr = '\0';
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            DUMP_NAV_LOGD("TEST_SPACE::TEST%s_GROUP, ", childName);
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            DUMP_NAV_LOGD("sizeof(TEST_SPACE::TEST%s_GROUP) / sizeof(DebugTestFrameGroup), \n" ,childName);
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            DUMP_NAV_LOGD("NULL, 0, ");
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("\"%s\"\n", name);
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("};\n");
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef DUMP_NAV_CACHE_USING_PRINTF
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (gNavCacheLogFile)
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            fclose(gNavCacheLogFile);
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gNavCacheLogFile = NULL;
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gWriteLogMutex.unlock();
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::init(char* buffer, size_t size) {
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    mBuffer = buffer;
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    mBufferSize = size;
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    mIndex = 0;
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    mPrefix = "";
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::groups() {
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = frameAnd();
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* child = frame->tree()->firstChild();
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hasChild = child != NULL;
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (frame->tree()->parent() == NULL && hasChild)
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("namespace TEST_SPACE {\n\n");
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Builder(child)->mDebug.groups();
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = child->tree()->nextSibling();
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (frame->tree()->parent() == NULL && hasChild)
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("\n} // end of namespace\n\n");
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Document* doc = frame->document();
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char name[256];
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* frameNamePtr = name;
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    frameName(frameNamePtr, frameNamePtr + sizeof(name) - 1);
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *frameNamePtr = '\0';
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (doc == NULL) {
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("// %s has no document\n", name);
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* renderer = doc->renderer();
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer == NULL) {
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("// %s has no renderer\n", name);
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderLayer* layer = renderer->enclosingLayer();
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (layer == NULL) {
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("// %s has no enclosingLayer\n", name);
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* node = doc;
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* focus = doc->focusedNode();
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool atLeastOne = false;
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ((atLeastOne |= isFocusable(node)) != false)
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while ((node = node->traverseNextNode()) != NULL);
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int focusIndex = -1;
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (atLeastOne == false) {
364b72d8281f4bbdb36f2d4a57c71fd266c41399c21Cary Clark        DUMP_NAV_LOGD("static DebugTestNode TEST%s_RECTS[] = {\n"
365b72d8281f4bbdb36f2d4a57c71fd266c41399c21Cary Clark            "{{0, 0, 0, 0}, \"\", 0, -1, \"\", {0, 0, 0, 0}, false, 0}\n"
366b72d8281f4bbdb36f2d4a57c71fd266c41399c21Cary Clark            "};\n\n", name);
367b72d8281f4bbdb36f2d4a57c71fd266c41399c21Cary Clark        DUMP_NAV_LOGD("static int TEST%s_RECT_COUNT = 1;"
368b72d8281f4bbdb36f2d4a57c71fd266c41399c21Cary Clark            " // no focusable nodes\n", name);
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("#define TEST%s_RECTPARTS NULL\n", name);
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        node = doc;
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int count = 1;
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("static DebugTestNode TEST%s_RECTS[] = {\n", name);
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        do {
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            String properties;
3768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (hasEventListener(node, eventNames().clickEvent))
3778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                properties.append("ONCLICK | ");
3788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (hasEventListener(node, eventNames().mousedownEvent))
3798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                properties.append("MOUSEDOWN | ");
3808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (hasEventListener(node, eventNames().mouseupEvent))
3818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                properties.append("MOUSEUP | ");
3828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (hasEventListener(node, eventNames().mouseoverEvent))
3838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                properties.append("MOUSEOVER | ");
3848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (hasEventListener(node, eventNames().mouseoutEvent))
3858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                properties.append("MOUSEOUT | ");
3868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (hasEventListener(node, eventNames().keydownEvent))
3878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                properties.append("KEYDOWN | ");
3888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (hasEventListener(node, eventNames().keyupEvent))
3898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                properties.append("KEYUP | ");
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (CacheBuilder::HasFrame(node))
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                properties.append("FRAME | ");
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (focus == node) {
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                properties.append("FOCUS | ");
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                focusIndex = count;
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node->isKeyboardFocusable(NULL))
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                properties.append("KEYBOARD_FOCUSABLE | ");
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node->isMouseFocusable())
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                properties.append("MOUSE_FOCUSABLE | ");
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node->isFocusable())
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                properties.append("SIMPLE_FOCUSABLE | ");
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (properties.isEmpty())
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                properties.append("0");
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                properties.truncate(properties.length() - 3);
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntRect rect = node->getRect();
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node->hasTagName(HTMLNames::areaTag))
408805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins                rect = getAreaRect(static_cast<HTMLAreaElement*>(node));
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            char buffer[DEBUG_BUFFER_SIZE];
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            memset(buffer, 0, sizeof(buffer));
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mBuffer = buffer;
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mBufferSize = sizeof(buffer);
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mPrefix = "\"\n\"";
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mIndex = snprintf(buffer, sizeof(buffer), "{{%d, %d, %d, %d}, ", rect.x(), rect.y(),
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                rect.width(), rect.height());
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            localName(node);
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            uChar(properties.characters(), properties.length(), false);
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            print(", ");
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int parentIndex = ParentIndex(node, count, node->parentNode());
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            char scratch[256];
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            snprintf(scratch, sizeof(scratch), "%d", parentIndex);
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            comma(scratch);
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Element* element = static_cast<Element*>(node);
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node->isElementNode() && element->hasID())
42588c81ae2263ae20fe63c346d9237d285cc12e84bCary Clark                wideString(element->getIdAttribute());
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else if (node->isTextNode()) {
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project #if 01 // set to one to abbreviate text that can be omitted from the address detection code
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project               if (rect.isEmpty() && node->textContent().length() > 100) {
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    wideString(node->textContent().characters(), 100, false);
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    snprintf(scratch, sizeof(scratch), "/* + %d bytes */",
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        node->textContent().length() - 100);
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    print(scratch);
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project #endif
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                   wideString(node->textContent().characters(), node->textContent().length(), true);
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else if (node->hasTagName(HTMLNames::aTag) ||
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                node->hasTagName(HTMLNames::areaTag))
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(node);
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                wideString(anchor->href());
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else if (node->hasTagName(HTMLNames::imgTag)) {
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                HTMLImageElement* image = static_cast<HTMLImageElement*>(node);
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                wideString(image->src());
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                print("\"\"");
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderObject* renderer = node->renderer();
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int tabindex = node->isElementNode() ? node->tabIndex() : 0;
448f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark            RenderLayer* layer = 0;
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (renderer) {
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                const IntRect& absB = renderer->absoluteBoundingBoxRect();
451f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                bool hasLayer = renderer->hasLayer();
452f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                layer = hasLayer ? toRenderBoxModelObject(renderer)->layer() : 0;
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                snprintf(scratch, sizeof(scratch), ", {%d, %d, %d, %d}, %s"
454f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                    ", %d, %s, %s},",
455f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                    absB.x(), absB.y(), absB.width(), absB.height(),
456f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                    renderer->hasOverflowClip() ? "true" : "false", tabindex,
457f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                    hasLayer ? "true" : "false",
458f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                    hasLayer && layer->isComposited() ? "true" : "false");
459b72d8281f4bbdb36f2d4a57c71fd266c41399c21Cary Clark                // TODO: add renderer->style()->visibility()
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                print(scratch);
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                print(", {0, 0, 0, 0}, false, 0},");
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            flush();
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            snprintf(scratch, sizeof(scratch), "// %d: ", count);
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mPrefix = "\n// ";
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            print(scratch);
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //print(renderer ? renderer->information().ascii() : "NO_RENDER_INFO");
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node->isElementNode()) {
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                Element* element = static_cast<Element*>(node);
4710181faa1ffede024c2712df19ae7c855a8cf64e3Cary Clark                NamedNodeMap* attrs = element->attributes();
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                unsigned length = attrs->length();
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (length > 0) {
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    newLine();
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    print("// attr: ");
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    for (unsigned i = 0; i < length; i++) {
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        Attribute* a = attrs->attributeItem(i);
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        attr(a->localName(), a->value());
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
48221d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark            if (renderer) {
48321d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                RenderStyle* style = renderer->style();
48421d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                snprintf(scratch, sizeof(scratch), "// renderStyle:"
48521d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                    " visibility=%s hasBackGround=%d"
486205a7cfa91854de791995f40278e8c19491f6d99Cary Clark                    " tapHighlightColor().alpha()=0x%02x"
487205a7cfa91854de791995f40278e8c19491f6d99Cary Clark                    " isTransparent()=%s",
48821d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                    style->visibility() == HIDDEN ? "HIDDEN" : "VISIBLE",
489205a7cfa91854de791995f40278e8c19491f6d99Cary Clark                    renderer->hasBackground(), style->tapHighlightColor().alpha(),
490205a7cfa91854de791995f40278e8c19491f6d99Cary Clark                    renderer->isTransparent() ? "true" : "false");
49121d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                newLine();
49221d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                print(scratch);
49321d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                RenderBlock* renderBlock = static_cast<RenderBlock*>(renderer);
49421d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                if (renderer->isRenderBlock() && renderBlock->hasColumns()) {
49521d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                    const RenderBox* box = static_cast<RenderBox*>(renderer);
49621d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                    const IntRect& oRect = box->visibleOverflowRect();
49721d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                    snprintf(scratch, sizeof(scratch), "// renderBlock:"
498a34b1107b2542fa334fd4db2d58e2df849e083b0Cary Clark                        " columnCount=%d columnGap=%d direction=%d"
49921d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                        " hasOverflowClip=%d overflow=(%d,%d,w=%d,h=%d)",
500a7b977fa312f9f87fb188a0df16952457052b391Cary Clark                        renderBlock->columnInfo()->columnCount(), renderBlock->columnGap(),
50121d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                        renderBlock->style()->direction(), renderer->hasOverflowClip(),
50221d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                        oRect.x(), oRect.y(), oRect.width(), oRect.height());
50321d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                    newLine();
50421d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                    print(scratch);
50521d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                }
50621d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark            }
50721d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark #if USE(ACCELERATED_COMPOSITING)
50821d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark            if (renderer && renderer->hasLayer()) {
50921d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
510f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                RenderLayerBacking* back = layer->backing();
5111a8ec29fc0211a6b5c53a8cd9ce20be5e630b005Patrick Scott                GraphicsLayer* grLayer = back ? back->graphicsLayer() : 0;
5121a8ec29fc0211a6b5c53a8cd9ce20be5e630b005Patrick Scott                LayerAndroid* aLayer = grLayer ? grLayer->platformLayer() : 0;
513f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                const SkPicture* pict = aLayer ? aLayer->picture() : 0;
51421d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                const IntRect& r = renderer->absoluteBoundingBoxRect();
515f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                snprintf(scratch, sizeof(scratch), "// layer:%p back:%p"
51621d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                    " gLayer:%p aLayer:%p pict:%p r:(%d,%d,w=%d,h=%d)",
51721d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                    layer, back, grLayer, aLayer, pict, r.x(), r.y(),
51821d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                    r.width(), r.height());
519f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                newLine();
52021d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark                print(scratch);
52121d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark            }
52221d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark #endif
52321d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark            count++;
52421d2e6a819424b1a73874b8e5a1bf031ced3c933Cary Clark            newLine();
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } while ((node = node->traverseNextNode()) != NULL);
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("}; // focusables = %d\n", count - 1);
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("\n");
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("static int TEST%s_RECT_COUNT = %d;\n\n", name, count - 1);
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // look for rects with multiple parts
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        node = doc;
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        count = 1;
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool hasRectParts = false;
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int globalOffsetX, globalOffsetY;
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        GetGlobalOffset(frame, &globalOffsetX, &globalOffsetY);
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        do {
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntRect rect;
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bool _isFocusable = isFocusable(node) || (node->isTextNode()
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              && node->getRect().isEmpty() == false
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                );
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int nodeIndex = count++;
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (_isFocusable == false)
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderObject* renderer = node->renderer();
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (renderer == NULL)
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            WTF::Vector<IntRect> rects;
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntRect clipBounds = IntRect(0, 0, INT_MAX, INT_MAX);
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntRect focusBounds = IntRect(0, 0, INT_MAX, INT_MAX);
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntRect* rectPtr = &focusBounds;
55099a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark            int imageCount = 0;
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node->isTextNode()) {
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                Text* textNode = (Text*) node;
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (CacheBuilder::ConstructTextRects(textNode, 0, textNode,
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        INT_MAX, globalOffsetX, globalOffsetY, rectPtr,
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        clipBounds, &rects) == false)
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                IntRect nodeBounds = node->getRect();
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (CacheBuilder::ConstructPartRects(node, nodeBounds, rectPtr,
56099a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark                        globalOffsetX, globalOffsetY, &rects, &imageCount) == false)
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            unsigned arraySize = rects.size();
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (arraySize > 1 || (arraySize == 1 && (rectPtr->width() != rect.width())) ||
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    rectPtr->height() != rect.height()) {
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (hasRectParts == false) {
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    DUMP_NAV_LOGD("static DebugTestRectPart TEST%s_RECTPARTS[] = {\n", name);
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    hasRectParts = true;
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (node->isTextNode() == false) {
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    unsigned rectIndex = 0;
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    for (; rectIndex < arraySize; rectIndex++) {
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        rectPtr = &rects.at(rectIndex);
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("{ %d, %d, %d, %d, %d }, // %d\n", nodeIndex,
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            rectPtr->x(), rectPtr->y(), rectPtr->width(),
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            rectPtr->height(), rectIndex + 1);
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    RenderText* renderText = (RenderText*) node->renderer();
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    InlineTextBox* textBox = renderText->firstTextBox();
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    unsigned rectIndex = 0;
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    while (textBox) {
583635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        FloatPoint pt = renderText->localToAbsolute();
584635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        IntRect rect = textBox->selectionRect((int) pt.x(), (int) pt.y(), 0, INT_MAX);
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        mIndex = 0;
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, "{ %d, %d, %d, %d, %d",
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            nodeIndex, rect.x(), rect.y(), rect.width(), rect.height());
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d",
589635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                            textBox->len(), 0 /*textBox->selectionHeight()*/,
590635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                            0 /*textBox->selectionTop()*/);
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d",
592635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                            0 /*textBox->spaceAdd()*/, textBox->start(), 0 /*textBox->textPos()*/);
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d, %d",
594a7b977fa312f9f87fb188a0df16952457052b391Cary Clark                            textBox->x(), textBox->y(), textBox->logicalWidth(), textBox->logicalHeight());
5955cfedfef172691d0f4bcf2be5ca3cddd8c9a47f4Grace Kloba                        int baseline = textBox->renderer()->style(textBox->isFirstLineStyle())->font().ascent();
59699a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark                        mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d }, // %d ",
59799a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark                            baseline, imageCount, ++rectIndex);
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        wideString(node->textContent().characters() + textBox->start(), textBox->len(), true);
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        DUMP_NAV_LOGD("%.*s\n", mIndex, mBuffer);
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        textBox = textBox->nextTextBox();
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } while ((node = node->traverseNextNode()) != NULL);
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hasRectParts)
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            DUMP_NAV_LOGD("{0}\n};\n\n");
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            DUMP_NAV_LOGD("static DebugTestRectPart* TEST%s_RECTPARTS = NULL;\n", name);
6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int contentsWidth = layer->width();
6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int contentsHeight = layer->height();
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DUMP_NAV_LOGD("static int TEST%s_FOCUS = %d;\n", name, focusIndex);
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DUMP_NAV_LOGD("static int TEST%s_WIDTH = %d;\n", name, contentsWidth);
614b72d8281f4bbdb36f2d4a57c71fd266c41399c21Cary Clark    DUMP_NAV_LOGD("static int TEST%s_HEIGHT = %d;\n\n", name, contentsHeight);
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::Debug::isFocusable(Node* node) {
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node->hasTagName(HTMLNames::areaTag))
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node->renderer() == false)
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node->isKeyboardFocusable(NULL))
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node->isMouseFocusable())
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node->isFocusable())
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (CacheBuilder::AnyIsClick(node))
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (CacheBuilder::HasTriggerEvent(node))
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::localName(Node* node) {
6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& local = node->localName();
6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node->isTextNode())
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        print("\"#text\"");
6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        wideString(local.characters(), local.length(), false);
6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    print(", ");
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::newLine(int indent) {
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (mPrefix[0] != '\n')
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        print(&mPrefix[0], 1);
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    flush();
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int lastnewline = mIndex - 1;
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (lastnewline >= 0 && mBuffer[lastnewline] != '\n')
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastnewline--;
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    lastnewline++;
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* buffer = mBuffer;
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (lastnewline > 0) {
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("%.*s", lastnewline, buffer);
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mIndex -= lastnewline;
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        buffer += lastnewline;
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t prefixLen = strlen(mPrefix);
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int minPrefix = prefixLen - 1;
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (minPrefix >= 0 && mPrefix[minPrefix] != '\n')
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        minPrefix--;
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    minPrefix = prefixLen - minPrefix - 1;
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (mIndex > minPrefix)
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DUMP_NAV_LOGD("%.*s\n", mIndex, buffer);
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    mIndex = 0;
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setIndent(indent);
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint CacheBuilder::Debug::ParentIndex(Node* node, int count, Node* parent)
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (parent == NULL)
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return -1;
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(node != parent);
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int result = count;
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* previous = node;
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result--;
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        previous = previous->traversePreviousNode();
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while (previous && previous != parent);
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (previous != NULL)
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return result;
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result = count;
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result++;
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while ((node = node->traverseNextNode()) != NULL && node != parent);
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node != NULL)
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return result;
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(0);
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::print(const char* name) {
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    print(name, strlen(name));
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::print(const char* name, unsigned len) {
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mIndex + len >= DEBUG_BUFFER_SIZE)
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            flush();
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int copyLen = mIndex + len < DEBUG_BUFFER_SIZE ?
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             len : DEBUG_BUFFER_SIZE - mIndex;
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        memcpy(&mBuffer[mIndex], name, copyLen);
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mIndex += copyLen;
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        name += copyLen;
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        len -= copyLen;
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while (len > 0);
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    mBuffer[mIndex] = '\0';
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::setIndent(int indent)
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char scratch[64];
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    snprintf(scratch, sizeof(scratch), "%.*s", indent,
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "                                                                    ");
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    print(scratch);
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::uChar(const UChar* name, unsigned len, bool hex) {
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* end = name + len;
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool wroteHex = false;
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (name < end) {
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unsigned ch = *name++;
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ch == '\t' || ch == '\n' || ch == '\r' || ch == 0xa0)
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ch = ' ';
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ch < ' ' || ch == 0x7f) {
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (hex) {
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, "\\x%02x", ch);
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                wroteHex = true;
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                mBuffer[mIndex++] = '?';
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (ch >= 0x80) {
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (hex) {
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (ch < 0x800)
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex,
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        "\\x%02x\\x%02x", ch >> 6 | 0xc0, (ch & 0x3f) | 0x80);
7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex,
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        "\\x%02x\\x%02x\\x%02x", ch >> 12 | 0xe0,
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        (ch >> 6 & 0x3f) | 0x80, (ch & 0x3f) | 0x80);
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                wroteHex = true;
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                mBuffer[mIndex++] = '?';
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (wroteHex && WTF::isASCIIHexDigit((UChar) ch))
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex,
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    "\" \"");
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else if (ch == '"' || ch == '\\')
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                mBuffer[mIndex++] = '\\';
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mBuffer[mIndex++] = ch;
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            wroteHex = false;
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mIndex + 1 >= DEBUG_BUFFER_SIZE)
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            flush();
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    flush();
7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::validateFrame() {
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = frameAnd();
7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Page* page = frame->page();
7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(page);
7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT((int) page > 0x10000);
7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* child = frame->tree()->firstChild();
7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Builder(child)->mDebug.validateFrame();
7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = child->tree()->nextSibling();
7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::wideString(const UChar* chars, int length, bool hex) {
7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (length == 0)
7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        print("\"\"");
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        print("\"");
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        uChar(chars, length, hex);
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        print("\"");
7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::Debug::wideString(const String& str) {
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wideString(str.characters(), str.length(), false);
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // DUMP_NAV_CACHE
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCacheBuilder::CacheBuilder()
7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7881d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark    mAllowableTypes = ALL_CACHEDNODE_BITS;
7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef DUMP_NAV_CACHE_USING_PRINTF
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    gNavCacheLogFile = NULL;
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::adjustForColumns(const ClipColumnTracker& track,
795b4b1148720e724bf404dadaa5443caaa286f5724Steve Block    CachedNode* node, IntRect* bounds, RenderBlock* renderer)
7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
797a7b977fa312f9f87fb188a0df16952457052b391Cary Clark    if (!renderer->hasColumns())
798a7b977fa312f9f87fb188a0df16952457052b391Cary Clark        return;
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int x = 0;
8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int y = 0;
8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int tx = track.mBounds.x();
8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int ty = track.mBounds.y();
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int columnGap = track.mColumnGap;
804c3109bb2893308e202242b132d7d912bb9799e43Iain Merrick    size_t limit = track.mColumnInfo->columnCount();
8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (size_t index = 0; index < limit; index++) {
806b4b1148720e724bf404dadaa5443caaa286f5724Steve Block        IntRect column = renderer->columnRectAt(track.mColumnInfo, index);
8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        column.move(tx, ty);
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect test = *bounds;
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        test.move(x, y);
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (column.contains(test)) {
8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if ((x | y) == 0)
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *bounds = test;
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            node->move(x, y);
8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int xOffset = column.width() + columnGap;
8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        x += track.mDirection == LTR ? xOffset : -xOffset;
8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        y -= column.height();
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// Checks if a node has one of event listener types.
8248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool CacheBuilder::NodeHasEventListeners(Node* node, AtomicString* eventTypes, int length) {
825db4aee9760c4b1e3cc14b24267a32cd66d550334Steve Block    for (int i = 0; i < length; ++i) {
826db4aee9760c4b1e3cc14b24267a32cd66d550334Steve Block        if (!node->getEventListeners(eventTypes[i]).isEmpty())
827db4aee9760c4b1e3cc14b24267a32cd66d550334Steve Block            return true;
8288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
8298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return false;
8308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
8318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::AnyChildIsClick(Node* node)
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    AtomicString eventTypes[5] = {
8358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().clickEvent,
8368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().mousedownEvent,
8378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().mouseupEvent,
8388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().keydownEvent,
8398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().keyupEvent
8408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    };
8418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* child = node->firstChild();
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child != NULL) {
8448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (child->isFocusable() ||
8458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            NodeHasEventListeners(child, eventTypes, 5))
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (AnyChildIsClick(child))
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = child->nextSibling();
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::AnyIsClick(Node* node)
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node->hasTagName(HTMLNames::bodyTag))
8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return AnyChildIsClick(node);
8588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    AtomicString eventTypeSetOne[4] = {
8608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().mouseoverEvent,
8618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().mouseoutEvent,
8628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().keydownEvent,
8638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().keyupEvent
8648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    };
8658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!NodeHasEventListeners(node, eventTypeSetOne, 4))
8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
8688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    AtomicString eventTypeSetTwo[3] = {
8708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().clickEvent,
8718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().mousedownEvent,
8728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().mouseupEvent
8738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    };
8748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (NodeHasEventListeners(node, eventTypeSetTwo, 3))
8768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
8778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return AnyChildIsClick(node);
8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::buildCache(CachedRoot* root)
8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = FrameAnd(this);
8840d4eb282a9331db55cb204c779cd172dba8ccf50Cary Clark    mPictureSetDisabled = false;
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    BuildFrame(frame, frame, root, (CachedFrame*) root);
8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    root->finishInit(); // set up frame parent pointers, child pointers
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setData((CachedFrame*) root);
8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
890a0428a863bd79d20e416d6d981d0120bd1569edfCary Clarkstatic Node* ParentWithChildren(Node* node)
891a0428a863bd79d20e416d6d981d0120bd1569edfCary Clark{
892a0428a863bd79d20e416d6d981d0120bd1569edfCary Clark    Node* parent = node;
893a0428a863bd79d20e416d6d981d0120bd1569edfCary Clark    while ((parent = parent->parentNode())) {
894a0428a863bd79d20e416d6d981d0120bd1569edfCary Clark        if (parent->childNodeCount() > 1)
895a0428a863bd79d20e416d6d981d0120bd1569edfCary Clark            return parent;
896a0428a863bd79d20e416d6d981d0120bd1569edfCary Clark    }
897a0428a863bd79d20e416d6d981d0120bd1569edfCary Clark    return 0;
898a0428a863bd79d20e416d6d981d0120bd1569edfCary Clark}
899a0428a863bd79d20e416d6d981d0120bd1569edfCary Clark
9009c4138e3d9ed158a6e7b500a372fc957715e4efdCary Clark// FIXME
9019c4138e3d9ed158a6e7b500a372fc957715e4efdCary Clark// Probably this should check for null instead of the caller. If the
9029c4138e3d9ed158a6e7b500a372fc957715e4efdCary Clark// Tracker object is the last thing in the dom, checking for null in the
9039c4138e3d9ed158a6e7b500a372fc957715e4efdCary Clark// caller in some cases fails to set up Tracker state which may be useful
9049c4138e3d9ed158a6e7b500a372fc957715e4efdCary Clark// to the nodes parsed immediately after the tracked noe.
9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic Node* OneAfter(Node* node)
9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* parent = node;
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* sibling = NULL;
9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while ((parent = parent->parentNode()) != NULL) {
9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sibling = parent->nextSibling();
9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (sibling != NULL)
9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return sibling;
9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// return true if this renderer is really a pluinview, and it wants
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// key-events (i.e. focus)
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool checkForPluginViewThatWantsFocus(RenderObject* renderer) {
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer->isWidget()) {
9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
922585ee724ef91cab37349b10b022e608510a7f763Ben Murdoch        if (widget && (widget->isPluginView() || widget->isPluginViewBase())) {
9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // check if this plugin really wants key events (TODO)
9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9302e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark#if USE(ACCELERATED_COMPOSITING)
93182f247bdbb98dd80c44209d87692c650c3704617Patrick Scottstatic void AddLayer(CachedFrame* frame, size_t index, const IntPoint& location, int id)
9322e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark{
9332e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark    DBG_NAV_LOGD("frame=%p index=%d loc=(%d,%d) id=%d", frame, index,
9342e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark        location.x(), location.y(), id);
9352e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark    CachedLayer cachedLayer;
9362e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark    cachedLayer.setCachedNodeIndex(index);
9372e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark    cachedLayer.setOffset(location);
9382e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark    cachedLayer.setUniqueId(id);
9392e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark    frame->add(cachedLayer);
9402e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark}
9412e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark#endif
9422e0b2223f6f6223fc09ce81529c611f2c032e38fCary Clark
9431b7c6c8d699a6520472f566710662983ed0ac650Cary Clarkstatic int FindColorIndex(WTF::Vector<CachedColor>& colorTracker,
9441b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    const CachedColor& cachedColor)
9451b7c6c8d699a6520472f566710662983ed0ac650Cary Clark{
9461b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    CachedColor* work = colorTracker.begin() - 1;
9471b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    CachedColor* end = colorTracker.end();
9481b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    while (++work < end) {
9491b7c6c8d699a6520472f566710662983ed0ac650Cary Clark        if (*work == cachedColor)
9501b7c6c8d699a6520472f566710662983ed0ac650Cary Clark            return work - colorTracker.begin();
9511b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    }
9521b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    int result = colorTracker.size();
9531b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    colorTracker.grow(result + 1);
9541b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    CachedColor& newColor = colorTracker.last();
9551b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    newColor = cachedColor;
9561b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    return result;
9571b7c6c8d699a6520472f566710662983ed0ac650Cary Clark}
9581b7c6c8d699a6520472f566710662983ed0ac650Cary Clark
9591b7c6c8d699a6520472f566710662983ed0ac650Cary Clarkstatic void InitColor(CachedColor* color)
9601b7c6c8d699a6520472f566710662983ed0ac650Cary Clark{
9611b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    color->setFillColor(RenderStyle::initialRingFillColor());
9621b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    color->setInnerWidth(RenderStyle::initialRingInnerWidth());
9631b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    color->setOuterWidth(RenderStyle::initialRingOuterWidth());
9641b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    color->setOutset(RenderStyle::initialRingOutset());
9651b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    color->setPressedInnerColor(RenderStyle::initialRingPressedInnerColor());
9661b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    color->setPressedOuterColor(RenderStyle::initialRingPressedOuterColor());
9671b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    color->setRadius(RenderStyle::initialRingRadius());
9681b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    color->setSelectedInnerColor(RenderStyle::initialRingSelectedInnerColor());
9691b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    color->setSelectedOuterColor(RenderStyle::initialRingSelectedOuterColor());
9701b7c6c8d699a6520472f566710662983ed0ac650Cary Clark}
9711b7c6c8d699a6520472f566710662983ed0ac650Cary Clark
9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// when new focus is found, push it's parent on a stack
9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // as long as more focii are found with the same (grand) parent, note it
9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (which only requires retrieving the last parent on the stack)
9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// when the parent's last child is found, pop the stack
9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// different from Tracker in that Tracker only pushes focii with children
9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// making this work with focus - child focus - grandchild focus is tricky
9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// if I keep the generation number, I may be able to more quickly determine that
9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// a node is a grandchild of the focus's parent
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// this additionally requires being able to find the grandchild's parent
9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// keep nodes that are focusable
9848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::BuildFrame(Frame* root, Frame* frame,
9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CachedRoot* cachedRoot, CachedFrame* cachedFrame)
9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
987f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    WTF::Vector<FocusTracker> tracker(1); // sentinel
9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
989f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        FocusTracker* baseTracker = tracker.data();
990f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        bzero(baseTracker, sizeof(FocusTracker));
9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        baseTracker->mCachedNodeIndex = -1;
9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
993f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    WTF::Vector<LayerTracker> layerTracker(1); // sentinel
994f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    bzero(layerTracker.data(), sizeof(LayerTracker));
995f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    WTF::Vector<ClipColumnTracker> clipTracker(1); // sentinel
996f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    bzero(clipTracker.data(), sizeof(ClipColumnTracker));
997f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    WTF::Vector<TabIndexTracker> tabIndexTracker(1); // sentinel
998f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    bzero(tabIndexTracker.data(), sizeof(TabIndexTracker));
9991b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    WTF::Vector<CachedColor> colorTracker(1);
10001b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    InitColor(colorTracker.data());
10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if DUMP_NAV_CACHE
10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* frameNamePtr = cachedFrame->mDebug.mFrameName;
10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Builder(frame)->mDebug.frameName(frameNamePtr, frameNamePtr +
10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sizeof(cachedFrame->mDebug.mFrameName) - 1);
10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *frameNamePtr = '\0';
10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int nodeIndex = 1;
10078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NodeWalk walk;
10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Document* doc = frame->document();
10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* parent = doc;
10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CachedNode cachedParentNode;
10128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cachedParentNode.init(parent);
10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if DUMP_NAV_CACHE
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cachedParentNode.mDebug.mNodeIndex = nodeIndex;
10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
10161b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    cachedFrame->add(colorTracker[0]);
10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cachedFrame->add(cachedParentNode);
10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* node = parent;
10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int cacheIndex = 1;
10201b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    int colorIndex = 0; // assume no special css ring colors
10211b7c6c8d699a6520472f566710662983ed0ac650Cary Clark    const void* lastStyleDataPtr = 0;
10221d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark    int textInputIndex = 0;
10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* focused = doc->focusedNode();
102446dfee13b2bec1b39f46c138df565b2207ccbc86Cary Clark    if (focused)
102546dfee13b2bec1b39f46c138df565b2207ccbc86Cary Clark        cachedRoot->setFocusBounds(focused->getRect());
10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int globalOffsetX, globalOffsetY;
10278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GetGlobalOffset(frame, &globalOffsetX, &globalOffsetY);
10281dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott#if USE(ACCELERATED_COMPOSITING)
10291dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott    // The frame itself might be composited so we need to track the layer.  Do
10301dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott    // not track the base frame's layer as the main content is draw as part of
10311dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott    // BaseLayerAndroid's picture.
103217355895d12e1d97f449ae6a2f2d82f28d50980fCary Clark    if (frame != root && frame->contentRenderer()
103317355895d12e1d97f449ae6a2f2d82f28d50980fCary Clark        && frame->contentRenderer()->usesCompositing() && node->lastChild())
103417355895d12e1d97f449ae6a2f2d82f28d50980fCary Clark        TrackLayer(layerTracker, frame->contentRenderer(), node->lastChild(),
103517355895d12e1d97f449ae6a2f2d82f28d50980fCary Clark            globalOffsetX, globalOffsetY);
10361dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott#endif
10378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (walk.mMore || (node = node->traverseNextNode()) != NULL) {
10388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if DUMP_NAV_CACHE
10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        nodeIndex++;
10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1041f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        FocusTracker* last = &tracker.last();
10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int lastChildIndex = cachedFrame->size() - 1;
10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (node == last->mLastChild) {
1044a34b1107b2542fa334fd4db2d58e2df849e083b0Cary Clark            if (CleanUpContainedNodes(cachedRoot, cachedFrame, last, lastChildIndex))
10458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                cacheIndex--;
10468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tracker.removeLast();
10478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastChildIndex = last->mCachedNodeIndex;
10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            last = &tracker.last();
10498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        do {
10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const ClipColumnTracker* lastClip = &clipTracker.last();
10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node != lastClip->mLastChild)
10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clipTracker.removeLast();
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } while (true);
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        do {
1057f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark            const LayerTracker* lastLayer = &layerTracker.last();
1058f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark            if (node != lastLayer->mLastChild)
1059f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                break;
1060f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark            layerTracker.removeLast();
1061f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        } while (true);
1062f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        do {
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const TabIndexTracker* lastTabIndex = &tabIndexTracker.last();
10648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node != lastTabIndex->mLastChild)
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tabIndexTracker.removeLast();
10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } while (true);
10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Frame* child = HasFrame(node);
10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        CachedNode cachedNode;
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (child != NULL) {
10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (child->document() == NULL)
10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderObject* nodeRenderer = node->renderer();
10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (nodeRenderer != NULL && nodeRenderer->style()->visibility() == HIDDEN)
10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CachedFrame cachedChild;
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cachedChild.init(cachedRoot, cacheIndex, child);
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int childFrameIndex = cachedFrame->childCount();
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cachedFrame->addFrame(cachedChild);
10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cachedNode.init(node);
10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cachedNode.setIndex(cacheIndex++);
10821d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            cachedNode.setDataIndex(childFrameIndex);
10831d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            cachedNode.setType(FRAME_CACHEDNODETYPE);
10848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if DUMP_NAV_CACHE
10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cachedNode.mDebug.mNodeIndex = nodeIndex;
10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cachedNode.mDebug.mParentGroupIndex = Debug::ParentIndex(
10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                node, nodeIndex, NULL);
10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cachedFrame->add(cachedNode);
10908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CachedFrame* childPtr = cachedFrame->lastChild();
10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            BuildFrame(root, child, cachedRoot, childPtr);
10928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int tabIndex = node->tabIndex();
10958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* lastChild = node->lastChild();
10968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (tabIndex <= 0)
10978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tabIndex = tabIndexTracker.last().mTabIndex;
10988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (tabIndex > 0 && lastChild) {
10998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            DBG_NAV_LOGD("tabIndex=%d node=%p", tabIndex, node);
11008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tabIndexTracker.grow(tabIndexTracker.size() + 1);
11018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            TabIndexTracker& indexTracker = tabIndexTracker.last();
11028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            indexTracker.mTabIndex = tabIndex;
11038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            indexTracker.mLastChild = OneAfter(lastChild);
11048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderObject* nodeRenderer = node->renderer();
11068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool isTransparent = false;
110746dfee13b2bec1b39f46c138df565b2207ccbc86Cary Clark        bool hasCursorRing = true;
11088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (nodeRenderer != NULL) {
11098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderStyle* style = nodeRenderer->style();
11108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (style->visibility() == HIDDEN)
11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
1112605e3841dfeddd1eeaa36441c6bd4ec4667b89e8Steve Block            isTransparent = nodeRenderer->hasBackground() == false;
11138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
111446dfee13b2bec1b39f46c138df565b2207ccbc86Cary Clark            hasCursorRing = style->tapHighlightColor().alpha() > 0;
11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1116f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark#if USE(ACCELERATED_COMPOSITING)
111782f247bdbb98dd80c44209d87692c650c3704617Patrick Scott            // If this renderer has its own layer and the layer is composited,
111882f247bdbb98dd80c44209d87692c650c3704617Patrick Scott            // start tracking it.
11198b0b15e74bb7f1bd03bfd07f706a5afa637b0b73Patrick Scott            if (lastChild && nodeRenderer->hasLayer() && toRenderBoxModelObject(nodeRenderer)->layer()->backing())
11201dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott                TrackLayer(layerTracker, nodeRenderer, lastChild, globalOffsetX, globalOffsetY);
1121f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark#endif
11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool more = walk.mMore;
11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        walk.reset();
11258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     //   GetGlobalBounds(node, &bounds, false);
112646dfee13b2bec1b39f46c138df565b2207ccbc86Cary Clark        bool computeCursorRings = false;
11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool hasClip = false;
11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool hasMouseOver = false;
11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool isUnclipped = false;
11308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool isFocus = node == focused;
11318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool takesFocus = false;
11328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int columnGap = 0;
113399a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark        int imageCount = 0;
11348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        TextDirection direction = LTR;
11358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String exported;
11368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        CachedNodeType type = NORMAL_CACHEDNODETYPE;
11371b7c6c8d699a6520472f566710662983ed0ac650Cary Clark        CachedColor cachedColor;
11381d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark        CachedInput cachedInput;
11398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect bounds;
11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect absBounds;
1141d4924af12855cd19162ba1442a6055664c98ca32Cary Clark        IntRect originalAbsBounds;
1142c3109bb2893308e202242b132d7d912bb9799e43Iain Merrick        ColumnInfo* columnInfo = NULL;
11431d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark        if (node->hasTagName(HTMLNames::areaTag)) {
11441d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            type = AREA_CACHEDNODETYPE;
11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HTMLAreaElement* area = static_cast<HTMLAreaElement*>(node);
11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bounds = getAreaRect(area);
1147d4924af12855cd19162ba1442a6055664c98ca32Cary Clark            originalAbsBounds = bounds;
11488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bounds.move(globalOffsetX, globalOffsetY);
11498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            absBounds = bounds;
11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            isUnclipped = true;  // FIXME: areamaps require more effort to detect
11518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             // assume areamaps are always visible for now
11528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            takesFocus = true;
11538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            goto keepNode;
11548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (nodeRenderer == NULL)
11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
11578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // some common setup
11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        absBounds = nodeRenderer->absoluteBoundingBoxRect();
1160d4924af12855cd19162ba1442a6055664c98ca32Cary Clark        originalAbsBounds = absBounds;
11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        absBounds.move(globalOffsetX, globalOffsetY);
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        hasClip = nodeRenderer->hasOverflowClip();
11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (checkForPluginViewThatWantsFocus(nodeRenderer)) {
11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bounds = absBounds;
11668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            isUnclipped = true;
11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            takesFocus = true;
11681d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            type = PLUGIN_CACHEDNODETYPE;
11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            goto keepNode;
11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11711cc2f5523913bd14a01c0c85710dcd6f0d7b5bb8Leon Scroggins        // Only use the root contentEditable element
117224bd542d53743a6d367519174823cc57ad9cd3f8Steve Block        if (node->rendererIsEditable() && !node->parentOrHostNode()->rendererIsEditable()) {
11731cc2f5523913bd14a01c0c85710dcd6f0d7b5bb8Leon Scroggins            bounds = absBounds;
11741cc2f5523913bd14a01c0c85710dcd6f0d7b5bb8Leon Scroggins            takesFocus = true;
11751cc2f5523913bd14a01c0c85710dcd6f0d7b5bb8Leon Scroggins            type = CONTENT_EDITABLE_CACHEDNODETYPE;
11761cc2f5523913bd14a01c0c85710dcd6f0d7b5bb8Leon Scroggins            goto keepNode;
11771cc2f5523913bd14a01c0c85710dcd6f0d7b5bb8Leon Scroggins        }
11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (nodeRenderer->isRenderBlock()) {
11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderBlock* renderBlock = (RenderBlock*) nodeRenderer;
11808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (renderBlock->hasColumns()) {
1181c3109bb2893308e202242b132d7d912bb9799e43Iain Merrick                columnInfo = renderBlock->columnInfo();
11828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                columnGap = renderBlock->columnGap();
11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                direction = renderBlock->style()->direction();
11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1186c3109bb2893308e202242b132d7d912bb9799e43Iain Merrick        if ((hasClip != false || columnInfo != NULL) && lastChild) {
11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clipTracker.grow(clipTracker.size() + 1);
11888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ClipColumnTracker& clip = clipTracker.last();
11898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clip.mBounds = absBounds;
11908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clip.mLastChild = OneAfter(lastChild);
11918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clip.mNode = node;
1192c3109bb2893308e202242b132d7d912bb9799e43Iain Merrick            clip.mColumnInfo = columnInfo;
11938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clip.mColumnGap = columnGap;
11948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clip.mHasClip = hasClip;
11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clip.mDirection = direction;
1196c3109bb2893308e202242b132d7d912bb9799e43Iain Merrick            if (columnInfo != NULL) {
1197559e8b5e40d6fdd5897bbf576376f92a029a5828Ben Murdoch                const IntRect& oRect = ((RenderBox*)nodeRenderer)->visualOverflowRect();
11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                clip.mBounds.move(oRect.x(), oRect.y());
11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
12008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
12011d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark        if (node->isTextNode() && mAllowableTypes != NORMAL_CACHEDNODE_BITS) {
12028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (last->mSomeParentTakesFocus) // don't look at text inside focusable node
12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
12048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CachedNodeType checkType;
12058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (isFocusableText(&walk, more, node, &checkType,
12068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    &exported) == false)
12078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
12088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        #if DUMP_NAV_CACHE
12098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
12108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                char buffer[DEBUG_BUFFER_SIZE];
12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                mDebug.init(buffer, sizeof(buffer));
12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                mDebug.print("text link found: ");
12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                mDebug.wideString(exported);
12148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                DUMP_NAV_LOGD("%s\n", buffer);
12158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
12168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        #endif
12171d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            type = checkType;
12188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // !!! test ! is the following line correctly needed for frames to work?
12198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cachedNode.init(node);
12208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const ClipColumnTracker& clipTrack = clipTracker.last();
12218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const IntRect& clip = clipTrack.mHasClip ? clipTrack.mBounds :
12228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                IntRect(0, 0, INT_MAX, INT_MAX);
12238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (ConstructTextRects((WebCore::Text*) node, walk.mStart,
12248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    (WebCore::Text*) walk.mFinalNode, walk.mEnd, globalOffsetX,
122541ca040d7db923a179953baf91f30d539df6b055Cary Clark                    globalOffsetY, &bounds, clip, &cachedNode.mCursorRing) == false)
12268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
12278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            absBounds = bounds;
12288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cachedNode.setBounds(bounds);
12298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (bounds.width() < MINIMUM_FOCUSABLE_WIDTH)
12308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (bounds.height() < MINIMUM_FOCUSABLE_HEIGHT)
12328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
123346dfee13b2bec1b39f46c138df565b2207ccbc86Cary Clark            computeCursorRings = true;
12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            isUnclipped = true;  // FIXME: to hide or partially occlude synthesized links, each
12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                 // focus ring will also need the offset and length of characters
12368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                 // used to produce it
12378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            goto keepTextNode;
12388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
12398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (node->hasTagName(WebCore::HTMLNames::inputTag)) {
124062d9c8e597ebe68adce93008597730a41a1d716bLeon Scroggins            HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
12411d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            if (input->isTextField()) {
12427c6889e97c9d38a2815faac73c7bb97ae4e572e3Leon Scroggins                if (input->readOnly())
12437c6889e97c9d38a2815faac73c7bb97ae4e572e3Leon Scroggins                    continue;
12441d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark                type = TEXT_INPUT_CACHEDNODETYPE;
12451d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark                cachedInput.init();
1246ba87d726a9663788c0c5eae2ddb6c3ee24c4a740Leon Scroggins                cachedInput.setAutoComplete(input->autoComplete());
124785e3844824444f304a15e57f62d2e5670fb3bf47Michael Kolb                cachedInput.setSpellcheck(input->spellcheck());
124891a3bec8a1f1a64c6e1ca755766988b4fd6bf41aLeon Scroggins                cachedInput.setFormPointer(input->form());
12491d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark                cachedInput.setIsTextField(true);
1250de2098fbe71502df93eb3228ceaabd698aef0542Leon Scroggins                exported = input->value().threadsafeCopy();
12511d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark                cachedInput.setMaxLength(input->maxLength());
1252737a377f81baa2bf868b48f3457cc9a53cea2e6eBen Murdoch                cachedInput.setTypeFromElement(input);
12531d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark    // If this does not need to be threadsafe, we can use crossThreadString().
12541d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark    // See http://trac.webkit.org/changeset/49160.
12551d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark                cachedInput.setName(input->name().string().threadsafeCopy());
12561d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark    // can't detect if this is drawn on top (example: deviant.com login parts)
12571d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark                isUnclipped = isTransparent;
125841c8cd06bd25769654e321d1222856182ebad067Ben Murdoch            } else if (input->isInputTypeHidden())
1259dcbb033aafed2abc472f0d88520869a6b1f1945bLeon Scroggins                continue;
1260eecc9eee4d053cf13f84700d37047ede01c88b12Cary Clark            else if (input->isRadioButton() || input->isCheckbox())
1261eecc9eee4d053cf13f84700d37047ede01c88b12Cary Clark                isTransparent = false;
12628601da30c7a307f6ca8a2b15688480cc1e8251c9Leon Scroggins        } else if (node->hasTagName(HTMLNames::textareaTag)) {
12637c6889e97c9d38a2815faac73c7bb97ae4e572e3Leon Scroggins            HTMLTextAreaElement* area = static_cast<HTMLTextAreaElement*>(node);
12647c6889e97c9d38a2815faac73c7bb97ae4e572e3Leon Scroggins            if (area->readOnly())
12657c6889e97c9d38a2815faac73c7bb97ae4e572e3Leon Scroggins                continue;
12661d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            cachedInput.init();
12671d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            type = TEXT_INPUT_CACHEDNODETYPE;
126891a3bec8a1f1a64c6e1ca755766988b4fd6bf41aLeon Scroggins            cachedInput.setFormPointer(area->form());
126941c8cd06bd25769654e321d1222856182ebad067Ben Murdoch            cachedInput.setIsTextArea(true);
127084080ee930ca8af9706379ed3e304904f598050aJohn Reck            cachedInput.setSpellcheck(area->spellcheck());
1271de2098fbe71502df93eb3228ceaabd698aef0542Leon Scroggins            exported = area->value().threadsafeCopy();
12728601da30c7a307f6ca8a2b15688480cc1e8251c9Leon Scroggins        } else if (node->hasTagName(HTMLNames::aTag)) {
12738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const HTMLAnchorElement* anchorNode =
12748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                (const HTMLAnchorElement*) node;
12758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!anchorNode->isFocusable() && !HasTriggerEvent(node))
12768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
12778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (node->disabled())
12788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
12798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            hasMouseOver = NodeHasEventListeners(node, &eventNames().mouseoverEvent, 1);
12801d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            type = ANCHOR_CACHEDNODETYPE;
12818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            KURL href = anchorNode->href();
128206f1ecff0f609438be162b71b50a3be08983df23Patrick Scott            if (!href.isEmpty() && !WebCore::protocolIsJavaScript(href.string()))
12838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Set the exported string for all non-javascript anchors.
12848e1c14d2cd6633dac941b17af2bea9c045ee0140Steve Block                exported = href.string().threadsafeCopy();
1285daef1e675c1c6ebcf304236d68375b611c3871e7Leon Scroggins        } else if (node->hasTagName(HTMLNames::selectTag)) {
1286daef1e675c1c6ebcf304236d68375b611c3871e7Leon Scroggins            type = SELECT_CACHEDNODETYPE;
12878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
12881d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark        if (type == TEXT_INPUT_CACHEDNODETYPE) {
12898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderTextControl* renderText =
12908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                static_cast<RenderTextControl*>(nodeRenderer);
12918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (isFocus)
12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                cachedRoot->setSelection(renderText->selectionStart(), renderText->selectionEnd());
12938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // FIXME: Are we sure there will always be a style and font, and it's correct?
12948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderStyle* style = nodeRenderer->style();
12958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (style) {
12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                isUnclipped |= !style->hasAppearance();
1297d8fcffded6ee266e903e4e191ed95a07007fac74Leon Scroggins                int lineHeight = -1;
1298d8fcffded6ee266e903e4e191ed95a07007fac74Leon Scroggins                Length lineHeightLength = style->lineHeight();
1299d8fcffded6ee266e903e4e191ed95a07007fac74Leon Scroggins                // If the lineHeight is negative, WebTextView will calculate it
1300d8fcffded6ee266e903e4e191ed95a07007fac74Leon Scroggins                // based on the text size, using the Paint.
1301d8fcffded6ee266e903e4e191ed95a07007fac74Leon Scroggins                // See RenderStyle.computedLineHeight.
1302d8fcffded6ee266e903e4e191ed95a07007fac74Leon Scroggins                if (lineHeightLength.isPositive())
1303d8fcffded6ee266e903e4e191ed95a07007fac74Leon Scroggins                    lineHeight = style->computedLineHeight();
1304d8fcffded6ee266e903e4e191ed95a07007fac74Leon Scroggins                cachedInput.setLineHeight(lineHeight);
13053a3b28707d2d6a06afe9f3137e9bedc07246d600Leon Scroggins                cachedInput.setTextSize(style->font().size());
13061d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark                cachedInput.setIsRtlText(style->direction() == RTL
13071d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark                        || style->textAlign() == WebCore::RIGHT
13081d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark                        || style->textAlign() == WebCore::WEBKIT_RIGHT);
13098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1310390c2b5702d131f0875199fdca1c3ba5010d7659Leon Scroggins            cachedInput.setPaddingLeft(renderText->paddingLeft() + renderText->borderLeft());
1311390c2b5702d131f0875199fdca1c3ba5010d7659Leon Scroggins            cachedInput.setPaddingTop(renderText->paddingTop() + renderText->borderTop());
1312390c2b5702d131f0875199fdca1c3ba5010d7659Leon Scroggins            cachedInput.setPaddingRight(renderText->paddingRight() + renderText->borderRight());
1313390c2b5702d131f0875199fdca1c3ba5010d7659Leon Scroggins            cachedInput.setPaddingBottom(renderText->paddingBottom() + renderText->borderBottom());
13148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        takesFocus = true;
131608ccebc1045cc42af60d01c19ce6ce27ca616604Cary Clark        bounds = absBounds;
13171d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark        if (type != ANCHOR_CACHEDNODETYPE) {
13188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bool isFocusable = node->isKeyboardFocusable(NULL) ||
13198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                node->isMouseFocusable() || node->isFocusable();
13208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (isFocusable == false) {
13218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (node->disabled())
13228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
13238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool overOrOut = HasOverOrOut(node);
13248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool hasTrigger = HasTriggerEvent(node);
13258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (overOrOut == false && hasTrigger == false)
13268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
13278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                takesFocus = hasTrigger;
13288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
13298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
133046dfee13b2bec1b39f46c138df565b2207ccbc86Cary Clark        computeCursorRings = true;
13318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    keepNode:
13328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.init(node);
133346dfee13b2bec1b39f46c138df565b2207ccbc86Cary Clark        if (computeCursorRings == false) {
13348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cachedNode.setBounds(bounds);
133541ca040d7db923a179953baf91f30d539df6b055Cary Clark            cachedNode.mCursorRing.append(bounds);
133641ca040d7db923a179953baf91f30d539df6b055Cary Clark        } else if (ConstructPartRects(node, bounds, &cachedNode.mBounds,
133799a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark                globalOffsetX, globalOffsetY, &cachedNode.mCursorRing,
133899a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark                &imageCount) == false)
13398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
13408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    keepTextNode:
13411b7c6c8d699a6520472f566710662983ed0ac650Cary Clark        if (nodeRenderer) { // area tags' node->renderer() == 0
13421b7c6c8d699a6520472f566710662983ed0ac650Cary Clark            RenderStyle* style = nodeRenderer->style();
13431b7c6c8d699a6520472f566710662983ed0ac650Cary Clark            const void* styleDataPtr = style->ringData();
13441b7c6c8d699a6520472f566710662983ed0ac650Cary Clark            // to save time, see if we're pointing to the same style data as before
13451b7c6c8d699a6520472f566710662983ed0ac650Cary Clark            if (lastStyleDataPtr != styleDataPtr) {
13461b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                lastStyleDataPtr = styleDataPtr;
13471b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                cachedColor.setFillColor(style->ringFillColor());
13481b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                cachedColor.setInnerWidth(style->ringInnerWidth());
13491b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                cachedColor.setOuterWidth(style->ringOuterWidth());
13501b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                cachedColor.setOutset(style->ringOutset());
13511b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                cachedColor.setPressedInnerColor(style->ringPressedInnerColor());
13521b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                cachedColor.setPressedOuterColor(style->ringPressedOuterColor());
13531b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                cachedColor.setRadius(style->ringRadius());
13541b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                cachedColor.setSelectedInnerColor(style->ringSelectedInnerColor());
13551b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                cachedColor.setSelectedOuterColor(style->ringSelectedOuterColor());
13561b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                int oldSize = colorTracker.size();
13571b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                colorIndex = FindColorIndex(colorTracker, cachedColor);
13581b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                if (colorIndex == oldSize)
13591b7c6c8d699a6520472f566710662983ed0ac650Cary Clark                    cachedFrame->add(cachedColor);
13601b7c6c8d699a6520472f566710662983ed0ac650Cary Clark            }
13611b7c6c8d699a6520472f566710662983ed0ac650Cary Clark        } else
13621b7c6c8d699a6520472f566710662983ed0ac650Cary Clark            colorIndex = 0;
13638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect clip = hasClip ? bounds : absBounds;
13648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        size_t clipIndex = clipTracker.size();
13658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (clipTracker.last().mNode == node)
13668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clipIndex -= 1;
13678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (--clipIndex > 0) {
13688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const ClipColumnTracker& clipTrack = clipTracker.at(clipIndex);
13698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (clipTrack.mHasClip == false) {
1370b4b1148720e724bf404dadaa5443caaa286f5724Steve Block                adjustForColumns(clipTrack, &cachedNode, &absBounds, static_cast<RenderBlock*>(nodeRenderer));
13718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
13728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
13738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const IntRect& parentClip = clipTrack.mBounds;
13741d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            if (hasClip == false && type == ANCHOR_CACHEDNODETYPE)
13758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                clip = parentClip;
13768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
13778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                clip.intersect(parentClip);
13788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            hasClip = true;
13798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1380f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        bool isInLayer = false;
1381f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark#if USE(ACCELERATED_COMPOSITING)
138282f247bdbb98dd80c44209d87692c650c3704617Patrick Scott        // If this renderer has a composited parent layer (including itself),
138382f247bdbb98dd80c44209d87692c650c3704617Patrick Scott        // add the node to the cached layer.
1384f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        // FIXME: does not work for area rects
138582f247bdbb98dd80c44209d87692c650c3704617Patrick Scott        RenderLayer* enclosingLayer = nodeRenderer->enclosingLayer();
138682f247bdbb98dd80c44209d87692c650c3704617Patrick Scott        if (enclosingLayer && enclosingLayer->enclosingCompositingLayer()) {
138782f247bdbb98dd80c44209d87692c650c3704617Patrick Scott            LayerAndroid* layer = layerTracker.last().mLayer;
138882f247bdbb98dd80c44209d87692c650c3704617Patrick Scott            if (layer) {
138982f247bdbb98dd80c44209d87692c650c3704617Patrick Scott                const IntRect& layerClip = layerTracker.last().mBounds;
139082f247bdbb98dd80c44209d87692c650c3704617Patrick Scott                if (!layerClip.isEmpty() && !cachedNode.clip(layerClip)) {
139182f247bdbb98dd80c44209d87692c650c3704617Patrick Scott                    DBG_NAV_LOGD("skipped on layer clip %d", cacheIndex);
139282f247bdbb98dd80c44209d87692c650c3704617Patrick Scott                    continue; // skip this node if outside of the clip
139382f247bdbb98dd80c44209d87692c650c3704617Patrick Scott                }
139482f247bdbb98dd80c44209d87692c650c3704617Patrick Scott                isInLayer = true;
139582f247bdbb98dd80c44209d87692c650c3704617Patrick Scott                isUnclipped = true; // assume that layers do not have occluded nodes
13968598c9fb9f861f25ab14efde9efb19cb91d7df1cPatrick Scott                hasClip = false;
139782f247bdbb98dd80c44209d87692c650c3704617Patrick Scott                AddLayer(cachedFrame, cachedFrame->size(), layerClip.location(),
139882f247bdbb98dd80c44209d87692c650c3704617Patrick Scott                         layer->uniqueId());
1399be4ea5d07252747b3faad9dd63d4bebe79f24db3Cary Clark            }
1400f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        }
1401f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark#endif
14028598c9fb9f861f25ab14efde9efb19cb91d7df1cPatrick Scott        if (hasClip) {
14038598c9fb9f861f25ab14efde9efb19cb91d7df1cPatrick Scott            if (clip.isEmpty())
14048598c9fb9f861f25ab14efde9efb19cb91d7df1cPatrick Scott                continue; // skip this node if clip prevents all drawing
14058598c9fb9f861f25ab14efde9efb19cb91d7df1cPatrick Scott            else if (cachedNode.clip(clip) == false)
14068598c9fb9f861f25ab14efde9efb19cb91d7df1cPatrick Scott                continue; // skip this node if outside of the clip
14078598c9fb9f861f25ab14efde9efb19cb91d7df1cPatrick Scott        }
14081b7c6c8d699a6520472f566710662983ed0ac650Cary Clark        cachedNode.setColorIndex(colorIndex);
14098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.setExport(exported);
141046dfee13b2bec1b39f46c138df565b2207ccbc86Cary Clark        cachedNode.setHasCursorRing(hasCursorRing);
14118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.setHasMouseOver(hasMouseOver);
14128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.setHitBounds(absBounds);
14138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.setIndex(cacheIndex);
14148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.setIsFocus(isFocus);
1415f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        cachedNode.setIsInLayer(isInLayer);
14168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.setIsTransparent(isTransparent);
14178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.setIsUnclipped(isUnclipped);
1418d4924af12855cd19162ba1442a6055664c98ca32Cary Clark        cachedNode.setOriginalAbsoluteBounds(originalAbsBounds);
14198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.setParentIndex(last->mCachedNodeIndex);
1420a0428a863bd79d20e416d6d981d0120bd1569edfCary Clark        cachedNode.setParentGroup(ParentWithChildren(node));
142199a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark        cachedNode.setSingleImage(imageCount == 1);
14228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.setTabIndex(tabIndex);
14238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.setType(type);
14241d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark        if (type == TEXT_INPUT_CACHEDNODETYPE) {
14251d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            cachedFrame->add(cachedInput);
14261d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            cachedNode.setDataIndex(textInputIndex);
14271d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            textInputIndex++;
14281d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark        } else
14291d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark            cachedNode.setDataIndex(-1);
14308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if DUMP_NAV_CACHE
14318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.mDebug.mNodeIndex = nodeIndex;
14328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedNode.mDebug.mParentGroupIndex = Debug::ParentIndex(
14338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            node, nodeIndex, (Node*) cachedNode.parentGroup());
14348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
14358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cachedFrame->add(cachedNode);
14368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
14378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int lastIndex = cachedFrame->size() - 1;
14388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node == focused) {
14398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                CachedNode* cachedNodePtr = cachedFrame->getIndex(lastIndex);
14408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                cachedRoot->setCachedFocus(cachedFrame, cachedNodePtr);
14418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
14428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (lastChild != NULL) {
14438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                tracker.grow(tracker.size() + 1);
1444f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark                FocusTracker& working = tracker.last();
14458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                working.mCachedNodeIndex = lastIndex;
14468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                working.mLastChild = OneAfter(lastChild);
14478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                last = &tracker.at(tracker.size() - 2);
14488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                working.mSomeParentTakesFocus = last->mSomeParentTakesFocus | takesFocus;
14498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
14508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
14518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cacheIndex++;
14528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (tracker.size() > 1) {
1454f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        FocusTracker* last = &tracker.last();
14558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int lastChildIndex = cachedFrame->size() - 1;
1456a34b1107b2542fa334fd4db2d58e2df849e083b0Cary Clark        if (CleanUpContainedNodes(cachedRoot, cachedFrame, last, lastChildIndex))
14578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cacheIndex--;
14588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        tracker.removeLast();
14598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1462a34b1107b2542fa334fd4db2d58e2df849e083b0Cary Clarkbool CacheBuilder::CleanUpContainedNodes(CachedRoot* cachedRoot,
1463a34b1107b2542fa334fd4db2d58e2df849e083b0Cary Clark    CachedFrame* cachedFrame, const FocusTracker* last, int lastChildIndex)
14648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // if outer is body, disable outer
14668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // or if there's more than one inner, disable outer
14678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // or if inner is keyboard focusable, disable outer
14688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // else disable inner by removing it
14698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int childCount = lastChildIndex - last->mCachedNodeIndex;
14708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (childCount == 0)
14718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
14728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CachedNode* lastCached = cachedFrame->getIndex(last->mCachedNodeIndex);
14738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* lastNode = (Node*) lastCached->nodePointer();
14748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ((childCount > 1 && lastNode->hasTagName(HTMLNames::selectTag) == false) ||
14758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastNode->hasTagName(HTMLNames::bodyTag) ||
14768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastNode->hasTagName(HTMLNames::formTag)) {
14778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastCached->setBounds(IntRect(0, 0, 0, 0));
147841ca040d7db923a179953baf91f30d539df6b055Cary Clark        lastCached->mCursorRing.clear();
14798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
14808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CachedNode* onlyChildCached = cachedFrame->lastNode();
14828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* onlyChild = (Node*) onlyChildCached->nodePointer();
14838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool outerIsMouseMoveOnly =
14848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastNode->isKeyboardFocusable(NULL) == false &&
14858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastNode->isMouseFocusable() == false &&
14868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastNode->isFocusable() == false &&
14878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HasOverOrOut(lastNode) == true &&
14888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HasTriggerEvent(lastNode) == false;
14898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (onlyChildCached->parent() == lastCached)
14908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        onlyChildCached->setParentIndex(lastCached->parentIndex());
1491a34b1107b2542fa334fd4db2d58e2df849e083b0Cary Clark    bool hasFocus = lastCached->isFocus() || onlyChildCached->isFocus();
1492b9e5acbf6b83aab48187946a1d498f0576ded418Derek Sollenberger    if (outerIsMouseMoveOnly || onlyChild->isKeyboardFocusable(NULL)
1493b9e5acbf6b83aab48187946a1d498f0576ded418Derek Sollenberger            || onlyChildCached->isPlugin()) {
1494908643d12d19aa4f2d69c47d5c1d4243da8ddfb7Cary Clark        int index = lastCached->index();
14958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *lastCached = *onlyChildCached;
1496908643d12d19aa4f2d69c47d5c1d4243da8ddfb7Cary Clark        lastCached->setIndex(index);
1497908643d12d19aa4f2d69c47d5c1d4243da8ddfb7Cary Clark        CachedFrame* frame = cachedFrame->hasFrame(lastCached);
1498908643d12d19aa4f2d69c47d5c1d4243da8ddfb7Cary Clark        if (frame)
1499908643d12d19aa4f2d69c47d5c1d4243da8ddfb7Cary Clark            frame->setIndexInParent(index);
1500908643d12d19aa4f2d69c47d5c1d4243da8ddfb7Cary Clark    }
15018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cachedFrame->removeLast();
1502a34b1107b2542fa334fd4db2d58e2df849e083b0Cary Clark    if (hasFocus)
1503a34b1107b2542fa334fd4db2d58e2df849e083b0Cary Clark        cachedRoot->setCachedFocus(cachedFrame, cachedFrame->lastNode());
15048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
15058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNode* CacheBuilder::currentFocus() const
15088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = FrameAnd(this);
15108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Document* doc = frame->document();
15118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (doc != NULL) {
15128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* focus = doc->focusedNode();
15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (focus != NULL)
15148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return focus;
15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* child = frame->tree()->firstChild();
15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        CacheBuilder* cacheBuilder = Builder(child);
15198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* focus = cacheBuilder->currentFocus();
15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (focus)
15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return focus;
15228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = child->tree()->nextSibling();
15238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return NULL;
15258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool strCharCmp(const char* matches, const UChar* test, int wordLength,
15288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int wordCount)
15298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int index = 0; index < wordCount; index++) {
15318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int inner = 0; inner < wordLength; inner++) {
15328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (matches[inner] != test[inner]) {
15338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                matches += wordLength;
15348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                goto next;
15358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
15368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
15378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
15388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnext:
15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ;
15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const int stateTwoLetter[] = {
15458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x02060c00,  // A followed by: [KLRSZ]
15468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00000000,  // B
15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00084001,  // C followed by: [AOT]
15488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00000014,  // D followed by: [CE]
15498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00000000,  // E
15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00001800,  // F followed by: [LM]
15518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00100001,  // G followed by: [AU]
15528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00000100,  // H followed by: [I]
15538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00002809,  // I followed by: [ADLN]
15548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00000000,  // J
15558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x01040000,  // K followed by: [SY]
15568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00000001,  // L followed by: [A]
15578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x000ce199,  // M followed by: [ADEHINOPST]
15588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x0120129c,  // N followed by: [CDEHJMVY]
15598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00020480,  // O followed by: [HKR]
15608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00420001,  // P followed by: [ARW]
15618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00000000,  // Q
15628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00000100,  // R followed by: [I]
15638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x0000000c,  // S followed by: [CD]
15648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00802000,  // T followed by: [NX]
15658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00080000,  // U followed by: [T]
15668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x00080101,  // V followed by: [AIT]
15678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0x01200101   // W followed by: [AIVY]
15688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
15698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const char firstIndex[] = {
15718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     0,  5,  5,  8, 10, 10, 12, 14,
15728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    15, 19, 19, 21, 22, 32, 40, 43,
15738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    46, 46, 47, 49, 51, 52, 55, 59
15748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
15758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// from http://infolab.stanford.edu/~manku/bitcount/bitcount.html
15778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define TWO(c)     (0x1u << (c))
15788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define MASK(c)    (((unsigned int)(-1)) / (TWO(TWO(c)) + 1u))
15798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define COUNT(x,c) ((x) & MASK(c)) + (((x) >> (TWO(c))) & MASK(c))
15808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint bitcount (unsigned int n)
15828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    n = COUNT(n, 0);
15848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    n = COUNT(n, 1);
15858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    n = COUNT(n, 2);
15868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    n = COUNT(n, 3);
15878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return COUNT(n, 4);
15888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#undef TWO
15918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#undef MASK
15928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#undef COUNT
15938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool isUnicodeSpace(UChar ch)
15958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == 0xa0;
15978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool validZip(int stateIndex, const UChar* zipPtr)
16008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static const struct {
16028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char mLow;
16038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char mHigh;
16048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char mException1;
16058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char mException2;
16068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } zipRange[] = {
16078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 99, 99, -1, -1 }, // AK Alaska
16088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 35, 36, -1, -1 }, // AL Alabama
16098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 71, 72, -1, -1 }, // AR Arkansas
16108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 96, 96, -1, -1 }, // AS American Samoa
16118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 85, 86, -1, -1 }, // AZ Arizona
16128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 90, 96, -1, -1 }, // CA California
16138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 80, 81, -1, -1 }, // CO Colorado
16148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {  6,  6, -1, -1 }, // CT Connecticut
16158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 20, 20, -1, -1 }, // DC District of Columbia
16168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 19, 19, -1, -1 }, // DE Delaware
16178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 32, 34, -1, -1 }, // FL Florida
16188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 96, 96, -1, -1 }, // FM Federated States of Micronesia
16198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 30, 31, -1, -1 }, // GA Georgia
16208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 96, 96, -1, -1 }, // GU Guam
16218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 96, 96, -1, -1 }, // HI Hawaii
16228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 50, 52, -1, -1 }, // IA Iowa
16238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 83, 83, -1, -1 }, // ID Idaho
16248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 60, 62, -1, -1 }, // IL Illinois
16258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 46, 47, -1, -1 }, // IN Indiana
16268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 66, 67, 73, -1 }, // KS Kansas
16278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 40, 42, -1, -1 }, // KY Kentucky
16288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 70, 71, -1, -1 }, // LA Louisiana
16298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {  1,  2, -1, -1 }, // MA Massachusetts
16308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 20, 21, -1, -1 }, // MD Maryland
16318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {  3,  4, -1, -1 }, // ME Maine
16328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 96, 96, -1, -1 }, // MH Marshall Islands
16338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 48, 49, -1, -1 }, // MI Michigan
16348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 55, 56, -1, -1 }, // MN Minnesota
16358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 63, 65, -1, -1 }, // MO Missouri
16368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 96, 96, -1, -1 }, // MP Northern Mariana Islands
16378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 38, 39, -1, -1 }, // MS Mississippi
16388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 55, 56, -1, -1 }, // MT Montana
16398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 27, 28, -1, -1 }, // NC North Carolina
16408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 58, 58, -1, -1 }, // ND North Dakota
16418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 68, 69, -1, -1 }, // NE Nebraska
16428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {  3,  4, -1, -1 }, // NH New Hampshire
16438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {  7,  8, -1, -1 }, // NJ New Jersey
16448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 87, 88, 86, -1 }, // NM New Mexico
16458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 88, 89, 96, -1 }, // NV Nevada
16468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 10, 14,  0,  6 }, // NY New York
16478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 43, 45, -1, -1 }, // OH Ohio
16488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 73, 74, -1, -1 }, // OK Oklahoma
16498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 97, 97, -1, -1 }, // OR Oregon
16508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 15, 19, -1, -1 }, // PA Pennsylvania
16518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {  6,  6,  0,  9 }, // PR Puerto Rico
16528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 96, 96, -1, -1 }, // PW Palau
16538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {  2,  2, -1, -1 }, // RI Rhode Island
16548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 29, 29, -1, -1 }, // SC South Carolina
16558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 57, 57, -1, -1 }, // SD South Dakota
16568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 37, 38, -1, -1 }, // TN Tennessee
16578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 75, 79, 87, 88 }, // TX Texas
16588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 84, 84, -1, -1 }, // UT Utah
16598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 22, 24, 20, -1 }, // VA Virginia
16608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {  6,  9, -1, -1 }, // VI Virgin Islands
16618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {  5,  5, -1, -1 }, // VT Vermont
16628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 98, 99, -1, -1 }, // WA Washington
16638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 53, 54, -1, -1 }, // WI Wisconsin
16648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 24, 26, -1, -1 }, // WV West Virginia
16658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        { 82, 83, -1, -1 }  // WY Wyoming
16668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
16678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int zip = zipPtr[0] - '0';
16698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    zip *= 10;
16708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    zip += zipPtr[1] - '0';
16718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int low = zipRange[stateIndex].mLow;
16728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int high = zipRange[stateIndex].mHigh;
16738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (zip >= low && zip <= high)
16748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
16758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (zip == zipRange[stateIndex].mException1)
16768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (zip == zipRange[stateIndex].mException2)
16788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
16798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
16808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define MAX_PLACE_NAME_LENGTH 25 // the longest allowable one word place name
16838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16848e9932d793b751bd6a2c1150bf273867f40c5f55Cary ClarkCacheBuilder::FoundState CacheBuilder::FindAddress(const UChar* chars,
16858e9932d793b751bd6a2c1150bf273867f40c5f55Cary Clark    unsigned length, int* start, int* end, bool caseInsensitive)
16868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FindState addressState;
16888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FindReset(&addressState);
16898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    addressState.mWords[0] = addressState.mStarts[0] = chars;
16908e9932d793b751bd6a2c1150bf273867f40c5f55Cary Clark    addressState.mCaseInsensitive = caseInsensitive;
16918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FoundState state = FindPartialAddress(chars, chars, length, &addressState);
16928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (state == FOUND_PARTIAL && addressState.mProgress == ZIP_CODE &&
16938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            addressState.mNumberCount == 0) {
16948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addressState.mProgress = FIND_STREET;
16958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        state = FindPartialAddress(NULL, NULL, 0, &addressState);
16968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *start = addressState.mStartResult;
16988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *end = addressState.mEndResult;
16998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return state;
17008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCacheBuilder::FoundState CacheBuilder::FindPartialAddress(const UChar* baseChars,
17038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* chars, unsigned length, FindState* s)
17048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
17058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // lower case letters are optional; trailing asterisk is optional 's'
17068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static char const* const longStreetNames[] = {
17078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x04" "LleY" "\x04" "NneX" "\x05" "RCade" "\x05" "VEnue" "\x06" "LAMEDA", // A
17088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x04" "aYoU" "\x04" "eaCH" "\x03" "eND" "\x05" "LuFf*" "\x05" "oTtoM"
17098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x08" "ouLeVarD" "\x05" "Ranch" "\x05" "RidGe" "\x05" "RooK*"
17108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x04" "urG*" "\x05" "YPass" "\x07" "roadWAY", // B
17118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x05" "AMINO"
17128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x03" "amP" "\x05" "anYoN" "\x03" "aPE" "\x07" "auSeWaY" "\x06" "enTeR*"
17138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x06" "IRcle*" "\x05" "LiFf*" "\x03" "LuB" "\x05" "oMmoN" "\x06" "ORner*"
17148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x05" "ouRSE" "\x05" "ourT*" "\x04" "oVe*" "\x04" "ReeK" "\x07" "REScent"
17158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x04" "ReST" "\x07" "ROSSING" "\x08" "ROSSROAD" "\x04" "URVe"
17168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x05" "AMINO" "\x06" "IRCULO" "\x07" "REScent", // C
17178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x03" "aLe" "\x02" "aM" "\x05" "iVide" "\x05" "Rive*", // D
17188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x06" "STate*" "\x09" "XPresswaY" "\x09" "XTension*", // E
17198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x04" "ALL*" "\x04" "eRrY" "\x05" "ieLD*" "\x04" "LaT*" "\x04" "oRD*"
17208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x05" "oReST" "\x05" "oRGe*" "\x04" "oRK*" "\x03" "orT" "\x06" "reeWaY", // F
17218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x06" "arDeN*" "\x06" "aTeWaY" "\x04" "LeN*" "\x05" "ReeN*" "\x05" "RoVe*", // G
17228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x06" "arBoR*" "\x04" "aVeN" "\x06" "eighTS" "\x06" "ighWaY" "\x04" "iLl*"
17238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x05" "OLloW", // H
17248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x04" "NLeT" "\x06" "Sland*" "\x03" "SLE", // I
17258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x08" "unCTion*", // J
17268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x03" "eY*" "\x05" "NoLl*", // K
17278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x04" "aKe*" "\x03" "AND" "\x06" "aNDinG" "\x03" "aNe" "\x05" "iGhT*"
17288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x03" "oaF" "\x04" "oCK*" "\x04" "oDGe" "\x03" "OOP", // L
17298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x03" "ALL" "\x05" "aNoR*" "\x06" "eaDoW*" "\x03" "EWS" "\x04" "iLl*"
17308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x06" "iSsioN" "\x07" "oTorWaY" "\x04" "ounT" "\x08" "ounTaiN*", // M
17318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x03" "eCK", // N
17328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x06" "RCHard" "\x03" "VAL" "\x07" "verPASs", // O
17338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x04" "ARK*" "\x07" "arKWaY*" "\x03" "ASS" "\x06" "aSsaGE" "\x03" "ATH"
17348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x03" "IKE" "\x04" "iNE*" "\x04" "Lace" "\x05" "LaiN*" "\x04" "LaZa"
17358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x05" "oinT*" "\x04" "oRT*" "\x06" "Rairie" "\x06" "RIVADA", // P
17368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,
17378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x05" "ADiaL" "\x03" "AMP" "\x04" "aNCH" "\x05" "aPiD*"
17388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x03" "eST"
17398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x05" "iDGe*" "\x04" "IVer" "\x04" "oaD*" "\x04" "ouTE" "\x02" "OW"
17408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x02" "UE" "\x02" "UN", // R
17418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x05" "HoaL*" "\x05" "HoRe*" "\x05" "KyWaY" "\x06" "PrinG*" "\x04" "PUR*"
17428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x06" "Quare*" "\x06" "TAtion" "\x08" "TRAvenue" "\x05" "TReaM"
17438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x06" "Treet*" "\x05" "uMmiT" "\x07" "PeeDWaY", // S
17448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x06" "ERrace" "\x09" "hRoughWaY" "\x04" "RaCE" "\x04" "RAcK" "\x09" "RaFficwaY"
17458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x04" "RaiL" "\x05" "UNneL" "\x07" "urnPiKE", // T
17468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x08" "nderPASs" "\x05" "Nion*", // U
17478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x06" "aLleY*" "\x06" "IAduct" "\x04" "ieW*" "\x07" "iLlaGe*" "\x04" "iLle"
17488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            "\x04" "ISta", // V
17498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x04" "ALK*" "\x03" "ALL" "\x03" "AY*" "\x04" "eLl*", // W
17508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x03" "ING" "\x02" "RD", // X
17518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
17528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static char const* const longStateNames[] = {
17548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x8e" "la" "\x85" "bama" "\x02" "\x84" "ska" "\x01" "\x8f" "merican Samoa" "\x04"
17558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             "\x91" "r" "\x86" "izona" "\x05" "\x87" "kansas" "\x03",
17568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,
17578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x8b" "alifornia" "\x06" "\x95" "o" "\x87" "lorado" "\x07" "\x8a" "nnecticut" "\x08",
17588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x89" "elaware" "\x0a" "\x95" "istrict of Columbia" "\x09",
17598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,
17608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x9f" "ederated States of Micronesia" "\x0c" "\x88" "lorida" "\x0b",
17618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x85" "uam" "\x0e" "\x88" "eorgia" "\x0d",
17628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x87" "awaii" "\x0f",
17638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x86" "daho" "\x11" "\x89" "llinois" "\x12" "\x88" "ndiana" "\x13" "\x85"
17648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             "owa" "\x10",
17658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,
17668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x87" "ansas" "\x14" "\x89" "entucky" "\x15",
17678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x8a" "ouisiana" "\x16",
17688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x86" "aine" "\x19" "\x99" "ar" "\x8e" "shall Islands" "\x1a" "\x86" "yland" "\x18"
17698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             "\x8e" "assachusetts" "\x17" "\x93" "i" "\x87" "chigan" "\x1b"
17708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             "\x88" "nnesota" "\x1c" "\x93" "iss" "\x88" "issippi" "\x1f" "\x85"
17718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             "ouri" "\x1d" "\x88" "ontana" "\x20",
17728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x90" "e" "\x87" "braska" "\x23" "\x85" "vada" "\x27" "\xa5" "ew " "\x8a"
17738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             "Hampshire" "\x24" "\x87" "Jersey" "\x25" "\x87" "Mexico" "\x26"
17748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             "\x85" "York" "\x28" "\x98" "orth " "\x89" "Carolina" "\x21" "\x87"
17758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             "Dakota" "\x22" "\x99" "orthern Mariana Islands" "\x1e",
17768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x85" "hio" "\x29" "\x89" "klahoma" "\x2a" "\x87" "regon" "\x2b",
17778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x86" "alau" "\x2e" "\x8d" "ennsylvania" "\x2c" "\x8c" "uerto Rico" "\x2d",
17788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,
17798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x8d" "hode Island" "\x2f",
17808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x98" "outh " "\x89" "Carolina" "\x30" "\x87" "Dakota" "\x31",
17818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x90" "e" "\x88" "nnessee" "\x32" "\x84" "xas" "\x33",
17828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x85" "tah" "\x34",
17838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x88" "ermont" "\x37" "\x94" "irgin" "\x89" " Islands" "\x36" "\x83" "ia" "\x35",
17848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x8b" "ashington" "\x38" "\x8e" "est Virginia" "\x3a" "\x8a" "isconsin" "\x39"
17858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project             "\x88" "yoming" "\x3b"
17868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
17878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if 0 // DEBUG_NAV_UI
17898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static char const* const progressNames[] = {
17908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "NO_ADDRESS",
17918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "SKIP_TO_SPACE",
17928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "HOUSE_NUMBER",
17938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "NUMBER_TRAILING_SPACE",
17948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "ADDRESS_LINE",
17958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "STATE_NAME",
17968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "SECOND_HALF",
17978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "ZIP_CODE",
17988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "PLUS_4",
17998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "FIND_STREET"
18008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
18018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
18028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // strategy: US only support at first
18038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // look for a 1 - 5 digit number for a street number (no support for 'One Microsoft Way')
18048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // ignore if preceded by '#', Suite, Ste, Rm
18058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // look for two or more words (up to 5? North Frank Lloyd Wright Blvd)
18068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // note: "The Circle at North Hills St." has six words, and a lower 'at' -- allow at, by, of, in, the, and, ... ?
18078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // if a word starts with a lowercase letter, no match
18088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // allow: , . - # / (for 1/2) ' "
18098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // don't look for street name type yet
18108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // look for one or two delimiters to represent possible 2nd addr line and city name
18118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // look for either full state name, or state two letters, and/or zip code (5 or 9 digits)
18128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // now look for street suffix, either in full or abbreviated form, with optional 's' if there's an asterisk
18138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s->mCurrentStart = chars;
18158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s->mEnd = chars + length;
18168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int candIndex = 0;
181710dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark    bool retryState;
18188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool mustBeAllUpper = false;
18198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool secondHalf = false;
18208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    chars -= 1;
18218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar ch = s->mCurrent;
18228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (++chars <= s->mEnd) {
18238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        UChar prior = ch;
18248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ch = chars < s->mEnd ? *chars : ' ';
18258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        switch (s->mProgress) {
18268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case NO_ADDRESS:
18278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIDigit(ch) == false) {
18288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (ch != 'O') // letter 'O', not zero
18298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
18308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mEnd - chars < 3)
18318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
18328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    prior = *++chars;
18338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ch = *++chars;
18348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if ((prior != 'n' || ch != 'e') && (prior != 'N' || ch != 'E'))
18358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
18368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (isUnicodeSpace(*++chars) == false)
18378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
18388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mProgress = ADDRESS_LINE;
18398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mStartResult = chars - 3 - s->mCurrentStart;
18408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
18418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
18428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (isUnicodeSpace(prior) == false) {
18438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mProgress = SKIP_TO_SPACE;
18448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
18458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
18468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mNumberCount = 1;
18478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mProgress = HOUSE_NUMBER;
18488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mStartResult = chars - s->mCurrentStart;
18498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
18508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case SKIP_TO_SPACE:
18518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (isUnicodeSpace(ch) == false)
18528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
18538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
18548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case HOUSE_NUMBER:
18558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIDigit(ch)) {
18568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (++s->mNumberCount >= 6)
18578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mProgress = SKIP_TO_SPACE;
18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIUpper(ch)) { // allow one letter after house number, e.g. 12A SKOLFIELD PL, HARPSWELL, ME 04079
18618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (WTF::isASCIIDigit(prior) == false)
18628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mProgress = SKIP_TO_SPACE;
18638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
18648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
18658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (ch == '-') {
18668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mNumberCount > 0) { // permit 21-23 ELM ST
18678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        ++s->mNumberCount;
18688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
18698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
18708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
18718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mNumberCount = 0;
18728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mProgress = NUMBER_TRAILING_SPACE;
18738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case NUMBER_TRAILING_SPACE:
18748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (isUnicodeSpace(ch))
18758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
18768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (0 && WTF::isASCIIDigit(ch)) {
18778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mNumberCount = 1;
18788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mProgress = HOUSE_NUMBER;
18798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mStartResult = chars - s->mCurrentStart;
18808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
18818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
18828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIDigit(ch) == false && WTF::isASCIIUpper(ch) == false)
18838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
18848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mProgress = ADDRESS_LINE;
18858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case ADDRESS_LINE:
18868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIAlpha(ch) || ch == '\'' || ch == '-' || ch == '&' || ch == '(' || ch == ')') {
18878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (++s->mLetterCount > 1) {
18888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mNumberWords &= ~(1 << s->mWordCount);
18898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
18908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
18918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mNumberCount >= 5)
18928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
18938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: the test below was added to give up on a non-address, but it
18948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// incorrectly discards addresses where the house number is in one node
18958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// and the street name is in the next; I don't recall what the failing case
18968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// is that suggested this fix.
18978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//                    if (s->mWordCount == 0 && s->mContinuationNode)
18988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//                        return FOUND_NONE;
1899bbab1c84ba835d6d9591ea291ceebe8dcce2d343Cary Clark                    s->newWord(baseChars, chars);
19008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (WTF::isASCIILower(ch) && s->mNumberCount == 0)
19018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mFirstLower = chars;
19028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mNumberCount = 0;
19038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (WTF::isASCIILower(ch) || (WTF::isASCIIAlpha(ch) == false && ch != '-'))
19048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mNumberWords &= ~(1 << s->mWordCount);
19058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mUnparsed = true;
19068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
19078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (s->mLetterCount >= MAX_PLACE_NAME_LENGTH) {
19088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
19098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (s->mFirstLower != NULL) {
19108e9932d793b751bd6a2c1150bf273867f40c5f55Cary Clark                    if (s->mCaseInsensitive)
19118e9932d793b751bd6a2c1150bf273867f40c5f55Cary Clark                        goto resetWord;
19128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    size_t length = chars - s->mFirstLower;
19138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (length > 3)
19148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
19158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (length == 3 && strCharCmp("and" "the", s->mFirstLower, 3, 2) == false)
19168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
19178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (length == 2 && strCharCmp("at" "by" "el" "in" "of", s->mFirstLower, 2, 5) == false)
19188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
19198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    goto resetWord;
19208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
19218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (ch == ',' || ch == '*') { // delimits lines
19228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // asterisk as delimiter: http://www.sa.sc.edu/wellness/members.html
19238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (++s->mLineCount > 5)
19248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
19258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    goto lookForState;
19268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
19278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (isUnicodeSpace(ch) || prior == '-') {
19288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lookForState:
19298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mUnparsed == false)
19308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
19318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    const UChar* candidate = s->mWords[s->mWordCount];
19328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    UChar firstLetter = candidate[0];
19338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (WTF::isASCIIUpper(firstLetter) == false && WTF::isASCIIDigit(firstLetter) == false)
19348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto resetWord;
19358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mWordCount++;
19368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if ((s->mWordCount == 2 && s->mNumberWords == 3 && WTF::isASCIIDigit(s->mWords[1][1])) || // choose second of 8888 333 Main
19378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        (s->mWordCount >= sizeof(s->mWords) / sizeof(s->mWords[0]) - 1)) { // subtract 1 since state names may have two parts
19388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // search for simple number already stored since first potential house # didn't pan out
19398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (s->mNumberWords == 0)
19408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            break;
19418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        int shift = 0;
19428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        while ((s->mNumberWords & (1 << shift)) == 0)
19438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            shift++;
19448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mNumberWords >>= ++shift;
19458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (s->mBases[0] != s->mBases[shift]) // if we're past the original node, bail
19468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            break;
1947bbab1c84ba835d6d9591ea291ceebe8dcce2d343Cary Clark                        s->shiftWords(shift);
19488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mStartResult = s->mWords[0] - s->mStarts[0];
19498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mWordCount -= shift;
19508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // FIXME: need to adjust lineCount to account for discarded delimiters
19518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
19528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mWordCount < 4)
19538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto resetWord;
19548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    firstLetter -= 'A';
19558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (firstLetter > 'W' - 'A')
19568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto resetWord;
19578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    UChar secondLetter = candidate[1];
19588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (prior == '-')
19598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mLetterCount--; // trim trailing dashes, to accept CA-94043
19608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mLetterCount == 2) {
19618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        secondLetter -= 'A';
19628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (secondLetter > 'Z' - 'A')
19638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto resetWord;
19648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if ((stateTwoLetter[firstLetter] & 1 << secondLetter) != 0) {
19658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            // special case to ignore 'et al'
19668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            if (strCharCmp("ET", s->mWords[s->mWordCount - 2], 2, 1) == false) {
19678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                s->mStateWord = s->mWordCount - 1;
19688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                s->mZipHint = firstIndex[firstLetter] +
19698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    bitcount(stateTwoLetter[firstLetter] & ((1 << secondLetter) - 1));
19708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                goto foundStateName;
19718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
19728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
19738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto resetWord;
19748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
19758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mStates = longStateNames[firstLetter];
19768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mStates == NULL)
19778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto resetWord;
19788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    mustBeAllUpper = false;
19798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mProgress = STATE_NAME;
19808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    unsigned char section = s->mStates[0];
19818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ASSERT(section > 0x80);
19828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mSectionLength = section & 0x7f;
19838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    candIndex = 1;
19848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    secondHalf = false;
19858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mStateWord = s->mWordCount - 1;
19868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    goto stateName;
19878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
19888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIDigit(ch)) {
19898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mLetterCount == 0) {
19908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (++s->mNumberCount > 1)
19918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            continue;
19928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (s->mWordCount == 0 && s->mContinuationNode)
19938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            return FOUND_NONE;
1994bbab1c84ba835d6d9591ea291ceebe8dcce2d343Cary Clark                        s->newWord(baseChars, chars);
19958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mNumberWords |= 1 << s->mWordCount;
19968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mUnparsed = true;
19978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
19988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
19998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
20008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (ch == '.') { // optionally can follow letters
20018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mLetterCount == 0)
20028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
20038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mNumberCount > 0)
20048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
20058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
20068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
20078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (ch == '/') // between numbers (1/2) between words (12 Main / Ste 4d)
20088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    goto resetWord;
20098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (ch == '#') // can precede numbers, allow it to appear randomly
20108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    goto resetWord;
20118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (ch == '"') // sometimes parts of addresses are quoted (FIXME: cite an example here)
20128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
20138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
20148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case SECOND_HALF:
20158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIAlpha(ch)) {
20168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mLetterCount == 0) {
2017bbab1c84ba835d6d9591ea291ceebe8dcce2d343Cary Clark                        s->newWord(baseChars, chars);
20188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mWordCount++;
20198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
20208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mLetterCount++;
20218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
20228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
20238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIDigit(ch) == false) {
20248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mLetterCount > 0) {
20258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mProgress = STATE_NAME;
20268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        candIndex = 0;
20278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        secondHalf = true;
20288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto stateName;
20298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
20308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
20318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
20328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mProgress = ADDRESS_LINE;
20338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                goto resetState;
20348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case STATE_NAME:
20358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            stateName:
20368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // pick up length of first section
20378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                do {
20388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int stateIndex = 1;
20398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int skip = 0;
20408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int prefix = 0;
20418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    bool subStr = false;
20428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    do {
20438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        unsigned char match = s->mStates[stateIndex];
20448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (match >= 0x80) {
20458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            if (stateIndex == s->mSectionLength)
20468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                break;
20478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            subStr = true;
20488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                  //          if (skip > 0)
20498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                  //              goto foundStateName;
20508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            prefix = candIndex;
20518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            skip = match & 0x7f;
20528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            match = s->mStates[++stateIndex];
20538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
20548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        UChar candChar = s->mWords[s->mWordCount - 1][candIndex];
20558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (mustBeAllUpper && WTF::isASCIILower(candChar))
20568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto skipToNext;
20578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (match != candChar) {
20588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            if (match != WTF::toASCIILower(candChar)) {
20598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                       skipToNext:
20608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                if (subStr == false)
20618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    break;
20628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                if (stateIndex == s->mSectionLength) {
20638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    if (secondHalf) {
20648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        s->mProgress = ADDRESS_LINE;
20658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        goto resetState;
20668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    }
20678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    break;
20688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                }
20698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                stateIndex += skip;
20708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                skip = 0;
20718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                candIndex = prefix;
20728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                continue; // try next substring
20738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
20748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            mustBeAllUpper = true;
20758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
20768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        int nextindex = stateIndex + 1;
20778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (++candIndex >= s->mLetterCount && s->mStates[nextindex] == ' ') {
20788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            s->mProgress = SECOND_HALF;
20798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            s->mStates += nextindex;
20808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            s->mSectionLength -= nextindex;
20818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto resetWord;
20828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
20838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (nextindex + 1 == s->mSectionLength || skip == 2) {
20848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            s->mZipHint = s->mStates[nextindex] - 1;
20858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto foundStateName;
20868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
20878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        stateIndex += 1;
20888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        skip -= 1;
20898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } while (true);
20908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mStates += s->mSectionLength;
20918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ASSERT(s->mStates[0] == 0 || (unsigned) s->mStates[0] > 0x80);
20928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mSectionLength = s->mStates[0] & 0x7f;
20938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    candIndex = 1;
20948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    subStr = false;
20958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } while (s->mSectionLength != 0);
20968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mProgress = ADDRESS_LINE;
20978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                goto resetState;
20988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            foundStateName:
20998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mEndResult = chars - s->mCurrentStart;
21008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mEndWord = s->mWordCount - 1;
21018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mProgress = ZIP_CODE;
21028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // a couple of delimiters is an indication that the state name is good
21038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // or, a non-space / non-alpha-digit is also good
21043b3752c8d25150e6cf8d31c0fc5d9f8953a5c4f7Cary Clark                s->mZipDelimiter = s->mLineCount > 2
21053b3752c8d25150e6cf8d31c0fc5d9f8953a5c4f7Cary Clark                    || isUnicodeSpace(ch) == false
21063b3752c8d25150e6cf8d31c0fc5d9f8953a5c4f7Cary Clark                    || chars == s->mEnd;
21078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIDigit(ch))
21088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mZipStart = chars;
21098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                goto resetState;
21108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case ZIP_CODE:
21118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIDigit(ch)) {
21128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int count = ++s->mNumberCount;
21138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (count == 1) {
21148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (WTF::isASCIIDigit(prior))
21158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            ++s->mNumberCount;
21168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        else
21178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            s->mZipStart = chars;
21188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
21198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (count <= 9)
21208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
21218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (isUnicodeSpace(ch)) {
21228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mNumberCount == 0) {
21238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mZipDelimiter = true; // two spaces delimit state name
21248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
21258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
21268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (ch == '-') {
21278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mNumberCount == 5 && validZip(s->mZipHint, s->mZipStart)) {
21288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mNumberCount = 0;
21298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mProgress = PLUS_4;
21308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
21318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
21328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mNumberCount == 0)
21338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mZipDelimiter = true;
21348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (WTF::isASCIIAlpha(ch) == false)
21358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mZipDelimiter = true;
213610dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                else {
213710dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                    if (s->mLetterCount == 0) {
2138bbab1c84ba835d6d9591ea291ceebe8dcce2d343Cary Clark                        s->newWord(baseChars, chars);
213910dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                        s->mUnparsed = true;
214010dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                    }
214110dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                    ++s->mLetterCount;
214210dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                }
21438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (s->mNumberCount == 5 || s->mNumberCount == 9) {
21448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (validZip(s->mZipHint, s->mZipStart) == false)
21458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto noZipMatch;
21468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mEndResult = chars - s->mCurrentStart;
21478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mEndWord = s->mWordCount - 1;
21488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (s->mZipDelimiter == false) {
21498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            noZipMatch:
21508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    --chars;
21518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mProgress = ADDRESS_LINE;
21528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
21538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
21548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mProgress = FIND_STREET;
21558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                goto findStreet;
21568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case PLUS_4:
21578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (WTF::isASCIIDigit(ch)) {
21588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (++s->mNumberCount <= 4)
21598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
21608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
21618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (isUnicodeSpace(ch)) {
21628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mNumberCount == 0)
21638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
21648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
21658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (s->mNumberCount == 4) {
21668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (WTF::isASCIIAlpha(ch) == false) {
21678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mEndResult = chars - s->mCurrentStart;
21688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        s->mEndWord = s->mWordCount - 1;
21698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
21708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (s->mNumberCount != 0)
21718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
21728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mProgress = FIND_STREET;
21738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case FIND_STREET:
217410dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark            findStreet:
217510dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                retryState = false;
217610dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                for (int wordsIndex = s->mStateWord - 1; wordsIndex >= 0; --wordsIndex) {
21778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    const UChar* test = s->mWords[wordsIndex];
21788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    UChar letter = test[0];
21798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    letter -= 'A';
21808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (letter > 'X' - 'A')
21818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
21828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    const char* names = longStreetNames[letter];
21838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (names == NULL)
21848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
21858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    int offset;
21868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    while ((offset = *names++) != 0) {
21878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        int testIndex = 1;
21888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        bool abbr = false;
21898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        for (int idx = 0; idx < offset; idx++) {
21908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            char nameLetter = names[idx];
21918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            char testUpper = WTF::toASCIIUpper(test[testIndex]);
21928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            if (nameLetter == '*') {
21938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                if (testUpper == 'S')
21948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    testIndex++;
21958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                break;
21968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
21978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            bool fullOnly = WTF::isASCIILower(nameLetter);
21988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            nameLetter = WTF::toASCIIUpper(nameLetter);
21998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            if (testUpper == nameLetter) {
22008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                if (abbr && fullOnly)
22018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    goto nextTest;
22028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                testIndex++;
22038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                continue;
22048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
22058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            if (fullOnly == false)
22068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                goto nextTest;
22078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            abbr = true;
22088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
2209bbab1c84ba835d6d9591ea291ceebe8dcce2d343Cary Clark                        letter = &test[testIndex] < s->mEnds[wordsIndex] ?
2210bbab1c84ba835d6d9591ea291ceebe8dcce2d343Cary Clark                            test[testIndex] : ' ';
22118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (WTF::isASCIIAlpha(letter) == false && WTF::isASCIIDigit(letter) == false) {
22128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            if (s->mNumberWords != 0) {
22138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                int shift = 0;
22148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                int wordReduction = -1;
22158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                do {
22168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    while ((s->mNumberWords & (1 << shift)) == 0)
22178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        shift++;
22188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    if (shift > wordsIndex)
22198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        break;
22208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    wordReduction = shift;
22218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                } while (s->mNumberWords >> ++shift != 0);
22228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                if (wordReduction >= 0) {
222310dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                                    if (s->mContinuationNode) {
222410dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                                        if (retryState)
222510dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                                            break;
22268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                        return FOUND_NONE;
222710dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                                    }
22288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    s->mStartResult = s->mWords[wordReduction] - s->mStarts[wordReduction];
22298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                }
22308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
223110dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                            if (wordsIndex != s->mStateWord - 1)
223210dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                                return FOUND_COMPLETE;
223310dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                            retryState = true;
22348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
22358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    nextTest:
22368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        names += offset;
22378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
22388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
223910dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                if (retryState) {
224010dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                    s->mProgress = ADDRESS_LINE;
224110dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                    s->mStates = NULL;
224210dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                    continue;
224310dd59ed29ea8ab537279de1bd91fb93dce15ca3Cary Clark                }
22448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (s->mNumberWords != 0) {
22458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    unsigned shift = 0;
22468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    while ((s->mNumberWords & (1 << shift)) == 0)
22478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        shift++;
22488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mNumberWords >>= ++shift;
22498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (s->mBases[0] != s->mBases[shift])
22508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return FOUND_NONE;
2251bbab1c84ba835d6d9591ea291ceebe8dcce2d343Cary Clark                    s->shiftWords(shift);
22528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mStartResult = s->mWords[0] - s->mStarts[0];
22538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mWordCount -= shift;
22548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    s->mProgress = ADDRESS_LINE;
22558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    --chars;
22568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
22578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
22588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
22598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
22608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (s->mContinuationNode)
22618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return FOUND_NONE;
22628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s->mProgress = NO_ADDRESS;
22638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s->mWordCount = s->mLineCount = 0;
22648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s->mNumberWords = 0;
22658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    resetState:
22668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s->mStates = NULL;
22678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    resetWord:
22688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s->mNumberCount = s->mLetterCount = 0;
22698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s->mFirstLower = NULL;
22708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        s->mUnparsed = false;
22718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
22728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s->mCurrent = ch;
22738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return s->mProgress == NO_ADDRESS ? FOUND_NONE : FOUND_PARTIAL;
22748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
22758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Recogize common email patterns only. Currently has lots of state, walks text forwards and backwards -- will be
22778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// a real challenge to adapt to walk text across multiple nodes, I imagine
22788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: it's too hard for the caller to call these incrementally -- it's probably best for this to
22798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// either walk the node tree directly or make a callout to get the next or previous node, if there is one
22808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// walking directly will avoid adding logic in caller to track the multiple partial or full nodes that compose this
22818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// text pattern.
22828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCacheBuilder::FoundState CacheBuilder::FindPartialEMail(const UChar* chars, unsigned length,
22838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FindState* s)
22848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
22858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the following tables were generated by tests/browser/focusNavigation/BrowserDebug.cpp
22868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // hand-edit at your own risk
22878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static const int domainTwoLetter[] = {
22888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x02df797c,  // a followed by: [cdefgilmnoqrstuwxz]
22898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x036e73fb,  // b followed by: [abdefghijmnorstvwyz]
22908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x03b67ded,  // c followed by: [acdfghiklmnorsuvxyz]
22918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x02005610,  // d followed by: [ejkmoz]
22928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x001e00d4,  // e followed by: [ceghrstu]
22938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x00025700,  // f followed by: [ijkmor]
22948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x015fb9fb,  // g followed by: [abdefghilmnpqrstuwy]
22958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x001a3400,  // h followed by: [kmnrtu]
22968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x000f7818,  // i followed by: [delmnoqrst]
22978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x0000d010,  // j followed by: [emop]
22988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x0342b1d0,  // k followed by: [eghimnprwyz]
22998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x013e0507,  // l followed by: [abcikrstuvy]
23008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x03fffccd,  // m followed by: [acdghklmnopqrstuvwxyz]
23018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x0212c975,  // n followed by: [acefgilopruz]
23028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x00001000,  // o followed by: [m]
23038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x014e3cf1,  // p followed by: [aefghklmnrstwy]
23048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x00000001,  // q followed by: [a]
23058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x00504010,  // r followed by: [eouw]
23068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x032a7fdf,  // s followed by: [abcdeghijklmnortvyz]
23078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x026afeec,  // t followed by: [cdfghjklmnoprtvwz]
23088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x03041441,  // u followed by: [agkmsyz]
23098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x00102155,  // v followed by: [aceginu]
23108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x00040020,  // w followed by: [fs]
23118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x00000000,  // x
23128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x00180010,  // y followed by: [etu]
23138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        0x00401001,  // z followed by: [amw]
23148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
23158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static char const* const longDomainNames[] = {
23178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x03" "ero" "\x03" "rpa",  // aero, arpa
23188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x02" "iz",  // biz
23198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x02" "at" "\x02" "om" "\x03" "oop",  // cat, com, coop
23208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // d
23218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x02" "du",  // edu
23228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // f
23238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x02" "ov",  // gov
23248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // h
23258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x03" "nfo" "\x02" "nt",  // info, int
23268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x03" "obs",  // jobs
23278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // k
23288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // l
23298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x02" "il" "\x03" "obi" "\x05" "useum",  // mil, mobi, museum
23308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x03" "ame" "\x02" "et",  // name, net
23318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x02" "rg",  // , org
23328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x02" "ro",  // pro
23338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // q
23348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // r
23358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // s
23368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        "\x05" "ravel",  // travel
23378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // u
23388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // v
23398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // w
23408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // x
23418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // y
23428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL,  // z
23438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
23448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
23458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* start = chars;
23468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* end = chars + length;
23478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (chars < end) {
23488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        UChar ch = *chars++;
23498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ch != '@')
23508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
23518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const UChar* atLocation = chars - 1;
23528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // search for domain
23538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ch = *chars++ | 0x20; // convert uppercase to lower
23548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ch < 'a' || ch > 'z')
23558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
23568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (chars < end) {
23578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ch = *chars++;
23588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (IsDomainChar(ch) == false)
23598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                goto nextAt;
23608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (ch != '.')
23618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
23628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            UChar firstLetter = *chars++ | 0x20; // first letter of the domain
23638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (chars >= end)
23648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return FOUND_NONE; // only one letter; must be at least two
23658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            firstLetter -= 'a';
23668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (firstLetter > 'z' - 'a')
23678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue; // non-letter followed '.'
23688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int secondLetterMask = domainTwoLetter[firstLetter];
23698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ch = *chars | 0x20; // second letter of the domain
23708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ch -= 'a';
23718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (ch >= 'z' - 'a')
23728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
23738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bool secondMatch = (secondLetterMask & 1 << ch) != 0;
23748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const char* wordMatch = longDomainNames[firstLetter];
23758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int wordIndex = 0;
23768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (wordMatch != NULL) {
23778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int len = *wordMatch++;
23788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                char match;
23798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                do {
23808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    match = wordMatch[wordIndex];
23818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (match < 0x20)
23828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto foundDomainStart;
23838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (chars[wordIndex] != match)
23848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
23858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    wordIndex++;
23868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } while (true);
23878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                wordMatch += len;
23888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (*wordMatch == '\0')
23898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
23908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                wordIndex = 0;
23918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
23928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (secondMatch) {
23938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                wordIndex = 1;
23948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        foundDomainStart:
23958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                chars += wordIndex;
23968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (chars < end) {
23978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ch = *chars;
23988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (ch != '.') {
23998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (IsDomainChar(ch))
24008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto nextDot;
24018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else if (chars + 1 < end && IsDomainChar(chars[1]))
24028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto nextDot;
24038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
24048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // found domain. Search backwards from '@' for beginning of email address
24058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mEndResult = chars - start;
24068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                chars = atLocation;
24078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (chars <= start)
24088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    goto nextAt;
24098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ch = *--chars;
24108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (ch == '.')
24118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    goto nextAt; // mailbox can't end in period
24128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                do {
24138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (IsMailboxChar(ch) == false) {
24148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        chars++;
24158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
24168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
24178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (chars == start)
24188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
24198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    ch = *--chars;
24208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } while (true);
24218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                UChar firstChar = *chars;
24228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (firstChar == '.' || firstChar == '@') // mailbox can't start with period or be empty
24238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    goto nextAt;
24248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mStartResult = chars - start;
24258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return FOUND_COMPLETE;
24268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
24278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    nextDot:
24288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ;
24298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
24308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectnextAt:
24318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        chars = atLocation + 1;
24328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
24338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return FOUND_NONE;
24348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
24358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define PHONE_PATTERN "(200) /-.\\ 100 -. 0000" // poor man's regex: parens optional, any one of punct, digit smallest allowed
24378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
24388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCacheBuilder::FoundState CacheBuilder::FindPartialNumber(const UChar* chars, unsigned length,
24398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FindState* s)
24408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
24418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* pattern = s->mPattern;
24428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UChar* store = s->mStorePtr;
24438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* start = chars;
24448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* end = chars + length;
24458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* lastDigit = NULL;
24468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
24478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool initialized = s->mInitialized;
24488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (chars < end) {
24498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (initialized == false) {
24508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mBackTwo = s->mBackOne;
24518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                s->mBackOne = s->mCurrent;
24528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
24538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            UChar ch = s->mCurrent = *chars;
24548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            do {
24558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                char patternChar = *pattern;
24568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                switch (patternChar) {
24578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case '2':
24588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            if (initialized == false) {
24598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                s->mStartResult = chars - start;
24608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                initialized = true;
24618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
24628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case '0':
24638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case '1':
24648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (ch < patternChar || ch > '9')
24658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto resetPattern;
24668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        *store++ = ch;
24678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        pattern++;
24688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        lastDigit = chars;
24698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto nextChar;
24708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case '\0':
24718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (WTF::isASCIIDigit(ch) == false) {
24728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            *store = '\0';
24738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto checkMatch;
24748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
24758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto resetPattern;
24768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case ' ':
24778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (ch == patternChar)
24788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto nextChar;
24798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
24808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case '(':
24818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (ch == patternChar) {
24828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            s->mStartResult = chars - start;
24838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            initialized = true;
24848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            s->mOpenParen = true;
24858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
24868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        goto commonPunctuation;
24878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case ')':
24888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if ((ch == patternChar) ^ s->mOpenParen)
24898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto resetPattern;
24908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    default:
24918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    commonPunctuation:
24928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (ch == patternChar) {
24938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            pattern++;
24948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto nextChar;
24958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
24968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
24978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } while (++pattern); // never false
24988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    nextChar:
24998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            chars++;
25008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
25018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
25028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectresetPattern:
25038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (s->mContinuationNode)
25048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return FOUND_NONE;
25058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        FindResetNumber(s);
25068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pattern = s->mPattern;
25078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        store = s->mStorePtr;
25088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while (++chars < end);
25098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectcheckMatch:
25108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (WTF::isASCIIDigit(s->mBackOne != '1' ? s->mBackOne : s->mBackTwo))
25118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return FOUND_NONE;
25128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *store = '\0';
25138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s->mStorePtr = store;
25148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s->mPattern = pattern;
25158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    s->mEndResult = lastDigit - start + 1;
25168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char pState = pattern[0];
25178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return pState == '\0' ? FOUND_COMPLETE : pState == '(' || (WTF::isASCIIDigit(pState) && WTF::isASCIIDigit(pattern[-1])) ?
25188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        FOUND_NONE : FOUND_PARTIAL;
25198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCacheBuilder::FoundState CacheBuilder::FindPhoneNumber(const UChar* chars, unsigned length,
25228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int* start, int* end)
25238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
25248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FindState state;
25258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FindReset(&state);
25268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FoundState result = FindPartialNumber(chars, length, &state);
25278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *start = state.mStartResult;
25288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *end = state.mEndResult;
25298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
25308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::FindReset(FindState* state)
25338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
25348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memset(state, 0, sizeof(FindState));
25358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    state->mCurrent = ' ';
25368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FindResetNumber(state);
25378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::FindResetNumber(FindState* state)
25408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
25418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    state->mOpenParen = false;
25428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    state->mPattern = (char*) PHONE_PATTERN;
25438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    state->mStorePtr = state->mStore;
25448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2546805e9335952da33d9af0f1ec5c07bc5568feb312Leon ScrogginsIntRect CacheBuilder::getAreaRect(const HTMLAreaElement* area)
25478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2548805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins    Node* node = area->document();
2549805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins    while ((node = node->traverseNextNode()) != NULL) {
2550805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins        RenderObject* renderer = node->renderer();
2551805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins        if (renderer && renderer->isRenderImage()) {
2552805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins            RenderImage* image = static_cast<RenderImage*>(renderer);
2553805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins            HTMLMapElement* map = image->imageMap();
2554805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins            if (map) {
2555805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins                Node* n;
2556805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins                for (n = map->firstChild(); n;
2557805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins                        n = n->traverseNextNode(map)) {
2558805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins                    if (n == area) {
2559805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins                        if (area->isDefault())
2560805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins                            return image->absoluteBoundingBoxRect();
2561022577c9685aff683d1886ad93000e115dd4d686Steve Block                        return area->computeRect(image);
2562805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins                    }
2563805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins                }
2564805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins            }
2565805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins        }
2566805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins    }
2567805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins    return IntRect();
25688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::GetGlobalOffset(Node* node, int* x, int * y)
25718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
25728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GetGlobalOffset(node->document()->frame(), x, y);
25738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CacheBuilder::GetGlobalOffset(Frame* frame, int* x, int* y)
25768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
25778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//    TIMER_PROBE(__FUNCTION__);
25788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(x);
25798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(y);
25808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *x = 0;
25818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *y = 0;
25828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame->view())
25838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
25848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* parent;
25858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while ((parent = frame->tree()->parent()) != NULL) {
25868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const WebCore::IntRect& rect = frame->view()->platformWidget()->getBounds();
25878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *x += rect.x();
25888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *y += rect.y();
25898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        frame = parent;
25908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
25918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project //   TIMER_PROBE_END();
25928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
25938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFrame* CacheBuilder::HasFrame(Node* node)
25958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
25968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* renderer = node->renderer();
25978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer == NULL)
25988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NULL;
25998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer->isWidget() == false)
26008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NULL;
26018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
26028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (widget == NULL)
26038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NULL;
26048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (widget->isFrameView() == false)
26058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NULL;
26068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<FrameView*>(widget)->frame();
26078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::HasOverOrOut(Node* node)
26108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
26118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // eventNames are thread-local data, I avoid using 'static' variable here.
26128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    AtomicString eventTypes[2] = {
26138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().mouseoverEvent,
26148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().mouseoutEvent
26158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    };
26168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return NodeHasEventListeners(node, eventTypes, 2);
26188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::HasTriggerEvent(Node* node)
26218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
26228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    AtomicString eventTypes[5] = {
26238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().clickEvent,
26248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().mousedownEvent,
26258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().mouseupEvent,
26268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().keydownEvent,
26278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        eventNames().keyupEvent
26288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    };
26298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
26308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return NodeHasEventListeners(node, eventTypes, 5);
26318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// #define EMAIL_PATTERN "x@y.d" // where 'x' is letters, numbers, and '-', '.', '_' ; 'y' is 'x' without the underscore, and 'd' is a valid domain
26348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//  - 0x2D . 0x2E 0-9 0x30-39 A-Z 0x41-5A  _ 0x5F a-z 0x61-7A
26358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::IsDomainChar(UChar ch)
26378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
26388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static const unsigned body[] = {0x03ff6000, 0x07fffffe, 0x07fffffe}; // 0-9 . - A-Z a-z
26398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ch -= 0x20;
26408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ch > 'z' - 0x20)
26418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
26428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return (body[ch >> 5] & 1 << (ch & 0x1f)) != 0;
26438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
26448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::isFocusableText(NodeWalk* walk, bool more, Node* node,
26468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CachedNodeType* type, String* exported) const
26478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
26488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Text* textNode = static_cast<Text*>(node);
2649bd6026bd45e3421253a3bcdbaf61a4f7c08476eaSteve Block    StringImpl* string = textNode->dataImpl();
26508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* baseChars = string->characters();
26518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//    const UChar* originalBase = baseChars;
26528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int length = string->length();
26538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int index = 0;
26548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (index < length && isUnicodeSpace(baseChars[index]))
26558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        index++;
26568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (index >= length)
26578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
26588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (more == false) {
26598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        walk->mStart = 0;
26608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        walk->mEnd = 0;
26618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        walk->mFinalNode = node;
26628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        walk->mLastInline = NULL;
26638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
26648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // starting with this node, search forward for email, phone number, and address
26658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // if any of the three is found, track it so that the remaining can be looked for later
26668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FoundState state = FOUND_NONE;
26678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderText* renderer = (RenderText*) node->renderer();
26688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool foundBetter = false;
26698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* baseInline = walk->mLastInline != NULL ? walk->mLastInline :
26708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        renderer->firstTextBox();
26718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (baseInline == NULL)
26728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
26738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int start = walk->mEnd;
26748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* saveInline;
26758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int baseStart, firstStart = start;
26768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    saveInline = baseInline;
26778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    baseStart = start;
26788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (CachedNodeType checkType = ADDRESS_CACHEDNODETYPE;
26798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        checkType <= PHONE_CACHEDNODETYPE;
26801d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark        checkType = static_cast<CachedNodeType>(checkType + 1))
26818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
26821d330120b6c2ee2d3f1c25300d0e3d446ef8c640Cary Clark        if ((1 << (checkType - 1) & mAllowableTypes) == 0)
26838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
26848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        InlineTextBox* inlineTextBox = baseInline;
26858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        FindState findState;
26868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        FindReset(&findState);
26878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        start = baseStart;
26888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (checkType == ADDRESS_CACHEDNODETYPE) {
26898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            findState.mBases[0] = baseChars;
26908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            findState.mWords[0] = baseChars + start;
26918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            findState.mStarts[0] = baseChars + start;
26928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
26938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* lastPartialNode = NULL;
26948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int lastPartialEnd = -1;
26958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool lastPartialMore = false;
26968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool firstPartial = true;
26978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        InlineTextBox* lastPartialInline = NULL;
26988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        do {
26998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            do {
27008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                const UChar* chars = baseChars + start;
27018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                length = inlineTextBox == NULL ? 0 :
27028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    inlineTextBox->end() - start + 1;
27038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                bool wasInitialized = findState.mInitialized;
27048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                switch (checkType) {
27058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case ADDRESS_CACHEDNODETYPE:
27068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        state = FindPartialAddress(baseChars, chars, length, &findState);
27078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
27088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case EMAIL_CACHEDNODETYPE:
27098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        state = FindPartialEMail(chars, length, &findState);
27108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
27118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case PHONE_CACHEDNODETYPE:
27128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        state = FindPartialNumber(chars, length, &findState);
27138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
27148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    default:
27158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        ASSERT(0);
27168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
27178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                findState.mInitialized = state != FOUND_NONE;
27188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (wasInitialized != findState.mInitialized)
27198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    firstStart = start;
27208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (state == FOUND_PARTIAL) {
27218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    lastPartialNode = node;
27228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    lastPartialEnd = findState.mEndResult + start;
27238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    lastPartialMore = firstPartial &&
27248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        lastPartialEnd < (int) string->length();
27258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    firstPartial = false;
27268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    lastPartialInline = inlineTextBox;
27278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    findState.mContinuationNode = true;
27288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (state == FOUND_COMPLETE) {
27298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (foundBetter == false || walk->mStart > findState.mStartResult) {
27308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        walk->mStart = findState.mStartResult + firstStart;
27318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (findState.mEndResult > 0) {
27328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            walk->mFinalNode = node;
27338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            walk->mEnd = findState.mEndResult + start;
27348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            walk->mMore = node == textNode &&
27358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                walk->mEnd < (int) string->length();
27368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            walk->mLastInline = inlineTextBox;
27378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        } else {
27388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            walk->mFinalNode = lastPartialNode;
27398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            walk->mEnd = lastPartialEnd;
27408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            walk->mMore = lastPartialMore;
27418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            walk->mLastInline = lastPartialInline;
27428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
27438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        *type = checkType;
27448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (checkType == PHONE_CACHEDNODETYPE) {
27458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            const UChar* store = findState.mStore;
27468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            *exported = String(store);
27478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        } else {
27488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            Node* temp = textNode;
27498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            length = 1;
27508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            start = walk->mStart;
27518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            exported->truncate(0);
27528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            do {
27538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                Text* tempText = static_cast<Text*>(temp);
2754bd6026bd45e3421253a3bcdbaf61a4f7c08476eaSteve Block                                StringImpl* string = tempText->dataImpl();
27558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                int end = tempText == walk->mFinalNode ?
27568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    walk->mEnd : string->length();
27578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                exported->append(String(string->substring(
27588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    start, end - start)));
27598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                ASSERT(end > start);
27608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                length += end - start + 1;
27618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                if (temp == walk->mFinalNode)
27628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    break;
27638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                start = 0;
27648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                do {
27658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    temp = temp->traverseNextNode();
27668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    ASSERT(temp);
27678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                } while (temp->isTextNode() == false);
27688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                // add a space in between text nodes to avoid
27698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                // words collapsing together
27708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                exported->append(" ");
27718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            } while (true);
27728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
27738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        foundBetter = true;
27748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
27758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    goto tryNextCheckType;
27768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (findState.mContinuationNode)
27778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
27788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (inlineTextBox == NULL)
27798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
27808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                inlineTextBox = inlineTextBox->nextTextBox();
27818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (inlineTextBox == NULL)
27828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
27838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                start = inlineTextBox->start();
27848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (state == FOUND_PARTIAL && node == textNode)
27858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    findState.mContinuationNode = false;
27868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } while (true);
27878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (state == FOUND_NONE)
27888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
27898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // search for next text node, if any
27908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Text* nextNode;
27918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            do {
27928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                do {
27938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    do {
279488c81ae2263ae20fe63c346d9237d285cc12e84bCary Clark                        if (node)
279588c81ae2263ae20fe63c346d9237d285cc12e84bCary Clark                            node = node->traverseNextNode();
2796c0d24cbb37881d1f35f708b3794697dac8374b4dCary Clark                        if (node == NULL || node->hasTagName(HTMLNames::aTag)
2797c0d24cbb37881d1f35f708b3794697dac8374b4dCary Clark                                || node->hasTagName(HTMLNames::inputTag)
2798c0d24cbb37881d1f35f708b3794697dac8374b4dCary Clark                                || node->hasTagName(HTMLNames::textareaTag)) {
27998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            if (state == FOUND_PARTIAL &&
28008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    checkType == ADDRESS_CACHEDNODETYPE &&
28018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    findState.mProgress == ZIP_CODE &&
28028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    findState.mNumberCount == 0) {
28038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                baseChars = NULL;
28048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                inlineTextBox = NULL;
28058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                start = 0;
28068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                findState.mProgress = FIND_STREET;
28078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                goto finalNode;
28088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
28098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            goto tryNextCheckType;
28108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
28118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } while (node->isTextNode() == false);
28128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    nextNode = static_cast<Text*>(node);
28138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    renderer = (RenderText*) nextNode->renderer();
28148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } while (renderer == NULL);
28158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                baseInline = renderer->firstTextBox();
28168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } while (baseInline == NULL);
2817bd6026bd45e3421253a3bcdbaf61a4f7c08476eaSteve Block            string = nextNode->dataImpl();
28188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            baseChars = string->characters();
28198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            inlineTextBox = baseInline;
28208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            start = inlineTextBox->start();
28218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        finalNode:
28228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            findState.mEndResult = 0;
28238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } while (true);
28248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjecttryNextCheckType:
28258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        node = textNode;
28268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        baseInline = saveInline;
2827bd6026bd45e3421253a3bcdbaf61a4f7c08476eaSteve Block        string = textNode->dataImpl();
28288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        baseChars = string->characters();
28298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (foundBetter) {
28318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        CachedNodeType temp = *type;
28328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        switch (temp) {
28338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case ADDRESS_CACHEDNODETYPE: {
28348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                static const char geoString[] = "geo:0,0?q=";
28358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                exported->insert(String(geoString), 0);
28368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                int index = sizeof(geoString) - 1;
28378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                String escapedComma("%2C");
28388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                while ((index = exported->find(',', index)) >= 0)
28398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    exported->replace(index, 1, escapedComma);
28408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } break;
2841c66ad0770a778012c9a4dd154234a4e553f03b96Patrick Scott            case EMAIL_CACHEDNODETYPE: {
2842c66ad0770a778012c9a4dd154234a4e553f03b96Patrick Scott                String encoded = WebCore::encodeWithURLEscapeSequences(*exported);
2843c66ad0770a778012c9a4dd154234a4e553f03b96Patrick Scott                exported->swap(encoded);
284445b64f60af3cbfa8c78388e35e9b669a0c284bdcBen Murdoch                exported->insert(WTF::String("mailto:"), 0);
2845c66ad0770a778012c9a4dd154234a4e553f03b96Patrick Scott                } break;
28468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case PHONE_CACHEDNODETYPE:
284745b64f60af3cbfa8c78388e35e9b669a0c284bdcBen Murdoch                exported->insert(WTF::String("tel:"), 0);
28488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
28498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            default:
28508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
28518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
28528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
28538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
28548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectnoTextMatch:
28558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    walk->reset();
28568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
28578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
28588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::IsMailboxChar(UChar ch)
28608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2861c66ad0770a778012c9a4dd154234a4e553f03b96Patrick Scott    // According to http://en.wikipedia.org/wiki/Email_address
2862c66ad0770a778012c9a4dd154234a4e553f03b96Patrick Scott    // ! # $ % & ' * + - . / 0-9 = ?
2863c66ad0770a778012c9a4dd154234a4e553f03b96Patrick Scott    // A-Z ^ _
2864c66ad0770a778012c9a4dd154234a4e553f03b96Patrick Scott    // ` a-z { | } ~
2865c66ad0770a778012c9a4dd154234a4e553f03b96Patrick Scott    static const unsigned body[] = {0xa3ffecfa, 0xc7fffffe, 0x7fffffff};
28668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ch -= 0x20;
2867c66ad0770a778012c9a4dd154234a4e553f03b96Patrick Scott    if (ch > '~' - 0x20)
28688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
28698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return (body[ch >> 5] & 1 << (ch & 0x1f)) != 0;
28708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
28718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::setData(CachedFrame* cachedFrame)
28738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
28748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = FrameAnd(this);
28758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Document* doc = frame->document();
28768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (doc == NULL)
28778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
28788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* renderer = doc->renderer();
28798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (renderer == NULL)
28808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
28818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderLayer* layer = renderer->enclosingLayer();
28828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (layer == NULL)
28838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
28848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame->view())
28858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
28868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int x, y;
28878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GetGlobalOffset(frame, &x, &y);
28888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    WebCore::IntRect viewBounds = frame->view()->platformWidget()->getBounds();
28898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ((x | y) != 0)
28908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        viewBounds.setLocation(WebCore::IntPoint(x, y));
28918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cachedFrame->setLocalViewBounds(viewBounds);
28920f75d6be298fed21695112a14351eae2ebb6d3bbShimeng (Simon) Wang    cachedFrame->setContentsSize(layer->scrollWidth(), layer->scrollHeight());
28938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (cachedFrame->childCount() == 0)
28948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
28958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CachedFrame* lastCachedFrame = cachedFrame->lastChild();
28968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cachedFrame = cachedFrame->firstChild();
28978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
28988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        CacheBuilder* cacheBuilder = Builder((Frame* )cachedFrame->framePointer());
28998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cacheBuilder->setData(cachedFrame);
29008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while (cachedFrame++ != lastCachedFrame);
29018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
29028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
29038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2904f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark#if USE(ACCELERATED_COMPOSITING)
2905f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clarkvoid CacheBuilder::TrackLayer(WTF::Vector<LayerTracker>& layerTracker,
2906c55376b5c400a21391d42fa36dde78f836f9a2baCary Clark    RenderObject* nodeRenderer, Node* lastChild, int offsetX, int offsetY)
2907f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark{
290882f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    RenderLayer* layer = nodeRenderer->enclosingLayer();
2909f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    RenderLayerBacking* back = layer->backing();
2910f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    if (!back)
2911f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        return;
29121a8ec29fc0211a6b5c53a8cd9ce20be5e630b005Patrick Scott    GraphicsLayer* grLayer = back->graphicsLayer();
29131a8ec29fc0211a6b5c53a8cd9ce20be5e630b005Patrick Scott    if (back->hasContentsLayer())
29141a8ec29fc0211a6b5c53a8cd9ce20be5e630b005Patrick Scott        grLayer = back->foregroundLayer();
2915f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    if (!grLayer)
2916f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        return;
29171a8ec29fc0211a6b5c53a8cd9ce20be5e630b005Patrick Scott    LayerAndroid* aLayer = grLayer->platformLayer();
2918f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    if (!aLayer)
2919f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark        return;
292082f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    IntPoint scroll(layer->scrollXOffset(), layer->scrollYOffset());
292182f247bdbb98dd80c44209d87692c650c3704617Patrick Scott#if ENABLE(ANDROID_OVERFLOW_SCROLL)
292282f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    // If this is an overflow element, track the content layer.
29238b0b15e74bb7f1bd03bfd07f706a5afa637b0b73Patrick Scott    if (layer->hasOverflowScroll() && aLayer->getChild(0))
292482f247bdbb98dd80c44209d87692c650c3704617Patrick Scott        aLayer = aLayer->getChild(0)->getChild(0);
292582f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    if (!aLayer)
292682f247bdbb98dd80c44209d87692c650c3704617Patrick Scott        return;
29271dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott    // Prevent a crash when scrolling a layer that does not have a parent.
29281dd1344ade226cec7f9f85e84744fffdd222d232Patrick Scott    if (layer->stackingContext())
29299bbecbe38e6249c7b1c0874e80503f6162f13613Ben Murdoch        layer->scrollToOffset(0, 0);
293082f247bdbb98dd80c44209d87692c650c3704617Patrick Scott#endif
2931f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    layerTracker.grow(layerTracker.size() + 1);
2932f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    LayerTracker& indexTracker = layerTracker.last();
2933f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark    indexTracker.mLayer = aLayer;
2934726264480d16a18c02f405aff63a32ba06fb0476Patrick Scott    indexTracker.mRenderLayer = layer;
29358598c9fb9f861f25ab14efde9efb19cb91d7df1cPatrick Scott    indexTracker.mBounds = enclosingIntRect(aLayer->bounds());
293682f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    // Use the absolute location of the layer as the bounds location.  This
293782f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    // provides the original offset of nodes in the layer so that we can
293882f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    // translate nodes between their original location and the layer's new
293982f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    // location.
294082f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    indexTracker.mBounds.setLocation(layer->absoluteBoundingBox().location());
2941c55376b5c400a21391d42fa36dde78f836f9a2baCary Clark    indexTracker.mBounds.move(offsetX, offsetY);
294282f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    indexTracker.mScroll = scroll;
294382f247bdbb98dd80c44209d87692c650c3704617Patrick Scott    indexTracker.mLastChild = OneAfter(lastChild);
2944be4ea5d07252747b3faad9dd63d4bebe79f24db3Cary Clark    DBG_NAV_LOGD("layer=%p [%d] bounds=(%d,%d,w=%d,h=%d)", aLayer,
2945be4ea5d07252747b3faad9dd63d4bebe79f24db3Cary Clark        aLayer->uniqueId(), indexTracker.mBounds.x(), indexTracker.mBounds.y(),
2946be4ea5d07252747b3faad9dd63d4bebe79f24db3Cary Clark        indexTracker.mBounds.width(), indexTracker.mBounds.height());
2947f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark}
2948f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark#endif
2949f4cefb9302ee62602c19cdfbdb6cc1fbdf540953Cary Clark
2950805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scrogginsbool CacheBuilder::validNode(Frame* startFrame, void* matchFrame,
2951805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins        void* matchNode)
29528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2953805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins    if (matchFrame == startFrame) {
29548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (matchNode == NULL)
29558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
2956805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins        Node* node = startFrame->document();
29578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (node != NULL) {
29588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node == matchNode) {
29598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                const IntRect& rect = node->hasTagName(HTMLNames::areaTag) ?
29608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    getAreaRect(static_cast<HTMLAreaElement*>(node)) : node->getRect();
29618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Consider nodes with empty rects that are not at the origin
29628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // to be valid, since news.google.com has valid nodes like this
29638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (rect.x() == 0 && rect.y() == 0 && rect.isEmpty())
29648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return false;
29658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
29668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
29678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            node = node->traverseNextNode();
29688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
29698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DBG_NAV_LOGD("frame=%p valid node=%p invalid\n", matchFrame, matchNode);
29708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
29718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2972805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins    Frame* child = startFrame->tree()->firstChild();
29738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (child) {
2974805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins        bool result = validNode(child, matchFrame, matchNode);
29758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (result)
29768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return result;
29778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = child->tree()->nextSibling();
29788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
29798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if DEBUG_NAV_UI
2980805e9335952da33d9af0f1ec5c07bc5568feb312Leon Scroggins    if (startFrame->tree()->parent() == NULL)
29818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DBG_NAV_LOGD("frame=%p node=%p false\n", matchFrame, matchNode);
29828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
29838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
29848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
29858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int Area(const IntRect& rect)
29878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
29888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return rect.width() * rect.height();
29898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
29908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::AddPartRect(IntRect& bounds, int x, int y,
29928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    WTF::Vector<IntRect>* result, IntRect* focusBounds)
29938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
29948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (bounds.isEmpty())
29958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
29968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bounds.move(x, y);
29971ed8c4d16ac986307f1c0589a3a720a37e60f313Steve Block    if (bounds.maxX() <= 0 || bounds.maxY() <= 0)
29988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
29998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect* work = result->begin() - 1;
30008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect* end = result->end();
30018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (++work < end) {
30028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (work->contains(bounds))
30038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
30048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (bounds.contains(*work)) {
30058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            *work = bounds;
30068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            focusBounds->unite(bounds);
30078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
30088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
30098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ((bounds.x() != work->x() || bounds.width() != work->width()) &&
30108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project               (bounds.y() != work->y() || bounds.height() != work->height()))
30118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
30128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect test = *work;
30138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        test.unite(bounds);
30148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (Area(test) > Area(*work) + Area(bounds))
30158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
30168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *work = test;
30178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        focusBounds->unite(bounds);
30188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
30198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
30208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result->size() >= MAXIMUM_FOCUS_RING_COUNT)
30218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
30228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result->append(bounds);
30238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (focusBounds->isEmpty())
30248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *focusBounds = bounds;
30258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
30268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        focusBounds->unite(bounds);
30278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
30288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
30298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::ConstructPartRects(Node* node, const IntRect& bounds,
303199a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark    IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result,
303299a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark    int* imageCountPtr)
30338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
30348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    WTF::Vector<ClipColumnTracker> clipTracker(1);
30358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ClipColumnTracker* baseTracker = clipTracker.data(); // sentinel
30368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bzero(baseTracker, sizeof(ClipColumnTracker));
30378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node->hasChildNodes() && node->hasTagName(HTMLNames::buttonTag) == false
30388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            && node->hasTagName(HTMLNames::selectTag) == false) {
30398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // collect all text rects from first to last child
30408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* test = node->firstChild();
30418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* last = NULL;
30428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* prior = node;
30438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while ((prior = prior->lastChild()) != NULL)
30448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            last = prior;
30458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(last != NULL);
30468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool nodeIsAnchor = node->hasTagName(HTMLNames::aTag);
30478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        do {
30488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            do {
30498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                const ClipColumnTracker* lastClip = &clipTracker.last();
30508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (test != lastClip->mLastChild)
30518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
30528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                clipTracker.removeLast();
30538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } while (true);
30548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderObject* renderer = test->renderer();
30558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (renderer == NULL)
30568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
30578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            EVisibility vis = renderer->style()->visibility();
30588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (vis == HIDDEN)
30598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
3060205a7cfa91854de791995f40278e8c19491f6d99Cary Clark            bool hasClip = renderer->hasOverflowClip();
3061205a7cfa91854de791995f40278e8c19491f6d99Cary Clark            size_t clipIndex = clipTracker.size();
3062205a7cfa91854de791995f40278e8c19491f6d99Cary Clark            IntRect clipBounds = IntRect(0, 0, INT_MAX, INT_MAX);
3063205a7cfa91854de791995f40278e8c19491f6d99Cary Clark            if (hasClip || --clipIndex > 0) {
3064205a7cfa91854de791995f40278e8c19491f6d99Cary Clark                clipBounds = hasClip ? renderer->absoluteBoundingBoxRect() :
3065205a7cfa91854de791995f40278e8c19491f6d99Cary Clark                    clipTracker.at(clipIndex).mBounds; // x, y fixup done by ConstructTextRect
3066205a7cfa91854de791995f40278e8c19491f6d99Cary Clark            }
30678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (test->isTextNode()) {
30688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                RenderText* renderText = (RenderText*) renderer;
30698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                InlineTextBox *textBox = renderText->firstTextBox();
30708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (textBox == NULL)
30718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
30728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (ConstructTextRect((Text*) test, textBox, 0, INT_MAX,
30738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        x, y, focusBounds, clipBounds, result) == false) {
30748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return false;
30758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
30768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
30778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
30788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (test->hasTagName(HTMLNames::imgTag)) {
30798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                IntRect bounds = test->getRect();
3080205a7cfa91854de791995f40278e8c19491f6d99Cary Clark                bounds.intersect(clipBounds);
30818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (AddPartRect(bounds, x, y, result, focusBounds) == false)
30828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return false;
308399a3d689283e80afdfb9e7711900dd9906f4c1f4Cary Clark                *imageCountPtr += 1;
30848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
30858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
30868598c9fb9f861f25ab14efde9efb19cb91d7df1cPatrick Scott            if (hasClip == false) {
30878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (nodeIsAnchor && test->hasTagName(HTMLNames::divTag)) {
30888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    IntRect bounds = renderer->absoluteBoundingBoxRect();  // x, y fixup done by AddPartRect
30891ed8c4d16ac986307f1c0589a3a720a37e60f313Steve Block                    RenderBox* renderBox = static_cast<RenderBox*>(renderer);
30901ed8c4d16ac986307f1c0589a3a720a37e60f313Steve Block                    int left = bounds.x() + renderBox->paddingLeft() + renderBox->borderLeft();
30911ed8c4d16ac986307f1c0589a3a720a37e60f313Steve Block                    int top = bounds.y() + renderBox->paddingTop() + renderBox->borderTop();
30921ed8c4d16ac986307f1c0589a3a720a37e60f313Steve Block                    int right = bounds.maxX() - renderBox->paddingRight() - renderBox->borderRight();
30931ed8c4d16ac986307f1c0589a3a720a37e60f313Steve Block                    int bottom = bounds.maxY() - renderBox->paddingBottom() - renderBox->borderBottom();
30948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (left >= right || top >= bottom)
30958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        continue;
30968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    bounds = IntRect(left, top, right - left, bottom - top);
30978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (AddPartRect(bounds, x, y, result, focusBounds) == false)
30988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return false;
30998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
31008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
31018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
31028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Node* lastChild = test->lastChild();
31038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (lastChild == NULL)
31048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
31058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clipTracker.grow(clipTracker.size() + 1);
31068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ClipColumnTracker& clip = clipTracker.last();
31078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clip.mBounds = renderer->absoluteBoundingBoxRect(); // x, y fixup done by ConstructTextRect
31088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clip.mLastChild = OneAfter(lastChild);
31098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            clip.mNode = test;
31108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } while (test != last && (test = test->traverseNextNode()) != NULL);
31118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
31128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result->size() == 0 || focusBounds->width() < MINIMUM_FOCUSABLE_WIDTH
31138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            || focusBounds->height() < MINIMUM_FOCUSABLE_HEIGHT) {
31148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (bounds.width() < MINIMUM_FOCUSABLE_WIDTH)
31158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
31168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (bounds.height() < MINIMUM_FOCUSABLE_HEIGHT)
31178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
31188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result->append(bounds);
31198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *focusBounds = bounds;
31208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
31218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
31228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline bool isNotSpace(UChar c)
31258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return c <= 0xA0 ? isUnicodeSpace(c) == false :
31278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        WTF::Unicode::direction(c) != WTF::Unicode::WhiteSpaceNeutral;
31288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::ConstructTextRect(Text* textNode,
31318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    InlineTextBox* textBox, int start, int relEnd, int x, int y,
31328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect* focusBounds, const IntRect& clipBounds, WTF::Vector<IntRect>* result)
31338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderText* renderText = (RenderText*) textNode->renderer();
31358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    EVisibility vis = renderText->style()->visibility();
3136bd6026bd45e3421253a3bcdbaf61a4f7c08476eaSteve Block    StringImpl* string = textNode->dataImpl();
31378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const UChar* chars = string->characters();
3138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    FloatPoint pt = renderText->localToAbsolute();
31398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
31408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int textBoxStart = textBox->start();
31418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int textBoxEnd = textBoxStart + textBox->len();
31428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (textBoxEnd <= start)
31438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
31448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (textBoxEnd > relEnd)
31458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            textBoxEnd = relEnd;
3146635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        IntRect bounds = textBox->selectionRect((int) pt.x(), (int) pt.y(),
31478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            start, textBoxEnd);
31488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bounds.intersect(clipBounds);
31498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (bounds.isEmpty())
31508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
31518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool drawable = false;
31528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int index = start; index < textBoxEnd; index++)
31538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if ((drawable |= isNotSpace(chars[index])) != false)
31548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
31558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (drawable && vis != HIDDEN) {
31568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (AddPartRect(bounds, x, y, result, focusBounds) == false)
31578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
31588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
31598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (textBoxEnd == relEnd)
31608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
31618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while ((textBox = textBox->nextTextBox()) != NULL);
31628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
31638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CacheBuilder::ConstructTextRects(Text* node, int start,
31668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Text* last, int end, int x, int y, IntRect* focusBounds,
31678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const IntRect& clipBounds, WTF::Vector<IntRect>* result)
31688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
31698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result->clear();
31708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *focusBounds = IntRect(0, 0, 0, 0);
31718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
31728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderText* renderText = (RenderText*) node->renderer();
31738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int relEnd = node == last ? end : renderText->textLength();
31748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        InlineTextBox *textBox = renderText->firstTextBox();
31758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (textBox != NULL) {
31768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            do {
31778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if ((int) textBox->end() >= start)
31788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
31798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } while ((textBox = textBox->nextTextBox()) != NULL);
31806a43648b5e4b2aabf05b77e03601b8c7b70c0db8Cary Clark            if (textBox && ConstructTextRect(node, textBox, start, relEnd,
31818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    x, y, focusBounds, clipBounds, result) == false)
31828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
31838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
31848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        start = 0;
31858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        do {
31868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (node == last)
31878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
31888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            node = (Text*) node->traverseNextNode();
31898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(node != NULL);
31908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } while (node->isTextNode() == false || node->renderer() == NULL);
31918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while (true);
31928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
31938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3195