1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/subresource_filter/content/browser/navigation_console_logger.h"
6 
7 #include "base/memory/ptr_util.h"
8 #include "content/public/browser/navigation_handle.h"
9 
10 namespace subresource_filter {
11 
12 // static
LogMessageOnCommit(content::NavigationHandle * handle,blink::mojom::ConsoleMessageLevel level,const std::string & message)13 void NavigationConsoleLogger::LogMessageOnCommit(
14     content::NavigationHandle* handle,
15     blink::mojom::ConsoleMessageLevel level,
16     const std::string& message) {
17   DCHECK(handle->IsInMainFrame());
18   if (handle->HasCommitted() && !handle->IsErrorPage()) {
19     handle->GetRenderFrameHost()->AddMessageToConsole(level, message);
20   } else {
21     NavigationConsoleLogger::CreateIfNeededForNavigation(handle)
22         ->commit_messages_.emplace_back(level, message);
23   }
24 }
25 
26 // static
CreateIfNeededForNavigation(content::NavigationHandle * handle)27 NavigationConsoleLogger* NavigationConsoleLogger::CreateIfNeededForNavigation(
28     content::NavigationHandle* handle) {
29   DCHECK(handle->IsInMainFrame());
30   content::WebContents* contents = handle->GetWebContents();
31   auto* logger = FromWebContents(contents);
32   if (!logger) {
33     auto new_logger = base::WrapUnique(new NavigationConsoleLogger(handle));
34     logger = new_logger.get();
35     contents->SetUserData(UserDataKey(), std::move(new_logger));
36   }
37   return logger;
38 }
39 
40 NavigationConsoleLogger::~NavigationConsoleLogger() = default;
41 
NavigationConsoleLogger(content::NavigationHandle * handle)42 NavigationConsoleLogger::NavigationConsoleLogger(
43     content::NavigationHandle* handle)
44     : content::WebContentsObserver(handle->GetWebContents()), handle_(handle) {}
45 
DidFinishNavigation(content::NavigationHandle * handle)46 void NavigationConsoleLogger::DidFinishNavigation(
47     content::NavigationHandle* handle) {
48   if (handle != handle_)
49     return;
50 
51   // The main frame navigation has finished.
52   if (handle->HasCommitted() && !handle->IsErrorPage()) {
53     for (const auto& message : commit_messages_) {
54       handle->GetRenderFrameHost()->AddMessageToConsole(message.first,
55                                                         message.second);
56     }
57   }
58   // Deletes |this|.
59   web_contents()->RemoveUserData(UserDataKey());
60 }
61 
62 WEB_CONTENTS_USER_DATA_KEY_IMPL(NavigationConsoleLogger)
63 
64 }  // namespace subresource_filter
65