Commit message: None
CVE: CVE-2013-2908
Vulnerability description: Google Chrome before 30.0.1599.66 uses incorrect function calls to determine the values of NavigationEntry objects, which allows remote attackers to spoof the address bar via vectors involving a response with a 204 (aka No Content) status code.

Project: Chrome

ScriptController::ScriptController(Frame* frame)
    : m_frame(frame)
    , m_sourceURL(0)
    , m_isolate(v8::Isolate::GetCurrent())
    , m_windowShell(V8WindowShell::create(frame, mainThreadNormalWorld(), m_isolate))
    , m_paused(false)
    , m_windowScriptNPObject(0)
{
}

Project: Chrome

v8::Local<v8::Value> ScriptController::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
{
    RefPtr<Frame> protect(m_frame);
    return ScriptController::callFunctionWithInstrumentation(m_frame ? m_frame->document() : 0, function, receiver, argc, args);
}

Project: Chrome

v8::Local<v8::Value> ScriptController::callFunctionWithInstrumentation(ScriptExecutionContext* context, v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
{
    InspectorInstrumentationCookie cookie;
    if (InspectorInstrumentation::timelineAgentEnabled(context)) {
        String resourceName;
        int lineNumber;
        resourceInfo(function, resourceName, lineNumber);
        cookie = InspectorInstrumentation::willCallFunction(context, resourceName, lineNumber);
    }

    v8::Local<v8::Value> result = V8ScriptRunner::callFunction(function, context, receiver, argc, args);

    InspectorInstrumentation::didCallFunction(cookie);
    return result;
}

Project: Chrome

bool ScriptController::canExecuteScripts(ReasonForCallingCanExecuteScripts reason)
{
    if (m_frame->document() && m_frame->document()->isSandboxed(SandboxScripts)) {
        if (reason == AboutToExecuteScript)
            m_frame->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked script execution in '" + m_frame->document()->url().elidedString() + "' because the document's frame is sandboxed and the 'allow-scripts' permission is not set.");
        return false;
    }

    if (m_frame->document() && m_frame->document()->isViewSource()) {
        ASSERT(m_frame->document()->securityOrigin()->isUnique());
        return true;
    }

    Settings* settings = m_frame->settings();
    const bool allowed = m_frame->loader()->client()->allowScript(settings && settings->isScriptEnabled());
    if (!allowed && reason == AboutToExecuteScript)
        m_frame->loader()->client()->didNotAllowScript();
    return allowed;
}

Project: Chrome

void ScriptController::cleanupScriptObjectsForPlugin(Widget* nativeHandle)
{
    PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle);
    if (it == m_pluginObjects.end())
        return;
    _NPN_UnregisterObject(it->value);
    _NPN_ReleaseObject(it->value);
    m_pluginObjects.remove(it);
}

Project: Chrome

void ScriptController::clearForClose(bool destroyGlobal)
{
    m_windowShell->clearForClose(destroyGlobal);
    for (IsolatedWorldMap::iterator iter = m_isolatedWorlds.begin(); iter != m_isolatedWorlds.end(); ++iter)
        iter->value->clearForClose(destroyGlobal);
    V8GCController::hintForCollectGarbage();
}

Project: Chrome

void ScriptController::clearForClose()
{
    double start = currentTime();
    clearForClose(false);
    HistogramSupport::histogramCustomCounts("WebCore.ScriptController.clearForClose", (currentTime() - start) * 1000, 0, 10000, 50);
}

Project: Chrome

void ScriptController::clearForOutOfMemory()
{
    clearForClose(true);
}

Project: Chrome

void ScriptController::clearScriptObjects()
{
    PluginObjectMap::iterator it = m_pluginObjects.begin();
    for (; it != m_pluginObjects.end(); ++it) {
        _NPN_UnregisterObject(it->value);
        _NPN_ReleaseObject(it->value);
    }
    m_pluginObjects.clear();

    if (m_windowScriptNPObject) {
        disposeUnderlyingV8Object(m_windowScriptNPObject);
        _NPN_ReleaseObject(m_windowScriptNPObject);
        m_windowScriptNPObject = 0;
    }
}

Project: Chrome

void ScriptController::collectIsolatedContexts(Vector<std::pair<ScriptState*, SecurityOrigin*> >& result)
{
    v8::HandleScope handleScope;
    for (IsolatedWorldMap::iterator it = m_isolatedWorlds.begin(); it != m_isolatedWorlds.end(); ++it) {
        V8WindowShell* isolatedWorldShell = it->value.get();
        SecurityOrigin* origin = isolatedWorldShell->world()->isolatedWorldSecurityOrigin();
        if (!origin)
            continue;
        v8::Local<v8::Context> v8Context = isolatedWorldShell->context();
        if (v8Context.IsEmpty())
            continue;
        ScriptState* scriptState = ScriptState::forContext(v8Context);
        result.append(std::pair<ScriptState*, SecurityOrigin*>(scriptState, origin));
    }
}

Project: Chrome

v8::Local<v8::Value> ScriptController::compileAndRunScript(const ScriptSourceCode& source, AccessControlStatus corsStatus)
{
    ASSERT(v8::Context::InContext());

    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(m_frame, source.url().isNull() ? String() : source.url().string(), source.startLine());

    v8::Local<v8::Value> result;
    {
        v8::TryCatch tryCatch;
        tryCatch.SetVerbose(true);

        v8::Handle<v8::String> code = v8String(source.source(), m_isolate);
        OwnPtr<v8::ScriptData> scriptData = V8ScriptRunner::precompileScript(code, source.cachedScript());

        v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(code, source.url(), source.startPosition(), scriptData.get(), m_isolate, corsStatus);

        RefPtr<Frame> protect(m_frame);
        result = V8ScriptRunner::runCompiledScript(script, m_frame->document());
        ASSERT(!tryCatch.HasCaught() || result.IsEmpty());
    }

    InspectorInstrumentation::didEvaluateScript(cookie);

    return result;
}

Project: Chrome

int ScriptController::contextDebugId(v8::Handle<v8::Context> context)
{
    return V8PerContextDebugData::contextDebugId(context);
}

Project: Chrome

static inline v8::Local<v8::Context> contextForWorld(ScriptController* scriptController, DOMWrapperWorld* world)
{
    return scriptController->windowShell(world)->context();
}

Project: Chrome

PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget)
{
    ASSERT(widget);

    if (!widget->isPluginView())
        return 0;

    NPObject* npObject = toPluginView(widget)->scriptableObject();
    if (!npObject)
        return 0;


    v8::Local<v8::Object> wrapper = createV8ObjectForNPObject(npObject, 0);

    m_pluginObjects.set(widget, npObject);

    return V8ScriptInstance::create(wrapper);
}

Project: Chrome

static NPObject* createScriptObject(Frame* frame)
{
    v8::HandleScope handleScope;
    v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(frame);
    if (v8Context.IsEmpty())
        return createNoScriptObject();

    v8::Context::Scope scope(v8Context);
    DOMWindow* window = frame->domWindow();
    v8::Handle<v8::Value> global = toV8(window, v8::Handle<v8::Object>(), v8Context->GetIsolate());
    ASSERT(global->IsObject());

    return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(global), window);
}

Project: Chrome

NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin)
{
    if (!canExecuteScripts(NotAboutToExecuteScript))
        return createNoScriptObject();

    v8::HandleScope handleScope;
    v8::Handle<v8::Context> v8Context = ScriptController::mainWorldContext(m_frame);
    if (v8Context.IsEmpty())
        return createNoScriptObject();
    v8::Context::Scope scope(v8Context);

    DOMWindow* window = m_frame->domWindow();
    v8::Handle<v8::Value> v8plugin = toV8(plugin, v8::Handle<v8::Object>(), v8Context->GetIsolate());
    if (!v8plugin->IsObject())
        return createNoScriptObject();

    return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(v8plugin), window);
}

Project: Chrome

v8::Local<v8::Context> ScriptController::currentWorldContext()
{
    if (!v8::Context::InContext())
        return contextForWorld(this, mainThreadNormalWorld());

    v8::Handle<v8::Context> context = v8::Context::GetEntered();
    DOMWrapperWorld* isolatedWorld = DOMWrapperWorld::isolatedWorld(context);
    if (!isolatedWorld)
        return contextForWorld(this, mainThreadNormalWorld());

    Frame* frame = toFrameIfNotDetached(context);
    if (!m_frame)
        return v8::Local<v8::Context>();

    if (m_frame == frame)
        return v8::Local<v8::Context>::New(context);

    return contextForWorld(this, isolatedWorld);
}

Project: Chrome

void ScriptController::disableEval(const String& errorMessage)
{
    if (!m_windowShell->isContextInitialized())
        return;
    v8::HandleScope handleScope(m_isolate);
    v8::Local<v8::Context> v8Context = m_windowShell->context();
    v8Context->AllowCodeGenerationFromStrings(false);
    v8Context->SetErrorMessageForCodeGenerationFromStrings(v8String(errorMessage, m_isolate));
}

Project: Chrome

void ScriptController::enableEval()
{
    if (!m_windowShell->isContextInitialized())
        return;
    v8::HandleScope handleScope(m_isolate);
    m_windowShell->context()->AllowCodeGenerationFromStrings(true);
}

Project: Chrome

ScriptValue ScriptController::executeScript(const String& script, bool forceUserGesture)
{
    UserGestureIndicator gestureIndicator(forceUserGesture ? DefinitelyProcessingNewUserGesture : PossiblyProcessingUserGesture);
    return executeScript(ScriptSourceCode(script, m_frame->document()->url()));
}

Project: Chrome

ScriptValue ScriptController::executeScript(const ScriptSourceCode& sourceCode)
{
    if (!canExecuteScripts(AboutToExecuteScript) || isPaused())
        return ScriptValue();

    RefPtr<Frame> protect(m_frame); // Script execution can destroy the frame, and thus the ScriptController.

    return executeScriptInMainWorld(sourceCode);
}

Project: Chrome

V8WindowShell* ScriptController::existingWindowShell(DOMWrapperWorld* world)
{
    ASSERT(world);

    if (world->isMainWorld())
        return m_windowShell->isContextInitialized() ? m_windowShell.get() : 0;

    if (world == existingWindowShellWorkaroundWorld())
        return m_windowShell.get();

    IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(world->worldId());
    if (iter == m_isolatedWorlds.end())
        return 0;
    return iter->value->isContextInitialized() ? iter->value.get() : 0;
}

Project: Chrome

v8::Local<v8::Context> ScriptController::mainWorldContext(Frame* frame)
{
    if (!frame)
        return v8::Local<v8::Context>();

    return contextForWorld(frame->script(), mainThreadNormalWorld());
}

Project: Chrome

void ScriptController::namedItemAdded(HTMLDocument* doc, const AtomicString& name)
{
    windowShell(mainThreadNormalWorld())->namedItemAdded(doc, name);
}

Project: Chrome

void ScriptController::namedItemRemoved(HTMLDocument* doc, const AtomicString& name)
{
    windowShell(mainThreadNormalWorld())->namedItemRemoved(doc, name);
}

Project: Chrome

void ScriptController::registerExtensionIfNeeded(v8::Extension* extension)
{
    const V8Extensions& extensions = registeredExtensions();
    for (size_t i = 0; i < extensions.size(); ++i) {
        if (extensions[i] == extension)
            return;
    }
    v8::RegisterExtension(extension);
    registeredExtensions().append(extension);
}

Project: Chrome

V8Extensions& ScriptController::registeredExtensions()
{
    DEFINE_STATIC_LOCAL(V8Extensions, extensions, ());
    return extensions;
}

Project: Chrome

static void resourceInfo(const v8::Handle<v8::Function> function, String& resourceName, int& lineNumber)
{
    v8::ScriptOrigin origin = function->GetScriptOrigin();
    if (origin.ResourceName().IsEmpty()) {
        resourceName = "undefined";
        lineNumber = 1;
    } else {
        resourceName = toWebCoreString(origin.ResourceName());
        lineNumber = function->GetScriptLineNumber() + 1;
    }
}

Project: Chrome

static String resourceString(const v8::Handle<v8::Function> function)
{
    String resourceName;
    int lineNumber;
    resourceInfo(function, resourceName, lineNumber);

    StringBuilder builder;
    builder.append(resourceName);
    builder.append(':');
    builder.appendNumber(lineNumber);
    return builder.toString();
}

Project: Chrome

bool ScriptController::setContextDebugId(int debugId)
{
    ASSERT(debugId > 0);
    if (!m_windowShell->isContextInitialized())
        return false;
    v8::HandleScope scope;
    v8::Local<v8::Context> context = m_windowShell->context();
    return V8PerContextDebugData::setContextDebugData(context, "page", debugId);
}

Project: Chrome

bool ScriptController::shouldBypassMainWorldContentSecurityPolicy()
{
    if (DOMWrapperWorld* world = isolatedWorldForEnteredContext())
        return world->isolatedWorldHasContentSecurityPolicy();
    return false;
}

Project: Chrome

void ScriptController::updateDocument()
{
    if ((!m_windowShell->isContextInitialized() || !m_windowShell->isGlobalInitialized()) && m_frame->loader()->stateMachine()->creatingInitialEmptyDocument())
        return;

    if (!initializeMainWorld())
        windowShell(mainThreadNormalWorld())->updateDocument();
}

Project: Chrome

void ScriptController::updateSecurityOrigin()
{
    m_windowShell->updateSecurityOrigin();
}

Project: Chrome

NPObject* ScriptController::windowScriptNPObject()
{
    if (m_windowScriptNPObject)
        return m_windowScriptNPObject;

    if (canExecuteScripts(NotAboutToExecuteScript)) {
        m_windowScriptNPObject = createScriptObject(m_frame);
        _NPN_RegisterObject(m_windowScriptNPObject, 0);
    } else {
        m_windowScriptNPObject = createNoScriptObject();
    }
    return m_windowScriptNPObject;
}

Project: Chrome

V8WindowShell* ScriptController::windowShell(DOMWrapperWorld* world)
{
    ASSERT(world);

    V8WindowShell* shell = 0;
    if (world->isMainWorld())
        shell = m_windowShell.get();
    else {
        IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(world->worldId());
        if (iter != m_isolatedWorlds.end())
            shell = iter->value.get();
        else {
            OwnPtr<V8WindowShell> isolatedWorldShell = V8WindowShell::create(m_frame, world, m_isolate);
            shell = isolatedWorldShell.get();
            m_isolatedWorlds.set(world->worldId(), isolatedWorldShell.release());
        }
    }
    if (!shell->isContextInitialized() && shell->initializeIfNeeded()) {
        if (world->isMainWorld()) {
            m_frame->loader()->dispatchDidClearWindowObjectInWorld(existingWindowShellWorkaroundWorld());
        } else
            m_frame->loader()->dispatchDidClearWindowObjectInWorld(world);
    }
    return shell;
}

Project: Chrome

ScriptController::~ScriptController()
{
    clearForClose(true);
}

Project: Chrome

    FindUpdateWebFrameClient()
        : m_findResultsAreReady(false)
        , m_count(-1)
    {
    }

Project: Chrome

        Notification(WebFrame* frame, v8::Handle<v8::Context> context, int worldId)
            : frame(frame)
            , context(context->GetIsolate(), context)
            , worldId(worldId)
        {
        }

Project: Chrome

    explicit SpellCheckClient(uint32_t hash = 0) : m_numberOfTimesChecked(0), m_hash(hash) { }

Project: Chrome

    StubbornSpellCheckClient() : m_completion(0) { }

Project: Chrome

    virtual void TearDown()
    {
        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
    }

Project: Chrome

    TestAccessInitialDocumentWebFrameClient() : m_didAccessInitialDocument(false)
    {
    }

Project: Chrome

    TestDidCreateFrameWebFrameClient() : m_frameCount(0), m_parent(0)
    {
    }

Project: Chrome

     TestMainFrameUserOrProgrammaticScrollFrameClient() { reset(); }

Project: Chrome

    TestSameDocumentWebFrameClient()
        : m_frameLoadTypeSameSeen(false)
    {
    }

Project: Chrome

    TestStartStopCallbackWebViewClient()
        : m_startLoadingCount(0)
        , m_stopLoadingCount(0)
    {
    }

Project: Chrome

    TestSubstituteDataWebFrameClient()
        : m_commitCalled(false)
    {
    }

Project: Chrome

    TestWillInsertBodyWebFrameClient() : m_numBodies(0), m_didLoad(false)
    {
    }

Project: Chrome

    WebFrameTest()
        : m_baseURL("http://www.test.com/")
        , m_chromeURL("chrome://")
        , m_webView(0)
    {
    }

Project: Chrome

static WebPoint bottomRightMinusOne(const WebRect& rect)
{
    return WebPoint(rect.x + rect.width - 1, rect.y + rect.height - 1);
}

Project: Chrome

static int computeOffset(WebCore::RenderObject* renderer, int x, int y)
{
    return WebCore::VisiblePosition(renderer->positionForPoint(WebCore::LayoutPoint(x, y))).deepEquivalent().computeOffsetInContainerNode();
}

Project: Chrome

    static WebCore::FloatSize computeRelativeOffset(const WebCore::IntPoint& absoluteOffset, const WebCore::LayoutRect& rect)
    {
        WebCore::FloatSize relativeOffset = WebCore::FloatPoint(absoluteOffset) - rect.location();
        relativeOffset.scale(1.f / rect.width(), 1.f / rect.height());
        return relativeOffset;
    }

Project: Chrome

    int count() const { return m_count; }

Project: Chrome

    void createCompositingWebView()
    {
        m_fakeCompositingWebViewClient = adoptPtr(new FakeCompositingWebViewClient());
        m_webView = WebView::create(m_fakeCompositingWebViewClient.get());
        m_webView->settings()->setJavaScriptEnabled(true);
        m_webView->settings()->setForceCompositingMode(true);
        m_webView->settings()->setAcceleratedCompositingEnabled(true);
        m_webView->settings()->setAcceleratedCompositingForFixedPositionEnabled(true);
        m_webView->settings()->setAcceleratedCompositingForOverflowScrollEnabled(true);
        m_webView->settings()->setAcceleratedCompositingForScrollableFramesEnabled(true);
        m_webView->settings()->setCompositedScrollingForFramesEnabled(true);
        m_webView->settings()->setFixedPositionCreatesStackingContext(true);
        m_webView->initializeMainFrame(&m_fakeCompositingWebViewClient->m_fakeWebFrameClient);
    }

Project: Chrome

static WebView* createWebViewForTextSelection(const std::string& url)
{
    WebView* webView = FrameTestHelpers::createWebViewAndLoad(url, true);
    webView->settings()->setDefaultFontSize(12);
    webView->enableFixedLayoutMode(false);
    webView->resize(WebSize(640, 480));
    return webView;
}

Project: Chrome

    virtual WebNavigationPolicy decidePolicyForNavigation(
        WebFrame*, const WebURLRequest&, WebNavigationType,
        WebNavigationPolicy defaultPolicy, bool isRedirect)
    {
        EXPECT_FALSE(isRedirect);
        return WebNavigationPolicyCurrentTab;
    }

Project: Chrome

    virtual void didAccessInitialDocument(WebFrame* frame)
    {
        EXPECT_TRUE(!m_didAccessInitialDocument);
        m_didAccessInitialDocument = true;
    }

Project: Chrome

    virtual void didCommitProvisionalLoad(WebFrame* frame, bool)
    {
        if (frame->dataSource()->response().url() != WebURL(URLTestHelpers::toKURL("about:blank")))
            m_commitCalled = true;
    }

Project: Chrome

    virtual void didCreateFrame(WebFrame* parent, WebFrame* child)
    {
        m_frameCount++;
        if (!m_parent)
            m_parent = parent;
    }

Project: Chrome

    virtual void didFailProvisionalLoad(WebFrame* frame, const WebURLError& error)
    {
        frame->loadHTMLString("This should appear", toKURL("data:text/html,chromewebdata"), error.unreachableURL, true);
        runPendingTasks();
    }

Project: Chrome

    virtual void didNavigateWithinPage(WebFrame*, bool)
    {
        EXPECT_TRUE(false);
    }

Project: Chrome

    virtual void didStartLoading()
    {
        m_startLoadingCount++;
    }

Project: Chrome

    virtual void didStopLoading()
    {
        m_stopLoadingCount++;
    }

Project: Chrome

static WebRect elementBounds(WebFrame* frame, const WebString& id)
{
    return frame->document().getElementById(id).boundsInViewportSpace();
}

Project: Chrome

static WebGestureEvent fatTap(int x, int y)
{
    WebGestureEvent event;
    event.type = WebInputEvent::GestureTap;
    event.x = x;
    event.y = y;
    event.data.tap.width = 50;
    event.data.tap.height = 50;
    return event;
}

Project: Chrome

    bool findResultsAreReady() const { return m_findResultsAreReady; }

Project: Chrome

    void kick()
    {
        if (!m_completion)
            return;
        Vector<WebTextCheckingResult> results;
        const int misspellingStartOffset = 1;
        const int misspellingLength = 8;
        results.append(WebTextCheckingResult(WebTextCheckingTypeSpelling, misspellingStartOffset, misspellingLength));
        m_completion->didFinishCheckingText(results);
        m_completion = 0;
    }

Project: Chrome

    int numberOfTimesChecked() const { return m_numberOfTimesChecked; }

Project: Chrome

    void registerMockedChromeURLLoad(const std::string& fileName)
    {
        URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_chromeURL.c_str()), WebString::fromUTF8(fileName.c_str()));
    }

Project: Chrome

    void reset()
    {
        for (size_t i = 0; i < createNotifications.size(); ++i)
            delete createNotifications[i];

        for (size_t i = 0; i < releaseNotifications.size(); ++i)
            delete releaseNotifications[i];

        createNotifications.clear();
        releaseNotifications.clear();
    }

Project: Chrome

    void reset()
    {
        m_didScrollMainFrame = false;
        m_wasProgrammaticScroll = false;
    }

Project: Chrome

    void resetTriggered() { m_triggered = false; }

Project: Chrome

static std::string selectionAsString(WebFrame* frame)
{
    return std::string(frame->selectionAsText().utf8().data());
}

Project: Chrome

void setScaleAndScrollAndLayout(WebKit::WebView* webView, WebPoint scroll, float scale)
{
    webView->setPageScaleFactor(scale, WebPoint(scroll.x, scroll.y));
    webView->layout();
}

Project: Chrome

void simulateDoubleTap(WebViewImpl* webViewImpl, WebPoint& point, float& scale)
{
    webViewImpl->animateDoubleTapZoom(point);
    EXPECT_TRUE(webViewImpl->fakeDoubleTapAnimationPendingForTesting());
    simulatePageScale(webViewImpl, scale);
}

Project: Chrome

void simulateMultiTargetZoom(WebViewImpl* webViewImpl, const WebRect& rect, float& scale)
{
    if (webViewImpl->zoomToMultipleTargetsRect(rect))
        simulatePageScale(webViewImpl, scale);
}

Project: Chrome

    int startLoadingCount() const { return m_startLoadingCount; }

Project: Chrome

    int stopLoadingCount() const { return m_stopLoadingCount; }

Project: Chrome

    void testResizeYieldsCorrectScrollAndScale(const char* url,
                                               const float initialPageScaleFactor,
                                               const WebSize scrollOffset,
                                               const WebSize viewportSize,
                                               const bool shouldScaleRelativeToViewportWidth) {
        registerMockedHttpURLLoad(url);

        const float aspectRatio = static_cast<float>(viewportSize.width) / viewportSize.height;

        m_webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + url, true);
        m_webView->settings()->setViewportEnabled(true);
        m_webView->enableFixedLayoutMode(true);
        WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(m_webView);

        {
            webViewImpl->resize(WebSize(viewportSize.width, viewportSize.height));
            m_webView->setPageScaleFactor(initialPageScaleFactor, WebPoint());
            webViewImpl->resize(WebSize(viewportSize.height, viewportSize.width));
            float expectedPageScaleFactor = initialPageScaleFactor * (shouldScaleRelativeToViewportWidth ? 1 / aspectRatio : 1);
            EXPECT_NEAR(expectedPageScaleFactor, webViewImpl->pageScaleFactor(), 0.05f);
            EXPECT_EQ(WebSize(), webViewImpl->mainFrame()->scrollOffset());
        }

        {
            webViewImpl->resize(WebSize(viewportSize.width, viewportSize.height));
            m_webView->setPageScaleFactor(initialPageScaleFactor, WebPoint());
            webViewImpl->mainFrame()->setScrollOffset(WebSize(0, 10));
            webViewImpl->resize(WebSize(viewportSize.width, viewportSize.height * 1.25f));
            EXPECT_EQ(initialPageScaleFactor, webViewImpl->pageScaleFactor());
            webViewImpl->resize(WebSize(viewportSize.width, viewportSize.height * .8f));
            EXPECT_EQ(initialPageScaleFactor, webViewImpl->pageScaleFactor());
        }

        {
            webViewImpl->resize(WebSize(viewportSize.height, viewportSize.width));
            float pageScaleFactor = webViewImpl->pageScaleFactor();
            webViewImpl->resize(WebSize(viewportSize.width, viewportSize.height));
            float expectedPageScaleFactor = pageScaleFactor * (shouldScaleRelativeToViewportWidth ? aspectRatio : 1);
            EXPECT_NEAR(expectedPageScaleFactor, webViewImpl->pageScaleFactor(), 0.05f);
            webViewImpl->mainFrame()->setScrollOffset(scrollOffset);

            WebCore::IntPoint anchorPoint = WebCore::IntPoint(scrollOffset) + WebCore::IntPoint(viewportSize.width / 2, 0);
            RefPtr<WebCore::Node> anchorNode = webViewImpl->mainFrameImpl()->frame()->eventHandler()->hitTestResultAtPoint(anchorPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent).innerNode();
            ASSERT(anchorNode);

            pageScaleFactor = webViewImpl->pageScaleFactor();
            const WebCore::FloatSize preResizeRelativeOffset
                = computeRelativeOffset(anchorPoint, anchorNode->boundingBox());
            webViewImpl->resize(WebSize(viewportSize.height, viewportSize.width));
            WebCore::IntPoint newAnchorPoint = WebCore::IntPoint(webViewImpl->mainFrame()->scrollOffset()) + WebCore::IntPoint(viewportSize.height / 2, 0);
            const WebCore::FloatSize postResizeRelativeOffset
                = computeRelativeOffset(newAnchorPoint, anchorNode->boundingBox());
            EXPECT_NEAR(preResizeRelativeOffset.width(), postResizeRelativeOffset.width(), 0.15f);
            expectedPageScaleFactor = pageScaleFactor * (shouldScaleRelativeToViewportWidth ? 1 / aspectRatio : 1);
            EXPECT_NEAR(expectedPageScaleFactor, webViewImpl->pageScaleFactor(), 0.05f);
        }
    }

Project: Chrome

static WebPoint topLeft(const WebRect& rect)
{
    return WebPoint(rect.x, rect.y);
}

Project: Chrome

    bool triggered() const { return m_triggered; }

Project: Chrome

    bool wasProgrammaticScroll() const { return m_didScrollMainFrame && m_wasProgrammaticScroll; }

Project: Chrome

    bool wasUserScroll() const { return m_didScrollMainFrame && !m_wasProgrammaticScroll; }

Project: Chrome

    virtual ~ContextLifetimeTestWebFrameClient()
    {
        reset();
    }

Project: Chrome

    virtual ~FakeCompositingWebViewClient()
    {
    }

Project: Chrome

        ~Notification()
        {
            context.Dispose();
        }

Project: Chrome

    virtual ~SpellCheckClient() { }

Project: Chrome

    virtual ~StubbornSpellCheckClient() { }

Project: Chrome

    virtual ~WebFrameTest()
    {
        if (m_webView)
            m_webView->close();
    }