diff options
Diffstat (limited to 'ext/web/15_performance.js')
-rw-r--r-- | ext/web/15_performance.js | 1032 |
1 files changed, 516 insertions, 516 deletions
diff --git a/ext/web/15_performance.js b/ext/web/15_performance.js index 9107ce75b..6a50f45f8 100644 --- a/ext/web/15_performance.js +++ b/ext/web/15_performance.js @@ -1,594 +1,594 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -"use strict"; - -((window) => { - const { - ArrayPrototypeFilter, - ArrayPrototypeFind, - ArrayPrototypePush, - ArrayPrototypeReverse, - ArrayPrototypeSlice, - ObjectKeys, - ObjectPrototypeIsPrototypeOf, - ReflectHas, - Symbol, - SymbolFor, - TypeError, - } = window.__bootstrap.primordials; - - const { webidl, structuredClone } = window.__bootstrap; - const consoleInternal = window.__bootstrap.console; - const { EventTarget } = window.__bootstrap.eventTarget; - const { opNow } = window.__bootstrap.timers; - const { DOMException } = window.__bootstrap.domException; - - const illegalConstructorKey = Symbol("illegalConstructorKey"); - const customInspect = SymbolFor("Deno.customInspect"); - let performanceEntries = []; - let timeOrigin; - - webidl.converters["PerformanceMarkOptions"] = webidl - .createDictionaryConverter( - "PerformanceMarkOptions", - [ - { - key: "detail", - converter: webidl.converters.any, - }, - { - key: "startTime", - converter: webidl.converters.DOMHighResTimeStamp, - }, - ], - ); - - webidl.converters["DOMString or DOMHighResTimeStamp"] = (V, opts) => { - if (webidl.type(V) === "Number" && V !== null) { - return webidl.converters.DOMHighResTimeStamp(V, opts); - } - return webidl.converters.DOMString(V, opts); - }; - - webidl.converters["PerformanceMeasureOptions"] = webidl - .createDictionaryConverter( - "PerformanceMeasureOptions", - [ - { - key: "detail", - converter: webidl.converters.any, - }, - { - key: "start", - converter: webidl.converters["DOMString or DOMHighResTimeStamp"], - }, - { - key: "duration", - converter: webidl.converters.DOMHighResTimeStamp, - }, - { - key: "end", - converter: webidl.converters["DOMString or DOMHighResTimeStamp"], - }, - ], - ); - webidl.converters["DOMString or PerformanceMeasureOptions"] = (V, opts) => { - if (webidl.type(V) === "Object" && V !== null) { - return webidl.converters["PerformanceMeasureOptions"](V, opts); - } - return webidl.converters.DOMString(V, opts); - }; +const primordials = globalThis.__bootstrap.primordials; +const { + ArrayPrototypeFilter, + ArrayPrototypeFind, + ArrayPrototypePush, + ArrayPrototypeReverse, + ArrayPrototypeSlice, + ObjectKeys, + ObjectPrototypeIsPrototypeOf, + ReflectHas, + Symbol, + SymbolFor, + TypeError, +} = primordials; +import * as webidl from "internal:ext/webidl/00_webidl.js"; +import { structuredClone } from "internal:ext/web/02_structured_clone.js"; +import { createFilteredInspectProxy } from "internal:ext/console/02_console.js"; +import { EventTarget } from "internal:ext/web/02_event.js"; +import { opNow } from "internal:ext/web/02_timers.js"; +import DOMException from "internal:ext/web/01_dom_exception.js"; + +const illegalConstructorKey = Symbol("illegalConstructorKey"); +const customInspect = SymbolFor("Deno.customInspect"); +let performanceEntries = []; +let timeOrigin; + +webidl.converters["PerformanceMarkOptions"] = webidl + .createDictionaryConverter( + "PerformanceMarkOptions", + [ + { + key: "detail", + converter: webidl.converters.any, + }, + { + key: "startTime", + converter: webidl.converters.DOMHighResTimeStamp, + }, + ], + ); - function setTimeOrigin(origin) { - timeOrigin = origin; +webidl.converters["DOMString or DOMHighResTimeStamp"] = (V, opts) => { + if (webidl.type(V) === "Number" && V !== null) { + return webidl.converters.DOMHighResTimeStamp(V, opts); } + return webidl.converters.DOMString(V, opts); +}; + +webidl.converters["PerformanceMeasureOptions"] = webidl + .createDictionaryConverter( + "PerformanceMeasureOptions", + [ + { + key: "detail", + converter: webidl.converters.any, + }, + { + key: "start", + converter: webidl.converters["DOMString or DOMHighResTimeStamp"], + }, + { + key: "duration", + converter: webidl.converters.DOMHighResTimeStamp, + }, + { + key: "end", + converter: webidl.converters["DOMString or DOMHighResTimeStamp"], + }, + ], + ); - function findMostRecent( - name, - type, - ) { - return ArrayPrototypeFind( - ArrayPrototypeReverse(ArrayPrototypeSlice(performanceEntries)), - (entry) => entry.name === name && entry.entryType === type, - ); +webidl.converters["DOMString or PerformanceMeasureOptions"] = (V, opts) => { + if (webidl.type(V) === "Object" && V !== null) { + return webidl.converters["PerformanceMeasureOptions"](V, opts); } - - function convertMarkToTimestamp(mark) { - if (typeof mark === "string") { - const entry = findMostRecent(mark, "mark"); - if (!entry) { - throw new DOMException( - `Cannot find mark: "${mark}".`, - "SyntaxError", - ); - } - return entry.startTime; - } - if (mark < 0) { - throw new TypeError("Mark cannot be negative."); + return webidl.converters.DOMString(V, opts); +}; + +function setTimeOrigin(origin) { + timeOrigin = origin; +} + +function findMostRecent( + name, + type, +) { + return ArrayPrototypeFind( + ArrayPrototypeReverse(ArrayPrototypeSlice(performanceEntries)), + (entry) => entry.name === name && entry.entryType === type, + ); +} + +function convertMarkToTimestamp(mark) { + if (typeof mark === "string") { + const entry = findMostRecent(mark, "mark"); + if (!entry) { + throw new DOMException( + `Cannot find mark: "${mark}".`, + "SyntaxError", + ); } - return mark; + return entry.startTime; } - - function filterByNameType( - name, - type, - ) { - return ArrayPrototypeFilter( - performanceEntries, - (entry) => - (name ? entry.name === name : true) && - (type ? entry.entryType === type : true), - ); + if (mark < 0) { + throw new TypeError("Mark cannot be negative."); + } + return mark; +} + +function filterByNameType( + name, + type, +) { + return ArrayPrototypeFilter( + performanceEntries, + (entry) => + (name ? entry.name === name : true) && + (type ? entry.entryType === type : true), + ); +} + +const now = opNow; + +const _name = Symbol("[[name]]"); +const _entryType = Symbol("[[entryType]]"); +const _startTime = Symbol("[[startTime]]"); +const _duration = Symbol("[[duration]]"); +class PerformanceEntry { + [_name] = ""; + [_entryType] = ""; + [_startTime] = 0; + [_duration] = 0; + + get name() { + webidl.assertBranded(this, PerformanceEntryPrototype); + return this[_name]; } - const now = opNow; + get entryType() { + webidl.assertBranded(this, PerformanceEntryPrototype); + return this[_entryType]; + } - const _name = Symbol("[[name]]"); - const _entryType = Symbol("[[entryType]]"); - const _startTime = Symbol("[[startTime]]"); - const _duration = Symbol("[[duration]]"); - class PerformanceEntry { - [_name] = ""; - [_entryType] = ""; - [_startTime] = 0; - [_duration] = 0; + get startTime() { + webidl.assertBranded(this, PerformanceEntryPrototype); + return this[_startTime]; + } - get name() { - webidl.assertBranded(this, PerformanceEntryPrototype); - return this[_name]; - } + get duration() { + webidl.assertBranded(this, PerformanceEntryPrototype); + return this[_duration]; + } - get entryType() { - webidl.assertBranded(this, PerformanceEntryPrototype); - return this[_entryType]; + constructor( + name = null, + entryType = null, + startTime = null, + duration = null, + key = undefined, + ) { + if (key !== illegalConstructorKey) { + webidl.illegalConstructor(); } + this[webidl.brand] = webidl.brand; - get startTime() { - webidl.assertBranded(this, PerformanceEntryPrototype); - return this[_startTime]; - } + this[_name] = name; + this[_entryType] = entryType; + this[_startTime] = startTime; + this[_duration] = duration; + } - get duration() { - webidl.assertBranded(this, PerformanceEntryPrototype); - return this[_duration]; - } + toJSON() { + webidl.assertBranded(this, PerformanceEntryPrototype); + return { + name: this[_name], + entryType: this[_entryType], + startTime: this[_startTime], + duration: this[_duration], + }; + } - constructor( - name = null, - entryType = null, - startTime = null, - duration = null, - key = undefined, - ) { - if (key !== illegalConstructorKey) { - webidl.illegalConstructor(); - } - this[webidl.brand] = webidl.brand; + [customInspect](inspect) { + return inspect(createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf( + PerformanceEntryPrototype, + this, + ), + keys: [ + "name", + "entryType", + "startTime", + "duration", + ], + })); + } +} +webidl.configurePrototype(PerformanceEntry); +const PerformanceEntryPrototype = PerformanceEntry.prototype; - this[_name] = name; - this[_entryType] = entryType; - this[_startTime] = startTime; - this[_duration] = duration; - } +const _detail = Symbol("[[detail]]"); +class PerformanceMark extends PerformanceEntry { + [_detail] = null; - toJSON() { - webidl.assertBranded(this, PerformanceEntryPrototype); - return { - name: this[_name], - entryType: this[_entryType], - startTime: this[_startTime], - duration: this[_duration], - }; - } + get detail() { + webidl.assertBranded(this, PerformanceMarkPrototype); + return this[_detail]; + } - [customInspect](inspect) { - return inspect(consoleInternal.createFilteredInspectProxy({ - object: this, - evaluate: ObjectPrototypeIsPrototypeOf( - PerformanceEntryPrototype, - this, - ), - keys: [ - "name", - "entryType", - "startTime", - "duration", - ], - })); - } + get entryType() { + webidl.assertBranded(this, PerformanceMarkPrototype); + return "mark"; } - webidl.configurePrototype(PerformanceEntry); - const PerformanceEntryPrototype = PerformanceEntry.prototype; - const _detail = Symbol("[[detail]]"); - class PerformanceMark extends PerformanceEntry { - [_detail] = null; + constructor( + name, + options = {}, + ) { + const prefix = "Failed to construct 'PerformanceMark'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); - get detail() { - webidl.assertBranded(this, PerformanceMarkPrototype); - return this[_detail]; - } + name = webidl.converters.DOMString(name, { + prefix, + context: "Argument 1", + }); - get entryType() { - webidl.assertBranded(this, PerformanceMarkPrototype); - return "mark"; - } + options = webidl.converters.PerformanceMarkOptions(options, { + prefix, + context: "Argument 2", + }); - constructor( - name, - options = {}, - ) { - const prefix = "Failed to construct 'PerformanceMark'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); + const { detail = null, startTime = now() } = options; - name = webidl.converters.DOMString(name, { - prefix, - context: "Argument 1", - }); + super(name, "mark", startTime, 0, illegalConstructorKey); + this[webidl.brand] = webidl.brand; + if (startTime < 0) { + throw new TypeError("startTime cannot be negative"); + } + this[_detail] = structuredClone(detail); + } - options = webidl.converters.PerformanceMarkOptions(options, { - prefix, - context: "Argument 2", - }); + toJSON() { + webidl.assertBranded(this, PerformanceMarkPrototype); + return { + name: this.name, + entryType: this.entryType, + startTime: this.startTime, + duration: this.duration, + detail: this.detail, + }; + } - const { detail = null, startTime = now() } = options; + [customInspect](inspect) { + return inspect(createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(PerformanceMarkPrototype, this), + keys: [ + "name", + "entryType", + "startTime", + "duration", + "detail", + ], + })); + } +} +webidl.configurePrototype(PerformanceMark); +const PerformanceMarkPrototype = PerformanceMark.prototype; +class PerformanceMeasure extends PerformanceEntry { + [_detail] = null; + + get detail() { + webidl.assertBranded(this, PerformanceMeasurePrototype); + return this[_detail]; + } - super(name, "mark", startTime, 0, illegalConstructorKey); - this[webidl.brand] = webidl.brand; - if (startTime < 0) { - throw new TypeError("startTime cannot be negative"); - } - this[_detail] = structuredClone(detail); - } + get entryType() { + webidl.assertBranded(this, PerformanceMeasurePrototype); + return "measure"; + } - toJSON() { - webidl.assertBranded(this, PerformanceMarkPrototype); - return { - name: this.name, - entryType: this.entryType, - startTime: this.startTime, - duration: this.duration, - detail: this.detail, - }; + constructor( + name = null, + startTime = null, + duration = null, + detail = null, + key = undefined, + ) { + if (key !== illegalConstructorKey) { + webidl.illegalConstructor(); } - [customInspect](inspect) { - return inspect(consoleInternal.createFilteredInspectProxy({ - object: this, - evaluate: ObjectPrototypeIsPrototypeOf(PerformanceMarkPrototype, this), - keys: [ - "name", - "entryType", - "startTime", - "duration", - "detail", - ], - })); - } + super(name, "measure", startTime, duration, key); + this[webidl.brand] = webidl.brand; + this[_detail] = structuredClone(detail); } - webidl.configurePrototype(PerformanceMark); - const PerformanceMarkPrototype = PerformanceMark.prototype; - class PerformanceMeasure extends PerformanceEntry { - [_detail] = null; - get detail() { - webidl.assertBranded(this, PerformanceMeasurePrototype); - return this[_detail]; - } + toJSON() { + webidl.assertBranded(this, PerformanceMeasurePrototype); + return { + name: this.name, + entryType: this.entryType, + startTime: this.startTime, + duration: this.duration, + detail: this.detail, + }; + } - get entryType() { - webidl.assertBranded(this, PerformanceMeasurePrototype); - return "measure"; + [customInspect](inspect) { + return inspect(createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf( + PerformanceMeasurePrototype, + this, + ), + keys: [ + "name", + "entryType", + "startTime", + "duration", + "detail", + ], + })); + } +} +webidl.configurePrototype(PerformanceMeasure); +const PerformanceMeasurePrototype = PerformanceMeasure.prototype; +class Performance extends EventTarget { + constructor(key = null) { + if (key != illegalConstructorKey) { + webidl.illegalConstructor(); } - constructor( - name = null, - startTime = null, - duration = null, - detail = null, - key = undefined, - ) { - if (key !== illegalConstructorKey) { - webidl.illegalConstructor(); - } + super(); + this[webidl.brand] = webidl.brand; + } - super(name, "measure", startTime, duration, key); - this[webidl.brand] = webidl.brand; - this[_detail] = structuredClone(detail); - } + get timeOrigin() { + webidl.assertBranded(this, PerformancePrototype); + return timeOrigin; + } - toJSON() { - webidl.assertBranded(this, PerformanceMeasurePrototype); - return { - name: this.name, - entryType: this.entryType, - startTime: this.startTime, - duration: this.duration, - detail: this.detail, - }; - } + clearMarks(markName = undefined) { + webidl.assertBranded(this, PerformancePrototype); + if (markName !== undefined) { + markName = webidl.converters.DOMString(markName, { + prefix: "Failed to execute 'clearMarks' on 'Performance'", + context: "Argument 1", + }); - [customInspect](inspect) { - return inspect(consoleInternal.createFilteredInspectProxy({ - object: this, - evaluate: ObjectPrototypeIsPrototypeOf( - PerformanceMeasurePrototype, - this, - ), - keys: [ - "name", - "entryType", - "startTime", - "duration", - "detail", - ], - })); + performanceEntries = ArrayPrototypeFilter( + performanceEntries, + (entry) => !(entry.name === markName && entry.entryType === "mark"), + ); + } else { + performanceEntries = ArrayPrototypeFilter( + performanceEntries, + (entry) => entry.entryType !== "mark", + ); } } - webidl.configurePrototype(PerformanceMeasure); - const PerformanceMeasurePrototype = PerformanceMeasure.prototype; - class Performance extends EventTarget { - constructor(key = null) { - if (key != illegalConstructorKey) { - webidl.illegalConstructor(); - } - super(); - this[webidl.brand] = webidl.brand; - } - - get timeOrigin() { - webidl.assertBranded(this, PerformancePrototype); - return timeOrigin; - } + clearMeasures(measureName = undefined) { + webidl.assertBranded(this, PerformancePrototype); + if (measureName !== undefined) { + measureName = webidl.converters.DOMString(measureName, { + prefix: "Failed to execute 'clearMeasures' on 'Performance'", + context: "Argument 1", + }); - clearMarks(markName = undefined) { - webidl.assertBranded(this, PerformancePrototype); - if (markName !== undefined) { - markName = webidl.converters.DOMString(markName, { - prefix: "Failed to execute 'clearMarks' on 'Performance'", - context: "Argument 1", - }); - - performanceEntries = ArrayPrototypeFilter( - performanceEntries, - (entry) => !(entry.name === markName && entry.entryType === "mark"), - ); - } else { - performanceEntries = ArrayPrototypeFilter( - performanceEntries, - (entry) => entry.entryType !== "mark", - ); - } + performanceEntries = ArrayPrototypeFilter( + performanceEntries, + (entry) => + !(entry.name === measureName && entry.entryType === "measure"), + ); + } else { + performanceEntries = ArrayPrototypeFilter( + performanceEntries, + (entry) => entry.entryType !== "measure", + ); } + } - clearMeasures(measureName = undefined) { - webidl.assertBranded(this, PerformancePrototype); - if (measureName !== undefined) { - measureName = webidl.converters.DOMString(measureName, { - prefix: "Failed to execute 'clearMeasures' on 'Performance'", - context: "Argument 1", - }); - - performanceEntries = ArrayPrototypeFilter( - performanceEntries, - (entry) => - !(entry.name === measureName && entry.entryType === "measure"), - ); - } else { - performanceEntries = ArrayPrototypeFilter( - performanceEntries, - (entry) => entry.entryType !== "measure", - ); - } - } + getEntries() { + webidl.assertBranded(this, PerformancePrototype); + return filterByNameType(); + } - getEntries() { - webidl.assertBranded(this, PerformancePrototype); - return filterByNameType(); - } + getEntriesByName( + name, + type = undefined, + ) { + webidl.assertBranded(this, PerformancePrototype); + const prefix = "Failed to execute 'getEntriesByName' on 'Performance'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); - getEntriesByName( - name, - type = undefined, - ) { - webidl.assertBranded(this, PerformancePrototype); - const prefix = "Failed to execute 'getEntriesByName' on 'Performance'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); + name = webidl.converters.DOMString(name, { + prefix, + context: "Argument 1", + }); - name = webidl.converters.DOMString(name, { + if (type !== undefined) { + type = webidl.converters.DOMString(type, { prefix, - context: "Argument 1", + context: "Argument 2", }); + } - if (type !== undefined) { - type = webidl.converters.DOMString(type, { - prefix, - context: "Argument 2", - }); - } + return filterByNameType(name, type); + } - return filterByNameType(name, type); - } + getEntriesByType(type) { + webidl.assertBranded(this, PerformancePrototype); + const prefix = "Failed to execute 'getEntriesByName' on 'Performance'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); - getEntriesByType(type) { - webidl.assertBranded(this, PerformancePrototype); - const prefix = "Failed to execute 'getEntriesByName' on 'Performance'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); + type = webidl.converters.DOMString(type, { + prefix, + context: "Argument 1", + }); - type = webidl.converters.DOMString(type, { - prefix, - context: "Argument 1", - }); + return filterByNameType(undefined, type); + } - return filterByNameType(undefined, type); - } + mark( + markName, + markOptions = {}, + ) { + webidl.assertBranded(this, PerformancePrototype); + const prefix = "Failed to execute 'mark' on 'Performance'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); + + markName = webidl.converters.DOMString(markName, { + prefix, + context: "Argument 1", + }); + + markOptions = webidl.converters.PerformanceMarkOptions(markOptions, { + prefix, + context: "Argument 2", + }); + + // 3.1.1.1 If the global object is a Window object and markName uses the + // same name as a read only attribute in the PerformanceTiming interface, + // throw a SyntaxError. - not implemented + const entry = new PerformanceMark(markName, markOptions); + // 3.1.1.7 Queue entry - not implemented + ArrayPrototypePush(performanceEntries, entry); + return entry; + } - mark( - markName, - markOptions = {}, - ) { - webidl.assertBranded(this, PerformancePrototype); - const prefix = "Failed to execute 'mark' on 'Performance'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); + measure( + measureName, + startOrMeasureOptions = {}, + endMark = undefined, + ) { + webidl.assertBranded(this, PerformancePrototype); + const prefix = "Failed to execute 'measure' on 'Performance'"; + webidl.requiredArguments(arguments.length, 1, { prefix }); - markName = webidl.converters.DOMString(markName, { - prefix, - context: "Argument 1", - }); + measureName = webidl.converters.DOMString(measureName, { + prefix, + context: "Argument 1", + }); - markOptions = webidl.converters.PerformanceMarkOptions(markOptions, { + startOrMeasureOptions = webidl.converters + ["DOMString or PerformanceMeasureOptions"](startOrMeasureOptions, { prefix, context: "Argument 2", }); - // 3.1.1.1 If the global object is a Window object and markName uses the - // same name as a read only attribute in the PerformanceTiming interface, - // throw a SyntaxError. - not implemented - const entry = new PerformanceMark(markName, markOptions); - // 3.1.1.7 Queue entry - not implemented - ArrayPrototypePush(performanceEntries, entry); - return entry; - } - - measure( - measureName, - startOrMeasureOptions = {}, - endMark = undefined, - ) { - webidl.assertBranded(this, PerformancePrototype); - const prefix = "Failed to execute 'measure' on 'Performance'"; - webidl.requiredArguments(arguments.length, 1, { prefix }); - - measureName = webidl.converters.DOMString(measureName, { + if (endMark !== undefined) { + endMark = webidl.converters.DOMString(endMark, { prefix, - context: "Argument 1", + context: "Argument 3", }); + } - startOrMeasureOptions = webidl.converters - ["DOMString or PerformanceMeasureOptions"](startOrMeasureOptions, { - prefix, - context: "Argument 2", - }); - - if (endMark !== undefined) { - endMark = webidl.converters.DOMString(endMark, { - prefix, - context: "Argument 3", - }); + if ( + startOrMeasureOptions && typeof startOrMeasureOptions === "object" && + ObjectKeys(startOrMeasureOptions).length > 0 + ) { + if (endMark) { + throw new TypeError("Options cannot be passed with endMark."); } - if ( - startOrMeasureOptions && typeof startOrMeasureOptions === "object" && - ObjectKeys(startOrMeasureOptions).length > 0 - ) { - if (endMark) { - throw new TypeError("Options cannot be passed with endMark."); - } - if ( - !ReflectHas(startOrMeasureOptions, "start") && - !ReflectHas(startOrMeasureOptions, "end") - ) { - throw new TypeError( - "A start or end mark must be supplied in options.", - ); - } - if ( - ReflectHas(startOrMeasureOptions, "start") && - ReflectHas(startOrMeasureOptions, "duration") && - ReflectHas(startOrMeasureOptions, "end") - ) { - throw new TypeError( - "Cannot specify start, end, and duration together in options.", - ); - } - } - let endTime; - if (endMark) { - endTime = convertMarkToTimestamp(endMark); - } else if ( - typeof startOrMeasureOptions === "object" && - ReflectHas(startOrMeasureOptions, "end") - ) { - endTime = convertMarkToTimestamp(startOrMeasureOptions.end); - } else if ( - typeof startOrMeasureOptions === "object" && - ReflectHas(startOrMeasureOptions, "start") && - ReflectHas(startOrMeasureOptions, "duration") + !ReflectHas(startOrMeasureOptions, "start") && + !ReflectHas(startOrMeasureOptions, "end") ) { - const start = convertMarkToTimestamp(startOrMeasureOptions.start); - const duration = convertMarkToTimestamp(startOrMeasureOptions.duration); - endTime = start + duration; - } else { - endTime = now(); + throw new TypeError( + "A start or end mark must be supplied in options.", + ); } - let startTime; if ( - typeof startOrMeasureOptions === "object" && - ReflectHas(startOrMeasureOptions, "start") - ) { - startTime = convertMarkToTimestamp(startOrMeasureOptions.start); - } else if ( - typeof startOrMeasureOptions === "object" && - ReflectHas(startOrMeasureOptions, "end") && - ReflectHas(startOrMeasureOptions, "duration") + ReflectHas(startOrMeasureOptions, "start") && + ReflectHas(startOrMeasureOptions, "duration") && + ReflectHas(startOrMeasureOptions, "end") ) { - const end = convertMarkToTimestamp(startOrMeasureOptions.end); - const duration = convertMarkToTimestamp(startOrMeasureOptions.duration); - startTime = end - duration; - } else if (typeof startOrMeasureOptions === "string") { - startTime = convertMarkToTimestamp(startOrMeasureOptions); - } else { - startTime = 0; + throw new TypeError( + "Cannot specify start, end, and duration together in options.", + ); } - const entry = new PerformanceMeasure( - measureName, - startTime, - endTime - startTime, - typeof startOrMeasureOptions === "object" - ? startOrMeasureOptions.detail ?? null - : null, - illegalConstructorKey, - ); - ArrayPrototypePush(performanceEntries, entry); - return entry; - } - - now() { - webidl.assertBranded(this, PerformancePrototype); - return now(); - } - - toJSON() { - webidl.assertBranded(this, PerformancePrototype); - return { - timeOrigin: this.timeOrigin, - }; } + let endTime; + if (endMark) { + endTime = convertMarkToTimestamp(endMark); + } else if ( + typeof startOrMeasureOptions === "object" && + ReflectHas(startOrMeasureOptions, "end") + ) { + endTime = convertMarkToTimestamp(startOrMeasureOptions.end); + } else if ( + typeof startOrMeasureOptions === "object" && + ReflectHas(startOrMeasureOptions, "start") && + ReflectHas(startOrMeasureOptions, "duration") + ) { + const start = convertMarkToTimestamp(startOrMeasureOptions.start); + const duration = convertMarkToTimestamp(startOrMeasureOptions.duration); + endTime = start + duration; + } else { + endTime = now(); + } + let startTime; + if ( + typeof startOrMeasureOptions === "object" && + ReflectHas(startOrMeasureOptions, "start") + ) { + startTime = convertMarkToTimestamp(startOrMeasureOptions.start); + } else if ( + typeof startOrMeasureOptions === "object" && + ReflectHas(startOrMeasureOptions, "end") && + ReflectHas(startOrMeasureOptions, "duration") + ) { + const end = convertMarkToTimestamp(startOrMeasureOptions.end); + const duration = convertMarkToTimestamp(startOrMeasureOptions.duration); + startTime = end - duration; + } else if (typeof startOrMeasureOptions === "string") { + startTime = convertMarkToTimestamp(startOrMeasureOptions); + } else { + startTime = 0; + } + const entry = new PerformanceMeasure( + measureName, + startTime, + endTime - startTime, + typeof startOrMeasureOptions === "object" + ? startOrMeasureOptions.detail ?? null + : null, + illegalConstructorKey, + ); + ArrayPrototypePush(performanceEntries, entry); + return entry; + } - [customInspect](inspect) { - return inspect(consoleInternal.createFilteredInspectProxy({ - object: this, - evaluate: ObjectPrototypeIsPrototypeOf(PerformancePrototype, this), - keys: [], - })); - } + now() { + webidl.assertBranded(this, PerformancePrototype); + return now(); } - webidl.configurePrototype(Performance); - const PerformancePrototype = Performance.prototype; - webidl.converters["Performance"] = webidl.createInterfaceConverter( - "Performance", - PerformancePrototype, - ); + toJSON() { + webidl.assertBranded(this, PerformancePrototype); + return { + timeOrigin: this.timeOrigin, + }; + } - window.__bootstrap.performance = { - PerformanceEntry, - PerformanceMark, - PerformanceMeasure, - Performance, - performance: new Performance(illegalConstructorKey), - setTimeOrigin, - }; -})(this); + [customInspect](inspect) { + return inspect(createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(PerformancePrototype, this), + keys: [], + })); + } +} +webidl.configurePrototype(Performance); +const PerformancePrototype = Performance.prototype; + +webidl.converters["Performance"] = webidl.createInterfaceConverter( + "Performance", + PerformancePrototype, +); + +const performance = new Performance(illegalConstructorKey); + +export { + Performance, + performance, + PerformanceEntry, + PerformanceMark, + PerformanceMeasure, + setTimeOrigin, +}; |