Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1298)

Side by Side Diff: chrome/renderer/loadtimes_extension_bindings.cc

Issue 1750893003: Convert LoadTimeExtension to gin::Wrappable (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/renderer/loadtimes_extension_bindings.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/loadtimes_extension_bindings.h" 5 #include "chrome/renderer/loadtimes_extension_bindings.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/time/time.h" 9 #include "base/time/time.h"
10 #include "content/public/renderer/document_state.h" 10 #include "content/public/renderer/document_state.h"
11 #include "content/public/renderer/render_frame.h"
12 #include "gin/arguments.h"
13 #include "gin/handle.h"
14 #include "gin/object_template_builder.h"
11 #include "net/http/http_response_info.h" 15 #include "net/http/http_response_info.h"
16 #include "third_party/WebKit/public/web/WebKit.h"
12 #include "third_party/WebKit/public/web/WebLocalFrame.h" 17 #include "third_party/WebKit/public/web/WebLocalFrame.h"
13 #include "v8/include/v8.h" 18 #include "v8/include/v8.h"
14 19
15 using blink::WebDataSource; 20 using blink::WebDataSource;
16 using blink::WebLocalFrame; 21 using blink::WebLocalFrame;
17 using blink::WebNavigationType; 22 using blink::WebNavigationType;
18 using content::DocumentState; 23 using content::DocumentState;
19 24
25 namespace {
26
20 // Values for CSI "tran" property 27 // Values for CSI "tran" property
21 const int kTransitionLink = 0; 28 const int kTransitionLink = 0;
22 const int kTransitionForwardBack = 6; 29 const int kTransitionForwardBack = 6;
23 const int kTransitionOther = 15; 30 const int kTransitionOther = 15;
24 const int kTransitionReload = 16; 31 const int kTransitionReload = 16;
25 32
33 const char* GetNavigationType(WebNavigationType nav_type) {
34 switch (nav_type) {
35 case blink::WebNavigationTypeLinkClicked:
36 return "LinkClicked";
37 case blink::WebNavigationTypeFormSubmitted:
38 return "FormSubmitted";
39 case blink::WebNavigationTypeBackForward:
40 return "BackForward";
41 case blink::WebNavigationTypeReload:
42 return "Reload";
43 case blink::WebNavigationTypeFormResubmitted:
44 return "Resubmitted";
45 case blink::WebNavigationTypeOther:
46 return "Other";
47 }
48 return "";
49 }
50
51 int GetCSITransitionType(WebNavigationType nav_type) {
52 switch (nav_type) {
53 case blink::WebNavigationTypeLinkClicked:
54 case blink::WebNavigationTypeFormSubmitted:
55 case blink::WebNavigationTypeFormResubmitted:
56 return kTransitionLink;
57 case blink::WebNavigationTypeBackForward:
58 return kTransitionForwardBack;
59 case blink::WebNavigationTypeReload:
60 return kTransitionReload;
61 case blink::WebNavigationTypeOther:
62 return kTransitionOther;
63 }
64 return kTransitionOther;
65 }
66
67 } // namespace
68
26 namespace extensions_v8 { 69 namespace extensions_v8 {
27 70
28 static const char* const kLoadTimesExtensionName = "v8/LoadTimes"; 71 gin::WrapperInfo LoadTimesExtension::kWrapperInfo = {gin::kEmbedderNativeGin};
29 72
30 class LoadTimesExtensionWrapper : public v8::Extension { 73 LoadTimesExtensionHelper::LoadTimesExtensionHelper(
31 public: 74 content::RenderFrame* render_frame)
32 // Creates an extension which adds a new function, chromium.GetLoadTimes() 75 : RenderFrameObserver(render_frame) {}
33 // This function returns an object containing the following members:
34 // requestTime: The time the request to load the page was received
35 // loadTime: The time the renderer started the load process
36 // finishDocumentLoadTime: The time the document itself was loaded
37 // (this is before the onload() method is fired)
38 // finishLoadTime: The time all loading is done, after the onload()
39 // method and all resources
40 // navigationType: A string describing what user action initiated the load
41 LoadTimesExtensionWrapper() :
42 v8::Extension(kLoadTimesExtensionName,
43 "var chrome;"
44 "if (!chrome)"
45 " chrome = {};"
46 "chrome.loadTimes = function() {"
47 " native function GetLoadTimes();"
48 " return GetLoadTimes();"
49 "};"
50 "chrome.csi = function() {"
51 " native function GetCSI();"
52 " return GetCSI();"
53 "}") {}
54 76
55 v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate( 77 void LoadTimesExtensionHelper::DidFinishLoad() {
56 v8::Isolate* isolate, 78 LoadTimesExtension::Install(render_frame()->GetWebFrame());
57 v8::Local<v8::String> name) override { 79 }
58 if (name->Equals(v8::String::NewFromUtf8(isolate, "GetLoadTimes"))) { 80
59 return v8::FunctionTemplate::New(isolate, GetLoadTimes); 81 // static
60 } else if (name->Equals(v8::String::NewFromUtf8(isolate, "GetCSI"))) { 82 void LoadTimesExtension::Install(blink::WebFrame* frame) {
61 return v8::FunctionTemplate::New(isolate, GetCSI); 83 v8::Isolate* isolate = blink::mainThreadIsolate();
62 } 84 v8::HandleScope handle_scope(isolate);
63 return v8::Local<v8::FunctionTemplate>(); 85 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
86 if (context.IsEmpty()) return;
87
88 v8::Context::Scope context_scope(context);
89
90 gin::Handle<LoadTimesExtension> controller =
91 gin::CreateHandle(isolate, new LoadTimesExtension());
92 v8::Handle<v8::Object> global = context->Global();
93 v8::Handle<v8::Object> chrome =
94 global->Get(gin::StringToV8(isolate, "chrome"))->ToObject();
95 if (chrome.IsEmpty()) {
96 chrome = v8::Object::New(isolate);
97 global->Set(gin::StringToV8(isolate, "chrome"), chrome);
64 } 98 }
99 chrome->Set(gin::StringToV8(isolate, "loadTimesController"),
100 controller.ToV8());
101 }
65 102
66 static const char* GetNavigationType(WebNavigationType nav_type) { 103 gin::ObjectTemplateBuilder LoadTimesExtension::GetObjectTemplateBuilder(
67 switch (nav_type) { 104 v8::Isolate* isolate) {
68 case blink::WebNavigationTypeLinkClicked: 105 return gin::Wrappable<LoadTimesExtension>::GetObjectTemplateBuilder(isolate)
69 return "LinkClicked"; 106 .SetProperty("loadTimes", &LoadTimesExtension::LoadTimes)
70 case blink::WebNavigationTypeFormSubmitted: 107 .SetProperty("csi", &LoadTimesExtension::CSI);
71 return "FormSubmitted"; 108 }
72 case blink::WebNavigationTypeBackForward: 109
73 return "BackForward"; 110 v8::Local<v8::Object> LoadTimesExtension::LoadTimes() {
74 case blink::WebNavigationTypeReload: 111 WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext();
75 return "Reload"; 112 if (!frame) {
76 case blink::WebNavigationTypeFormResubmitted: 113 return v8::Local<v8::Object>();
77 return "Resubmitted";
78 case blink::WebNavigationTypeOther:
79 return "Other";
80 }
81 return "";
82 } 114 }
115 WebDataSource* data_source = frame->dataSource();
116 if (!data_source) {
117 return v8::Local<v8::Object>();
118 }
119 DocumentState* document_state = DocumentState::FromDataSource(data_source);
120 if (!document_state) {
121 return v8::Local<v8::Object>();
122 }
123 double request_time = document_state->request_time().ToDoubleT();
124 double start_load_time = document_state->start_load_time().ToDoubleT();
125 double commit_load_time = document_state->commit_load_time().ToDoubleT();
126 double finish_document_load_time =
127 document_state->finish_document_load_time().ToDoubleT();
128 double finish_load_time = document_state->finish_load_time().ToDoubleT();
129 double first_paint_time = document_state->first_paint_time().ToDoubleT();
130 double first_paint_after_load_time =
131 document_state->first_paint_after_load_time().ToDoubleT();
132 std::string navigation_type =
133 GetNavigationType(data_source->navigationType());
134 bool was_fetched_via_spdy = document_state->was_fetched_via_spdy();
135 bool was_npn_negotiated = document_state->was_npn_negotiated();
136 std::string npn_negotiated_protocol =
137 document_state->npn_negotiated_protocol();
138 bool was_alternate_protocol_available =
139 document_state->was_alternate_protocol_available();
140 std::string connection_info = net::HttpResponseInfo::ConnectionInfoToString(
141 document_state->connection_info());
142 // Important: |frame|, |data_source| and |document_state| should not be
143 // referred to below this line, as JS setters below can invalidate these
144 // pointers.
145 // v8::Isolate* isolate = args->isolate();
146 v8::Isolate* isolate = blink::mainThreadIsolate();
147 v8::Local<v8::Object> load_times = v8::Object::New(isolate);
148 load_times->Set(v8::String::NewFromUtf8(isolate, "requestTime"),
149 v8::Number::New(isolate, request_time));
150 load_times->Set(v8::String::NewFromUtf8(isolate, "startLoadTime"),
151 v8::Number::New(isolate, start_load_time));
152 load_times->Set(v8::String::NewFromUtf8(isolate, "commitLoadTime"),
153 v8::Number::New(isolate, commit_load_time));
154 load_times->Set(v8::String::NewFromUtf8(isolate, "finishDocumentLoadTime"),
155 v8::Number::New(isolate, finish_document_load_time));
156 load_times->Set(v8::String::NewFromUtf8(isolate, "finishLoadTime"),
157 v8::Number::New(isolate, finish_load_time));
158 load_times->Set(v8::String::NewFromUtf8(isolate, "firstPaintTime"),
159 v8::Number::New(isolate, first_paint_time));
160 load_times->Set(v8::String::NewFromUtf8(isolate, "firstPaintAfterLoadTime"),
161 v8::Number::New(isolate, first_paint_after_load_time));
162 load_times->Set(v8::String::NewFromUtf8(isolate, "navigationType"),
163 v8::String::NewFromUtf8(isolate, navigation_type.c_str()));
164 load_times->Set(v8::String::NewFromUtf8(isolate, "wasFetchedViaSpdy"),
165 v8::Boolean::New(isolate, was_fetched_via_spdy));
166 load_times->Set(v8::String::NewFromUtf8(isolate, "wasNpnNegotiated"),
167 v8::Boolean::New(isolate, was_npn_negotiated));
168 load_times->Set(
169 v8::String::NewFromUtf8(isolate, "npnNegotiatedProtocol"),
170 v8::String::NewFromUtf8(isolate, npn_negotiated_protocol.c_str()));
171 load_times->Set(
172 v8::String::NewFromUtf8(isolate, "wasAlternateProtocolAvailable"),
173 v8::Boolean::New(isolate, was_alternate_protocol_available));
174 load_times->Set(v8::String::NewFromUtf8(isolate, "connectionInfo"),
175 v8::String::NewFromUtf8(isolate, connection_info.c_str()));
176 return load_times;
177 }
83 178
84 static int GetCSITransitionType(WebNavigationType nav_type) { 179 v8::Local<v8::Object> LoadTimesExtension::CSI() {
85 switch (nav_type) { 180 WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext();
86 case blink::WebNavigationTypeLinkClicked: 181 if (!frame) {
87 case blink::WebNavigationTypeFormSubmitted: 182 return v8::Local<v8::Object>();
88 case blink::WebNavigationTypeFormResubmitted:
89 return kTransitionLink;
90 case blink::WebNavigationTypeBackForward:
91 return kTransitionForwardBack;
92 case blink::WebNavigationTypeReload:
93 return kTransitionReload;
94 case blink::WebNavigationTypeOther:
95 return kTransitionOther;
96 }
97 return kTransitionOther;
98 } 183 }
99 184 WebDataSource* data_source = frame->dataSource();
100 static void GetLoadTimes(const v8::FunctionCallbackInfo<v8::Value>& args) { 185 if (!data_source) {
101 WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext(); 186 return v8::Local<v8::Object>();
102 if (!frame) {
103 args.GetReturnValue().SetNull();
104 return;
105 }
106 WebDataSource* data_source = frame->dataSource();
107 if (!data_source) {
108 args.GetReturnValue().SetNull();
109 return;
110 }
111 DocumentState* document_state = DocumentState::FromDataSource(data_source);
112 if (!document_state) {
113 args.GetReturnValue().SetNull();
114 return;
115 }
116 double request_time = document_state->request_time().ToDoubleT();
117 double start_load_time = document_state->start_load_time().ToDoubleT();
118 double commit_load_time = document_state->commit_load_time().ToDoubleT();
119 double finish_document_load_time =
120 document_state->finish_document_load_time().ToDoubleT();
121 double finish_load_time = document_state->finish_load_time().ToDoubleT();
122 double first_paint_time = document_state->first_paint_time().ToDoubleT();
123 double first_paint_after_load_time =
124 document_state->first_paint_after_load_time().ToDoubleT();
125 std::string navigation_type =
126 GetNavigationType(data_source->navigationType());
127 bool was_fetched_via_spdy = document_state->was_fetched_via_spdy();
128 bool was_npn_negotiated = document_state->was_npn_negotiated();
129 std::string npn_negotiated_protocol =
130 document_state->npn_negotiated_protocol();
131 bool was_alternate_protocol_available =
132 document_state->was_alternate_protocol_available();
133 std::string connection_info = net::HttpResponseInfo::ConnectionInfoToString(
134 document_state->connection_info());
135 // Important: |frame|, |data_source| and |document_state| should not be
136 // referred to below this line, as JS setters below can invalidate these
137 // pointers.
138 v8::Isolate* isolate = args.GetIsolate();
139 v8::Local<v8::Object> load_times = v8::Object::New(isolate);
140 load_times->Set(v8::String::NewFromUtf8(isolate, "requestTime"),
141 v8::Number::New(isolate, request_time));
142 load_times->Set(v8::String::NewFromUtf8(isolate, "startLoadTime"),
143 v8::Number::New(isolate, start_load_time));
144 load_times->Set(v8::String::NewFromUtf8(isolate, "commitLoadTime"),
145 v8::Number::New(isolate, commit_load_time));
146 load_times->Set(v8::String::NewFromUtf8(isolate, "finishDocumentLoadTime"),
147 v8::Number::New(isolate, finish_document_load_time));
148 load_times->Set(v8::String::NewFromUtf8(isolate, "finishLoadTime"),
149 v8::Number::New(isolate, finish_load_time));
150 load_times->Set(v8::String::NewFromUtf8(isolate, "firstPaintTime"),
151 v8::Number::New(isolate, first_paint_time));
152 load_times->Set(v8::String::NewFromUtf8(isolate, "firstPaintAfterLoadTime"),
153 v8::Number::New(isolate, first_paint_after_load_time));
154 load_times->Set(v8::String::NewFromUtf8(isolate, "navigationType"),
155 v8::String::NewFromUtf8(isolate, navigation_type.c_str()));
156 load_times->Set(v8::String::NewFromUtf8(isolate, "wasFetchedViaSpdy"),
157 v8::Boolean::New(isolate, was_fetched_via_spdy));
158 load_times->Set(v8::String::NewFromUtf8(isolate, "wasNpnNegotiated"),
159 v8::Boolean::New(isolate, was_npn_negotiated));
160 load_times->Set(
161 v8::String::NewFromUtf8(isolate, "npnNegotiatedProtocol"),
162 v8::String::NewFromUtf8(isolate, npn_negotiated_protocol.c_str()));
163 load_times->Set(
164 v8::String::NewFromUtf8(isolate, "wasAlternateProtocolAvailable"),
165 v8::Boolean::New(isolate, was_alternate_protocol_available));
166 load_times->Set(v8::String::NewFromUtf8(isolate, "connectionInfo"),
167 v8::String::NewFromUtf8(isolate, connection_info.c_str()));
168 args.GetReturnValue().Set(load_times);
169 } 187 }
170 188 DocumentState* document_state = DocumentState::FromDataSource(data_source);
171 static void GetCSI(const v8::FunctionCallbackInfo<v8::Value>& args) { 189 if (!document_state) {
172 WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext(); 190 return v8::Local<v8::Object>();
173 if (!frame) {
174 args.GetReturnValue().SetNull();
175 return;
176 }
177 WebDataSource* data_source = frame->dataSource();
178 if (!data_source) {
179 args.GetReturnValue().SetNull();
180 return;
181 }
182 DocumentState* document_state = DocumentState::FromDataSource(data_source);
183 if (!document_state) {
184 args.GetReturnValue().SetNull();
185 return;
186 }
187 base::Time now = base::Time::Now();
188 base::Time start = document_state->request_time().is_null()
189 ? document_state->start_load_time()
190 : document_state->request_time();
191 base::Time onload = document_state->finish_document_load_time();
192 base::TimeDelta page = now - start;
193 int navigation_type = GetCSITransitionType(data_source->navigationType());
194 // Important: |frame|, |data_source| and |document_state| should not be
195 // referred to below this line, as JS setters below can invalidate these
196 // pointers.
197 v8::Isolate* isolate = args.GetIsolate();
198 v8::Local<v8::Object> csi = v8::Object::New(isolate);
199 csi->Set(v8::String::NewFromUtf8(isolate, "startE"),
200 v8::Number::New(isolate, floor(start.ToDoubleT() * 1000)));
201 csi->Set(v8::String::NewFromUtf8(isolate, "onloadT"),
202 v8::Number::New(isolate, floor(onload.ToDoubleT() * 1000)));
203 csi->Set(v8::String::NewFromUtf8(isolate, "pageT"),
204 v8::Number::New(isolate, page.InMillisecondsF()));
205 csi->Set(v8::String::NewFromUtf8(isolate, "tran"),
206 v8::Number::New(isolate, navigation_type));
207 args.GetReturnValue().Set(csi);
208 } 191 }
209 }; 192 base::Time now = base::Time::Now();
210 193 base::Time start = document_state->request_time().is_null()
211 v8::Extension* LoadTimesExtension::Get() { 194 ? document_state->start_load_time()
212 return new LoadTimesExtensionWrapper(); 195 : document_state->request_time();
196 base::Time onload = document_state->finish_document_load_time();
197 base::TimeDelta page = now - start;
198 int navigation_type = GetCSITransitionType(data_source->navigationType());
199 // Important: |frame|, |data_source| and |document_state| should not be
200 // referred to below this line, as JS setters below can invalidate these
201 // pointers.
202 v8::Isolate* isolate = blink::mainThreadIsolate();
203 v8::Local<v8::Object> csi = v8::Object::New(isolate);
204 csi->Set(v8::String::NewFromUtf8(isolate, "startE"),
205 v8::Number::New(isolate, floor(start.ToDoubleT() * 1000)));
206 csi->Set(v8::String::NewFromUtf8(isolate, "onloadT"),
207 v8::Number::New(isolate, floor(onload.ToDoubleT() * 1000)));
208 csi->Set(v8::String::NewFromUtf8(isolate, "pageT"),
209 v8::Number::New(isolate, page.InMillisecondsF()));
210 csi->Set(v8::String::NewFromUtf8(isolate, "tran"),
211 v8::Number::New(isolate, navigation_type));
212 return csi;
213 } 213 }
214 214
215 } // namespace extensions_v8 215 } // namespace extensions_v8
OLDNEW
« no previous file with comments | « chrome/renderer/loadtimes_extension_bindings.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698