chrome-devtools-frontend
Version:
Chrome DevTools UI
139 lines (113 loc) • 5.45 kB
text/typescript
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as Platform from '../../../core/platform/platform.js';
import * as Types from '../types/types.js';
import {getNavigationForTraceEvent} from './Trace.js';
export const millisecondsToMicroseconds = (value: Types.Timing.MilliSeconds): Types.Timing.MicroSeconds =>
Types.Timing.MicroSeconds(value * 1000);
export const secondsToMilliseconds = (value: Types.Timing.Seconds): Types.Timing.MilliSeconds =>
Types.Timing.MilliSeconds(value * 1000);
export const secondsToMicroseconds = (value: Types.Timing.Seconds): Types.Timing.MicroSeconds =>
millisecondsToMicroseconds(secondsToMilliseconds(value));
export const microSecondsToMilliseconds = (value: Types.Timing.MicroSeconds): Types.Timing.MilliSeconds =>
Types.Timing.MilliSeconds(value / 1000);
export function detectBestTimeUnit(timeInMicroseconds: Types.Timing.MicroSeconds): Types.Timing.TimeUnit {
if (timeInMicroseconds < 1000) {
return Types.Timing.TimeUnit.MICROSECONDS;
}
const timeInMilliseconds = timeInMicroseconds / 1000;
if (timeInMilliseconds < 1000) {
return Types.Timing.TimeUnit.MILLISECONDS;
}
const timeInSeconds = timeInMilliseconds / 1000;
if (timeInSeconds < 60) {
return Types.Timing.TimeUnit.SECONDS;
}
return Types.Timing.TimeUnit.MINUTES;
}
interface FormatOptions extends Intl.NumberFormatOptions {
format?: Types.Timing.TimeUnit;
}
const defaultFormatOptions = {
style: 'unit',
unit: 'millisecond',
unitDisplay: 'narrow',
};
// Create a bunch of common formatters up front, so that we're not creating
// them repeatedly during rendering.
const serialize = (value: {}): string => JSON.stringify(value);
const formatterFactory = (key: string|undefined): Intl.NumberFormat => {
return new Intl.NumberFormat(navigator.language, key ? JSON.parse(key) : {});
};
const formatters = new Map<string, Intl.NumberFormat>();
// Microsecond Formatter.
Platform.MapUtilities.getWithDefault(formatters, serialize({style: 'decimal'}), formatterFactory);
// Millisecond Formatter
Platform.MapUtilities.getWithDefault(formatters, serialize(defaultFormatOptions), formatterFactory);
// Second Formatter
Platform.MapUtilities.getWithDefault(
formatters, serialize({...defaultFormatOptions, unit: 'second'}), formatterFactory);
// Minute Formatter
Platform.MapUtilities.getWithDefault(
formatters, serialize({...defaultFormatOptions, unit: 'minute'}), formatterFactory);
export function formatMicrosecondsTime(
timeInMicroseconds: Types.Timing.MicroSeconds, opts: FormatOptions = {}): string {
if (!opts.format) {
opts.format = detectBestTimeUnit(timeInMicroseconds);
}
const timeInMilliseconds = timeInMicroseconds / 1000;
const timeInSeconds = timeInMilliseconds / 1000;
const formatterOpts = {...defaultFormatOptions, ...opts};
switch (opts.format) {
case Types.Timing.TimeUnit.MICROSECONDS: {
const formatter =
Platform.MapUtilities.getWithDefault(formatters, serialize({style: 'decimal'}), formatterFactory);
return `${formatter.format(timeInMicroseconds)}μs`;
}
case Types.Timing.TimeUnit.MILLISECONDS: {
const formatter = Platform.MapUtilities.getWithDefault(formatters, serialize(formatterOpts), formatterFactory);
return formatter.format(timeInMilliseconds);
}
case Types.Timing.TimeUnit.SECONDS: {
const formatter = Platform.MapUtilities.getWithDefault(
formatters, serialize({...formatterOpts, unit: 'second'}), formatterFactory);
return formatter.format(timeInSeconds);
}
default: {
// Switch to mins & seconds.
const minuteFormatter = Platform.MapUtilities.getWithDefault(
formatters, serialize({...formatterOpts, unit: 'minute'}), formatterFactory);
const secondFormatter = Platform.MapUtilities.getWithDefault(
formatters, serialize({...formatterOpts, unit: 'second'}), formatterFactory);
const timeInMinutes = timeInSeconds / 60;
const [mins, divider, fraction] = minuteFormatter.formatToParts(timeInMinutes);
let seconds = 0;
if (divider && fraction) {
// Convert the fraction value (a string) to the nearest second.
seconds = Math.round(Number(`0.${fraction.value}`) * 60);
}
return `${minuteFormatter.format(Number(mins.value))} ${secondFormatter.format(seconds)}`;
}
}
}
export function timeStampForEventAdjustedByClosestNavigation(
event: Types.TraceEvents.TraceEventData,
traceBounds: Types.Timing.TraceWindow,
navigationsByNavigationId: Map<string, Types.TraceEvents.TraceEventNavigationStart>,
navigationsByFrameId: Map<string, Types.TraceEvents.TraceEventNavigationStart[]>,
): Types.Timing.MicroSeconds {
let eventTimeStamp = event.ts - traceBounds.min;
if (event.args?.data?.navigationId) {
const navigationForEvent = navigationsByNavigationId.get(event.args.data.navigationId);
if (navigationForEvent) {
eventTimeStamp = event.ts - navigationForEvent.ts;
}
} else if (event.args?.data?.frame) {
const navigationForEvent = getNavigationForTraceEvent(event, event.args.data.frame, navigationsByFrameId);
if (navigationForEvent) {
eventTimeStamp = event.ts - navigationForEvent.ts;
}
}
return Types.Timing.MicroSeconds(eventTimeStamp);
}