#include "content/common/database_messages.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/common/drag_messages.h"
+#include "content/common/frame_messages.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "content/common/input_messages.h"
#include "content/common/java_bridge_messages.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
-#include "content/public/common/context_menu_params.h"
#include "content/public/common/drop_data.h"
#include "content/public/common/favicon_url.h"
#include "content/public/common/file_chooser_params.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "content/public/renderer/content_renderer_client.h"
-#include "content/public/renderer/context_menu_client.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/history_item_serialization.h"
#include "content/public/renderer/navigation_state.h"
#include "content/renderer/browser_plugin/browser_plugin.h"
#include "content/renderer/browser_plugin/browser_plugin_manager.h"
#include "content/renderer/browser_plugin/browser_plugin_manager_impl.h"
-#include "content/renderer/context_menu_params_builder.h"
#include "content/renderer/devtools/devtools_agent.h"
#include "content/renderer/disambiguation_popup_helper.h"
#include "content/renderer/dom_automation_controller.h"
#include "third_party/WebKit/public/web/WebPluginContainer.h"
#include "third_party/WebKit/public/web/WebPluginDocument.h"
#include "third_party/WebKit/public/web/WebRange.h"
-#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
#include "third_party/WebKit/public/web/WebScriptSource.h"
#include "third_party/WebKit/public/web/WebSearchableFormData.h"
#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
using blink::WebColor;
using blink::WebColorName;
using blink::WebConsoleMessage;
-using blink::WebContextMenuData;
using blink::WebData;
using blink::WebDataSource;
using blink::WebDocument;
using blink::WebRange;
using blink::WebRect;
using blink::WebReferrerPolicy;
-using blink::WebRuntimeFeatures;
using blink::WebScriptSource;
using blink::WebSearchableFormData;
using blink::WebSecurityOrigin;
static RenderViewImpl* (*g_create_render_view_impl)(RenderViewImplParams*) =
NULL;
-static bool IsReload(const ViewMsg_Navigate_Params& params) {
+// static
+bool RenderViewImpl::IsReload(const FrameMsg_Navigate_Params& params) {
return
- params.navigation_type == ViewMsg_Navigate_Type::RELOAD ||
- params.navigation_type == ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE ||
+ params.navigation_type == FrameMsg_Navigate_Type::RELOAD ||
+ params.navigation_type == FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE ||
params.navigation_type ==
- ViewMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
-}
-
-// static
-void RenderViewImpl::GetRedirectChain(WebDataSource* ds,
- std::vector<GURL>* result) {
- // Replace any occurrences of swappedout:// with about:blank.
- const WebURL& blank_url = GURL(kAboutBlankURL);
- WebVector<WebURL> urls;
- ds->redirectChain(urls);
- result->reserve(urls.size());
- for (size_t i = 0; i < urls.size(); ++i) {
- if (urls[i] != GURL(kSwappedOutURL))
- result->push_back(urls[i]);
- else
- result->push_back(blank_url);
- }
-}
-
-// static
-WebReferrerPolicy RenderViewImpl::GetReferrerPolicyFromRequest(
- WebFrame* frame,
- const WebURLRequest& request) {
- return request.extraData() ?
- static_cast<RequestExtraData*>(request.extraData())->referrer_policy() :
- frame->document().referrerPolicy();
+ FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
}
// static
WebFrame* frame,
const WebURLRequest& request) {
return Referrer(GURL(request.httpHeaderField(WebString::fromUTF8("Referer"))),
- GetReferrerPolicyFromRequest(frame, request));
-}
-
-// static
-WebURLResponseExtraDataImpl* RenderViewImpl::GetExtraDataFromResponse(
- const WebURLResponse& response) {
- return static_cast<WebURLResponseExtraDataImpl*>(
- response.extraData());
-}
-
-NOINLINE static void CrashIntentionally() {
- // NOTE(shess): Crash directly rather than using NOTREACHED() so
- // that the signature is easier to triage in crash reports.
- volatile int* zero = NULL;
- *zero = 0;
-}
-
-#if defined(ADDRESS_SANITIZER)
-NOINLINE static void MaybeTriggerAsanError(const GURL& url) {
- // NOTE(rogerm): We intentionally perform an invalid heap access here in
- // order to trigger an Address Sanitizer (ASAN) error report.
- static const char kCrashDomain[] = "crash";
- static const char kHeapOverflow[] = "/heap-overflow";
- static const char kHeapUnderflow[] = "/heap-underflow";
- static const char kUseAfterFree[] = "/use-after-free";
- static const int kArraySize = 5;
-
- if (!url.DomainIs(kCrashDomain, sizeof(kCrashDomain) - 1))
- return;
-
- if (!url.has_path())
- return;
-
- scoped_ptr<int[]> array(new int[kArraySize]);
- std::string crash_type(url.path());
- int dummy = 0;
- if (crash_type == kHeapOverflow) {
- dummy = array[kArraySize];
- } else if (crash_type == kHeapUnderflow ) {
- dummy = array[-1];
- } else if (crash_type == kUseAfterFree) {
- int* dangling = array.get();
- array.reset();
- dummy = dangling[kArraySize / 2];
- }
-
- // Make sure the assignments to the dummy value aren't optimized away.
- base::debug::Alias(&dummy);
-}
-#endif // ADDRESS_SANITIZER
-
-static void MaybeHandleDebugURL(const GURL& url) {
- if (!url.SchemeIs(chrome::kChromeUIScheme))
- return;
- if (url == GURL(kChromeUICrashURL)) {
- CrashIntentionally();
- } else if (url == GURL(kChromeUIKillURL)) {
- base::KillProcess(base::GetCurrentProcessHandle(), 1, false);
- } else if (url == GURL(kChromeUIHangURL)) {
- for (;;) {
- base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
- }
- } else if (url == GURL(kChromeUIShorthangURL)) {
- base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20));
- }
-
-#if defined(ADDRESS_SANITIZER)
- MaybeTriggerAsanError(url);
-#endif // ADDRESS_SANITIZER
+ request.referrerPolicy());
}
// Returns false unless this is a top-level navigation.
return false;
}
-static void NotifyTimezoneChange(blink::WebFrame* frame) {
+// static
+void RenderViewImpl::NotifyTimezoneChange(blink::WebFrame* frame) {
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
v8::Context::Scope context_scope(frame->mainWorldScriptContext());
v8::Date::DateTimeConfigurationChangeNotification(v8::Isolate::GetCurrent());
blink::WebWidget* webwidget_;
};
-int64 ExtractPostId(const WebHistoryItem& item) {
- if (item.isNull())
- return -1;
-
- if (item.httpBody().isNull())
- return -1;
-
- return item.httpBody().identifier();
-}
-
bool TouchEnabled() {
// Based on the definition of chrome::kEnableTouchIcon.
#if defined(OS_ANDROID)
session_storage_namespace_id_(params->session_storage_namespace_id),
handling_select_range_(false),
next_snapshot_id_(0),
- allow_partial_swap_(params->allow_partial_swap),
- context_menu_source_type_(ui::MENU_SOURCE_MOUSE) {
+ allow_partial_swap_(params->allow_partial_swap) {
}
void RenderViewImpl::Initialize(RenderViewImplParams* params) {
bool hidden,
int32 next_page_id,
const blink::WebScreenInfo& screen_info,
- AccessibilityMode accessibility_mode,
+ unsigned int accessibility_mode,
bool allow_partial_swap) {
DCHECK(routing_id != MSG_ROUTING_NONE);
RenderViewImplParams params(
OnSetEditCommandsForNextKeyEvent)
IPC_MESSAGE_HANDLER(InputMsg_Undo, OnUndo)
IPC_MESSAGE_HANDLER(InputMsg_Unselect, OnUnselect)
- IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
+ IPC_MESSAGE_HANDLER(FrameMsg_Navigate, OnNavigate)
IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop)
IPC_MESSAGE_HANDLER(ViewMsg_ReloadFrame, OnReloadFrame)
IPC_MESSAGE_HANDLER(ViewMsg_SetName, OnSetName)
OnOrientationChangeEvent)
IPC_MESSAGE_HANDLER(ViewMsg_PluginActionAt, OnPluginActionAt)
IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
- IPC_MESSAGE_HANDLER(ViewMsg_CustomContextMenuAction,
- OnCustomContextMenuAction)
IPC_MESSAGE_HANDLER(ViewMsg_GetAllSavableResourceLinksForCurrentPage,
OnGetAllSavableResourceLinksForCurrentPage)
IPC_MESSAGE_HANDLER(
ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks,
OnGetSerializedHtmlDataForCurrentPageWithLocalLinks)
- IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed)
IPC_MESSAGE_HANDLER(ViewMsg_ShowContextMenu, OnShowContextMenu)
// TODO(viettrungluu): Move to a separate message filter.
IPC_MESSAGE_HANDLER(ViewMsg_SetHistoryLengthAndPrune,
return handled;
}
-void RenderViewImpl::OnNavigate(const ViewMsg_Navigate_Params& params) {
- MaybeHandleDebugURL(params.url);
- if (!webview())
- return;
-
+void RenderViewImpl::OnNavigate(const FrameMsg_Navigate_Params& params) {
FOR_EACH_OBSERVER(RenderViewObserver, observers_, Navigate(params.url));
-
- bool is_reload = IsReload(params);
- WebURLRequest::CachePolicy cache_policy =
- WebURLRequest::UseProtocolCachePolicy;
-
- // If this is a stale back/forward (due to a recent navigation the browser
- // didn't know about), ignore it.
- if (IsBackForwardToStaleEntry(params, is_reload))
- return;
-
- // Swap this renderer back in if necessary.
- if (is_swapped_out_) {
- // We marked the view as hidden when swapping the view out, so be sure to
- // reset the visibility state before navigating to the new URL.
- webview()->setVisibilityState(visibilityState(), false);
-
- // If this is an attempt to reload while we are swapped out, we should not
- // reload swappedout://, but the previous page, which is stored in
- // params.state. Setting is_reload to false will treat this like a back
- // navigation to accomplish that.
- is_reload = false;
- cache_policy = WebURLRequest::ReloadIgnoringCacheData;
-
- // We refresh timezone when a view is swapped in since timezone
- // can get out of sync when the system timezone is updated while
- // the view is swapped out.
- NotifyTimezoneChange(webview()->mainFrame());
-
- SetSwappedOut(false);
- }
-
- if (params.should_clear_history_list) {
- CHECK_EQ(params.pending_history_list_offset, -1);
- CHECK_EQ(params.current_history_list_offset, -1);
- CHECK_EQ(params.current_history_list_length, 0);
- }
- history_list_offset_ = params.current_history_list_offset;
- history_list_length_ = params.current_history_list_length;
- if (history_list_length_ >= 0)
- history_page_ids_.resize(history_list_length_, -1);
- if (params.pending_history_list_offset >= 0 &&
- params.pending_history_list_offset < history_list_length_)
- history_page_ids_[params.pending_history_list_offset] = params.page_id;
-
- GetContentClient()->SetActiveURL(params.url);
-
- WebFrame* frame = webview()->mainFrame();
- if (!params.frame_to_navigate.empty()) {
- frame = webview()->findFrameByName(
- WebString::fromUTF8(params.frame_to_navigate));
- CHECK(frame) << "Invalid frame name passed: " << params.frame_to_navigate;
- }
-
- if (is_reload && frame->currentHistoryItem().isNull()) {
- // We cannot reload if we do not have any history state. This happens, for
- // example, when recovering from a crash.
- is_reload = false;
- cache_policy = WebURLRequest::ReloadIgnoringCacheData;
- }
-
- pending_navigation_params_.reset(new ViewMsg_Navigate_Params(params));
-
- // If we are reloading, then WebKit will use the history state of the current
- // page, so we should just ignore any given history state. Otherwise, if we
- // have history state, then we need to navigate to it, which corresponds to a
- // back/forward navigation event.
- if (is_reload) {
- bool reload_original_url =
- (params.navigation_type ==
- ViewMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
- bool ignore_cache = (params.navigation_type ==
- ViewMsg_Navigate_Type::RELOAD_IGNORING_CACHE);
-
- if (reload_original_url)
- frame->reloadWithOverrideURL(params.url, true);
- else
- frame->reload(ignore_cache);
- } else if (params.page_state.IsValid()) {
- // We must know the page ID of the page we are navigating back to.
- DCHECK_NE(params.page_id, -1);
- WebHistoryItem item = PageStateToHistoryItem(params.page_state);
- if (!item.isNull()) {
- // Ensure we didn't save the swapped out URL in UpdateState, since the
- // browser should never be telling us to navigate to swappedout://.
- CHECK(item.urlString() != WebString::fromUTF8(kSwappedOutURL));
- frame->loadHistoryItem(item, cache_policy);
- }
- } else if (!params.base_url_for_data_url.is_empty()) {
- // A loadData request with a specified base URL.
- std::string mime_type, charset, data;
- if (net::DataURL::Parse(params.url, &mime_type, &charset, &data)) {
- frame->loadData(
- WebData(data.c_str(), data.length()),
- WebString::fromUTF8(mime_type),
- WebString::fromUTF8(charset),
- params.base_url_for_data_url,
- params.history_url_for_data_url,
- false);
- } else {
- CHECK(false) <<
- "Invalid URL passed: " << params.url.possibly_invalid_spec();
- }
- } else {
- // Navigate to the given URL.
- WebURLRequest request(params.url);
-
- // A session history navigation should have been accompanied by state.
- CHECK_EQ(params.page_id, -1);
-
- if (frame->isViewSourceModeEnabled())
- request.setCachePolicy(WebURLRequest::ReturnCacheDataElseLoad);
-
- if (params.referrer.url.is_valid()) {
- WebString referrer = WebSecurityPolicy::generateReferrerHeader(
- params.referrer.policy,
- params.url,
- WebString::fromUTF8(params.referrer.url.spec()));
- if (!referrer.isEmpty())
- request.setHTTPHeaderField(WebString::fromUTF8("Referer"), referrer);
- }
-
- if (!params.extra_headers.empty()) {
- for (net::HttpUtil::HeadersIterator i(params.extra_headers.begin(),
- params.extra_headers.end(), "\n");
- i.GetNext(); ) {
- request.addHTTPHeaderField(WebString::fromUTF8(i.name()),
- WebString::fromUTF8(i.values()));
- }
- }
-
- if (params.is_post) {
- request.setHTTPMethod(WebString::fromUTF8("POST"));
-
- // Set post data.
- WebHTTPBody http_body;
- http_body.initialize();
- const char* data = NULL;
- if (params.browser_initiated_post_data.size()) {
- data = reinterpret_cast<const char*>(
- ¶ms.browser_initiated_post_data.front());
- }
- http_body.appendData(
- WebData(data, params.browser_initiated_post_data.size()));
- request.setHTTPBody(http_body);
- }
-
- frame->loadRequest(request);
-
- // If this is a cross-process navigation, the browser process will send
- // along the proper navigation start value.
- if (!params.browser_navigation_start.is_null() &&
- frame->provisionalDataSource()) {
- // browser_navigation_start is likely before this process existed, so we
- // can't use InterProcessTimeTicksConverter. Instead, the best we can do
- // is just ensure we don't report a bogus value in the future.
- base::TimeTicks navigation_start = std::min(
- base::TimeTicks::Now(), params.browser_navigation_start);
- double navigation_start_seconds =
- (navigation_start - base::TimeTicks()).InSecondsF();
- frame->provisionalDataSource()->setNavigationStartTime(
- navigation_start_seconds);
- }
- }
-
- // In case LoadRequest failed before DidCreateDataSource was called.
- pending_navigation_params_.reset();
}
bool RenderViewImpl::IsBackForwardToStaleEntry(
- const ViewMsg_Navigate_Params& params,
+ const FrameMsg_Navigate_Params& params,
bool is_reload) {
// Make sure this isn't a back/forward to an entry we have already cropped
// or replaced from our history, before the browser knew about it. If so,
if (webview())
webview()->mainFrame()->stopLoading();
FOR_EACH_OBSERVER(RenderViewObserver, observers_, OnStop());
+ main_render_frame_->OnStop();
}
// Reload current focused frame.
///////////////////////////////////////////////////////////////////////////////
-// Tell the embedding application that the URL of the active page has changed
-void RenderViewImpl::UpdateURL(WebFrame* frame) {
- WebDataSource* ds = frame->dataSource();
- DCHECK(ds);
-
- const WebURLRequest& request = ds->request();
- const WebURLRequest& original_request = ds->originalRequest();
- const WebURLResponse& response = ds->response();
-
- DocumentState* document_state = DocumentState::FromDataSource(ds);
- NavigationState* navigation_state = document_state->navigation_state();
- InternalDocumentStateData* internal_data =
- InternalDocumentStateData::FromDocumentState(document_state);
-
- ViewHostMsg_FrameNavigate_Params params;
- params.http_status_code = response.httpStatusCode();
- params.is_post = false;
- params.post_id = -1;
- params.page_id = page_id_;
- params.frame_id = frame->identifier();
- params.frame_unique_name = frame->uniqueName();
- params.socket_address.set_host(response.remoteIPAddress().utf8());
- params.socket_address.set_port(response.remotePort());
- WebURLResponseExtraDataImpl* extra_data = GetExtraDataFromResponse(response);
- if (extra_data) {
- params.was_fetched_via_proxy = extra_data->was_fetched_via_proxy();
- }
- params.was_within_same_page = navigation_state->was_within_same_page();
- params.security_info = response.securityInfo();
-
- // Set the URL to be displayed in the browser UI to the user.
- params.url = GetLoadingUrl(frame);
- DCHECK(!is_swapped_out_ || params.url == GURL(kSwappedOutURL));
-
- if (frame->document().baseURL() != params.url)
- params.base_url = frame->document().baseURL();
-
- GetRedirectChain(ds, ¶ms.redirects);
- params.should_update_history = !ds->hasUnreachableURL() &&
- !response.isMultipartPayload() && (response.httpStatusCode() != 404);
-
- params.searchable_form_url = internal_data->searchable_form_url();
- params.searchable_form_encoding = internal_data->searchable_form_encoding();
-
- params.gesture = navigation_gesture_;
- navigation_gesture_ = NavigationGestureUnknown;
-
- // Make navigation state a part of the FrameNavigate message so that commited
- // entry had it at all times.
- WebHistoryItem item = frame->currentHistoryItem();
- if (item.isNull()) {
- item.initialize();
- item.setURLString(request.url().spec().utf16());
- }
- params.page_state = HistoryItemToPageState(item);
-
- if (!frame->parent()) {
- // Top-level navigation.
-
- // Reset the zoom limits in case a plugin had changed them previously. This
- // will also call us back which will cause us to send a message to
- // update WebContentsImpl.
- webview()->zoomLimitsChanged(ZoomFactorToZoomLevel(kMinimumZoomFactor),
- ZoomFactorToZoomLevel(kMaximumZoomFactor));
-
- // Set zoom level, but don't do it for full-page plugin since they don't use
- // the same zoom settings.
- HostZoomLevels::iterator host_zoom =
- host_zoom_levels_.find(GURL(request.url()));
- if (webview()->mainFrame()->document().isPluginDocument()) {
- // Reset the zoom levels for plugins.
- webview()->setZoomLevel(0);
- } else {
- if (host_zoom != host_zoom_levels_.end())
- webview()->setZoomLevel(host_zoom->second);
- }
-
- if (host_zoom != host_zoom_levels_.end()) {
- // This zoom level was merely recorded transiently for this load. We can
- // erase it now. If at some point we reload this page, the browser will
- // send us a new, up-to-date zoom level.
- host_zoom_levels_.erase(host_zoom);
- }
-
- // Update contents MIME type for main frame.
- params.contents_mime_type = ds->response().mimeType().utf8();
-
- params.transition = navigation_state->transition_type();
- if (!PageTransitionIsMainFrame(params.transition)) {
- // If the main frame does a load, it should not be reported as a subframe
- // navigation. This can occur in the following case:
- // 1. You're on a site with frames.
- // 2. You do a subframe navigation. This is stored with transition type
- // MANUAL_SUBFRAME.
- // 3. You navigate to some non-frame site, say, google.com.
- // 4. You navigate back to the page from step 2. Since it was initially
- // MANUAL_SUBFRAME, it will be that same transition type here.
- // We don't want that, because any navigation that changes the toplevel
- // frame should be tracked as a toplevel navigation (this allows us to
- // update the URL bar, etc).
- params.transition = PAGE_TRANSITION_LINK;
- }
-
- // If the page contained a client redirect (meta refresh, document.loc...),
- // set the referrer and transition appropriately.
- if (ds->isClientRedirect()) {
- params.referrer = Referrer(params.redirects[0],
- GetReferrerPolicyFromRequest(frame, ds->request()));
- params.transition = static_cast<PageTransition>(
- params.transition | PAGE_TRANSITION_CLIENT_REDIRECT);
- } else {
- params.referrer = GetReferrerFromRequest(frame, ds->request());
- }
-
- base::string16 method = request.httpMethod();
- if (EqualsASCII(method, "POST")) {
- params.is_post = true;
- params.post_id = ExtractPostId(item);
- }
-
- // Send the user agent override back.
- params.is_overriding_user_agent = internal_data->is_overriding_user_agent();
-
- // Track the URL of the original request. We use the first entry of the
- // redirect chain if it exists because the chain may have started in another
- // process.
- if (params.redirects.size() > 0)
- params.original_request_url = params.redirects.at(0);
- else
- params.original_request_url = original_request.url();
-
- params.history_list_was_cleared =
- navigation_state->history_list_was_cleared();
-
- // Save some histogram data so we can compute the average memory used per
- // page load of the glyphs.
- UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad",
- blink::WebGlyphCache::pageCount());
-
- // This message needs to be sent before any of allowScripts(),
- // allowImages(), allowPlugins() is called for the new page, so that when
- // these functions send a ViewHostMsg_ContentBlocked message, it arrives
- // after the ViewHostMsg_FrameNavigate message.
- Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
- } else {
- // Subframe navigation: the type depends on whether this navigation
- // generated a new session history entry. When they do generate a session
- // history entry, it means the user initiated the navigation and we should
- // mark it as such. This test checks if this is the first time UpdateURL
- // has been called since WillNavigateToURL was called to initiate the load.
- if (page_id_ > last_page_id_sent_to_browser_)
- params.transition = PAGE_TRANSITION_MANUAL_SUBFRAME;
- else
- params.transition = PAGE_TRANSITION_AUTO_SUBFRAME;
-
- DCHECK(!navigation_state->history_list_was_cleared());
- params.history_list_was_cleared = false;
-
- // Don't send this message while the subframe is swapped out.
- // TODO(creis): This whole method should move to RenderFrame.
- RenderFrameImpl* rf = RenderFrameImpl::FromWebFrame(frame);
- if (!rf || !rf->is_swapped_out())
- Send(new ViewHostMsg_FrameNavigate(routing_id_, params));
- }
-
- last_page_id_sent_to_browser_ =
- std::max(last_page_id_sent_to_browser_, page_id_);
-
- // If we end up reusing this WebRequest (for example, due to a #ref click),
- // we don't want the transition type to persist. Just clear it.
- navigation_state->set_transition_type(PAGE_TRANSITION_LINK);
-}
-
// Tell the embedding application that the title of the active page has changed
void RenderViewImpl::UpdateTitle(WebFrame* frame,
const base::string16& title,
is_loading_ = true;
- Send(new ViewHostMsg_DidStartLoading(routing_id_));
+ // Send the IPC message through the top-level frame.
+ main_render_frame_->didStartLoading();
FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStartLoading());
}
// displayed when done loading. Ideally we would send notification when
// finished parsing the head, but webkit doesn't support that yet.
// The feed discovery code would also benefit from access to the head.
- Send(new ViewHostMsg_DidStopLoading(routing_id_));
+ // NOTE: Sending of the IPC message happens through the top-level frame.
+ main_render_frame_->didStopLoading();
if (load_progress_tracker_ != NULL)
load_progress_tracker_->DidStopLoading();
}
void RenderViewImpl::showContextMenu(
- WebFrame* frame, const WebContextMenuData& data) {
- ContextMenuParams params = ContextMenuParamsBuilder::Build(data);
- params.source_type = context_menu_source_type_;
- if (context_menu_source_type_ == ui::MENU_SOURCE_TOUCH_EDIT_MENU) {
- params.x = touch_editing_context_menu_location_.x();
- params.y = touch_editing_context_menu_location_.y();
- }
- OnShowHostContextMenu(¶ms);
-
- // Plugins, e.g. PDF, don't currently update the render view when their
- // selected text changes, but the context menu params do contain the updated
- // selection. If that's the case, update the render view's state just prior
- // to showing the context menu.
- // TODO(asvitkine): http://crbug.com/152432
- if (ShouldUpdateSelectionTextFromContextMenuParams(selection_text_,
- selection_text_offset_,
- selection_range_,
- params)) {
- selection_text_ = params.selection_text;
- // TODO(asvitkine): Text offset and range is not available in this case.
- selection_text_offset_ = 0;
- selection_range_ = gfx::Range(0, selection_text_.length());
- Send(new ViewHostMsg_SelectionChanged(routing_id_,
- selection_text_,
- selection_text_offset_,
- selection_range_));
- }
-
- // frame is NULL if invoked by BlockedPlugin.
- if (frame)
- params.frame_id = frame->identifier();
-
- // Serializing a GURL longer than kMaxURLChars will fail, so don't do
- // it. We replace it with an empty GURL so the appropriate items are disabled
- // in the context menu.
- // TODO(jcivelli): http://crbug.com/45160 This prevents us from saving large
- // data encoded images. We should have a way to save them.
- if (params.src_url.spec().size() > GetMaxURLChars())
- params.src_url = GURL();
- context_menu_node_ = data.node;
-
-#if defined(OS_ANDROID)
- gfx::Rect start_rect;
- gfx::Rect end_rect;
- GetSelectionBounds(&start_rect, &end_rect);
- params.selection_start = gfx::Point(start_rect.x(), start_rect.bottom());
- params.selection_end = gfx::Point(end_rect.right(), end_rect.bottom());
-#endif
-
- Send(new ViewHostMsg_ContextMenu(routing_id_, params));
-
- FOR_EACH_OBSERVER(
- RenderViewObserver, observers_, DidRequestShowContextMenu(frame, data));
+ WebFrame* frame, const blink::WebContextMenuData& data) {
+ // TODO(jam): move this method to WebFrameClient.
+ RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame);
+ render_frame->showContextMenu(data);
}
void RenderViewImpl::clearContextMenu() {
base::Unretained(GetContentClient()->renderer()),
static_cast<RenderFrame*>(render_frame)),
sink);
- return new WebMediaPlayerImpl(this, frame, client, AsWeakPtr(), params);
+ return new WebMediaPlayerImpl(frame, client, AsWeakPtr(), params);
#endif // defined(OS_ANDROID)
}
net::registry_controlled_domains::SameDomainOrHost(
frame_url,
url,
- net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
+ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
if (!same_domain_or_host || frame_url.scheme() != url.scheme()) {
OpenURL(frame, url, referrer, default_policy);
return blink::WebNavigationPolicyIgnore;
void RenderViewImpl::PopulateDocumentStateFromPending(
DocumentState* document_state) {
- const ViewMsg_Navigate_Params& params = *pending_navigation_params_.get();
+ const FrameMsg_Navigate_Params& params = *pending_navigation_params_.get();
document_state->set_request_time(params.request_time);
InternalDocumentStateData* internal_data =
InternalDocumentStateData::FromDocumentState(document_state);
if (!params.url.SchemeIs(kJavaScriptScheme) &&
- params.navigation_type == ViewMsg_Navigate_Type::RESTORE) {
+ params.navigation_type == FrameMsg_Navigate_Type::RESTORE) {
// We're doing a load of a page that was restored from the last session. By
// default this prefers the cache over loading (LOAD_PREFERRING_CACHE) which
// can result in stale data for pages that are set to expire. We explicitly
else
document_state->set_load_type(DocumentState::NORMAL_LOAD);
- internal_data->set_referrer_policy(params.referrer.policy);
internal_data->set_is_overriding_user_agent(params.is_overriding_user_agent);
internal_data->set_must_reset_scroll_and_scale_state(
params.navigation_type ==
- ViewMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
+ FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
document_state->set_can_load_local_resources(params.can_load_local_resources);
}
NavigationState* RenderViewImpl::CreateNavigationStateFromPending() {
- const ViewMsg_Navigate_Params& params = *pending_navigation_params_.get();
+ const FrameMsg_Navigate_Params& params = *pending_navigation_params_.get();
NavigationState* navigation_state = NULL;
// A navigation resulting from loading a javascript URL should not be treated
void RenderViewImpl::didCommitProvisionalLoad(WebFrame* frame,
bool is_new_navigation) {
- DocumentState* document_state =
- DocumentState::FromDataSource(frame->dataSource());
- NavigationState* navigation_state = document_state->navigation_state();
- InternalDocumentStateData* internal_data =
- InternalDocumentStateData::FromDocumentState(document_state);
-
- if (document_state->commit_load_time().is_null())
- document_state->set_commit_load_time(Time::Now());
-
- if (internal_data->must_reset_scroll_and_scale_state()) {
- webview()->resetScrollAndScaleState();
- internal_data->set_must_reset_scroll_and_scale_state(false);
- }
- internal_data->set_use_error_page(false);
- internal_data->clear_referrer_policy();
-
- if (is_new_navigation) {
- // When we perform a new navigation, we need to update the last committed
- // session history entry with state for the page we are leaving.
- UpdateSessionHistory(frame);
-
- // We bump our Page ID to correspond with the new session history entry.
- page_id_ = next_page_id_++;
-
- // Don't update history_page_ids_ (etc) for kSwappedOutURL, since
- // we don't want to forget the entry that was there, and since we will
- // never come back to kSwappedOutURL. Note that we have to call
- // UpdateSessionHistory and update page_id_ even in this case, so that
- // the current entry gets a state update and so that we don't send a
- // state update to the wrong entry when we swap back in.
- if (GetLoadingUrl(frame) != GURL(kSwappedOutURL)) {
- // Advance our offset in session history, applying the length limit.
- // There is now no forward history.
- history_list_offset_++;
- if (history_list_offset_ >= kMaxSessionHistoryEntries)
- history_list_offset_ = kMaxSessionHistoryEntries - 1;
- history_list_length_ = history_list_offset_ + 1;
- history_page_ids_.resize(history_list_length_, -1);
- history_page_ids_[history_list_offset_] = page_id_;
- }
- } else {
- // Inspect the navigation_state on this frame to see if the navigation
- // corresponds to a session history navigation... Note: |frame| may or
- // may not be the toplevel frame, but for the case of capturing session
- // history, the first committed frame suffices. We keep track of whether
- // we've seen this commit before so that only capture session history once
- // per navigation.
- //
- // Note that we need to check if the page ID changed. In the case of a
- // reload, the page ID doesn't change, and UpdateSessionHistory gets the
- // previous URL and the current page ID, which would be wrong.
- if (navigation_state->pending_page_id() != -1 &&
- navigation_state->pending_page_id() != page_id_ &&
- !navigation_state->request_committed()) {
- // This is a successful session history navigation!
- UpdateSessionHistory(frame);
- page_id_ = navigation_state->pending_page_id();
-
- history_list_offset_ = navigation_state->pending_history_list_offset();
-
- // If the history list is valid, our list of page IDs should be correct.
- DCHECK(history_list_length_ <= 0 ||
- history_list_offset_ < 0 ||
- history_list_offset_ >= history_list_length_ ||
- history_page_ids_[history_list_offset_] == page_id_);
- }
- }
-
FOR_EACH_OBSERVER(RenderViewObserver, observers_,
DidCommitProvisionalLoad(frame, is_new_navigation));
- // Remember that we've already processed this request, so we don't update
- // the session history again. We do this regardless of whether this is
- // a session history navigation, because if we attempted a session history
- // navigation without valid HistoryItem state, WebCore will think it is a
- // new navigation.
- navigation_state->set_request_committed(true);
-
- UpdateURL(frame);
-
- // Check whether we have new encoding name.
- UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
-
+ // TODO(nasko): Transition this code to RenderFrameImpl, since g_view_map is
+ // not accessible from there.
if (!frame->parent()) { // Only for top frames.
RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
if (render_thread_impl) { // Can be NULL in tests.
if (world_id)
return;
+ if (enabled_bindings_& BINDINGS_POLICY_WEB_UI)
+ WebUIExtension::Install(frame);
+
if (enabled_bindings_ & BINDINGS_POLICY_DOM_AUTOMATION)
DomAutomationController::Install(this, frame);
}
void RenderViewImpl::didFinishDocumentLoad(WebFrame* frame) {
- WebDataSource* ds = frame->dataSource();
- DocumentState* document_state = DocumentState::FromDataSource(ds);
- document_state->set_finish_document_load_time(Time::Now());
-
- Send(new ViewHostMsg_DocumentLoadedInFrame(routing_id_, frame->identifier()));
-
FOR_EACH_OBSERVER(RenderViewObserver, observers_,
DidFinishDocumentLoad(frame));
-
- // Check whether we have new encoding name.
- UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
}
void RenderViewImpl::didHandleOnloadEvents(WebFrame* frame) {
}
void RenderViewImpl::didFailLoad(WebFrame* frame, const WebURLError& error) {
- WebDataSource* ds = frame->dataSource();
- DCHECK(ds);
-
-
FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidFailLoad(frame, error));
-
- const WebURLRequest& failed_request = ds->request();
- base::string16 error_description;
- GetContentClient()->renderer()->GetNavigationErrorStrings(
- this,
- frame,
- failed_request,
- error,
- NULL,
- &error_description);
- Send(new ViewHostMsg_DidFailLoadWithError(routing_id_,
- frame->identifier(),
- failed_request.url(),
- !frame->parent(),
- error.reason,
- error_description));
}
void RenderViewImpl::didFinishLoad(WebFrame* frame) {
}
void RenderViewImpl::didNavigateWithinPage(
- WebFrame* frame, bool is_new_navigation) {
- // If this was a reference fragment navigation that we initiated, then we
- // could end up having a non-null pending navigation params. We just need to
- // update the ExtraData on the datasource so that others who read the
- // ExtraData will get the new NavigationState. Similarly, if we did not
- // initiate this navigation, then we need to take care to reset any pre-
- // existing navigation state to a content-initiated navigation state.
- // DidCreateDataSource conveniently takes care of this for us.
- didCreateDataSource(frame, frame->dataSource());
-
- DocumentState* document_state =
- DocumentState::FromDataSource(frame->dataSource());
- NavigationState* new_state = document_state->navigation_state();
- new_state->set_was_within_same_page(true);
-
- didCommitProvisionalLoad(frame, is_new_navigation);
+ WebFrame* frame,
+ bool is_new_navigation) {
+ // TODO(nasko): Forward calls to the main RenderFrameImpl until all
+ // callers of this method on RenderView are removed.
+ main_render_frame_->didNavigateWithinPage(frame, is_new_navigation);
}
void RenderViewImpl::didUpdateCurrentHistoryItem(WebFrame* frame) {
final_status_update));
}
-// static
-bool RenderViewImpl::ShouldUpdateSelectionTextFromContextMenuParams(
- const base::string16& selection_text,
- size_t selection_text_offset,
- const gfx::Range& selection_range,
- const ContextMenuParams& params) {
- base::string16 trimmed_selection_text;
- if (!selection_text.empty() && !selection_range.is_empty()) {
- const int start = selection_range.GetMin() - selection_text_offset;
- const size_t length = selection_range.length();
- if (start >= 0 && start + length <= selection_text.length()) {
- TrimWhitespace(selection_text.substr(start, length), TRIM_ALL,
- &trimmed_selection_text);
- }
- }
- base::string16 trimmed_params_text;
- TrimWhitespace(params.selection_text, TRIM_ALL, &trimmed_params_text);
- return trimmed_params_text != trimmed_selection_text;
-}
-
void RenderViewImpl::reportFindInPageMatchCount(int request_id,
int count,
bool final_update) {
WebFrame* frame,
WebStorageQuotaType type,
unsigned long long requested_size,
- WebStorageQuotaCallbacks* callbacks) {
+ blink::WebStorageQuotaCallbacks callbacks) {
NOTREACHED();
}
return filtered_time_per_frame();
}
-int RenderViewImpl::ShowContextMenu(ContextMenuClient* client,
- const ContextMenuParams& params) {
- DCHECK(client); // A null client means "internal" when we issue callbacks.
- ContextMenuParams our_params(params);
- our_params.custom_context.request_id = pending_context_menus_.Add(client);
- Send(new ViewHostMsg_ContextMenu(routing_id_, our_params));
- return our_params.custom_context.request_id;
-}
-
-void RenderViewImpl::CancelContextMenu(int request_id) {
- DCHECK(pending_context_menus_.Lookup(request_id));
- pending_context_menus_.Remove(request_id);
-}
-
blink::WebPageVisibilityState RenderViewImpl::GetVisibilityState() const {
return visibilityState();
}
}
void RenderViewImpl::DidPlay(blink::WebMediaPlayer* player) {
- Send(new ViewHostMsg_MediaNotification(routing_id_,
- reinterpret_cast<int64>(player),
- player->hasVideo(),
- player->hasAudio(),
- true));
+ Send(new ViewHostMsg_MediaPlayingNotification(routing_id_,
+ reinterpret_cast<int64>(player),
+ player->hasVideo(),
+ player->hasAudio()));
}
void RenderViewImpl::DidPause(blink::WebMediaPlayer* player) {
- Send(new ViewHostMsg_MediaNotification(routing_id_,
- reinterpret_cast<int64>(player),
- player->hasVideo(),
- player->hasAudio(),
- false));
+ Send(new ViewHostMsg_MediaPausedNotification(
+ routing_id_, reinterpret_cast<int64>(player)));
}
void RenderViewImpl::PlayerGone(blink::WebMediaPlayer* player) {
if (!frame)
return;
- frame->document().insertUserStyleSheet(
- WebString::fromUTF8(css),
- WebDocument::UserStyleAuthorLevel);
+ frame->document().insertStyleSheet(WebString::fromUTF8(css));
}
void RenderViewImpl::OnAllowBindings(int enabled_bindings_flags) {
if ((enabled_bindings_flags & BINDINGS_POLICY_WEB_UI) &&
!(enabled_bindings_ & BINDINGS_POLICY_WEB_UI)) {
- // WebUI uses <dialog> which is not yet enabled by default in Chrome.
- WebRuntimeFeatures::enableDialogElement(true);
-
- RenderThread::Get()->RegisterExtension(WebUIExtension::Get());
new WebUIExtensionData(this);
}
NotifyTimezoneChange(webview()->mainFrame());
}
-void RenderViewImpl::OnCustomContextMenuAction(
- const CustomContextMenuContext& custom_context,
- unsigned action) {
- if (custom_context.request_id) {
- // External context menu request, look in our map.
- ContextMenuClient* client =
- pending_context_menus_.Lookup(custom_context.request_id);
- if (client)
- client->OnMenuAction(custom_context.request_id, action);
- } else {
- // Internal request, forward to WebKit.
- webview()->performCustomContextMenuAction(action);
- }
-}
-
void RenderViewImpl::OnEnumerateDirectoryResponse(
int id,
const std::vector<base::FilePath>& paths) {
SetBackground(background);
}
-void RenderViewImpl::OnSetAccessibilityMode(AccessibilityMode new_mode) {
+void RenderViewImpl::OnSetAccessibilityMode(unsigned int new_mode) {
if (accessibility_mode_ == new_mode)
return;
accessibility_mode_ = new_mode;
delete renderer_accessibility_;
renderer_accessibility_ = NULL;
}
- if (accessibility_mode_ == AccessibilityModeComplete)
+ if (accessibility_mode_ == AccessibilityModeOff)
+ return;
+
+ if (accessibility_mode_ & AccessibilityModeFlagPlatformFullTree)
renderer_accessibility_ = new RendererAccessibilityComplete(this);
#if !defined(OS_ANDROID)
- else if (accessibility_mode_ == AccessibilityModeEditableTextOnly)
+ else
renderer_accessibility_ = new RendererAccessibilityFocusOnly(this);
#endif
}
}
bool RenderViewImpl::WillHandleMouseEvent(const blink::WebMouseEvent& event) {
- context_menu_source_type_ = ui::MENU_SOURCE_MOUSE;
possible_drag_event_info_.event_source =
ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE;
possible_drag_event_info_.event_location =
return mouse_lock_dispatcher_->WillHandleMouseEvent(event);
}
-bool RenderViewImpl::WillHandleKeyEvent(const blink::WebKeyboardEvent& event) {
- context_menu_source_type_ = ui::MENU_SOURCE_KEYBOARD;
- return false;
-}
-
bool RenderViewImpl::WillHandleGestureEvent(
const blink::WebGestureEvent& event) {
- context_menu_source_type_ = ui::MENU_SOURCE_TOUCH;
possible_drag_event_info_.event_source =
ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH;
possible_drag_event_info_.event_location =
blink::WebMIDIClient* RenderViewImpl::webMIDIClient() {
if (!midi_dispatcher_)
- midi_dispatcher_ = new MIDIDispatcher(this);
+ midi_dispatcher_ = new MidiDispatcher(this);
return midi_dispatcher_;
}
}
return new WebMediaPlayerAndroid(
- frame,
- client,
- AsWeakPtr(),
- media_player_manager_,
- stream_texture_factory.release(),
- RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy(),
- new RenderMediaLog());
+ frame,
+ client,
+ AsWeakPtr(),
+ media_player_manager_,
+ stream_texture_factory.release(),
+ RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy(),
+ new RenderMediaLog());
}
#endif // defined(OS_ANDROID)
}
#endif
-void RenderViewImpl::OnContextMenuClosed(
- const CustomContextMenuContext& custom_context) {
- if (custom_context.request_id) {
- // External request, should be in our map.
- ContextMenuClient* client =
- pending_context_menus_.Lookup(custom_context.request_id);
- if (client) {
- client->OnMenuClosed(custom_context.request_id);
- pending_context_menus_.Remove(custom_context.request_id);
- }
- } else {
- // Internal request, forward to WebKit.
- context_menu_node_.reset();
- }
-}
-
void RenderViewImpl::OnShowContextMenu(const gfx::Point& location) {
context_menu_source_type_ = ui::MENU_SOURCE_TOUCH_EDIT_MENU;
touch_editing_context_menu_location_ = location;
const WebVector<WebRect>& target_rects) {
// Never show a disambiguation popup when accessibility is enabled,
// as this interferes with "touch exploration".
- if (accessibility_mode_ == AccessibilityModeComplete)
+ bool matchesAccessibilityModeComplete =
+ (accessibility_mode_ & AccessibilityModeComplete) ==
+ AccessibilityModeComplete;
+ if (matchesAccessibilityModeComplete)
return false;
gfx::Rect finger_rect(