Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2010 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 
     33 #include "public/web/WebFrame.h"
     34 
     35 #include "SkBitmap.h"
     36 #include "SkCanvas.h"
     37 #include "core/UserAgentStyleSheets.h"
     38 #include "core/clipboard/Clipboard.h"
     39 #include "core/css/StyleSheetContents.h"
     40 #include "core/css/resolver/ViewportStyleResolver.h"
     41 #include "core/dom/DocumentMarkerController.h"
     42 #include "core/dom/FullscreenElementStack.h"
     43 #include "core/dom/Range.h"
     44 #include "core/editing/Editor.h"
     45 #include "core/editing/FrameSelection.h"
     46 #include "core/editing/SpellChecker.h"
     47 #include "core/editing/VisiblePosition.h"
     48 #include "core/events/MouseEvent.h"
     49 #include "core/frame/FrameView.h"
     50 #include "core/frame/LocalFrame.h"
     51 #include "core/frame/Settings.h"
     52 #include "core/html/HTMLFormElement.h"
     53 #include "core/loader/FrameLoadRequest.h"
     54 #include "core/page/EventHandler.h"
     55 #include "core/rendering/HitTestResult.h"
     56 #include "core/rendering/RenderView.h"
     57 #include "core/rendering/TextAutosizer.h"
     58 #include "core/rendering/compositing/RenderLayerCompositor.h"
     59 #include "platform/DragImage.h"
     60 #include "platform/RuntimeEnabledFeatures.h"
     61 #include "platform/UserGestureIndicator.h"
     62 #include "platform/geometry/FloatRect.h"
     63 #include "platform/network/ResourceError.h"
     64 #include "platform/scroll/ScrollbarTheme.h"
     65 #include "public/platform/Platform.h"
     66 #include "public/platform/WebFloatRect.h"
     67 #include "public/platform/WebThread.h"
     68 #include "public/platform/WebURL.h"
     69 #include "public/platform/WebURLResponse.h"
     70 #include "public/platform/WebUnitTestSupport.h"
     71 #include "public/web/WebDataSource.h"
     72 #include "public/web/WebDocument.h"
     73 #include "public/web/WebFindOptions.h"
     74 #include "public/web/WebFormElement.h"
     75 #include "public/web/WebFrameClient.h"
     76 #include "public/web/WebHistoryItem.h"
     77 #include "public/web/WebRange.h"
     78 #include "public/web/WebScriptSource.h"
     79 #include "public/web/WebSearchableFormData.h"
     80 #include "public/web/WebSecurityOrigin.h"
     81 #include "public/web/WebSecurityPolicy.h"
     82 #include "public/web/WebSettings.h"
     83 #include "public/web/WebSpellCheckClient.h"
     84 #include "public/web/WebTextCheckingCompletion.h"
     85 #include "public/web/WebTextCheckingResult.h"
     86 #include "public/web/WebViewClient.h"
     87 #include "web/WebLocalFrameImpl.h"
     88 #include "web/WebViewImpl.h"
     89 #include "web/tests/FrameTestHelpers.h"
     90 #include "web/tests/URLTestHelpers.h"
     91 #include "wtf/Forward.h"
     92 #include "wtf/dtoa/utils.h"
     93 #include <gmock/gmock.h>
     94 #include <gtest/gtest.h>
     95 #include <map>
     96 #include <v8.h>
     97 
     98 using namespace blink;
     99 using WebCore::Document;
    100 using WebCore::DocumentMarker;
    101 using WebCore::Element;
    102 using WebCore::FloatRect;
    103 using WebCore::HitTestRequest;
    104 using WebCore::Range;
    105 using blink::URLTestHelpers::toKURL;
    106 using blink::FrameTestHelpers::runPendingTasks;
    107 
    108 namespace {
    109 
    110 const int touchPointPadding = 32;
    111 
    112 #define EXPECT_EQ_RECT(a, b) \
    113     EXPECT_EQ(a.x(), b.x()); \
    114     EXPECT_EQ(a.y(), b.y()); \
    115     EXPECT_EQ(a.width(), b.width()); \
    116     EXPECT_EQ(a.height(), b.height());
    117 
    118 class FakeCompositingWebViewClient : public FrameTestHelpers::TestWebViewClient {
    119 public:
    120     virtual bool enterFullScreen() OVERRIDE { return true; }
    121 };
    122 
    123 class WebFrameTest : public testing::Test {
    124 protected:
    125     WebFrameTest()
    126         : m_baseURL("http://www.test.com/")
    127         , m_chromeURL("chrome://")
    128     {
    129     }
    130 
    131     virtual ~WebFrameTest()
    132     {
    133         Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
    134     }
    135 
    136     void registerMockedHttpURLLoad(const std::string& fileName)
    137     {
    138         URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
    139     }
    140 
    141     void registerMockedChromeURLLoad(const std::string& fileName)
    142     {
    143         URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_chromeURL.c_str()), WebString::fromUTF8(fileName.c_str()));
    144     }
    145 
    146     void applyViewportStyleOverride(FrameTestHelpers::WebViewHelper* webViewHelper)
    147     {
    148         RefPtrWillBeRawPtr<WebCore::StyleSheetContents> styleSheet = WebCore::StyleSheetContents::create(WebCore::CSSParserContext(WebCore::UASheetMode, 0));
    149         styleSheet->parseString(String(WebCore::viewportAndroidUserAgentStyleSheet, sizeof(WebCore::viewportAndroidUserAgentStyleSheet)));
    150         OwnPtrWillBeRawPtr<WebCore::RuleSet> ruleSet = WebCore::RuleSet::create();
    151         ruleSet->addRulesFromSheet(styleSheet.get(), WebCore::MediaQueryEvaluator("screen"));
    152 
    153         Document* document = toLocalFrame(webViewHelper->webViewImpl()->page()->mainFrame())->document();
    154         document->ensureStyleResolver().viewportStyleResolver()->collectViewportRules(ruleSet.get(), WebCore::ViewportStyleResolver::UserAgentOrigin);
    155         document->ensureStyleResolver().viewportStyleResolver()->resolve();
    156     }
    157 
    158     static void configueCompositingWebView(WebSettings* settings)
    159     {
    160         settings->setAcceleratedCompositingEnabled(true);
    161         settings->setAcceleratedCompositingForFixedPositionEnabled(true);
    162         settings->setAcceleratedCompositingForOverflowScrollEnabled(true);
    163         settings->setCompositedScrollingForFramesEnabled(true);
    164     }
    165 
    166     void initializeTextSelectionWebView(const std::string& url, FrameTestHelpers::WebViewHelper* webViewHelper)
    167     {
    168         webViewHelper->initializeAndLoad(url, true);
    169         webViewHelper->webView()->settings()->setDefaultFontSize(12);
    170         webViewHelper->webView()->resize(WebSize(640, 480));
    171     }
    172 
    173     PassOwnPtr<WebCore::DragImage> nodeImageTestSetup(FrameTestHelpers::WebViewHelper* webViewHelper, const std::string& testcase)
    174     {
    175         registerMockedHttpURLLoad("nodeimage.html");
    176         webViewHelper->initializeAndLoad(m_baseURL + "nodeimage.html");
    177         webViewHelper->webView()->resize(WebSize(640, 480));
    178         webViewHelper->webView()->layout();
    179         RefPtr<WebCore::LocalFrame> frame = toLocalFrame(webViewHelper->webViewImpl()->page()->mainFrame());
    180         WebCore::Element* element = frame->document()->getElementById(testcase.c_str());
    181         return frame->nodeImage(*element);
    182     }
    183 
    184     std::string m_baseURL;
    185     std::string m_chromeURL;
    186 };
    187 
    188 class UseMockScrollbarSettings {
    189 public:
    190     UseMockScrollbarSettings()
    191     {
    192         WebCore::Settings::setMockScrollbarsEnabled(true);
    193         WebCore::RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(true);
    194         EXPECT_TRUE(WebCore::ScrollbarTheme::theme()->usesOverlayScrollbars());
    195     }
    196 
    197     ~UseMockScrollbarSettings()
    198     {
    199         WebCore::Settings::setMockScrollbarsEnabled(false);
    200         WebCore::RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(false);
    201     }
    202 };
    203 
    204 TEST_F(WebFrameTest, ContentText)
    205 {
    206     registerMockedHttpURLLoad("iframes_test.html");
    207     registerMockedHttpURLLoad("visible_iframe.html");
    208     registerMockedHttpURLLoad("invisible_iframe.html");
    209     registerMockedHttpURLLoad("zero_sized_iframe.html");
    210 
    211     FrameTestHelpers::WebViewHelper webViewHelper;
    212     webViewHelper.initializeAndLoad(m_baseURL + "iframes_test.html");
    213 
    214     // Now retrieve the frames text and test it only includes visible elements.
    215     std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
    216     EXPECT_NE(std::string::npos, content.find(" visible paragraph"));
    217     EXPECT_NE(std::string::npos, content.find(" visible iframe"));
    218     EXPECT_EQ(std::string::npos, content.find(" invisible pararaph"));
    219     EXPECT_EQ(std::string::npos, content.find(" invisible iframe"));
    220     EXPECT_EQ(std::string::npos, content.find("iframe with zero size"));
    221 }
    222 
    223 TEST_F(WebFrameTest, FrameForEnteredContext)
    224 {
    225     registerMockedHttpURLLoad("iframes_test.html");
    226     registerMockedHttpURLLoad("visible_iframe.html");
    227     registerMockedHttpURLLoad("invisible_iframe.html");
    228     registerMockedHttpURLLoad("zero_sized_iframe.html");
    229 
    230     FrameTestHelpers::WebViewHelper webViewHelper;
    231     webViewHelper.initializeAndLoad(m_baseURL + "iframes_test.html", true);
    232 
    233     v8::HandleScope scope(v8::Isolate::GetCurrent());
    234     EXPECT_EQ(webViewHelper.webView()->mainFrame(), WebLocalFrame::frameForContext(webViewHelper.webView()->mainFrame()->mainWorldScriptContext()));
    235     EXPECT_EQ(webViewHelper.webView()->mainFrame()->firstChild(), WebLocalFrame::frameForContext(webViewHelper.webView()->mainFrame()->firstChild()->mainWorldScriptContext()));
    236 }
    237 
    238 TEST_F(WebFrameTest, FormWithNullFrame)
    239 {
    240     registerMockedHttpURLLoad("form.html");
    241 
    242     FrameTestHelpers::WebViewHelper webViewHelper;
    243     webViewHelper.initializeAndLoad(m_baseURL + "form.html");
    244 
    245     WebVector<WebFormElement> forms;
    246     webViewHelper.webView()->mainFrame()->document().forms(forms);
    247     webViewHelper.reset();
    248 
    249     EXPECT_EQ(forms.size(), 1U);
    250 
    251     // This test passes if this doesn't crash.
    252     WebSearchableFormData searchableDataForm(forms[0]);
    253 }
    254 
    255 TEST_F(WebFrameTest, ChromePageJavascript)
    256 {
    257     registerMockedChromeURLLoad("history.html");
    258 
    259     // Pass true to enable JavaScript.
    260     FrameTestHelpers::WebViewHelper webViewHelper;
    261     webViewHelper.initializeAndLoad(m_chromeURL + "history.html", true);
    262 
    263     // Try to run JS against the chrome-style URL.
    264     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.appendChild(document.createTextNode('Clobbered'))");
    265 
    266     // Required to see any updates in contentAsText.
    267     webViewHelper.webView()->layout();
    268 
    269     // Now retrieve the frame's text and ensure it was modified by running javascript.
    270     std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
    271     EXPECT_NE(std::string::npos, content.find("Clobbered"));
    272 }
    273 
    274 TEST_F(WebFrameTest, ChromePageNoJavascript)
    275 {
    276     registerMockedChromeURLLoad("history.html");
    277 
    278     /// Pass true to enable JavaScript.
    279     FrameTestHelpers::WebViewHelper webViewHelper;
    280     webViewHelper.initializeAndLoad(m_chromeURL + "history.html", true);
    281 
    282     // Try to run JS against the chrome-style URL after prohibiting it.
    283     WebSecurityPolicy::registerURLSchemeAsNotAllowingJavascriptURLs("chrome");
    284     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.appendChild(document.createTextNode('Clobbered'))");
    285 
    286     // Required to see any updates in contentAsText.
    287     webViewHelper.webView()->layout();
    288 
    289     // Now retrieve the frame's text and ensure it wasn't modified by running javascript.
    290     std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
    291     EXPECT_EQ(std::string::npos, content.find("Clobbered"));
    292 }
    293 
    294 TEST_F(WebFrameTest, LocationSetHostWithMissingPort)
    295 {
    296     std::string fileName = "print-location-href.html";
    297     registerMockedHttpURLLoad(fileName);
    298     URLTestHelpers::registerMockedURLLoad(toKURL("http://www.test.com:0/" + fileName), WebString::fromUTF8(fileName));
    299 
    300     FrameTestHelpers::WebViewHelper webViewHelper;
    301 
    302     /// Pass true to enable JavaScript.
    303     webViewHelper.initializeAndLoad(m_baseURL + fileName, true);
    304 
    305     // Setting host to "hostname:" should be treated as "hostname:0".
    306     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:location.host = 'www.test.com:'; void 0;");
    307 
    308     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.textContent = location.href; void 0;");
    309 
    310     std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
    311     EXPECT_EQ("http://www.test.com:0/" + fileName, content);
    312 }
    313 
    314 TEST_F(WebFrameTest, LocationSetEmptyPort)
    315 {
    316     std::string fileName = "print-location-href.html";
    317     registerMockedHttpURLLoad(fileName);
    318     URLTestHelpers::registerMockedURLLoad(toKURL("http://www.test.com:0/" + fileName), WebString::fromUTF8(fileName));
    319 
    320     FrameTestHelpers::WebViewHelper webViewHelper;
    321 
    322     /// Pass true to enable JavaScript.
    323     webViewHelper.initializeAndLoad(m_baseURL + fileName, true);
    324 
    325     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:location.port = ''; void 0;");
    326 
    327     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.textContent = location.href; void 0;");
    328 
    329     std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
    330     EXPECT_EQ("http://www.test.com:0/" + fileName, content);
    331 }
    332 
    333 class CSSCallbackWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
    334 public:
    335     CSSCallbackWebFrameClient() : m_updateCount(0) { }
    336     virtual void didMatchCSS(WebLocalFrame*, const WebVector<WebString>& newlyMatchingSelectors, const WebVector<WebString>& stoppedMatchingSelectors) OVERRIDE;
    337 
    338     std::map<WebLocalFrame*, std::set<std::string> > m_matchedSelectors;
    339     int m_updateCount;
    340 };
    341 
    342 void CSSCallbackWebFrameClient::didMatchCSS(WebLocalFrame* frame, const WebVector<WebString>& newlyMatchingSelectors, const WebVector<WebString>& stoppedMatchingSelectors)
    343 {
    344     ++m_updateCount;
    345     std::set<std::string>& frameSelectors = m_matchedSelectors[frame];
    346     for (size_t i = 0; i < newlyMatchingSelectors.size(); ++i) {
    347         std::string selector = newlyMatchingSelectors[i].utf8();
    348         EXPECT_EQ(0U, frameSelectors.count(selector)) << selector;
    349         frameSelectors.insert(selector);
    350     }
    351     for (size_t i = 0; i < stoppedMatchingSelectors.size(); ++i) {
    352         std::string selector = stoppedMatchingSelectors[i].utf8();
    353         EXPECT_EQ(1U, frameSelectors.count(selector)) << selector;
    354         frameSelectors.erase(selector);
    355     }
    356 }
    357 
    358 class WebFrameCSSCallbackTest : public testing::Test {
    359 protected:
    360     WebFrameCSSCallbackTest()
    361     {
    362 
    363         m_frame = m_helper.initializeAndLoad("about:blank", true, &m_client)->mainFrame()->toWebLocalFrame();
    364     }
    365 
    366     ~WebFrameCSSCallbackTest()
    367     {
    368         EXPECT_EQ(1U, m_client.m_matchedSelectors.size());
    369     }
    370 
    371     WebDocument doc() const
    372     {
    373         return m_frame->document();
    374     }
    375 
    376     int updateCount() const
    377     {
    378         return m_client.m_updateCount;
    379     }
    380 
    381     const std::set<std::string>& matchedSelectors()
    382     {
    383         return m_client.m_matchedSelectors[m_frame];
    384     }
    385 
    386     void loadHTML(const std::string& html)
    387     {
    388         FrameTestHelpers::loadHTMLString(m_frame, html, toKURL("about:blank"));
    389     }
    390 
    391     void executeScript(const WebString& code)
    392     {
    393         m_frame->executeScript(WebScriptSource(code));
    394         m_frame->view()->layout();
    395         runPendingTasks();
    396     }
    397 
    398     CSSCallbackWebFrameClient m_client;
    399     FrameTestHelpers::WebViewHelper m_helper;
    400     WebLocalFrame* m_frame;
    401 };
    402 
    403 TEST_F(WebFrameCSSCallbackTest, AuthorStyleSheet)
    404 {
    405     loadHTML(
    406         "<style>"
    407         // This stylesheet checks that the internal property and value can't be
    408         // set by a stylesheet, only WebDocument::watchCSSSelectors().
    409         "div.initial_on { -internal-callback: none; }"
    410         "div.initial_off { -internal-callback: -internal-presence; }"
    411         "</style>"
    412         "<div class=\"initial_on\"></div>"
    413         "<div class=\"initial_off\"></div>");
    414 
    415     std::vector<WebString> selectors;
    416     selectors.push_back(WebString::fromUTF8("div.initial_on"));
    417     m_frame->document().watchCSSSelectors(WebVector<WebString>(selectors));
    418     m_frame->view()->layout();
    419     runPendingTasks();
    420     EXPECT_EQ(1, updateCount());
    421     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("div.initial_on"));
    422 
    423     // Check that adding a watched selector calls back for already-present nodes.
    424     selectors.push_back(WebString::fromUTF8("div.initial_off"));
    425     doc().watchCSSSelectors(WebVector<WebString>(selectors));
    426     m_frame->view()->layout();
    427     runPendingTasks();
    428     EXPECT_EQ(2, updateCount());
    429     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("div.initial_off", "div.initial_on"));
    430 
    431     // Check that we can turn off callbacks for certain selectors.
    432     doc().watchCSSSelectors(WebVector<WebString>());
    433     m_frame->view()->layout();
    434     runPendingTasks();
    435     EXPECT_EQ(3, updateCount());
    436     EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
    437 }
    438 
    439 TEST_F(WebFrameCSSCallbackTest, SharedRenderStyle)
    440 {
    441     // Check that adding an element calls back when it matches an existing rule.
    442     std::vector<WebString> selectors;
    443     selectors.push_back(WebString::fromUTF8("span"));
    444     doc().watchCSSSelectors(WebVector<WebString>(selectors));
    445 
    446     executeScript(
    447         "i1 = document.createElement('span');"
    448         "i1.id = 'first_span';"
    449         "document.body.appendChild(i1)");
    450     EXPECT_EQ(1, updateCount());
    451     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
    452 
    453     // Adding a second element that shares a RenderStyle shouldn't call back.
    454     // We use <span>s to avoid default style rules that can set
    455     // RenderStyle::unique().
    456     executeScript(
    457         "i2 = document.createElement('span');"
    458         "i2.id = 'second_span';"
    459         "i1 = document.getElementById('first_span');"
    460         "i1.parentNode.insertBefore(i2, i1.nextSibling);");
    461     EXPECT_EQ(1, updateCount());
    462     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
    463 
    464     // Removing the first element shouldn't call back.
    465     executeScript(
    466         "i1 = document.getElementById('first_span');"
    467         "i1.parentNode.removeChild(i1);");
    468     EXPECT_EQ(1, updateCount());
    469     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
    470 
    471     // But removing the second element *should* call back.
    472     executeScript(
    473         "i2 = document.getElementById('second_span');"
    474         "i2.parentNode.removeChild(i2);");
    475     EXPECT_EQ(2, updateCount());
    476     EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
    477 }
    478 
    479 TEST_F(WebFrameCSSCallbackTest, CatchesAttributeChange)
    480 {
    481     loadHTML("<span></span>");
    482 
    483     std::vector<WebString> selectors;
    484     selectors.push_back(WebString::fromUTF8("span[attr=\"value\"]"));
    485     doc().watchCSSSelectors(WebVector<WebString>(selectors));
    486     runPendingTasks();
    487 
    488     EXPECT_EQ(0, updateCount());
    489     EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
    490 
    491     executeScript(
    492         "document.querySelector('span').setAttribute('attr', 'value');");
    493     EXPECT_EQ(1, updateCount());
    494     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span[attr=\"value\"]"));
    495 }
    496 
    497 TEST_F(WebFrameCSSCallbackTest, DisplayNone)
    498 {
    499     loadHTML("<div style='display:none'><span></span></div>");
    500 
    501     std::vector<WebString> selectors;
    502     selectors.push_back(WebString::fromUTF8("span"));
    503     doc().watchCSSSelectors(WebVector<WebString>(selectors));
    504     runPendingTasks();
    505 
    506     EXPECT_EQ(0, updateCount()) << "Don't match elements in display:none trees.";
    507 
    508     executeScript(
    509         "d = document.querySelector('div');"
    510         "d.style.display = 'block';");
    511     EXPECT_EQ(1, updateCount()) << "Match elements when they become displayed.";
    512     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
    513 
    514     executeScript(
    515         "d = document.querySelector('div');"
    516         "d.style.display = 'none';");
    517     EXPECT_EQ(2, updateCount()) << "Unmatch elements when they become undisplayed.";
    518     EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
    519 
    520     executeScript(
    521         "s = document.querySelector('span');"
    522         "s.style.display = 'none';");
    523     EXPECT_EQ(2, updateCount()) << "No effect from no-display'ing a span that's already undisplayed.";
    524 
    525     executeScript(
    526         "d = document.querySelector('div');"
    527         "d.style.display = 'block';");
    528     EXPECT_EQ(2, updateCount()) << "No effect from displaying a div whose span is display:none.";
    529 
    530     executeScript(
    531         "s = document.querySelector('span');"
    532         "s.style.display = 'inline';");
    533     EXPECT_EQ(3, updateCount()) << "Now the span is visible and produces a callback.";
    534     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
    535 
    536     executeScript(
    537         "s = document.querySelector('span');"
    538         "s.style.display = 'none';");
    539     EXPECT_EQ(4, updateCount()) << "Undisplaying the span directly should produce another callback.";
    540     EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
    541 }
    542 
    543 TEST_F(WebFrameCSSCallbackTest, Reparenting)
    544 {
    545     loadHTML(
    546         "<div id='d1'><span></span></div>"
    547         "<div id='d2'></div>");
    548 
    549     std::vector<WebString> selectors;
    550     selectors.push_back(WebString::fromUTF8("span"));
    551     doc().watchCSSSelectors(WebVector<WebString>(selectors));
    552     m_frame->view()->layout();
    553     runPendingTasks();
    554 
    555     EXPECT_EQ(1, updateCount());
    556     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
    557 
    558     executeScript(
    559         "s = document.querySelector('span');"
    560         "d2 = document.getElementById('d2');"
    561         "d2.appendChild(s);");
    562     EXPECT_EQ(1, updateCount()) << "Just moving an element that continues to match shouldn't send a spurious callback.";
    563     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
    564 }
    565 
    566 TEST_F(WebFrameCSSCallbackTest, MultiSelector)
    567 {
    568     loadHTML("<span></span>");
    569 
    570     // Check that selector lists match as the whole list, not as each element
    571     // independently.
    572     std::vector<WebString> selectors;
    573     selectors.push_back(WebString::fromUTF8("span"));
    574     selectors.push_back(WebString::fromUTF8("span,p"));
    575     doc().watchCSSSelectors(WebVector<WebString>(selectors));
    576     m_frame->view()->layout();
    577     runPendingTasks();
    578 
    579     EXPECT_EQ(1, updateCount());
    580     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span", "span, p"));
    581 }
    582 
    583 TEST_F(WebFrameCSSCallbackTest, InvalidSelector)
    584 {
    585     loadHTML("<p><span></span></p>");
    586 
    587     // Build a list with one valid selector and one invalid.
    588     std::vector<WebString> selectors;
    589     selectors.push_back(WebString::fromUTF8("span"));
    590     selectors.push_back(WebString::fromUTF8("[")); // Invalid.
    591     selectors.push_back(WebString::fromUTF8("p span")); // Not compound.
    592     doc().watchCSSSelectors(WebVector<WebString>(selectors));
    593     m_frame->view()->layout();
    594     runPendingTasks();
    595 
    596     EXPECT_EQ(1, updateCount());
    597     EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"))
    598         << "An invalid selector shouldn't prevent other selectors from matching.";
    599 }
    600 
    601 TEST_F(WebFrameTest, DispatchMessageEventWithOriginCheck)
    602 {
    603     registerMockedHttpURLLoad("postmessage_test.html");
    604 
    605     // Pass true to enable JavaScript.
    606     FrameTestHelpers::WebViewHelper webViewHelper;
    607     webViewHelper.initializeAndLoad(m_baseURL + "postmessage_test.html", true);
    608 
    609     // Send a message with the correct origin.
    610     WebSecurityOrigin correctOrigin(WebSecurityOrigin::create(toKURL(m_baseURL)));
    611     WebDOMEvent event = webViewHelper.webView()->mainFrame()->document().createEvent("MessageEvent");
    612     WebDOMMessageEvent message = event.to<WebDOMMessageEvent>();
    613     WebSerializedScriptValue data(WebSerializedScriptValue::fromString("foo"));
    614     message.initMessageEvent("message", false, false, data, "http://origin.com", 0, "");
    615     webViewHelper.webView()->mainFrame()->dispatchMessageEventWithOriginCheck(correctOrigin, message);
    616 
    617     // Send another message with incorrect origin.
    618     WebSecurityOrigin incorrectOrigin(WebSecurityOrigin::create(toKURL(m_chromeURL)));
    619     webViewHelper.webView()->mainFrame()->dispatchMessageEventWithOriginCheck(incorrectOrigin, message);
    620 
    621     // Required to see any updates in contentAsText.
    622     webViewHelper.webView()->layout();
    623 
    624     // Verify that only the first addition is in the body of the page.
    625     std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
    626     EXPECT_NE(std::string::npos, content.find("Message 1."));
    627     EXPECT_EQ(std::string::npos, content.find("Message 2."));
    628 }
    629 
    630 TEST_F(WebFrameTest, PostMessageThenDetach)
    631 {
    632     FrameTestHelpers::WebViewHelper webViewHelper;
    633     webViewHelper.initializeAndLoad("about:blank");
    634 
    635     RefPtr<WebCore::LocalFrame> frame = toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame());
    636     WebCore::NonThrowableExceptionState exceptionState;
    637     frame->domWindow()->postMessage(WebCore::SerializedScriptValue::create("message"), 0, "*", frame->domWindow(), exceptionState);
    638     webViewHelper.reset();
    639     EXPECT_FALSE(exceptionState.hadException());
    640 
    641     // Success is not crashing.
    642     runPendingTasks();
    643 }
    644 
    645 class FixedLayoutTestWebViewClient : public FrameTestHelpers::TestWebViewClient {
    646  public:
    647     virtual WebScreenInfo screenInfo() OVERRIDE { return m_screenInfo; }
    648 
    649     WebScreenInfo m_screenInfo;
    650 };
    651 
    652 // Viewport settings need to be set before the page gets loaded
    653 static void enableViewportSettings(WebSettings* settings)
    654 {
    655     settings->setViewportMetaEnabled(true);
    656     settings->setViewportEnabled(true);
    657     settings->setMainFrameResizesAreOrientationChanges(true);
    658     settings->setShrinksViewportContentToFit(true);
    659 }
    660 
    661 TEST_F(WebFrameTest, FrameViewNeedsLayoutOnFixedLayoutResize)
    662 {
    663     UseMockScrollbarSettings mockScrollbarSettings;
    664     registerMockedHttpURLLoad("fixed_layout.html");
    665 
    666     FixedLayoutTestWebViewClient client;
    667     int viewportWidth = 640;
    668     int viewportHeight = 480;
    669 
    670     // Make sure we initialize to minimum scale, even if the window size
    671     // only becomes available after the load begins.
    672     FrameTestHelpers::WebViewHelper webViewHelper;
    673     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
    674     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
    675     webViewHelper.webView()->layout();
    676 
    677     webViewHelper.webViewImpl()->setFixedLayoutSize(WebCore::IntSize(100, 100));
    678     EXPECT_TRUE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
    679 
    680     int prevLayoutCount = webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
    681     webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->setFrameRect(WebCore::IntRect(0, 0, 641, 481));
    682     EXPECT_EQ(prevLayoutCount, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount());
    683 
    684     webViewHelper.webViewImpl()->layout();
    685 }
    686 
    687 // Helper function to check or set text autosizing multipliers on a document.
    688 static bool checkOrSetTextAutosizingMultiplier(Document* document, float multiplier, bool setMultiplier)
    689 {
    690     bool multiplierCheckedOrSetAtLeastOnce = false;
    691     for (WebCore::RenderObject* renderer = document->renderView(); renderer; renderer = renderer->nextInPreOrder()) {
    692         if (renderer->style()) {
    693             if (setMultiplier)
    694                 renderer->style()->setTextAutosizingMultiplier(multiplier);
    695             EXPECT_EQ(multiplier, renderer->style()->textAutosizingMultiplier());
    696             multiplierCheckedOrSetAtLeastOnce = true;
    697         }
    698     }
    699     return multiplierCheckedOrSetAtLeastOnce;
    700 
    701 }
    702 
    703 static bool setTextAutosizingMultiplier(Document* document, float multiplier)
    704 {
    705     return checkOrSetTextAutosizingMultiplier(document, multiplier, true);
    706 }
    707 
    708 static bool checkTextAutosizingMultiplier(Document* document, float multiplier)
    709 {
    710     return checkOrSetTextAutosizingMultiplier(document, multiplier, false);
    711 }
    712 
    713 TEST_F(WebFrameTest, ChangeInFixedLayoutResetsTextAutosizingMultipliers)
    714 {
    715     UseMockScrollbarSettings mockScrollbarSettings;
    716     registerMockedHttpURLLoad("fixed_layout.html");
    717 
    718     FixedLayoutTestWebViewClient client;
    719     int viewportWidth = 640;
    720     int viewportHeight = 480;
    721 
    722     FrameTestHelpers::WebViewHelper webViewHelper;
    723     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
    724 
    725     WebCore::Document* document = toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->document();
    726     document->settings()->setTextAutosizingEnabled(true);
    727     EXPECT_TRUE(document->settings()->textAutosizingEnabled());
    728     webViewHelper.webViewImpl()->resize(WebSize(viewportWidth, viewportHeight));
    729     webViewHelper.webViewImpl()->layout();
    730 
    731     EXPECT_TRUE(setTextAutosizingMultiplier(document, 2));
    732 
    733     WebCore::ViewportDescription description = document->viewportDescription();
    734     // Choose a width that's not going match the viewport width of the loaded document.
    735     description.minWidth = WebCore::Length(100, WebCore::Fixed);
    736     description.maxWidth = WebCore::Length(100, WebCore::Fixed);
    737     webViewHelper.webViewImpl()->updatePageDefinedViewportConstraints(description);
    738 
    739     EXPECT_TRUE(checkTextAutosizingMultiplier(document, 1));
    740 }
    741 
    742 TEST_F(WebFrameTest, SetFrameRectInvalidatesTextAutosizingMultipliers)
    743 {
    744     UseMockScrollbarSettings mockScrollbarSettings;
    745     registerMockedHttpURLLoad("iframe_reload.html");
    746     registerMockedHttpURLLoad("visible_iframe.html");
    747 
    748     FixedLayoutTestWebViewClient client;
    749     int viewportWidth = 640;
    750     int viewportHeight = 480;
    751 
    752     FrameTestHelpers::WebViewHelper webViewHelper;
    753     webViewHelper.initializeAndLoad(m_baseURL + "iframe_reload.html", true, 0, &client, enableViewportSettings);
    754 
    755     WebCore::LocalFrame* mainFrame = toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame());
    756     WebCore::Document* document = mainFrame->document();
    757     WebCore::FrameView* frameView = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
    758     document->settings()->setTextAutosizingEnabled(true);
    759     EXPECT_TRUE(document->settings()->textAutosizingEnabled());
    760     webViewHelper.webViewImpl()->resize(WebSize(viewportWidth, viewportHeight));
    761     webViewHelper.webViewImpl()->layout();
    762 
    763     for (WebCore::Frame* frame = mainFrame; frame; frame = frame->tree().traverseNext()) {
    764         if (!frame->isLocalFrame())
    765             continue;
    766         EXPECT_TRUE(setTextAutosizingMultiplier(toLocalFrame(frame)->document(), 2));
    767         for (WebCore::RenderObject* renderer = toLocalFrame(frame)->document()->renderView(); renderer; renderer = renderer->nextInPreOrder()) {
    768             if (renderer->isText())
    769                 EXPECT_FALSE(renderer->needsLayout());
    770         }
    771     }
    772 
    773     frameView->setFrameRect(WebCore::IntRect(0, 0, 200, 200));
    774     for (WebCore::Frame* frame = mainFrame; frame; frame = frame->tree().traverseNext()) {
    775         if (!frame->isLocalFrame())
    776             continue;
    777         for (WebCore::RenderObject* renderer = toLocalFrame(frame)->document()->renderView(); renderer; renderer = renderer->nextInPreOrder()) {
    778             if (renderer->isText())
    779                 EXPECT_TRUE(renderer->needsLayout());
    780         }
    781     }
    782 }
    783 
    784 TEST_F(WebFrameTest, FixedLayoutSizeStopsResizeFromChangingLayoutSize)
    785 {
    786     UseMockScrollbarSettings mockScrollbarSettings;
    787     registerMockedHttpURLLoad("fixed_layout.html");
    788 
    789     int viewportWidth = 640;
    790     int viewportHeight = 480;
    791 
    792     int fixedLayoutWidth = viewportWidth / 2;
    793     int fixedLayoutHeight = viewportHeight / 2;
    794 
    795     FrameTestHelpers::WebViewHelper webViewHelper;
    796     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, 0, enableViewportSettings);
    797     webViewHelper.webView()->setFixedLayoutSize(WebSize(fixedLayoutWidth, fixedLayoutHeight));
    798     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
    799     webViewHelper.webView()->layout();
    800 
    801     EXPECT_EQ(fixedLayoutWidth, toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->view()->layoutSize().width());
    802     EXPECT_EQ(fixedLayoutHeight, toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->view()->layoutSize().height());
    803 }
    804 
    805 TEST_F(WebFrameTest, FixedLayoutSizePreventsResizeFromChangingPageScale)
    806 {
    807     UseMockScrollbarSettings mockScrollbarSettings;
    808     registerMockedHttpURLLoad("fixed_layout.html");
    809 
    810     int viewportWidth = 640;
    811     int viewportHeight = 480;
    812 
    813     int fixedLayoutWidth = viewportWidth / 2;
    814     int fixedLayoutHeight = viewportHeight / 2;
    815 
    816     FrameTestHelpers::WebViewHelper webViewHelper;
    817     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, 0, enableViewportSettings);
    818     webViewHelper.webView()->setFixedLayoutSize(WebSize(fixedLayoutWidth, fixedLayoutHeight));
    819     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
    820     webViewHelper.webView()->layout();
    821     float pageScaleFactor = webViewHelper.webView()->pageScaleFactor();
    822 
    823     webViewHelper.webView()->resize(WebSize(viewportWidth * 2, viewportHeight * 2));
    824 
    825     EXPECT_EQ(pageScaleFactor, webViewHelper.webView()->pageScaleFactor());
    826 }
    827 
    828 TEST_F(WebFrameTest, FixedLayoutSizePreventsLayoutFromChangingPageScale)
    829 {
    830     UseMockScrollbarSettings mockScrollbarSettings;
    831     registerMockedHttpURLLoad("fixed_layout.html");
    832 
    833     int viewportWidth = 640;
    834     int viewportHeight = 480;
    835 
    836     int fixedLayoutWidth = viewportWidth * 2;
    837     int fixedLayoutHeight = viewportHeight * 2;
    838 
    839     FrameTestHelpers::WebViewHelper webViewHelper;
    840     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, 0, enableViewportSettings);
    841     webViewHelper.webView()->setFixedLayoutSize(WebSize(viewportWidth, viewportHeight));
    842     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
    843     webViewHelper.webView()->layout();
    844     float pageScaleFactor = webViewHelper.webView()->pageScaleFactor();
    845 
    846     webViewHelper.webView()->setFixedLayoutSize(WebSize(fixedLayoutWidth, fixedLayoutHeight));
    847     webViewHelper.webView()->layout();
    848 
    849     EXPECT_EQ(pageScaleFactor, webViewHelper.webView()->pageScaleFactor());
    850 }
    851 
    852 TEST_F(WebFrameTest, PreferredSizeAndContentSizeReportedCorrectlyWithZeroHeightFixedLayout)
    853 {
    854     UseMockScrollbarSettings mockScrollbarSettings;
    855     registerMockedHttpURLLoad("200-by-300.html");
    856 
    857     int windowWidth = 100;
    858     int windowHeight = 100;
    859     int viewportWidth = 100;
    860     int viewportHeight = 0;
    861     int divWidth = 200;
    862     int divHeight = 300;
    863 
    864     FixedLayoutTestWebViewClient client;
    865     client.m_screenInfo.deviceScaleFactor = 1;
    866 
    867     FrameTestHelpers::WebViewHelper webViewHelper;
    868     webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, 0, &client, enableViewportSettings);
    869     webViewHelper.webView()->resize(WebSize(windowWidth, windowHeight));
    870     webViewHelper.webView()->setFixedLayoutSize(WebSize(viewportWidth, viewportHeight));
    871     webViewHelper.webView()->layout();
    872 
    873     EXPECT_EQ(divWidth, webViewHelper.webView()->mainFrame()->contentsSize().width);
    874     EXPECT_EQ(divHeight, webViewHelper.webView()->mainFrame()->contentsSize().height);
    875 
    876     EXPECT_EQ(divWidth, webViewHelper.webView()->contentsPreferredMinimumSize().width);
    877     EXPECT_EQ(divHeight, webViewHelper.webView()->contentsPreferredMinimumSize().height);
    878 }
    879 
    880 TEST_F(WebFrameTest, DisablingFixedLayoutSizeSetsCorrectLayoutSize)
    881 {
    882     UseMockScrollbarSettings mockScrollbarSettings;
    883     registerMockedHttpURLLoad("no_viewport_tag.html");
    884 
    885     FixedLayoutTestWebViewClient client;
    886     client.m_screenInfo.deviceScaleFactor = 1;
    887     int viewportWidth = 640;
    888     int viewportHeight = 480;
    889 
    890     FrameTestHelpers::WebViewHelper webViewHelper;
    891     webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
    892     applyViewportStyleOverride(&webViewHelper);
    893     webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
    894     webViewHelper.webView()->settings()->setUseWideViewport(true);
    895     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
    896 
    897     webViewHelper.webView()->setFixedLayoutSize(WebSize(viewportWidth, viewportHeight));
    898     EXPECT_TRUE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
    899     webViewHelper.webView()->layout();
    900     EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
    901 
    902     webViewHelper.webView()->setFixedLayoutSize(WebSize(0, 0));
    903     EXPECT_TRUE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
    904     webViewHelper.webView()->layout();
    905     EXPECT_EQ(980, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
    906 }
    907 
    908 TEST_F(WebFrameTest, ZeroHeightPositiveWidthNotIgnored)
    909 {
    910     UseMockScrollbarSettings mockScrollbarSettings;
    911 
    912     FixedLayoutTestWebViewClient client;
    913     client.m_screenInfo.deviceScaleFactor = 1;
    914     int viewportWidth = 1280;
    915     int viewportHeight = 0;
    916 
    917     FrameTestHelpers::WebViewHelper webViewHelper;
    918     webViewHelper.initialize(true, 0, &client, enableViewportSettings);
    919     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
    920 
    921     EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
    922     EXPECT_EQ(viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
    923 }
    924 
    925 TEST_F(WebFrameTest, DeviceScaleFactorUsesDefaultWithoutViewportTag)
    926 {
    927     UseMockScrollbarSettings mockScrollbarSettings;
    928     registerMockedHttpURLLoad("no_viewport_tag.html");
    929 
    930     int viewportWidth = 640;
    931     int viewportHeight = 480;
    932 
    933     FixedLayoutTestWebViewClient client;
    934     client.m_screenInfo.deviceScaleFactor = 2;
    935 
    936     FrameTestHelpers::WebViewHelper webViewHelper;
    937     webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
    938 
    939     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
    940     webViewHelper.webView()->layout();
    941 
    942     EXPECT_EQ(2, webViewHelper.webView()->deviceScaleFactor());
    943 
    944     // Device scale factor should be independent of page scale.
    945     webViewHelper.webView()->setPageScaleFactorLimits(1, 2);
    946     webViewHelper.webView()->setPageScaleFactor(0.5);
    947     webViewHelper.webView()->layout();
    948     EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor());
    949 
    950     // Force the layout to happen before leaving the test.
    951     webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
    952 }
    953 
    954 TEST_F(WebFrameTest, FixedLayoutInitializeAtMinimumScale)
    955 {
    956     UseMockScrollbarSettings mockScrollbarSettings;
    957 
    958     registerMockedHttpURLLoad("fixed_layout.html");
    959 
    960     FixedLayoutTestWebViewClient client;
    961     client.m_screenInfo.deviceScaleFactor = 1;
    962     int viewportWidth = 640;
    963     int viewportHeight = 480;
    964 
    965     // Make sure we initialize to minimum scale, even if the window size
    966     // only becomes available after the load begins.
    967     FrameTestHelpers::WebViewHelper webViewHelper;
    968     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
    969     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
    970 
    971     int defaultFixedLayoutWidth = 980;
    972     float minimumPageScaleFactor = viewportWidth / (float) defaultFixedLayoutWidth;
    973     EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
    974     EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->minimumPageScaleFactor());
    975 
    976     // Assume the user has pinch zoomed to page scale factor 2.
    977     float userPinchPageScaleFactor = 2;
    978     webViewHelper.webView()->setPageScaleFactor(userPinchPageScaleFactor);
    979     webViewHelper.webView()->layout();
    980 
    981     // Make sure we don't reset to initial scale if the page continues to load.
    982     webViewHelper.webViewImpl()->didCommitLoad(false, false);
    983     webViewHelper.webViewImpl()->didChangeContentsSize();
    984     EXPECT_EQ(userPinchPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
    985 
    986     // Make sure we don't reset to initial scale if the viewport size changes.
    987     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight + 100));
    988     EXPECT_EQ(userPinchPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
    989 }
    990 
    991 TEST_F(WebFrameTest, WideDocumentInitializeAtMinimumScale)
    992 {
    993     UseMockScrollbarSettings mockScrollbarSettings;
    994 
    995     registerMockedHttpURLLoad("wide_document.html");
    996 
    997     FixedLayoutTestWebViewClient client;
    998     client.m_screenInfo.deviceScaleFactor = 1;
    999     int viewportWidth = 640;
   1000     int viewportHeight = 480;
   1001 
   1002     // Make sure we initialize to minimum scale, even if the window size
   1003     // only becomes available after the load begins.
   1004     FrameTestHelpers::WebViewHelper webViewHelper;
   1005     webViewHelper.initializeAndLoad(m_baseURL + "wide_document.html", true, 0, &client, enableViewportSettings);
   1006     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1007 
   1008     int wideDocumentWidth = 1500;
   1009     float minimumPageScaleFactor = viewportWidth / (float) wideDocumentWidth;
   1010     EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1011     EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->minimumPageScaleFactor());
   1012 
   1013     // Assume the user has pinch zoomed to page scale factor 2.
   1014     float userPinchPageScaleFactor = 2;
   1015     webViewHelper.webView()->setPageScaleFactor(userPinchPageScaleFactor);
   1016     webViewHelper.webView()->layout();
   1017 
   1018     // Make sure we don't reset to initial scale if the page continues to load.
   1019     webViewHelper.webViewImpl()->didCommitLoad(false, false);
   1020     webViewHelper.webViewImpl()->didChangeContentsSize();
   1021     EXPECT_EQ(userPinchPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1022 
   1023     // Make sure we don't reset to initial scale if the viewport size changes.
   1024     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight + 100));
   1025     EXPECT_EQ(userPinchPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1026 }
   1027 
   1028 TEST_F(WebFrameTest, DelayedViewportInitialScale)
   1029 {
   1030     UseMockScrollbarSettings mockScrollbarSettings;
   1031     registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
   1032 
   1033     FixedLayoutTestWebViewClient client;
   1034     client.m_screenInfo.deviceScaleFactor = 1;
   1035     int viewportWidth = 640;
   1036     int viewportHeight = 480;
   1037 
   1038     FrameTestHelpers::WebViewHelper webViewHelper;
   1039     webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
   1040     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1041 
   1042     EXPECT_EQ(0.25f, webViewHelper.webView()->pageScaleFactor());
   1043 
   1044     WebCore::Document* document = toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->document();
   1045     WebCore::ViewportDescription description = document->viewportDescription();
   1046     description.zoom = 2;
   1047     document->setViewportDescription(description);
   1048     webViewHelper.webView()->layout();
   1049     EXPECT_EQ(2, webViewHelper.webView()->pageScaleFactor());
   1050 }
   1051 
   1052 TEST_F(WebFrameTest, setLoadWithOverviewModeToFalse)
   1053 {
   1054     UseMockScrollbarSettings mockScrollbarSettings;
   1055     registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
   1056 
   1057     FixedLayoutTestWebViewClient client;
   1058     client.m_screenInfo.deviceScaleFactor = 1;
   1059     int viewportWidth = 640;
   1060     int viewportHeight = 480;
   1061 
   1062     FrameTestHelpers::WebViewHelper webViewHelper;
   1063     webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
   1064     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1065     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
   1066     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1067 
   1068     // The page must be displayed at 100% zoom.
   1069     EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
   1070 }
   1071 
   1072 TEST_F(WebFrameTest, SetLoadWithOverviewModeToFalseAndNoWideViewport)
   1073 {
   1074     UseMockScrollbarSettings mockScrollbarSettings;
   1075     registerMockedHttpURLLoad("large-div.html");
   1076 
   1077     FixedLayoutTestWebViewClient client;
   1078     client.m_screenInfo.deviceScaleFactor = 1;
   1079     int viewportWidth = 640;
   1080     int viewportHeight = 480;
   1081 
   1082     FrameTestHelpers::WebViewHelper webViewHelper;
   1083     webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client, enableViewportSettings);
   1084     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
   1085     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1086     webViewHelper.webView()->settings()->setUseWideViewport(false);
   1087     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1088 
   1089     // The page must be displayed at 100% zoom, despite that it hosts a wide div element.
   1090     EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
   1091 }
   1092 
   1093 TEST_F(WebFrameTest, NoWideViewportIgnoresPageViewportWidth)
   1094 {
   1095     UseMockScrollbarSettings mockScrollbarSettings;
   1096     registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
   1097 
   1098     FixedLayoutTestWebViewClient client;
   1099     client.m_screenInfo.deviceScaleFactor = 1;
   1100     int viewportWidth = 640;
   1101     int viewportHeight = 480;
   1102 
   1103     FrameTestHelpers::WebViewHelper webViewHelper;
   1104     webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
   1105     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1106     webViewHelper.webView()->settings()->setUseWideViewport(false);
   1107     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1108 
   1109     // The page sets viewport width to 3000, but with UseWideViewport == false is must be ignored.
   1110     EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
   1111     EXPECT_EQ(viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
   1112 }
   1113 
   1114 TEST_F(WebFrameTest, NoWideViewportIgnoresPageViewportWidthButAccountsScale)
   1115 {
   1116     UseMockScrollbarSettings mockScrollbarSettings;
   1117     registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");
   1118 
   1119     FixedLayoutTestWebViewClient client;
   1120     client.m_screenInfo.deviceScaleFactor = 1;
   1121     int viewportWidth = 640;
   1122     int viewportHeight = 480;
   1123 
   1124     FrameTestHelpers::WebViewHelper webViewHelper;
   1125     webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
   1126     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1127     webViewHelper.webView()->settings()->setUseWideViewport(false);
   1128     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1129 
   1130     // The page sets viewport width to 3000, but with UseWideViewport == false it must be ignored.
   1131     // While the initial scale specified by the page must be accounted.
   1132     EXPECT_EQ(viewportWidth / 2, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
   1133     EXPECT_EQ(viewportHeight / 2, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
   1134 }
   1135 
   1136 TEST_F(WebFrameTest, WideViewportSetsTo980WithoutViewportTag)
   1137 {
   1138     UseMockScrollbarSettings mockScrollbarSettings;
   1139     registerMockedHttpURLLoad("no_viewport_tag.html");
   1140 
   1141     FixedLayoutTestWebViewClient client;
   1142     client.m_screenInfo.deviceScaleFactor = 1;
   1143     int viewportWidth = 640;
   1144     int viewportHeight = 480;
   1145 
   1146     FrameTestHelpers::WebViewHelper webViewHelper;
   1147     webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
   1148     applyViewportStyleOverride(&webViewHelper);
   1149     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1150     webViewHelper.webView()->settings()->setUseWideViewport(true);
   1151     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1152 
   1153     EXPECT_EQ(980, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
   1154     EXPECT_EQ(980.0 / viewportWidth * viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
   1155 }
   1156 
   1157 TEST_F(WebFrameTest, NoWideViewportAndHeightInMeta)
   1158 {
   1159     UseMockScrollbarSettings mockScrollbarSettings;
   1160     registerMockedHttpURLLoad("viewport-height-1000.html");
   1161 
   1162     FixedLayoutTestWebViewClient client;
   1163     client.m_screenInfo.deviceScaleFactor = 1;
   1164     int viewportWidth = 640;
   1165     int viewportHeight = 480;
   1166 
   1167     FrameTestHelpers::WebViewHelper webViewHelper;
   1168     webViewHelper.initializeAndLoad(m_baseURL + "viewport-height-1000.html", true, 0, &client, enableViewportSettings);
   1169     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1170     webViewHelper.webView()->settings()->setUseWideViewport(false);
   1171     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1172 
   1173     EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
   1174 }
   1175 
   1176 TEST_F(WebFrameTest, WideViewportSetsTo980WithAutoWidth)
   1177 {
   1178     UseMockScrollbarSettings mockScrollbarSettings;
   1179     registerMockedHttpURLLoad("viewport-2x-initial-scale.html");
   1180 
   1181     FixedLayoutTestWebViewClient client;
   1182     client.m_screenInfo.deviceScaleFactor = 1;
   1183     int viewportWidth = 640;
   1184     int viewportHeight = 480;
   1185 
   1186     FrameTestHelpers::WebViewHelper webViewHelper;
   1187     webViewHelper.initializeAndLoad(m_baseURL + "viewport-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
   1188     applyViewportStyleOverride(&webViewHelper);
   1189     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1190     webViewHelper.webView()->settings()->setUseWideViewport(true);
   1191     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1192 
   1193     EXPECT_EQ(980, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
   1194     EXPECT_EQ(980.0 / viewportWidth * viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
   1195 }
   1196 
   1197 TEST_F(WebFrameTest, PageViewportInitialScaleOverridesLoadWithOverviewMode)
   1198 {
   1199     UseMockScrollbarSettings mockScrollbarSettings;
   1200     registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");
   1201 
   1202     FixedLayoutTestWebViewClient client;
   1203     client.m_screenInfo.deviceScaleFactor = 1;
   1204     int viewportWidth = 640;
   1205     int viewportHeight = 480;
   1206 
   1207     FrameTestHelpers::WebViewHelper webViewHelper;
   1208     webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
   1209     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
   1210     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1211 
   1212     // The page must be displayed at 200% zoom, as specified in its viewport meta tag.
   1213     EXPECT_EQ(2.0f, webViewHelper.webView()->pageScaleFactor());
   1214 }
   1215 
   1216 TEST_F(WebFrameTest, setInitialPageScaleFactorPermanently)
   1217 {
   1218     UseMockScrollbarSettings mockScrollbarSettings;
   1219 
   1220     registerMockedHttpURLLoad("fixed_layout.html");
   1221 
   1222     FixedLayoutTestWebViewClient client;
   1223     client.m_screenInfo.deviceScaleFactor = 1;
   1224     float enforcedPageScaleFactor = 2.0f;
   1225 
   1226     FrameTestHelpers::WebViewHelper webViewHelper;
   1227     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
   1228     applyViewportStyleOverride(&webViewHelper);
   1229     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1230     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
   1231     webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
   1232     webViewHelper.webView()->layout();
   1233 
   1234     EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1235 
   1236     int viewportWidth = 640;
   1237     int viewportHeight = 480;
   1238     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1239     webViewHelper.webView()->layout();
   1240 
   1241     EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1242 
   1243     webViewHelper.webView()->setInitialPageScaleOverride(-1);
   1244     webViewHelper.webView()->layout();
   1245     EXPECT_EQ(1.0, webViewHelper.webView()->pageScaleFactor());
   1246 }
   1247 
   1248 TEST_F(WebFrameTest, PermanentInitialPageScaleFactorOverridesLoadWithOverviewMode)
   1249 {
   1250     UseMockScrollbarSettings mockScrollbarSettings;
   1251     registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
   1252 
   1253     FixedLayoutTestWebViewClient client;
   1254     client.m_screenInfo.deviceScaleFactor = 1;
   1255     int viewportWidth = 640;
   1256     int viewportHeight = 480;
   1257     float enforcedPageScaleFactor = 0.5f;
   1258 
   1259     FrameTestHelpers::WebViewHelper webViewHelper;
   1260     webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
   1261     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
   1262     webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
   1263     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1264 
   1265     EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1266 }
   1267 
   1268 TEST_F(WebFrameTest, PermanentInitialPageScaleFactorOverridesPageViewportInitialScale)
   1269 {
   1270     UseMockScrollbarSettings mockScrollbarSettings;
   1271     registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");
   1272 
   1273     FixedLayoutTestWebViewClient client;
   1274     client.m_screenInfo.deviceScaleFactor = 1;
   1275     int viewportWidth = 640;
   1276     int viewportHeight = 480;
   1277     float enforcedPageScaleFactor = 0.5f;
   1278 
   1279     FrameTestHelpers::WebViewHelper webViewHelper;
   1280     webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
   1281     webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
   1282     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1283 
   1284     EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1285 }
   1286 
   1287 TEST_F(WebFrameTest, SmallPermanentInitialPageScaleFactorIsClobbered)
   1288 {
   1289     UseMockScrollbarSettings mockScrollbarSettings;
   1290     const char* pages[] = {
   1291         // These pages trigger the clobbering condition. There must be a matching item in "pageScaleFactors" array.
   1292         "viewport-device-0.5x-initial-scale.html",
   1293         "viewport-initial-scale-1.html",
   1294         // These ones do not.
   1295         "viewport-auto-initial-scale.html",
   1296         "viewport-target-densitydpi-device-and-fixed-width.html"
   1297     };
   1298     float pageScaleFactors[] = { 0.5f, 1.0f };
   1299     for (size_t i = 0; i < ARRAY_SIZE(pages); ++i)
   1300         registerMockedHttpURLLoad(pages[i]);
   1301 
   1302     FixedLayoutTestWebViewClient client;
   1303     client.m_screenInfo.deviceScaleFactor = 1;
   1304     int viewportWidth = 400;
   1305     int viewportHeight = 300;
   1306     float enforcedPageScaleFactor = 0.75f;
   1307 
   1308     for (size_t i = 0; i < ARRAY_SIZE(pages); ++i) {
   1309         for (int quirkEnabled = 0; quirkEnabled <= 1; ++quirkEnabled) {
   1310             FrameTestHelpers::WebViewHelper webViewHelper;
   1311             webViewHelper.initializeAndLoad(m_baseURL + pages[i], true, 0, &client, enableViewportSettings);
   1312             applyViewportStyleOverride(&webViewHelper);
   1313             webViewHelper.webView()->settings()->setClobberUserAgentInitialScaleQuirk(quirkEnabled);
   1314             webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
   1315             webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1316 
   1317             float expectedPageScaleFactor = quirkEnabled && i < ARRAY_SIZE(pageScaleFactors) ? pageScaleFactors[i] : enforcedPageScaleFactor;
   1318             EXPECT_EQ(expectedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1319         }
   1320     }
   1321 }
   1322 
   1323 TEST_F(WebFrameTest, PermanentInitialPageScaleFactorAffectsLayoutWidth)
   1324 {
   1325     UseMockScrollbarSettings mockScrollbarSettings;
   1326 
   1327     FixedLayoutTestWebViewClient client;
   1328     client.m_screenInfo.deviceScaleFactor = 1;
   1329     int viewportWidth = 640;
   1330     int viewportHeight = 480;
   1331     float enforcedPageScaleFactor = 0.5;
   1332 
   1333     FrameTestHelpers::WebViewHelper webViewHelper;
   1334     webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
   1335     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1336     webViewHelper.webView()->settings()->setUseWideViewport(false);
   1337     webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
   1338     webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
   1339     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1340 
   1341     EXPECT_EQ(viewportWidth / enforcedPageScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
   1342     EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1343 }
   1344 
   1345 TEST_F(WebFrameTest, WideViewportInitialScaleDoesNotExpandFixedLayoutWidth)
   1346 {
   1347     UseMockScrollbarSettings mockScrollbarSettings;
   1348     registerMockedHttpURLLoad("viewport-device-0.5x-initial-scale.html");
   1349 
   1350     FixedLayoutTestWebViewClient client;
   1351     client.m_screenInfo.deviceScaleFactor = 1;
   1352     int viewportWidth = 640;
   1353     int viewportHeight = 480;
   1354 
   1355     FrameTestHelpers::WebViewHelper webViewHelper;
   1356     webViewHelper.initializeAndLoad(m_baseURL + "viewport-device-0.5x-initial-scale.html", true, 0, &client, enableViewportSettings);
   1357     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1358     webViewHelper.webView()->settings()->setUseWideViewport(true);
   1359     webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
   1360     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1361 
   1362     EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
   1363     EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor());
   1364 
   1365     webViewHelper.webView()->setFixedLayoutSize(WebSize(2000, 1500));
   1366     webViewHelper.webView()->layout();
   1367     EXPECT_EQ(2000, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
   1368     EXPECT_EQ(0.5f, webViewHelper.webView()->pageScaleFactor());
   1369 }
   1370 
   1371 TEST_F(WebFrameTest, SetForceZeroLayoutHeight)
   1372 {
   1373     UseMockScrollbarSettings mockScrollbarSettings;
   1374     registerMockedHttpURLLoad("200-by-300.html");
   1375 
   1376     FixedLayoutTestWebViewClient client;
   1377     client.m_screenInfo.deviceScaleFactor = 1;
   1378     int viewportWidth = 640;
   1379     int viewportHeight = 480;
   1380 
   1381     FrameTestHelpers::WebViewHelper webViewHelper;
   1382 
   1383     webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, 0, &client, enableViewportSettings);
   1384     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1385     webViewHelper.webView()->layout();
   1386 
   1387     EXPECT_LE(viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1388     webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
   1389     EXPECT_TRUE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
   1390 
   1391     EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1392 
   1393     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight * 2));
   1394     EXPECT_FALSE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
   1395     EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1396 
   1397     webViewHelper.webView()->resize(WebSize(viewportWidth * 2, viewportHeight));
   1398     webViewHelper.webView()->layout();
   1399     EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1400 
   1401     webViewHelper.webView()->settings()->setForceZeroLayoutHeight(false);
   1402     EXPECT_LE(viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1403 }
   1404 
   1405 TEST_F(WebFrameTest, SetForceZeroLayoutHeightWorksAcrossNavigations)
   1406 {
   1407     UseMockScrollbarSettings mockScrollbarSettings;
   1408     registerMockedHttpURLLoad("200-by-300.html");
   1409     registerMockedHttpURLLoad("large-div.html");
   1410 
   1411     FixedLayoutTestWebViewClient client;
   1412     client.m_screenInfo.deviceScaleFactor = 1;
   1413     int viewportWidth = 640;
   1414     int viewportHeight = 480;
   1415 
   1416     FrameTestHelpers::WebViewHelper webViewHelper;
   1417 
   1418     webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, 0, &client, enableViewportSettings);
   1419     webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
   1420     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1421     webViewHelper.webView()->layout();
   1422 
   1423     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "large-div.html");
   1424     webViewHelper.webView()->layout();
   1425 
   1426     EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1427 }
   1428 
   1429 TEST_F(WebFrameTest, SetForceZeroLayoutHeightWithWideViewportQuirk)
   1430 {
   1431     UseMockScrollbarSettings mockScrollbarSettings;
   1432     registerMockedHttpURLLoad("200-by-300.html");
   1433 
   1434     FixedLayoutTestWebViewClient client;
   1435     client.m_screenInfo.deviceScaleFactor = 1;
   1436     int viewportWidth = 640;
   1437     int viewportHeight = 480;
   1438 
   1439     FrameTestHelpers::WebViewHelper webViewHelper;
   1440 
   1441     webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, 0, &client, enableViewportSettings);
   1442     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1443     webViewHelper.webView()->settings()->setUseWideViewport(true);
   1444     webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
   1445     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1446     webViewHelper.webView()->layout();
   1447 
   1448     EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1449 }
   1450 
   1451 TEST_F(WebFrameTest, WideViewportAndWideContentWithInitialScale)
   1452 {
   1453     UseMockScrollbarSettings mockScrollbarSettings;
   1454     registerMockedHttpURLLoad("wide_document_width_viewport.html");
   1455 
   1456     FixedLayoutTestWebViewClient client;
   1457     client.m_screenInfo.deviceScaleFactor = 1;
   1458     int viewportWidth = 600;
   1459     int viewportHeight = 800;
   1460 
   1461     FrameTestHelpers::WebViewHelper webViewHelper;
   1462     webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
   1463     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1464     webViewHelper.webView()->settings()->setUseWideViewport(true);
   1465     webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
   1466     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1467 
   1468     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "wide_document_width_viewport.html");
   1469     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1470 
   1471     int wideDocumentWidth = 800;
   1472     float minimumPageScaleFactor = viewportWidth / (float) wideDocumentWidth;
   1473     EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1474     EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->minimumPageScaleFactor());
   1475 }
   1476 
   1477 TEST_F(WebFrameTest, WideViewportQuirkClobbersHeight)
   1478 {
   1479     UseMockScrollbarSettings mockScrollbarSettings;
   1480     registerMockedHttpURLLoad("viewport-height-1000.html");
   1481 
   1482     FixedLayoutTestWebViewClient client;
   1483     client.m_screenInfo.deviceScaleFactor = 1;
   1484     int viewportWidth = 600;
   1485     int viewportHeight = 800;
   1486 
   1487     FrameTestHelpers::WebViewHelper webViewHelper;
   1488     webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
   1489     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1490     webViewHelper.webView()->settings()->setUseWideViewport(false);
   1491     webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
   1492     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1493 
   1494     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "viewport-height-1000.html");
   1495     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1496 
   1497     EXPECT_EQ(800, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1498     EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor());
   1499 }
   1500 
   1501 TEST_F(WebFrameTest, LayoutSize320Quirk)
   1502 {
   1503     UseMockScrollbarSettings mockScrollbarSettings;
   1504     registerMockedHttpURLLoad("viewport/viewport-30.html");
   1505 
   1506     FixedLayoutTestWebViewClient client;
   1507     client.m_screenInfo.deviceScaleFactor = 1;
   1508     int viewportWidth = 600;
   1509     int viewportHeight = 800;
   1510 
   1511     FrameTestHelpers::WebViewHelper webViewHelper;
   1512     webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
   1513     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1514     webViewHelper.webView()->settings()->setUseWideViewport(true);
   1515     webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
   1516     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1517 
   1518     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "viewport/viewport-30.html");
   1519     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1520 
   1521     EXPECT_EQ(600, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
   1522     EXPECT_EQ(800, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1523     EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor());
   1524 
   1525     // The magic number to snap to device-width is 320, so test that 321 is
   1526     // respected.
   1527     WebCore::Document* document = toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->document();
   1528     WebCore::ViewportDescription description = document->viewportDescription();
   1529     description.minWidth = WebCore::Length(321, WebCore::Fixed);
   1530     description.maxWidth = WebCore::Length(321, WebCore::Fixed);
   1531     document->setViewportDescription(description);
   1532     webViewHelper.webView()->layout();
   1533     EXPECT_EQ(321, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
   1534 
   1535     description.minWidth = WebCore::Length(320, WebCore::Fixed);
   1536     description.maxWidth = WebCore::Length(320, WebCore::Fixed);
   1537     document->setViewportDescription(description);
   1538     webViewHelper.webView()->layout();
   1539     EXPECT_EQ(600, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
   1540 
   1541     description = document->viewportDescription();
   1542     description.maxHeight = WebCore::Length(1000, WebCore::Fixed);
   1543     document->setViewportDescription(description);
   1544     webViewHelper.webView()->layout();
   1545     EXPECT_EQ(1000, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1546 
   1547     description.maxHeight = WebCore::Length(320, WebCore::Fixed);
   1548     document->setViewportDescription(description);
   1549     webViewHelper.webView()->layout();
   1550     EXPECT_EQ(800, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
   1551 }
   1552 
   1553 TEST_F(WebFrameTest, ZeroValuesQuirk)
   1554 {
   1555     UseMockScrollbarSettings mockScrollbarSettings;
   1556     registerMockedHttpURLLoad("viewport-zero-values.html");
   1557 
   1558     FixedLayoutTestWebViewClient client;
   1559     client.m_screenInfo.deviceScaleFactor = 1;
   1560     int viewportWidth = 640;
   1561     int viewportHeight = 480;
   1562 
   1563     FrameTestHelpers::WebViewHelper webViewHelper;
   1564     webViewHelper.initialize(true, 0, &client, enableViewportSettings);
   1565     webViewHelper.webView()->settings()->setViewportMetaZeroValuesQuirk(true);
   1566     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1567     webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
   1568     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "viewport-zero-values.html");
   1569     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1570 
   1571     EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
   1572     EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
   1573 
   1574     webViewHelper.webView()->settings()->setUseWideViewport(true);
   1575     webViewHelper.webView()->layout();
   1576     EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
   1577     EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
   1578 }
   1579 
   1580 TEST_F(WebFrameTest, OverflowHiddenDisablesScrolling)
   1581 {
   1582     registerMockedHttpURLLoad("body-overflow-hidden.html");
   1583 
   1584     FixedLayoutTestWebViewClient client;
   1585     client.m_screenInfo.deviceScaleFactor = 1;
   1586     int viewportWidth = 640;
   1587     int viewportHeight = 480;
   1588 
   1589     FrameTestHelpers::WebViewHelper webViewHelper;
   1590     webViewHelper.initialize(true, 0, &client);
   1591     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "body-overflow-hidden.html");
   1592     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1593 
   1594     WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
   1595     EXPECT_FALSE(view->userInputScrollable(WebCore::VerticalScrollbar));
   1596 }
   1597 
   1598 TEST_F(WebFrameTest, IgnoreOverflowHiddenQuirk)
   1599 {
   1600     registerMockedHttpURLLoad("body-overflow-hidden.html");
   1601 
   1602     FixedLayoutTestWebViewClient client;
   1603     client.m_screenInfo.deviceScaleFactor = 1;
   1604     int viewportWidth = 640;
   1605     int viewportHeight = 480;
   1606 
   1607     FrameTestHelpers::WebViewHelper webViewHelper;
   1608     webViewHelper.initialize(true, 0, &client);
   1609     webViewHelper.webView()->settings()->setIgnoreMainFrameOverflowHiddenQuirk(true);
   1610     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "body-overflow-hidden.html");
   1611     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1612 
   1613     WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
   1614     EXPECT_TRUE(view->userInputScrollable(WebCore::VerticalScrollbar));
   1615 }
   1616 
   1617 TEST_F(WebFrameTest, NonZeroValuesNoQuirk)
   1618 {
   1619     UseMockScrollbarSettings mockScrollbarSettings;
   1620     registerMockedHttpURLLoad("viewport-nonzero-values.html");
   1621 
   1622     FixedLayoutTestWebViewClient client;
   1623     client.m_screenInfo.deviceScaleFactor = 1;
   1624     int viewportWidth = 640;
   1625     int viewportHeight = 480;
   1626     float expectedPageScaleFactor = 0.5f;
   1627 
   1628     FrameTestHelpers::WebViewHelper webViewHelper;
   1629     webViewHelper.initialize(true, 0, &client, enableViewportSettings);
   1630     webViewHelper.webView()->settings()->setViewportMetaZeroValuesQuirk(true);
   1631     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1632     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "viewport-nonzero-values.html");
   1633     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1634 
   1635     EXPECT_EQ(viewportWidth / expectedPageScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
   1636     EXPECT_EQ(expectedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1637 
   1638     webViewHelper.webView()->settings()->setUseWideViewport(true);
   1639     webViewHelper.webView()->layout();
   1640     EXPECT_EQ(viewportWidth / expectedPageScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
   1641     EXPECT_EQ(expectedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
   1642 }
   1643 
   1644 TEST_F(WebFrameTest, setPageScaleFactorDoesNotLayout)
   1645 {
   1646     UseMockScrollbarSettings mockScrollbarSettings;
   1647     registerMockedHttpURLLoad("fixed_layout.html");
   1648 
   1649     FixedLayoutTestWebViewClient client;
   1650     client.m_screenInfo.deviceScaleFactor = 1;
   1651     // Small viewport to ensure there are always scrollbars.
   1652     int viewportWidth = 64;
   1653     int viewportHeight = 48;
   1654 
   1655     FrameTestHelpers::WebViewHelper webViewHelper;
   1656     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
   1657     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1658     webViewHelper.webView()->layout();
   1659 
   1660     int prevLayoutCount = webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
   1661     webViewHelper.webViewImpl()->setPageScaleFactor(3);
   1662     EXPECT_FALSE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
   1663     EXPECT_EQ(prevLayoutCount, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount());
   1664 }
   1665 
   1666 TEST_F(WebFrameTest, setPageScaleFactorWithOverlayScrollbarsDoesNotLayout)
   1667 {
   1668     UseMockScrollbarSettings mockScrollbarSettings;
   1669 
   1670     registerMockedHttpURLLoad("fixed_layout.html");
   1671 
   1672     FixedLayoutTestWebViewClient client;
   1673     client.m_screenInfo.deviceScaleFactor = 1;
   1674     int viewportWidth = 640;
   1675     int viewportHeight = 480;
   1676 
   1677     FrameTestHelpers::WebViewHelper webViewHelper;
   1678     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
   1679     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1680     webViewHelper.webView()->layout();
   1681 
   1682     int prevLayoutCount = webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
   1683     webViewHelper.webViewImpl()->setPageScaleFactor(30);
   1684     EXPECT_FALSE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
   1685     EXPECT_EQ(prevLayoutCount, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount());
   1686 
   1687 }
   1688 
   1689 TEST_F(WebFrameTest, pageScaleFactorWrittenToHistoryItem)
   1690 {
   1691     UseMockScrollbarSettings mockScrollbarSettings;
   1692     registerMockedHttpURLLoad("fixed_layout.html");
   1693 
   1694     FixedLayoutTestWebViewClient client;
   1695     client.m_screenInfo.deviceScaleFactor = 1;
   1696     int viewportWidth = 640;
   1697     int viewportHeight = 480;
   1698 
   1699     FrameTestHelpers::WebViewHelper webViewHelper;
   1700     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
   1701     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1702     webViewHelper.webView()->layout();
   1703 
   1704     webViewHelper.webView()->setPageScaleFactor(3);
   1705     EXPECT_EQ(3, toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->loader().currentItem()->pageScaleFactor());
   1706 }
   1707 
   1708 TEST_F(WebFrameTest, initialScaleWrittenToHistoryItem)
   1709 {
   1710     UseMockScrollbarSettings mockScrollbarSettings;
   1711     registerMockedHttpURLLoad("fixed_layout.html");
   1712 
   1713     FixedLayoutTestWebViewClient client;
   1714     client.m_screenInfo.deviceScaleFactor = 1;
   1715     int viewportWidth = 640;
   1716     int viewportHeight = 480;
   1717 
   1718     FrameTestHelpers::WebViewHelper webViewHelper;
   1719     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
   1720     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1721     webViewHelper.webView()->layout();
   1722 
   1723     int defaultFixedLayoutWidth = 980;
   1724     float minimumPageScaleFactor = viewportWidth / (float) defaultFixedLayoutWidth;
   1725     EXPECT_EQ(minimumPageScaleFactor, toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->loader().currentItem()->pageScaleFactor());
   1726 }
   1727 
   1728 TEST_F(WebFrameTest, pageScaleFactorShrinksViewport)
   1729 {
   1730     UseMockScrollbarSettings mockScrollbarSettings;
   1731     registerMockedHttpURLLoad("large-div.html");
   1732 
   1733     FixedLayoutTestWebViewClient client;
   1734     client.m_screenInfo.deviceScaleFactor = 1;
   1735     // Small viewport to ensure there are always scrollbars.
   1736     int viewportWidth = 64;
   1737     int viewportHeight = 48;
   1738 
   1739     FrameTestHelpers::WebViewHelper webViewHelper;
   1740     webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client, enableViewportSettings);
   1741     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1742     webViewHelper.webView()->layout();
   1743 
   1744     WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
   1745     int viewportWidthMinusScrollbar = viewportWidth - (view->verticalScrollbar()->isOverlayScrollbar() ? 0 : 15);
   1746     int viewportHeightMinusScrollbar = viewportHeight - (view->horizontalScrollbar()->isOverlayScrollbar() ? 0 : 15);
   1747 
   1748     webViewHelper.webView()->setPageScaleFactor(2);
   1749 
   1750     WebCore::IntSize unscaledSize = view->unscaledVisibleContentSize(WebCore::IncludeScrollbars);
   1751     EXPECT_EQ(viewportWidth, unscaledSize.width());
   1752     EXPECT_EQ(viewportHeight, unscaledSize.height());
   1753 
   1754     WebCore::IntSize unscaledSizeMinusScrollbar = view->unscaledVisibleContentSize(WebCore::ExcludeScrollbars);
   1755     EXPECT_EQ(viewportWidthMinusScrollbar, unscaledSizeMinusScrollbar.width());
   1756     EXPECT_EQ(viewportHeightMinusScrollbar, unscaledSizeMinusScrollbar.height());
   1757 
   1758     WebCore::IntSize scaledSize = view->visibleContentRect().size();
   1759     EXPECT_EQ(ceil(viewportWidthMinusScrollbar / 2.0), scaledSize.width());
   1760     EXPECT_EQ(ceil(viewportHeightMinusScrollbar / 2.0), scaledSize.height());
   1761 }
   1762 
   1763 TEST_F(WebFrameTest, pageScaleFactorDoesNotApplyCssTransform)
   1764 {
   1765     UseMockScrollbarSettings mockScrollbarSettings;
   1766     registerMockedHttpURLLoad("fixed_layout.html");
   1767 
   1768     FixedLayoutTestWebViewClient client;
   1769     client.m_screenInfo.deviceScaleFactor = 1;
   1770     int viewportWidth = 640;
   1771     int viewportHeight = 480;
   1772 
   1773     FrameTestHelpers::WebViewHelper webViewHelper;
   1774     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
   1775     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1776     webViewHelper.webView()->layout();
   1777 
   1778     webViewHelper.webView()->setPageScaleFactor(2);
   1779 
   1780     EXPECT_EQ(980, toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->contentRenderer()->unscaledDocumentRect().width());
   1781     EXPECT_EQ(980, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
   1782 }
   1783 
   1784 TEST_F(WebFrameTest, targetDensityDpiHigh)
   1785 {
   1786     UseMockScrollbarSettings mockScrollbarSettings;
   1787     registerMockedHttpURLLoad("viewport-target-densitydpi-high.html");
   1788 
   1789     FixedLayoutTestWebViewClient client;
   1790     // high-dpi = 240
   1791     float targetDpi = 240.0f;
   1792     float deviceScaleFactors[] = { 1.0f, 4.0f / 3.0f, 2.0f };
   1793     int viewportWidth = 640;
   1794     int viewportHeight = 480;
   1795 
   1796     for (size_t i = 0; i < ARRAY_SIZE(deviceScaleFactors); ++i) {
   1797         float deviceScaleFactor = deviceScaleFactors[i];
   1798         float deviceDpi = deviceScaleFactor * 160.0f;
   1799         client.m_screenInfo.deviceScaleFactor = deviceScaleFactor;
   1800 
   1801         FrameTestHelpers::WebViewHelper webViewHelper;
   1802         webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-high.html", true, 0, &client, enableViewportSettings);
   1803         webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1804         webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
   1805         webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1806 
   1807         // We need to account for the fact that logical pixels are unconditionally multiplied by deviceScaleFactor to produce
   1808         // physical pixels.
   1809         float densityDpiScaleRatio = deviceScaleFactor * targetDpi / deviceDpi;
   1810         EXPECT_NEAR(viewportWidth * densityDpiScaleRatio, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
   1811         EXPECT_NEAR(viewportHeight * densityDpiScaleRatio, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f);
   1812         EXPECT_NEAR(1.0f / densityDpiScaleRatio, webViewHelper.webView()->pageScaleFactor(), 0.01f);
   1813     }
   1814 }
   1815 
   1816 TEST_F(WebFrameTest, targetDensityDpiDevice)
   1817 {
   1818     UseMockScrollbarSettings mockScrollbarSettings;
   1819     registerMockedHttpURLLoad("viewport-target-densitydpi-device.html");
   1820 
   1821     float deviceScaleFactors[] = { 1.0f, 4.0f / 3.0f, 2.0f };
   1822 
   1823     FixedLayoutTestWebViewClient client;
   1824     int viewportWidth = 640;
   1825     int viewportHeight = 480;
   1826 
   1827     for (size_t i = 0; i < ARRAY_SIZE(deviceScaleFactors); ++i) {
   1828         client.m_screenInfo.deviceScaleFactor = deviceScaleFactors[i];
   1829 
   1830         FrameTestHelpers::WebViewHelper webViewHelper;
   1831         webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-device.html", true, 0, &client, enableViewportSettings);
   1832         webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1833         webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
   1834         webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1835 
   1836         EXPECT_NEAR(viewportWidth * client.m_screenInfo.deviceScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
   1837         EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f);
   1838         EXPECT_NEAR(1.0f / client.m_screenInfo.deviceScaleFactor, webViewHelper.webView()->pageScaleFactor(), 0.01f);
   1839     }
   1840 }
   1841 
   1842 TEST_F(WebFrameTest, targetDensityDpiDeviceAndFixedWidth)
   1843 {
   1844     UseMockScrollbarSettings mockScrollbarSettings;
   1845     registerMockedHttpURLLoad("viewport-target-densitydpi-device-and-fixed-width.html");
   1846 
   1847     float deviceScaleFactors[] = { 1.0f, 4.0f / 3.0f, 2.0f };
   1848 
   1849     FixedLayoutTestWebViewClient client;
   1850     int viewportWidth = 640;
   1851     int viewportHeight = 480;
   1852 
   1853     for (size_t i = 0; i < ARRAY_SIZE(deviceScaleFactors); ++i) {
   1854         client.m_screenInfo.deviceScaleFactor = deviceScaleFactors[i];
   1855 
   1856         FrameTestHelpers::WebViewHelper webViewHelper;
   1857         webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-device-and-fixed-width.html", true, 0, &client, enableViewportSettings);
   1858         webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1859         webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
   1860         webViewHelper.webView()->settings()->setUseWideViewport(true);
   1861         webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1862 
   1863         EXPECT_NEAR(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
   1864         EXPECT_NEAR(viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f);
   1865         EXPECT_NEAR(1.0f, webViewHelper.webView()->pageScaleFactor(), 0.01f);
   1866     }
   1867 }
   1868 
   1869 TEST_F(WebFrameTest, NoWideViewportAndScaleLessThanOne)
   1870 {
   1871     UseMockScrollbarSettings mockScrollbarSettings;
   1872     registerMockedHttpURLLoad("viewport-initial-scale-less-than-1.html");
   1873 
   1874     FixedLayoutTestWebViewClient client;
   1875     client.m_screenInfo.deviceScaleFactor = 1.33f;
   1876     int viewportWidth = 640;
   1877     int viewportHeight = 480;
   1878 
   1879     FrameTestHelpers::WebViewHelper webViewHelper;
   1880     webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-less-than-1.html", true, 0, &client, enableViewportSettings);
   1881     webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
   1882     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1883     webViewHelper.webView()->settings()->setUseWideViewport(false);
   1884     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1885     webViewHelper.webView()->layout();
   1886 
   1887     EXPECT_NEAR(viewportWidth * client.m_screenInfo.deviceScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
   1888     EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f);
   1889     EXPECT_NEAR(1.0f / client.m_screenInfo.deviceScaleFactor, webViewHelper.webView()->pageScaleFactor(), 0.01f);
   1890 }
   1891 
   1892 TEST_F(WebFrameTest, NoWideViewportAndScaleLessThanOneWithDeviceWidth)
   1893 {
   1894     UseMockScrollbarSettings mockScrollbarSettings;
   1895     registerMockedHttpURLLoad("viewport-initial-scale-less-than-1-device-width.html");
   1896 
   1897     FixedLayoutTestWebViewClient client;
   1898     client.m_screenInfo.deviceScaleFactor = 1.33f;
   1899     int viewportWidth = 640;
   1900     int viewportHeight = 480;
   1901 
   1902     FrameTestHelpers::WebViewHelper webViewHelper;
   1903     webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-less-than-1-device-width.html", true, 0, &client, enableViewportSettings);
   1904     webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
   1905     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1906     webViewHelper.webView()->settings()->setUseWideViewport(false);
   1907     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1908     webViewHelper.webView()->layout();
   1909 
   1910     const float pageZoom = 0.25f;
   1911     EXPECT_NEAR(viewportWidth * client.m_screenInfo.deviceScaleFactor / pageZoom, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
   1912     EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor / pageZoom, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f);
   1913     EXPECT_NEAR(1.0f / client.m_screenInfo.deviceScaleFactor, webViewHelper.webView()->pageScaleFactor(), 0.01f);
   1914 }
   1915 
   1916 TEST_F(WebFrameTest, NoWideViewportAndNoViewportWithInitialPageScaleOverride)
   1917 {
   1918     UseMockScrollbarSettings mockScrollbarSettings;
   1919     registerMockedHttpURLLoad("large-div.html");
   1920 
   1921     FixedLayoutTestWebViewClient client;
   1922     int viewportWidth = 640;
   1923     int viewportHeight = 480;
   1924     float enforcedPageScaleFactor = 5.0f;
   1925 
   1926     FrameTestHelpers::WebViewHelper webViewHelper;
   1927     webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client, enableViewportSettings);
   1928     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1929     webViewHelper.webView()->settings()->setUseWideViewport(false);
   1930     webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
   1931     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1932     webViewHelper.webView()->layout();
   1933 
   1934     EXPECT_NEAR(viewportWidth / enforcedPageScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
   1935     EXPECT_NEAR(viewportHeight / enforcedPageScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f);
   1936     EXPECT_NEAR(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor(), 0.01f);
   1937 }
   1938 
   1939 TEST_F(WebFrameTest, NoUserScalableQuirkIgnoresViewportScale)
   1940 {
   1941     UseMockScrollbarSettings mockScrollbarSettings;
   1942     registerMockedHttpURLLoad("viewport-initial-scale-and-user-scalable-no.html");
   1943 
   1944     FixedLayoutTestWebViewClient client;
   1945     int viewportWidth = 640;
   1946     int viewportHeight = 480;
   1947 
   1948     FrameTestHelpers::WebViewHelper webViewHelper;
   1949     webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-and-user-scalable-no.html", true, 0, &client, enableViewportSettings);
   1950     webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
   1951     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1952     webViewHelper.webView()->layout();
   1953 
   1954     EXPECT_NEAR(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
   1955     EXPECT_NEAR(viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f);
   1956     EXPECT_NEAR(1.0f, webViewHelper.webView()->pageScaleFactor(), 0.01f);
   1957 }
   1958 
   1959 TEST_F(WebFrameTest, NoUserScalableQuirkIgnoresViewportScaleForNonWideViewport)
   1960 {
   1961     UseMockScrollbarSettings mockScrollbarSettings;
   1962     registerMockedHttpURLLoad("viewport-initial-scale-and-user-scalable-no.html");
   1963 
   1964     FixedLayoutTestWebViewClient client;
   1965     client.m_screenInfo.deviceScaleFactor = 1.33f;
   1966     int viewportWidth = 640;
   1967     int viewportHeight = 480;
   1968 
   1969     FrameTestHelpers::WebViewHelper webViewHelper;
   1970     webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-and-user-scalable-no.html", true, 0, &client, enableViewportSettings);
   1971     webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
   1972     webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
   1973     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1974     webViewHelper.webView()->settings()->setUseWideViewport(false);
   1975     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1976     webViewHelper.webView()->layout();
   1977 
   1978     EXPECT_NEAR(viewportWidth * client.m_screenInfo.deviceScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
   1979     EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f);
   1980     EXPECT_NEAR(1.0f / client.m_screenInfo.deviceScaleFactor, webViewHelper.webView()->pageScaleFactor(), 0.01f);
   1981 }
   1982 
   1983 TEST_F(WebFrameTest, NoUserScalableQuirkIgnoresViewportScaleForWideViewport)
   1984 {
   1985     UseMockScrollbarSettings mockScrollbarSettings;
   1986     registerMockedHttpURLLoad("viewport-2x-initial-scale-non-user-scalable.html");
   1987 
   1988     FixedLayoutTestWebViewClient client;
   1989     int viewportWidth = 640;
   1990     int viewportHeight = 480;
   1991 
   1992     FrameTestHelpers::WebViewHelper webViewHelper;
   1993     webViewHelper.initializeAndLoad(m_baseURL + "viewport-2x-initial-scale-non-user-scalable.html", true, 0, &client, enableViewportSettings);
   1994     webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
   1995     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   1996     webViewHelper.webView()->settings()->setUseWideViewport(true);
   1997     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   1998 
   1999     EXPECT_NEAR(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
   2000     EXPECT_NEAR(viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f);
   2001     EXPECT_NEAR(1.0f, webViewHelper.webView()->pageScaleFactor(), 0.01f);
   2002 }
   2003 
   2004 TEST_F(WebFrameTest, DesktopPageCanBeZoomedInWhenWideViewportIsTurnedOff)
   2005 {
   2006     UseMockScrollbarSettings mockScrollbarSettings;
   2007     registerMockedHttpURLLoad("no_viewport_tag.html");
   2008 
   2009     FixedLayoutTestWebViewClient client;
   2010     int viewportWidth = 640;
   2011     int viewportHeight = 480;
   2012 
   2013     FrameTestHelpers::WebViewHelper webViewHelper;
   2014     webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
   2015     webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
   2016     webViewHelper.webView()->settings()->setUseWideViewport(false);
   2017     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2018 
   2019     EXPECT_NEAR(1.0f, webViewHelper.webView()->pageScaleFactor(), 0.01f);
   2020     EXPECT_NEAR(1.0f, webViewHelper.webView()->minimumPageScaleFactor(), 0.01f);
   2021     EXPECT_NEAR(5.0f, webViewHelper.webView()->maximumPageScaleFactor(), 0.01f);
   2022 }
   2023 
   2024 class WebFrameResizeTest : public WebFrameTest {
   2025 protected:
   2026 
   2027     static WebCore::FloatSize computeRelativeOffset(const WebCore::IntPoint& absoluteOffset, const WebCore::LayoutRect& rect)
   2028     {
   2029         WebCore::FloatSize relativeOffset = WebCore::FloatPoint(absoluteOffset) - rect.location();
   2030         relativeOffset.scale(1.f / rect.width(), 1.f / rect.height());
   2031         return relativeOffset;
   2032     }
   2033 
   2034     void testResizeYieldsCorrectScrollAndScale(const char* url,
   2035                                                const float initialPageScaleFactor,
   2036                                                const WebSize scrollOffset,
   2037                                                const WebSize viewportSize,
   2038                                                const bool shouldScaleRelativeToViewportWidth) {
   2039         UseMockScrollbarSettings mockScrollbarSettings;
   2040         registerMockedHttpURLLoad(url);
   2041 
   2042         const float aspectRatio = static_cast<float>(viewportSize.width) / viewportSize.height;
   2043 
   2044         FrameTestHelpers::WebViewHelper webViewHelper;
   2045         webViewHelper.initializeAndLoad(m_baseURL + url, true, 0, 0, enableViewportSettings);
   2046 
   2047         // Origin scrollOffsets preserved under resize.
   2048         {
   2049             webViewHelper.webViewImpl()->resize(WebSize(viewportSize.width, viewportSize.height));
   2050             webViewHelper.webViewImpl()->setPageScaleFactor(initialPageScaleFactor);
   2051             ASSERT_EQ(viewportSize, webViewHelper.webViewImpl()->size());
   2052             ASSERT_EQ(initialPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor());
   2053             webViewHelper.webViewImpl()->resize(WebSize(viewportSize.height, viewportSize.width));
   2054             float expectedPageScaleFactor = initialPageScaleFactor * (shouldScaleRelativeToViewportWidth ? 1 / aspectRatio : 1);
   2055             EXPECT_NEAR(expectedPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor(), 0.05f);
   2056             EXPECT_EQ(WebSize(), webViewHelper.webViewImpl()->mainFrame()->scrollOffset());
   2057         }
   2058 
   2059         // Resizing just the height should not affect pageScaleFactor or scrollOffset.
   2060         {
   2061             webViewHelper.webViewImpl()->resize(WebSize(viewportSize.width, viewportSize.height));
   2062             webViewHelper.webViewImpl()->setPageScaleFactor(initialPageScaleFactor);
   2063             webViewHelper.webViewImpl()->setMainFrameScrollOffset(WebPoint(scrollOffset.width, scrollOffset.height));
   2064             webViewHelper.webViewImpl()->layout();
   2065             const WebSize expectedScrollOffset = webViewHelper.webViewImpl()->mainFrame()->scrollOffset();
   2066             webViewHelper.webViewImpl()->resize(WebSize(viewportSize.width, viewportSize.height * 0.8f));
   2067             EXPECT_EQ(initialPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor());
   2068             EXPECT_EQ(expectedScrollOffset, webViewHelper.webViewImpl()->mainFrame()->scrollOffset());
   2069             webViewHelper.webViewImpl()->resize(WebSize(viewportSize.width, viewportSize.height * 0.8f));
   2070             EXPECT_EQ(initialPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor());
   2071             EXPECT_EQ(expectedScrollOffset, webViewHelper.webViewImpl()->mainFrame()->scrollOffset());
   2072         }
   2073 
   2074         // Generic resize preserves scrollOffset relative to anchor node located
   2075         // the top center of the screen.
   2076         {
   2077             webViewHelper.webViewImpl()->resize(WebSize(viewportSize.height, viewportSize.width));
   2078             float pageScaleFactor = webViewHelper.webViewImpl()->pageScaleFactor();
   2079             webViewHelper.webViewImpl()->resize(WebSize(viewportSize.width, viewportSize.height));
   2080             float expectedPageScaleFactor = pageScaleFactor * (shouldScaleRelativeToViewportWidth ? aspectRatio : 1);
   2081             EXPECT_NEAR(expectedPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor(), 0.05f);
   2082             webViewHelper.webViewImpl()->mainFrame()->setScrollOffset(scrollOffset);
   2083 
   2084             WebCore::IntPoint anchorPoint = WebCore::IntPoint(scrollOffset) + WebCore::IntPoint(viewportSize.width / 2, 0);
   2085             RefPtrWillBeRawPtr<WebCore::Node> anchorNode = webViewHelper.webViewImpl()->mainFrameImpl()->frame()->eventHandler().hitTestResultAtPoint(anchorPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent).innerNode();
   2086             ASSERT(anchorNode);
   2087 
   2088             pageScaleFactor = webViewHelper.webViewImpl()->pageScaleFactor();
   2089             const WebCore::FloatSize preResizeRelativeOffset
   2090                 = computeRelativeOffset(anchorPoint, anchorNode->boundingBox());
   2091             webViewHelper.webViewImpl()->resize(WebSize(viewportSize.height, viewportSize.width));
   2092             WebCore::IntPoint newAnchorPoint = WebCore::IntPoint(webViewHelper.webViewImpl()->mainFrame()->scrollOffset()) + WebCore::IntPoint(viewportSize.height / 2, 0);
   2093             const WebCore::FloatSize postResizeRelativeOffset
   2094                 = computeRelativeOffset(newAnchorPoint, anchorNode->boundingBox());
   2095             EXPECT_NEAR(preResizeRelativeOffset.width(), postResizeRelativeOffset.width(), 0.15f);
   2096             expectedPageScaleFactor = pageScaleFactor * (shouldScaleRelativeToViewportWidth ? 1 / aspectRatio : 1);
   2097             EXPECT_NEAR(expectedPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor(), 0.05f);
   2098         }
   2099     }
   2100 };
   2101 
   2102 TEST_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForWidthEqualsDeviceWidth)
   2103 {
   2104     // With width=device-width, pageScaleFactor is preserved across resizes as
   2105     // long as the content adjusts according to the device-width.
   2106     const char* url = "resize_scroll_mobile.html";
   2107     const float initialPageScaleFactor = 1;
   2108     const WebSize scrollOffset(0, 50);
   2109     const WebSize viewportSize(120, 160);
   2110     const bool shouldScaleRelativeToViewportWidth = true;
   2111 
   2112     testResizeYieldsCorrectScrollAndScale(
   2113         url, initialPageScaleFactor, scrollOffset, viewportSize, shouldScaleRelativeToViewportWidth);
   2114 }
   2115 
   2116 TEST_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForFixedWidth)
   2117 {
   2118     // With a fixed width, pageScaleFactor scales by the relative change in viewport width.
   2119     const char* url = "resize_scroll_fixed_width.html";
   2120     const float initialPageScaleFactor = 2;
   2121     const WebSize scrollOffset(0, 200);
   2122     const WebSize viewportSize(240, 320);
   2123     const bool shouldScaleRelativeToViewportWidth = true;
   2124 
   2125     testResizeYieldsCorrectScrollAndScale(
   2126         url, initialPageScaleFactor, scrollOffset, viewportSize, shouldScaleRelativeToViewportWidth);
   2127 }
   2128 
   2129 TEST_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForFixedLayout)
   2130 {
   2131     // With a fixed layout, pageScaleFactor scales by the relative change in viewport width.
   2132     const char* url = "resize_scroll_fixed_layout.html";
   2133     const float initialPageScaleFactor = 2;
   2134     const WebSize scrollOffset(200, 400);
   2135     const WebSize viewportSize(320, 240);
   2136     const bool shouldScaleRelativeToViewportWidth = true;
   2137 
   2138     testResizeYieldsCorrectScrollAndScale(
   2139         url, initialPageScaleFactor, scrollOffset, viewportSize, shouldScaleRelativeToViewportWidth);
   2140 }
   2141 
   2142 TEST_F(WebFrameTest, pageScaleFactorScalesPaintClip)
   2143 {
   2144     UseMockScrollbarSettings mockScrollbarSettings;
   2145     registerMockedHttpURLLoad("large-div.html");
   2146 
   2147     FixedLayoutTestWebViewClient client;
   2148     client.m_screenInfo.deviceScaleFactor = 1;
   2149     int viewportWidth = 50;
   2150     int viewportHeight = 50;
   2151 
   2152     FrameTestHelpers::WebViewHelper webViewHelper;
   2153     webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client);
   2154     // FIXME: This test breaks if the viewport is enabled before loading the page due to the paint
   2155     // calls below not working on composited layers. For some reason, enabling the viewport here
   2156     // doesn't cause compositing
   2157     webViewHelper.webView()->settings()->setViewportEnabled(true);
   2158     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2159     webViewHelper.webView()->layout();
   2160 
   2161     // Set <1 page scale so that the clip rect should be larger than
   2162     // the viewport size as passed into resize().
   2163     webViewHelper.webView()->setPageScaleFactor(0.5);
   2164 
   2165     SkBitmap bitmap;
   2166     ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
   2167     bitmap.eraseColor(0);
   2168     SkCanvas canvas(bitmap);
   2169 
   2170     WebCore::GraphicsContext context(&canvas);
   2171     context.setTrackOpaqueRegion(true);
   2172 
   2173     EXPECT_EQ_RECT(WebCore::IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
   2174 
   2175     WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
   2176     WebCore::IntRect paintRect(0, 0, 200, 200);
   2177     view->paint(&context, paintRect);
   2178 
   2179     // FIXME: This test broke in release builds when changing the FixedLayoutTestWebViewClient
   2180     // to return a non-null layerTreeView, which is what all our shipping configurations do,
   2181     // so this is just exposing an existing bug.
   2182     // crbug.com/365812
   2183 #ifndef NDEBUG
   2184     int viewportWidthMinusScrollbar = 50 - (view->verticalScrollbar()->isOverlayScrollbar() ? 0 : 15);
   2185     int viewportHeightMinusScrollbar = 50 - (view->horizontalScrollbar()->isOverlayScrollbar() ? 0 : 15);
   2186     WebCore::IntRect clippedRect(0, 0, viewportWidthMinusScrollbar * 2, viewportHeightMinusScrollbar * 2);
   2187     EXPECT_EQ_RECT(clippedRect, context.opaqueRegion().asRect());
   2188 #endif
   2189 }
   2190 
   2191 TEST_F(WebFrameTest, pageScaleFactorUpdatesScrollbars)
   2192 {
   2193     UseMockScrollbarSettings mockScrollbarSettings;
   2194     registerMockedHttpURLLoad("fixed_layout.html");
   2195 
   2196     FixedLayoutTestWebViewClient client;
   2197     client.m_screenInfo.deviceScaleFactor = 1;
   2198     int viewportWidth = 640;
   2199     int viewportHeight = 480;
   2200 
   2201     FrameTestHelpers::WebViewHelper webViewHelper;
   2202     webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
   2203     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2204     webViewHelper.webView()->layout();
   2205 
   2206     WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
   2207     EXPECT_EQ(view->scrollSize(WebCore::HorizontalScrollbar), view->contentsSize().width() - view->visibleContentRect().width());
   2208     EXPECT_EQ(view->scrollSize(WebCore::VerticalScrollbar), view->contentsSize().height() - view->visibleContentRect().height());
   2209 
   2210     webViewHelper.webView()->setPageScaleFactor(10);
   2211 
   2212     EXPECT_EQ(view->scrollSize(WebCore::HorizontalScrollbar), view->contentsSize().width() - view->visibleContentRect().width());
   2213     EXPECT_EQ(view->scrollSize(WebCore::VerticalScrollbar), view->contentsSize().height() - view->visibleContentRect().height());
   2214 }
   2215 
   2216 TEST_F(WebFrameTest, CanOverrideScaleLimits)
   2217 {
   2218     UseMockScrollbarSettings mockScrollbarSettings;
   2219 
   2220     registerMockedHttpURLLoad("no_scale_for_you.html");
   2221 
   2222     FixedLayoutTestWebViewClient client;
   2223     client.m_screenInfo.deviceScaleFactor = 1;
   2224     int viewportWidth = 640;
   2225     int viewportHeight = 480;
   2226 
   2227     FrameTestHelpers::WebViewHelper webViewHelper;
   2228     webViewHelper.initializeAndLoad(m_baseURL + "no_scale_for_you.html", true, 0, &client, enableViewportSettings);
   2229     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2230 
   2231     EXPECT_EQ(2.0f, webViewHelper.webView()->minimumPageScaleFactor());
   2232     EXPECT_EQ(2.0f, webViewHelper.webView()->maximumPageScaleFactor());
   2233 
   2234     webViewHelper.webView()->setIgnoreViewportTagScaleLimits(true);
   2235     webViewHelper.webView()->layout();
   2236 
   2237     EXPECT_EQ(1.0f, webViewHelper.webView()->minimumPageScaleFactor());
   2238     EXPECT_EQ(5.0f, webViewHelper.webView()->maximumPageScaleFactor());
   2239 
   2240     webViewHelper.webView()->setIgnoreViewportTagScaleLimits(false);
   2241     webViewHelper.webView()->layout();
   2242 
   2243     EXPECT_EQ(2.0f, webViewHelper.webView()->minimumPageScaleFactor());
   2244     EXPECT_EQ(2.0f, webViewHelper.webView()->maximumPageScaleFactor());
   2245 }
   2246 
   2247 TEST_F(WebFrameTest, updateOverlayScrollbarLayers)
   2248 {
   2249     UseMockScrollbarSettings mockScrollbarSettings;
   2250 
   2251     registerMockedHttpURLLoad("large-div.html");
   2252 
   2253     int viewWidth = 500;
   2254     int viewHeight = 500;
   2255 
   2256     OwnPtr<FakeCompositingWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FakeCompositingWebViewClient());
   2257     FrameTestHelpers::WebViewHelper webViewHelper;
   2258     webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
   2259 
   2260     webViewHelper.webView()->setPageScaleFactorLimits(1, 1);
   2261     webViewHelper.webView()->resize(WebSize(viewWidth, viewHeight));
   2262     FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "large-div.html");
   2263 
   2264     WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
   2265     EXPECT_TRUE(view->renderView()->compositor()->layerForHorizontalScrollbar());
   2266     EXPECT_TRUE(view->renderView()->compositor()->layerForVerticalScrollbar());
   2267 
   2268     webViewHelper.webView()->resize(WebSize(viewWidth * 10, viewHeight * 10));
   2269     webViewHelper.webView()->layout();
   2270     EXPECT_FALSE(view->renderView()->compositor()->layerForHorizontalScrollbar());
   2271     EXPECT_FALSE(view->renderView()->compositor()->layerForVerticalScrollbar());
   2272 }
   2273 
   2274 void setScaleAndScrollAndLayout(blink::WebView* webView, WebPoint scroll, float scale)
   2275 {
   2276     webView->setPageScaleFactor(scale);
   2277     webView->setMainFrameScrollOffset(WebPoint(scroll.x, scroll.y));
   2278     webView->layout();
   2279 }
   2280 
   2281 TEST_F(WebFrameTest, DivAutoZoomParamsTest)
   2282 {
   2283     registerMockedHttpURLLoad("get_scale_for_auto_zoom_into_div_test.html");
   2284 
   2285     const float deviceScaleFactor = 2.0f;
   2286     int viewportWidth = 640 / deviceScaleFactor;
   2287     int viewportHeight = 1280 / deviceScaleFactor;
   2288     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
   2289     FrameTestHelpers::WebViewHelper webViewHelper;
   2290     webViewHelper.initializeAndLoad(m_baseURL + "get_scale_for_auto_zoom_into_div_test.html");
   2291     webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
   2292     webViewHelper.webView()->setPageScaleFactorLimits(0.01f, 4);
   2293     webViewHelper.webView()->setPageScaleFactor(0.5f);
   2294     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2295     webViewHelper.webView()->layout();
   2296 
   2297     WebRect wideDiv(200, 100, 400, 150);
   2298     WebRect tallDiv(200, 300, 400, 800);
   2299     WebRect doubleTapPointWide(wideDiv.x + 50, wideDiv.y + 50, touchPointPadding, touchPointPadding);
   2300     WebRect doubleTapPointTall(tallDiv.x + 50, tallDiv.y + 50, touchPointPadding, touchPointPadding);
   2301     WebRect wideBlockBounds;
   2302     WebRect tallBlockBounds;
   2303     float scale;
   2304     WebPoint scroll;
   2305 
   2306     float doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
   2307 
   2308     // Test double-tap zooming into wide div.
   2309     wideBlockBounds = webViewHelper.webViewImpl()->computeBlockBounds(doubleTapPointWide, false);
   2310     webViewHelper.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(doubleTapPointWide.x, doubleTapPointWide.y), wideBlockBounds, touchPointPadding, doubleTapZoomAlreadyLegibleScale, scale, scroll);
   2311     // The div should horizontally fill the screen (modulo margins), and
   2312     // vertically centered (modulo integer rounding).
   2313     EXPECT_NEAR(viewportWidth / (float) wideDiv.width, scale, 0.1);
   2314     EXPECT_NEAR(wideDiv.x, scroll.x, 20);
   2315     EXPECT_EQ(0, scroll.y);
   2316 
   2317     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), scroll, scale);
   2318 
   2319     // Test zoom out back to minimum scale.
   2320     wideBlockBounds = webViewHelper.webViewImpl()->computeBlockBounds(doubleTapPointWide, false);
   2321     webViewHelper.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(doubleTapPointWide.x, doubleTapPointWide.y), wideBlockBounds, touchPointPadding, doubleTapZoomAlreadyLegibleScale, scale, scroll);
   2322 
   2323     scale = webViewHelper.webViewImpl()->minimumPageScaleFactor();
   2324     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), scale);
   2325 
   2326     // Test double-tap zooming into tall div.
   2327     tallBlockBounds = webViewHelper.webViewImpl()->computeBlockBounds(doubleTapPointTall, false);
   2328     webViewHelper.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(doubleTapPointTall.x, doubleTapPointTall.y), tallBlockBounds, touchPointPadding, doubleTapZoomAlreadyLegibleScale, scale, scroll);
   2329     // The div should start at the top left of the viewport.
   2330     EXPECT_NEAR(viewportWidth / (float) tallDiv.width, scale, 0.1);
   2331     EXPECT_NEAR(tallDiv.x, scroll.x, 20);
   2332     EXPECT_NEAR(tallDiv.y, scroll.y, 20);
   2333 
   2334     // Test for Non-doubletap scaling
   2335     // Test zooming into div.
   2336     webViewHelper.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(250, 250), webViewHelper.webViewImpl()->computeBlockBounds(WebRect(250, 250, 10, 10), true), 0, doubleTapZoomAlreadyLegibleScale, scale, scroll);
   2337     EXPECT_NEAR(viewportWidth / (float) wideDiv.width, scale, 0.1);
   2338 }
   2339 
   2340 void simulatePageScale(WebViewImpl* webViewImpl, float& scale)
   2341 {
   2342     WebCore::IntSize scrollDelta = webViewImpl->fakePageScaleAnimationTargetPositionForTesting() - webViewImpl->mainFrameImpl()->frameView()->scrollPosition();
   2343     float scaleDelta = webViewImpl->fakePageScaleAnimationPageScaleForTesting() / webViewImpl->pageScaleFactor();
   2344     webViewImpl->applyScrollAndScale(scrollDelta, scaleDelta);
   2345     scale = webViewImpl->pageScaleFactor();
   2346 }
   2347 
   2348 void simulateMultiTargetZoom(WebViewImpl* webViewImpl, const WebRect& rect, float& scale)
   2349 {
   2350     if (webViewImpl->zoomToMultipleTargetsRect(rect))
   2351         simulatePageScale(webViewImpl, scale);
   2352 }
   2353 
   2354 void simulateDoubleTap(WebViewImpl* webViewImpl, WebPoint& point, float& scale)
   2355 {
   2356     webViewImpl->animateDoubleTapZoom(point);
   2357     EXPECT_TRUE(webViewImpl->fakeDoubleTapAnimationPendingForTesting());
   2358     simulatePageScale(webViewImpl, scale);
   2359 }
   2360 
   2361 TEST_F(WebFrameTest, DivAutoZoomWideDivTest)
   2362 {
   2363     registerMockedHttpURLLoad("get_wide_div_for_auto_zoom_test.html");
   2364 
   2365     const float deviceScaleFactor = 2.0f;
   2366     int viewportWidth = 640 / deviceScaleFactor;
   2367     int viewportHeight = 1280 / deviceScaleFactor;
   2368     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
   2369     FrameTestHelpers::WebViewHelper webViewHelper;
   2370     webViewHelper.initializeAndLoad(m_baseURL + "get_wide_div_for_auto_zoom_test.html");
   2371     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2372     webViewHelper.webView()->setPageScaleFactorLimits(1.0f, 4);
   2373     webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
   2374     webViewHelper.webView()->setPageScaleFactor(1.0f);
   2375     webViewHelper.webView()->layout();
   2376 
   2377     webViewHelper.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
   2378 
   2379     float doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
   2380 
   2381     WebRect div(0, 100, viewportWidth, 150);
   2382     WebPoint point(div.x + 50, div.y + 50);
   2383     float scale;
   2384     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
   2385 
   2386     simulateDoubleTap(webViewHelper.webViewImpl(), point, scale);
   2387     EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
   2388     simulateDoubleTap(webViewHelper.webViewImpl(), point, scale);
   2389     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2390 }
   2391 
   2392 TEST_F(WebFrameTest, DivAutoZoomVeryTallTest)
   2393 {
   2394     // When a block is taller than the viewport and a zoom targets a lower part
   2395     // of it, then we should keep the target point onscreen instead of snapping
   2396     // back up the top of the block.
   2397     registerMockedHttpURLLoad("very_tall_div.html");
   2398 
   2399     const float deviceScaleFactor = 2.0f;
   2400     int viewportWidth = 640 / deviceScaleFactor;
   2401     int viewportHeight = 1280 / deviceScaleFactor;
   2402     FrameTestHelpers::WebViewHelper webViewHelper;
   2403     webViewHelper.initializeAndLoad(m_baseURL + "very_tall_div.html", true, 0, 0, enableViewportSettings);
   2404     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2405     webViewHelper.webView()->setPageScaleFactorLimits(1.0f, 4);
   2406     webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
   2407     webViewHelper.webView()->setPageScaleFactor(1.0f);
   2408     webViewHelper.webView()->layout();
   2409 
   2410     WebRect div(200, 300, 400, 5000);
   2411     WebPoint point(div.x + 50, div.y + 3000);
   2412     float scale;
   2413     WebPoint scroll;
   2414 
   2415     WebRect blockBounds = webViewHelper.webViewImpl()->computeBlockBounds(WebRect(point.x, point.y, 0, 0), true);
   2416     webViewHelper.webViewImpl()->computeScaleAndScrollForBlockRect(point, blockBounds, 0, 1.0f, scale, scroll);
   2417     EXPECT_EQ(scale, 1.0f);
   2418     EXPECT_EQ(scroll.y, 2660);
   2419 }
   2420 
   2421 TEST_F(WebFrameTest, DivAutoZoomMultipleDivsTest)
   2422 {
   2423     registerMockedHttpURLLoad("get_multiple_divs_for_auto_zoom_test.html");
   2424 
   2425     const float deviceScaleFactor = 2.0f;
   2426     int viewportWidth = 640 / deviceScaleFactor;
   2427     int viewportHeight = 1280 / deviceScaleFactor;
   2428     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
   2429     FrameTestHelpers::WebViewHelper webViewHelper;
   2430     webViewHelper.initializeAndLoad(m_baseURL + "get_multiple_divs_for_auto_zoom_test.html");
   2431     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2432     webViewHelper.webView()->setPageScaleFactorLimits(0.5f, 4);
   2433     webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
   2434     webViewHelper.webView()->setPageScaleFactor(0.5f);
   2435     webViewHelper.webView()->layout();
   2436 
   2437     webViewHelper.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
   2438 
   2439     WebRect topDiv(200, 100, 200, 150);
   2440     WebRect bottomDiv(200, 300, 200, 150);
   2441     WebPoint topPoint(topDiv.x + 50, topDiv.y + 50);
   2442     WebPoint bottomPoint(bottomDiv.x + 50, bottomDiv.y + 50);
   2443     float scale;
   2444     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
   2445 
   2446     // Test double tap on two different divs
   2447     // After first zoom, we should go back to minimum page scale with a second double tap.
   2448     simulateDoubleTap(webViewHelper.webViewImpl(), topPoint, scale);
   2449     EXPECT_FLOAT_EQ(1, scale);
   2450     simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
   2451     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2452 
   2453     // If the user pinch zooms after double tap, a second double tap should zoom back to the div.
   2454     simulateDoubleTap(webViewHelper.webViewImpl(), topPoint, scale);
   2455     EXPECT_FLOAT_EQ(1, scale);
   2456     webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 0.6f);
   2457     simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
   2458     EXPECT_FLOAT_EQ(1, scale);
   2459     simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
   2460     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2461 
   2462     // If we didn't yet get an auto-zoom update and a second double-tap arrives, should go back to minimum scale.
   2463     webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
   2464     webViewHelper.webViewImpl()->animateDoubleTapZoom(topPoint);
   2465     EXPECT_TRUE(webViewHelper.webViewImpl()->fakeDoubleTapAnimationPendingForTesting());
   2466     simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
   2467     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2468 }
   2469 
   2470 TEST_F(WebFrameTest, DivAutoZoomScaleBoundsTest)
   2471 {
   2472     registerMockedHttpURLLoad("get_scale_bounds_check_for_auto_zoom_test.html");
   2473 
   2474     int viewportWidth = 320;
   2475     int viewportHeight = 480;
   2476     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
   2477     FrameTestHelpers::WebViewHelper webViewHelper;
   2478     webViewHelper.initializeAndLoad(m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html");
   2479     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2480     webViewHelper.webView()->setDeviceScaleFactor(1.5f);
   2481     webViewHelper.webView()->layout();
   2482 
   2483     webViewHelper.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
   2484 
   2485     WebRect div(200, 100, 200, 150);
   2486     WebPoint doubleTapPoint(div.x + 50, div.y + 50);
   2487     float scale;
   2488 
   2489     // Test double tap scale bounds.
   2490     // minimumPageScale < doubleTapZoomAlreadyLegibleScale < 1
   2491     webViewHelper.webView()->setPageScaleFactorLimits(0.5f, 4);
   2492     webViewHelper.webView()->layout();
   2493     float doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
   2494     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
   2495     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2496     EXPECT_FLOAT_EQ(1, scale);
   2497     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2498     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2499     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2500     EXPECT_FLOAT_EQ(1, scale);
   2501 
   2502     // Zoom in to reset double_tap_zoom_in_effect flag.
   2503     webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
   2504     // 1 < minimumPageScale < doubleTapZoomAlreadyLegibleScale
   2505     webViewHelper.webView()->setPageScaleFactorLimits(1.1f, 4);
   2506     webViewHelper.webView()->layout();
   2507     doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
   2508     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
   2509     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2510     EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
   2511     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2512     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2513     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2514     EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
   2515 
   2516     // Zoom in to reset double_tap_zoom_in_effect flag.
   2517     webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
   2518     // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale
   2519     webViewHelper.webView()->setPageScaleFactorLimits(0.95f, 4);
   2520     webViewHelper.webView()->layout();
   2521     doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
   2522     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
   2523     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2524     EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
   2525     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2526     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2527     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2528     EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
   2529 }
   2530 
   2531 TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest)
   2532 {
   2533     registerMockedHttpURLLoad("get_scale_bounds_check_for_auto_zoom_test.html");
   2534 
   2535     int viewportWidth = 320;
   2536     int viewportHeight = 480;
   2537     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
   2538     float accessibilityFontScaleFactor = 1.13f;
   2539     FrameTestHelpers::WebViewHelper webViewHelper;
   2540     webViewHelper.initializeAndLoad(m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html");
   2541     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2542     webViewHelper.webView()->layout();
   2543 
   2544     webViewHelper.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
   2545     webViewHelper.webViewImpl()->page()->settings().setTextAutosizingEnabled(true);
   2546     webViewHelper.webViewImpl()->page()->settings().setAccessibilityFontScaleFactor(accessibilityFontScaleFactor);
   2547 
   2548     WebRect div(200, 100, 200, 150);
   2549     WebPoint doubleTapPoint(div.x + 50, div.y + 50);
   2550     float scale;
   2551 
   2552     // Test double tap scale bounds.
   2553     // minimumPageScale < doubleTapZoomAlreadyLegibleScale < 1 < accessibilityFontScaleFactor
   2554     float legibleScale = accessibilityFontScaleFactor;
   2555     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
   2556     float doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
   2557     webViewHelper.webView()->setPageScaleFactorLimits(0.5f, 4);
   2558     webViewHelper.webView()->layout();
   2559     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2560     EXPECT_FLOAT_EQ(legibleScale, scale);
   2561     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2562     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2563     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2564     EXPECT_FLOAT_EQ(legibleScale, scale);
   2565 
   2566     // Zoom in to reset double_tap_zoom_in_effect flag.
   2567     webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
   2568     // 1 < accessibilityFontScaleFactor < minimumPageScale < doubleTapZoomAlreadyLegibleScale
   2569     webViewHelper.webView()->setPageScaleFactorLimits(1.0f, 4);
   2570     webViewHelper.webView()->layout();
   2571     doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
   2572     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
   2573     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2574     EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
   2575     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2576     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2577     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2578     EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
   2579 
   2580     // Zoom in to reset double_tap_zoom_in_effect flag.
   2581     webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
   2582     // minimumPageScale < 1 < accessibilityFontScaleFactor < doubleTapZoomAlreadyLegibleScale
   2583     webViewHelper.webView()->setPageScaleFactorLimits(0.95f, 4);
   2584     webViewHelper.webView()->layout();
   2585     doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
   2586     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
   2587     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2588     EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
   2589     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2590     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2591     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2592     EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
   2593 
   2594     // Zoom in to reset double_tap_zoom_in_effect flag.
   2595     webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
   2596     // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale < accessibilityFontScaleFactor
   2597     webViewHelper.webView()->setPageScaleFactorLimits(0.9f, 4);
   2598     webViewHelper.webView()->layout();
   2599     doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
   2600     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
   2601     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2602     EXPECT_FLOAT_EQ(legibleScale, scale);
   2603     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2604     EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
   2605     simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
   2606     EXPECT_FLOAT_EQ(legibleScale, scale);
   2607 }
   2608 
   2609 TEST_F(WebFrameTest, DivMultipleTargetZoomMultipleDivsTest)
   2610 {
   2611     registerMockedHttpURLLoad("get_multiple_divs_for_auto_zoom_test.html");
   2612 
   2613     const float deviceScaleFactor = 2.0f;
   2614     int viewportWidth = 640 / deviceScaleFactor;
   2615     int viewportHeight = 1280 / deviceScaleFactor;
   2616     float doubleTapZoomAlreadyLegibleRatio = 1.2f;
   2617     FrameTestHelpers::WebViewHelper webViewHelper;
   2618     webViewHelper.initializeAndLoad(m_baseURL + "get_multiple_divs_for_auto_zoom_test.html");
   2619     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2620     webViewHelper.webView()->setPageScaleFactorLimits(0.5f, 4);
   2621     webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
   2622     webViewHelper.webView()->setPageScaleFactor(0.5f);
   2623     webViewHelper.webView()->layout();
   2624 
   2625     webViewHelper.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
   2626 
   2627     WebRect viewportRect(0, 0, viewportWidth, viewportHeight);
   2628     WebRect topDiv(200, 100, 200, 150);
   2629     WebRect bottomDiv(200, 300, 200, 150);
   2630     float scale;
   2631     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
   2632 
   2633     simulateMultiTargetZoom(webViewHelper.webViewImpl(), topDiv, scale);
   2634     EXPECT_FLOAT_EQ(1, scale);
   2635     simulateMultiTargetZoom(webViewHelper.webViewImpl(), bottomDiv, scale);
   2636     EXPECT_FLOAT_EQ(1, scale);
   2637     simulateMultiTargetZoom(webViewHelper.webViewImpl(), viewportRect, scale);
   2638     EXPECT_FLOAT_EQ(1, scale);
   2639     webViewHelper.webViewImpl()->setPageScaleFactor(webViewHelper.webViewImpl()->minimumPageScaleFactor());
   2640     simulateMultiTargetZoom(webViewHelper.webViewImpl(), topDiv, scale);
   2641     EXPECT_FLOAT_EQ(1, scale);
   2642 }
   2643 
   2644 TEST_F(WebFrameTest, DivScrollIntoEditableTest)
   2645 {
   2646     registerMockedHttpURLLoad("get_scale_for_zoom_into_editable_test.html");
   2647 
   2648     int viewportWidth = 450;
   2649     int viewportHeight = 300;
   2650     float leftBoxRatio = 0.3f;
   2651     int caretPadding = 10;
   2652     float minReadableCaretHeight = 18.0f;
   2653     FrameTestHelpers::WebViewHelper webViewHelper;
   2654     webViewHelper.initializeAndLoad(m_baseURL + "get_scale_for_zoom_into_editable_test.html");
   2655     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2656     webViewHelper.webView()->setPageScaleFactorLimits(1, 4);
   2657     webViewHelper.webView()->layout();
   2658     webViewHelper.webView()->setDeviceScaleFactor(1.5f);
   2659     webViewHelper.webView()->settings()->setAutoZoomFocusedNodeToLegibleScale(true);
   2660 
   2661     webViewHelper.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
   2662 
   2663     WebRect editBoxWithText(200, 200, 250, 20);
   2664     WebRect editBoxWithNoText(200, 250, 250, 20);
   2665 
   2666     // Test scrolling the focused node
   2667     // The edit box is shorter and narrower than the viewport when legible.
   2668     webViewHelper.webView()->advanceFocus(false);
   2669     // Set the caret to the end of the input box.
   2670     webViewHelper.webView()->mainFrame()->document().getElementById("EditBoxWithText").to<WebInputElement>().setSelectionRange(1000, 1000);
   2671     setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0), 1);
   2672     WebRect rect, caret;
   2673     webViewHelper.webViewImpl()->selectionBounds(caret, rect);
   2674 
   2675     float scale;
   2676     WebCore::IntPoint scroll;
   2677     bool needAnimation;
   2678     webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->focusedElement(), scale, scroll, needAnimation);
   2679     EXPECT_TRUE(needAnimation);
   2680     // The edit box should be left aligned with a margin for possible label.
   2681     int hScroll = editBoxWithText.x - leftBoxRatio * viewportWidth / scale;
   2682     EXPECT_NEAR(hScroll, scroll.x(), 1);
   2683     int vScroll = editBoxWithText.y - (viewportHeight / scale - editBoxWithText.height) / 2;
   2684     EXPECT_NEAR(vScroll, scroll.y(), 1);
   2685     EXPECT_NEAR(minReadableCaretHeight / caret.height, scale, 0.1);
   2686 
   2687     // The edit box is wider than the viewport when legible.
   2688     viewportWidth = 200;
   2689     viewportHeight = 150;
   2690     webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
   2691     setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0), 1);
   2692     webViewHelper.webViewImpl()->selectionBounds(caret, rect);
   2693     webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->focusedElement(), scale, scroll, needAnimation);
   2694     EXPECT_TRUE(needAnimation);
   2695     // The caret should be right aligned since the caret would be offscreen when the edit box is left aligned.
   2696     hScroll = caret.x + caret.width + caretPadding - viewportWidth / scale;
   2697     EXPECT_NEAR(hScroll, scroll.x(), 1);
   2698     EXPECT_NEAR(minReadableCaretHeight / caret.height, scale, 0.1);
   2699 
   2700     setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0), 1);
   2701     // Move focus to edit box with text.
   2702     webViewHelper.webView()->advanceFocus(false);
   2703     webViewHelper.webViewImpl()->selectionBounds(caret, rect);
   2704     webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->focusedElement(), scale, scroll, needAnimation);
   2705     EXPECT_TRUE(needAnimation);
   2706     // The edit box should be left aligned.
   2707     hScroll = editBoxWithNoText.x;
   2708     EXPECT_NEAR(hScroll, scroll.x(), 1);
   2709     vScroll = editBoxWithNoText.y - (viewportHeight / scale - editBoxWithNoText.height) / 2;
   2710     EXPECT_NEAR(vScroll, scroll.y(), 1);
   2711     EXPECT_NEAR(minReadableCaretHeight / caret.height, scale, 0.1);
   2712 
   2713     setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), scroll, scale);
   2714 
   2715     // Move focus back to the first edit box.
   2716     webViewHelper.webView()->advanceFocus(true);
   2717     webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->focusedElement(), scale, scroll, needAnimation);
   2718     // The position should have stayed the same since this box was already on screen with the right scale.
   2719     EXPECT_FALSE(needAnimation);
   2720 }
   2721 
   2722 class TestReloadDoesntRedirectWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
   2723 public:
   2724     virtual WebNavigationPolicy decidePolicyForNavigation(
   2725         WebLocalFrame*, WebDataSource::ExtraData*, const WebURLRequest&, WebNavigationType,
   2726         WebNavigationPolicy defaultPolicy, bool isRedirect) OVERRIDE
   2727     {
   2728         EXPECT_FALSE(isRedirect);
   2729         return WebNavigationPolicyCurrentTab;
   2730     }
   2731 };
   2732 
   2733 TEST_F(WebFrameTest, ReloadDoesntSetRedirect)
   2734 {
   2735     // Test for case in http://crbug.com/73104. Reloading a frame very quickly
   2736     // would sometimes call decidePolicyForNavigation with isRedirect=true
   2737     registerMockedHttpURLLoad("form.html");
   2738 
   2739     TestReloadDoesntRedirectWebFrameClient webFrameClient;
   2740     FrameTestHelpers::WebViewHelper webViewHelper;
   2741     webViewHelper.initializeAndLoad(m_baseURL + "form.html", false, &webFrameClient);
   2742 
   2743     webViewHelper.webView()->mainFrame()->reload(true);
   2744     // start another reload before request is delivered.
   2745     FrameTestHelpers::reloadFrameIgnoringCache(webViewHelper.webView()->mainFrame());
   2746 }
   2747 
   2748 class ReloadWithOverrideURLTask : public WebThread::Task {
   2749 public:
   2750     ReloadWithOverrideURLTask(WebFrame* frame, const WebCore::KURL& url, bool ignoreCache)
   2751         : m_frame(frame), m_url(url), m_ignoreCache(ignoreCache)
   2752     {
   2753     }
   2754 
   2755     virtual void run() OVERRIDE
   2756     {
   2757         m_frame->reloadWithOverrideURL(m_url, m_ignoreCache);
   2758     }
   2759 
   2760 private:
   2761     WebFrame* const m_frame;
   2762     const WebCore::KURL m_url;
   2763     const bool m_ignoreCache;
   2764 };
   2765 
   2766 TEST_F(WebFrameTest, ReloadWithOverrideURLPreservesState)
   2767 {
   2768     const std::string firstURL = "find.html";
   2769     const std::string secondURL = "form.html";
   2770     const std::string thirdURL = "history.html";
   2771     const float pageScaleFactor = 1.1684f;
   2772     const int pageWidth = 640;
   2773     const int pageHeight = 480;
   2774 
   2775     registerMockedHttpURLLoad(firstURL);
   2776     registerMockedHttpURLLoad(secondURL);
   2777     registerMockedHttpURLLoad(thirdURL);
   2778 
   2779     FrameTestHelpers::WebViewHelper webViewHelper;
   2780     webViewHelper.initializeAndLoad(m_baseURL + firstURL, true);
   2781     webViewHelper.webViewImpl()->resize(WebSize(pageWidth, pageHeight));
   2782     webViewHelper.webViewImpl()->mainFrame()->setScrollOffset(WebSize(pageWidth / 4, pageHeight / 4));
   2783     webViewHelper.webViewImpl()->setPageScaleFactor(pageScaleFactor);
   2784 
   2785     WebSize previousOffset = webViewHelper.webViewImpl()->mainFrame()->scrollOffset();
   2786     float previousScale = webViewHelper.webViewImpl()->pageScaleFactor();
   2787 
   2788     // Reload the page using the cache.
   2789     Platform::current()->currentThread()->postTask(
   2790         new ReloadWithOverrideURLTask(webViewHelper.webViewImpl()->mainFrame(), toKURL(m_baseURL + secondURL), false));
   2791     FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper.webViewImpl()->mainFrame());
   2792     ASSERT_EQ(previousOffset, webViewHelper.webViewImpl()->mainFrame()->scrollOffset());
   2793     ASSERT_EQ(previousScale, webViewHelper.webViewImpl()->pageScaleFactor());
   2794 
   2795     // Reload the page while ignoring the cache.
   2796     Platform::current()->currentThread()->postTask(
   2797         new ReloadWithOverrideURLTask(webViewHelper.webViewImpl()->mainFrame(), toKURL(m_baseURL + thirdURL), true));
   2798     FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper.webViewImpl()->mainFrame());
   2799     ASSERT_EQ(previousOffset, webViewHelper.webViewImpl()->mainFrame()->scrollOffset());
   2800     ASSERT_EQ(previousScale, webViewHelper.webViewImpl()->pageScaleFactor());
   2801 }
   2802 
   2803 TEST_F(WebFrameTest, ReloadWhileProvisional)
   2804 {
   2805     // Test that reloading while the previous load is still pending does not cause the initial
   2806     // request to get lost.
   2807     registerMockedHttpURLLoad("fixed_layout.html");
   2808 
   2809     FrameTestHelpers::WebViewHelper webViewHelper;
   2810     webViewHelper.initialize();
   2811     WebURLRequest request;
   2812     request.initialize();
   2813     request.setURL(toKURL(m_baseURL + "fixed_layout.html"));
   2814     webViewHelper.webView()->mainFrame()->loadRequest(request);
   2815     // start reload before first request is delivered.
   2816     FrameTestHelpers::reloadFrameIgnoringCache(webViewHelper.webView()->mainFrame());
   2817 
   2818     WebDataSource* dataSource = webViewHelper.webView()->mainFrame()->dataSource();
   2819     ASSERT_TRUE(dataSource);
   2820     EXPECT_EQ(toKURL(m_baseURL + "fixed_layout.html"), toKURL(dataSource->request().url().spec()));
   2821 }
   2822 
   2823 TEST_F(WebFrameTest, AppendRedirects)
   2824 {
   2825     const std::string firstURL = "about:blank";
   2826     const std::string secondURL = "http://www.test.com";
   2827 
   2828     FrameTestHelpers::WebViewHelper webViewHelper;
   2829     webViewHelper.initializeAndLoad(firstURL, true);
   2830 
   2831     WebDataSource* dataSource = webViewHelper.webView()->mainFrame()->dataSource();
   2832     ASSERT_TRUE(dataSource);
   2833     dataSource->appendRedirect(toKURL(secondURL));
   2834 
   2835     WebVector<WebURL> redirects;
   2836     dataSource->redirectChain(redirects);
   2837     ASSERT_EQ(2U, redirects.size());
   2838     EXPECT_EQ(toKURL(firstURL), toKURL(redirects[0].spec().data()));
   2839     EXPECT_EQ(toKURL(secondURL), toKURL(redirects[1].spec().data()));
   2840 }
   2841 
   2842 TEST_F(WebFrameTest, IframeRedirect)
   2843 {
   2844     registerMockedHttpURLLoad("iframe_redirect.html");
   2845     registerMockedHttpURLLoad("visible_iframe.html");
   2846 
   2847     FrameTestHelpers::WebViewHelper webViewHelper;
   2848     webViewHelper.initializeAndLoad(m_baseURL + "iframe_redirect.html", true);
   2849     // Pump pending requests one more time. The test page loads script that navigates.
   2850     FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper.webView()->mainFrame());
   2851 
   2852     WebFrame* iframe = webViewHelper.webView()->findFrameByName(WebString::fromUTF8("ifr"));
   2853     ASSERT_TRUE(iframe);
   2854     WebDataSource* iframeDataSource = iframe->dataSource();
   2855     ASSERT_TRUE(iframeDataSource);
   2856     WebVector<WebURL> redirects;
   2857     iframeDataSource->redirectChain(redirects);
   2858     ASSERT_EQ(2U, redirects.size());
   2859     EXPECT_EQ(toKURL("about:blank"), toKURL(redirects[0].spec().data()));
   2860     EXPECT_EQ(toKURL("http://www.test.com/visible_iframe.html"), toKURL(redirects[1].spec().data()));
   2861 }
   2862 
   2863 TEST_F(WebFrameTest, ClearFocusedNodeTest)
   2864 {
   2865     registerMockedHttpURLLoad("iframe_clear_focused_node_test.html");
   2866     registerMockedHttpURLLoad("autofocus_input_field_iframe.html");
   2867 
   2868     FrameTestHelpers::WebViewHelper webViewHelper;
   2869     webViewHelper.initializeAndLoad(m_baseURL + "iframe_clear_focused_node_test.html", true);
   2870 
   2871     // Clear the focused node.
   2872     webViewHelper.webView()->clearFocusedElement();
   2873 
   2874     // Now retrieve the FocusedNode and test it should be null.
   2875     EXPECT_EQ(0, webViewHelper.webViewImpl()->focusedElement());
   2876 }
   2877 
   2878 // Implementation of WebFrameClient that tracks the v8 contexts that are created
   2879 // and destroyed for verification.
   2880 class ContextLifetimeTestWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
   2881 public:
   2882     struct Notification {
   2883     public:
   2884         Notification(WebLocalFrame* frame, v8::Handle<v8::Context> context, int worldId)
   2885             : frame(frame)
   2886             , context(context->GetIsolate(), context)
   2887             , worldId(worldId)
   2888         {
   2889         }
   2890 
   2891         ~Notification()
   2892         {
   2893             context.Reset();
   2894         }
   2895 
   2896         bool Equals(Notification* other)
   2897         {
   2898             return other && frame == other->frame && context == other->context && worldId == other->worldId;
   2899         }
   2900 
   2901         WebLocalFrame* frame;
   2902         v8::Persistent<v8::Context> context;
   2903         int worldId;
   2904     };
   2905 
   2906     virtual ~ContextLifetimeTestWebFrameClient()
   2907     {
   2908         reset();
   2909     }
   2910 
   2911     void reset()
   2912     {
   2913         for (size_t i = 0; i < createNotifications.size(); ++i)
   2914             delete createNotifications[i];
   2915 
   2916         for (size_t i = 0; i < releaseNotifications.size(); ++i)
   2917             delete releaseNotifications[i];
   2918 
   2919         createNotifications.clear();
   2920         releaseNotifications.clear();
   2921     }
   2922 
   2923     std::vector<Notification*> createNotifications;
   2924     std::vector<Notification*> releaseNotifications;
   2925 
   2926  private:
   2927     virtual void didCreateScriptContext(WebLocalFrame* frame, v8::Handle<v8::Context> context, int extensionGroup, int worldId) OVERRIDE
   2928     {
   2929         createNotifications.push_back(new Notification(frame, context, worldId));
   2930     }
   2931 
   2932     virtual void willReleaseScriptContext(WebLocalFrame* frame, v8::Handle<v8::Context> context, int worldId) OVERRIDE
   2933     {
   2934         releaseNotifications.push_back(new Notification(frame, context, worldId));
   2935     }
   2936 };
   2937 
   2938 // TODO(aa): Deflake this test.
   2939 TEST_F(WebFrameTest, FLAKY_ContextNotificationsLoadUnload)
   2940 {
   2941     v8::HandleScope handleScope(v8::Isolate::GetCurrent());
   2942 
   2943     registerMockedHttpURLLoad("context_notifications_test.html");
   2944     registerMockedHttpURLLoad("context_notifications_test_frame.html");
   2945 
   2946     // Load a frame with an iframe, make sure we get the right create notifications.
   2947     ContextLifetimeTestWebFrameClient webFrameClient;
   2948     FrameTestHelpers::WebViewHelper webViewHelper;
   2949     webViewHelper.initializeAndLoad(m_baseURL + "context_notifications_test.html", true, &webFrameClient);
   2950 
   2951     WebFrame* mainFrame = webViewHelper.webView()->mainFrame();
   2952     WebFrame* childFrame = mainFrame->firstChild();
   2953 
   2954     ASSERT_EQ(2u, webFrameClient.createNotifications.size());
   2955     EXPECT_EQ(0u, webFrameClient.releaseNotifications.size());
   2956 
   2957     ContextLifetimeTestWebFrameClient::Notification* firstCreateNotification = webFrameClient.createNotifications[0];
   2958     ContextLifetimeTestWebFrameClient::Notification* secondCreateNotification = webFrameClient.createNotifications[1];
   2959 
   2960     EXPECT_EQ(mainFrame, firstCreateNotification->frame);
   2961     EXPECT_EQ(mainFrame->mainWorldScriptContext(), firstCreateNotification->context);
   2962     EXPECT_EQ(0, firstCreateNotification->worldId);
   2963 
   2964     EXPECT_EQ(childFrame, secondCreateNotification->frame);
   2965     EXPECT_EQ(childFrame->mainWorldScriptContext(), secondCreateNotification->context);
   2966     EXPECT_EQ(0, secondCreateNotification->worldId);
   2967 
   2968     // Close the view. We should get two release notifications that are exactly the same as the create ones, in reverse order.
   2969     webViewHelper.reset();
   2970 
   2971     ASSERT_EQ(2u, webFrameClient.releaseNotifications.size());
   2972     ContextLifetimeTestWebFrameClient::Notification* firstReleaseNotification = webFrameClient.releaseNotifications[0];
   2973     ContextLifetimeTestWebFrameClient::Notification* secondReleaseNotification = webFrameClient.releaseNotifications[1];
   2974 
   2975     ASSERT_TRUE(firstCreateNotification->Equals(secondReleaseNotification));
   2976     ASSERT_TRUE(secondCreateNotification->Equals(firstReleaseNotification));
   2977 }
   2978 
   2979 TEST_F(WebFrameTest, ContextNotificationsReload)
   2980 {
   2981     v8::HandleScope handleScope(v8::Isolate::GetCurrent());
   2982 
   2983     registerMockedHttpURLLoad("context_notifications_test.html");
   2984     registerMockedHttpURLLoad("context_notifications_test_frame.html");
   2985 
   2986     ContextLifetimeTestWebFrameClient webFrameClient;
   2987     FrameTestHelpers::WebViewHelper webViewHelper;
   2988     webViewHelper.initializeAndLoad(m_baseURL + "context_notifications_test.html", true, &webFrameClient);
   2989 
   2990     // Refresh, we should get two release notifications and two more create notifications.
   2991     FrameTestHelpers::reloadFrame(webViewHelper.webView()->mainFrame());
   2992     ASSERT_EQ(4u, webFrameClient.createNotifications.size());
   2993     ASSERT_EQ(2u, webFrameClient.releaseNotifications.size());
   2994 
   2995     // The two release notifications we got should be exactly the same as the first two create notifications.
   2996     for (size_t i = 0; i < webFrameClient.releaseNotifications.size(); ++i) {
   2997       EXPECT_TRUE(webFrameClient.releaseNotifications[i]->Equals(
   2998           webFrameClient.createNotifications[webFrameClient.createNotifications.size() - 3 - i]));
   2999     }
   3000 
   3001     // The last two create notifications should be for the current frames and context.
   3002     WebFrame* mainFrame = webViewHelper.webView()->mainFrame();
   3003     WebFrame* childFrame = mainFrame->firstChild();
   3004     ContextLifetimeTestWebFrameClient::Notification* firstRefreshNotification = webFrameClient.createNotifications[2];
   3005     ContextLifetimeTestWebFrameClient::Notification* secondRefreshNotification = webFrameClient.createNotifications[3];
   3006 
   3007     EXPECT_EQ(mainFrame, firstRefreshNotification->frame);
   3008     EXPECT_EQ(mainFrame->mainWorldScriptContext(), firstRefreshNotification->context);
   3009     EXPECT_EQ(0, firstRefreshNotification->worldId);
   3010 
   3011     EXPECT_EQ(childFrame, secondRefreshNotification->frame);
   3012     EXPECT_EQ(childFrame->mainWorldScriptContext(), secondRefreshNotification->context);
   3013     EXPECT_EQ(0, secondRefreshNotification->worldId);
   3014 }
   3015 
   3016 TEST_F(WebFrameTest, ContextNotificationsIsolatedWorlds)
   3017 {
   3018     v8::Isolate* isolate = v8::Isolate::GetCurrent();
   3019     v8::HandleScope handleScope(isolate);
   3020 
   3021     registerMockedHttpURLLoad("context_notifications_test.html");
   3022     registerMockedHttpURLLoad("context_notifications_test_frame.html");
   3023 
   3024     ContextLifetimeTestWebFrameClient webFrameClient;
   3025     FrameTestHelpers::WebViewHelper webViewHelper;
   3026     webViewHelper.initializeAndLoad(m_baseURL + "context_notifications_test.html", true, &webFrameClient);
   3027 
   3028     // Add an isolated world.
   3029     webFrameClient.reset();
   3030 
   3031     int isolatedWorldId = 42;
   3032     WebScriptSource scriptSource("hi!");
   3033     int numSources = 1;
   3034     int extensionGroup = 0;
   3035     webViewHelper.webView()->mainFrame()->executeScriptInIsolatedWorld(isolatedWorldId, &scriptSource, numSources, extensionGroup);
   3036 
   3037     // We should now have a new create notification.
   3038     ASSERT_EQ(1u, webFrameClient.createNotifications.size());
   3039     ContextLifetimeTestWebFrameClient::Notification* notification = webFrameClient.createNotifications[0];
   3040     ASSERT_EQ(isolatedWorldId, notification->worldId);
   3041     ASSERT_EQ(webViewHelper.webView()->mainFrame(), notification->frame);
   3042 
   3043     // We don't have an API to enumarate isolated worlds for a frame, but we can at least assert that the context we got is *not* the main world's context.
   3044     ASSERT_NE(webViewHelper.webView()->mainFrame()->mainWorldScriptContext(), v8::Local<v8::Context>::New(isolate, notification->context));
   3045 
   3046     webViewHelper.reset();
   3047 
   3048     // We should have gotten three release notifications (one for each of the frames, plus one for the isolated context).
   3049     ASSERT_EQ(3u, webFrameClient.releaseNotifications.size());
   3050 
   3051     // And one of them should be exactly the same as the create notification for the isolated context.
   3052     int matchCount = 0;
   3053     for (size_t i = 0; i < webFrameClient.releaseNotifications.size(); ++i) {
   3054       if (webFrameClient.releaseNotifications[i]->Equals(webFrameClient.createNotifications[0]))
   3055         ++matchCount;
   3056     }
   3057     EXPECT_EQ(1, matchCount);
   3058 }
   3059 
   3060 TEST_F(WebFrameTest, FindInPage)
   3061 {
   3062     registerMockedHttpURLLoad("find.html");
   3063     FrameTestHelpers::WebViewHelper webViewHelper;
   3064     webViewHelper.initializeAndLoad(m_baseURL + "find.html");
   3065     WebFrame* frame = webViewHelper.webView()->mainFrame();
   3066     const int findIdentifier = 12345;
   3067     WebFindOptions options;
   3068 
   3069     // Find in a <div> element.
   3070     EXPECT_TRUE(frame->find(findIdentifier, WebString::fromUTF8("bar1"), options, false, 0));
   3071     frame->stopFinding(false);
   3072     WebRange range = frame->selectionRange();
   3073     EXPECT_EQ(5, range.startOffset());
   3074     EXPECT_EQ(9, range.endOffset());
   3075     EXPECT_TRUE(frame->document().focusedElement().isNull());
   3076 
   3077     // Find in an <input> value.
   3078     EXPECT_TRUE(frame->find(findIdentifier, WebString::fromUTF8("bar2"), options, false, 0));
   3079     // Confirm stopFinding(false) sets the selection on the found text.
   3080     frame->stopFinding(false);
   3081     range = frame->selectionRange();
   3082     ASSERT_FALSE(range.isNull());
   3083     EXPECT_EQ(5, range.startOffset());
   3084     EXPECT_EQ(9, range.endOffset());
   3085     EXPECT_EQ(WebString::fromUTF8("INPUT"), frame->document().focusedElement().tagName());
   3086 
   3087     // Find in a <textarea> content.
   3088     EXPECT_TRUE(frame->find(findIdentifier, WebString::fromUTF8("bar3"), options, false, 0));
   3089     // Confirm stopFinding(false) sets the selection on the found text.
   3090     frame->stopFinding(false);
   3091     range = frame->selectionRange();
   3092     ASSERT_FALSE(range.isNull());
   3093     EXPECT_EQ(5, range.startOffset());
   3094     EXPECT_EQ(9, range.endOffset());
   3095     EXPECT_EQ(WebString::fromUTF8("TEXTAREA"), frame->document().focusedElement().tagName());
   3096 
   3097     // Find in a contentEditable element.
   3098     EXPECT_TRUE(frame->find(findIdentifier, WebString::fromUTF8("bar4"), options, false, 0));
   3099     // Confirm stopFinding(false) sets the selection on the found text.
   3100     frame->stopFinding(false);
   3101     range = frame->selectionRange();
   3102     ASSERT_FALSE(range.isNull());
   3103     EXPECT_EQ(0, range.startOffset());
   3104     EXPECT_EQ(4, range.endOffset());
   3105     // "bar4" is surrounded by <span>, but the focusable node should be the parent <div>.
   3106     EXPECT_EQ(WebString::fromUTF8("DIV"), frame->document().focusedElement().tagName());
   3107 
   3108     // Find in <select> content.
   3109     EXPECT_FALSE(frame->find(findIdentifier, WebString::fromUTF8("bar5"), options, false, 0));
   3110     // If there are any matches, stopFinding will set the selection on the found text.
   3111     // However, we do not expect any matches, so check that the selection is null.
   3112     frame->stopFinding(false);
   3113     range = frame->selectionRange();
   3114     ASSERT_TRUE(range.isNull());
   3115 }
   3116 
   3117 TEST_F(WebFrameTest, GetContentAsPlainText)
   3118 {
   3119     FrameTestHelpers::WebViewHelper webViewHelper;
   3120     webViewHelper.initializeAndLoad("about:blank", true);
   3121     // We set the size because it impacts line wrapping, which changes the
   3122     // resulting text value.
   3123     webViewHelper.webView()->resize(WebSize(640, 480));
   3124     WebFrame* frame = webViewHelper.webView()->mainFrame();
   3125 
   3126     // Generate a simple test case.
   3127     const char simpleSource[] = "<div>Foo bar</div><div></div>baz";
   3128     WebCore::KURL testURL = toKURL("about:blank");
   3129     FrameTestHelpers::loadHTMLString(frame, simpleSource, testURL);
   3130 
   3131     // Make sure it comes out OK.
   3132     const std::string expected("Foo bar\nbaz");
   3133     WebString text = frame->contentAsText(std::numeric_limits<size_t>::max());
   3134     EXPECT_EQ(expected, text.utf8());
   3135 
   3136     // Try reading the same one with clipping of the text.
   3137     const int length = 5;
   3138     text = frame->contentAsText(length);
   3139     EXPECT_EQ(expected.substr(0, length), text.utf8());
   3140 
   3141     // Now do a new test with a subframe.
   3142     const char outerFrameSource[] = "Hello<iframe></iframe> world";
   3143     FrameTestHelpers::loadHTMLString(frame, outerFrameSource, testURL);
   3144 
   3145     // Load something into the subframe.
   3146     WebFrame* subframe = frame->firstChild();
   3147     ASSERT_TRUE(subframe);
   3148     FrameTestHelpers::loadHTMLString(subframe, "sub<p>text", testURL);
   3149 
   3150     text = frame->contentAsText(std::numeric_limits<size_t>::max());
   3151     EXPECT_EQ("Hello world\n\nsub\ntext", text.utf8());
   3152 
   3153     // Get the frame text where the subframe separator falls on the boundary of
   3154     // what we'll take. There used to be a crash in this case.
   3155     text = frame->contentAsText(12);
   3156     EXPECT_EQ("Hello world", text.utf8());
   3157 }
   3158 
   3159 TEST_F(WebFrameTest, GetFullHtmlOfPage)
   3160 {
   3161     FrameTestHelpers::WebViewHelper webViewHelper;
   3162     webViewHelper.initializeAndLoad("about:blank", true);
   3163     WebFrame* frame = webViewHelper.webView()->mainFrame();
   3164 
   3165     // Generate a simple test case.
   3166     const char simpleSource[] = "<p>Hello</p><p>World</p>";
   3167     WebCore::KURL testURL = toKURL("about:blank");
   3168     FrameTestHelpers::loadHTMLString(frame, simpleSource, testURL);
   3169 
   3170     WebString text = frame->contentAsText(std::numeric_limits<size_t>::max());
   3171     EXPECT_EQ("Hello\n\nWorld", text.utf8());
   3172 
   3173     const std::string html = frame->contentAsMarkup().utf8();
   3174 
   3175     // Load again with the output html.
   3176     FrameTestHelpers::loadHTMLString(frame, html, testURL);
   3177 
   3178     EXPECT_EQ(html, frame->contentAsMarkup().utf8());
   3179 
   3180     text = frame->contentAsText(std::numeric_limits<size_t>::max());
   3181     EXPECT_EQ("Hello\n\nWorld", text.utf8());
   3182 
   3183     // Test selection check
   3184     EXPECT_FALSE(frame->hasSelection());
   3185     frame->executeCommand(WebString::fromUTF8("SelectAll"));
   3186     EXPECT_TRUE(frame->hasSelection());
   3187     frame->executeCommand(WebString::fromUTF8("Unselect"));
   3188     EXPECT_FALSE(frame->hasSelection());
   3189     WebString selectionHtml = frame->selectionAsMarkup();
   3190     EXPECT_TRUE(selectionHtml.isEmpty());
   3191 }
   3192 
   3193 class TestExecuteScriptDuringDidCreateScriptContext : public FrameTestHelpers::TestWebFrameClient {
   3194 public:
   3195     virtual void didCreateScriptContext(WebLocalFrame* frame, v8::Handle<v8::Context> context, int extensionGroup, int worldId) OVERRIDE
   3196     {
   3197         frame->executeScript(WebScriptSource("window.history = 'replaced';"));
   3198     }
   3199 };
   3200 
   3201 TEST_F(WebFrameTest, ExecuteScriptDuringDidCreateScriptContext)
   3202 {
   3203     registerMockedHttpURLLoad("hello_world.html");
   3204 
   3205     TestExecuteScriptDuringDidCreateScriptContext webFrameClient;
   3206     FrameTestHelpers::WebViewHelper webViewHelper;
   3207     webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html", true, &webFrameClient);
   3208 
   3209     FrameTestHelpers::reloadFrame(webViewHelper.webView()->mainFrame());
   3210 }
   3211 
   3212 class FindUpdateWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
   3213 public:
   3214     FindUpdateWebFrameClient()
   3215         : m_findResultsAreReady(false)
   3216         , m_count(-1)
   3217     {
   3218     }
   3219 
   3220     virtual void reportFindInPageMatchCount(int, int count, bool finalUpdate) OVERRIDE
   3221     {
   3222         m_count = count;
   3223         if (finalUpdate)
   3224             m_findResultsAreReady = true;
   3225     }
   3226 
   3227     bool findResultsAreReady() const { return m_findResultsAreReady; }
   3228     int count() const { return m_count; }
   3229 
   3230 private:
   3231     bool m_findResultsAreReady;
   3232     int m_count;
   3233 };
   3234 
   3235 // This fails on Mac https://bugs.webkit.org/show_bug.cgi?id=108574
   3236 // Also failing on Android: http://crbug.com/341314
   3237 #if OS(MACOSX) || OS(ANDROID)
   3238 TEST_F(WebFrameTest, DISABLED_FindInPageMatchRects)
   3239 #else
   3240 TEST_F(WebFrameTest, FindInPageMatchRects)
   3241 #endif
   3242 {
   3243     registerMockedHttpURLLoad("find_in_page.html");
   3244     registerMockedHttpURLLoad("find_in_page_frame.html");
   3245 
   3246     FindUpdateWebFrameClient client;
   3247     FrameTestHelpers::WebViewHelper webViewHelper;
   3248     webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true, &client);
   3249     webViewHelper.webView()->resize(WebSize(640, 480));
   3250     webViewHelper.webView()->layout();
   3251     runPendingTasks();
   3252 
   3253     // Note that the 'result 19' in the <select> element is not expected to produce a match.
   3254     static const char* kFindString = "result";
   3255     static const int kFindIdentifier = 12345;
   3256     static const int kNumResults = 19;
   3257 
   3258     WebFindOptions options;
   3259     WebString searchText = WebString::fromUTF8(kFindString);
   3260     WebLocalFrameImpl* mainFrame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
   3261     EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchText, options, false, 0));
   3262 
   3263     mainFrame->resetMatchCount();
   3264 
   3265     for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
   3266         frame->scopeStringMatches(kFindIdentifier, searchText, options, true);
   3267 
   3268     runPendingTasks();
   3269     EXPECT_TRUE(client.findResultsAreReady());
   3270 
   3271     WebVector<WebFloatRect> webMatchRects;
   3272     mainFrame->findMatchRects(webMatchRects);
   3273     ASSERT_EQ(webMatchRects.size(), static_cast<size_t>(kNumResults));
   3274     int rectsVersion = mainFrame->findMatchMarkersVersion();
   3275 
   3276     for (int resultIndex = 0; resultIndex < kNumResults; ++resultIndex) {
   3277         FloatRect resultRect = static_cast<FloatRect>(webMatchRects[resultIndex]);
   3278 
   3279         // Select the match by the center of its rect.
   3280         EXPECT_EQ(mainFrame->selectNearestFindMatch(resultRect.center(), 0), resultIndex + 1);
   3281 
   3282         // Check that the find result ordering matches with our expectations.
   3283         Range* result = mainFrame->activeMatchFrame()->activeMatch();
   3284         ASSERT_TRUE(result);
   3285         result->setEnd(result->endContainer(), result->endOffset() + 3);
   3286         EXPECT_EQ(result->text(), String::format("%s %02d", kFindString, resultIndex));
   3287 
   3288         // Verify that the expected match rect also matches the currently active match.
   3289         // Compare the enclosing rects to prevent precision issues caused by CSS transforms.
   3290         FloatRect activeMatch = mainFrame->activeFindMatchRect();
   3291         EXPECT_EQ(enclosingIntRect(activeMatch), enclosingIntRect(resultRect));
   3292 
   3293         // The rects version should not have changed.
   3294         EXPECT_EQ(mainFrame->findMatchMarkersVersion(), rectsVersion);
   3295     }
   3296 
   3297     // All results after the first two ones should be below between them in find-in-page coordinates.
   3298     // This is because results 2 to 9 are inside an iframe located between results 0 and 1. This applies to the fixed div too.
   3299     EXPECT_TRUE(webMatchRects[0].y < webMatchRects[1].y);
   3300     for (int resultIndex = 2; resultIndex < kNumResults; ++resultIndex) {
   3301         EXPECT_TRUE(webMatchRects[0].y < webMatchRects[resultIndex].y);
   3302         EXPECT_TRUE(webMatchRects[1].y > webMatchRects[resultIndex].y);
   3303     }
   3304 
   3305     // Result 3 should be below both 2 and 4. This is caused by the CSS transform in the containing div.
   3306     // If the transform doesn't work then 3 will be between 2 and 4.
   3307     EXPECT_TRUE(webMatchRects[3].y > webMatchRects[2].y);
   3308     EXPECT_TRUE(webMatchRects[3].y > webMatchRects[4].y);
   3309 
   3310     // Results 6, 7, 8 and 9 should be one below the other in that same order.
   3311     // If overflow:scroll is not properly handled then result 8 would be below result 9 or
   3312     // result 7 above result 6 depending on the scroll.
   3313     EXPECT_TRUE(webMatchRects[6].y < webMatchRects[7].y);
   3314     EXPECT_TRUE(webMatchRects[7].y < webMatchRects[8].y);
   3315     EXPECT_TRUE(webMatchRects[8].y < webMatchRects[9].y);
   3316 
   3317     // Results 11, 12, 13 and 14 should be between results 10 and 15, as they are inside the table.
   3318     EXPECT_TRUE(webMatchRects[11].y > webMatchRects[10].y);
   3319     EXPECT_TRUE(webMatchRects[12].y > webMatchRects[10].y);
   3320     EXPECT_TRUE(webMatchRects[13].y > webMatchRects[10].y);
   3321     EXPECT_TRUE(webMatchRects[14].y > webMatchRects[10].y);
   3322     EXPECT_TRUE(webMatchRects[11].y < webMatchRects[15].y);
   3323     EXPECT_TRUE(webMatchRects[12].y < webMatchRects[15].y);
   3324     EXPECT_TRUE(webMatchRects[13].y < webMatchRects[15].y);
   3325     EXPECT_TRUE(webMatchRects[14].y < webMatchRects[15].y);
   3326 
   3327     // Result 11 should be above 12, 13 and 14 as it's in the table header.
   3328     EXPECT_TRUE(webMatchRects[11].y < webMatchRects[12].y);
   3329     EXPECT_TRUE(webMatchRects[11].y < webMatchRects[13].y);
   3330     EXPECT_TRUE(webMatchRects[11].y < webMatchRects[14].y);
   3331 
   3332     // Result 11 should also be right to 12, 13 and 14 because of the colspan.
   3333     EXPECT_TRUE(webMatchRects[11].x > webMatchRects[12].x);
   3334     EXPECT_TRUE(webMatchRects[11].x > webMatchRects[13].x);
   3335     EXPECT_TRUE(webMatchRects[11].x > webMatchRects[14].x);
   3336 
   3337     // Result 12 should be left to results 11, 13 and 14 in the table layout.
   3338     EXPECT_TRUE(webMatchRects[12].x < webMatchRects[11].x);
   3339     EXPECT_TRUE(webMatchRects[12].x < webMatchRects[13].x);
   3340     EXPECT_TRUE(webMatchRects[12].x < webMatchRects[14].x);
   3341 
   3342     // Results 13, 12 and 14 should be one above the other in that order because of the rowspan
   3343     // and vertical-align: middle by default.
   3344     EXPECT_TRUE(webMatchRects[13].y < webMatchRects[12].y);
   3345     EXPECT_TRUE(webMatchRects[12].y < webMatchRects[14].y);
   3346 
   3347     // Result 16 should be below result 15.
   3348     EXPECT_TRUE(webMatchRects[15].y > webMatchRects[14].y);
   3349 
   3350     // Result 18 should be normalized with respect to the position:relative div, and not it's
   3351     // immediate containing div. Consequently, result 18 should be above result 17.
   3352     EXPECT_TRUE(webMatchRects[17].y > webMatchRects[18].y);
   3353 
   3354     // Resizing should update the rects version.
   3355     webViewHelper.webView()->resize(WebSize(800, 600));
   3356     runPendingTasks();
   3357     EXPECT_TRUE(mainFrame->findMatchMarkersVersion() != rectsVersion);
   3358 }
   3359 
   3360 TEST_F(WebFrameTest, FindInPageSkipsHiddenFrames)
   3361 {
   3362     registerMockedHttpURLLoad("find_in_hidden_frame.html");
   3363 
   3364     FindUpdateWebFrameClient client;
   3365     FrameTestHelpers::WebViewHelper webViewHelper;
   3366     webViewHelper.initializeAndLoad(m_baseURL + "find_in_hidden_frame.html", true, &client);
   3367     webViewHelper.webView()->resize(WebSize(640, 480));
   3368     webViewHelper.webView()->layout();
   3369     runPendingTasks();
   3370 
   3371     static const char* kFindString = "hello";
   3372     static const int kFindIdentifier = 12345;
   3373     static const int kNumResults = 1;
   3374 
   3375     WebFindOptions options;
   3376     WebString searchText = WebString::fromUTF8(kFindString);
   3377     WebLocalFrameImpl* mainFrame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
   3378     EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchText, options, false, 0));
   3379 
   3380     mainFrame->resetMatchCount();
   3381 
   3382     for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
   3383         frame->scopeStringMatches(kFindIdentifier, searchText, options, true);
   3384 
   3385