From 1f76638609e13de2b3de92c0ef955f8ccfecfb23 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Mon, 27 Nov 2023 13:42:35 +0000 Subject: [PATCH 01/15] LoAF: Add HTML monkey-patches --- index.bs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/index.bs b/index.bs index cea0b11..73a7828 100644 --- a/index.bs +++ b/index.bs @@ -50,6 +50,7 @@ urlPrefix: https://html.spec.whatwg.org/multipage/; spec: HTML; type: dfn; url: #unit-of-related-browsing-contexts; text: unit of related browsing contexts type: dfn; url: #script-evaluation-environment-settings-object-set; text: script evaluation environment settings object set type: dfn; url: #integration-with-the-javascript-agent-cluster-formalism; text: agent cluster + type: dfn; url: #concept-task-document; for: task; text: document; urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT; type: dfn; url: #sec-code-realms; text: JavaScript Realms; urlPrefix: https://dom.spec.whatwg.org/; spec: DOM; @@ -346,6 +347,8 @@ Report long tasks {#report-long-tasks}
Given |start time|, |end time|, |top-level browsing contexts|, and |task|, perform the following algorithm: + 1. [=Report task end time=] given |end time| and |task|'s [=task/document=]. + 1. If |end time| minus |start time| is less than the long tasks threshold of 50 ms, abort these steps. 1. Let |destinationRealms| be an empty set. @@ -555,6 +558,30 @@ Report Long Animation Frames {#loaf-processing-model} 1. set |document|'s [=nearest same-origin root=]'s [=current frame timing info=] to null.
+Monkey-patches to the HTML standard {#html-monkey-patches} +======================================= + +
+ Insert step after step 2.3 of the event loop processing model, + after setting |taskStartTime| and |oldestTask|: + + 1. [=Report task start time=] given |taskStartTime| and |oldestTask|'s [=task/document=]. +
+ +
+ Insert a step before [update the rendering](https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering) step 6.14, + right before the loop that calculates style and layout for each {{Document}}: + + 1. Let |unsafeStyleAndLayoutStartTime| be the [=unsafe shared current time=]. + + Insert the following steps after [update the rendering](https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering) step 6.18, + right after calling [=mark paint timing=], using the existing |docs| variable: + + 1. Let |unsafeRenderingEndTime| be the [=unsafe shared current time=]. + 1. [=Report rendering time=] for each [=fully active=] {{Document}} object in |docs| given |unsafeRenderingEndTime| |unsafeStyleAndLayoutStartTime|. + +
+ Security & privacy considerations {#priv-sec} =============================================== From 61a67ee58896d6e6da4281db6cbb17e9ac38eecc Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Mon, 27 Nov 2023 14:11:19 +0000 Subject: [PATCH 02/15] Fix WebIDL overloading --- index.bs | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/index.bs b/index.bs index 73a7828..bc5fe9c 100644 --- a/index.bs +++ b/index.bs @@ -161,6 +161,12 @@ Long Task timing involves the following new interfaces:
     [Exposed=Window]
     interface PerformanceLongTaskTiming : PerformanceEntry {
+        // Overloading PerformanceEntry
+        readonly attribute DOMHighResTimeStamp startTime;
+        readonly attribute DOMHighResTimeStamp duration;
+        readonly attribute DOMString name;
+        readonly attribute DOMString entryType;
+
         readonly attribute FrozenArray<TaskAttributionTiming> attribution;
         [Default] object toJSON();
     };
@@ -192,11 +198,11 @@ The {{PerformanceEntry/name}} attribute's getter will return one of the followin
 Note: There are some inconsistencies across these names, such as the "-unreachable" and the "-contexts" suffixes.
 These names are kept for backward compatibility reasons.
 
-The {{PerformanceEntry/entryType}} attribute's getter will return "longtask".
+The {{PerformanceLongTaskTiming/entryType}} attribute's getter step is to return "longtask".
 
-The {{PerformanceEntry/startTime}} attribute's getter will return a {{DOMHighResTimeStamp}} of when the task started.
+The {{PerformanceLongTaskTiming/startTime}} attribute's getter step is to return a {{DOMHighResTimeStamp}} of when the task started.
 
-The {{PerformanceEntry/duration}} attribute's getter will return a {{DOMHighResTimeStamp}} equal to the elapsed time between the start and end of task, with a 1 ms granularity.
+The {{PerformanceLongTaskTiming/duration}} attribute's getter step is to return a {{DOMHighResTimeStamp}} equal to the elapsed time between the start and end of task, with a 1 ms granularity.
 
 The attribution attribute's getter will return a frozen array of {{TaskAttributionTiming}} entries.
 
@@ -206,6 +212,12 @@ The attribution attribute's g
 
     [Exposed=Window]
     interface TaskAttributionTiming : PerformanceEntry {
+        // Overloading PerformanceEntry
+        readonly attribute DOMHighResTimeStamp startTime;
+        readonly attribute DOMHighResTimeStamp duration;
+        readonly attribute DOMString name;
+        readonly attribute DOMString entryType;
+
         readonly attribute DOMString containerType;
         readonly attribute DOMString containerSrc;
         readonly attribute DOMString containerId;
@@ -216,13 +228,13 @@ The attribution attribute's g
 
 The values of the attributes of a {{TaskAttributionTiming}} are set in the processing model in [[#report-long-tasks]]. The following provides an informative summary of how they will be set.
 
-The {{PerformanceEntry/name}} attribute's getter will always return "unknown".
+The {{TaskAttributionTiming/name}} attribute's getter will always return "unknown".
 
-The {{PerformanceEntry/entryType}} attribute's getter will always return "taskattribution".
+The {{TaskAttributionTiming/entryType}} attribute's getter will always return "taskattribution".
 
-The {{PerformanceEntry/startTime}} attribute's getter will always return 0.
+The {{TaskAttributionTiming/startTime}} attribute's getter will always return 0.
 
-The {{PerformanceEntry/duration}} attribute's getter will always return 0.
+The {{TaskAttributionTiming/duration}} attribute's getter will always return 0.
 
 The containerType attribute's getter will return the type of the culprit browsing context container, such as "iframe", "embed", or "object". If no single culprit browsing context container is found, it will return "window".
 
@@ -300,6 +312,12 @@ Long Animation Frame timing involves the following new interfaces:
 
     [Exposed=Window]
     interface PerformanceLongAnimationFrameTiming : PerformanceEntry {
+        // Overloading PerformanceEntry
+        readonly attribute DOMHighResTimeStamp startTime;
+        readonly attribute DOMHighResTimeStamp duration;
+        readonly attribute DOMString name;
+        readonly attribute DOMString entryType;
+
         readonly attribute DOMHighResTimeStamp renderStart;
         readonly attribute DOMHighResTimeStamp styleAndLayoutStart;
         readonly attribute DOMHighResTimeStamp blockingDuration;
@@ -310,13 +328,13 @@ Long Animation Frame timing involves the following new interfaces:
 
 A {{PerformanceLongAnimationFrameTiming}} has a [=frame timing info=] timing info.
 
-The {{PerformanceEntry/entryType}} attribute's getter step is to return "long-animation-frame".
+The {{PerformanceLongAnimationFrameTiming/entryType}} attribute's getter step is to return "long-animation-frame".
 
-The {{PerformanceEntry/name}} attribute's getter step is to return "long-animation-frame".
+The {{PerformanceLongAnimationFrameTiming/name}} attribute's getter step is to return "long-animation-frame".
 
-The {{PerformanceEntry/startTime}} attribute's getter step is to return the [=relative high resolution time=] given [=this=]'s [=PerformanceLongAnimationFrameTiming/timing info=]'s [=frame timing info/start time=] and [=this=]'s [=relevant global object=].
+The {{PerformanceLongAnimationFrameTiming/startTime}} attribute's getter step is to return the [=relative high resolution time=] given [=this=]'s [=PerformanceLongAnimationFrameTiming/timing info=]'s [=frame timing info/start time=] and [=this=]'s [=relevant global object=].
 
-The {{PerformanceEntry/duration}} attribute's getter step is to return the [=duration=] between [=this=]'s {{PerformanceEntry/startTime}} and the [=relative high resolution time=] given [=this=]'s [=PerformanceLongAnimationFrameTiming/timing info=]'s [=frame timing info/end time=] and [=this=]'s [=relevant global object=].
+The {{PerformanceLongAnimationFrameTiming/duration}} attribute's getter step is to return the [=duration=] between [=this=]'s {{PerformanceEntry/startTime}} and the [=relative high resolution time=] given [=this=]'s [=PerformanceLongAnimationFrameTiming/timing info=]'s [=frame timing info/end time=] and [=this=]'s [=relevant global object=].
 
 The {{PerformanceLongAnimationFrameTiming/renderStart}} attribute's getter step is to return the [=relative high resolution time=] given [=this=]'s [=PerformanceLongAnimationFrameTiming/timing info=]'s [=frame timing info/update the rendering start time=] and [=this=]'s [=relevant global object=].
 

From d277da30d884eb6b0eab961d31cbce2baf947109 Mon Sep 17 00:00:00 2001
From: Noam Rosenthal 
Date: Mon, 27 Nov 2023 14:28:21 +0000
Subject: [PATCH 03/15] nit

---
 index.bs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/index.bs b/index.bs
index bc5fe9c..02b093d 100644
--- a/index.bs
+++ b/index.bs
@@ -161,7 +161,7 @@ Long Task timing involves the following new interfaces:
 
     [Exposed=Window]
     interface PerformanceLongTaskTiming : PerformanceEntry {
-        // Overloading PerformanceEntry
+        /* Overloading PerformanceEntry */
         readonly attribute DOMHighResTimeStamp startTime;
         readonly attribute DOMHighResTimeStamp duration;
         readonly attribute DOMString name;
@@ -212,7 +212,7 @@ The attribution attribute's g
 
     [Exposed=Window]
     interface TaskAttributionTiming : PerformanceEntry {
-        // Overloading PerformanceEntry
+        /* Overloading PerformanceEntry */
         readonly attribute DOMHighResTimeStamp startTime;
         readonly attribute DOMHighResTimeStamp duration;
         readonly attribute DOMString name;
@@ -312,7 +312,7 @@ Long Animation Frame timing involves the following new interfaces:
 
     [Exposed=Window]
     interface PerformanceLongAnimationFrameTiming : PerformanceEntry {
-        // Overloading PerformanceEntry
+        /* Overloading PerformanceEntry */
         readonly attribute DOMHighResTimeStamp startTime;
         readonly attribute DOMHighResTimeStamp duration;
         readonly attribute DOMString name;

From 229708daf339c18ae43a013004b5d28dcef686b2 Mon Sep 17 00:00:00 2001
From: Noam Rosenthal 
Date: Mon, 27 Nov 2023 14:01:36 +0000
Subject: [PATCH 04/15] LoAF: add support for scripts

This adds support for reporting scripts:
- The PerformanceScriptTiming IDL
- Algorithms for how script entries are created
- Monkey patches to HTML/DOM/WebIDL
---
 index.bs | 322 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 317 insertions(+), 5 deletions(-)

diff --git a/index.bs b/index.bs
index 02b093d..f15a6b4 100644
--- a/index.bs
+++ b/index.bs
@@ -51,11 +51,16 @@ urlPrefix: https://html.spec.whatwg.org/multipage/; spec: HTML;
     type: dfn; url: #script-evaluation-environment-settings-object-set; text: script evaluation environment settings object set
     type: dfn; url: #integration-with-the-javascript-agent-cluster-formalism; text: agent cluster
     type: dfn; url: #concept-task-document; for: task; text: document;
+    type: dfn; url: #running-script; text: running script;
+    type: dfn; url: #muted-errors; for: classic script; text: muted errors;
 urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT;
     type: dfn; url: #sec-code-realms; text: JavaScript Realms;
 urlPrefix: https://dom.spec.whatwg.org/; spec: DOM;
     type: attribute; for: Element;
         text: id; url: #dom-element-id;
+urlPrefix: https://webidl.spec.whatwg.org/; spec: WEBIDL;
+    type: dfn; text: identifier; url: #identifier;
+    type: dfn; text: attribute; url: #attribute;
 
@@ -338,7 +344,9 @@ The {{PerformanceLongAnimationFrameTiming/duration}} attribute's getter step is The {{PerformanceLongAnimationFrameTiming/renderStart}} attribute's getter step is to return the [=relative high resolution time=] given [=this=]'s [=PerformanceLongAnimationFrameTiming/timing info=]'s [=frame timing info/update the rendering start time=] and [=this=]'s [=relevant global object=]. -The {{PerformanceLongAnimationFrameTiming/styleAndLayoutStart}} attribute's getter step is to return the [=relative high resolution time=] given [=this=]'s [=PerformanceLongAnimationFrameTiming/timing info=]'s [=frame timing info/style and layout start time=] and [=this=]'s [=relevant global object=]. +The {{PerformanceLongAnimationFrameTiming/styleAndLayoutStart}} attribute's getter step is to return the [=relative high resolution time=] given [=this=]'s [=PerformanceLongAnimationFrameTiming/timing info=]'s [=frame timing info/style and layout start time=] and [=this=]'s [=relevant global object=]. + +The {{PerformanceLongAnimationFrameTiming/firstUIEventTimestamp}} attribute's getter step is to return the [=relative high resolution time=] given [=this=]'s [=PerformanceLongAnimationFrameTiming/timing info=]'s [=frame timing info/first ui event timestamp=] and [=this=]'s [=relevant global object=]. The {{PerformanceLongAnimationFrameTiming/blockingDuration}} attribute's getter steps are: @@ -350,7 +358,92 @@ The {{PerformanceLongAnimationFrameTiming/blockingDuration}} attribute's getter 1. If |workDuration| + |renderDuration| is greater than 50, then return |workDuration| + |renderDuration| - 50 milliseconds. 1. Return 0. - +The {{PerformanceLongAnimationFrameTiming/scripts}} attribute's getter steps are: + 1. Let |scripts| be « ». + 1. [=list/For each=] |scriptInfo| in [=this=]'s [=frame timing info=]'s [=frame timing info/scripts=]: + 1. Let |scriptEntry| be a new {{PerformanceScriptTiming}} in [=this=]'s [=relevant realm=], + whose [=PerformanceScriptTiming/timing info=] is |scriptInfo|. + 1. [=list/Append=] |scriptEntry| to |scripts|. + 1. Return |scripts|. + +{{PerformanceScriptTiming}} interface {#sec-PerformanceScriptTiming} +------------------------------------------------------------------------ + +
+    enum ScriptTimingType {
+        "classic-script",
+        "module-script",
+        "event-listener",
+        "user-callback",
+        "resolve-promise",
+        "reject-promise"
+    };
+
+    [Exposed=Window]
+    interface PerformanceScriptTiming : PerformanceEntry {
+        /* Overloading PerformanceEntry */
+        readonly attribute DOMHighResTimeStamp startTime;
+        readonly attribute DOMHighResTimeStamp duration;
+        readonly attribute DOMString name;
+        readonly attribute DOMString entryType;
+
+        readonly attribute ScriptTimingType type;
+        readonly attribute DOMHighResTimeStamp executionStart;
+        readonly attribute DOMString sourceLocation;
+        [Default] object toJSON();
+    };
+
+ +A {{PerformanceScriptTiming}} has an associated [=script timing info=] timing info. + +The {{PerformanceScriptTiming/entryType}} attribute's getter step is to return "script". + +The {{PerformanceScriptTiming/type}} attribute's getter step is to return [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/type=]. + +The {{PerformanceScriptTiming/name}} attribute's getter steps are: + 1. Switch on |this|'s {{PerformanceScriptTiming/type}}: + + : "`classic-script`" + : "`module-script`" + :: Return |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/source url=]. + + : "`event-listener`" + :: + 1. Let |targetName| be |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/invoker name=]. + 1. If |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element id=] is not the empty string, then: + Set |targetName| to the [=concatenate|concatenation=] of « |targetName|, "#", |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element id=] ». + 1. Else, If |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element src attribute=] is not the empty string, then: + Set |targetName| to the [=concatenate|concatenation=] of « |targetName|, '[src=', |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element src attribute=], ']' ». + 1. Return the [=concatenate|concatenation=] of « |targetName|, ".on", [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event type=] ». + + : "`user-callback`" + :: Return |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/invoker name=]. + + : "`resolve-promise`" + : "`reject-promise`" + :: + 1. If |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/invoker name=] is the empty string, + then: + 1. If |this|'s {{PerformanceScriptTiming/type}} is "`resolve-promise`", then return "`Promise.resolve`". + 1. Otherwise, return "`Promise.reject`". + 1. Let |thenOrCatch| be "`then`" if {{PerformanceScriptTiming/type}} is "`resolve-promise`"; Otherwise "`reject-promise`". + 1. Return the [=concatenate|concatenation=] of « [=script timing info/invoker name=], ".", |thenOrCatch| ». + +The {{PerformanceScriptTiming/startTime}} attribute's getter step is to return the [=relative high resolution time=] given [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/start time=] and [=this=]'s [=relevant global object=]. + +The {{PerformanceScriptTiming/duration}} attribute's getter step is to return the [=duration=] between [=this=]'s {{PerformanceScriptTiming/startTime}} and the [=relative high resolution time=] given [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/end time=] and [=this=]'s [=relevant global object=]. + +The {{PerformanceScriptTiming/executionStart}} attribute's getter step is to return 0 if [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/execution start time=] is 0; Otherwise the [=relative high resolution time=] given [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/execution start time=] and [=this=]'s [=relevant global object=]. + +The {{PerformanceScriptTiming/sourceLocation}} attribute's getter steps are: + 1. If [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/source url=] is the empty string, return the empty string. + 1. Let |serializedSourceLocation| be [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/source url=]. + 1. If [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/source function name=] is not the empty string, then + set |serializedSourceLocation| to the [=concatenate|concatenation=] of « [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/source function name=], "@", |serializedSourceLocation| ». + 1. If [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/source character position=] is greater than -1, then + set |serializedSourceLocation| to the [=concatenate|concatenation=] of «|serializedSourceLocation|, ":", [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/source character position=] ». + 1. Return |serializedSourceLocation|. + Processing model {#sec-processing-model} ======================================== @@ -476,6 +569,7 @@ It has the following [=struct/items=]: : current task start time : update the rendering start time : style and layout start time + : first ui event timestamp : end time :: A {{DOMHighResTimeStamp}}, initially 0. Note: all the above are [=monotonic clock/unsafe current time=|unsafe=], @@ -484,6 +578,34 @@ It has the following [=struct/items=]: : longest task duration :: A {{DOMHighResTimeStamp}}, initially 0. + : scripts + :: A [=/list=] of [=script timing info=], initially empty. + + : pending script + :: Null or a [=script timing info=], initially null. + + +script timing info is a [=struct=]. It has the following [=struct/items=]: + +
+ : type + :: A {{ScriptTimingType}}. + + : start time + : end time + : execution start time + :: An unsafe {{DOMHighResTimeStamp}}, initially 0. + + : invoker name + : source url + : source function name + : event type + : event target element id + : event target element src attribute + :: A string, initially the empty string. + + : source character position + :: A number, initially -1.
A {{Document}} has a null or [=frame timing info=] current frame timing info, initially null. @@ -492,6 +614,8 @@ A {{Document}} has a null or [=frame timing info=] current frame timing inf Report Long Animation Frames {#loaf-processing-model} ------------------------------------------ +### Long Animation Frame Monitoring {#loaf-monitoring} +
To get the nearest same-origin root for a {{Document}} |document|: 1. Let |ancestors| be the [=ancestor navigables=] of |document|. @@ -576,9 +700,158 @@ Report Long Animation Frames {#loaf-processing-model} 1. set |document|'s [=nearest same-origin root=]'s [=current frame timing info=] to null.
-Monkey-patches to the HTML standard {#html-monkey-patches} -======================================= +### Long Script Monitoring ### {#long-script-monitoring} + +
+ To report user callback given a [=callback function=] |callback| and an [=environment settings object=] |settings|: + [=Create script entry point=] given "`user-callback`", |settings|, + and the following steps given a [=script timing info=] |scriptTimingInfo|: + 1. Set |scriptTimingInfo|'s [=script timing info/invoker name=] to |callback|'s [=identifier=]. + 1. [=Apply source location=] for |scriptTimingInfo| given |callback|. +
+ +
+ To report timer handler given a string or {{Function}} |handler|, an [=environment settings object=] |settings|, and a boolean |repeat|: + [=Create script entry point=] given "`user-callback`", |settings|, + and the following steps given a [=script timing info=] |scriptTimingInfo|: + + 1. Let |setTimeoutOrInterval| be "setInterval" if |repeat| is true, "setTimeout" otherwise. + 1. Set |scriptTimingInfo|'s [=script timing info/invoker name=] to [=concatenate|concatenation=] of + « TimerHandler:", |setTimeoutOrInterval| ». + 1. If |handler| is a {{Function}}, then [=apply source location=] for |scriptTimingInfo| given |handler|. +
+ +
+ To report event handler given an {{Event}} |event| and an {{EventListener}} |listener|: + [=Create script entry point=] given "`event-listener`", |target|'s [=relevant settings object=], + and the following steps given a [=script timing info=] |scriptTimingInfo| and a [=frame timing info=] |frameTimingInfo|: + + 1. Set |scriptTimingInfo|'s [=script timing info/event type=] to |event|'s {{Event/type}}. + 1. If |target| is a {{Node}}, then: + 1. Set |scriptTimingInfo|'s [=script timing info/invoker name=] to |target|'s {{Node/nodeName}}. + 1. If |target| is an {{Element}}, then: + 1. Set |scriptTimingInfo|'s [=script timing info/event target element id=] to |target|'s [=Element/id=]. + 1. Set |scriptTimingInfo|'s [=script timing info/event target element src attribute=] to the result of [=get an attribute by name|getting an attribute value by name] "`src`" and |target|. + 1. Else, set |scriptTimingInfo|'s [=script timing info/invoker name=] to |target|'s interface name. + 1. [=Apply source location=] for |scriptTimingInfo| given |listener|'s [=event listener/callback=]. + 1. If |event| is a {{UIEvent}}, and |frameTimingInfo|'s [=frame timing info/first ui event timestamp=] is 0, + then set |frameTimingInfo|'s [=frame timing info/first ui event timestamp=] to |event|'s {{Event/timeStamp}}. +
+ +
+ To report promise resolver given a {{Promise}} |promise| and a "`resolve-promise`" or "`reject-promise`" |type|: + 1. [=Create script entry point=] given |type|, |promise|'s [=relevant realm=]'s [=realm/settings object=], + and the following steps given a [=script timing info=] |scriptTimingInfo|: + + 1. Set |scriptTimingInfo|'s [=script timing info/invoker name=] to |promise|'s [=Promise/invoker name when created=]. + 1. Set |scriptTimingInfo|'s [=script timing info/source url=] to |promise|'s [=Promise/script url when created=]. +
+ +
+ To report script execution start given a [=/script=] |script|: + 1. Let |scheme| be |script|'s [=script/base URL=]'s [=url/scheme=]. + 1. If |scheme| is neither "`http`", "`https`", "`blob`", or "`data`", return. + + Note: this also excludes CORS cross-origin scripts, as they would have a [=script/base URL=] of about:blank. + + 1. Let |type| be "`module-script`" if |script| is a [=module script=], otherwise "`classic-script`". + + 1. [=Create script entry point=] with |script|'s [=script/settings object=], |type|, + and the following step given a [=script timing info=] |scriptTimingInfo|: + 1. If |script| is a [=classic script=] then: + 1. Set |scriptTimingInfo|'s [=script timing info/execution start time=] to |scriptTimingInfo|'s [=script timing info/start time=]. + 1. Set |scriptTimingInfo|'s [=script timing info/start time=] to |script|'s [=classic script/creation time=]. + 1. If |scheme| is "`http`" or "`https`", then set |scriptTimingInfo|'s [=script timing info/source url=] to |script|'s [=script/base URL=]. + 1. Otherwise, set |scriptTimingInfo|'s [=script timing info/source url=] to the [=concatenate|concatenation=] of « |scheme|, ":"" ». + +
+ +
+ To create script entry point given an [=environment settings object=] |settings|, + a {{ScriptTimingType}} |type|, and |steps|, + which is an algorithm that takes a [=script timing info=] and an optional [=frame timing info=]: + + 1. If |settings| is not a {{Window}}, then return. + 1. Let |document| be |settings|'s {{Window/document}}. + 1. If |document| is not [=fully active=] or {{Document/hidden}}, then return. + 1. Let |frameTimingInfo| be |document|'s [=relevant frame timing info=]. + 1. If |frameTimingInfo|'s [=frame timing info/pending script=] is not null, then return. + 1. Let |scriptTimingInfo| be a new [=script timing info=] + whose [=script timing info/start time=] is the [=unsafe shared current time=], + and whose [=script timing info/type=] is |type|. + 1. Run |steps| given |scriptTimingInfo| and |frameTimingInfo|. + 1. Set |frameTimingInfo|'s [=frame timing info/pending script=] to |scriptTimingInfo|. +
+ +
+ To flush script entry point: + + 1. Let |script| be the [=running script=]. + 1. Let |settings| be |script|'s [=script/settings object=]. + 1. Let |document| be |settings|'s {{Window/document}}. + 1. If |document| is not [=fully active=] or {{Document/hidden}}, then return. + 1. Let |frameTimingInfo| be |document|'s [=relevant frame timing info=]. + 1. Let |scriptTimingInfo| be |frameTimingInfo|'s [=frame timing info/pending script=]. + 1. Set |frameTimingInfo|'s [=frame timing info/pending script=] to null. + 1. If |scriptTimingInfo| is null, then return. + 1. Set |scriptTimingInfo|'s [=script timing info/end time=] to the [=unsafe shared current time=]. + 1. If |script| is a [=classic script=] whose [=classic script/muted errors=] is true, then: + 1. set |scriptTimingInfo|'s [=script timing info/source url=] to the empty string. + 1. set |scriptTimingInfo|'s [=script timing info/source character position=] to -1. + 1. set |scriptTimingInfo|'s [=script timing info/source function name=] to the empty string. + 1. If the [=duration=] between |scriptTimingInfo|'s [=script timing info/start time=] and |scriptTimingInfo|'s [=script timing info/end time=] is greater than 5 milliseconds, then + [=list/append=] |scriptTimingInfo| to |frameTimingInfo|'s [=frame timing info/scripts=]. +
+ +
+ To apply source location to a [=script timing info=] |scriptTimingInfo| given a [=callback function=] or {{Function}} |callback|: + 1. The user agent may set |scriptTimingInfo|'s [=script timing info/source url=] to the source URL of the script where |callback| was defined. + 1. The user agent may set |scriptTimingInfo|'s [=script timing info/source function name=] to the function name of |callback|. + 1. The user agent may set |scriptTimingInfo|'s [=script timing info/source character position=] to the character position where |callback| was defined. +
+ +Additions to existing standards {#other-standards} +================================================== + +Monkey-patches to the WebIDL standard {#webidl-monkey-patches} +---------------------------------------------------------- +
+The {{Promise}} interface has an associated string invoker name when created, initially "`Promise`". +The {{Promise}} interface has an associated string script url when created, initially the empty string. + +Append the following steps to creating a new promise, before returning the {{Promise}}: + 1. Let |interfaceName| be a string representing the [=interface=] responsible for creating this promise. + 1. Let |attributeName| be a string representing the [=attribute=] in the interface responsible for creating this promise. + 1. The user-agent may set the created {{Promise}}'s [=Promise/invoker name when created=] to the last known [=concatenate|concatenation=] of + « |interfaceName|, ".", |attributeName| » + 1. The user-agent may set the created {{Promise}}'s [=Promise/script url when created=] to the current script URL. + +Prepend the following step to resolve a promise given {{Promise}} |p|: + [=Report promise resolver=] given |p| and "`resolve-promise`". + +Prepend the following step to reject a promise given {{Promise}} |p|: + [=Report promise resolver=] given |p| and "`reject-promise`". +
+ +
+Insert the following steps to invoke a callback function, + once we have an [=environment settings object=] |relevant settings| and a [=callback function=] |F|: + [=Report user callback=] given |F| and |relevant settings|. +
+ + +Monkey-patches to the DOM standard {#dom-monkey-patches} +---------------------------------------------------------- +
+ Insert the following step to the inner invoke steps, + after determining that |global| is a {{Window}} (after step 8.2), assuming an [=event listener=] |listener|: + [=Report event handler=] given |global|'s {{Window/event}} and |listener|. +
+ + +Monkey-patches to the HTML standard {#html-monkey-patches} +----------------------------------------------------------
Insert step after step 2.3 of the event loop processing model, after setting |taskStartTime| and |oldestTask|: @@ -597,6 +870,45 @@ Monkey-patches to the HTML standard {#html-monkey-patches} 1. Let |unsafeRenderingEndTime| be the [=unsafe shared current time=]. 1. [=Report rendering time=] for each [=fully active=] {{Document}} object in |docs| given |unsafeRenderingEndTime| |unsafeStyleAndLayoutStartTime|. +
+ +
+ Insert a step to the timer initialisation steps, + after asserting that the timer ID exists in the map of active timers (After step 8.1), + assuming a {{Function}} or string |handler|, a {{WindowOrWorkerGlobalScope}} |global|, and a boolean |repeat|: + + 1. [=Report timer handler=] given |handler|, |global|'s [=relevant settings object=], and |repeat|. + + 1. Let |unsafeStyleAndLayoutStartTime| be the [=unsafe shared current time=]. + + Insert the following steps after [update the rendering](https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering) step 6.18, + right after calling [=mark paint timing=], using the existing |docs| variable: + + 1. Let |unsafeRenderingEndTime| be the [=unsafe shared current time=]. + 1. [=Report rendering time=] for each [=fully active=] {{Document}} object in |docs| given |unsafeRenderingEndTime| |unsafeStyleAndLayoutStartTime|. +
+ +
+ The [=classic script=] [=struct=] has an additional item: + + creation time, a {{DOMHighResTimeStamp}}. + + Insert a step to the create a classic script steps, + before parsing the script, assuming the |script| variable is populated: + Set |script|'s [=classic script/creation time=] to the [=unsafe shared current time=]. + + Insert a step to the run a classic script steps, + before preparing to run a script (between steps 2 and 3): + [=Report script execution start=] given |script|. + + Insert a step to the run a module script steps, + before preparing to run a script (between steps 2 and 3): + [=Report script execution start=] given |script|. +
+ +
+ Append the following step to perform a microtask checkpoint: + [=Flush script entry point=].
From e8d5168a0d20f9e2bb7f7245e3382f8760e0758c Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Wed, 29 Nov 2023 16:30:38 +0000 Subject: [PATCH 05/15] Add privsec --- index.bs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index f15a6b4..3c639c2 100644 --- a/index.bs +++ b/index.bs @@ -53,6 +53,7 @@ urlPrefix: https://html.spec.whatwg.org/multipage/; spec: HTML; type: dfn; url: #concept-task-document; for: task; text: document; type: dfn; url: #running-script; text: running script; type: dfn; url: #muted-errors; for: classic script; text: muted errors; + type: dfn; url: #cors-cross-origin; text: CORS cross-origin; urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT; type: dfn; url: #sec-code-realms; text: JavaScript Realms; urlPrefix: https://dom.spec.whatwg.org/; spec: DOM; @@ -823,9 +824,9 @@ The {{Promise}} interface has an associated string script url w Append the following steps to creating a new promise, before returning the {{Promise}}: 1. Let |interfaceName| be a string representing the [=interface=] responsible for creating this promise. 1. Let |attributeName| be a string representing the [=attribute=] in the interface responsible for creating this promise. + 1. Set the created {{Promise}}'s [=Promise/script url when created=] to the [=running script=]'s [=script/base URL=]. 1. The user-agent may set the created {{Promise}}'s [=Promise/invoker name when created=] to the last known [=concatenate|concatenation=] of « |interfaceName|, ".", |attributeName| » - 1. The user-agent may set the created {{Promise}}'s [=Promise/script url when created=] to the current script URL. Prepend the following step to resolve a promise given {{Promise}} |p|: [=Report promise resolver=] given |p| and "`resolve-promise`". @@ -957,7 +958,7 @@ Cross origin rules for what is exposed: occurrred in its cross-origin ancestor but does not receive any information about it. Attack Scenarios Considered {#attack-scenarios} --------------------------------------------------------- +----------------------------------------------- The following are the timing attacks considered: @@ -985,4 +986,11 @@ though long animation frames exposes them at a higher fidelity. To mitigate this, long animation frames are only reported to "participating local roots": only documents that are associated with a work task that contributed to the sequence, or that were rendered as part of the frame, are eligible to observe the long animation frame, and that long animation frame would be available only in -their nearest ancestor that is either topmost or has a cross-origin parent. \ No newline at end of file +their nearest ancestor that is either topmost or has a cross-origin parent. + +{{PerformanceScriptTiming}} and opaque scripts {#loaf-opaque-scripts-sec} +----------------------------------------------- +Since {{PerformanceScriptTiming}} exposes information about script execution, we need to make sure it +doesn't expose too much information about [=CORS cross-origin=] scripts that cannot be easily deduced otherwise. +To do that, we use the existing [=classic script/muted errors=] boolean, and report an empty {{PerformanceScriptTiming/sourceLocation}} +in such cases. \ No newline at end of file From 9191e01ae58a765ba4fb74143b50b9208077c20b Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Wed, 29 Nov 2023 17:31:14 +0000 Subject: [PATCH 06/15] Still report opaque script source --- index.bs | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/index.bs b/index.bs index 3c639c2..178dea4 100644 --- a/index.bs +++ b/index.bs @@ -750,22 +750,28 @@ Report Long Animation Frames {#loaf-processing-model}
- To report script execution start given a [=/script=] |script|: - 1. Let |scheme| be |script|'s [=script/base URL=]'s [=url/scheme=]. - 1. If |scheme| is neither "`http`", "`https`", "`blob`", or "`data`", return. + To set source url for script block given a [=script timing info=] |scriptTimingInfo| and a [=/URL=] |url|: + 1. If |url|'s [=url/scheme=] is "`http`" or "`https`", then set |scriptTimingInfo|'s [=script timing info/source url=] to |script|'s [=script/base URL=]. + 1. Otherwise, if |url|'s [=url/scheme=] is "`blob`" or "`data`" then set |scriptTimingInfo|'s [=script timing info/source url=] to the [=concatenate|concatenation=] of « |url|'s [=url/scheme=], ":"" ». - Note: this also excludes CORS cross-origin scripts, as they would have a [=script/base URL=] of about:blank. + To report classic script creation given a [=/script=] |script| and a [=/URL=] |originalSourceURL|: + 1. [=Create script entry point=] with |script|'s [=script/settings object=], "`classic-script`", + and the following step given a [=script timing info=] |scriptTimingInfo|: + [=Set source url for script block=] given |scriptTimingInfo| and |originalSourceURL|. - 1. Let |type| be "`module-script`" if |script| is a [=module script=], otherwise "`classic-script`". + To report classic script execution start given a [=classic script=] |script|: + 1. If |settings| is not a {{Window}}, then return. + 1. Let |document| be |settings|'s {{Window/document}}. + 1. Let |frameTimingInfo| be |document|'s [=relevant frame timing info=]. + 1. If |frameTimingInfo| is null or if |frameTimingInfo|'s [=frame timing info/pending script=] is not null, then return. + 1. Assert: |frameTimingInfo|'s [=frame timing info/pending script=]'s [=script timing info/type=] is "`classic-script`". + 1. Set |scriptTimingInfo|'s [=script timing info/execution start time=] to the [=unsafe shared current time=]. - 1. [=Create script entry point=] with |script|'s [=script/settings object=], |type|, + To report module script execution start given a [=module script=] |script|: + [=Create script entry point=] with |script|'s [=script/settings object=], "`module-script`", and the following step given a [=script timing info=] |scriptTimingInfo|: - 1. If |script| is a [=classic script=] then: - 1. Set |scriptTimingInfo|'s [=script timing info/execution start time=] to |scriptTimingInfo|'s [=script timing info/start time=]. - 1. Set |scriptTimingInfo|'s [=script timing info/start time=] to |script|'s [=classic script/creation time=]. - 1. If |scheme| is "`http`" or "`https`", then set |scriptTimingInfo|'s [=script timing info/source url=] to |script|'s [=script/base URL=]. - 1. Otherwise, set |scriptTimingInfo|'s [=script timing info/source url=] to the [=concatenate|concatenation=] of « |scheme|, ":"" ». - + 1. Set |scriptTimingInfo|'s [=script timing info/execution start time=] to |script|'s |scriptTimingInfo|'s [=script timing info/start time=]. + 1. [=Set source url for script block=] given |scriptTimingInfo| and |script|'s [=script/base URL=].
@@ -892,19 +898,17 @@ Monkey-patches to the HTML standard {#html-monkey-patches}
The [=classic script=] [=struct=] has an additional item: - creation time, a {{DOMHighResTimeStamp}}. - Insert a step to the create a classic script steps, - before parsing the script, assuming the |script| variable is populated: - Set |script|'s [=classic script/creation time=] to the [=unsafe shared current time=]. + before parsing the script, assuming the |script| variable is populated, assuming a |url| variable: + [=Report classic script creation=] given |script| and |url|. Insert a step to the run a classic script steps, before preparing to run a script (between steps 2 and 3): - [=Report script execution start=] given |script|. + [=Report classic script execution start=] given |script|. Insert a step to the run a module script steps, before preparing to run a script (between steps 2 and 3): - [=Report script execution start=] given |script|. + [=Report module script execution start=] given |script|.
From 105f0fe8c14aa13ebe96e7d0d1c799246262bab9 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Wed, 29 Nov 2023 17:31:56 +0000 Subject: [PATCH 07/15] Still report opaque script source --- index.bs | 1 + 1 file changed, 1 insertion(+) diff --git a/index.bs b/index.bs index 178dea4..1d8f062 100644 --- a/index.bs +++ b/index.bs @@ -760,6 +760,7 @@ Report Long Animation Frames {#loaf-processing-model} [=Set source url for script block=] given |scriptTimingInfo| and |originalSourceURL|. To report classic script execution start given a [=classic script=] |script|: + 1. If |script|'s [=classic script/muted errors=] is true, then return. 1. If |settings| is not a {{Window}}, then return. 1. Let |document| be |settings|'s {{Window/document}}. 1. Let |frameTimingInfo| be |document|'s [=relevant frame timing info=]. From 5f48e122a32567acb25a8d3aa5854d0d01eed496 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Wed, 13 Dec 2023 16:51:56 +0000 Subject: [PATCH 08/15] Fix indent --- index.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.bs b/index.bs index 1d8f062..bde4668 100644 --- a/index.bs +++ b/index.bs @@ -590,12 +590,12 @@ It has the following [=struct/items=]:
: type - :: A {{ScriptTimingType}}. + :: A {{ScriptTimingType}}. : start time : end time : execution start time - :: An unsafe {{DOMHighResTimeStamp}}, initially 0. + :: An unsafe {{DOMHighResTimeStamp}}, initially 0. : invoker name : source url @@ -603,10 +603,10 @@ It has the following [=struct/items=]: : event type : event target element id : event target element src attribute - :: A string, initially the empty string. + :: A string, initially the empty string. : source character position - :: A number, initially -1. + :: A number, initially -1.
A {{Document}} has a null or [=frame timing info=] current frame timing info, initially null. From 4e3850998d636f20fe287527a80b898bbd77881f Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Wed, 13 Dec 2023 16:58:27 +0000 Subject: [PATCH 09/15] Fix indent --- index.bs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/index.bs b/index.bs index bde4668..9267ea4 100644 --- a/index.bs +++ b/index.bs @@ -589,24 +589,24 @@ It has the following [=struct/items=]: script timing info is a [=struct=]. It has the following [=struct/items=]:
- : type +
type :: A {{ScriptTimingType}}. - : start time - : end time - : execution start time +
start time +
end time +
execution start time :: An unsafe {{DOMHighResTimeStamp}}, initially 0. - : invoker name - : source url - : source function name - : event type - : event target element id - : event target element src attribute - :: A string, initially the empty string. +
invoker name +
source url +
source function name +
event type +
event target element id +
event target element src attribute +
A string, initially the empty string. - : source character position - :: A number, initially -1. +
source character position +
A number, initially -1.
A {{Document}} has a null or [=frame timing info=] current frame timing info, initially null. From 6130e87de49e2e334045caeea9807257364ffd5f Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Wed, 13 Dec 2023 16:59:08 +0000 Subject: [PATCH 10/15] Fix indent --- index.bs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/index.bs b/index.bs index 9267ea4..39021d0 100644 --- a/index.bs +++ b/index.bs @@ -566,31 +566,31 @@ Frame Timing Info {#sec-frame-timing-info} It has the following [=struct/items=]:
- : start time - : current task start time - : update the rendering start time - : style and layout start time - : first ui event timestamp - : end time - :: A {{DOMHighResTimeStamp}}, initially 0. +
start time +
current task start time +
update the rendering start time +
style and layout start time +
first ui event timestamp +
end time +
A {{DOMHighResTimeStamp}}, initially 0. Note: all the above are [=monotonic clock/unsafe current time=|unsafe=], and should be [=coarsen time|coarsened=] when exposed via an API. - : longest task duration - :: A {{DOMHighResTimeStamp}}, initially 0. +
longest task duration +
A {{DOMHighResTimeStamp}}, initially 0. - : scripts - :: A [=/list=] of [=script timing info=], initially empty. +
scripts +
A [=/list=] of [=script timing info=], initially empty. - : pending script - :: Null or a [=script timing info=], initially null. +
pending script +
Null or a [=script timing info=], initially null.
script timing info is a [=struct=]. It has the following [=struct/items=]:
type - :: A {{ScriptTimingType}}. +
A {{ScriptTimingType}}.
start time
end time From 57d977df2873b21770ab04f60e343cda4e06949d Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Wed, 13 Dec 2023 19:17:40 +0000 Subject: [PATCH 11/15] Fix indent --- index.bs | 88 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/index.bs b/index.bs index 39021d0..333aa59 100644 --- a/index.bs +++ b/index.bs @@ -406,29 +406,29 @@ The {{PerformanceScriptTiming/name}} attribute's getter steps are: : "`classic-script`" : "`module-script`" - :: Return |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/source url=]. + :: Return |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/source url=]. : "`event-listener`" - :: - 1. Let |targetName| be |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/invoker name=]. - 1. If |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element id=] is not the empty string, then: - Set |targetName| to the [=concatenate|concatenation=] of « |targetName|, "#", |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element id=] ». - 1. Else, If |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element src attribute=] is not the empty string, then: - Set |targetName| to the [=concatenate|concatenation=] of « |targetName|, '[src=', |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element src attribute=], ']' ». - 1. Return the [=concatenate|concatenation=] of « |targetName|, ".on", [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event type=] ». + :: + 1. Let |targetName| be |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/invoker name=]. + 1. If |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element id=] is not the empty string, then: + Set |targetName| to the [=concatenate|concatenation=] of « |targetName|, "#", |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element id=] ». + 1. Else, If |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element src attribute=] is not the empty string, then: + Set |targetName| to the [=concatenate|concatenation=] of « |targetName|, '[src=', |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element src attribute=], ']' ». + 1. Return the [=concatenate|concatenation=] of « |targetName|, ".on", [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event type=] ». : "`user-callback`" - :: Return |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/invoker name=]. + :: Return |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/invoker name=]. : "`resolve-promise`" : "`reject-promise`" - :: - 1. If |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/invoker name=] is the empty string, - then: - 1. If |this|'s {{PerformanceScriptTiming/type}} is "`resolve-promise`", then return "`Promise.resolve`". - 1. Otherwise, return "`Promise.reject`". - 1. Let |thenOrCatch| be "`then`" if {{PerformanceScriptTiming/type}} is "`resolve-promise`"; Otherwise "`reject-promise`". - 1. Return the [=concatenate|concatenation=] of « [=script timing info/invoker name=], ".", |thenOrCatch| ». + :: + 1. If |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/invoker name=] is the empty string, + then: + 1. If |this|'s {{PerformanceScriptTiming/type}} is "`resolve-promise`", then return "`Promise.resolve`". + 1. Otherwise, return "`Promise.reject`". + 1. Let |thenOrCatch| be "`then`" if {{PerformanceScriptTiming/type}} is "`resolve-promise`"; Otherwise "`reject-promise`". + 1. Return the [=concatenate|concatenation=] of « [=script timing info/invoker name=], ".", |thenOrCatch| ». The {{PerformanceScriptTiming/startTime}} attribute's getter step is to return the [=relative high resolution time=] given [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/start time=] and [=this=]'s [=relevant global object=]. @@ -566,47 +566,47 @@ Frame Timing Info {#sec-frame-timing-info} It has the following [=struct/items=]:
-
start time -
current task start time -
update the rendering start time -
style and layout start time -
first ui event timestamp -
end time -
A {{DOMHighResTimeStamp}}, initially 0. + : start time + : current task start time + : update the rendering start time + : style and layout start time + : first ui event timestamp + : end time + :: A {{DOMHighResTimeStamp}}, initially 0. Note: all the above are [=monotonic clock/unsafe current time=|unsafe=], - and should be [=coarsen time|coarsened=] when exposed via an API. + and should be [=coarsen time|coarsened=] when exposed via an API. -
longest task duration -
A {{DOMHighResTimeStamp}}, initially 0. + : longest task duration + :: A {{DOMHighResTimeStamp}}, initially 0. -
scripts -
A [=/list=] of [=script timing info=], initially empty. + : scripts + :: A [=/list=] of [=script timing info=], initially empty. -
pending script -
Null or a [=script timing info=], initially null. + : pending script + :: Null or a [=script timing info=], initially null.
script timing info is a [=struct=]. It has the following [=struct/items=]:
-
type -
A {{ScriptTimingType}}. + : type + :: A {{ScriptTimingType}}. -
start time -
end time -
execution start time + : start time + : end time + : execution start time :: An unsafe {{DOMHighResTimeStamp}}, initially 0. -
invoker name -
source url -
source function name -
event type -
event target element id -
event target element src attribute -
A string, initially the empty string. + : invoker name + : source url + : source function name + : event type + : event target element id + : event target element src attribute + :: A string, initially the empty string. -
source character position -
A number, initially -1. + : source character position + :: A number, initially -1.
A {{Document}} has a null or [=frame timing info=] current frame timing info, initially null. From 3565f5a9071773e052f0833a8711008b3cb76bf0 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Thu, 14 Dec 2023 20:25:43 +0000 Subject: [PATCH 12/15] nits --- index.bs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.bs b/index.bs index 333aa59..802a6c3 100644 --- a/index.bs +++ b/index.bs @@ -360,7 +360,7 @@ The {{PerformanceLongAnimationFrameTiming/blockingDuration}} attribute's getter 1. Return 0. The {{PerformanceLongAnimationFrameTiming/scripts}} attribute's getter steps are: - 1. Let |scripts| be « ». + 1. Let |scripts| be a [=/list=] « ». 1. [=list/For each=] |scriptInfo| in [=this=]'s [=frame timing info=]'s [=frame timing info/scripts=]: 1. Let |scriptEntry| be a new {{PerformanceScriptTiming}} in [=this=]'s [=relevant realm=], whose [=PerformanceScriptTiming/timing info=] is |scriptInfo|. @@ -417,6 +417,8 @@ The {{PerformanceScriptTiming/name}} attribute's getter steps are: Set |targetName| to the [=concatenate|concatenation=] of « |targetName|, '[src=', |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event target element src attribute=], ']' ». 1. Return the [=concatenate|concatenation=] of « |targetName|, ".on", [=this=]'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/event type=] ». + Issue: this feels a bit custom, need to discuss name generation. + : "`user-callback`" :: Return |this|'s [=PerformanceScriptTiming/timing info=]'s [=script timing info/invoker name=]. From b13e825a14c6be6f92c95d9878f5d76d15769ee2 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Thu, 14 Dec 2023 20:27:00 +0000 Subject: [PATCH 13/15] nits --- index.bs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.bs b/index.bs index 802a6c3..257eae9 100644 --- a/index.bs +++ b/index.bs @@ -60,8 +60,8 @@ urlPrefix: https://dom.spec.whatwg.org/; spec: DOM; type: attribute; for: Element; text: id; url: #dom-element-id; urlPrefix: https://webidl.spec.whatwg.org/; spec: WEBIDL; - type: dfn; text: identifier; url: #identifier; - type: dfn; text: attribute; url: #attribute; + type: dfn; text: identifier; url: #dfn-identifier; + type: dfn; text: attribute; url: #dfn-attribute;