15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/renderer/aw_render_view_ext.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/common/aw_hit_test_data.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/common/render_view_messages.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/strings/utf_string_conversions.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/time/time.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/renderer/android_content_detection_prefixes.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/document_state.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_view.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "skia/ext/refptr.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebSize.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebVector.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebDataSource.h"
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebDocument.h"
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebElement.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebElementCollection.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebHitTestResult.h"
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "third_party/WebKit/public/web/WebImageCache.h"
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "third_party/WebKit/public/web/WebLocalFrame.h"
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebNode.h"
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/WebKit/public/web/WebView.h"
323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "url/url_canon.h"
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "url/url_constants.h"
343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "url/url_util.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace android_webview {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GURL GetAbsoluteUrl(const blink::WebNode& node,
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    const base::string16& url_fragment) {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GURL(node.document().completeURL(url_fragment));
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 GetHref(const blink::WebElement& element) {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Get the actual 'href' attribute, which might relative if valid or can
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // possibly contain garbage otherwise, so not using absoluteLinkURL here.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return element.getAttribute("href");
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)GURL GetAbsoluteSrcUrl(const blink::WebElement& element) {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (element.isNull())
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return GURL();
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetAbsoluteUrl(element, element.getAttribute("src"));
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)blink::WebElement GetImgChild(const blink::WebElement& element) {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This implementation is incomplete (for example if is an area tag) but
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // matches the original WebViewClassic implementation.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  blink::WebElementCollection collection =
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      element.getElementsByHTMLTagName("img");
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!collection.isNull());
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return collection.firstItem();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool RemovePrefixAndAssignIfMatches(const base::StringPiece& prefix,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const GURL& url,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    std::string* dest) {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::StringPiece spec(url.possibly_invalid_spec());
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (spec.starts_with(prefix)) {
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    url::RawCanonOutputW<1024> output;
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    url::DecodeURLEscapeSequences(spec.data() + prefix.length(),
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                  spec.length() - prefix.length(),
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                  &output);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string decoded_url = base::UTF16ToUTF8(
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::string16(output.data(), output.length()));
793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    dest->assign(decoded_url.begin(), decoded_url.end());
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DistinguishAndAssignSrcLinkType(const GURL& url, AwHitTestData* data) {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (RemovePrefixAndAssignIfMatches(
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::kAddressPrefix,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &data->extra_data_for_type)) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->type = AwHitTestData::GEO_TYPE;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (RemovePrefixAndAssignIfMatches(
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::kPhoneNumberPrefix,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &data->extra_data_for_type)) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->type = AwHitTestData::PHONE_TYPE;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (RemovePrefixAndAssignIfMatches(
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::kEmailPrefix,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &data->extra_data_for_type)) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->type = AwHitTestData::EMAIL_TYPE;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->type = AwHitTestData::SRC_LINK_TYPE;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->extra_data_for_type = url.possibly_invalid_spec();
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!data->extra_data_for_type.empty())
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      data->href = base::UTF8ToUTF16(data->extra_data_for_type);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PopulateHitTestData(const GURL& absolute_link_url,
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const GURL& absolute_image_url,
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         bool is_editable,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         AwHitTestData* data) {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: Using GURL::is_empty instead of GURL:is_valid due to the
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebViewClassic allowing any kind of protocol which GURL::is_valid
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // disallows. Similar reasons for using GURL::possibly_invalid_spec instead of
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // GURL::spec.
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!absolute_image_url.is_empty())
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->img_src = absolute_image_url;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool is_javascript_scheme =
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      absolute_link_url.SchemeIs(url::kJavaScriptScheme);
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool has_link_url = !absolute_link_url.is_empty();
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool has_image_url = !absolute_image_url.is_empty();
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_link_url && !has_image_url && !is_javascript_scheme) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DistinguishAndAssignSrcLinkType(absolute_link_url, data);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (has_link_url && has_image_url && !is_javascript_scheme) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->type = AwHitTestData::SRC_IMAGE_LINK_TYPE;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->extra_data_for_type = data->img_src.possibly_invalid_spec();
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (absolute_link_url.is_valid())
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      data->href = base::UTF8ToUTF16(absolute_link_url.possibly_invalid_spec());
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (!has_link_url && has_image_url) {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->type = AwHitTestData::IMAGE_TYPE;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->extra_data_for_type = data->img_src.possibly_invalid_spec();
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (is_editable) {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data->type = AwHitTestData::EDIT_TEXT_TYPE;
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK_EQ(0u, data->extra_data_for_type.length());
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AwRenderViewExt::AwRenderViewExt(content::RenderView* render_view)
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : content::RenderViewObserver(render_view), page_scale_factor_(0.0f) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AwRenderViewExt::~AwRenderViewExt() {
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AwRenderViewExt::RenderViewCreated(content::RenderView* render_view) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new AwRenderViewExt(render_view);  // |render_view| takes ownership.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AwRenderViewExt::OnMessageReceived(const IPC::Message& message) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(AwRenderViewExt, message)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AwViewMsg_DocumentHasImages, OnDocumentHasImagesRequest)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(AwViewMsg_DoHitTest, OnDoHitTest)
160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    IPC_MESSAGE_HANDLER(AwViewMsg_SetTextZoomFactor, OnSetTextZoomFactor)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(AwViewMsg_ResetScrollAndScaleState,
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnResetScrollAndScaleState)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(AwViewMsg_SetInitialPageScale, OnSetInitialPageScale)
164a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    IPC_MESSAGE_HANDLER(AwViewMsg_SetBackgroundColor, OnSetBackgroundColor)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AwRenderViewExt::OnDocumentHasImagesRequest(int id) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool hasImages = false;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (render_view()) {
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebView* webview = render_view()->GetWebView();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (webview) {
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebVector<blink::WebElement> images;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      webview->mainFrame()->document().images(images);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hasImages = !images.isEmpty();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new AwViewHostMsg_DocumentHasImagesResponse(routing_id(), id,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   hasImages));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AwRenderViewExt::DidCommitCompositorFrame() {
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UpdatePageScaleFactor();
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AwRenderViewExt::DidUpdateLayout() {
189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (check_contents_size_timer_.IsRunning())
190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  check_contents_size_timer_.Start(FROM_HERE,
193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::TimeDelta::FromMilliseconds(0), this,
194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   &AwRenderViewExt::CheckContentsSize);
195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AwRenderViewExt::UpdatePageScaleFactor() {
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (page_scale_factor_ != render_view()->GetWebView()->pageScaleFactor()) {
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    page_scale_factor_ = render_view()->GetWebView()->pageScaleFactor();
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Send(new AwViewHostMsg_PageScaleFactorChanged(routing_id(),
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                  page_scale_factor_));
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AwRenderViewExt::CheckContentsSize() {
206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!render_view()->GetWebView())
207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  gfx::Size contents_size;
210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebFrame* main_frame = render_view()->GetWebView()->mainFrame();
212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (main_frame)
213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    contents_size = main_frame->contentsSize();
214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Fall back to contentsPreferredMinimumSize if the mainFrame is reporting a
216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // 0x0 size (this happens during initial load).
217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (contents_size.IsEmpty()) {
218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    contents_size = render_view()->GetWebView()->contentsPreferredMinimumSize();
219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
221d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (contents_size == last_sent_contents_size_)
222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  last_sent_contents_size_ = contents_size;
225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Send(new AwViewHostMsg_OnContentsSizeChanged(routing_id(), contents_size));
226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void AwRenderViewExt::Navigate(const GURL& url) {
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Navigate is called only on NEW navigations, so WebImageCache won't be freed
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // when the user just clicks on links, but only when a navigation is started,
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // for instance via loadUrl. A better approach would be clearing the cache on
2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // cross-site boundaries, however this would require too many changes both on
2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // the browser side (in RenderViewHostManger), to the IPCmessages and to the
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // RenderViewObserver. Thus, clearing decoding image cache on Navigate, seems
2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // a more acceptable compromise.
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebImageCache::clear();
2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AwRenderViewExt::FocusedNodeChanged(const blink::WebNode& node) {
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (node.isNull() || !node.isElementNode() || !render_view())
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: element is not const due to innerText() is not const.
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebElement element = node.toConst<blink::WebElement>();
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AwHitTestData data;
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.href = GetHref(element);
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.anchor_text = element.innerText();
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL absolute_link_url;
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (node.isLink())
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    absolute_link_url = GetAbsoluteUrl(node, data.href);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL absolute_image_url;
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const blink::WebElement child_img = GetImgChild(element);
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!child_img.isNull()) {
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    absolute_image_url =
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        GetAbsoluteSrcUrl(child_img);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PopulateHitTestData(absolute_link_url,
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      absolute_image_url,
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      render_view()->IsEditableNode(node),
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      &data);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Send(new AwViewHostMsg_UpdateHitTestData(routing_id(), data));
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AwRenderViewExt::OnDoHitTest(int view_x, int view_y) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!render_view() || !render_view()->GetWebView())
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const blink::WebHitTestResult result =
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      render_view()->GetWebView()->hitTestResultAt(
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          blink::WebPoint(view_x, view_y));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AwHitTestData data;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!result.urlElement().isNull()) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data.anchor_text = result.urlElement().innerText();
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data.href = GetHref(result.urlElement());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PopulateHitTestData(result.absoluteLinkURL(),
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      result.absoluteImageURL(),
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      result.isContentEditable(),
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      &data);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new AwViewHostMsg_UpdateHitTestData(routing_id(), data));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void AwRenderViewExt::OnSetTextZoomFactor(float zoom_factor) {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!render_view() || !render_view()->GetWebView())
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Hide selection and autofill popups.
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  render_view()->GetWebView()->hidePopups();
294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  render_view()->GetWebView()->setTextZoomFactor(zoom_factor);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AwRenderViewExt::OnResetScrollAndScaleState() {
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!render_view() || !render_view()->GetWebView())
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  render_view()->GetWebView()->resetScrollAndScaleState();
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AwRenderViewExt::OnSetInitialPageScale(double page_scale_factor) {
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!render_view() || !render_view()->GetWebView())
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  render_view()->GetWebView()->setInitialPageScaleOverride(
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      page_scale_factor);
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
310a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid AwRenderViewExt::OnSetBackgroundColor(SkColor c) {
311a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (!render_view() || !render_view()->GetWebView())
312a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return;
313558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  render_view()->GetWebView()->setBaseBackgroundColor(c);
314a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
315a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace android_webview
317