Skip to content

Commit 06cbec8

Browse files
add optional marker for early exits in algorithm steps (#683)
1 parent 68ef31d commit 06cbec8

54 files changed

Lines changed: 201 additions & 35 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

css/elements.css

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
--link-foreground-color: #206ca7;
66
--link-hover-foreground-color: #239dee;
77

8-
--user-code-foreground-color: brown;
8+
--annotation-foreground-color: brown;
99

1010
--var-foreground-color: #218379;
1111

@@ -89,7 +89,7 @@
8989
--link-foreground-color: #439de2;
9090
--link-hover-foreground-color: #80cafb;
9191

92-
--user-code-foreground-color: brown;
92+
--annotation-foreground-color: brown;
9393

9494
--var-foreground-color: #4fb6ab;
9595

@@ -337,9 +337,9 @@ span.e-user-code {
337337
a.e-user-code::before,
338338
span.e-user-code::before {
339339
display: none;
340-
color: var(--user-code-foreground-color);
340+
color: var(--annotation-foreground-color);
341341
background-color: var(--background-color);
342-
border: 2pt solid var(--user-code-foreground-color);
342+
border: 2pt solid var(--annotation-foreground-color);
343343
padding: 0.3ex;
344344
margin: 0 0.25em 0 0;
345345
line-height: normal;
@@ -354,12 +354,12 @@ span.e-user-code::before {
354354

355355
a.e-user-code:hover::before,
356356
span.e-user-code:hover::before {
357-
background-color: var(--user-code-foreground-color);
357+
background-color: var(--annotation-foreground-color);
358358
color: var(--background-color);
359359
}
360360

361-
html.show-ao-annotations a.e-user-code::before,
362-
html.show-ao-annotations span.e-user-code::before {
361+
html.show-uc-annotations a.e-user-code::before,
362+
html.show-uc-annotations span.e-user-code::before {
363363
display: inline-block;
364364
}
365365

@@ -462,6 +462,25 @@ emu-val {
462462
font-weight: bold;
463463
}
464464

465+
/* prefix algorithm-terminating steps with an indicator when dynamically enabled */
466+
emu-alg li.exit::before {
467+
display: none;
468+
border: 2pt solid var(--annotation-foreground-color);
469+
font-size: small;
470+
color: var(--annotation-foreground-color);
471+
padding: 0 0.25em;
472+
background-color: var(--background-color);
473+
content: '⏎';
474+
margin-right: 0.25em;
475+
line-height: 15px;
476+
vertical-align: middle;
477+
}
478+
479+
html.show-early-exits emu-alg li.exit:not(emu-alg ol.ac-body > li:last-child):not(emu-alg > ol > li:last-child)::before {
480+
display: inline-block;
481+
}
482+
483+
465484
/* depth 1 */
466485
emu-alg ol,
467486
/* depth 4 */

js/menu.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1111,7 +1111,9 @@ function doShortcut(e) {
11111111
location = 'multipage/' + hash;
11121112
}
11131113
} else if (e.key === 'u') {
1114-
document.documentElement.classList.toggle('show-ao-annotations');
1114+
document.documentElement.classList.toggle('show-uc-annotations');
1115+
} else if (e.key === 'e') {
1116+
document.documentElement.classList.toggle('show-early-exits');
11151117
} else if (e.key === '?') {
11161118
document.getElementById('shortcuts-help').classList.toggle('active');
11171119
}

src/Algorithm.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,21 @@ export default class Algorithm extends Builder {
7878
html = html.replace(/[ \t]+([»}])/g, ' $1');
7979
node.innerHTML = html;
8080

81+
// mark algorithm-terminating steps (return/throw/?) with the `exit` class
82+
const earlyExitIndicator = /\b(?:return|throw)\b|[\s(]\?\s/i;
83+
// these are macros in ECMA-262 that expand to steps that include a return/throw/?
84+
const earlyExitMacro = /\bIfAbrupt(?:CloseIterator|CloseAsyncIterator|RejectPromise)\(/;
85+
const note = /^(?:NOTE|Assert): /;
86+
for (const ol of node.querySelectorAll('ol')) {
87+
const items = ol.children;
88+
for (let i = 0; i < items.length; i++) {
89+
const text = ownTextContent(items[i]);
90+
if ((earlyExitIndicator.test(text) || earlyExitMacro.test(text)) && !note.test(text)) {
91+
items[i].classList.add('exit');
92+
}
93+
}
94+
}
95+
8196
const labeledStepEntries: StepBiblioEntry[] = [];
8297
const replaces = node.getAttribute('replaces-step');
8398
if (replaces) {

src/Spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,7 @@ ${await utils.readFile(path.join(__dirname, '../js/multipage.js'))}
13281328
<ul>
13291329
<li><span>Toggle shortcuts help</span><code>?</code></li>
13301330
<li><span>Toggle "can call user code" annotations</span><code>u</code></li>
1331+
<li><span>Toggle early exit annotations</span><code>e</code></li>
13311332
${this.opts.multipage ? `<li><span>Navigate to/from multipage</span><code>m</code></li>` : ''}
13321333
<li><span>Jump to search box</span><code>/</code></li>
13331334
<li><span>Toggle pinning of the current clause</span><code>p</code></li>

src/utils.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,9 @@ export function isAbstractClosureHeader(text: string): boolean {
349349
export function ownTextContent(el: Element): string {
350350
let text = '';
351351
for (const child of el.childNodes) {
352-
if (child.nodeType === 1 && (child as Element).tagName === 'OL') continue;
353-
text += child.textContent;
352+
if (child.nodeType === 3) {
353+
text += child.textContent;
354+
}
354355
}
355356
return text;
356357
}

test/baselines/generated-reference/abstract-methods.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<ul>
44
<li><span>Toggle shortcuts help</span><code>?</code></li>
55
<li><span>Toggle "can call user code" annotations</span><code>u</code></li>
6+
<li><span>Toggle early exit annotations</span><code>e</code></li>
67

78
<li><span>Jump to search box</span><code>/</code></li>
89
<li><span>Toggle pinning of the current clause</span><code>p</code></li>
@@ -67,21 +68,21 @@ <h1><span class="secnum">1</span> Concrete Methods Definitions</h1>
6768
<h1><span class="secnum">1.1</span> ResolveExport ( <var>exportName</var> [ , <var>resolveSet</var> ] )</h1>
6869
<p>The <emu-xref aoid="ResolveExport" id="_ref_0"><a href="#abstract-resolveexport">ResolveExport</a></emu-xref> concrete method of a <emu-xref href="#sourctextmodule-record"><a href="https://tc39.es/ecma262/#sourctextmodule-record">Source Text Module Record</a></emu-xref> <var>foo</var> takes argument <var>exportName</var> (a String) and optional argument <var>resolveSet</var> (a <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">List</a></emu-xref> of <emu-xref href="#sec-abstract-module-records"><a href="https://tc39.es/ecma262/#sec-abstract-module-records">Module Records</a></emu-xref>) and returns either a <emu-xref href="#sec-abstract-module-records"><a href="https://tc39.es/ecma262/#sec-abstract-module-records">Module Record</a></emu-xref> or <emu-val>null</emu-val>. It performs the following steps when called:</p>
6970

70-
<emu-alg><ol><li>Return <emu-const>unused</emu-const>.</li></ol></emu-alg>
71+
<emu-alg><ol><li class="exit">Return <emu-const>unused</emu-const>.</li></ol></emu-alg>
7172
</emu-clause>
7273

7374
<emu-clause id="sec-smr-ResolveExport" type="concrete method">
7475
<h1><span class="secnum">1.2</span> ResolveExport ( <var>exportName</var> [ , <var>resolveSet</var> ] )</h1>
7576
<p>The <emu-xref aoid="ResolveExport" id="_ref_1"><a href="#abstract-resolveexport">ResolveExport</a></emu-xref> concrete method of a Synthetic <emu-xref href="#sec-abstract-module-records"><a href="https://tc39.es/ecma262/#sec-abstract-module-records">Module Record</a></emu-xref> <var>foo</var> takes argument <var>exportName</var> (a String) and optional argument <var>resolveSet</var> (a <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">List</a></emu-xref> of <emu-xref href="#sec-abstract-module-records"><a href="https://tc39.es/ecma262/#sec-abstract-module-records">Module Records</a></emu-xref>) and returns either a <emu-xref href="#sec-abstract-module-records"><a href="https://tc39.es/ecma262/#sec-abstract-module-records">Module Record</a></emu-xref> or <emu-val>null</emu-val>. It performs the following steps when called:</p>
7677

77-
<emu-alg><ol><li>Do something.</li><li>Return <emu-const>unused</emu-const>.</li></ol></emu-alg>
78+
<emu-alg><ol><li>Do something.</li><li class="exit">Return <emu-const>unused</emu-const>.</li></ol></emu-alg>
7879
</emu-clause>
7980
</emu-clause>
8081

8182
<emu-clause id="sec-UseIt" type="abstract operation" aoid="UseIt">
8283
<h1><span class="secnum">2</span> UseIt ( <var>module</var> )</h1>
8384
<p>The abstract operation UseIt takes argument <var>module</var> (a <emu-xref href="#sec-abstract-module-records"><a href="https://tc39.es/ecma262/#sec-abstract-module-records">Module Record</a></emu-xref>) and returns <emu-const>unused</emu-const>. It performs the following steps when called:</p>
8485

85-
<emu-alg><ol><li>Let <var>result</var> be <var>module</var>.<emu-xref aoid="ResolveExport" id="_ref_2"><a href="#abstract-resolveexport">ResolveExport</a></emu-xref>(<emu-val>"example"</emu-val>).</li><li>Perform <var>module</var>.<emu-xref aoid="NewName" id="_ref_3"><a href="#abstract-newname">NewName</a></emu-xref>().</li><li>Perform <var>module</var>.<emu-xref aoid="AddedMethod" id="_ref_4"><a href="#abstract-addedmethod">AddedMethod</a></emu-xref>().</li><li>Return <emu-const>unused</emu-const>.</li></ol></emu-alg>
86+
<emu-alg><ol><li>Let <var>result</var> be <var>module</var>.<emu-xref aoid="ResolveExport" id="_ref_2"><a href="#abstract-resolveexport">ResolveExport</a></emu-xref>(<emu-val>"example"</emu-val>).</li><li>Perform <var>module</var>.<emu-xref aoid="NewName" id="_ref_3"><a href="#abstract-newname">NewName</a></emu-xref>().</li><li>Perform <var>module</var>.<emu-xref aoid="AddedMethod" id="_ref_4"><a href="#abstract-addedmethod">AddedMethod</a></emu-xref>().</li><li class="exit">Return <emu-const>unused</emu-const>.</li></ol></emu-alg>
8687
</emu-clause>
8788
</div></body>

test/baselines/generated-reference/algorithm-replacements.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<ul>
44
<li><span>Toggle shortcuts help</span><code>?</code></li>
55
<li><span>Toggle "can call user code" annotations</span><code>u</code></li>
6+
<li><span>Toggle early exit annotations</span><code>e</code></li>
67

78
<li><span>Jump to search box</span><code>/</code></li>
89
<li><span>Toggle pinning of the current clause</span><code>p</code></li>

test/baselines/generated-reference/algorithms.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<ul>
44
<li><span>Toggle shortcuts help</span><code>?</code></li>
55
<li><span>Toggle "can call user code" annotations</span><code>u</code></li>
6+
<li><span>Toggle early exit annotations</span><code>e</code></li>
67

78
<li><span>Jump to search box</span><code>/</code></li>
89
<li><span>Toggle pinning of the current clause</span><code>p</code></li>
@@ -11,7 +12,7 @@
1112
<li><span>Jump to the most recent link target</span><code>`</code></li>
1213
</ul></div><div id="spec-container">
1314

14-
<emu-alg><ol><li>Can call <emu-xref href="#sec-algorithm-conventions-abstract-operations"><a href="https://tc39.es/ecma262/#sec-algorithm-conventions-abstract-operations">abstract operations</a></emu-xref> in this spec: <emu-xref aoid="Internal" id="_ref_0"><a href="#sec-internal">Internal</a></emu-xref>();</li><li>Can call <emu-xref href="#sec-algorithm-conventions-abstract-operations"><a href="https://tc39.es/ecma262/#sec-algorithm-conventions-abstract-operations">abstract operations</a></emu-xref> in ES6: <emu-xref aoid="ReturnIfAbrupt"><a href="https://tc39.es/ecma262/#sec-returnifabrupt">ReturnIfAbrupt</a></emu-xref>(<var>completion</var>);</li><li>Can call <emu-xref href="#sec-algorithm-conventions-abstract-operations"><a href="https://tc39.es/ecma262/#sec-algorithm-conventions-abstract-operations">abstract operations</a></emu-xref> in a biblio file: <emu-xref aoid="Biblio"><a href="http://example.com/fooSite.html#sec-biblio">Biblio</a></emu-xref>();</li><li>Unfound <emu-xref href="#sec-algorithm-conventions-abstract-operations"><a href="https://tc39.es/ecma262/#sec-algorithm-conventions-abstract-operations">abstract operations</a></emu-xref> just don't link: Unfound();</li><li>Can prefix with !&nbsp;and ?.<ol><li>Let <var>foo</var> be ?&nbsp;<emu-xref aoid="Internal" id="_ref_1"><a href="#sec-internal">Internal</a></emu-xref>();</li><li>Set <var>foo</var> to !&nbsp;<emu-xref aoid="Internal" id="_ref_2"><a href="#sec-internal">Internal</a></emu-xref>();</li><li>Set <var>foo</var> to !&nbsp;SDO of <var>operation</var>.</li><li>Set <var>foo</var> to !&nbsp;<var>operation</var>.<var class="field">[[MOP]]</var>().</li></ol></li><li>A <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">Record</a></emu-xref> looks like this: <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">Record</a></emu-xref> { <var class="field">[[Key]]</var>: 0&nbsp;}.</li><li>A <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">List</a></emu-xref> looks like this: « 0, 1&nbsp;».</li></ol></emu-alg>
15+
<emu-alg><ol><li>Can call <emu-xref href="#sec-algorithm-conventions-abstract-operations"><a href="https://tc39.es/ecma262/#sec-algorithm-conventions-abstract-operations">abstract operations</a></emu-xref> in this spec: <emu-xref aoid="Internal" id="_ref_0"><a href="#sec-internal">Internal</a></emu-xref>();</li><li>Can call <emu-xref href="#sec-algorithm-conventions-abstract-operations"><a href="https://tc39.es/ecma262/#sec-algorithm-conventions-abstract-operations">abstract operations</a></emu-xref> in ES6: <emu-xref aoid="ReturnIfAbrupt"><a href="https://tc39.es/ecma262/#sec-returnifabrupt">ReturnIfAbrupt</a></emu-xref>(<var>completion</var>);</li><li>Can call <emu-xref href="#sec-algorithm-conventions-abstract-operations"><a href="https://tc39.es/ecma262/#sec-algorithm-conventions-abstract-operations">abstract operations</a></emu-xref> in a biblio file: <emu-xref aoid="Biblio"><a href="http://example.com/fooSite.html#sec-biblio">Biblio</a></emu-xref>();</li><li>Unfound <emu-xref href="#sec-algorithm-conventions-abstract-operations"><a href="https://tc39.es/ecma262/#sec-algorithm-conventions-abstract-operations">abstract operations</a></emu-xref> just don't link: Unfound();</li><li>Can prefix with !&nbsp;and ?.<ol><li class="exit">Let <var>foo</var> be ?&nbsp;<emu-xref aoid="Internal" id="_ref_1"><a href="#sec-internal">Internal</a></emu-xref>();</li><li>Set <var>foo</var> to !&nbsp;<emu-xref aoid="Internal" id="_ref_2"><a href="#sec-internal">Internal</a></emu-xref>();</li><li>Set <var>foo</var> to !&nbsp;SDO of <var>operation</var>.</li><li>Set <var>foo</var> to !&nbsp;<var>operation</var>.<var class="field">[[MOP]]</var>().</li></ol></li><li>A <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">Record</a></emu-xref> looks like this: <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">Record</a></emu-xref> { <var class="field">[[Key]]</var>: 0&nbsp;}.</li><li>A <emu-xref href="#sec-list-and-record-specification-type"><a href="https://tc39.es/ecma262/#sec-list-and-record-specification-type">List</a></emu-xref> looks like this: « 0, 1&nbsp;».</li></ol></emu-alg>
1516

1617
<emu-clause id="sec-internal" aoid="Internal">
1718
<h1><span class="secnum">1</span> Internal Function</h1>

test/baselines/generated-reference/assets-inline.html

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,7 +1195,9 @@
11951195
location = 'multipage/' + hash;
11961196
}
11971197
} else if (e.key === 'u') {
1198-
document.documentElement.classList.toggle('show-ao-annotations');
1198+
document.documentElement.classList.toggle('show-uc-annotations');
1199+
} else if (e.key === 'e') {
1200+
document.documentElement.classList.toggle('show-early-exits');
11991201
} else if (e.key === '?') {
12001202
document.getElementById('shortcuts-help').classList.toggle('active');
12011203
}
@@ -1623,7 +1625,7 @@
16231625
--link-foreground-color: #206ca7;
16241626
--link-hover-foreground-color: #239dee;
16251627
1626-
--user-code-foreground-color: brown;
1628+
--annotation-foreground-color: brown;
16271629
16281630
--var-foreground-color: #218379;
16291631
@@ -1707,7 +1709,7 @@
17071709
--link-foreground-color: #439de2;
17081710
--link-hover-foreground-color: #80cafb;
17091711
1710-
--user-code-foreground-color: brown;
1712+
--annotation-foreground-color: brown;
17111713
17121714
--var-foreground-color: #4fb6ab;
17131715
@@ -1955,9 +1957,9 @@
19551957
a.e-user-code::before,
19561958
span.e-user-code::before {
19571959
display: none;
1958-
color: var(--user-code-foreground-color);
1960+
color: var(--annotation-foreground-color);
19591961
background-color: var(--background-color);
1960-
border: 2pt solid var(--user-code-foreground-color);
1962+
border: 2pt solid var(--annotation-foreground-color);
19611963
padding: 0.3ex;
19621964
margin: 0 0.25em 0 0;
19631965
line-height: normal;
@@ -1972,12 +1974,12 @@
19721974
19731975
a.e-user-code:hover::before,
19741976
span.e-user-code:hover::before {
1975-
background-color: var(--user-code-foreground-color);
1977+
background-color: var(--annotation-foreground-color);
19761978
color: var(--background-color);
19771979
}
19781980
1979-
html.show-ao-annotations a.e-user-code::before,
1980-
html.show-ao-annotations span.e-user-code::before {
1981+
html.show-uc-annotations a.e-user-code::before,
1982+
html.show-uc-annotations span.e-user-code::before {
19811983
display: inline-block;
19821984
}
19831985
@@ -2080,6 +2082,25 @@
20802082
font-weight: bold;
20812083
}
20822084
2085+
/* prefix algorithm-terminating steps with an indicator when dynamically enabled */
2086+
emu-alg li.exit::before {
2087+
display: none;
2088+
border: 2pt solid var(--annotation-foreground-color);
2089+
font-size: small;
2090+
color: var(--annotation-foreground-color);
2091+
padding: 0 0.25em;
2092+
background-color: var(--background-color);
2093+
content: '';
2094+
margin-right: 0.25em;
2095+
line-height: 15px;
2096+
vertical-align: middle;
2097+
}
2098+
2099+
html.show-early-exits emu-alg li.exit:not(emu-alg ol.ac-body > li:last-child):not(emu-alg > ol > li:last-child)::before {
2100+
display: inline-block;
2101+
}
2102+
2103+
20832104
/* depth 1 */
20842105
emu-alg ol,
20852106
/* depth 4 */
@@ -3985,6 +4006,7 @@
39854006
<ul>
39864007
<li><span>Toggle shortcuts help</span><code>?</code></li>
39874008
<li><span>Toggle "can call user code" annotations</span><code>u</code></li>
4009+
<li><span>Toggle early exit annotations</span><code>e</code></li>
39884010
39894011
<li><span>Jump to search box</span><code>/</code></li>
39904012
<li><span>Toggle pinning of the current clause</span><code>p</code></li>

test/baselines/generated-reference/autolinking.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<ul>
44
<li><span>Toggle shortcuts help</span><code>?</code></li>
55
<li><span>Toggle "can call user code" annotations</span><code>u</code></li>
6+
<li><span>Toggle early exit annotations</span><code>e</code></li>
67

78
<li><span>Jump to search box</span><code>/</code></li>
89
<li><span>Toggle pinning of the current clause</span><code>p</code></li>

0 commit comments

Comments
 (0)