blob: 9005128093d6dc1c345b4db7146648d7338cd42f [file] [log] [blame]
[email protected]c20210e62009-04-03 21:39:261// Copyright (c) 2006-2009 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
[email protected]0bc46552009-04-07 21:56:425#include "chrome/renderer/loadtimes_extension_bindings.h"
[email protected]c20210e62009-04-03 21:39:266
[email protected]c80efa12009-06-30 20:06:417#include <math.h>
8
[email protected]c20210e62009-04-03 21:39:269#include "base/time.h"
[email protected]921f1592011-03-18 00:41:0210#include "content/renderer/navigation_state.h"
[email protected]8bd0fe62011-01-17 06:44:3711#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
[email protected]c80efa12009-06-30 20:06:4112#include "v8/include/v8.h"
[email protected]726985e22009-06-18 21:09:2813
14using WebKit::WebDataSource;
[email protected]dd7daa82009-08-10 05:46:4515using WebKit::WebFrame;
[email protected]726985e22009-06-18 21:09:2816using WebKit::WebNavigationType;
[email protected]c20210e62009-04-03 21:39:2617
[email protected]c80efa12009-06-30 20:06:4118// Values for CSI "tran" property
19const int kTransitionLink = 0;
20const int kTransitionForwardBack = 6;
21const int kTransitionOther = 15;
22const int kTransitionReload = 16;
23
[email protected]c20210e62009-04-03 21:39:2624namespace extensions_v8 {
25
[email protected]088bd872009-10-19 16:47:2326static const char* const kLoadTimesExtensionName = "v8/LoadTimes";
[email protected]c20210e62009-04-03 21:39:2627
28class LoadTimesExtensionWrapper : public v8::Extension {
29 public:
30 // Creates an extension which adds a new function, chromium.GetLoadTimes()
31 // This function returns an object containing the following members:
32 // requestTime: The time the request to load the page was received
33 // loadTime: The time the renderer started the load process
34 // finishDocumentLoadTime: The time the document itself was loaded
35 // (this is before the onload() method is fired)
36 // finishLoadTime: The time all loading is done, after the onload()
37 // method and all resources
38 // navigationType: A string describing what user action initiated the load
39 LoadTimesExtensionWrapper() :
40 v8::Extension(kLoadTimesExtensionName,
[email protected]a2f6bc112009-06-27 16:27:2541 "var chrome;"
42 "if (!chrome)"
43 " chrome = {};"
[email protected]c80efa12009-06-30 20:06:4144 "chrome.loadTimes = function() {"
[email protected]c20210e62009-04-03 21:39:2645 " native function GetLoadTimes();"
46 " return GetLoadTimes();"
[email protected]c80efa12009-06-30 20:06:4147 "};"
48 "chrome.csi = function() {"
49 " native function GetCSI();"
50 " return GetCSI();"
[email protected]c20210e62009-04-03 21:39:2651 "}") {}
52
53 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
54 v8::Handle<v8::String> name) {
55 if (name->Equals(v8::String::New("GetLoadTimes"))) {
56 return v8::FunctionTemplate::New(GetLoadTimes);
[email protected]c80efa12009-06-30 20:06:4157 } else if (name->Equals(v8::String::New("GetCSI"))) {
58 return v8::FunctionTemplate::New(GetCSI);
[email protected]c20210e62009-04-03 21:39:2659 }
60 return v8::Handle<v8::FunctionTemplate>();
61 }
62
[email protected]088bd872009-10-19 16:47:2363 static const char* GetNavigationType(WebNavigationType nav_type) {
[email protected]c20210e62009-04-03 21:39:2664 switch (nav_type) {
[email protected]726985e22009-06-18 21:09:2865 case WebKit::WebNavigationTypeLinkClicked:
66 return "LinkClicked";
67 case WebKit::WebNavigationTypeFormSubmitted:
68 return "FormSubmitted";
69 case WebKit::WebNavigationTypeBackForward:
70 return "BackForward";
71 case WebKit::WebNavigationTypeReload:
72 return "Reload";
73 case WebKit::WebNavigationTypeFormResubmitted:
74 return "Resubmitted";
75 case WebKit::WebNavigationTypeOther:
76 return "Other";
[email protected]c20210e62009-04-03 21:39:2677 }
78 return "";
79 }
80
[email protected]c80efa12009-06-30 20:06:4181 static int GetCSITransitionType(WebNavigationType nav_type) {
82 switch (nav_type) {
83 case WebKit::WebNavigationTypeLinkClicked:
84 case WebKit::WebNavigationTypeFormSubmitted:
85 case WebKit::WebNavigationTypeFormResubmitted:
86 return kTransitionLink;
87 case WebKit::WebNavigationTypeBackForward:
88 return kTransitionForwardBack;
89 case WebKit::WebNavigationTypeReload:
90 return kTransitionReload;
91 case WebKit::WebNavigationTypeOther:
92 return kTransitionOther;
93 }
94 return kTransitionOther;
95 }
96
[email protected]c20210e62009-04-03 21:39:2697 static v8::Handle<v8::Value> GetLoadTimes(const v8::Arguments& args) {
[email protected]79997c832010-02-09 01:06:3898 WebFrame* frame = WebFrame::frameForCurrentContext();
[email protected]ed3fb032009-06-16 19:50:5699 if (frame) {
[email protected]dd7daa82009-08-10 05:46:45100 WebDataSource* data_source = frame->dataSource();
[email protected]c20210e62009-04-03 21:39:26101 if (data_source) {
[email protected]6256e212009-06-29 20:22:41102 NavigationState* navigation_state =
103 NavigationState::FromDataSource(data_source);
[email protected]c20210e62009-04-03 21:39:26104 v8::Local<v8::Object> load_times = v8::Object::New();
105 load_times->Set(
106 v8::String::New("requestTime"),
[email protected]ed3fb032009-06-16 19:50:56107 v8::Number::New(navigation_state->request_time().ToDoubleT()));
[email protected]c20210e62009-04-03 21:39:26108 load_times->Set(
109 v8::String::New("startLoadTime"),
[email protected]ed3fb032009-06-16 19:50:56110 v8::Number::New(navigation_state->start_load_time().ToDoubleT()));
[email protected]c20210e62009-04-03 21:39:26111 load_times->Set(
[email protected]a2f6bc112009-06-27 16:27:25112 v8::String::New("commitLoadTime"),
113 v8::Number::New(navigation_state->commit_load_time().ToDoubleT()));
114 load_times->Set(
[email protected]c20210e62009-04-03 21:39:26115 v8::String::New("finishDocumentLoadTime"),
116 v8::Number::New(
[email protected]ed3fb032009-06-16 19:50:56117 navigation_state->finish_document_load_time().ToDoubleT()));
[email protected]c20210e62009-04-03 21:39:26118 load_times->Set(
119 v8::String::New("finishLoadTime"),
[email protected]ed3fb032009-06-16 19:50:56120 v8::Number::New(navigation_state->finish_load_time().ToDoubleT()));
[email protected]c20210e62009-04-03 21:39:26121 load_times->Set(
[email protected]a2f6bc112009-06-27 16:27:25122 v8::String::New("firstPaintTime"),
123 v8::Number::New(navigation_state->first_paint_time().ToDoubleT()));
[email protected]e7e4f3c2009-04-21 15:24:08124 load_times->Set(
[email protected]c80efa12009-06-30 20:06:41125 v8::String::New("firstPaintAfterLoadTime"),
126 v8::Number::New(
127 navigation_state->first_paint_after_load_time().ToDoubleT()));
128 load_times->Set(
[email protected]c20210e62009-04-03 21:39:26129 v8::String::New("navigationType"),
[email protected]726985e22009-06-18 21:09:28130 v8::String::New(GetNavigationType(data_source->navigationType())));
[email protected]9fc38b32010-01-11 21:34:46131 load_times->Set(
132 v8::String::New("wasFetchedViaSpdy"),
133 v8::Boolean::New(navigation_state->was_fetched_via_spdy()));
[email protected]65041fa2010-05-21 06:56:53134 load_times->Set(
135 v8::String::New("wasNpnNegotiated"),
136 v8::Boolean::New(navigation_state->was_npn_negotiated()));
[email protected]193b0b892010-06-26 03:57:57137 load_times->Set(
138 v8::String::New("wasAlternateProtocolAvailable"),
139 v8::Boolean::New(
140 navigation_state->was_alternate_protocol_available()));
[email protected]c20210e62009-04-03 21:39:26141 return load_times;
142 }
143 }
144 return v8::Null();
145 }
[email protected]c80efa12009-06-30 20:06:41146
147 static v8::Handle<v8::Value> GetCSI(const v8::Arguments& args) {
[email protected]79997c832010-02-09 01:06:38148 WebFrame* frame = WebFrame::frameForCurrentContext();
[email protected]c80efa12009-06-30 20:06:41149 if (frame) {
[email protected]dd7daa82009-08-10 05:46:45150 WebDataSource* data_source = frame->dataSource();
[email protected]c80efa12009-06-30 20:06:41151 if (data_source) {
152 NavigationState* navigation_state =
153 NavigationState::FromDataSource(data_source);
154 v8::Local<v8::Object> csi = v8::Object::New();
155 base::Time now = base::Time::Now();
156 base::Time start = navigation_state->request_time().is_null() ?
157 navigation_state->start_load_time() :
158 navigation_state->request_time();
159 base::Time onload = navigation_state->finish_document_load_time();
160 base::TimeDelta page = now - start;
161 csi->Set(
162 v8::String::New("startE"),
163 v8::Number::New(floor(start.ToDoubleT() * 1000)));
164 csi->Set(
165 v8::String::New("onloadT"),
166 v8::Number::New(floor(onload.ToDoubleT() * 1000)));
167 csi->Set(
168 v8::String::New("pageT"),
169 v8::Number::New(page.InMillisecondsF()));
170 csi->Set(
171 v8::String::New("tran"),
172 v8::Number::New(
173 GetCSITransitionType(data_source->navigationType())));
174
175 return csi;
176 }
177 }
178 return v8::Null();
179 }
[email protected]c20210e62009-04-03 21:39:26180};
181
182v8::Extension* LoadTimesExtension::Get() {
183 return new LoadTimesExtensionWrapper();
184}
185
186} // namespace extensions_v8