Roll src/third_party/WebKit 3c1b001:57aef96 (svn 201977:201978)
[chromium-blink-merge.git] / chrome / renderer / loadtimes_extension_bindings.cc
blob036c98064308cb465e0386bea6b540ae115774f2
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
3 // found in the LICENSE file.
5 #include "chrome/renderer/loadtimes_extension_bindings.h"
7 #include <math.h>
9 #include "base/time/time.h"
10 #include "content/public/renderer/document_state.h"
11 #include "net/http/http_response_info.h"
12 #include "third_party/WebKit/public/web/WebLocalFrame.h"
13 #include "v8/include/v8.h"
15 using blink::WebDataSource;
16 using blink::WebLocalFrame;
17 using blink::WebNavigationType;
18 using content::DocumentState;
20 // Values for CSI "tran" property
21 const int kTransitionLink = 0;
22 const int kTransitionForwardBack = 6;
23 const int kTransitionOther = 15;
24 const int kTransitionReload = 16;
26 namespace extensions_v8 {
28 static const char* const kLoadTimesExtensionName = "v8/LoadTimes";
30 class LoadTimesExtensionWrapper : public v8::Extension {
31 public:
32 // Creates an extension which adds a new function, chromium.GetLoadTimes()
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 "}") {}
55 v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate(
56 v8::Isolate* isolate,
57 v8::Local<v8::String> name) override {
58 if (name->Equals(v8::String::NewFromUtf8(isolate, "GetLoadTimes"))) {
59 return v8::FunctionTemplate::New(isolate, GetLoadTimes);
60 } else if (name->Equals(v8::String::NewFromUtf8(isolate, "GetCSI"))) {
61 return v8::FunctionTemplate::New(isolate, GetCSI);
63 return v8::Local<v8::FunctionTemplate>();
66 static const char* GetNavigationType(WebNavigationType nav_type) {
67 switch (nav_type) {
68 case blink::WebNavigationTypeLinkClicked:
69 return "LinkClicked";
70 case blink::WebNavigationTypeFormSubmitted:
71 return "FormSubmitted";
72 case blink::WebNavigationTypeBackForward:
73 return "BackForward";
74 case blink::WebNavigationTypeReload:
75 return "Reload";
76 case blink::WebNavigationTypeFormResubmitted:
77 return "Resubmitted";
78 case blink::WebNavigationTypeOther:
79 return "Other";
81 return "";
84 static int GetCSITransitionType(WebNavigationType nav_type) {
85 switch (nav_type) {
86 case blink::WebNavigationTypeLinkClicked:
87 case blink::WebNavigationTypeFormSubmitted:
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;
97 return kTransitionOther;
100 static void GetLoadTimes(const v8::FunctionCallbackInfo<v8::Value>& args) {
101 WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext();
102 if (frame) {
103 WebDataSource* data_source = frame->dataSource();
104 if (data_source) {
105 DocumentState* document_state =
106 DocumentState::FromDataSource(data_source);
107 v8::Isolate* isolate = args.GetIsolate();
108 v8::Local<v8::Object> load_times = v8::Object::New(isolate);
109 load_times->Set(
110 v8::String::NewFromUtf8(isolate, "requestTime"),
111 v8::Number::New(isolate,
112 document_state->request_time().ToDoubleT()));
113 load_times->Set(
114 v8::String::NewFromUtf8(isolate, "startLoadTime"),
115 v8::Number::New(isolate,
116 document_state->start_load_time().ToDoubleT()));
117 load_times->Set(
118 v8::String::NewFromUtf8(isolate, "commitLoadTime"),
119 v8::Number::New(isolate,
120 document_state->commit_load_time().ToDoubleT()));
121 load_times->Set(
122 v8::String::NewFromUtf8(isolate, "finishDocumentLoadTime"),
123 v8::Number::New(
124 isolate,
125 document_state->finish_document_load_time().ToDoubleT()));
126 load_times->Set(
127 v8::String::NewFromUtf8(isolate, "finishLoadTime"),
128 v8::Number::New(isolate,
129 document_state->finish_load_time().ToDoubleT()));
130 load_times->Set(
131 v8::String::NewFromUtf8(isolate, "firstPaintTime"),
132 v8::Number::New(isolate,
133 document_state->first_paint_time().ToDoubleT()));
134 load_times->Set(
135 v8::String::NewFromUtf8(isolate, "firstPaintAfterLoadTime"),
136 v8::Number::New(
137 isolate,
138 document_state->first_paint_after_load_time().ToDoubleT()));
139 load_times->Set(
140 v8::String::NewFromUtf8(isolate, "navigationType"),
141 v8::String::NewFromUtf8(
142 isolate, GetNavigationType(data_source->navigationType())));
143 load_times->Set(
144 v8::String::NewFromUtf8(isolate, "wasFetchedViaSpdy"),
145 v8::Boolean::New(isolate, document_state->was_fetched_via_spdy()));
146 load_times->Set(
147 v8::String::NewFromUtf8(isolate, "wasNpnNegotiated"),
148 v8::Boolean::New(isolate, document_state->was_npn_negotiated()));
149 load_times->Set(
150 v8::String::NewFromUtf8(isolate, "npnNegotiatedProtocol"),
151 v8::String::NewFromUtf8(
152 isolate, document_state->npn_negotiated_protocol().c_str()));
153 load_times->Set(
154 v8::String::NewFromUtf8(isolate, "wasAlternateProtocolAvailable"),
155 v8::Boolean::New(
156 isolate, document_state->was_alternate_protocol_available()));
157 load_times->Set(v8::String::NewFromUtf8(isolate, "connectionInfo"),
158 v8::String::NewFromUtf8(
159 isolate,
160 net::HttpResponseInfo::ConnectionInfoToString(
161 document_state->connection_info()).c_str()));
162 args.GetReturnValue().Set(load_times);
163 return;
166 args.GetReturnValue().SetNull();
169 static void GetCSI(const v8::FunctionCallbackInfo<v8::Value>& args) {
170 WebLocalFrame* frame = WebLocalFrame::frameForCurrentContext();
171 if (frame) {
172 WebDataSource* data_source = frame->dataSource();
173 if (data_source) {
174 DocumentState* document_state =
175 DocumentState::FromDataSource(data_source);
176 v8::Isolate* isolate = args.GetIsolate();
177 v8::Local<v8::Object> csi = v8::Object::New(isolate);
178 base::Time now = base::Time::Now();
179 base::Time start = document_state->request_time().is_null() ?
180 document_state->start_load_time() :
181 document_state->request_time();
182 base::Time onload = document_state->finish_document_load_time();
183 base::TimeDelta page = now - start;
184 csi->Set(v8::String::NewFromUtf8(isolate, "startE"),
185 v8::Number::New(isolate, floor(start.ToDoubleT() * 1000)));
186 csi->Set(v8::String::NewFromUtf8(isolate, "onloadT"),
187 v8::Number::New(isolate, floor(onload.ToDoubleT() * 1000)));
188 csi->Set(v8::String::NewFromUtf8(isolate, "pageT"),
189 v8::Number::New(isolate, page.InMillisecondsF()));
190 csi->Set(
191 v8::String::NewFromUtf8(isolate, "tran"),
192 v8::Number::New(
193 isolate, GetCSITransitionType(data_source->navigationType())));
195 args.GetReturnValue().Set(csi);
196 return;
199 args.GetReturnValue().SetNull();
200 return;
204 v8::Extension* LoadTimesExtension::Get() {
205 return new LoadTimesExtensionWrapper();
208 } // namespace extensions_v8