Path: blob/main/plugins/default-browser-emulator/injected-scripts/window.chrome.ts
1029 views
function toSeconds(millis) {1let entry = (millis / 1000).toFixed(3);2if (entry.endsWith('0')) entry = entry.substr(0, entry.length - 1);3return parseFloat(entry);4}56interface PerformanceEntry {7loadEventEnd: number;8responseStart: number;9domContentLoadedEventEnd: number;10type: string;11nextHopProtocol: string;12}1314// from https://developers.google.com/web/updates/2017/12/chrome-loadtimes-deprecated15const loadTimeConversion = {16requestTime() {17const ntEntry = performance.getEntriesByType('navigation')[0];18const start = ntEntry ? ntEntry.startTime : 0;19return toSeconds(start + performance.timeOrigin);20},21startLoadTime() {22const ntEntry = performance.getEntriesByType('navigation')[0];23const start = ntEntry ? ntEntry.startTime : 0;24return toSeconds(start + performance.timeOrigin);25},26commitLoadTime() {27const ntEntry = performance.getEntriesByType('navigation')[0];28const start = ntEntry ? ntEntry.responseStart : 0;29return toSeconds(start + performance.timeOrigin);30},31finishDocumentLoadTime() {32const ntEntry = performance.getEntriesByType('navigation')[0];33const start = ntEntry ? ntEntry.domContentLoadedEventEnd : 0;34return toSeconds(start + performance.timeOrigin);35},36finishLoadTime() {37const ntEntry = performance.getEntriesByType('navigation')[0];38const start = ntEntry ? ntEntry.loadEventEnd : 0;39return toSeconds(start + performance.timeOrigin);40},41firstPaintTime() {42let fpEntry: { startTime: number } = performance.getEntriesByType('paint')[0];43if (!fpEntry) {44const ntEntry = performance.getEntriesByType('navigation')[0];45const start = ntEntry ? ntEntry.loadEventEnd : 0;46fpEntry = { startTime: start + Math.random() * 85 };47}48return toSeconds(fpEntry.startTime + performance.timeOrigin);49},50navigationType() {51const ntEntry = performance.getEntriesByType('navigation')[0];52if (!ntEntry) return 'Other';53switch (ntEntry.type) {54case 'back_forward':55return 'BackForward';56case 'reload':57return 'Reload';58case 'prerender':59case 'navigate':60default:61return 'Other';62}63// case blink::kWebNavigationTypeLinkClicked:64// return "LinkClicked";65// case blink::kWebNavigationTypeFormSubmitted:66// return "FormSubmitted";67// case blink::kWebNavigationTypeFormResubmitted:68// return "Resubmitted";69},70wasFetchedViaSpdy() {71// SPDY is deprecated in favor of HTTP/2, but this implementation returns72// true for HTTP/2 or HTTP2+QUIC/39 as well.73const ntEntry = performance.getEntriesByType('navigation')[0];74if (!ntEntry) return true;75return ['h2', 'hq'].includes(ntEntry.nextHopProtocol);76},77wasNpnNegotiated() {78// NPN is deprecated in favor of ALPN, but this implementation returns true79// for HTTP/2 or HTTP2+QUIC/39 requests negotiated via ALPN.80const ntEntry = performance.getEntriesByType('navigation')[0];81if (!ntEntry) return true;82return ['h2', 'hq'].includes(ntEntry.nextHopProtocol);83},84connectionInfo() {85const ntEntry = performance.getEntriesByType('navigation')[0];86if (!ntEntry) return 'h2';87return ntEntry.nextHopProtocol;88},89};9091const csiConversion = {92startE() {93const ntEntry = performance.getEntriesByType('navigation')[0];94const start = ntEntry ? ntEntry.loadEventEnd : 0;95return parseInt((start + performance.timeOrigin) as any, 10);96},97onloadT() {98const ntEntry = performance.getEntriesByType('navigation')[0];99const load = ntEntry ? ntEntry.domContentLoadedEventEnd : 0;100return parseInt((load + performance.timeOrigin) as any, 10);101},102pageT() {103return parseFloat(performance.now().toFixed(3));104},105tran() {106const ntEntry = performance.getEntriesByType('navigation')[0];107const type = ntEntry ? ntEntry.type : 'navigate';108// https://chromium.googlesource.com/chromium/src.git/+/master/chrome/renderer/loadtimes_extension_bindings.cc109switch (type) {110case 'back_forward':111return 6;112case 'reload':113return 16;114case 'prerender':115case 'navigate':116default:117return 15;118}119/**120*121const int kTransitionLink = 0;122123case blink::kWebNavigationTypeLinkClicked:124case blink::kWebNavigationTypeFormSubmitted:125case blink::kWebNavigationTypeFormResubmitted:126return kTransitionLink;127*/128},129};130131const polyfill = args.polyfill;132const { prevProperty, property } = polyfill;133if (args.updateLoadTimes) {134for (const [name, func] of Object.entries(loadTimeConversion)) {135property.loadTimes['new()'][name]['_$$value()'] = func;136}137for (const [name, func] of Object.entries(csiConversion)) {138property.csi['new()'][name]['_$$value()'] = func;139}140}141const descriptor = buildDescriptor(property);142addDescriptorAfterProperty('window', prevProperty, 'chrome', descriptor);143144145