Reffy now extracts algorithms from specs, see algorithms extracts in Webref. Extraction is far from perfect (a number of limitations are noted as TODO comments in the extraction logic) but the results are still good enough to start analyzing potential problems in algorithms, see study-algorithms.js.
Also see @dontcallmeDOM's initial algorithms explorer based on the extracts.
Analysis: parallel steps that should call "queue a task"
First thing I analyzed are steps that run in parallel because I always forget the need to queue a task within parallel steps before resolving/rejecting a Promise or firing an event. @jyasskin noted the same problem back in 2022 in https://github.com/whatwg/html/issues/8569. What's new here is that we can now compute that information automatically, giving us more weapons to play whack-a-mole.
The results show that about 50% of the specs (56/113) that define algorithms with "in parallel" steps need fixing:
Specs with steps in parallel that miss a call to "queue a task" (56 specs)
- [Accelerated Shape Detection in Images](https://wicg.github.io/shape-detection-api/)
- The [BarcodeDetector/getSupportedFormats()](https://wicg.github.io/shape-detection-api/#dom-barcodedetector-getsupportedformats) algorithm has a parallel step that resolves/rejects a promise directly
- [Audio Output Devices API](https://w3c.github.io/mediacapture-output/)
- The [HTMLMediaElement/setSinkId()](https://w3c.github.io/mediacapture-output/#dom-htmlmediaelement-setsinkid) algorithm has a parallel step that resolves/rejects a promise directly
- The [MediaDevices/selectAudioOutput()](https://w3c.github.io/mediacapture-output/#dom-mediadevices-selectaudiooutput) algorithm has a parallel step that resolves/rejects a promise directly
- [Background Fetch](https://wicg.github.io/background-fetch/)
- The [create record objects](https://wicg.github.io/background-fetch/#create-record-objects) algorithm has a parallel step that resolves/rejects a promise directly
- The [get(id)](https://wicg.github.io/background-fetch/#dom-backgroundfetchmanager-get) algorithm has a parallel step that resolves/rejects a promise directly
- The [getIds()](https://wicg.github.io/background-fetch/#dom-backgroundfetchmanager-getids) algorithm has a parallel step that resolves/rejects a promise directly
- The [abort()](https://wicg.github.io/background-fetch/#dom-backgroundfetchregistration-abort) algorithm has a parallel step that resolves/rejects a promise directly
- The [updateUI(options)](https://wicg.github.io/background-fetch/#dom-backgroundfetchupdateuievent-updateui) algorithm has a parallel step that resolves/rejects a promise directly
- [Contact Picker API](https://w3c.github.io/contact-picker/)
- The [getProperties()](https://w3c.github.io/contact-picker/#dom-contactsmanager-getproperties) algorithm has a parallel step that resolves/rejects a promise directly
- [Content Index](https://wicg.github.io/content-index/spec/)
- The [add(description)](https://wicg.github.io/content-index/spec/#dom-contentindex-add) algorithm has a parallel step that resolves/rejects a promise directly
- The [delete(id)](https://wicg.github.io/content-index/spec/#dom-contentindex-delete) algorithm has a parallel step that resolves/rejects a promise directly
- The [getAll()](https://wicg.github.io/content-index/spec/#dom-contentindex-getall) algorithm has a parallel step that resolves/rejects a promise directly
- [Cookie Store API](https://wicg.github.io/cookie-store/)
- The [CookieStore/get(name)](https://wicg.github.io/cookie-store/#dom-cookiestore-get) algorithm has a parallel step that resolves/rejects a promise directly
- The [CookieStore/get(options)](https://wicg.github.io/cookie-store/#dom-cookiestore-get-options) algorithm has a parallel step that resolves/rejects a promise directly
- The [CookieStore/getAll(name)](https://wicg.github.io/cookie-store/#dom-cookiestore-getall) algorithm has a parallel step that resolves/rejects a promise directly
- The [CookieStore/getAll(options)](https://wicg.github.io/cookie-store/#dom-cookiestore-getall-options) algorithm has a parallel step that resolves/rejects a promise directly
- The [CookieStore/set(name, value)](https://wicg.github.io/cookie-store/#dom-cookiestore-set) algorithm has a parallel step that resolves/rejects a promise directly
- The [CookieStore/set(options)](https://wicg.github.io/cookie-store/#dom-cookiestore-set-options) algorithm has a parallel step that resolves/rejects a promise directly
- The [CookieStore/delete(name)](https://wicg.github.io/cookie-store/#dom-cookiestore-delete) algorithm has a parallel step that resolves/rejects a promise directly
- The [CookieStore/delete(options)](https://wicg.github.io/cookie-store/#dom-cookiestore-delete-options) algorithm has a parallel step that resolves/rejects a promise directly
- The [CookieStoreManager/subscribe(subscriptions)](https://wicg.github.io/cookie-store/#dom-cookiestoremanager-subscribe) algorithm has a parallel step that resolves/rejects a promise directly
- The [CookieStoreManager/getSubscriptions()](https://wicg.github.io/cookie-store/#dom-cookiestoremanager-getsubscriptions) algorithm has a parallel step that resolves/rejects a promise directly
- The [CookieStoreManager/unsubscribe(subscriptions)](https://wicg.github.io/cookie-store/#dom-cookiestoremanager-unsubscribe) algorithm has a parallel step that resolves/rejects a promise directly
- [Credential Management Level 1](https://w3c.github.io/webappsec-credential-management/)
- The [Request a Credential](https://w3c.github.io/webappsec-credential-management/#abstract-opdef-request-a-credential) algorithm has a parallel step that resolves/rejects a promise directly
- The [Create a Credential](https://w3c.github.io/webappsec-credential-management/#abstract-opdef-create-a-credential) algorithm has a parallel step that resolves/rejects a promise directly
- The [Prevent Silent Access](https://w3c.github.io/webappsec-credential-management/#abstract-opdef-prevent-silent-access) algorithm has a parallel step that resolves/rejects a promise directly
- [CSS Object Model (CSSOM)](https://drafts.csswg.org/cssom-1/)
- The [CSSStyleSheet/replace(text)](https://drafts.csswg.org/cssom-1/#dom-cssstylesheet-replace) algorithm has a parallel step that resolves/rejects a promise directly
- [Element Capture](https://screen-share.github.io/element-capture/)
- The [BrowserCaptureMediaStreamTrack/restrictTo()](https://screen-share.github.io/element-capture/#dom-browsercapturemediastreamtrack-restrictto) algorithm has a parallel step that resolves/rejects a promise directly
- [Encrypted Media Extensions](https://w3c.github.io/encrypted-media/)
- The [Navigator/requestMediaKeySystemAccess()](https://w3c.github.io/encrypted-media/#dom-navigator-requestmediakeysystemaccess) algorithm has a parallel step that resolves/rejects a promise directly
- The [MediaKeySystemAccess/createMediaKeys()](https://w3c.github.io/encrypted-media/#dom-mediakeysystemaccess-createmediakeys) algorithm has a parallel step that resolves/rejects a promise directly
- The [MediaKeys/setServerCertificate()](https://w3c.github.io/encrypted-media/#dom-mediakeys-setservercertificate) algorithm has a parallel step that resolves/rejects a promise directly
- The [MediaKeySession/generateRequest()](https://w3c.github.io/encrypted-media/#dom-mediakeysession-generaterequest) algorithm has a parallel step that resolves/rejects a promise directly
- The [MediaKeySession/load()](https://w3c.github.io/encrypted-media/#dom-mediakeysession-load) algorithm has a parallel step that resolves/rejects a promise directly
- The [MediaKeySession/update()](https://w3c.github.io/encrypted-media/#dom-mediakeysession-update) algorithm has a parallel step that resolves/rejects a promise directly
- The [HTMLMediaElement/setMediaKeys()](https://w3c.github.io/encrypted-media/#dom-htmlmediaelement-setmediakeys) algorithm has a parallel step that resolves/rejects a promise directly
- [EyeDropper API](https://wicg.github.io/eyedropper-api/)
- The [EyeDropper/open()](https://wicg.github.io/eyedropper-api/#dom-eyedropper-open) algorithm has a parallel step that resolves/rejects a promise directly
- [Federated Credential Management API](https://fedidcg.github.io/FedCM/)
- The [attempt to disconnect](https://fedidcg.github.io/FedCM/#attempt-to-disconnect) algorithm has a parallel step that resolves/rejects a promise directly
- The getUserInfo algorithm has a parallel step that resolves/rejects a promise directly
- [File System Access](https://wicg.github.io/file-system-access/)
- The [FileSystemHandle/queryPermission(descriptor)](https://wicg.github.io/file-system-access/#dom-filesystemhandle-querypermission) algorithm has a parallel step that resolves/rejects a promise directly
- The [FileSystemHandle/requestPermission(descriptor)](https://wicg.github.io/file-system-access/#dom-filesystemhandle-requestpermission) algorithm has a parallel step that resolves/rejects a promise directly
- The [Window/showOpenFilePicker(options)](https://wicg.github.io/file-system-access/#dom-window-showopenfilepicker) algorithm has a parallel step that resolves/rejects a promise directly
- The [Window/showSaveFilePicker(options)](https://wicg.github.io/file-system-access/#dom-window-showsavefilepicker) algorithm has a parallel step that resolves/rejects a promise directly
- The [Window/showDirectoryPicker(options)](https://wicg.github.io/file-system-access/#dom-window-showdirectorypicker) algorithm has a parallel step that resolves/rejects a promise directly
- The [DataTransferItem/getAsFileSystemHandle()](https://wicg.github.io/file-system-access/#dom-datatransferitem-getasfilesystemhandle) algorithm has a parallel step that resolves/rejects a promise directly
- [Fullscreen API Standard](https://fullscreen.spec.whatwg.org/)
- The [requestFullscreen(options)](https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen) algorithm has a parallel step that resolves/rejects a promise directly
- The [exit fullscreen](https://fullscreen.spec.whatwg.org/#exit-fullscreen) algorithm has a parallel step that resolves/rejects a promise directly
- [Gamepad](https://w3c.github.io/gamepad/)
- The [GamepadHapticActuator/reset()](https://w3c.github.io/gamepad/#dom-gamepadhapticactuator-reset) algorithm has a parallel step that resolves/rejects a promise directly
- [Geolocation Sensor](https://w3c.github.io/geolocation-sensor/)
- The read algorithm has a parallel step that resolves/rejects a promise directly
- [Get Installed Related Apps API](https://wicg.github.io/get-installed-related-apps/spec/)
- The [getInstalledRelatedApps()](https://wicg.github.io/get-installed-related-apps/spec/#dom-navigator-getinstalledrelatedapps) algorithm has a parallel step that resolves/rejects a promise directly
- [Handwriting Recognition API](https://wicg.github.io/handwriting-recognition/)
- The navigator-query-handwriting-recognizer algorithm has a parallel step that resolves/rejects a promise directly
- The navigator-create-handwriting-recognizer algorithm has a parallel step that resolves/rejects a promise directly
- The handwriting-drawing-get-prediction algorithm has a parallel step that resolves/rejects a promise directly
- [HTML Standard](https://html.spec.whatwg.org/multipage/)
- The [HTMLImageElement/decode()](https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-decode) algorithm has a parallel step that resolves/rejects a promise directly
- The [WindowOrWorkerGlobalScope/createImageBitmap(image, options)](https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap) algorithm has a parallel step that resolves/rejects a promise directly
- [Idle Detection API](https://wicg.github.io/idle-detection/)
- The [IdleDetector/requestPermission()](https://wicg.github.io/idle-detection/#dom-idledetector-requestpermission) algorithm has a parallel step that resolves/rejects a promise directly
- [Indexed Database API 3.0](https://w3c.github.io/IndexedDB/)
- The [IDBFactory/databases()](https://w3c.github.io/IndexedDB/#dom-idbfactory-databases) algorithm has a parallel step that resolves/rejects a promise directly
- [JS Self-Profiling API](https://wicg.github.io/js-self-profiling/)
- The algorithm that starts with "Stops the profiler and returns a trace. This method MUST run these steps:" has a parallel step that resolves/rejects a promise directly
- [Keyboard Map](https://wicg.github.io/keyboard-map/)
- The [keyboard-getlayoutmap](https://wicg.github.io/keyboard-map/#keyboard-getlayoutmap) algorithm has a parallel step that resolves/rejects a promise directly
- [Local Font Access API](https://wicg.github.io/local-font-access/)
- The [Window/queryLocalFonts(options)](https://wicg.github.io/local-font-access/#dom-window-querylocalfonts) algorithm has a parallel step that resolves/rejects a promise directly
- The [FontData/blob()](https://wicg.github.io/local-font-access/#dom-fontdata-blob) algorithm has a parallel step that resolves/rejects a promise directly
- [Managed Configuration API](https://wicg.github.io/WebApiDevice/managed_config/)
- The [NavigatorManagedData/getManagedConfiguration(keys)](https://wicg.github.io/WebApiDevice/managed_config/#dom-navigatormanageddata-getmanagedconfiguration) algorithm has a parallel step that resolves/rejects a promise directly
- [Media Capabilities](https://w3c.github.io/media-capabilities/)
- The algorithm that starts with "The decodingInfo() method method MUST run the following steps:" has a parallel step that resolves/rejects a promise directly
- The algorithm that starts with "The encodingInfo() method MUST run the following steps:" has a parallel step that resolves/rejects a promise directly
- [Media Capture and Streams](https://w3c.github.io/mediacapture-main/)
- The [MediaDevices/enumerateDevices()](https://w3c.github.io/mediacapture-main/#dom-mediadevices-enumeratedevices) algorithm has a parallel step that resolves/rejects a promise directly
- The [MediaDevices/getUserMedia()](https://w3c.github.io/mediacapture-main/#dom-mediadevices-getusermedia) algorithm has a parallel step that resolves/rejects a promise directly
- [Media Session](https://w3c.github.io/mediasession/)
- The [update capture state algorithm](https://w3c.github.io/mediasession/#update-capture-state-algorithm) algorithm has a parallel step that resolves/rejects a promise directly
- [MediaStream Image Capture](https://w3c.github.io/mediacapture-image/)
- The [ImageCapture/takePhoto(photoSettings)](https://w3c.github.io/mediacapture-image/#dom-imagecapture-takephoto) algorithm has a parallel step that resolves/rejects a promise directly
- The [ImageCapture/getPhotoCapabilities()](https://w3c.github.io/mediacapture-image/#dom-imagecapture-getphotocapabilities) algorithm has a parallel step that resolves/rejects a promise directly
- The [ImageCapture/getPhotoSettings()](https://w3c.github.io/mediacapture-image/#dom-imagecapture-getphotosettings) algorithm has a parallel step that resolves/rejects a promise directly
- The [ImageCapture/grabFrame()](https://w3c.github.io/mediacapture-image/#dom-imagecapture-grabframe) algorithm has a parallel step that resolves/rejects a promise directly
- [Payment Handler API](https://w3c.github.io/payment-handler/)
- The algorithm that starts with "Upon receiving a PaymentRequest by way of PaymentRequest.show() and subsequent user selection of a payment handler, the user agent MUST run the following steps:" has a parallel step that resolves/rejects a promise directly
- An algorithm has a parallel step that resolves/rejects a promise directly
- [Payment Request API](https://w3c.github.io/payment-request/)
- The algorithm that starts with "The show(optional detailsPromise) method MUST act as follows:" has a parallel step that resolves/rejects a promise directly
- The algorithm that starts with "The complete() method MUST act as follows:" has a parallel step that resolves/rejects a promise directly
- The [can make payment algorithm](https://w3c.github.io/payment-request/#dfn-can-make-payment-algorithm) algorithm has a parallel step that resolves/rejects a promise directly
- [Picture-in-Picture](https://w3c.github.io/picture-in-picture/)
- The algorithm that starts with "The requestPictureInPicture() method, when invoked, MUST return a new promise promise and run the following steps in parallel:" has a parallel step that resolves/rejects a promise directly
- The algorithm that starts with "The exitPictureInPicture() method, when invoked, MUST return a new promise promise and run the following steps in parallel:" has a parallel step that resolves/rejects a promise directly
- [Presentation API](https://w3c.github.io/presentation-api/)
- The [PresentationRequest/start()](https://w3c.github.io/presentation-api/#dom-presentationrequest-start) algorithm has a parallel step that resolves/rejects a promise directly
- The [PresentationRequest/reconnect()](https://w3c.github.io/presentation-api/#dom-presentationrequest-reconnect) algorithm has a parallel step that resolves/rejects a promise directly
- The [PresentationRequest/getAvailability()](https://w3c.github.io/presentation-api/#dom-presentationrequest-getavailability) algorithm has a parallel step that resolves/rejects a promise directly
- The [monitoring incoming presentation connections](https://w3c.github.io/presentation-api/#dfn-monitoring-incoming-presentation-connections) algorithm has a parallel step that resolves/rejects a promise directly
- [Region Capture](https://w3c.github.io/mediacapture-region/)
- The [BrowserCaptureMediaStreamTrack/cropTo()](https://w3c.github.io/mediacapture-region/#dom-browsercapturemediastreamtrack-cropto) algorithm has a parallel step that resolves/rejects a promise directly
- [Remote Playback API](https://w3c.github.io/remote-playback/)
- The [RemotePlayback/prompt()](https://w3c.github.io/remote-playback/#dom-remoteplayback-prompt) algorithm has a parallel step that resolves/rejects a promise directly
- [Screen Capture](https://w3c.github.io/mediacapture-screen-share/)
- The [MediaDevices/getDisplayMedia()](https://w3c.github.io/mediacapture-screen-share/#dom-mediadevices-getdisplaymedia) algorithm has a parallel step that resolves/rejects a promise directly
- [Screen Orientation](https://w3c.github.io/screen-orientation/)
- The [apply orientation lock](https://w3c.github.io/screen-orientation/#dfn-apply-orientation-lock) algorithm has a parallel step that resolves/rejects a promise directly
- [Service Workers Nightly](https://w3c.github.io/ServiceWorker/)
- The [navigator-service-worker-getRegistration](https://w3c.github.io/ServiceWorker/#dom-serviceworkercontainer-getregistration) algorithm has a parallel step that resolves/rejects a promise directly
- The [navigation-preload-manager-enable](https://w3c.github.io/ServiceWorker/#dom-navigationpreloadmanager-enable) algorithm has a parallel step that resolves/rejects a promise directly
- The [navigation-preload-manager-disable](https://w3c.github.io/ServiceWorker/#dom-navigationpreloadmanager-disable) algorithm has a parallel step that resolves/rejects a promise directly
- The [navigation-preload-manager-setheadervalue](https://w3c.github.io/ServiceWorker/#dom-navigationpreloadmanager-setheadervalue) algorithm has a parallel step that resolves/rejects a promise directly
- The [navigation-preload-manager-getstate](https://w3c.github.io/ServiceWorker/#dom-navigationpreloadmanager-getstate) algorithm has a parallel step that resolves/rejects a promise directly
- The [service-worker-global-scope-skipwaiting](https://w3c.github.io/ServiceWorker/#dom-serviceworkerglobalscope-skipwaiting) algorithm has a parallel step that resolves/rejects a promise directly
- The [client-postmessage-options](https://w3c.github.io/ServiceWorker/#dom-client-postmessage-message-options) algorithm has a parallel step that fires an event directly
- The [clients-get](https://w3c.github.io/ServiceWorker/#dom-clients-get) algorithm has a parallel step that resolves/rejects a promise directly
- The [clients-claim](https://w3c.github.io/ServiceWorker/#dom-clients-claim) algorithm has a parallel step that resolves/rejects a promise directly
- The [cache-match](https://w3c.github.io/ServiceWorker/#dom-cache-match) algorithm has a parallel step that resolves/rejects a promise directly
- The [cache-matchall](https://w3c.github.io/ServiceWorker/#dom-cache-matchall) algorithm has a parallel step that resolves/rejects a promise directly
- The [cache-storage-match](https://w3c.github.io/ServiceWorker/#dom-cachestorage-match) algorithm has a parallel step that resolves/rejects a promise directly
- The [cache-storage-has](https://w3c.github.io/ServiceWorker/#dom-cachestorage-has) algorithm has a parallel step that resolves/rejects a promise directly
- The [cache-storage-open](https://w3c.github.io/ServiceWorker/#dom-cachestorage-open) algorithm has a parallel step that resolves/rejects a promise directly
- The [cache-storage-delete](https://w3c.github.io/ServiceWorker/#dom-cachestorage-delete) algorithm has a parallel step that resolves/rejects a promise directly
- The [cache-storage-keys](https://w3c.github.io/ServiceWorker/#dom-cachestorage-keys) algorithm has a parallel step that resolves/rejects a promise directly
- The [Handle Fetch](https://w3c.github.io/ServiceWorker/#handle-fetch) algorithm has a parallel step that resolves/rejects a promise directly
- [Test Utils Standard](https://testutils.spec.whatwg.org/)
- The algorithm that starts with "The gc() method must run these steps:" has a parallel step that resolves/rejects a promise directly
- [The Capture-Handle Actions Mechanism](https://w3c.github.io/mediacapture-handle/actions/)
- The [MediaStreamTrack/sendCaptureAction()](https://w3c.github.io/mediacapture-handle/actions/#dom-mediastreamtrack-sendcaptureaction) algorithm has a parallel step that resolves/rejects a promise directly
- [Viewport Capture](https://w3c.github.io/mediacapture-viewport/)
- The [MediaDevices/getViewportMedia()](https://w3c.github.io/mediacapture-viewport/#dom-mediadevices-getviewportmedia) algorithm has a parallel step that resolves/rejects a promise directly
- [VirtualKeyboard API](https://w3c.github.io/virtual-keyboard/)
- The [VirtualKeyboard/show()](https://w3c.github.io/virtual-keyboard/#dom-virtualkeyboard-show) algorithm has a parallel step that fires an event directly
- The [VirtualKeyboard/hide()](https://w3c.github.io/virtual-keyboard/#dom-virtualkeyboard-hide) algorithm has a parallel step that fires an event directly
- [Web Background Synchronization](https://wicg.github.io/background-sync/spec/)
- The [SyncManager/register(tag)](https://wicg.github.io/background-sync/spec/#dom-syncmanager-register) algorithm has a parallel step that resolves/rejects a promise directly
- The [SyncManager/getTags()](https://wicg.github.io/background-sync/spec/#dom-syncmanager-gettags) algorithm has a parallel step that resolves/rejects a promise directly
- The [fire a sync event](https://wicg.github.io/background-sync/spec/#fire-a-sync-event) algorithm has a parallel step that fires an event directly
- [Web Bluetooth](https://webbluetoothcg.github.io/web-bluetooth/)
- The [getDevice invocation](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getdevices) algorithm has a parallel step that resolves/rejects a promise directly
- The [requestDevice invocation](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice) algorithm has a parallel step that resolves/rejects a promise directly
- The [query Bluetooth cache](https://webbluetoothcg.github.io/web-bluetooth/#query-the-bluetooth-cache) algorithm has a parallel step that resolves/rejects a promise directly
- The [BluetoothRemoteGATTServer connect](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect) algorithm has a parallel step that resolves/rejects a promise directly
- The [BluetoothRemoteGATTService construction](https://webbluetoothcg.github.io/web-bluetooth/#create-a-bluetoothremotegattservice-representing) algorithm has a parallel step that resolves/rejects a promise directly
- The [BluetoothRemoteGATTCharacteristic constructor](https://webbluetoothcg.github.io/web-bluetooth/#create-a-bluetoothremotegattcharacteristic-representing) algorithm has a parallel step that resolves/rejects a promise directly
- The [BluetoothRemoteGATTCharacteristic readValue()](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue) algorithm has a parallel step that resolves/rejects a promise directly
- The [Write Characteristic value](https://webbluetoothcg.github.io/web-bluetooth/#writecharacteristicvalue) algorithm has a parallel step that resolves/rejects a promise directly
- The [BluetoothRemoteGATTCharacteristic startNotifications](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications) algorithm has a parallel step that resolves/rejects a promise directly
- The [BluetoothCharacteristicProperties constructor](https://webbluetoothcg.github.io/web-bluetooth/#create-a-bluetoothcharacteristicproperties-instance-from-the-characteristic) algorithm has a parallel step that resolves/rejects a promise directly
- The [BluetoothRemoteGATTDescriptor constructor](https://webbluetoothcg.github.io/web-bluetooth/#create-a-bluetoothremotegattdescriptor-representing) algorithm has a parallel step that resolves/rejects a promise directly
- The [BluetoothRemoteGATTDescriptor readValue](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue) algorithm has a parallel step that resolves/rejects a promise directly
- The [BluetoothRemoteGATTDescriptor writeValue](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue) algorithm has a parallel step that resolves/rejects a promise directly
- [Web Bluetooth Scanning](https://webbluetoothcg.github.io/web-bluetooth/scanning.html)
- The [Bluetooth/requestLEScan(options)](https://webbluetoothcg.github.io/web-bluetooth/scanning.html#dom-bluetooth-requestlescan) algorithm has a parallel step that resolves/rejects a promise directly
- [Web Cryptography API](https://w3c.github.io/webcrypto/)
- The [SubtleCrypto/encrypt()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-encrypt) algorithm has a parallel step that resolves/rejects a promise directly
- The [SubtleCrypto/sign()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-sign) algorithm has a parallel step that resolves/rejects a promise directly
- The [SubtleCrypto/digest()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-digest) algorithm has a parallel step that resolves/rejects a promise directly
- The [SubtleCrypto/generateKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-generateKey) algorithm has a parallel step that resolves/rejects a promise directly
- The [SubtleCrypto/deriveKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-deriveKey) algorithm has a parallel step that resolves/rejects a promise directly
- The [SubtleCrypto/deriveBits()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-deriveBits) algorithm has a parallel step that resolves/rejects a promise directly
- The [SubtleCrypto/importKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-importKey) algorithm has a parallel step that resolves/rejects a promise directly
- The [SubtleCrypto/exportKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-exportKey) algorithm has a parallel step that resolves/rejects a promise directly
- The [SubtleCrypto/wrapKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-wrapKey) algorithm has a parallel step that resolves/rejects a promise directly
- The [SubtleCrypto/unwrapKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-unwrapKey) algorithm has a parallel step that resolves/rejects a promise directly
- [Web NFC](https://w3c.github.io/web-nfc/)
- The [NDEFReader/write()](https://w3c.github.io/web-nfc/#dom-ndefreader-write) algorithm has a parallel step that resolves/rejects a promise directly
- The [NDEFReader/makeReadOnly()](https://w3c.github.io/web-nfc/#dom-ndefreader-makereadonly) algorithm has a parallel step that resolves/rejects a promise directly
- The [clean up the pending scan](https://w3c.github.io/web-nfc/#dfn-clean-up-the-pending-scan) algorithm has a parallel step that resolves/rejects a promise directly
- [Web Periodic Background Synchronization](https://wicg.github.io/periodic-background-sync/)
- The [Process periodic sync registrations](https://wicg.github.io/periodic-background-sync/#process-periodic-sync-registrations) algorithm has a parallel step that fires an event directly
- [WebCodecs](https://w3c.github.io/webcodecs/)
- The [ImageDecoder/isTypeSupported(type)](https://w3c.github.io/webcodecs/#dom-imagedecoder-istypesupported) algorithm has a parallel step that resolves/rejects a promise directly
- [WebDriver](https://w3c.github.io/webdriver/)
- The algorithm that starts with "The remote end steps, given session, URL variables and parameters are:" has a parallel step that resolves/rejects a promise directly
- The algorithm that starts with "The remote end steps, given session, URL variables and parameters are:" has a parallel step that resolves/rejects a promise directly
- [WebHID API](https://wicg.github.io/webhid/)
- The algorithm that starts with "The forget() method steps are:" has a parallel step that resolves/rejects a promise directly
- [WebRTC Encoded Transform](https://w3c.github.io/webrtc-encoded-transform/)
- The algorithm that starts with "The SFrame transform algorithm, given sframe as a SFrameTransform object and frame, runs these steps:" has a parallel step that resolves/rejects a promise directly
- The [generate key frame algorithm](https://w3c.github.io/webrtc-encoded-transform/#abstract-opdef-generate-key-frame-algorithm) algorithm has a parallel step that resolves/rejects a promise directly
- The [send request key frame algorithm](https://w3c.github.io/webrtc-encoded-transform/#abstract-opdef-send-request-key-frame-algorithm) algorithm has a parallel step that resolves/rejects a promise directly
- [WebRTC: Real-Time Communication in Browsers](https://w3c.github.io/webrtc-pc/)
- The [RTCPeerConnection/generateCertificate()](https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-generatecertificate) algorithm has a parallel step that resolves/rejects a promise directly
- The [RTCRtpSender/replaceTrack()](https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-replacetrack) algorithm has a parallel step that resolves/rejects a promise directly
- The [RTCRtpSender/getStats()](https://w3c.github.io/webrtc-pc/#widl-RTCRtpSender-getStats-Promise-RTCStatsReport) algorithm has a parallel step that resolves/rejects a promise directly
- The [RTCRtpReceiver/getStats()](https://w3c.github.io/webrtc-pc/#widl-RTCRtpReceiver-getStats-Promise-RTCStatsReport) algorithm has a parallel step that resolves/rejects a promise directly
- The [RTCPeerConnection/getStats()](https://w3c.github.io/webrtc-pc/#widl-RTCPeerConnection-getStats-Promise-RTCStatsReport--MediaStreamTrack-selector) algorithm has a parallel step that resolves/rejects a promise directly
- [WebTransport](https://w3c.github.io/webtransport/)
- The [WebTransport/getStats()](https://w3c.github.io/webtransport/#dom-webtransport-getstats) algorithm has a parallel step that resolves/rejects a promise directly
- The [WebTransport/createBidirectionalStream(options)](https://w3c.github.io/webtransport/#dom-webtransport-createbidirectionalstream) algorithm has a parallel step that resolves/rejects a promise directly
- The [WebTransport/createUnidirectionalStream(options)](https://w3c.github.io/webtransport/#dom-webtransport-createunidirectionalstream) algorithm has a parallel step that resolves/rejects a promise directly
- [WebUSB API](https://wicg.github.io/webusb/)
- The algorithm that starts with "The getDevices() method, when invoked, MUST return a new Promise and run the following steps in parallel:" has a parallel step that resolves/rejects a promise directly
- The [request the "usb" permission](https://wicg.github.io/webusb/#request-the-usb-permission) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.open()](https://wicg.github.io/webusb/#dom-usbdevice-open) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.close()](https://wicg.github.io/webusb/#dom-usbdevice-close) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.forget()](https://wicg.github.io/webusb/#dom-usbdevice-forget) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.selectConfiguration(configurationValue)](https://wicg.github.io/webusb/#dom-usbdevice-selectconfiguration) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.claimInterface(interfaceNumber)](https://wicg.github.io/webusb/#dom-usbdevice-claiminterface) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.releaseInterface(interfaceNumber)](https://wicg.github.io/webusb/#dom-usbdevice-releaseinterface) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.selectAlternateInterface(interfaceNumber, alternateSetting)](https://wicg.github.io/webusb/#dom-usbdevice-selectalternateinterface) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.controlTransferIn(setup, length)](https://wicg.github.io/webusb/#dom-usbdevice-controltransferin) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.controlTransferOut(setup, data)](https://wicg.github.io/webusb/#dom-usbdevice-controltransferout) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.clearHalt(direction, endpointNumber)](https://wicg.github.io/webusb/#dom-usbdevice-clearhalt) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.transferIn(endpointNumber, length)](https://wicg.github.io/webusb/#dom-usbdevice-transferin) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.transferOut(endpointNumber, data)](https://wicg.github.io/webusb/#dom-usbdevice-transferout) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.isochronousTransferIn(endpointNumber, packetLengths)](https://wicg.github.io/webusb/#dom-usbdevice-isochronoustransferin) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.isochronousTransferOut(endpointNumber, data, packetLengths)](https://wicg.github.io/webusb/#dom-usbdevice-isochronoustransferout) algorithm has a parallel step that resolves/rejects a promise directly
- The [USBDevice.reset()](https://wicg.github.io/webusb/#dom-usbdevice-reset) algorithm has a parallel step that resolves/rejects a promise directly
- [WebXR Device API](https://immersive-web.github.io/webxr/)
- The [session-supported](https://immersive-web.github.io/webxr/#dom-xrsystem-issessionsupported) algorithm has a parallel step that resolves/rejects a promise directly
- The [request-reference-space](https://immersive-web.github.io/webxr/#dom-xrsession-requestreferencespace) algorithm has a parallel step that resolves/rejects a promise directly
To run the analysis and refresh the above results, retrieve Webref's latest crawl results data locally and run:
The parallel queue example in the Parallelism section in HTML seems wrong as well: steps 2.4 in both the "incorrect" and "correct" versions should also queue a task, the former because the step explicitly runs "in parallel" in step 2, the latter because steps enqueued to a parallel queue also run in parallel, I think.
(Edit: reported in https://github.com/whatwg/html/issues/10535)
We could start reporting these problems to spec authors on a semi-automated basis (after review) as we do for broken links. Now, as noted by @jyasskin in https://github.com/whatwg/html/issues/8569, "queue a task" means selecting a task source, which is also something that people get confused about (looking into it, I realize that I raised https://github.com/w3ctag/design-principles/issues/38 on this topic back in 2016), and often choose to ignore.
Given the number of specs that get it wrong, two questions that I'm wondering about:
Would it be better to consider less error prone ways to write such steps first?
Do these problems materialize in interoperability bugs? Should we rather keep that in the back burner if it does not have practical implications?
Further analyses
Additional analyses that could be done:
Look into task sources as well. Whether a task source is defined is a bit harder to evaluate automatically because various specs have a blanket "use the foo task source for all tasks in this specification" statement; but the name of the task source is usually wrapped in a <dfn>, which should be easy to detect.
Report terms in steps that should link to their formal definition (e.g., "in parallel", "queue a task") and that don't.
Look into phrasing conventions when defining an algorithm and calling an algorithm, to progressively converge on a similar pseudo-language for algorithms. See how to define an algorithm in Infra for the definition part.
Start tracking algorithm variables, inputs and outputs. That probably requires settling down on stricter conventions first.
Analyze the list of step operations. In the extraction logic, the list is used to assess that a list item is indeed part of an algorithm. It reveals the many verbs that specs use to tell implementers what needs to be done. Some have formal definitions. The meaning of others is more fuzzy. Ideally, the meaning of all operations would be normatively defined somewhere.
Any other interesting or important analyses that could be worth looking into?
How to write/flag algorithms
More broadly speaking, algorithms are currently written with semi-formal structures. There are opportunities to converge on a more formal structure if that seems useful. Examples:
Infra describes how to define an algorithm. Specs use other variants here and there, such as "When the foo() method is invoked, run the following steps...", or algorithms sections where the sub-heading's title is the name of the algorithm.
Specs and spec authoring tools follow different conventions with regards to flagging these algorithms, e.g., with a class="algorithm" attribute. This makes it harder to extract the relevant prose, algorithm name, and actual steps.
Algorithm steps may be more or less atomic. Sometimes, a single step performs multiple operations (e.g., if/then/else all in one sentence). Related discussions about "inlining" steps in HTML in https://github.com/whatwg/html/issues/10049
On top of us raising issues afterwards, spec authoring tools could perhaps better guide spec authors at the authoring step. Additional classes could also help make algorithms visually more readable, as attempted with flowchart symbols in the algorithms explorer.
In any case, convergence would make it easier to extract the algorithms and run further analyses.
Strudy was re-written to ease semi-automatic reporting of various types of anomalies.
This made it possible to file "missing "ueue a task" issues against specifications, which we've now started to do. That may take a bit of time but anomalies reported above should end up being reported.
Context: algorithms extraction
Reffy now extracts algorithms from specs, see algorithms extracts in Webref. Extraction is far from perfect (a number of limitations are noted as TODO comments in the extraction logic) but the results are still good enough to start analyzing potential problems in algorithms, see
study-algorithms.js
.Also see @dontcallmeDOM's initial algorithms explorer based on the extracts.
Analysis: parallel steps that should call "queue a task"
First thing I analyzed are steps that run in parallel because I always forget the need to queue a task within parallel steps before resolving/rejecting a
Promise
or firing an event. @jyasskin noted the same problem back in 2022 in https://github.com/whatwg/html/issues/8569. What's new here is that we can now compute that information automatically, giving us more weapons to play whack-a-mole.The results show that about 50% of the specs (56/113) that define algorithms with "in parallel" steps need fixing:
Specs with steps in parallel that miss a call to "queue a task" (56 specs)
- [Accelerated Shape Detection in Images](https://wicg.github.io/shape-detection-api/) - The [BarcodeDetector/getSupportedFormats()](https://wicg.github.io/shape-detection-api/#dom-barcodedetector-getsupportedformats) algorithm has a parallel step that resolves/rejects a promise directly - [Audio Output Devices API](https://w3c.github.io/mediacapture-output/) - The [HTMLMediaElement/setSinkId()](https://w3c.github.io/mediacapture-output/#dom-htmlmediaelement-setsinkid) algorithm has a parallel step that resolves/rejects a promise directly - The [MediaDevices/selectAudioOutput()](https://w3c.github.io/mediacapture-output/#dom-mediadevices-selectaudiooutput) algorithm has a parallel step that resolves/rejects a promise directly - [Background Fetch](https://wicg.github.io/background-fetch/) - The [create record objects](https://wicg.github.io/background-fetch/#create-record-objects) algorithm has a parallel step that resolves/rejects a promise directly - The [get(id)](https://wicg.github.io/background-fetch/#dom-backgroundfetchmanager-get) algorithm has a parallel step that resolves/rejects a promise directly - The [getIds()](https://wicg.github.io/background-fetch/#dom-backgroundfetchmanager-getids) algorithm has a parallel step that resolves/rejects a promise directly - The [abort()](https://wicg.github.io/background-fetch/#dom-backgroundfetchregistration-abort) algorithm has a parallel step that resolves/rejects a promise directly - The [updateUI(options)](https://wicg.github.io/background-fetch/#dom-backgroundfetchupdateuievent-updateui) algorithm has a parallel step that resolves/rejects a promise directly - [Contact Picker API](https://w3c.github.io/contact-picker/) - The [getProperties()](https://w3c.github.io/contact-picker/#dom-contactsmanager-getproperties) algorithm has a parallel step that resolves/rejects a promise directly - [Content Index](https://wicg.github.io/content-index/spec/) - The [add(description)](https://wicg.github.io/content-index/spec/#dom-contentindex-add) algorithm has a parallel step that resolves/rejects a promise directly - The [delete(id)](https://wicg.github.io/content-index/spec/#dom-contentindex-delete) algorithm has a parallel step that resolves/rejects a promise directly - The [getAll()](https://wicg.github.io/content-index/spec/#dom-contentindex-getall) algorithm has a parallel step that resolves/rejects a promise directly - [Cookie Store API](https://wicg.github.io/cookie-store/) - The [CookieStore/get(name)](https://wicg.github.io/cookie-store/#dom-cookiestore-get) algorithm has a parallel step that resolves/rejects a promise directly - The [CookieStore/get(options)](https://wicg.github.io/cookie-store/#dom-cookiestore-get-options) algorithm has a parallel step that resolves/rejects a promise directly - The [CookieStore/getAll(name)](https://wicg.github.io/cookie-store/#dom-cookiestore-getall) algorithm has a parallel step that resolves/rejects a promise directly - The [CookieStore/getAll(options)](https://wicg.github.io/cookie-store/#dom-cookiestore-getall-options) algorithm has a parallel step that resolves/rejects a promise directly - The [CookieStore/set(name, value)](https://wicg.github.io/cookie-store/#dom-cookiestore-set) algorithm has a parallel step that resolves/rejects a promise directly - The [CookieStore/set(options)](https://wicg.github.io/cookie-store/#dom-cookiestore-set-options) algorithm has a parallel step that resolves/rejects a promise directly - The [CookieStore/delete(name)](https://wicg.github.io/cookie-store/#dom-cookiestore-delete) algorithm has a parallel step that resolves/rejects a promise directly - The [CookieStore/delete(options)](https://wicg.github.io/cookie-store/#dom-cookiestore-delete-options) algorithm has a parallel step that resolves/rejects a promise directly - The [CookieStoreManager/subscribe(subscriptions)](https://wicg.github.io/cookie-store/#dom-cookiestoremanager-subscribe) algorithm has a parallel step that resolves/rejects a promise directly - The [CookieStoreManager/getSubscriptions()](https://wicg.github.io/cookie-store/#dom-cookiestoremanager-getsubscriptions) algorithm has a parallel step that resolves/rejects a promise directly - The [CookieStoreManager/unsubscribe(subscriptions)](https://wicg.github.io/cookie-store/#dom-cookiestoremanager-unsubscribe) algorithm has a parallel step that resolves/rejects a promise directly - [Credential Management Level 1](https://w3c.github.io/webappsec-credential-management/) - The [Request a Credential](https://w3c.github.io/webappsec-credential-management/#abstract-opdef-request-a-credential) algorithm has a parallel step that resolves/rejects a promise directly - The [Create a Credential](https://w3c.github.io/webappsec-credential-management/#abstract-opdef-create-a-credential) algorithm has a parallel step that resolves/rejects a promise directly - The [Prevent Silent Access](https://w3c.github.io/webappsec-credential-management/#abstract-opdef-prevent-silent-access) algorithm has a parallel step that resolves/rejects a promise directly - [CSS Object Model (CSSOM)](https://drafts.csswg.org/cssom-1/) - The [CSSStyleSheet/replace(text)](https://drafts.csswg.org/cssom-1/#dom-cssstylesheet-replace) algorithm has a parallel step that resolves/rejects a promise directly - [Element Capture](https://screen-share.github.io/element-capture/) - The [BrowserCaptureMediaStreamTrack/restrictTo()](https://screen-share.github.io/element-capture/#dom-browsercapturemediastreamtrack-restrictto) algorithm has a parallel step that resolves/rejects a promise directly - [Encrypted Media Extensions](https://w3c.github.io/encrypted-media/) - The [Navigator/requestMediaKeySystemAccess()](https://w3c.github.io/encrypted-media/#dom-navigator-requestmediakeysystemaccess) algorithm has a parallel step that resolves/rejects a promise directly - The [MediaKeySystemAccess/createMediaKeys()](https://w3c.github.io/encrypted-media/#dom-mediakeysystemaccess-createmediakeys) algorithm has a parallel step that resolves/rejects a promise directly - The [MediaKeys/setServerCertificate()](https://w3c.github.io/encrypted-media/#dom-mediakeys-setservercertificate) algorithm has a parallel step that resolves/rejects a promise directly - The [MediaKeySession/generateRequest()](https://w3c.github.io/encrypted-media/#dom-mediakeysession-generaterequest) algorithm has a parallel step that resolves/rejects a promise directly - The [MediaKeySession/load()](https://w3c.github.io/encrypted-media/#dom-mediakeysession-load) algorithm has a parallel step that resolves/rejects a promise directly - The [MediaKeySession/update()](https://w3c.github.io/encrypted-media/#dom-mediakeysession-update) algorithm has a parallel step that resolves/rejects a promise directly - The [HTMLMediaElement/setMediaKeys()](https://w3c.github.io/encrypted-media/#dom-htmlmediaelement-setmediakeys) algorithm has a parallel step that resolves/rejects a promise directly - [EyeDropper API](https://wicg.github.io/eyedropper-api/) - The [EyeDropper/open()](https://wicg.github.io/eyedropper-api/#dom-eyedropper-open) algorithm has a parallel step that resolves/rejects a promise directly - [Federated Credential Management API](https://fedidcg.github.io/FedCM/) - The [attempt to disconnect](https://fedidcg.github.io/FedCM/#attempt-to-disconnect) algorithm has a parallel step that resolves/rejects a promise directly - The getUserInfo algorithm has a parallel step that resolves/rejects a promise directly - [File System Access](https://wicg.github.io/file-system-access/) - The [FileSystemHandle/queryPermission(descriptor)](https://wicg.github.io/file-system-access/#dom-filesystemhandle-querypermission) algorithm has a parallel step that resolves/rejects a promise directly - The [FileSystemHandle/requestPermission(descriptor)](https://wicg.github.io/file-system-access/#dom-filesystemhandle-requestpermission) algorithm has a parallel step that resolves/rejects a promise directly - The [Window/showOpenFilePicker(options)](https://wicg.github.io/file-system-access/#dom-window-showopenfilepicker) algorithm has a parallel step that resolves/rejects a promise directly - The [Window/showSaveFilePicker(options)](https://wicg.github.io/file-system-access/#dom-window-showsavefilepicker) algorithm has a parallel step that resolves/rejects a promise directly - The [Window/showDirectoryPicker(options)](https://wicg.github.io/file-system-access/#dom-window-showdirectorypicker) algorithm has a parallel step that resolves/rejects a promise directly - The [DataTransferItem/getAsFileSystemHandle()](https://wicg.github.io/file-system-access/#dom-datatransferitem-getasfilesystemhandle) algorithm has a parallel step that resolves/rejects a promise directly - [Fullscreen API Standard](https://fullscreen.spec.whatwg.org/) - The [requestFullscreen(options)](https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen) algorithm has a parallel step that resolves/rejects a promise directly - The [exit fullscreen](https://fullscreen.spec.whatwg.org/#exit-fullscreen) algorithm has a parallel step that resolves/rejects a promise directly - [Gamepad](https://w3c.github.io/gamepad/) - The [GamepadHapticActuator/reset()](https://w3c.github.io/gamepad/#dom-gamepadhapticactuator-reset) algorithm has a parallel step that resolves/rejects a promise directly - [Geolocation Sensor](https://w3c.github.io/geolocation-sensor/) - The read algorithm has a parallel step that resolves/rejects a promise directly - [Get Installed Related Apps API](https://wicg.github.io/get-installed-related-apps/spec/) - The [getInstalledRelatedApps()](https://wicg.github.io/get-installed-related-apps/spec/#dom-navigator-getinstalledrelatedapps) algorithm has a parallel step that resolves/rejects a promise directly - [Handwriting Recognition API](https://wicg.github.io/handwriting-recognition/) - The navigator-query-handwriting-recognizer algorithm has a parallel step that resolves/rejects a promise directly - The navigator-create-handwriting-recognizer algorithm has a parallel step that resolves/rejects a promise directly - The handwriting-drawing-get-prediction algorithm has a parallel step that resolves/rejects a promise directly - [HTML Standard](https://html.spec.whatwg.org/multipage/) - The [HTMLImageElement/decode()](https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-decode) algorithm has a parallel step that resolves/rejects a promise directly - The [WindowOrWorkerGlobalScope/createImageBitmap(image, options)](https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap) algorithm has a parallel step that resolves/rejects a promise directly - [Idle Detection API](https://wicg.github.io/idle-detection/) - The [IdleDetector/requestPermission()](https://wicg.github.io/idle-detection/#dom-idledetector-requestpermission) algorithm has a parallel step that resolves/rejects a promise directly - [Indexed Database API 3.0](https://w3c.github.io/IndexedDB/) - The [IDBFactory/databases()](https://w3c.github.io/IndexedDB/#dom-idbfactory-databases) algorithm has a parallel step that resolves/rejects a promise directly - [JS Self-Profiling API](https://wicg.github.io/js-self-profiling/) - The algorithm that starts with "Stops the profiler and returns a trace. This method MUST run these steps:" has a parallel step that resolves/rejects a promise directly - [Keyboard Map](https://wicg.github.io/keyboard-map/) - The [keyboard-getlayoutmap](https://wicg.github.io/keyboard-map/#keyboard-getlayoutmap) algorithm has a parallel step that resolves/rejects a promise directly - [Local Font Access API](https://wicg.github.io/local-font-access/) - The [Window/queryLocalFonts(options)](https://wicg.github.io/local-font-access/#dom-window-querylocalfonts) algorithm has a parallel step that resolves/rejects a promise directly - The [FontData/blob()](https://wicg.github.io/local-font-access/#dom-fontdata-blob) algorithm has a parallel step that resolves/rejects a promise directly - [Managed Configuration API](https://wicg.github.io/WebApiDevice/managed_config/) - The [NavigatorManagedData/getManagedConfiguration(keys)](https://wicg.github.io/WebApiDevice/managed_config/#dom-navigatormanageddata-getmanagedconfiguration) algorithm has a parallel step that resolves/rejects a promise directly - [Media Capabilities](https://w3c.github.io/media-capabilities/) - The algorithm that starts with "The decodingInfo() method method MUST run the following steps:" has a parallel step that resolves/rejects a promise directly - The algorithm that starts with "The encodingInfo() method MUST run the following steps:" has a parallel step that resolves/rejects a promise directly - [Media Capture and Streams](https://w3c.github.io/mediacapture-main/) - The [MediaDevices/enumerateDevices()](https://w3c.github.io/mediacapture-main/#dom-mediadevices-enumeratedevices) algorithm has a parallel step that resolves/rejects a promise directly - The [MediaDevices/getUserMedia()](https://w3c.github.io/mediacapture-main/#dom-mediadevices-getusermedia) algorithm has a parallel step that resolves/rejects a promise directly - [Media Session](https://w3c.github.io/mediasession/) - The [update capture state algorithm](https://w3c.github.io/mediasession/#update-capture-state-algorithm) algorithm has a parallel step that resolves/rejects a promise directly - [MediaStream Image Capture](https://w3c.github.io/mediacapture-image/) - The [ImageCapture/takePhoto(photoSettings)](https://w3c.github.io/mediacapture-image/#dom-imagecapture-takephoto) algorithm has a parallel step that resolves/rejects a promise directly - The [ImageCapture/getPhotoCapabilities()](https://w3c.github.io/mediacapture-image/#dom-imagecapture-getphotocapabilities) algorithm has a parallel step that resolves/rejects a promise directly - The [ImageCapture/getPhotoSettings()](https://w3c.github.io/mediacapture-image/#dom-imagecapture-getphotosettings) algorithm has a parallel step that resolves/rejects a promise directly - The [ImageCapture/grabFrame()](https://w3c.github.io/mediacapture-image/#dom-imagecapture-grabframe) algorithm has a parallel step that resolves/rejects a promise directly - [Payment Handler API](https://w3c.github.io/payment-handler/) - The algorithm that starts with "Upon receiving a PaymentRequest by way of PaymentRequest.show() and subsequent user selection of a payment handler, the user agent MUST run the following steps:" has a parallel step that resolves/rejects a promise directly - An algorithm has a parallel step that resolves/rejects a promise directly - [Payment Request API](https://w3c.github.io/payment-request/) - The algorithm that starts with "The show(optional detailsPromise) method MUST act as follows:" has a parallel step that resolves/rejects a promise directly - The algorithm that starts with "The complete() method MUST act as follows:" has a parallel step that resolves/rejects a promise directly - The [can make payment algorithm](https://w3c.github.io/payment-request/#dfn-can-make-payment-algorithm) algorithm has a parallel step that resolves/rejects a promise directly - [Picture-in-Picture](https://w3c.github.io/picture-in-picture/) - The algorithm that starts with "The requestPictureInPicture() method, when invoked, MUST return a new promise promise and run the following steps in parallel:" has a parallel step that resolves/rejects a promise directly - The algorithm that starts with "The exitPictureInPicture() method, when invoked, MUST return a new promise promise and run the following steps in parallel:" has a parallel step that resolves/rejects a promise directly - [Presentation API](https://w3c.github.io/presentation-api/) - The [PresentationRequest/start()](https://w3c.github.io/presentation-api/#dom-presentationrequest-start) algorithm has a parallel step that resolves/rejects a promise directly - The [PresentationRequest/reconnect()](https://w3c.github.io/presentation-api/#dom-presentationrequest-reconnect) algorithm has a parallel step that resolves/rejects a promise directly - The [PresentationRequest/getAvailability()](https://w3c.github.io/presentation-api/#dom-presentationrequest-getavailability) algorithm has a parallel step that resolves/rejects a promise directly - The [monitoring incoming presentation connections](https://w3c.github.io/presentation-api/#dfn-monitoring-incoming-presentation-connections) algorithm has a parallel step that resolves/rejects a promise directly - [Region Capture](https://w3c.github.io/mediacapture-region/) - The [BrowserCaptureMediaStreamTrack/cropTo()](https://w3c.github.io/mediacapture-region/#dom-browsercapturemediastreamtrack-cropto) algorithm has a parallel step that resolves/rejects a promise directly - [Remote Playback API](https://w3c.github.io/remote-playback/) - The [RemotePlayback/prompt()](https://w3c.github.io/remote-playback/#dom-remoteplayback-prompt) algorithm has a parallel step that resolves/rejects a promise directly - [Screen Capture](https://w3c.github.io/mediacapture-screen-share/) - The [MediaDevices/getDisplayMedia()](https://w3c.github.io/mediacapture-screen-share/#dom-mediadevices-getdisplaymedia) algorithm has a parallel step that resolves/rejects a promise directly - [Screen Orientation](https://w3c.github.io/screen-orientation/) - The [apply orientation lock](https://w3c.github.io/screen-orientation/#dfn-apply-orientation-lock) algorithm has a parallel step that resolves/rejects a promise directly - [Service Workers Nightly](https://w3c.github.io/ServiceWorker/) - The [navigator-service-worker-getRegistration](https://w3c.github.io/ServiceWorker/#dom-serviceworkercontainer-getregistration) algorithm has a parallel step that resolves/rejects a promise directly - The [navigation-preload-manager-enable](https://w3c.github.io/ServiceWorker/#dom-navigationpreloadmanager-enable) algorithm has a parallel step that resolves/rejects a promise directly - The [navigation-preload-manager-disable](https://w3c.github.io/ServiceWorker/#dom-navigationpreloadmanager-disable) algorithm has a parallel step that resolves/rejects a promise directly - The [navigation-preload-manager-setheadervalue](https://w3c.github.io/ServiceWorker/#dom-navigationpreloadmanager-setheadervalue) algorithm has a parallel step that resolves/rejects a promise directly - The [navigation-preload-manager-getstate](https://w3c.github.io/ServiceWorker/#dom-navigationpreloadmanager-getstate) algorithm has a parallel step that resolves/rejects a promise directly - The [service-worker-global-scope-skipwaiting](https://w3c.github.io/ServiceWorker/#dom-serviceworkerglobalscope-skipwaiting) algorithm has a parallel step that resolves/rejects a promise directly - The [client-postmessage-options](https://w3c.github.io/ServiceWorker/#dom-client-postmessage-message-options) algorithm has a parallel step that fires an event directly - The [clients-get](https://w3c.github.io/ServiceWorker/#dom-clients-get) algorithm has a parallel step that resolves/rejects a promise directly - The [clients-claim](https://w3c.github.io/ServiceWorker/#dom-clients-claim) algorithm has a parallel step that resolves/rejects a promise directly - The [cache-match](https://w3c.github.io/ServiceWorker/#dom-cache-match) algorithm has a parallel step that resolves/rejects a promise directly - The [cache-matchall](https://w3c.github.io/ServiceWorker/#dom-cache-matchall) algorithm has a parallel step that resolves/rejects a promise directly - The [cache-storage-match](https://w3c.github.io/ServiceWorker/#dom-cachestorage-match) algorithm has a parallel step that resolves/rejects a promise directly - The [cache-storage-has](https://w3c.github.io/ServiceWorker/#dom-cachestorage-has) algorithm has a parallel step that resolves/rejects a promise directly - The [cache-storage-open](https://w3c.github.io/ServiceWorker/#dom-cachestorage-open) algorithm has a parallel step that resolves/rejects a promise directly - The [cache-storage-delete](https://w3c.github.io/ServiceWorker/#dom-cachestorage-delete) algorithm has a parallel step that resolves/rejects a promise directly - The [cache-storage-keys](https://w3c.github.io/ServiceWorker/#dom-cachestorage-keys) algorithm has a parallel step that resolves/rejects a promise directly - The [Handle Fetch](https://w3c.github.io/ServiceWorker/#handle-fetch) algorithm has a parallel step that resolves/rejects a promise directly - [Test Utils Standard](https://testutils.spec.whatwg.org/) - The algorithm that starts with "The gc() method must run these steps:" has a parallel step that resolves/rejects a promise directly - [The Capture-Handle Actions Mechanism](https://w3c.github.io/mediacapture-handle/actions/) - The [MediaStreamTrack/sendCaptureAction()](https://w3c.github.io/mediacapture-handle/actions/#dom-mediastreamtrack-sendcaptureaction) algorithm has a parallel step that resolves/rejects a promise directly - [Viewport Capture](https://w3c.github.io/mediacapture-viewport/) - The [MediaDevices/getViewportMedia()](https://w3c.github.io/mediacapture-viewport/#dom-mediadevices-getviewportmedia) algorithm has a parallel step that resolves/rejects a promise directly - [VirtualKeyboard API](https://w3c.github.io/virtual-keyboard/) - The [VirtualKeyboard/show()](https://w3c.github.io/virtual-keyboard/#dom-virtualkeyboard-show) algorithm has a parallel step that fires an event directly - The [VirtualKeyboard/hide()](https://w3c.github.io/virtual-keyboard/#dom-virtualkeyboard-hide) algorithm has a parallel step that fires an event directly - [Web Background Synchronization](https://wicg.github.io/background-sync/spec/) - The [SyncManager/register(tag)](https://wicg.github.io/background-sync/spec/#dom-syncmanager-register) algorithm has a parallel step that resolves/rejects a promise directly - The [SyncManager/getTags()](https://wicg.github.io/background-sync/spec/#dom-syncmanager-gettags) algorithm has a parallel step that resolves/rejects a promise directly - The [fire a sync event](https://wicg.github.io/background-sync/spec/#fire-a-sync-event) algorithm has a parallel step that fires an event directly - [Web Bluetooth](https://webbluetoothcg.github.io/web-bluetooth/) - The [getDevice invocation](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getdevices) algorithm has a parallel step that resolves/rejects a promise directly - The [requestDevice invocation](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice) algorithm has a parallel step that resolves/rejects a promise directly - The [query Bluetooth cache](https://webbluetoothcg.github.io/web-bluetooth/#query-the-bluetooth-cache) algorithm has a parallel step that resolves/rejects a promise directly - The [BluetoothRemoteGATTServer connect](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect) algorithm has a parallel step that resolves/rejects a promise directly - The [BluetoothRemoteGATTService construction](https://webbluetoothcg.github.io/web-bluetooth/#create-a-bluetoothremotegattservice-representing) algorithm has a parallel step that resolves/rejects a promise directly - The [BluetoothRemoteGATTCharacteristic constructor](https://webbluetoothcg.github.io/web-bluetooth/#create-a-bluetoothremotegattcharacteristic-representing) algorithm has a parallel step that resolves/rejects a promise directly - The [BluetoothRemoteGATTCharacteristic readValue()](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue) algorithm has a parallel step that resolves/rejects a promise directly - The [Write Characteristic value](https://webbluetoothcg.github.io/web-bluetooth/#writecharacteristicvalue) algorithm has a parallel step that resolves/rejects a promise directly - The [BluetoothRemoteGATTCharacteristic startNotifications](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications) algorithm has a parallel step that resolves/rejects a promise directly - The [BluetoothCharacteristicProperties constructor](https://webbluetoothcg.github.io/web-bluetooth/#create-a-bluetoothcharacteristicproperties-instance-from-the-characteristic) algorithm has a parallel step that resolves/rejects a promise directly - The [BluetoothRemoteGATTDescriptor constructor](https://webbluetoothcg.github.io/web-bluetooth/#create-a-bluetoothremotegattdescriptor-representing) algorithm has a parallel step that resolves/rejects a promise directly - The [BluetoothRemoteGATTDescriptor readValue](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue) algorithm has a parallel step that resolves/rejects a promise directly - The [BluetoothRemoteGATTDescriptor writeValue](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue) algorithm has a parallel step that resolves/rejects a promise directly - [Web Bluetooth Scanning](https://webbluetoothcg.github.io/web-bluetooth/scanning.html) - The [Bluetooth/requestLEScan(options)](https://webbluetoothcg.github.io/web-bluetooth/scanning.html#dom-bluetooth-requestlescan) algorithm has a parallel step that resolves/rejects a promise directly - [Web Cryptography API](https://w3c.github.io/webcrypto/) - The [SubtleCrypto/encrypt()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-encrypt) algorithm has a parallel step that resolves/rejects a promise directly - The [SubtleCrypto/sign()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-sign) algorithm has a parallel step that resolves/rejects a promise directly - The [SubtleCrypto/digest()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-digest) algorithm has a parallel step that resolves/rejects a promise directly - The [SubtleCrypto/generateKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-generateKey) algorithm has a parallel step that resolves/rejects a promise directly - The [SubtleCrypto/deriveKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-deriveKey) algorithm has a parallel step that resolves/rejects a promise directly - The [SubtleCrypto/deriveBits()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-deriveBits) algorithm has a parallel step that resolves/rejects a promise directly - The [SubtleCrypto/importKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-importKey) algorithm has a parallel step that resolves/rejects a promise directly - The [SubtleCrypto/exportKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-exportKey) algorithm has a parallel step that resolves/rejects a promise directly - The [SubtleCrypto/wrapKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-wrapKey) algorithm has a parallel step that resolves/rejects a promise directly - The [SubtleCrypto/unwrapKey()](https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-unwrapKey) algorithm has a parallel step that resolves/rejects a promise directly - [Web NFC](https://w3c.github.io/web-nfc/) - The [NDEFReader/write()](https://w3c.github.io/web-nfc/#dom-ndefreader-write) algorithm has a parallel step that resolves/rejects a promise directly - The [NDEFReader/makeReadOnly()](https://w3c.github.io/web-nfc/#dom-ndefreader-makereadonly) algorithm has a parallel step that resolves/rejects a promise directly - The [clean up the pending scan](https://w3c.github.io/web-nfc/#dfn-clean-up-the-pending-scan) algorithm has a parallel step that resolves/rejects a promise directly - [Web Periodic Background Synchronization](https://wicg.github.io/periodic-background-sync/) - The [Process periodic sync registrations](https://wicg.github.io/periodic-background-sync/#process-periodic-sync-registrations) algorithm has a parallel step that fires an event directly - [WebCodecs](https://w3c.github.io/webcodecs/) - The [ImageDecoder/isTypeSupported(type)](https://w3c.github.io/webcodecs/#dom-imagedecoder-istypesupported) algorithm has a parallel step that resolves/rejects a promise directly - [WebDriver](https://w3c.github.io/webdriver/) - The algorithm that starts with "The remote end steps, given session, URL variables and parameters are:" has a parallel step that resolves/rejects a promise directly - The algorithm that starts with "The remote end steps, given session, URL variables and parameters are:" has a parallel step that resolves/rejects a promise directly - [WebHID API](https://wicg.github.io/webhid/) - The algorithm that starts with "The forget() method steps are:" has a parallel step that resolves/rejects a promise directly - [WebRTC Encoded Transform](https://w3c.github.io/webrtc-encoded-transform/) - The algorithm that starts with "The SFrame transform algorithm, given sframe as a SFrameTransform object and frame, runs these steps:" has a parallel step that resolves/rejects a promise directly - The [generate key frame algorithm](https://w3c.github.io/webrtc-encoded-transform/#abstract-opdef-generate-key-frame-algorithm) algorithm has a parallel step that resolves/rejects a promise directly - The [send request key frame algorithm](https://w3c.github.io/webrtc-encoded-transform/#abstract-opdef-send-request-key-frame-algorithm) algorithm has a parallel step that resolves/rejects a promise directly - [WebRTC: Real-Time Communication in Browsers](https://w3c.github.io/webrtc-pc/) - The [RTCPeerConnection/generateCertificate()](https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-generatecertificate) algorithm has a parallel step that resolves/rejects a promise directly - The [RTCRtpSender/replaceTrack()](https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-replacetrack) algorithm has a parallel step that resolves/rejects a promise directly - The [RTCRtpSender/getStats()](https://w3c.github.io/webrtc-pc/#widl-RTCRtpSender-getStats-Promise-RTCStatsReport) algorithm has a parallel step that resolves/rejects a promise directly - The [RTCRtpReceiver/getStats()](https://w3c.github.io/webrtc-pc/#widl-RTCRtpReceiver-getStats-Promise-RTCStatsReport) algorithm has a parallel step that resolves/rejects a promise directly - The [RTCPeerConnection/getStats()](https://w3c.github.io/webrtc-pc/#widl-RTCPeerConnection-getStats-Promise-RTCStatsReport--MediaStreamTrack-selector) algorithm has a parallel step that resolves/rejects a promise directly - [WebTransport](https://w3c.github.io/webtransport/) - The [WebTransport/getStats()](https://w3c.github.io/webtransport/#dom-webtransport-getstats) algorithm has a parallel step that resolves/rejects a promise directly - The [WebTransport/createBidirectionalStream(options)](https://w3c.github.io/webtransport/#dom-webtransport-createbidirectionalstream) algorithm has a parallel step that resolves/rejects a promise directly - The [WebTransport/createUnidirectionalStream(options)](https://w3c.github.io/webtransport/#dom-webtransport-createunidirectionalstream) algorithm has a parallel step that resolves/rejects a promise directly - [WebUSB API](https://wicg.github.io/webusb/) - The algorithm that starts with "The getDevices() method, when invoked, MUST return a new Promise and run the following steps in parallel:" has a parallel step that resolves/rejects a promise directly - The [request the "usb" permission](https://wicg.github.io/webusb/#request-the-usb-permission) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.open()](https://wicg.github.io/webusb/#dom-usbdevice-open) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.close()](https://wicg.github.io/webusb/#dom-usbdevice-close) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.forget()](https://wicg.github.io/webusb/#dom-usbdevice-forget) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.selectConfiguration(configurationValue)](https://wicg.github.io/webusb/#dom-usbdevice-selectconfiguration) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.claimInterface(interfaceNumber)](https://wicg.github.io/webusb/#dom-usbdevice-claiminterface) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.releaseInterface(interfaceNumber)](https://wicg.github.io/webusb/#dom-usbdevice-releaseinterface) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.selectAlternateInterface(interfaceNumber, alternateSetting)](https://wicg.github.io/webusb/#dom-usbdevice-selectalternateinterface) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.controlTransferIn(setup, length)](https://wicg.github.io/webusb/#dom-usbdevice-controltransferin) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.controlTransferOut(setup, data)](https://wicg.github.io/webusb/#dom-usbdevice-controltransferout) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.clearHalt(direction, endpointNumber)](https://wicg.github.io/webusb/#dom-usbdevice-clearhalt) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.transferIn(endpointNumber, length)](https://wicg.github.io/webusb/#dom-usbdevice-transferin) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.transferOut(endpointNumber, data)](https://wicg.github.io/webusb/#dom-usbdevice-transferout) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.isochronousTransferIn(endpointNumber, packetLengths)](https://wicg.github.io/webusb/#dom-usbdevice-isochronoustransferin) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.isochronousTransferOut(endpointNumber, data, packetLengths)](https://wicg.github.io/webusb/#dom-usbdevice-isochronoustransferout) algorithm has a parallel step that resolves/rejects a promise directly - The [USBDevice.reset()](https://wicg.github.io/webusb/#dom-usbdevice-reset) algorithm has a parallel step that resolves/rejects a promise directly - [WebXR Device API](https://immersive-web.github.io/webxr/) - The [session-supported](https://immersive-web.github.io/webxr/#dom-xrsystem-issessionsupported) algorithm has a parallel step that resolves/rejects a promise directly - The [request-reference-space](https://immersive-web.github.io/webxr/#dom-xrsession-requestreferencespace) algorithm has a parallel step that resolves/rejects a promise directlyTo run the analysis and refresh the above results, retrieve Webref's latest crawl results data locally and run:
On top of these problems (Edit: both examples have been fixed):
AbortController
andAbortSignal
objects in the DOM spec seems wrong: step 3.2 should queue a task to resolvep
with amazingResult (but note step 2.3.2 seems correct, because abort steps run within a global task) (Edit: reported in https://github.com/whatwg/dom/issues/1300)We could start reporting these problems to spec authors on a semi-automated basis (after review) as we do for broken links. Now, as noted by @jyasskin in https://github.com/whatwg/html/issues/8569, "queue a task" means selecting a task source, which is also something that people get confused about (looking into it, I realize that I raised https://github.com/w3ctag/design-principles/issues/38 on this topic back in 2016), and often choose to ignore.
Given the number of specs that get it wrong, two questions that I'm wondering about:
Further analyses
Additional analyses that could be done:
<dfn>
, which should be easy to detect.Any other interesting or important analyses that could be worth looking into?
How to write/flag algorithms
More broadly speaking, algorithms are currently written with semi-formal structures. There are opportunities to converge on a more formal structure if that seems useful. Examples:
foo()
method is invoked, run the following steps...", or algorithms sections where the sub-heading's title is the name of the algorithm.class="algorithm"
attribute. This makes it harder to extract the relevant prose, algorithm name, and actual steps.On top of us raising issues afterwards, spec authoring tools could perhaps better guide spec authors at the authoring step. Additional classes could also help make algorithms visually more readable, as attempted with flowchart symbols in the algorithms explorer.
In any case, convergence would make it easier to extract the algorithms and run further analyses.