├── .editorconfig ├── .github ├── linters │ └── .ecrc └── workflows │ ├── ci-lib.yml │ └── ci-super-linter.yml ├── .gitignore ├── LICENSE ├── README.md ├── idl ├── animation.webidl ├── clipboard.webidl ├── css.webidl ├── cssomview.webidl ├── dom.webidl ├── fetch.webidl ├── file.webidl ├── geometry.webidl ├── html.webidl ├── indexedDB.webidl ├── mediasource.webidl ├── mediastream.webidl ├── permissions.webidl ├── serviceworker.webidl ├── streams.webidl ├── svg.webidl ├── uievents.webidl ├── url.webidl ├── visibility.webidl ├── webgl.webidl ├── webidl.webidl └── xhr.webidl ├── pack.toml ├── spec ├── attributes ├── grammar └── webidl.html ├── src ├── Main.idr └── Text │ └── WebIDL │ ├── Codegen.idr │ └── Codegen │ ├── Args.idr │ ├── Definitions.idr │ ├── Enum.idr │ ├── Members.idr │ ├── Rules.idr │ ├── Types.idr │ └── Util.idr └── webidl.ipkg /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | # Defaults for every file 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | charset = utf-8 10 | 11 | # Idris source files 12 | [*.{idr,ipkg,tex,yaff,lidr}] 13 | indent_style = space 14 | indent_size = 2 15 | 16 | # Various configuration files 17 | [{*.yml,.ecrc}] 18 | indent_style = space 19 | indent_size = 2 20 | 21 | [*.py] 22 | indent_style = space 23 | indent_size = 4 24 | 25 | [*.{c,h}] 26 | indent_style = space 27 | indent_size = 4 28 | 29 | [*.{md,rst}] 30 | indent_style = space 31 | indent_size = 2 32 | 33 | [*.sh] 34 | indent_style = space 35 | indent_size = 4 36 | shell_variant = posix 37 | switch_case_indent = true 38 | 39 | [*.bat] 40 | indent_style = space 41 | indent_size = 4 42 | 43 | [{Makefile,*.mk}] 44 | indent_style = tab 45 | 46 | [*.nix] 47 | indent_style = space 48 | indent_size = 2 49 | 50 | [expected] 51 | trim_trailing_whitespace = false 52 | -------------------------------------------------------------------------------- /.github/linters/.ecrc: -------------------------------------------------------------------------------- 1 | { 2 | "Disable": { 3 | "IndentSize": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.github/workflows/ci-lib.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Build 3 | 4 | on: 5 | push: 6 | branches: 7 | - '**' 8 | tags: 9 | - '**' 10 | pull_request: 11 | branches: 12 | - main 13 | 14 | defaults: 15 | run: 16 | shell: bash 17 | 18 | jobs: 19 | 20 | build: 21 | name: Build the lib with pack latest 22 | runs-on: ubuntu-latest 23 | env: 24 | PACK_DIR: /root/.pack 25 | strategy: 26 | fail-fast: false 27 | container: ghcr.io/stefan-hoeck/idris2-pack:latest 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v2 31 | - name: Build lib 32 | run: pack typecheck webidl 33 | -------------------------------------------------------------------------------- /.github/workflows/ci-super-linter.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | tags: 8 | - '*' 9 | pull_request: 10 | branches: 11 | - main 12 | - master 13 | 14 | jobs: 15 | build: 16 | name: Lint Code Base 17 | runs-on: ubuntu-latest 18 | steps: 19 | 20 | - name: Checkout 21 | uses: actions/checkout@v2 22 | with: 23 | # Full git history is needed to get a proper list of changed files within `super-linter` 24 | fetch-depth: 0 25 | 26 | - name: Lint Code Base 27 | uses: github/super-linter/slim@v4 28 | env: 29 | VALIDATE_ALL_CODEBASE: false 30 | DEFAULT_BRANCH: main 31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 32 | IGNORE_GENERATED_FILES: true 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | generated/ 3 | *.*~ 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2021, Stefan Höck 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [ WIP ] idris2-webidl: A Generator for Idris2 Web Bindings 2 | 3 | Parsers and (eventually) Idris code generator for WebIDL documents 4 | 5 | ## Progress 6 | 7 | - [x] WebIDL parser 8 | - [x] Parse WebIDL toplevel specs into a syntax tree 9 | (types can be found in the `Text.WebIDL.Types` submodules). 10 | - [x] Encode syntax trees back to valid WebIDL 11 | - [x] Property test for parsers and encoders 12 | - [ ] Idris2 code generator 13 | - [ ] Foreign function implementations 14 | - [x] Attribute getters 15 | - [x] Attribute setters 16 | - [x] Regular function implementations 17 | - [x] Interface constructors 18 | - [x] Dictionary constructors 19 | - [x] Static functions 20 | - [x] Function to callback converters 21 | - [ ] Iterables 22 | - [ ] Namespace members 23 | - [x] Setters and Getters 24 | - [x] Stringifiers 25 | - [ ] Setlikes (no instance in spec) 26 | - [ ] Maplikes (no instance in spec) 27 | - [ ] API function implementations 28 | - [x] Attribute getters 29 | - [x] Attribute setters 30 | - [x] Optional attribute unsetters 31 | - [x] Optional attribute getters supporting a default return value 32 | - [x] Regular functions (no optional arguments or variadic argument) 33 | - [x] Functions with optional arguments 34 | (including a second version with the optional arguments 35 | missing) 36 | - [x] Functions with a variadic argument 37 | - [x] Function to callback converters 38 | - [x] Static functions 39 | - [ ] Iterables 40 | - [ ] Namespace members 41 | - [x] Setters and Getters 42 | - [x] Stringifiers 43 | - [ ] Setlikes (no instance in spec) 44 | - [ ] Maplikes (no instance in spec) 45 | - [x] Marshalling 46 | - [x] from enum types to `String` and back 47 | - [x] from `Maybe` to `Nullable` and back 48 | - [x] from `Union` to `NS I` (from `Data.SOP.NS`) and back 49 | - [x] from `UndefOr` to an appropriate Idris2 ADT 50 | - [x] from Idris2 functions to callback types 51 | 52 | ## Codegen Notes 53 | 54 | ### Transferring WebIDL types to Idris2 types 55 | 56 | WebIDL types can be found in module `Text.WebIDL.Types.Type`. 57 | Here is an summary about how these types are being mapped to 58 | Idris2 types by the code generator. Eventually, the list below 59 | will also give additional information about functionality 60 | required from these bindings, but in a first step 61 | 62 | * `Undefined`: This type actually has two Idris2 representations. 63 | As a function argument, it is mapped to an external 64 | `Undefined` Idris2 type. As an unwrapped return value, it 65 | is mapped to `()`. 66 | 67 | * Integral types: These are mapped to the following types 68 | * `octet` : `Bits8` 69 | * `byte` : `Int8` 70 | * `unsigned short` : `Bits16` 71 | * `short` : `Int16` 72 | * `unsigned long` : `Bits32` 73 | * `long` : `Int32` 74 | * `unsigned long long` : `UInt64` 75 | * `long long` : `UInt64` 76 | 77 | Up to 32-bit integers, these all implement the usual numeric 78 | interfaces (including `Data.Bits`). The 64-bit types are 79 | still lacking an API, as they are represented by `Number` 80 | in the backend and this doesn't support integer operations 81 | at this precision. Will have to do some reading on how these 82 | are handled elsewhere (for instance in PureScript). 83 | 84 | * Floating point types: These are mapped to `Double` for 85 | simplicity. Not yet sure whether it is worth to treat `float` 86 | and `unrestricted float` differently. 87 | 88 | * `bigint` : This is obviously mapped to `Integer`. 89 | 90 | * `boolean` : This gets its own external `Boolean` type with 91 | marshalling functions from and to Idris2 `Bool`. 92 | 93 | * String types: `DOMString` and `USVString` are ordinary Idris2 94 | strings, `ByteString` gets its own external type (API yet to be 95 | defined). 96 | 97 | * Buffer related types: These are mapped to external types 98 | of the same name. APIs are yet to be defined. 99 | 100 | * Nullable types: These get their own external type `Nullable` 101 | like in PureScript, with functionality to convert from 102 | and to `Maybe`. 103 | 104 | * `Any`: This is mapped to `AnyPtr`. 105 | 106 | * `Promise`: This is mapped to an external type of the same name. 107 | API yet to be defined (have a look at PureScript again). 108 | 109 | * `Object`: This is mapped to an external type of the same name. 110 | The API should at least provide an `IO` function for returning an 111 | empty object. 112 | 113 | * `Symbol`: This is mapped to an external type of the same name. 114 | API yet to be defined. 115 | 116 | * `Record`: Again, this gets its own parameterized external type. 117 | API yet to be defined. In Idris2, it should be possible to 118 | make sure that the key parameter can only be `String` 119 | or `ByteString`. 120 | 121 | * Union types : These are mapped to an external `Union` type 122 | parameterized by a list of types listing the choices. 123 | It should be straight forward to marshall from an n-ary sum 124 | (`Data.SOP.NS`) to a union type. Marshalling back requires some 125 | thinking, however. 126 | 127 | * Callbacks : These get their own external types. We should, however, 128 | provide a way to for each callback type marshall from a corresponding 129 | Idris2 function to the callback (as in PureScript, these should be 130 | `IO` actions, as they create new objects in the backend). I'm not 131 | sure whether it will be necessary to marshall from a callback 132 | back to an Idris2 function. 133 | 134 | * Enums: These are treated as `String` in FFI calls, but 135 | get their own Idris2 enum type with proper conversions 136 | from and to their `String` representation. 137 | 138 | * Interfaces : These git their own external types. Their API is generated 139 | by this code generator from the idl specs. 140 | API yet to be defined. 141 | 142 | * Dictionaries : These get their own external types. Their API is generated 143 | by this code generator from the idl specs. In addition, each dictionary 144 | should get one or two (if the dictionary has optional attributes) 145 | constructor. 146 | 147 | * Mixins : These just get their own external types without any 148 | constructor. 149 | 150 | * Constants : Right now, these are implemented as plain Idris2 151 | nullary functions. Eventually, I'd like define proper Idris2 types 152 | for these and define rules for the code generator, where to 153 | replace the primitive types by these Idris2 types. This is future work, 154 | however. 155 | 156 | ### Inheritance and Mixins 157 | 158 | WebIDL specifies inheritance relations for interfaces and dictionaries. 159 | The code generator generates implementations for a `JSType` interface, 160 | listing a type's parent types and included mixins. The API supports 161 | then safe upcasting from a type to one of its parent types or mixins. 162 | 163 | Downcasting is trickier, as it requires a way to inspect the 164 | type of a value at runtime. The web API should provide a `SafeCast` interface 165 | for types, which can be checked at runtime. This includes 166 | all Idris2 primitives, the external numeric types, `String`, `Object`, 167 | `Symbol`, `Undefine`, `Boolean`, and all interfaces and dictionary types, 168 | whose type can be inspected by traversing a value's prototype chain. 169 | -------------------------------------------------------------------------------- /idl/animation.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://www.w3.org/TR/web-animations-1/ 2 | 3 | [Exposed=Window] 4 | interface AnimationTimeline { 5 | readonly attribute double? currentTime; 6 | }; 7 | 8 | dictionary DocumentTimelineOptions { 9 | DOMHighResTimeStamp originTime = 0; 10 | }; 11 | 12 | [Exposed=Window, 13 | Constructor (optional DocumentTimelineOptions options)] 14 | interface DocumentTimeline : AnimationTimeline { 15 | }; 16 | 17 | [Exposed=Window, 18 | Constructor (optional AnimationEffect? effect = null, 19 | optional AnimationTimeline? timeline)] 20 | interface Animation : EventTarget { 21 | attribute DOMString id; 22 | attribute AnimationEffect? effect; 23 | attribute AnimationTimeline? timeline; 24 | attribute double? startTime; 25 | attribute double? currentTime; 26 | attribute double playbackRate; 27 | readonly attribute AnimationPlayState playState; 28 | readonly attribute boolean pending; 29 | readonly attribute Promise ready; 30 | readonly attribute Promise finished; 31 | attribute EventHandler onfinish; 32 | attribute EventHandler oncancel; 33 | void cancel (); 34 | void finish (); 35 | void play (); 36 | void pause (); 37 | void updatePlaybackRate (double playbackRate); 38 | void reverse (); 39 | }; 40 | 41 | enum AnimationPlayState { "idle", "running", "paused", "finished" }; 42 | 43 | [Exposed=Window] 44 | interface AnimationEffect { 45 | EffectTiming getTiming(); 46 | ComputedEffectTiming getComputedTiming(); 47 | void updateTiming(optional OptionalEffectTiming timing); 48 | }; 49 | 50 | dictionary EffectTiming { 51 | double delay = 0; 52 | double endDelay = 0; 53 | FillMode fill = "auto"; 54 | double iterationStart = 0.0; 55 | unrestricted double iterations = 1.0; 56 | (unrestricted double or DOMString) duration = "auto"; 57 | PlaybackDirection direction = "normal"; 58 | DOMString easing = "linear"; 59 | }; 60 | 61 | dictionary OptionalEffectTiming { 62 | double delay; 63 | double endDelay; 64 | FillMode fill; 65 | double iterationStart; 66 | unrestricted double iterations; 67 | (unrestricted double or DOMString) duration; 68 | PlaybackDirection direction; 69 | DOMString easing; 70 | }; 71 | 72 | enum FillMode { "none", "forwards", "backwards", "both", "auto" }; 73 | 74 | enum PlaybackDirection { "normal", "reverse", "alternate", "alternate-reverse" }; 75 | 76 | dictionary ComputedEffectTiming : EffectTiming { 77 | unrestricted double endTime; 78 | unrestricted double activeDuration; 79 | double? localTime; 80 | double? progress; 81 | unrestricted double? currentIteration; 82 | }; 83 | 84 | [Exposed=Window, 85 | Constructor ((Element or CSSPseudoElement)? target, 86 | object? keyframes, 87 | optional (unrestricted double or KeyframeEffectOptions) options), 88 | Constructor (KeyframeEffect source)] 89 | interface KeyframeEffect : AnimationEffect { 90 | attribute (Element or CSSPseudoElement)? target; 91 | attribute IterationCompositeOperation iterationComposite; 92 | attribute CompositeOperation composite; 93 | sequence getKeyframes (); 94 | void setKeyframes (object? keyframes); 95 | }; 96 | 97 | dictionary BaseComputedKeyframe { 98 | double? offset = null; 99 | double computedOffset; 100 | DOMString easing = "linear"; 101 | CompositeOperationOrAuto composite = "auto"; 102 | }; 103 | 104 | dictionary BasePropertyIndexedKeyframe { 105 | (double? or sequence) offset = []; 106 | (DOMString or sequence) easing = []; 107 | (CompositeOperationOrAuto or sequence) composite = []; 108 | }; 109 | 110 | dictionary BaseKeyframe { 111 | double? offset = null; 112 | DOMString easing = "linear"; 113 | CompositeOperationOrAuto composite = "auto"; 114 | }; 115 | 116 | dictionary KeyframeEffectOptions : EffectTiming { 117 | IterationCompositeOperation iterationComposite = "replace"; 118 | CompositeOperation composite = "replace"; 119 | }; 120 | 121 | enum IterationCompositeOperation {"replace", "accumulate"}; 122 | 123 | enum CompositeOperation {"replace", "add", "accumulate"}; 124 | 125 | enum CompositeOperationOrAuto {"replace", "add", "accumulate", "auto"}; 126 | 127 | interface mixin Animatable { 128 | Animation animate (object? keyframes, 129 | optional (unrestricted double or KeyframeAnimationOptions) options); 130 | sequence getAnimations (); 131 | }; 132 | dictionary KeyframeAnimationOptions : KeyframeEffectOptions { 133 | DOMString id = ""; 134 | }; 135 | 136 | partial interface Document { 137 | readonly attribute DocumentTimeline timeline; 138 | sequence getAnimations(); 139 | }; 140 | 141 | Element includes Animatable; 142 | 143 | CSSPseudoElement includes Animatable; 144 | 145 | [Exposed=Window, 146 | Constructor (DOMString type, optional AnimationPlaybackEventInit eventInitDict)] 147 | interface AnimationPlaybackEvent : Event { 148 | readonly attribute double? currentTime; 149 | readonly attribute double? timelineTime; 150 | }; 151 | dictionary AnimationPlaybackEventInit : EventInit { 152 | double? currentTime = null; 153 | double? timelineTime = null; 154 | }; 155 | -------------------------------------------------------------------------------- /idl/clipboard.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://w3c.github.io/clipboard-apis/ 2 | 3 | dictionary ClipboardEventInit : EventInit { 4 | DataTransfer? clipboardData = null; 5 | }; 6 | 7 | [Exposed=Window] 8 | interface ClipboardEvent : Event { 9 | constructor(DOMString type, optional ClipboardEventInit eventInitDict = {}); 10 | readonly attribute DataTransfer? clipboardData; 11 | }; 12 | 13 | partial interface Navigator { 14 | [SecureContext, SameObject] readonly attribute Clipboard clipboard; 15 | }; 16 | 17 | typedef sequence ClipboardItems; 18 | 19 | [SecureContext, Exposed=Window] interface Clipboard : EventTarget { 20 | Promise read(); 21 | Promise readText(); 22 | Promise write(ClipboardItems data); 23 | Promise writeText(DOMString data); 24 | }; 25 | 26 | typedef (DOMString or Blob) ClipboardItemDataType; 27 | typedef Promise ClipboardItemData; 28 | 29 | callback ClipboardItemDelayedCallback = ClipboardItemData (); 30 | 31 | [Exposed=Window] interface ClipboardItem { 32 | constructor(record items, 33 | optional ClipboardItemOptions options = {}); 34 | static ClipboardItem createDelayed( 35 | record items, 36 | optional ClipboardItemOptions options = {}); 37 | 38 | readonly attribute PresentationStyle presentationStyle; 39 | readonly attribute long long lastModified; 40 | readonly attribute boolean delayed; 41 | 42 | readonly attribute FrozenArray types; 43 | 44 | Promise getType(DOMString type); 45 | }; 46 | 47 | enum PresentationStyle { "unspecified", "inline", "attachment" }; 48 | 49 | dictionary ClipboardItemOptions { 50 | PresentationStyle presentationStyle = "unspecified"; 51 | }; 52 | 53 | dictionary ClipboardPermissionDescriptor : PermissionDescriptor { 54 | boolean allowWithoutGesture = false; 55 | }; 56 | -------------------------------------------------------------------------------- /idl/css.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://drafts.csswg.org/cssom/ 2 | // and https://www.w3.org/TR/css-pseudo-4/ 3 | // plus added a typedef for CSSOMString at the bottom 4 | 5 | [Exposed=Window] 6 | interface MediaList { 7 | stringifier attribute [LegacyNullToEmptyString] CSSOMString mediaText; 8 | readonly attribute unsigned long length; 9 | getter CSSOMString? item(unsigned long index); 10 | undefined appendMedium(CSSOMString medium); 11 | undefined deleteMedium(CSSOMString medium); 12 | }; 13 | 14 | [Exposed=Window] 15 | interface StyleSheet { 16 | readonly attribute CSSOMString type; 17 | readonly attribute USVString? href; 18 | readonly attribute (Element or ProcessingInstruction)? ownerNode; 19 | readonly attribute CSSStyleSheet? parentStyleSheet; 20 | readonly attribute DOMString? title; 21 | [SameObject, PutForwards=mediaText] readonly attribute MediaList media; 22 | attribute boolean disabled; 23 | }; 24 | 25 | [Exposed=Window] 26 | interface CSSStyleSheet : StyleSheet { 27 | readonly attribute CSSRule? ownerRule; 28 | [SameObject] readonly attribute CSSRuleList cssRules; 29 | unsigned long insertRule(CSSOMString rule, optional unsigned long index = 0); 30 | undefined deleteRule(unsigned long index); 31 | }; 32 | 33 | partial interface CSSStyleSheet { 34 | [SameObject] readonly attribute CSSRuleList rules; 35 | long addRule(optional DOMString selector = "undefined", optional DOMString style = "undefined", optional unsigned long index); 36 | undefined removeRule(optional unsigned long index = 0); 37 | }; 38 | 39 | [Exposed=Window] 40 | interface StyleSheetList { 41 | getter CSSStyleSheet? item(unsigned long index); 42 | readonly attribute unsigned long length; 43 | }; 44 | 45 | partial interface mixin DocumentOrShadowRoot { 46 | [SameObject] readonly attribute StyleSheetList styleSheets; 47 | }; 48 | 49 | interface mixin LinkStyle { 50 | readonly attribute CSSStyleSheet? sheet; 51 | }; 52 | 53 | ProcessingInstruction includes LinkStyle; 54 | [Exposed=Window] 55 | interface CSSRuleList { 56 | getter CSSRule? item(unsigned long index); 57 | readonly attribute unsigned long length; 58 | }; 59 | 60 | [Exposed=Window] 61 | interface CSSRule { 62 | attribute CSSOMString cssText; 63 | readonly attribute CSSRule? parentRule; 64 | readonly attribute CSSStyleSheet? parentStyleSheet; 65 | 66 | // the following attribute and constants are historical 67 | readonly attribute unsigned short type; 68 | const unsigned short STYLE_RULE = 1; 69 | const unsigned short CHARSET_RULE = 2; 70 | const unsigned short IMPORT_RULE = 3; 71 | const unsigned short MEDIA_RULE = 4; 72 | const unsigned short FONT_FACE_RULE = 5; 73 | const unsigned short PAGE_RULE = 6; 74 | const unsigned short MARGIN_RULE = 9; 75 | const unsigned short NAMESPACE_RULE = 10; 76 | }; 77 | 78 | [Exposed=Window] 79 | interface CSSStyleRule : CSSRule { 80 | attribute CSSOMString selectorText; 81 | [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; 82 | }; 83 | 84 | [Exposed=Window] 85 | interface CSSImportRule : CSSRule { 86 | readonly attribute USVString href; 87 | [SameObject, PutForwards=mediaText] readonly attribute MediaList media; 88 | [SameObject] readonly attribute CSSStyleSheet styleSheet; 89 | }; 90 | 91 | [Exposed=Window] 92 | interface CSSGroupingRule : CSSRule { 93 | [SameObject] readonly attribute CSSRuleList cssRules; 94 | unsigned long insertRule(CSSOMString rule, optional unsigned long index = 0); 95 | undefined deleteRule(unsigned long index); 96 | }; 97 | 98 | [Exposed=Window] 99 | interface CSSPageRule : CSSGroupingRule { 100 | attribute CSSOMString selectorText; 101 | [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; 102 | }; 103 | 104 | [Exposed=Window] 105 | interface CSSMarginRule : CSSRule { 106 | readonly attribute CSSOMString name; 107 | [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; 108 | }; 109 | 110 | [Exposed=Window] 111 | interface CSSNamespaceRule : CSSRule { 112 | readonly attribute CSSOMString namespaceURI; 113 | readonly attribute CSSOMString prefix; 114 | }; 115 | 116 | [Exposed=Window] 117 | interface CSSStyleDeclaration { 118 | [CEReactions] attribute CSSOMString cssText; 119 | readonly attribute unsigned long length; 120 | getter CSSOMString item(unsigned long index); 121 | CSSOMString getPropertyValue(CSSOMString property); 122 | CSSOMString getPropertyPriority(CSSOMString property); 123 | [CEReactions] undefined setProperty(CSSOMString property, [LegacyNullToEmptyString] CSSOMString value, optional [LegacyNullToEmptyString] CSSOMString priority = ""); 124 | [CEReactions] CSSOMString removeProperty(CSSOMString property); 125 | readonly attribute CSSRule? parentRule; 126 | [CEReactions] attribute [LegacyNullToEmptyString] CSSOMString cssFloat; 127 | }; 128 | 129 | interface mixin ElementCSSInlineStyle { 130 | [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; 131 | }; 132 | 133 | HTMLElement includes ElementCSSInlineStyle; 134 | 135 | SVGElement includes ElementCSSInlineStyle; 136 | 137 | MathMLElement includes ElementCSSInlineStyle; 138 | 139 | partial interface Window { 140 | [NewObject] CSSStyleDeclaration getComputedStyle(Element elt, optional CSSOMString? pseudoElt); 141 | }; 142 | 143 | [Exposed=Window] 144 | namespace CSS { 145 | CSSOMString escape(CSSOMString ident); 146 | }; 147 | 148 | [Exposed=Window] 149 | interface CSSPseudoElement : EventTarget { 150 | readonly attribute CSSOMString type; 151 | readonly attribute Element element; 152 | }; 153 | 154 | partial interface Element { 155 | CSSPseudoElement? pseudo(CSSOMString type); 156 | }; 157 | 158 | // Added to get rid of CSSOMString 159 | typedef DOMString CSSOMString; 160 | -------------------------------------------------------------------------------- /idl/cssomview.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://w3c.github.io/csswg-drafts/cssom-view/ 2 | 3 | enum ScrollBehavior { "auto", "instant", "smooth"}; 4 | 5 | dictionary ScrollOptions { 6 | ScrollBehavior behavior = "auto"; 7 | }; 8 | 9 | dictionary ScrollToOptions : ScrollOptions { 10 | unrestricted double left; 11 | unrestricted double top; 12 | }; 13 | 14 | partial interface Window { 15 | [NewObject] MediaQueryList matchMedia(CSSOMString query); 16 | [SameObject, Replaceable] readonly attribute Screen screen; 17 | [SameObject, Replaceable] readonly attribute VisualViewport? visualViewport; 18 | 19 | // browsing context 20 | undefined moveTo(long x, long y); 21 | undefined moveBy(long x, long y); 22 | undefined resizeTo(long width, long height); 23 | undefined resizeBy(long x, long y); 24 | 25 | // viewport 26 | [Replaceable] readonly attribute long innerWidth; 27 | [Replaceable] readonly attribute long innerHeight; 28 | 29 | // viewport scrolling 30 | [Replaceable] readonly attribute double scrollX; 31 | [Replaceable] readonly attribute double pageXOffset; 32 | [Replaceable] readonly attribute double scrollY; 33 | [Replaceable] readonly attribute double pageYOffset; 34 | undefined scroll(optional ScrollToOptions options = {}); 35 | undefined scroll(unrestricted double x, unrestricted double y); 36 | undefined scrollTo(optional ScrollToOptions options = {}); 37 | undefined scrollTo(unrestricted double x , unrestricted double y); 38 | undefined scrollBy(optional ScrollToOptions options = {}); 39 | undefined scrollBy(unrestricted double x, unrestricted double y); 40 | 41 | // client 42 | [Replaceable] readonly attribute long screenX; 43 | [Replaceable] readonly attribute long screenLeft; 44 | [Replaceable] readonly attribute long screenY; 45 | [Replaceable] readonly attribute long screenTop; 46 | [Replaceable] readonly attribute long outerWidth; 47 | [Replaceable] readonly attribute long outerHeight; 48 | [Replaceable] readonly attribute double devicePixelRatio; 49 | }; 50 | 51 | [Exposed=Window] 52 | interface MediaQueryList : EventTarget { 53 | readonly attribute CSSOMString media; 54 | readonly attribute boolean matches; 55 | undefined addListener(EventListener? callback); 56 | undefined removeListener(EventListener? callback); 57 | attribute EventHandler onchange; 58 | }; 59 | 60 | [Exposed=Window] 61 | interface MediaQueryListEvent : Event { 62 | constructor (CSSOMString type, optional MediaQueryListEventInit eventInitDict = {}); 63 | readonly attribute CSSOMString media; 64 | readonly attribute boolean matches; 65 | }; 66 | 67 | dictionary MediaQueryListEventInit : EventInit { 68 | CSSOMString media = ""; 69 | boolean matches = false; 70 | }; 71 | 72 | [Exposed=Window] 73 | interface Screen { 74 | readonly attribute long availWidth; 75 | readonly attribute long availHeight; 76 | readonly attribute long width; 77 | readonly attribute long height; 78 | readonly attribute unsigned long colorDepth; 79 | readonly attribute unsigned long pixelDepth; 80 | }; 81 | 82 | partial interface Document { 83 | Element? elementFromPoint(double x, double y); 84 | sequence elementsFromPoint(double x, double y); 85 | CaretPosition? caretPositionFromPoint(double x, double y); 86 | readonly attribute Element? scrollingElement; 87 | }; 88 | 89 | [Exposed=Window] 90 | interface CaretPosition { 91 | readonly attribute Node offsetNode; 92 | readonly attribute unsigned long offset; 93 | [NewObject] DOMRect? getClientRect(); 94 | }; 95 | 96 | enum ScrollLogicalPosition { "start" 97 | , "center" 98 | , "end" 99 | , "nearest" 100 | }; 101 | dictionary ScrollIntoViewOptions : ScrollOptions { 102 | ScrollLogicalPosition block = "start"; 103 | ScrollLogicalPosition inline = "nearest"; 104 | }; 105 | 106 | dictionary CheckVisibilityOptions { 107 | boolean checkOpacity = false; 108 | boolean checkVisibilityCSS = false; 109 | }; 110 | 111 | partial interface Element { 112 | DOMRectList getClientRects(); 113 | [NewObject] DOMRect getBoundingClientRect(); 114 | 115 | boolean checkVisibility(optional CheckVisibilityOptions options = {}); 116 | 117 | undefined scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg = {}); 118 | undefined scroll(optional ScrollToOptions options = {}); 119 | undefined scroll(unrestricted double x, unrestricted double y); 120 | undefined scrollTo(optional ScrollToOptions options = {}); 121 | undefined scrollTo(unrestricted double x, unrestricted double y); 122 | undefined scrollBy(optional ScrollToOptions options = {}); 123 | undefined scrollBy(unrestricted double x, unrestricted double y); 124 | attribute unrestricted double scrollTop; 125 | attribute unrestricted double scrollLeft; 126 | readonly attribute long scrollWidth; 127 | readonly attribute long scrollHeight; 128 | readonly attribute long clientTop; 129 | readonly attribute long clientLeft; 130 | readonly attribute long clientWidth; 131 | readonly attribute long clientHeight; 132 | }; 133 | 134 | partial interface HTMLElement { 135 | readonly attribute Element? offsetParent; 136 | readonly attribute long offsetTop; 137 | readonly attribute long offsetLeft; 138 | readonly attribute long offsetWidth; 139 | readonly attribute long offsetHeight; 140 | }; 141 | 142 | partial interface HTMLImageElement { 143 | readonly attribute long x; 144 | readonly attribute long y; 145 | }; 146 | 147 | partial interface Range { 148 | DOMRectList getClientRects(); 149 | [NewObject] DOMRect getBoundingClientRect(); 150 | }; 151 | 152 | partial interface MouseEvent { 153 | readonly attribute double screenX; 154 | readonly attribute double screenY; 155 | readonly attribute double pageX; 156 | readonly attribute double pageY; 157 | readonly attribute double clientX; 158 | readonly attribute double clientY; 159 | readonly attribute double x; 160 | readonly attribute double y; 161 | readonly attribute double offsetX; 162 | readonly attribute double offsetY; 163 | }; 164 | 165 | partial dictionary MouseEventInit { 166 | double screenX = 0.0; 167 | double screenY = 0.0; 168 | double clientX = 0.0; 169 | double clientY = 0.0; 170 | }; 171 | 172 | enum CSSBoxType {"margin", "border", "padding", "content"}; 173 | 174 | dictionary BoxQuadOptions { 175 | CSSBoxType box = "border"; 176 | GeometryNode relativeTo; // XXX default document (i.e. viewport) 177 | }; 178 | 179 | dictionary ConvertCoordinateOptions { 180 | CSSBoxType fromBox = "border"; 181 | CSSBoxType toBox = "border"; 182 | }; 183 | 184 | interface mixin GeometryUtils { 185 | sequence getBoxQuads(optional BoxQuadOptions options = {}); 186 | DOMQuad convertQuadFromNode(DOMQuadInit quad, GeometryNode from, optional ConvertCoordinateOptions options = {}); 187 | DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options = {}); 188 | DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from , optional ConvertCoordinateOptions options = {}); // XXX z,w turns into 0 189 | }; 190 | 191 | Text includes GeometryUtils; // like Range 192 | Element includes GeometryUtils; 193 | CSSPseudoElement includes GeometryUtils; 194 | Document includes GeometryUtils; 195 | 196 | typedef (Text or Element or CSSPseudoElement or Document) GeometryNode; 197 | 198 | [Exposed=Window] 199 | interface VisualViewport : EventTarget { 200 | readonly attribute double offsetLeft; 201 | readonly attribute double offsetTop; 202 | 203 | readonly attribute double pageLeft; 204 | readonly attribute double pageTop; 205 | 206 | readonly attribute double width; 207 | readonly attribute double height; 208 | 209 | readonly attribute double scale; 210 | 211 | attribute EventHandler onresize; 212 | attribute EventHandler onscroll; 213 | attribute EventHandler onscrollend; 214 | }; 215 | -------------------------------------------------------------------------------- /idl/fetch.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://fetch.spec.whatwg.org/#idl-index 2 | // and https://w3c.github.io/webappsec-referrer-policy/#idl-index 3 | 4 | typedef (sequence> or record) HeadersInit; 5 | 6 | [Exposed=(Window,Worker)] 7 | interface Headers { 8 | constructor(optional HeadersInit init); 9 | 10 | undefined append(ByteString name, ByteString value); 11 | undefined delete(ByteString name); 12 | ByteString? get(ByteString name); 13 | boolean has(ByteString name); 14 | undefined set(ByteString name, ByteString value); 15 | iterable; 16 | }; 17 | 18 | typedef (Blob or BufferSource or FormData or URLSearchParams or USVString) XMLHttpRequestBodyInit; 19 | 20 | typedef (ReadableStream or XMLHttpRequestBodyInit) BodyInit; 21 | interface mixin Body { 22 | readonly attribute ReadableStream? body; 23 | readonly attribute boolean bodyUsed; 24 | [NewObject] Promise arrayBuffer(); 25 | [NewObject] Promise blob(); 26 | [NewObject] Promise formData(); 27 | [NewObject] Promise json(); 28 | [NewObject] Promise text(); 29 | }; 30 | typedef (Request or USVString) RequestInfo; 31 | 32 | [Exposed=(Window,Worker)] 33 | interface Request { 34 | constructor(RequestInfo input, optional RequestInit init = {}); 35 | 36 | readonly attribute ByteString method; 37 | readonly attribute USVString url; 38 | [SameObject] readonly attribute Headers headers; 39 | 40 | readonly attribute RequestDestination destination; 41 | readonly attribute USVString referrer; 42 | readonly attribute ReferrerPolicy referrerPolicy; 43 | readonly attribute RequestMode mode; 44 | readonly attribute RequestCredentials credentials; 45 | readonly attribute RequestCache cache; 46 | readonly attribute RequestRedirect redirect; 47 | readonly attribute DOMString integrity; 48 | readonly attribute boolean keepalive; 49 | readonly attribute boolean isReloadNavigation; 50 | readonly attribute boolean isHistoryNavigation; 51 | readonly attribute AbortSignal signal; 52 | 53 | [NewObject] Request clone(); 54 | }; 55 | Request includes Body; 56 | 57 | dictionary RequestInit { 58 | ByteString method; 59 | HeadersInit headers; 60 | BodyInit? body; 61 | USVString referrer; 62 | ReferrerPolicy referrerPolicy; 63 | RequestMode mode; 64 | RequestCredentials credentials; 65 | RequestCache cache; 66 | RequestRedirect redirect; 67 | DOMString integrity; 68 | boolean keepalive; 69 | AbortSignal? signal; 70 | any window; // can only be set to null 71 | }; 72 | 73 | enum RequestDestination { "", "audio", "audioworklet", "document", "embed", "font", "frame", "iframe", "image", "manifest", "object", "paintworklet", "report", "script", "sharedworker", "style", "track", "video", "worker", "xslt" }; 74 | enum RequestMode { "navigate", "same-origin", "no-cors", "cors" }; 75 | enum RequestCredentials { "omit", "same-origin", "include" }; 76 | enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" }; 77 | enum RequestRedirect { "follow", "error", "manual" }; 78 | 79 | [Exposed=(Window,Worker)]interface Response { 80 | constructor(optional BodyInit? body = null, optional ResponseInit init = {}); 81 | 82 | [NewObject] static Response error(); 83 | [NewObject] static Response redirect(USVString url, optional unsigned short status = 302); 84 | 85 | readonly attribute ResponseType type; 86 | 87 | readonly attribute USVString url; 88 | readonly attribute boolean redirected; 89 | readonly attribute unsigned short status; 90 | readonly attribute boolean ok; 91 | readonly attribute ByteString statusText; 92 | [SameObject] readonly attribute Headers headers; 93 | 94 | [NewObject] Response clone(); 95 | }; 96 | Response includes Body; 97 | 98 | dictionary ResponseInit { 99 | unsigned short status = 200; 100 | ByteString statusText = ""; 101 | HeadersInit headers; 102 | }; 103 | 104 | enum ResponseType { "basic", "cors", "default", "error", "opaque", "opaqueredirect" }; 105 | 106 | partial interface mixin WindowOrWorkerGlobalScope { 107 | [NewObject] Promise fetch(RequestInfo input, optional RequestInit init = {}); 108 | }; 109 | 110 | enum ReferrerPolicy { 111 | "", 112 | "no-referrer", 113 | "no-referrer-when-downgrade", 114 | "same-origin", 115 | "origin", 116 | "strict-origin", 117 | "origin-when-cross-origin", 118 | "strict-origin-when-cross-origin", 119 | "unsafe-url" 120 | }; 121 | -------------------------------------------------------------------------------- /idl/file.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://w3c.github.io/FileAPI/ 2 | 3 | [Exposed=(Window,Worker), Serializable] 4 | interface Blob { 5 | constructor(optional sequence blobParts, 6 | optional BlobPropertyBag options = {}); 7 | 8 | readonly attribute unsigned long long size; 9 | readonly attribute DOMString type; 10 | 11 | // slice Blob into byte-ranged chunks 12 | Blob slice(optional [Clamp] long long start, 13 | optional [Clamp] long long end, 14 | optional DOMString contentType); 15 | 16 | // read from the Blob. 17 | [NewObject] ReadableStream stream(); 18 | [NewObject] Promise text(); 19 | [NewObject] Promise arrayBuffer(); 20 | }; 21 | 22 | enum EndingType { "transparent", "native" }; 23 | 24 | dictionary BlobPropertyBag { 25 | DOMString type = ""; 26 | EndingType endings = "transparent"; 27 | }; 28 | 29 | typedef (BufferSource or Blob or USVString) BlobPart; 30 | 31 | [Exposed=(Window,Worker), Serializable] 32 | interface File : Blob { 33 | constructor(sequence fileBits, 34 | USVString fileName, 35 | optional FilePropertyBag options = {}); 36 | readonly attribute DOMString name; 37 | readonly attribute long long lastModified; 38 | }; 39 | 40 | dictionary FilePropertyBag : BlobPropertyBag { 41 | long long lastModified; 42 | }; 43 | 44 | [Exposed=(Window,Worker), Serializable] 45 | interface FileList { 46 | getter File? item(unsigned long index); 47 | readonly attribute unsigned long length; 48 | }; 49 | 50 | [Exposed=(Window,Worker)] 51 | interface FileReader: EventTarget { 52 | constructor(); 53 | // async read methods 54 | undefined readAsArrayBuffer(Blob blob); 55 | undefined readAsBinaryString(Blob blob); 56 | undefined readAsText(Blob blob, optional DOMString encoding); 57 | undefined readAsDataURL(Blob blob); 58 | 59 | undefined abort(); 60 | 61 | // states 62 | const unsigned short EMPTY = 0; 63 | const unsigned short LOADING = 1; 64 | const unsigned short DONE = 2; 65 | 66 | readonly attribute unsigned short readyState; 67 | 68 | // File or Blob data 69 | readonly attribute (DOMString or ArrayBuffer)? result; 70 | 71 | readonly attribute DOMException? error; 72 | 73 | // event handler content attributes 74 | attribute EventHandler onloadstart; 75 | attribute EventHandler onprogress; 76 | attribute EventHandler onload; 77 | attribute EventHandler onabort; 78 | attribute EventHandler onerror; 79 | attribute EventHandler onloadend; 80 | }; 81 | 82 | [Exposed=(DedicatedWorker,SharedWorker)] 83 | interface FileReaderSync { 84 | constructor(); 85 | // Synchronously return strings 86 | 87 | ArrayBuffer readAsArrayBuffer(Blob blob); 88 | DOMString readAsBinaryString(Blob blob); 89 | DOMString readAsText(Blob blob, optional DOMString encoding); 90 | DOMString readAsDataURL(Blob blob); 91 | }; 92 | 93 | [Exposed=(Window,DedicatedWorker,SharedWorker)] 94 | partial interface URL { 95 | static DOMString createObjectURL((Blob or MediaSource) obj); 96 | static undefined revokeObjectURL(DOMString url); 97 | }; 98 | -------------------------------------------------------------------------------- /idl/geometry.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://www.w3.org/TR/geometry-1/#idl-index 2 | 3 | [Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0, 4 | optional unrestricted double z = 0, optional unrestricted double w = 1), 5 | Exposed=(Window,Worker), 6 | Serializable] 7 | interface DOMPointReadOnly { 8 | [NewObject] static DOMPointReadOnly fromPoint(optional DOMPointInit other); 9 | 10 | readonly attribute unrestricted double x; 11 | readonly attribute unrestricted double y; 12 | readonly attribute unrestricted double z; 13 | readonly attribute unrestricted double w; 14 | 15 | DOMPoint matrixTransform(optional DOMMatrixInit matrix); 16 | 17 | [Default] object toJSON(); 18 | }; 19 | 20 | [Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0, 21 | optional unrestricted double z = 0, optional unrestricted double w = 1), 22 | Exposed=(Window,Worker), 23 | Serializable, 24 | LegacyWindowAlias=SVGPoint] 25 | interface DOMPoint : DOMPointReadOnly { 26 | [NewObject] static DOMPoint fromPoint(optional DOMPointInit other); 27 | 28 | inherit attribute unrestricted double x; 29 | inherit attribute unrestricted double y; 30 | inherit attribute unrestricted double z; 31 | inherit attribute unrestricted double w; 32 | }; 33 | 34 | dictionary DOMPointInit { 35 | unrestricted double x = 0; 36 | unrestricted double y = 0; 37 | unrestricted double z = 0; 38 | unrestricted double w = 1; 39 | }; 40 | 41 | [Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0, 42 | optional unrestricted double width = 0, optional unrestricted double height = 0), 43 | Exposed=(Window,Worker), 44 | Serializable] 45 | interface DOMRectReadOnly { 46 | [NewObject] static DOMRectReadOnly fromRect(optional DOMRectInit other); 47 | 48 | readonly attribute unrestricted double x; 49 | readonly attribute unrestricted double y; 50 | readonly attribute unrestricted double width; 51 | readonly attribute unrestricted double height; 52 | readonly attribute unrestricted double top; 53 | readonly attribute unrestricted double right; 54 | readonly attribute unrestricted double bottom; 55 | readonly attribute unrestricted double left; 56 | 57 | [Default] object toJSON(); 58 | }; 59 | 60 | [Constructor(optional unrestricted double x = 0, optional unrestricted double y = 0, 61 | optional unrestricted double width = 0, optional unrestricted double height = 0), 62 | Exposed=(Window,Worker), 63 | Serializable, 64 | LegacyWindowAlias=SVGRect] 65 | interface DOMRect : DOMRectReadOnly { 66 | [NewObject] static DOMRect fromRect(optional DOMRectInit other); 67 | 68 | inherit attribute unrestricted double x; 69 | inherit attribute unrestricted double y; 70 | inherit attribute unrestricted double width; 71 | inherit attribute unrestricted double height; 72 | }; 73 | 74 | dictionary DOMRectInit { 75 | unrestricted double x = 0; 76 | unrestricted double y = 0; 77 | unrestricted double width = 0; 78 | unrestricted double height = 0; 79 | }; 80 | 81 | interface DOMRectList { 82 | readonly attribute unsigned long length; 83 | getter DOMRect? item(unsigned long index); 84 | }; 85 | 86 | [Constructor(optional DOMPointInit p1, optional DOMPointInit p2, 87 | optional DOMPointInit p3, optional DOMPointInit p4), 88 | Exposed=(Window,Worker), 89 | Serializable] 90 | interface DOMQuad { 91 | [NewObject] static DOMQuad fromRect(optional DOMRectInit other); 92 | [NewObject] static DOMQuad fromQuad(optional DOMQuadInit other); 93 | 94 | [SameObject] readonly attribute DOMPoint p1; 95 | [SameObject] readonly attribute DOMPoint p2; 96 | [SameObject] readonly attribute DOMPoint p3; 97 | [SameObject] readonly attribute DOMPoint p4; 98 | [NewObject] DOMRect getBounds(); 99 | 100 | [Default] object toJSON(); 101 | }; 102 | 103 | dictionary DOMQuadInit { 104 | DOMPointInit p1; 105 | DOMPointInit p2; 106 | DOMPointInit p3; 107 | DOMPointInit p4; 108 | }; 109 | 110 | [Constructor(optional (DOMString or sequence) init), 111 | Exposed=(Window,Worker), 112 | Serializable] 113 | interface DOMMatrixReadOnly { 114 | [NewObject] static DOMMatrixReadOnly fromMatrix(optional DOMMatrixInit other); 115 | [NewObject] static DOMMatrixReadOnly fromFloat32Array(Float32Array array32); 116 | [NewObject] static DOMMatrixReadOnly fromFloat64Array(Float64Array array64); 117 | 118 | // These attributes are simple aliases for certain elements of the 4x4 matrix 119 | readonly attribute unrestricted double a; 120 | readonly attribute unrestricted double b; 121 | readonly attribute unrestricted double c; 122 | readonly attribute unrestricted double d; 123 | readonly attribute unrestricted double e; 124 | readonly attribute unrestricted double f; 125 | 126 | readonly attribute unrestricted double m11; 127 | readonly attribute unrestricted double m12; 128 | readonly attribute unrestricted double m13; 129 | readonly attribute unrestricted double m14; 130 | readonly attribute unrestricted double m21; 131 | readonly attribute unrestricted double m22; 132 | readonly attribute unrestricted double m23; 133 | readonly attribute unrestricted double m24; 134 | readonly attribute unrestricted double m31; 135 | readonly attribute unrestricted double m32; 136 | readonly attribute unrestricted double m33; 137 | readonly attribute unrestricted double m34; 138 | readonly attribute unrestricted double m41; 139 | readonly attribute unrestricted double m42; 140 | readonly attribute unrestricted double m43; 141 | readonly attribute unrestricted double m44; 142 | 143 | readonly attribute boolean is2D; 144 | readonly attribute boolean isIdentity; 145 | 146 | // Immutable transform methods 147 | [NewObject] DOMMatrix translate(optional unrestricted double tx = 0, 148 | optional unrestricted double ty = 0, 149 | optional unrestricted double tz = 0); 150 | [NewObject] DOMMatrix scale(optional unrestricted double scaleX = 1, 151 | optional unrestricted double scaleY, 152 | optional unrestricted double scaleZ = 1, 153 | optional unrestricted double originX = 0, 154 | optional unrestricted double originY = 0, 155 | optional unrestricted double originZ = 0); 156 | [NewObject] DOMMatrix scaleNonUniform(optional unrestricted double scaleX = 1, 157 | optional unrestricted double scaleY = 1); 158 | [NewObject] DOMMatrix scale3d(optional unrestricted double scale = 1, 159 | optional unrestricted double originX = 0, 160 | optional unrestricted double originY = 0, 161 | optional unrestricted double originZ = 0); 162 | [NewObject] DOMMatrix rotate(optional unrestricted double rotX = 0, 163 | optional unrestricted double rotY, 164 | optional unrestricted double rotZ); 165 | [NewObject] DOMMatrix rotateFromVector(optional unrestricted double x = 0, 166 | optional unrestricted double y = 0); 167 | [NewObject] DOMMatrix rotateAxisAngle(optional unrestricted double x = 0, 168 | optional unrestricted double y = 0, 169 | optional unrestricted double z = 0, 170 | optional unrestricted double angle = 0); 171 | [NewObject] DOMMatrix skewX(optional unrestricted double sx = 0); 172 | [NewObject] DOMMatrix skewY(optional unrestricted double sy = 0); 173 | [NewObject] DOMMatrix multiply(optional DOMMatrixInit other); 174 | [NewObject] DOMMatrix flipX(); 175 | [NewObject] DOMMatrix flipY(); 176 | [NewObject] DOMMatrix inverse(); 177 | 178 | [NewObject] DOMPoint transformPoint(optional DOMPointInit point); 179 | [NewObject] Float32Array toFloat32Array(); 180 | [NewObject] Float64Array toFloat64Array(); 181 | 182 | [Exposed=Window] stringifier; 183 | [Default] object toJSON(); 184 | }; 185 | 186 | [Constructor(optional (DOMString or sequence) init), 187 | Exposed=(Window,Worker), 188 | Serializable, 189 | LegacyWindowAlias=(SVGMatrix,WebKitCSSMatrix)] 190 | interface DOMMatrix : DOMMatrixReadOnly { 191 | [NewObject] static DOMMatrix fromMatrix(optional DOMMatrixInit other); 192 | [NewObject] static DOMMatrix fromFloat32Array(Float32Array array32); 193 | [NewObject] static DOMMatrix fromFloat64Array(Float64Array array64); 194 | 195 | // These attributes are simple aliases for certain elements of the 4x4 matrix 196 | inherit attribute unrestricted double a; 197 | inherit attribute unrestricted double b; 198 | inherit attribute unrestricted double c; 199 | inherit attribute unrestricted double d; 200 | inherit attribute unrestricted double e; 201 | inherit attribute unrestricted double f; 202 | 203 | inherit attribute unrestricted double m11; 204 | inherit attribute unrestricted double m12; 205 | inherit attribute unrestricted double m13; 206 | inherit attribute unrestricted double m14; 207 | inherit attribute unrestricted double m21; 208 | inherit attribute unrestricted double m22; 209 | inherit attribute unrestricted double m23; 210 | inherit attribute unrestricted double m24; 211 | inherit attribute unrestricted double m31; 212 | inherit attribute unrestricted double m32; 213 | inherit attribute unrestricted double m33; 214 | inherit attribute unrestricted double m34; 215 | inherit attribute unrestricted double m41; 216 | inherit attribute unrestricted double m42; 217 | inherit attribute unrestricted double m43; 218 | inherit attribute unrestricted double m44; 219 | 220 | // Mutable transform methods 221 | DOMMatrix multiplySelf(optional DOMMatrixInit other); 222 | DOMMatrix preMultiplySelf(optional DOMMatrixInit other); 223 | DOMMatrix translateSelf(optional unrestricted double tx = 0, 224 | optional unrestricted double ty = 0, 225 | optional unrestricted double tz = 0); 226 | DOMMatrix scaleSelf(optional unrestricted double scaleX = 1, 227 | optional unrestricted double scaleY, 228 | optional unrestricted double scaleZ = 1, 229 | optional unrestricted double originX = 0, 230 | optional unrestricted double originY = 0, 231 | optional unrestricted double originZ = 0); 232 | DOMMatrix scale3dSelf(optional unrestricted double scale = 1, 233 | optional unrestricted double originX = 0, 234 | optional unrestricted double originY = 0, 235 | optional unrestricted double originZ = 0); 236 | DOMMatrix rotateSelf(optional unrestricted double rotX = 0, 237 | optional unrestricted double rotY, 238 | optional unrestricted double rotZ); 239 | DOMMatrix rotateFromVectorSelf(optional unrestricted double x = 0, 240 | optional unrestricted double y = 0); 241 | DOMMatrix rotateAxisAngleSelf(optional unrestricted double x = 0, 242 | optional unrestricted double y = 0, 243 | optional unrestricted double z = 0, 244 | optional unrestricted double angle = 0); 245 | DOMMatrix skewXSelf(optional unrestricted double sx = 0); 246 | DOMMatrix skewYSelf(optional unrestricted double sy = 0); 247 | DOMMatrix invertSelf(); 248 | 249 | [Exposed=Window] DOMMatrix setMatrixValue(DOMString transformList); 250 | }; 251 | 252 | dictionary DOMMatrix2DInit { 253 | unrestricted double a; 254 | unrestricted double b; 255 | unrestricted double c; 256 | unrestricted double d; 257 | unrestricted double e; 258 | unrestricted double f; 259 | unrestricted double m11; 260 | unrestricted double m12; 261 | unrestricted double m21; 262 | unrestricted double m22; 263 | unrestricted double m41; 264 | unrestricted double m42; 265 | }; 266 | 267 | dictionary DOMMatrixInit : DOMMatrix2DInit { 268 | unrestricted double m13 = 0; 269 | unrestricted double m14 = 0; 270 | unrestricted double m23 = 0; 271 | unrestricted double m24 = 0; 272 | unrestricted double m31 = 0; 273 | unrestricted double m32 = 0; 274 | unrestricted double m33 = 1; 275 | unrestricted double m34 = 0; 276 | unrestricted double m43 = 0; 277 | unrestricted double m44 = 1; 278 | boolean is2D; 279 | }; 280 | -------------------------------------------------------------------------------- /idl/indexedDB.webidl: -------------------------------------------------------------------------------- 1 | [Exposed=(Window,Worker)] 2 | interface IDBRequest : EventTarget { 3 | readonly attribute any result; 4 | readonly attribute DOMException? error; 5 | readonly attribute (IDBObjectStore or IDBIndex or IDBCursor)? source; 6 | readonly attribute IDBTransaction? transaction; 7 | readonly attribute IDBRequestReadyState readyState; 8 | 9 | // Event handlers: 10 | attribute EventHandler onsuccess; 11 | attribute EventHandler onerror; 12 | }; 13 | 14 | enum IDBRequestReadyState { 15 | "pending", 16 | "done" 17 | }; 18 | [Exposed=(Window,Worker)] 19 | interface IDBOpenDBRequest : IDBRequest { 20 | // Event handlers: 21 | attribute EventHandler onblocked; 22 | attribute EventHandler onupgradeneeded; 23 | }; 24 | [Exposed=(Window,Worker)] 25 | interface IDBVersionChangeEvent : Event { 26 | constructor(DOMString type, optional IDBVersionChangeEventInit eventInitDict = {}); 27 | readonly attribute unsigned long long oldVersion; 28 | readonly attribute unsigned long long? newVersion; 29 | }; 30 | 31 | dictionary IDBVersionChangeEventInit : EventInit { 32 | unsigned long long oldVersion = 0; 33 | unsigned long long? newVersion = null; 34 | }; 35 | partial interface mixin WindowOrWorkerGlobalScope { 36 | [SameObject] readonly attribute IDBFactory indexedDB; 37 | }; 38 | [Exposed=(Window,Worker)] 39 | interface IDBFactory { 40 | [NewObject] IDBOpenDBRequest open(DOMString name, 41 | optional [EnforceRange] unsigned long long version); 42 | [NewObject] IDBOpenDBRequest deleteDatabase(DOMString name); 43 | 44 | Promise> databases(); 45 | 46 | short cmp(any first, any second); 47 | }; 48 | 49 | dictionary IDBDatabaseInfo { 50 | DOMString name; 51 | unsigned long long version; 52 | }; 53 | [Exposed=(Window,Worker)] 54 | interface IDBDatabase : EventTarget { 55 | readonly attribute DOMString name; 56 | readonly attribute unsigned long long version; 57 | readonly attribute DOMStringList objectStoreNames; 58 | 59 | [NewObject] IDBTransaction transaction((DOMString or sequence) storeNames, 60 | optional IDBTransactionMode mode = "readonly", 61 | optional IDBTransactionOptions options = {}); 62 | undefined close(); 63 | 64 | [NewObject] IDBObjectStore createObjectStore( 65 | DOMString name, 66 | optional IDBObjectStoreParameters options = {}); 67 | undefined deleteObjectStore(DOMString name); 68 | 69 | // Event handlers: 70 | attribute EventHandler onabort; 71 | attribute EventHandler onclose; 72 | attribute EventHandler onerror; 73 | attribute EventHandler onversionchange; 74 | }; 75 | 76 | enum IDBTransactionDurability { "default", "strict", "relaxed" }; 77 | 78 | dictionary IDBTransactionOptions { 79 | IDBTransactionDurability durability = "default"; 80 | }; 81 | 82 | dictionary IDBObjectStoreParameters { 83 | (DOMString or sequence)? keyPath = null; 84 | boolean autoIncrement = false; 85 | }; 86 | [Exposed=(Window,Worker)] 87 | interface IDBObjectStore { 88 | attribute DOMString name; 89 | readonly attribute any keyPath; 90 | readonly attribute DOMStringList indexNames; 91 | [SameObject] readonly attribute IDBTransaction transaction; 92 | readonly attribute boolean autoIncrement; 93 | 94 | [NewObject] IDBRequest put(any value, optional any key); 95 | [NewObject] IDBRequest add(any value, optional any key); 96 | [NewObject] IDBRequest delete(any query); 97 | [NewObject] IDBRequest clear(); 98 | [NewObject] IDBRequest get(any query); 99 | [NewObject] IDBRequest getKey(any query); 100 | [NewObject] IDBRequest getAll(optional any query, 101 | optional [EnforceRange] unsigned long count); 102 | [NewObject] IDBRequest getAllKeys(optional any query, 103 | optional [EnforceRange] unsigned long count); 104 | [NewObject] IDBRequest count(optional any query); 105 | 106 | [NewObject] IDBRequest openCursor(optional any query, 107 | optional IDBCursorDirection direction = "next"); 108 | [NewObject] IDBRequest openKeyCursor(optional any query, 109 | optional IDBCursorDirection direction = "next"); 110 | 111 | IDBIndex index(DOMString name); 112 | 113 | [NewObject] IDBIndex createIndex(DOMString name, 114 | (DOMString or sequence) keyPath, 115 | optional IDBIndexParameters options = {}); 116 | undefined deleteIndex(DOMString name); 117 | }; 118 | 119 | dictionary IDBIndexParameters { 120 | boolean unique = false; 121 | boolean multiEntry = false; 122 | }; 123 | [Exposed=(Window,Worker)] 124 | interface IDBIndex { 125 | attribute DOMString name; 126 | [SameObject] readonly attribute IDBObjectStore objectStore; 127 | readonly attribute any keyPath; 128 | readonly attribute boolean multiEntry; 129 | readonly attribute boolean unique; 130 | 131 | [NewObject] IDBRequest get(any query); 132 | [NewObject] IDBRequest getKey(any query); 133 | [NewObject] IDBRequest getAll(optional any query, 134 | optional [EnforceRange] unsigned long count); 135 | [NewObject] IDBRequest getAllKeys(optional any query, 136 | optional [EnforceRange] unsigned long count); 137 | [NewObject] IDBRequest count(optional any query); 138 | 139 | [NewObject] IDBRequest openCursor(optional any query, 140 | optional IDBCursorDirection direction = "next"); 141 | [NewObject] IDBRequest openKeyCursor(optional any query, 142 | optional IDBCursorDirection direction = "next"); 143 | }; 144 | [Exposed=(Window,Worker)] 145 | interface IDBKeyRange { 146 | readonly attribute any lower; 147 | readonly attribute any upper; 148 | readonly attribute boolean lowerOpen; 149 | readonly attribute boolean upperOpen; 150 | 151 | // Static construction methods: 152 | [NewObject] static IDBKeyRange only(any value); 153 | [NewObject] static IDBKeyRange lowerBound(any lower, optional boolean open = false); 154 | [NewObject] static IDBKeyRange upperBound(any upper, optional boolean open = false); 155 | [NewObject] static IDBKeyRange bound(any lower, 156 | any upper, 157 | optional boolean lowerOpen = false, 158 | optional boolean upperOpen = false); 159 | 160 | boolean includes(any key); 161 | }; 162 | [Exposed=(Window,Worker)] 163 | interface IDBCursor { 164 | readonly attribute (IDBObjectStore or IDBIndex) source; 165 | readonly attribute IDBCursorDirection direction; 166 | readonly attribute any key; 167 | readonly attribute any primaryKey; 168 | [SameObject] readonly attribute IDBRequest request; 169 | 170 | undefined advance([EnforceRange] unsigned long count); 171 | undefined continue(optional any key); 172 | undefined continuePrimaryKey(any key, any primaryKey); 173 | 174 | [NewObject] IDBRequest update(any value); 175 | [NewObject] IDBRequest delete(); 176 | }; 177 | 178 | enum IDBCursorDirection { 179 | "next", 180 | "nextunique", 181 | "prev", 182 | "prevunique" 183 | }; 184 | [Exposed=(Window,Worker)] 185 | interface IDBCursorWithValue : IDBCursor { 186 | readonly attribute any value; 187 | }; 188 | [Exposed=(Window,Worker)] 189 | interface IDBTransaction : EventTarget { 190 | readonly attribute DOMStringList objectStoreNames; 191 | readonly attribute IDBTransactionMode mode; 192 | readonly attribute IDBTransactionDurability durability; 193 | [SameObject] readonly attribute IDBDatabase db; 194 | readonly attribute DOMException? error; 195 | 196 | IDBObjectStore objectStore(DOMString name); 197 | undefined commit(); 198 | undefined abort(); 199 | 200 | // Event handlers: 201 | attribute EventHandler onabort; 202 | attribute EventHandler oncomplete; 203 | attribute EventHandler onerror; 204 | }; 205 | 206 | enum IDBTransactionMode { 207 | "readonly", 208 | "readwrite", 209 | "versionchange" 210 | }; 211 | -------------------------------------------------------------------------------- /idl/mediasource.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://w3c.github.io/media-source/#text-track-extensions 2 | 3 | enum ReadyState { 4 | "closed", 5 | "open", 6 | "ended" 7 | }; 8 | 9 | enum EndOfStreamError { 10 | "network", 11 | "decode" 12 | }; 13 | 14 | [Exposed=Window] 15 | interface MediaSource : EventTarget { 16 | constructor(); 17 | readonly attribute SourceBufferList sourceBuffers; 18 | readonly attribute SourceBufferList activeSourceBuffers; 19 | readonly attribute ReadyState readyState; 20 | attribute unrestricted double duration; 21 | attribute EventHandler onsourceopen; 22 | attribute EventHandler onsourceended; 23 | attribute EventHandler onsourceclose; 24 | SourceBuffer addSourceBuffer (DOMString type); 25 | undefined removeSourceBuffer (SourceBuffer sourceBuffer); 26 | undefined endOfStream (optional EndOfStreamError error); 27 | undefined setLiveSeekableRange (double start, double end); 28 | undefined clearLiveSeekableRange (); 29 | static boolean isTypeSupported (DOMString type); 30 | }; 31 | 32 | enum AppendMode { 33 | "segments", 34 | "sequence" 35 | }; 36 | 37 | [Exposed=Window] 38 | interface SourceBuffer : EventTarget { 39 | attribute AppendMode mode; 40 | readonly attribute boolean updating; 41 | readonly attribute TimeRanges buffered; 42 | attribute double timestampOffset; 43 | readonly attribute AudioTrackList audioTracks; 44 | readonly attribute VideoTrackList videoTracks; 45 | readonly attribute TextTrackList textTracks; 46 | attribute double appendWindowStart; 47 | attribute unrestricted double appendWindowEnd; 48 | attribute EventHandler onupdatestart; 49 | attribute EventHandler onupdate; 50 | attribute EventHandler onupdateend; 51 | attribute EventHandler onerror; 52 | attribute EventHandler onabort; 53 | undefined appendBuffer (BufferSource data); 54 | undefined abort (); 55 | undefined remove (double start, unrestricted double end); 56 | }; 57 | 58 | [Exposed=Window] 59 | interface SourceBufferList : EventTarget { 60 | readonly attribute unsigned long length; 61 | attribute EventHandler onaddsourcebuffer; 62 | attribute EventHandler onremovesourcebuffer; 63 | getter SourceBuffer (unsigned long index); 64 | }; 65 | 66 | [Exposed=Window] 67 | partial interface URL { 68 | static DOMString createObjectURL (MediaSource mediaSource); 69 | }; 70 | 71 | partial interface AudioTrack { 72 | readonly attribute SourceBuffer? sourceBuffer; 73 | }; 74 | 75 | partial interface VideoTrack { 76 | readonly attribute SourceBuffer? sourceBuffer; 77 | }; 78 | 79 | partial interface TextTrack { 80 | readonly attribute SourceBuffer? sourceBuffer; 81 | }; 82 | -------------------------------------------------------------------------------- /idl/mediastream.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://w3c.github.io/mediacapture-main/getusermedia.html#idl-def-mediastream 2 | 3 | [Exposed=Window] 4 | interface MediaStream : EventTarget { 5 | constructor(); 6 | constructor(MediaStream stream); 7 | constructor(sequence tracks); 8 | readonly attribute DOMString id; 9 | sequence getAudioTracks(); 10 | sequence getVideoTracks(); 11 | sequence getTracks(); 12 | MediaStreamTrack? getTrackById(DOMString trackId); 13 | undefined addTrack(MediaStreamTrack track); 14 | undefined removeTrack(MediaStreamTrack track); 15 | MediaStream clone(); 16 | readonly attribute boolean active; 17 | attribute EventHandler onaddtrack; 18 | attribute EventHandler onremovetrack; 19 | }; 20 | 21 | [Exposed=Window] 22 | interface MediaStreamTrack : EventTarget { 23 | readonly attribute DOMString kind; 24 | readonly attribute DOMString id; 25 | readonly attribute DOMString label; 26 | attribute boolean enabled; 27 | readonly attribute boolean muted; 28 | attribute EventHandler onmute; 29 | attribute EventHandler onunmute; 30 | readonly attribute MediaStreamTrackState readyState; 31 | attribute EventHandler onended; 32 | MediaStreamTrack clone(); 33 | undefined stop(); 34 | MediaTrackCapabilities getCapabilities(); 35 | MediaTrackConstraints getConstraints(); 36 | MediaTrackSettings getSettings(); 37 | Promise applyConstraints(optional MediaTrackConstraints constraints = {}); 38 | }; 39 | 40 | enum MediaStreamTrackState { 41 | "live", 42 | "ended" 43 | }; 44 | 45 | dictionary MediaTrackSupportedConstraints { 46 | boolean width = true; 47 | boolean height = true; 48 | boolean aspectRatio = true; 49 | boolean frameRate = true; 50 | boolean facingMode = true; 51 | boolean resizeMode = true; 52 | boolean sampleRate = true; 53 | boolean sampleSize = true; 54 | boolean echoCancellation = true; 55 | boolean autoGainControl = true; 56 | boolean noiseSuppression = true; 57 | boolean latency = true; 58 | boolean channelCount = true; 59 | boolean deviceId = true; 60 | boolean groupId = true; 61 | }; 62 | 63 | dictionary MediaTrackCapabilities { 64 | ULongRange width; 65 | ULongRange height; 66 | DoubleRange aspectRatio; 67 | DoubleRange frameRate; 68 | sequence facingMode; 69 | sequence resizeMode; 70 | ULongRange sampleRate; 71 | ULongRange sampleSize; 72 | sequence echoCancellation; 73 | sequence autoGainControl; 74 | sequence noiseSuppression; 75 | DoubleRange latency; 76 | ULongRange channelCount; 77 | DOMString deviceId; 78 | DOMString groupId; 79 | }; 80 | 81 | dictionary MediaTrackConstraints : MediaTrackConstraintSet { 82 | sequence advanced; 83 | }; 84 | 85 | dictionary MediaTrackConstraintSet { 86 | ConstrainULong width; 87 | ConstrainULong height; 88 | ConstrainDouble aspectRatio; 89 | ConstrainDouble frameRate; 90 | ConstrainDOMString facingMode; 91 | ConstrainDOMString resizeMode; 92 | ConstrainULong sampleRate; 93 | ConstrainULong sampleSize; 94 | ConstrainBoolean echoCancellation; 95 | ConstrainBoolean autoGainControl; 96 | ConstrainBoolean noiseSuppression; 97 | ConstrainDouble latency; 98 | ConstrainULong channelCount; 99 | ConstrainDOMString deviceId; 100 | ConstrainDOMString groupId; 101 | }; 102 | 103 | dictionary MediaTrackSettings { 104 | long width; 105 | long height; 106 | double aspectRatio; 107 | double frameRate; 108 | DOMString facingMode; 109 | DOMString resizeMode; 110 | long sampleRate; 111 | long sampleSize; 112 | boolean echoCancellation; 113 | boolean autoGainControl; 114 | boolean noiseSuppression; 115 | double latency; 116 | long channelCount; 117 | DOMString deviceId; 118 | DOMString groupId; 119 | }; 120 | 121 | enum VideoFacingModeEnum { 122 | "user", 123 | "environment", 124 | "left", 125 | "right" 126 | }; 127 | 128 | enum VideoResizeModeEnum { 129 | "none", 130 | "crop-and-scale" 131 | }; 132 | 133 | [Exposed=Window] 134 | interface MediaStreamTrackEvent : Event { 135 | constructor(DOMString type, MediaStreamTrackEventInit eventInitDict); 136 | [SameObject] readonly attribute MediaStreamTrack track; 137 | }; 138 | 139 | dictionary MediaStreamTrackEventInit : EventInit { 140 | required MediaStreamTrack track; 141 | }; 142 | 143 | [Exposed=Window] 144 | interface OverconstrainedError : DOMException { 145 | constructor(DOMString constraint, optional DOMString message = ""); 146 | readonly attribute DOMString constraint; 147 | }; 148 | 149 | partial interface Navigator { 150 | [SameObject, SecureContext] readonly attribute MediaDevices mediaDevices; 151 | }; 152 | 153 | [Exposed=Window, SecureContext] 154 | interface MediaDevices : EventTarget { 155 | attribute EventHandler ondevicechange; 156 | Promise> enumerateDevices(); 157 | }; 158 | 159 | [Exposed=Window, SecureContext] 160 | interface MediaDeviceInfo { 161 | readonly attribute DOMString deviceId; 162 | readonly attribute MediaDeviceKind kind; 163 | readonly attribute DOMString label; 164 | readonly attribute DOMString groupId; 165 | [Default] object toJSON(); 166 | }; 167 | 168 | enum MediaDeviceKind { 169 | "audioinput", 170 | "audiooutput", 171 | "videoinput" 172 | }; 173 | 174 | [Exposed=Window] 175 | interface InputDeviceInfo : MediaDeviceInfo { 176 | MediaTrackCapabilities getCapabilities(); 177 | }; 178 | 179 | partial interface Navigator { 180 | [SecureContext] undefined getUserMedia(MediaStreamConstraints constraints, 181 | NavigatorUserMediaSuccessCallback successCallback, 182 | NavigatorUserMediaErrorCallback errorCallback); 183 | }; 184 | 185 | partial interface MediaDevices { 186 | MediaTrackSupportedConstraints getSupportedConstraints(); 187 | Promise getUserMedia(optional MediaStreamConstraints constraints = {}); 188 | }; 189 | 190 | dictionary MediaStreamConstraints { 191 | (boolean or MediaTrackConstraints) video = false; 192 | (boolean or MediaTrackConstraints) audio = false; 193 | }; 194 | 195 | callback NavigatorUserMediaSuccessCallback = undefined (MediaStream stream); 196 | 197 | callback NavigatorUserMediaErrorCallback = undefined (DOMException error); 198 | 199 | [Exposed=Window] 200 | interface ConstrainablePattern { 201 | Capabilities getCapabilities(); 202 | Constraints getConstraints(); 203 | Settings getSettings(); 204 | Promise applyConstraints(optional Constraints constraints = {}); 205 | }; 206 | 207 | dictionary DoubleRange { 208 | double max; 209 | double min; 210 | }; 211 | 212 | dictionary ConstrainDoubleRange : DoubleRange { 213 | double exact; 214 | double ideal; 215 | }; 216 | 217 | dictionary ULongRange { 218 | [Clamp] unsigned long max; 219 | [Clamp] unsigned long min; 220 | }; 221 | 222 | dictionary ConstrainULongRange : ULongRange { 223 | [Clamp] unsigned long exact; 224 | [Clamp] unsigned long ideal; 225 | }; 226 | 227 | dictionary ConstrainBooleanParameters { 228 | boolean exact; 229 | boolean ideal; 230 | }; 231 | 232 | dictionary ConstrainDOMStringParameters { 233 | (DOMString or sequence) exact; 234 | (DOMString or sequence) ideal; 235 | }; 236 | 237 | typedef ([Clamp] unsigned long or ConstrainULongRange) ConstrainULong; 238 | 239 | typedef (double or ConstrainDoubleRange) ConstrainDouble; 240 | 241 | typedef (boolean or ConstrainBooleanParameters) ConstrainBoolean; 242 | 243 | typedef (DOMString or 244 | sequence or 245 | ConstrainDOMStringParameters) ConstrainDOMString; 246 | 247 | dictionary Capabilities {}; 248 | 249 | dictionary Settings {}; 250 | 251 | dictionary ConstraintSet {}; 252 | 253 | dictionary Constraints : ConstraintSet { 254 | sequence advanced; 255 | }; 256 | -------------------------------------------------------------------------------- /idl/permissions.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://w3c.github.io/permissions/ 2 | 3 | dictionary PermissionDescriptor { 4 | required PermissionName name; 5 | }; 6 | 7 | enum PermissionState { 8 | "granted", 9 | "denied", 10 | "prompt", 11 | }; 12 | 13 | [Exposed=(Window,Worker)] 14 | interface PermissionStatus : EventTarget { 15 | readonly attribute PermissionState state; 16 | attribute EventHandler onchange; 17 | }; 18 | 19 | [Exposed=(Window)] 20 | partial interface Navigator { 21 | [SameObject] readonly attribute Permissions permissions; 22 | }; 23 | 24 | [Exposed=(Worker)] 25 | partial interface WorkerNavigator { 26 | [SameObject] readonly attribute Permissions permissions; 27 | }; 28 | 29 | [Exposed=(Window,Worker)] 30 | interface Permissions { 31 | Promise query(object permissionDesc); 32 | }; 33 | 34 | enum PermissionName { 35 | "geolocation", 36 | "notifications", 37 | "push", 38 | "midi", 39 | "camera", 40 | "microphone", 41 | "speaker-selection", 42 | "device-info", 43 | "background-fetch", 44 | "background-sync", 45 | "bluetooth", 46 | "persistent-storage", 47 | "ambient-light-sensor", 48 | "accelerometer", 49 | "gyroscope", 50 | "magnetometer", 51 | "clipboard-read", 52 | "clipboard-write", 53 | "display-capture", 54 | "nfc", 55 | }; 56 | 57 | dictionary PushPermissionDescriptor : PermissionDescriptor { 58 | boolean userVisibleOnly = false; 59 | }; 60 | 61 | dictionary MidiPermissionDescriptor : PermissionDescriptor { 62 | boolean sysex = false; 63 | }; 64 | 65 | dictionary DevicePermissionDescriptor : PermissionDescriptor { 66 | DOMString deviceId; 67 | }; 68 | 69 | dictionary CameraDevicePermissionDescriptor : DevicePermissionDescriptor { 70 | boolean panTiltZoom = false; 71 | }; 72 | 73 | dictionary PermissionSetParameters { 74 | required PermissionDescriptor descriptor; 75 | required PermissionState state; 76 | boolean oneRealm = false; 77 | }; 78 | -------------------------------------------------------------------------------- /idl/serviceworker.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://w3c.github.io/ServiceWorker/#idl-index 2 | 3 | [SecureContext, Exposed=(Window,Worker)] 4 | interface ServiceWorker : EventTarget { 5 | readonly attribute USVString scriptURL; 6 | readonly attribute ServiceWorkerState state; 7 | undefined postMessage(any message, sequence transfer); 8 | undefined postMessage(any message, optional PostMessageOptions options = {}); 9 | 10 | // event 11 | attribute EventHandler onstatechange; 12 | }; 13 | ServiceWorker includes AbstractWorker; 14 | 15 | enum ServiceWorkerState { 16 | "parsed", 17 | "installing", 18 | "installed", 19 | "activating", 20 | "activated", 21 | "redundant" 22 | }; 23 | 24 | [SecureContext, Exposed=(Window,Worker)] 25 | interface ServiceWorkerRegistration : EventTarget { 26 | readonly attribute ServiceWorker? installing; 27 | readonly attribute ServiceWorker? waiting; 28 | readonly attribute ServiceWorker? active; 29 | [SameObject] readonly attribute NavigationPreloadManager navigationPreload; 30 | 31 | readonly attribute USVString scope; 32 | readonly attribute ServiceWorkerUpdateViaCache updateViaCache; 33 | 34 | [NewObject] Promise update(); 35 | [NewObject] Promise unregister(); 36 | 37 | // event 38 | attribute EventHandler onupdatefound; 39 | }; 40 | 41 | enum ServiceWorkerUpdateViaCache { 42 | "imports", 43 | "all", 44 | "none" 45 | }; 46 | 47 | partial interface Navigator { 48 | [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker; 49 | }; 50 | 51 | partial interface WorkerNavigator { 52 | [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker; 53 | }; 54 | 55 | [SecureContext, Exposed=(Window,Worker)] 56 | interface ServiceWorkerContainer : EventTarget { 57 | readonly attribute ServiceWorker? controller; 58 | readonly attribute Promise ready; 59 | 60 | [NewObject] Promise register(USVString scriptURL, optional RegistrationOptions options = {}); 61 | 62 | [NewObject] Promise<(ServiceWorkerRegistration or undefined)> getRegistration(optional USVString clientURL = ""); 63 | [NewObject] Promise> getRegistrations(); 64 | 65 | undefined startMessages(); 66 | 67 | 68 | // events 69 | attribute EventHandler oncontrollerchange; 70 | attribute EventHandler onmessage; // event.source of message events is ServiceWorker object 71 | attribute EventHandler onmessageerror; 72 | }; 73 | 74 | dictionary RegistrationOptions { 75 | USVString scope; 76 | WorkerType type = "classic"; 77 | ServiceWorkerUpdateViaCache updateViaCache = "imports"; 78 | }; 79 | 80 | [SecureContext, Exposed=(Window,Worker)] 81 | interface NavigationPreloadManager { 82 | Promise enable(); 83 | Promise disable(); 84 | Promise setHeaderValue(ByteString value); 85 | Promise getState(); 86 | }; 87 | 88 | dictionary NavigationPreloadState { 89 | boolean enabled = false; 90 | ByteString headerValue; 91 | }; 92 | 93 | [Global=(Worker,ServiceWorker), Exposed=ServiceWorker] 94 | interface ServiceWorkerGlobalScope : WorkerGlobalScope { 95 | [SameObject] readonly attribute Clients clients; 96 | [SameObject] readonly attribute ServiceWorkerRegistration registration; 97 | [SameObject] readonly attribute ServiceWorker serviceWorker; 98 | 99 | [NewObject] Promise skipWaiting(); 100 | 101 | attribute EventHandler oninstall; 102 | attribute EventHandler onactivate; 103 | attribute EventHandler onfetch; 104 | 105 | attribute EventHandler onmessage; 106 | attribute EventHandler onmessageerror; 107 | }; 108 | 109 | [Exposed=ServiceWorker] 110 | interface Client { 111 | readonly attribute USVString url; 112 | readonly attribute FrameType frameType; 113 | readonly attribute DOMString id; 114 | readonly attribute ClientType type; 115 | undefined postMessage(any message, sequence transfer); 116 | undefined postMessage(any message, optional PostMessageOptions options = {}); 117 | }; 118 | 119 | [Exposed=ServiceWorker] 120 | interface WindowClient : Client { 121 | readonly attribute VisibilityState visibilityState; 122 | readonly attribute boolean focused; 123 | [SameObject] readonly attribute FrozenArray ancestorOrigins; 124 | [NewObject] Promise focus(); 125 | [NewObject] Promise navigate(USVString url); 126 | }; 127 | 128 | enum FrameType { 129 | "auxiliary", 130 | "top-level", 131 | "nested", 132 | "none" 133 | }; 134 | 135 | [Exposed=ServiceWorker] 136 | interface Clients { 137 | // The objects returned will be new instances every time 138 | [NewObject] Promise<(Client or undefined)> get(DOMString id); 139 | [NewObject] Promise> matchAll(optional ClientQueryOptions options = {}); 140 | [NewObject] Promise openWindow(USVString url); 141 | [NewObject] Promise claim(); 142 | }; 143 | 144 | dictionary ClientQueryOptions { 145 | boolean includeUncontrolled = false; 146 | ClientType type = "window"; 147 | }; 148 | 149 | enum ClientType { 150 | "window", 151 | "worker", 152 | "sharedworker", 153 | "all" 154 | }; 155 | 156 | [Exposed=ServiceWorker] 157 | interface ExtendableEvent : Event { 158 | constructor(DOMString type, optional ExtendableEventInit eventInitDict = {}); 159 | undefined waitUntil(Promise f); 160 | }; 161 | 162 | dictionary ExtendableEventInit : EventInit { 163 | // Defined for the forward compatibility across the derived events 164 | }; 165 | 166 | [Exposed=ServiceWorker] 167 | interface FetchEvent : ExtendableEvent { 168 | constructor(DOMString type, FetchEventInit eventInitDict); 169 | [SameObject] readonly attribute Request request; 170 | readonly attribute Promise preloadResponse; 171 | readonly attribute DOMString clientId; 172 | readonly attribute DOMString resultingClientId; 173 | readonly attribute DOMString replacesClientId; 174 | readonly attribute Promise handled; 175 | 176 | undefined respondWith(Promise r); 177 | }; 178 | 179 | dictionary FetchEventInit : ExtendableEventInit { 180 | required Request request; 181 | Promise preloadResponse; 182 | DOMString clientId = ""; 183 | DOMString resultingClientId = ""; 184 | DOMString replacesClientId = ""; 185 | Promise handled; 186 | }; 187 | 188 | [Exposed=ServiceWorker] 189 | interface ExtendableMessageEvent : ExtendableEvent { 190 | constructor(DOMString type, optional ExtendableMessageEventInit eventInitDict = {}); 191 | readonly attribute any data; 192 | readonly attribute USVString origin; 193 | readonly attribute DOMString lastEventId; 194 | [SameObject] readonly attribute (Client or ServiceWorker or MessagePort)? source; 195 | readonly attribute FrozenArray ports; 196 | }; 197 | 198 | dictionary ExtendableMessageEventInit : ExtendableEventInit { 199 | any data = null; 200 | USVString origin = ""; 201 | DOMString lastEventId = ""; 202 | (Client or ServiceWorker or MessagePort)? source = null; 203 | sequence ports = []; 204 | }; 205 | 206 | partial interface mixin WindowOrWorkerGlobalScope { 207 | [SecureContext, SameObject] readonly attribute CacheStorage caches; 208 | }; 209 | 210 | [SecureContext, Exposed=(Window,Worker)] 211 | interface Cache { 212 | [NewObject] Promise<(Response or undefined)> match(RequestInfo request, optional CacheQueryOptions options = {}); 213 | [NewObject] Promise> matchAll(optional RequestInfo request, optional CacheQueryOptions options = {}); 214 | [NewObject] Promise add(RequestInfo request); 215 | [NewObject] Promise addAll(sequence requests); 216 | [NewObject] Promise put(RequestInfo request, Response response); 217 | [NewObject] Promise delete(RequestInfo request, optional CacheQueryOptions options = {}); 218 | [NewObject] Promise> keys(optional RequestInfo request, optional CacheQueryOptions options = {}); 219 | }; 220 | 221 | dictionary CacheQueryOptions { 222 | boolean ignoreSearch = false; 223 | boolean ignoreMethod = false; 224 | boolean ignoreVary = false; 225 | }; 226 | 227 | [SecureContext, Exposed=(Window,Worker)] 228 | interface CacheStorage { 229 | [NewObject] Promise<(Response or undefined)> match(RequestInfo request, optional MultiCacheQueryOptions options = {}); 230 | [NewObject] Promise has(DOMString cacheName); 231 | [NewObject] Promise open(DOMString cacheName); 232 | [NewObject] Promise delete(DOMString cacheName); 233 | [NewObject] Promise> keys(); 234 | }; 235 | 236 | dictionary MultiCacheQueryOptions : CacheQueryOptions { 237 | DOMString cacheName; 238 | }; 239 | -------------------------------------------------------------------------------- /idl/streams.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://streams.spec.whatwg.org/#idl-index 2 | 3 | [Exposed=(Window,Worker,Worklet), Transferable] 4 | interface ReadableStream { 5 | constructor(optional object underlyingSource, optional QueuingStrategy strategy = {}); 6 | 7 | readonly attribute boolean locked; 8 | 9 | Promise cancel(optional any reason); 10 | ReadableStreamReader getReader(optional ReadableStreamGetReaderOptions options = {}); 11 | ReadableStream pipeThrough(ReadableWritablePair transform, optional StreamPipeOptions options = {}); 12 | Promise pipeTo(WritableStream destination, optional StreamPipeOptions options = {}); 13 | sequence tee(); 14 | 15 | async iterable(optional ReadableStreamIteratorOptions options = {}); 16 | }; 17 | 18 | typedef (ReadableStreamDefaultReader or ReadableStreamBYOBReader) ReadableStreamReader; 19 | 20 | enum ReadableStreamReaderMode { "byob" }; 21 | 22 | dictionary ReadableStreamGetReaderOptions { 23 | ReadableStreamReaderMode mode; 24 | }; 25 | 26 | dictionary ReadableStreamIteratorOptions { 27 | boolean preventCancel = false; 28 | }; 29 | 30 | dictionary ReadableWritablePair { 31 | required ReadableStream readable; 32 | required WritableStream writable; 33 | }; 34 | 35 | dictionary StreamPipeOptions { 36 | boolean preventClose = false; 37 | boolean preventAbort = false; 38 | boolean preventCancel = false; 39 | AbortSignal signal; 40 | }; 41 | 42 | dictionary UnderlyingSource { 43 | UnderlyingSourceStartCallback start; 44 | UnderlyingSourcePullCallback pull; 45 | UnderlyingSourceCancelCallback cancel; 46 | ReadableStreamType type; 47 | [EnforceRange] unsigned long long autoAllocateChunkSize; 48 | }; 49 | 50 | typedef (ReadableStreamDefaultController or ReadableByteStreamController) ReadableStreamController; 51 | 52 | callback UnderlyingSourceStartCallback = any (ReadableStreamController controller); 53 | callback UnderlyingSourcePullCallback = Promise (ReadableStreamController controller); 54 | callback UnderlyingSourceCancelCallback = Promise (optional any reason); 55 | 56 | enum ReadableStreamType { "bytes" }; 57 | 58 | interface mixin ReadableStreamGenericReader { 59 | readonly attribute Promise closed; 60 | 61 | Promise cancel(optional any reason); 62 | }; 63 | 64 | [Exposed=(Window,Worker,Worklet)] 65 | interface ReadableStreamDefaultReader { 66 | constructor(ReadableStream stream); 67 | 68 | Promise read(); 69 | undefined releaseLock(); 70 | }; 71 | ReadableStreamDefaultReader includes ReadableStreamGenericReader; 72 | 73 | dictionary ReadableStreamDefaultReadResult { 74 | any value; 75 | boolean done; 76 | }; 77 | 78 | [Exposed=(Window,Worker,Worklet)] 79 | interface ReadableStreamBYOBReader { 80 | constructor(ReadableStream stream); 81 | 82 | Promise read(ArrayBufferView view); 83 | undefined releaseLock(); 84 | }; 85 | ReadableStreamBYOBReader includes ReadableStreamGenericReader; 86 | 87 | dictionary ReadableStreamBYOBReadResult { 88 | ArrayBufferView value; 89 | boolean done; 90 | }; 91 | 92 | [Exposed=(Window,Worker,Worklet)] 93 | interface ReadableStreamDefaultController { 94 | readonly attribute unrestricted double? desiredSize; 95 | 96 | undefined close(); 97 | undefined enqueue(optional any chunk); 98 | undefined error(optional any e); 99 | }; 100 | 101 | [Exposed=(Window,Worker,Worklet)] 102 | interface ReadableByteStreamController { 103 | readonly attribute ReadableStreamBYOBRequest? byobRequest; 104 | readonly attribute unrestricted double? desiredSize; 105 | 106 | undefined close(); 107 | undefined enqueue(ArrayBufferView chunk); 108 | undefined error(optional any e); 109 | }; 110 | 111 | [Exposed=(Window,Worker,Worklet)] 112 | interface ReadableStreamBYOBRequest { 113 | readonly attribute ArrayBufferView? view; 114 | 115 | undefined respond([EnforceRange] unsigned long long bytesWritten); 116 | undefined respondWithNewView(ArrayBufferView view); 117 | }; 118 | 119 | [Exposed=(Window,Worker,Worklet), Transferable] 120 | interface WritableStream { 121 | constructor(optional object underlyingSink, optional QueuingStrategy strategy = {}); 122 | 123 | readonly attribute boolean locked; 124 | 125 | Promise abort(optional any reason); 126 | Promise close(); 127 | WritableStreamDefaultWriter getWriter(); 128 | }; 129 | 130 | dictionary UnderlyingSink { 131 | UnderlyingSinkStartCallback start; 132 | UnderlyingSinkWriteCallback write; 133 | UnderlyingSinkCloseCallback close; 134 | UnderlyingSinkAbortCallback abort; 135 | any type; 136 | }; 137 | 138 | callback UnderlyingSinkStartCallback = any (WritableStreamDefaultController controller); 139 | callback UnderlyingSinkWriteCallback = Promise (any chunk, WritableStreamDefaultController controller); 140 | callback UnderlyingSinkCloseCallback = Promise (); 141 | callback UnderlyingSinkAbortCallback = Promise (optional any reason); 142 | 143 | [Exposed=(Window,Worker,Worklet)] 144 | interface WritableStreamDefaultWriter { 145 | constructor(WritableStream stream); 146 | 147 | readonly attribute Promise closed; 148 | readonly attribute unrestricted double? desiredSize; 149 | readonly attribute Promise ready; 150 | 151 | Promise abort(optional any reason); 152 | Promise close(); 153 | undefined releaseLock(); 154 | Promise write(optional any chunk); 155 | }; 156 | 157 | [Exposed=(Window,Worker,Worklet)] 158 | interface WritableStreamDefaultController { 159 | undefined error(optional any e); 160 | }; 161 | 162 | [Exposed=(Window,Worker,Worklet), Transferable] 163 | interface TransformStream { 164 | constructor(optional object transformer, 165 | optional QueuingStrategy writableStrategy = {}, 166 | optional QueuingStrategy readableStrategy = {}); 167 | 168 | readonly attribute ReadableStream readable; 169 | readonly attribute WritableStream writable; 170 | }; 171 | 172 | dictionary Transformer { 173 | TransformerStartCallback start; 174 | TransformerTransformCallback transform; 175 | TransformerFlushCallback flush; 176 | any readableType; 177 | any writableType; 178 | }; 179 | 180 | callback TransformerStartCallback = any (TransformStreamDefaultController controller); 181 | callback TransformerFlushCallback = Promise (TransformStreamDefaultController controller); 182 | callback TransformerTransformCallback = Promise (any chunk, TransformStreamDefaultController controller); 183 | 184 | [Exposed=(Window,Worker,Worklet)] 185 | interface TransformStreamDefaultController { 186 | readonly attribute unrestricted double? desiredSize; 187 | 188 | undefined enqueue(optional any chunk); 189 | undefined error(optional any reason); 190 | undefined terminate(); 191 | }; 192 | 193 | dictionary QueuingStrategy { 194 | unrestricted double highWaterMark; 195 | QueuingStrategySize size; 196 | }; 197 | 198 | callback QueuingStrategySize = unrestricted double (optional any chunk); 199 | 200 | dictionary QueuingStrategyInit { 201 | required unrestricted double highWaterMark; 202 | }; 203 | 204 | [Exposed=(Window,Worker,Worklet)] 205 | interface ByteLengthQueuingStrategy { 206 | constructor(QueuingStrategyInit init); 207 | 208 | readonly attribute unrestricted double highWaterMark; 209 | readonly attribute Function size; 210 | }; 211 | 212 | [Exposed=(Window,Worker,Worklet)] 213 | interface CountQueuingStrategy { 214 | constructor(QueuingStrategyInit init); 215 | 216 | readonly attribute unrestricted double highWaterMark; 217 | readonly attribute Function size; 218 | }; 219 | 220 | interface mixin GenericTransformStream { 221 | readonly attribute ReadableStream readable; 222 | readonly attribute WritableStream writable; 223 | }; 224 | -------------------------------------------------------------------------------- /idl/uievents.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://www.w3.org/TR/uievents/#idl-index 2 | // Some stuff for MouseEvent was removed because it is handled 3 | // in cssomview.webidl 4 | 5 | [Constructor(DOMString type, optional UIEventInit eventInitDict), Exposed=Window] 6 | interface UIEvent : Event { 7 | readonly attribute Window? view; 8 | readonly attribute long detail; 9 | }; 10 | 11 | dictionary UIEventInit : EventInit { 12 | Window? view = null; 13 | long detail = 0; 14 | }; 15 | 16 | [Constructor(DOMString type, optional FocusEventInit eventInitDict), Exposed=Window] 17 | interface FocusEvent : UIEvent { 18 | readonly attribute EventTarget? relatedTarget; 19 | }; 20 | 21 | dictionary FocusEventInit : UIEventInit { 22 | EventTarget? relatedTarget = null; 23 | }; 24 | 25 | [Constructor(DOMString type, optional MouseEventInit eventInitDict), Exposed=Window] 26 | interface MouseEvent : UIEvent { 27 | readonly attribute boolean ctrlKey; 28 | readonly attribute boolean shiftKey; 29 | readonly attribute boolean altKey; 30 | readonly attribute boolean metaKey; 31 | 32 | readonly attribute short button; 33 | readonly attribute unsigned short buttons; 34 | 35 | readonly attribute EventTarget? relatedTarget; 36 | 37 | boolean getModifierState(DOMString keyArg); 38 | }; 39 | 40 | dictionary MouseEventInit : EventModifierInit { 41 | short button = 0; 42 | unsigned short buttons = 0; 43 | EventTarget? relatedTarget = null; 44 | }; 45 | 46 | dictionary EventModifierInit : UIEventInit { 47 | boolean ctrlKey = false; 48 | boolean shiftKey = false; 49 | boolean altKey = false; 50 | boolean metaKey = false; 51 | 52 | boolean modifierAltGraph = false; 53 | boolean modifierCapsLock = false; 54 | boolean modifierFn = false; 55 | boolean modifierFnLock = false; 56 | boolean modifierHyper = false; 57 | boolean modifierNumLock = false; 58 | boolean modifierScrollLock = false; 59 | boolean modifierSuper = false; 60 | boolean modifierSymbol = false; 61 | boolean modifierSymbolLock = false; 62 | }; 63 | 64 | [Constructor(DOMString type, optional WheelEventInit eventInitDict), Exposed=Window] 65 | interface WheelEvent : MouseEvent { 66 | // DeltaModeCode 67 | const unsigned long DOM_DELTA_PIXEL = 0x00; 68 | const unsigned long DOM_DELTA_LINE = 0x01; 69 | const unsigned long DOM_DELTA_PAGE = 0x02; 70 | 71 | readonly attribute double deltaX; 72 | readonly attribute double deltaY; 73 | readonly attribute double deltaZ; 74 | readonly attribute unsigned long deltaMode; 75 | }; 76 | 77 | dictionary WheelEventInit : MouseEventInit { 78 | double deltaX = 0.0; 79 | double deltaY = 0.0; 80 | double deltaZ = 0.0; 81 | unsigned long deltaMode = 0; 82 | }; 83 | 84 | [Constructor(DOMString type, optional InputEventInit eventInitDict), Exposed=Window] 85 | interface InputEvent : UIEvent { 86 | readonly attribute DOMString? data; 87 | readonly attribute boolean isComposing; 88 | readonly attribute DOMString inputType; 89 | }; 90 | 91 | dictionary InputEventInit : UIEventInit { 92 | DOMString? data = ""; 93 | boolean isComposing = false; 94 | DOMString inputType = ""; 95 | }; 96 | 97 | [Constructor(DOMString type, optional KeyboardEventInit eventInitDict), Exposed=Window] 98 | interface KeyboardEvent : UIEvent { 99 | // KeyLocationCode 100 | const unsigned long DOM_KEY_LOCATION_STANDARD = 0x00; 101 | const unsigned long DOM_KEY_LOCATION_LEFT = 0x01; 102 | const unsigned long DOM_KEY_LOCATION_RIGHT = 0x02; 103 | const unsigned long DOM_KEY_LOCATION_NUMPAD = 0x03; 104 | 105 | readonly attribute DOMString key; 106 | readonly attribute DOMString code; 107 | readonly attribute unsigned long location; 108 | 109 | readonly attribute boolean ctrlKey; 110 | readonly attribute boolean shiftKey; 111 | readonly attribute boolean altKey; 112 | readonly attribute boolean metaKey; 113 | 114 | readonly attribute boolean repeat; 115 | readonly attribute boolean isComposing; 116 | 117 | boolean getModifierState(DOMString keyArg); 118 | }; 119 | 120 | dictionary KeyboardEventInit : EventModifierInit { 121 | DOMString key = ""; 122 | DOMString code = ""; 123 | unsigned long location = 0; 124 | boolean repeat = false; 125 | boolean isComposing = false; 126 | }; 127 | 128 | [Constructor(DOMString type, optional CompositionEventInit eventInitDict), Exposed=Window] 129 | interface CompositionEvent : UIEvent { 130 | readonly attribute DOMString data; 131 | }; 132 | 133 | dictionary CompositionEventInit : UIEventInit { 134 | DOMString data = ""; 135 | }; 136 | 137 | partial interface UIEvent { 138 | // The following support legacy user agents 139 | readonly attribute unsigned long which; 140 | }; 141 | 142 | partial interface KeyboardEvent { 143 | // The following support legacy user agents 144 | readonly attribute unsigned long charCode; 145 | readonly attribute unsigned long keyCode; 146 | }; 147 | -------------------------------------------------------------------------------- /idl/url.webidl: -------------------------------------------------------------------------------- 1 | [Exposed=(Window,Worker), 2 | LegacyWindowAlias=webkitURL] 3 | interface URL { 4 | constructor(USVString url, optional USVString base); 5 | 6 | stringifier attribute USVString href; 7 | readonly attribute USVString origin; 8 | attribute USVString protocol; 9 | attribute USVString username; 10 | attribute USVString password; 11 | attribute USVString host; 12 | attribute USVString hostname; 13 | attribute USVString port; 14 | attribute USVString pathname; 15 | attribute USVString search; 16 | [SameObject] readonly attribute URLSearchParams searchParams; 17 | attribute USVString hash; 18 | 19 | USVString toJSON(); 20 | }; 21 | 22 | [Exposed=(Window,Worker)] 23 | interface URLSearchParams { 24 | constructor(optional (sequence> or record or USVString) init = ""); 25 | 26 | undefined append(USVString name, USVString value); 27 | undefined delete(USVString name); 28 | USVString? get(USVString name); 29 | sequence getAll(USVString name); 30 | boolean has(USVString name); 31 | undefined set(USVString name, USVString value); 32 | 33 | undefined sort(); 34 | 35 | iterable; 36 | stringifier; 37 | }; 38 | -------------------------------------------------------------------------------- /idl/visibility.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://www.w3.org/TR/page-visibility 2 | 3 | enum VisibilityState { 4 | "hidden", 5 | "visible" 6 | }; 7 | 8 | partial interface Document { 9 | readonly attribute boolean hidden; 10 | readonly attribute VisibilityState visibilityState; 11 | attribute EventHandler onvisibilitychange; 12 | }; 13 | -------------------------------------------------------------------------------- /idl/webidl.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://heycam.github.io/webidl/ 2 | 3 | typedef (Int8Array or Int16Array or Int32Array or 4 | Uint8Array or Uint16Array or Uint32Array or Uint8ClampedArray or 5 | Float32Array or Float64Array or DataView) ArrayBufferView; 6 | 7 | typedef (ArrayBufferView or ArrayBuffer) BufferSource; 8 | 9 | [Exposed=(Window,Worker), 10 | Serializable] 11 | interface DOMException { // but see below note about ECMAScript binding 12 | constructor(optional DOMString message 13 | = "", optional DOMString name 14 | = "Error"); 15 | readonly attribute DOMString name; 16 | readonly attribute DOMString message; 17 | readonly attribute unsigned short code; 18 | 19 | const unsigned short INDEX_SIZE_ERR = 1; 20 | const unsigned short DOMSTRING_SIZE_ERR 21 | = 2; 22 | const unsigned short HIERARCHY_REQUEST_ERR = 3; 23 | const unsigned short WRONG_DOCUMENT_ERR = 4; 24 | const unsigned short INVALID_CHARACTER_ERR = 5; 25 | const unsigned short NO_DATA_ALLOWED_ERR 26 | = 6; 27 | const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7; 28 | const unsigned short NOT_FOUND_ERR = 8; 29 | const unsigned short NOT_SUPPORTED_ERR = 9; 30 | const unsigned short INUSE_ATTRIBUTE_ERR = 10; 31 | const unsigned short INVALID_STATE_ERR = 11; 32 | const unsigned short SYNTAX_ERR = 12; 33 | const unsigned short INVALID_MODIFICATION_ERR = 13; 34 | const unsigned short NAMESPACE_ERR = 14; 35 | const unsigned short INVALID_ACCESS_ERR = 15; 36 | const unsigned short VALIDATION_ERR 37 | = 16; 38 | const unsigned short TYPE_MISMATCH_ERR = 17; 39 | const unsigned short SECURITY_ERR = 18; 40 | const unsigned short NETWORK_ERR = 19; 41 | const unsigned short ABORT_ERR = 20; 42 | const unsigned short URL_MISMATCH_ERR = 21; 43 | const unsigned short QUOTA_EXCEEDED_ERR = 22; 44 | const unsigned short TIMEOUT_ERR = 23; 45 | const unsigned short INVALID_NODE_TYPE_ERR = 24; 46 | const unsigned short DATA_CLONE_ERR = 25; 47 | }; 48 | 49 | typedef unsigned long long DOMTimeStamp; 50 | 51 | callback VoidFunction = undefined (); 52 | 53 | callback Function = any (any... arguments); 54 | -------------------------------------------------------------------------------- /idl/xhr.webidl: -------------------------------------------------------------------------------- 1 | // Extracted from https://xhr.spec.whatwg.org/ 2 | 3 | [Exposed=(Window,DedicatedWorker,SharedWorker)] 4 | interface XMLHttpRequestEventTarget : EventTarget { 5 | // event handlers 6 | attribute EventHandler onloadstart; 7 | attribute EventHandler onprogress; 8 | attribute EventHandler onabort; 9 | attribute EventHandler onerror; 10 | attribute EventHandler onload; 11 | attribute EventHandler ontimeout; 12 | attribute EventHandler onloadend; 13 | }; 14 | 15 | [Exposed=(Window,DedicatedWorker,SharedWorker)] 16 | interface XMLHttpRequestUpload : XMLHttpRequestEventTarget { 17 | }; 18 | 19 | enum XMLHttpRequestResponseType { 20 | "", 21 | "arraybuffer", 22 | "blob", 23 | "document", 24 | "json", 25 | "text" 26 | }; 27 | 28 | [Exposed=(Window,DedicatedWorker,SharedWorker)] 29 | interface XMLHttpRequest : XMLHttpRequestEventTarget { 30 | constructor(); 31 | 32 | // event handler 33 | attribute EventHandler onreadystatechange; 34 | 35 | // states 36 | const unsigned short UNSENT = 0; 37 | const unsigned short OPENED = 1; 38 | const unsigned short HEADERS_RECEIVED = 2; 39 | const unsigned short LOADING = 3; 40 | const unsigned short DONE = 4; 41 | readonly attribute unsigned short readyState; 42 | 43 | // request 44 | undefined open(ByteString method, USVString url); 45 | undefined open(ByteString method, USVString url, boolean async, optional USVString? username = null, optional USVString? password = null); 46 | undefined setRequestHeader(ByteString name, ByteString value); 47 | attribute unsigned long timeout; 48 | attribute boolean withCredentials; 49 | [SameObject] readonly attribute XMLHttpRequestUpload upload; 50 | undefined send(optional (Document or XMLHttpRequestBodyInit)? body = null); 51 | undefined abort(); 52 | 53 | // response 54 | readonly attribute USVString responseURL; 55 | readonly attribute unsigned short status; 56 | readonly attribute ByteString statusText; 57 | ByteString? getResponseHeader(ByteString name); 58 | ByteString getAllResponseHeaders(); 59 | undefined overrideMimeType(DOMString mime); 60 | attribute XMLHttpRequestResponseType responseType; 61 | readonly attribute any response; 62 | readonly attribute USVString responseText; 63 | [Exposed=Window] readonly attribute Document? responseXML; 64 | }; 65 | 66 | typedef (File or USVString) FormDataEntryValue; 67 | 68 | [Exposed=(Window,Worker)] 69 | interface FormData { 70 | constructor(optional HTMLFormElement form); 71 | 72 | undefined append(USVString name, USVString value); 73 | undefined append(USVString name, Blob blobValue, optional USVString filename); 74 | undefined delete(USVString name); 75 | FormDataEntryValue? get(USVString name); 76 | sequence getAll(USVString name); 77 | boolean has(USVString name); 78 | undefined set(USVString name, USVString value); 79 | undefined set(USVString name, Blob blobValue, optional USVString filename); 80 | iterable; 81 | }; 82 | 83 | [Exposed=(Window,Worker)] 84 | interface ProgressEvent : Event { 85 | constructor(DOMString type, optional ProgressEventInit eventInitDict = {}); 86 | 87 | readonly attribute boolean lengthComputable; 88 | readonly attribute unsigned long long loaded; 89 | readonly attribute unsigned long long total; 90 | }; 91 | 92 | dictionary ProgressEventInit : EventInit { 93 | boolean lengthComputable = false; 94 | unsigned long long loaded = 0; 95 | unsigned long long total = 0; 96 | }; 97 | -------------------------------------------------------------------------------- /pack.toml: -------------------------------------------------------------------------------- 1 | [custom.all.webidl] 2 | type = "local" 3 | path = "." 4 | ipkg = "webidl.ipkg" 5 | 6 | [custom.all.parser] 7 | type = "git" 8 | url = "https://github.com/stefan-hoeck/idris2-parser" 9 | commit = "latest:main" 10 | ipkg = "parser.ipkg" 11 | 12 | [custom.all.parser-webidl] 13 | type = "git" 14 | url = "https://github.com/stefan-hoeck/idris2-parser" 15 | commit = "latest:main" 16 | ipkg = "webidl/parser-webidl.ipkg" 17 | -------------------------------------------------------------------------------- /spec/attributes: -------------------------------------------------------------------------------- 1 | AllowShared 2 | CEReactions 3 | Clamp 4 | Constructor (DOMString type , optional AnimationPlaybackEventInit eventInitDict ) 5 | Constructor (DOMString type , optional CompositionEventInit eventInitDict ) 6 | Constructor (DOMString type , optional FocusEventInit eventInitDict ) 7 | Constructor (DOMString type , optional InputEventInit eventInitDict ) 8 | Constructor (DOMString type , optional KeyboardEventInit eventInitDict ) 9 | Constructor (DOMString type , optional MouseEventInit eventInitDict ) 10 | Constructor (DOMString type , optional UIEventInit eventInitDict ) 11 | Constructor (DOMString type , optional WheelEventInit eventInitDict ) 12 | Constructor ((Element or CSSPseudoElement ) ? target , object ? keyframes , optional (unrestricted double or KeyframeEffectOptions ) options ) 13 | Constructor (KeyframeEffect source ) 14 | Constructor (optional AnimationEffect ? effect = null , optional AnimationTimeline ? timeline ) 15 | Constructor (optional DocumentTimelineOptions options ) 16 | Constructor (optional DOMPointInit p1 , optional DOMPointInit p2 , optional DOMPointInit p3 , optional DOMPointInit p4 ) 17 | Constructor (optional (DOMString or sequence < unrestricted double > ) init ) 18 | Constructor (optional unrestricted double x = 00 , optional unrestricted double y = 00 , optional unrestricted double width = 00 , optional unrestricted double height = 00 ) 19 | Constructor (optional unrestricted double x = 00 , optional unrestricted double y = 00 , optional unrestricted double z = 00 , optional unrestricted double w = 1 ) 20 | Default 21 | EnforceRange 22 | Exposed = DedicatedWorker 23 | Exposed = (DedicatedWorker , SharedWorker ) 24 | Exposed = ServiceWorker 25 | Exposed = SharedWorker 26 | Exposed = Window 27 | Exposed = (Window , DedicatedWorker , SharedWorker ) 28 | Exposed = (Window , Worker ) 29 | Exposed = (Window , Worker , AudioWorklet ) 30 | Exposed = (Window , Worker , Worklet ) 31 | Exposed = Worker 32 | Exposed = Worklet 33 | Global = Window 34 | Global = (Worker , DedicatedWorker ) 35 | Global = (Worker , ServiceWorker ) 36 | Global = (Worker , SharedWorker ) 37 | HTMLConstructor 38 | LegacyFactoryFunction = Audio (optional DOMString src ) 39 | LegacyFactoryFunction = Image (optional unsigned long width , optional unsigned long height ) 40 | LegacyFactoryFunction = Option (optional DOMString text = "" , optional DOMString value , optional boolean defaultSelected = false , optional boolean selected = false ) 41 | LegacyLenientThis 42 | LegacyNullToEmptyString 43 | LegacyOverrideBuiltIns 44 | LegacyTreatNonObjectAsNull 45 | LegacyUnenumerableNamedProperties 46 | LegacyUnforgeable 47 | LegacyWindowAlias = (SVGMatrix , WebKitCSSMatrix ) 48 | LegacyWindowAlias = SVGPoint 49 | LegacyWindowAlias = SVGRect 50 | LegacyWindowAlias = webkitURL 51 | NewObject 52 | PutForwards = cssText 53 | PutForwards = href 54 | PutForwards = mediaText 55 | PutForwards = value 56 | Replaceable 57 | SameObject 58 | SecureContext 59 | Serializable 60 | Transferable 61 | Unscopable 62 | WebGLHandlesContextLoss 63 | -------------------------------------------------------------------------------- /spec/grammar: -------------------------------------------------------------------------------- 1 | [done] Tokens 2 | 3 | [done] integer = /-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)/ 4 | [done] decimal = /-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/ 5 | [done] identifier = /[_-]?[A-Za-z][0-9A-Z_a-z-]*/ 6 | [done] string = /"[^"]*"/ 7 | [done] whitespace = /[\t\n\r ]+/ 8 | [done] comment = /\/\/.*|\/\*(.|\n)*?\*\// 9 | [done] other = /[^\t\n\r 0-9A-Za-z]/ 10 | 11 | Grammar 12 | [done] Definitions :: 13 | ExtendedAttributeList Definition Definitions 14 | ε 15 | 16 | [done] Definition :: 17 | CallbackOrInterfaceOrMixin 18 | Namespace 19 | Partial 20 | Dictionary 21 | Enum 22 | Typedef 23 | IncludesStatement 24 | 25 | [done] ArgumentNameKeyword :: 26 | async 27 | attribute 28 | callback 29 | const 30 | constructor 31 | deleter 32 | dictionary 33 | enum 34 | getter 35 | includes 36 | inherit 37 | interface 38 | iterable 39 | maplike 40 | mixin 41 | namespace 42 | partial 43 | readonly 44 | required 45 | setlike 46 | setter 47 | static 48 | stringifier 49 | typedef 50 | unrestricted 51 | 52 | [done] CallbackOrInterfaceOrMixin :: 53 | callback CallbackRestOrInterface 54 | interface InterfaceOrMixin 55 | 56 | [done] InterfaceOrMixin :: 57 | InterfaceRest 58 | MixinRest 59 | 60 | [done] InterfaceRest :: 61 | identifier Inheritance { InterfaceMembers } ; 62 | 63 | [done] Partial :: 64 | partial PartialDefinition 65 | 66 | [done] PartialDefinition :: 67 | interface PartialInterfaceOrPartialMixin 68 | PartialDictionary 69 | Namespace 70 | 71 | [done] PartialInterfaceOrPartialMixin :: 72 | PartialInterfaceRest 73 | MixinRest 74 | 75 | [done] PartialInterfaceRest :: 76 | identifier { PartialInterfaceMembers } ; 77 | 78 | [done] InterfaceMembers :: 79 | ExtendedAttributeList InterfaceMember InterfaceMembers 80 | ε 81 | 82 | [done] InterfaceMember :: 83 | PartialInterfaceMember 84 | Constructor 85 | 86 | [done] PartialInterfaceMembers :: 87 | ExtendedAttributeList PartialInterfaceMember PartialInterfaceMembers 88 | ε 89 | 90 | [done] PartialInterfaceMember :: 91 | Const 92 | Operation 93 | Stringifier 94 | StaticMember 95 | Iterable 96 | AsyncIterable 97 | ReadOnlyMember 98 | ReadWriteAttribute 99 | ReadWriteMaplike 100 | ReadWriteSetlike 101 | InheritAttribute 102 | 103 | [done] Inheritance :: 104 | : identifier 105 | ε 106 | 107 | [done] MixinRest :: 108 | mixin identifier { MixinMembers } ; 109 | 110 | [done] MixinMembers :: 111 | ExtendedAttributeList MixinMember MixinMembers 112 | ε 113 | 114 | [done] MixinMember :: 115 | Const 116 | RegularOperation 117 | Stringifier 118 | OptionalReadOnly AttributeRest 119 | 120 | [done] IncludesStatement :: 121 | identifier includes identifier ; 122 | 123 | [done] CallbackRestOrInterface :: 124 | CallbackRest 125 | interface identifier { CallbackInterfaceMembers } ; 126 | 127 | [done] CallbackInterfaceMembers :: 128 | ExtendedAttributeList CallbackInterfaceMember CallbackInterfaceMembers 129 | ε 130 | 131 | [done] CallbackInterfaceMember :: 132 | Const 133 | RegularOperation 134 | 135 | [done] Const :: 136 | const ConstType identifier = ConstValue ; 137 | 138 | [done] ConstValue :: 139 | BooleanLiteral 140 | FloatLiteral 141 | integer 142 | 143 | [done] BooleanLiteral :: 144 | true 145 | false 146 | 147 | [done] FloatLiteral :: 148 | decimal 149 | -Infinity 150 | Infinity 151 | NaN 152 | 153 | [done] ConstType :: 154 | PrimitiveType 155 | identifier 156 | 157 | [done] ReadOnlyMember :: 158 | readonly ReadOnlyMemberRest 159 | 160 | [done] ReadOnlyMemberRest :: 161 | AttributeRest 162 | MaplikeRest 163 | SetlikeRest 164 | 165 | [done] ReadWriteAttribute :: 166 | AttributeRest 167 | 168 | [done] InheritAttribute :: 169 | inherit AttributeRest 170 | 171 | [done] AttributeRest :: 172 | attribute TypeWithExtendedAttributes AttributeName ; 173 | 174 | [done] AttributeName :: 175 | AttributeNameKeyword 176 | identifier 177 | 178 | [done] AttributeNameKeyword :: 179 | async 180 | required 181 | 182 | [done] OptionalReadOnly :: 183 | readonly 184 | ε 185 | 186 | [done (part of Default)] DefaultValue :: 187 | ConstValue 188 | string 189 | [ ] 190 | { } 191 | null 192 | 193 | [done] Operation :: 194 | RegularOperation 195 | SpecialOperation 196 | 197 | [done] RegularOperation :: 198 | Type OperationRest 199 | 200 | [done] SpecialOperation :: 201 | Special RegularOperation 202 | 203 | [done] Special :: 204 | getter 205 | setter 206 | deleter 207 | 208 | [done] OperationRest :: 209 | OptionalOperationName ( ArgumentList ) ; 210 | 211 | [done] OptionalOperationName :: 212 | OperationName 213 | ε 214 | 215 | [done] OperationName :: 216 | OperationNameKeyword 217 | identifier 218 | 219 | [done] OperationNameKeyword :: 220 | includes 221 | 222 | [done] ArgumentList :: 223 | Argument Arguments 224 | ε 225 | 226 | [done (part of ArgumentList)] Arguments :: 227 | , Argument Arguments 228 | ε 229 | 230 | [done (part of ArgumentList)] Argument :: 231 | ExtendedAttributeList ArgumentRest 232 | 233 | [done] ArgumentRest :: 234 | optional TypeWithExtendedAttributes ArgumentName Default 235 | Type Ellipsis ArgumentName 236 | 237 | [done] ArgumentName :: 238 | ArgumentNameKeyword 239 | identifier 240 | 241 | [done] Ellipsis :: 242 | ... 243 | ε 244 | 245 | [done] Constructor :: 246 | constructor ( ArgumentList ) ; 247 | 248 | [done] Stringifier :: 249 | stringifier StringifierRest 250 | 251 | [done] StringifierRest :: 252 | OptionalReadOnly AttributeRest 253 | RegularOperation 254 | ; 255 | 256 | [done] StaticMember :: 257 | static StaticMemberRest 258 | 259 | [done] StaticMemberRest :: 260 | OptionalReadOnly AttributeRest 261 | RegularOperation 262 | 263 | [done] Iterable :: 264 | iterable < TypeWithExtendedAttributes OptionalType > ; 265 | 266 | [done] OptionalType :: 267 | , TypeWithExtendedAttributes 268 | ε 269 | 270 | [done] AsyncIterable :: 271 | async iterable < TypeWithExtendedAttributes OptionalType > OptionalArgumentList ; 272 | 273 | [done] OptionalArgumentList :: 274 | ( ArgumentList ) 275 | ε 276 | 277 | [done] ReadWriteMaplike :: 278 | MaplikeRest 279 | 280 | [done] MaplikeRest :: 281 | maplike < TypeWithExtendedAttributes , TypeWithExtendedAttributes > ; 282 | 283 | [done] ReadWriteSetlike :: 284 | SetlikeRest 285 | 286 | [done] SetlikeRest :: 287 | setlike < TypeWithExtendedAttributes > ; 288 | 289 | [done] Namespace :: 290 | namespace identifier { NamespaceMembers } ; 291 | 292 | [done] NamespaceMembers :: 293 | ExtendedAttributeList NamespaceMember NamespaceMembers 294 | ε 295 | 296 | [done] NamespaceMember :: 297 | RegularOperation 298 | readonly AttributeRest 299 | 300 | [done] Dictionary :: 301 | dictionary identifier Inheritance { DictionaryMembers } ; 302 | 303 | [done] DictionaryMembers :: 304 | DictionaryMember DictionaryMembers 305 | ε 306 | 307 | [done] DictionaryMember :: 308 | ExtendedAttributeList DictionaryMemberRest 309 | 310 | [done] DictionaryMemberRest :: 311 | required TypeWithExtendedAttributes identifier ; 312 | Type identifier Default ; 313 | 314 | [done (part of PartialDefinition)] PartialDictionary :: 315 | dictionary identifier { DictionaryMembers } ; 316 | 317 | [done] Default :: 318 | = DefaultValue 319 | ε 320 | 321 | [done] Enum :: 322 | enum identifier { EnumValueList } ; 323 | 324 | [done (part of Enum)] EnumValueList :: 325 | string EnumValueListComma 326 | 327 | [done (part of Enum)] EnumValueListComma :: 328 | , EnumValueListString 329 | ε 330 | 331 | [done (part of Enum)] EnumValueListString :: 332 | string EnumValueListComma 333 | ε 334 | 335 | [done] CallbackRest :: 336 | identifier = Type ( ArgumentList ) ; 337 | 338 | [done] Typedef :: 339 | typedef TypeWithExtendedAttributes identifier ; 340 | 341 | [done] Type :: 342 | SingleType 343 | UnionType Null 344 | 345 | [done] TypeWithExtendedAttributes :: 346 | ExtendedAttributeList Type 347 | 348 | [done (part of Type)] SingleType :: 349 | DistinguishableType 350 | any 351 | PromiseType 352 | 353 | [done] UnionType :: 354 | ( UnionMemberType or UnionMemberType UnionMemberTypes ) 355 | 356 | [done] UnionMemberType :: 357 | ExtendedAttributeList DistinguishableType 358 | UnionType Null 359 | 360 | [done (part of UnionType)] UnionMemberTypes :: 361 | or UnionMemberType UnionMemberTypes 362 | ε 363 | 364 | [done] DistinguishableType :: 365 | PrimitiveType Null 366 | StringType Null 367 | identifier Null 368 | sequence < TypeWithExtendedAttributes > Null 369 | object Null 370 | symbol Null 371 | BufferRelatedType Null 372 | FrozenArray < TypeWithExtendedAttributes > Null 373 | ObservableArray < TypeWithExtendedAttributes > Null 374 | RecordType Null 375 | 376 | [done] PrimitiveType :: 377 | UnsignedIntegerType 378 | UnrestrictedFloatType 379 | undefined 380 | boolean 381 | byte 382 | octet 383 | bigint 384 | 385 | [done] UnrestrictedFloatType :: 386 | unrestricted FloatType 387 | FloatType 388 | 389 | [done] FloatType :: 390 | float 391 | double 392 | 393 | [done] UnsignedIntegerType :: 394 | unsigned IntegerType 395 | IntegerType 396 | 397 | [done] IntegerType :: 398 | short 399 | long OptionalLong 400 | 401 | [done] OptionalLong :: 402 | long 403 | ε 404 | 405 | [done] StringType :: 406 | ByteString 407 | DOMString 408 | USVString 409 | 410 | [done] PromiseType :: 411 | Promise < Type > 412 | 413 | [done] RecordType :: 414 | record < StringType , TypeWithExtendedAttributes > 415 | 416 | [done] Null :: 417 | ? 418 | ε 419 | 420 | [done] BufferRelatedType :: 421 | ArrayBuffer 422 | DataView 423 | Int8Array 424 | Int16Array 425 | Int32Array 426 | Uint8Array 427 | Uint16Array 428 | Uint32Array 429 | Uint8ClampedArray 430 | Float32Array 431 | Float64Array 432 | 433 | [done] ExtendedAttributeList :: 434 | [ ExtendedAttribute ExtendedAttributes ] 435 | ε 436 | 437 | [done] ExtendedAttributes :: 438 | , ExtendedAttribute ExtendedAttributes 439 | ε 440 | 441 | [done] ExtendedAttribute :: 442 | ( ExtendedAttributeInner ) ExtendedAttributeRest 443 | [ ExtendedAttributeInner ] ExtendedAttributeRest 444 | { ExtendedAttributeInner } ExtendedAttributeRest 445 | Other ExtendedAttributeRest 446 | 447 | [done] ExtendedAttributeRest :: 448 | ExtendedAttribute 449 | ε 450 | 451 | [done] ExtendedAttributeInner :: 452 | ( ExtendedAttributeInner ) ExtendedAttributeInner 453 | [ ExtendedAttributeInner ] ExtendedAttributeInner 454 | { ExtendedAttributeInner } ExtendedAttributeInner 455 | OtherOrComma ExtendedAttributeInner 456 | ε 457 | 458 | [done] Other :: 459 | [done] integer 460 | [done] decimal 461 | [done] identifier 462 | [done] string 463 | [done] other 464 | [done] - 465 | [done] -Infinity 466 | [done] . 467 | [done] ... 468 | [done] : 469 | [done] ; 470 | [done] < 471 | [done] = 472 | [done] > 473 | [done] ? 474 | ByteString 475 | DOMString 476 | FrozenArray 477 | [done] Infinity 478 | [done] NaN 479 | ObservableArray 480 | Promise 481 | USVString 482 | any 483 | bigint 484 | boolean 485 | byte 486 | double 487 | false 488 | float 489 | long 490 | null 491 | object 492 | octet 493 | or 494 | optional 495 | record 496 | sequence 497 | short 498 | symbol 499 | true 500 | unsigned 501 | undefined 502 | ArgumentNameKeyword 503 | BufferRelatedType 504 | 505 | [done] OtherOrComma :: 506 | Other 507 | , 508 | 509 | [done] IdentifierList :: 510 | identifier Identifiers 511 | 512 | [done, part of IdentifierList] Identifiers :: 513 | , identifier Identifiers 514 | ε 515 | -------------------------------------------------------------------------------- /src/Main.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | import Control.Monad.Either 4 | import Data.List.Elem 5 | import Data.SOP 6 | import Data.String 7 | import System 8 | import System.GetOpts 9 | import System.File 10 | import Text.WebIDL.Codegen as Codegen 11 | import Text.WebIDL.Encoder 12 | import Text.WebIDL.Types 13 | import Text.WebIDL.Parser 14 | import Text.PrettyPrint.Bernardy 15 | 16 | %default total 17 | 18 | -------------------------------------------------------------------------------- 19 | -- Command line options 20 | -------------------------------------------------------------------------------- 21 | 22 | record Config where 23 | constructor MkConfig 24 | outDir : String 25 | maxInheritance : Nat 26 | files : List String 27 | 28 | init : List String -> Config 29 | init = MkConfig "../dom/src" 100 30 | 31 | setOutDir : String -> Config -> Either (List String) Config 32 | setOutDir s = Right . { outDir := s } 33 | 34 | descs : List $ OptDescr (Config -> Either (List String) Config) 35 | descs = 36 | [ MkOpt 37 | ['o'] 38 | ["outDir"] 39 | (ReqArg setOutDir "") 40 | "output directory" 41 | ] 42 | 43 | applyArgs : List String -> Either (List String) Config 44 | applyArgs args = 45 | case getOpt RequireOrder descs args of 46 | MkResult opts n [] [] => foldl (>>=) (Right $ init n) opts 47 | MkResult _ _ u e => Left $ map unknown u ++ e 48 | 49 | where 50 | unknown : String -> String 51 | unknown = ("Unknown option: " ++) 52 | 53 | -------------------------------------------------------------------------------- 54 | -- Codegen 55 | -------------------------------------------------------------------------------- 56 | 57 | 0 Prog : Type -> Type 58 | Prog = EitherT String IO 59 | 60 | toProgWith : (a -> String) -> IO (Either a b) -> Prog b 61 | toProgWith f io = MkEitherT $ map (mapFst f) io 62 | 63 | toProg : Show a => IO (Either a b) -> Prog b 64 | toProg = toProgWith show 65 | 66 | runProg : Prog () -> IO () 67 | runProg (MkEitherT p) = do 68 | Right _ <- p | Left e => putStrLn ("Error: " ++ e) 69 | pure () 70 | 71 | fromCodegen : Codegen a -> Prog a 72 | fromCodegen = toProgWith (fastUnlines . map err) . pure 73 | where 74 | err : CodegenErr -> String 75 | err (CBInterfaceInvalidOps x y k) = 76 | "Invalid number of callback operations in \{x.domain}: \{y.value} (\{show k} operations)" 77 | err (RegularOpWithoutName x y) = 78 | "Unnamed regular operation in \{x.domain}: \{y.value}" 79 | err (InvalidGetter x y) = 80 | "Invalid getter in \{x.domain}: \{y.value}" 81 | err (InvalidSetter x y) = 82 | "Invalid setter in \{x.domain}: \{y.value}" 83 | err (UnresolvedAlias x y) = 84 | "Unresolved alias in \{x.domain}: \{y.value}" 85 | err (AnyInUnion x) = "\"Any\" type in a union type in \{x.domain}" 86 | err (PromiseInUnion x) = "\"Promise\" type in a union type in \{x.domain}" 87 | err (NullableAny x) = "Nullable \"Any\" type in \{x.domain}" 88 | err (NullablePromise x) = "Nullable \"Promise\" type in \{x.domain}" 89 | err (InvalidConstType x) = "Invalid constant type in \{x.domain}" 90 | 91 | writeDoc : String -> String -> Prog () 92 | writeDoc f doc = toProg $ writeFile f doc 93 | 94 | covering 95 | loadDef : String -> Prog (String,PartsAndDefs) 96 | loadDef f = 97 | let mn := 98 | moduleName 99 | . head 100 | . split ('.' ==) 101 | . last 102 | $ split ('/' ==) f 103 | 104 | in do 105 | s <- toProg (readFile f) 106 | d <- toProg (pure $ parseIdl partsAndDefs s) 107 | pure (mn,d) 108 | 109 | typesGen : Config -> List CGDomain -> Prog () 110 | typesGen c ds = 111 | let typesFile := c.outDir ++ "/Web/Internal/Types.idr" 112 | in writeDoc typesFile (typedefs ds) 113 | 114 | codegen : Config -> CGDomain -> Prog () 115 | codegen c d = 116 | let typesFile := c.outDir ++ "/Web/Internal/" ++ d.name ++ "Types.idr" 117 | primFile := c.outDir ++ "/Web/Internal/" ++ d.name ++ "Prim.idr" 118 | apiFile := c.outDir ++ "/Web/Raw/" ++ d.name ++ ".idr" 119 | 120 | in do 121 | writeDoc typesFile (types d) 122 | writeDoc primFile (primitives d) 123 | writeDoc apiFile (definitions d) 124 | 125 | logAttributes : HasAttributes a => a -> Prog () 126 | logAttributes = traverse_ (putStrLn . extAttribute) . attributes 127 | 128 | -------------------------------------------------------------------------------- 129 | -- Main Function 130 | -------------------------------------------------------------------------------- 131 | 132 | covering 133 | run : List String -> Prog () 134 | run args = do 135 | config <- toProg (pure $ applyArgs args) 136 | ds <- toDomains <$> traverse loadDef config.files 137 | 138 | let e := env config.maxInheritance ds 139 | 140 | doms <- fromCodegen (traverse (domain e) ds) 141 | 142 | -- logAttributes ds 143 | traverse_ (codegen config) doms 144 | typesGen config doms 145 | 146 | covering 147 | main : IO () 148 | main = do 149 | (pn :: args) <- getArgs | Nil => die "Missing executable name. Aborting..." 150 | runProg (run args) 151 | -------------------------------------------------------------------------------- /src/Text/WebIDL/Codegen.idr: -------------------------------------------------------------------------------- 1 | module Text.WebIDL.Codegen 2 | 3 | import public Data.SortedMap 4 | import public Text.WebIDL.Codegen.Rules as Codegen 5 | import public Text.WebIDL.Codegen.Definitions as Codegen 6 | -------------------------------------------------------------------------------- /src/Text/WebIDL/Codegen/Args.idr: -------------------------------------------------------------------------------- 1 | ||| We need at least three different code generators for 2 | ||| WebIDL types and arguments. When used in the FFI, they should 3 | ||| be mapped to external types and primitives. In API functions, 4 | ||| however, they should be mapped to types convenient for 5 | ||| users of the API. Same for return types, but there, the rules 6 | ||| about what is possible are different. 7 | ||| 8 | ||| Finally, types affect how we adjust values and return values 9 | ||| in function implementations. 10 | module Text.WebIDL.Codegen.Args 11 | 12 | import Data.List 13 | import Data.List1 14 | import Text.WebIDL.Codegen.Util 15 | import Text.WebIDL.Encoder as E 16 | 17 | %default total 18 | 19 | public export 20 | record PrettyArg (opts : LayoutOpts) where 21 | constructor MkPrettyArg 22 | name : ArgumentName 23 | doc : Doc opts 24 | 25 | export 26 | argIdent : PrettyArg opts -> IdrisIdent 27 | argIdent = fromString . value . name 28 | 29 | public export 30 | 0 PrettyArgs : (opts : LayoutOpts) -> Type 31 | PrettyArgs = List . PrettyArg 32 | 33 | -------------------------------------------------------------------------------- 34 | -- FFI 35 | -------------------------------------------------------------------------------- 36 | 37 | parameters {opts : LayoutOpts} 38 | 39 | nullableSimpleFFI : Prec -> Nullable SimpleType -> Doc opts 40 | 41 | nullableUnionFFI : Prec -> Nullable (List1 SimpleType) -> Doc opts 42 | 43 | simpleFFI : Prec -> SimpleType -> Doc opts 44 | 45 | simpleFFIs : Prec -> List SimpleType -> List (Doc opts) 46 | 47 | unionFFI : Prec -> List1 SimpleType -> Doc opts 48 | 49 | export 50 | ffi : Prec -> CGType -> Doc opts 51 | 52 | 53 | simpleFFI p Undef = line "Undefined" 54 | simpleFFI p Boolean = line "Boolean" 55 | simpleFFI p (Interface _ x) = line x.value 56 | simpleFFI p (Dictionary x) = line x.value 57 | simpleFFI p (Mixin x) = line x.value 58 | simpleFFI p (Primitive x) = line x 59 | simpleFFI p (Unchangeable x) = line x 60 | simpleFFI p (Enum x) = line "String" 61 | simpleFFI p (Array x) = prettyCon p "Array" [ffi App x] 62 | simpleFFI p (Record x y) = prettyCon p "Record" [line x, ffi App y] 63 | 64 | simpleFFIs p [] = [] 65 | simpleFFIs p (h::t) = simpleFFI p h :: simpleFFIs p t 66 | 67 | unionFFI p (h:::t) = 68 | prettyCon p "Union\{show . S $ length t}" 69 | (simpleFFI App h :: simpleFFIs App t) 70 | 71 | ffi p Any = "AnyPtr" 72 | ffi p (Promise x) = prettyCon p "Promise" [ffi App x] 73 | ffi p (Simple x) = nullableSimpleFFI p x 74 | ffi p (Union x) = nullableUnionFFI p x 75 | 76 | nullableSimpleFFI p (MaybeNull x) = prettyCon p "Nullable" [simpleFFI App x] 77 | nullableSimpleFFI p (NotNull x) = simpleFFI p x 78 | 79 | nullableUnionFFI p (MaybeNull x) = prettyCon p "Nullable" [unionFFI App x] 80 | nullableUnionFFI p (NotNull x) = unionFFI p x 81 | 82 | -------------------------------------------------------------------------------- 83 | -- API 84 | -------------------------------------------------------------------------------- 85 | 86 | 87 | simpleAPI : Maybe Nat -> Prec -> SimpleType -> Doc opts 88 | simpleAPI (Just k) _ (Dictionary _) = line "t\{show k}" 89 | simpleAPI (Just k) _ (Mixin _) = line "t\{show k}" 90 | simpleAPI (Just k) _ (Interface True _) = line "t\{show k}" 91 | simpleAPI Nothing _ (Dictionary x) = line x.value 92 | simpleAPI Nothing _ (Mixin x) = line x.value 93 | simpleAPI _ _ (Interface _ x) = line x.value 94 | simpleAPI _ _ Undef = line "Undefined" 95 | simpleAPI _ _ Boolean = line "Bool" 96 | simpleAPI _ _ (Primitive x) = line x 97 | simpleAPI _ _ (Unchangeable x) = line x 98 | simpleAPI _ _ (Enum x) = line x.value 99 | simpleAPI _ p (Array x) = prettyCon p "Array" [ffi App x] 100 | simpleAPI _ p (Record x y) = prettyCon p "Record" [line x, ffi App y] 101 | 102 | unionAPI : Prec -> List1 SimpleType -> Doc opts 103 | unionAPI p (h ::: t) = 104 | prettyCon p "HSum" [list $ map (simpleAPI Nothing Open) (h::t)] 105 | 106 | nullableAPI : (Prec -> a -> Doc opts) -> Prec -> Nullable a -> Doc opts 107 | nullableAPI f p (MaybeNull x) = prettyCon p "Maybe" [f App x] 108 | nullableAPI f p (NotNull x) = f p x 109 | 110 | api : Maybe Nat -> Prec -> CGType -> Doc opts 111 | api _ p Any = "Any" 112 | api _ p (Promise x) = prettyCon p "Promise" [ffi App x] 113 | api k p (Simple x) = nullableAPI (simpleAPI k) p x 114 | api _ p (Union x) = nullableAPI unionAPI p x 115 | 116 | -------------------------------------------------------------------------------- 117 | -- Return Types 118 | -------------------------------------------------------------------------------- 119 | 120 | export 121 | ret : Prec -> CGType -> Doc opts 122 | ret p (Union $ MaybeNull xs) = 123 | let u := 124 | if all SimpleType.safeCast xs 125 | then unionAPI App xs 126 | else unionFFI App xs 127 | 128 | in prettyCon p "Maybe" [u] 129 | 130 | ret p t@(Union $ NotNull xs) = 131 | if all SimpleType.safeCast xs then api Nothing p t else ffi p t 132 | 133 | ret p t = api Nothing p t 134 | 135 | returnTypeFFI' : (io : String) -> ReturnType -> Doc opts 136 | returnTypeFFI' io Undefined = line "\{io} ()" 137 | returnTypeFFI' io (Def t) = prettyCon Open io [ffi App t] 138 | returnTypeFFI' io (UndefOr t _) = 139 | prettyCon Open io [prettyCon App "UndefOr" [ffi App t]] 140 | 141 | returnTypeFFI : ReturnType -> Doc opts 142 | returnTypeFFI = returnTypeFFI' "PrimIO" 143 | 144 | returnTypeAPI : ReturnType -> Doc opts 145 | returnTypeAPI Undefined = line "JSIO ()" 146 | returnTypeAPI (Def t) = prettyCon Open "JSIO" [ret App t] 147 | returnTypeAPI (UndefOr t _) = 148 | prettyCon Open "JSIO" [prettyCon App "Optional" [ret App t]] 149 | 150 | export 151 | constTpe : CGConstType -> Doc opts 152 | constTpe = line . primitive 153 | 154 | -------------------------------------------------------------------------------- 155 | -- Default Arg 156 | -------------------------------------------------------------------------------- 157 | 158 | export 159 | prettyConst : ConstValue -> Doc opts 160 | prettyConst (B x) = pretty x 161 | prettyConst (F x) = line "\{x}" 162 | prettyConst (I x) = line "\{x}" 163 | 164 | defltS : SimpleType -> Default -> Maybe (Doc opts) 165 | defltS Boolean (C $ B x) = Just $ pretty x 166 | defltS (Primitive _) (S x) = Just . line $ interpolate x 167 | defltS (Primitive _) (C x) = Just $ prettyConst x 168 | defltS _ _ = Nothing 169 | 170 | unionD : Prec -> List1 SimpleType -> Default -> Maybe (Doc opts) 171 | unionD p ts d = 172 | let m = choiceMap (`defltS` d) ts 173 | in map (\x => prettyCon p "inject" [x]) m 174 | 175 | export 176 | deflt : Bool -> Prec -> CGType -> Default -> Maybe (Doc opts) 177 | deflt _ p Any Null = Just $ prettyCon p "MkAny" [line "$ null {a = ()}"] 178 | deflt _ p Any (S x) = Just $ prettyCon p "MkAny" [line "\{x}"] 179 | deflt _ p Any (C x) = Just $ prettyCon p "MkAny" [prettyConst x] 180 | deflt _ _ (Simple $ MaybeNull x) Null = Just "Nothing" 181 | 182 | deflt _ p (Simple $ MaybeNull x) d = 183 | map (\v => prettyCon p "Just" [v]) (defltS x d) 184 | 185 | deflt _ _ (Simple $ NotNull x) d = defltS x d 186 | 187 | deflt _ p (Union $ MaybeNull x) Null = Just "Nothing" 188 | 189 | deflt True p (Union $ MaybeNull x) d = 190 | map (\v => prettyCon p "Just" [v]) (unionD App x d) 191 | 192 | deflt True p (Union $ NotNull x) d = unionD p x d 193 | deflt _ _ _ _ = Nothing 194 | 195 | -------------------------------------------------------------------------------- 196 | -- Arguments 197 | -------------------------------------------------------------------------------- 198 | 199 | argTypeFFI : Prec -> CGArg -> Doc opts 200 | argTypeFFI p (Mandatory _ t) = ffi p t 201 | argTypeFFI p (VarArg _ t) = 202 | prettyCon p "IO" [prettyCon App "Array" [ffi App t]] 203 | argTypeFFI p (Optional _ t _) = prettyCon p "UndefOr" [ffi App t] 204 | 205 | argTypeAPI : Nat -> Prec -> CGArg -> Doc opts 206 | argTypeAPI k p (Mandatory _ t) = api (Just k) p t 207 | argTypeAPI _ p (VarArg _ t) = prettyCon p "List" [api Nothing App t] 208 | argTypeAPI k p (Optional _ t _) = prettyCon p "Optional" [api (Just k) App t] 209 | 210 | arg : PrettyArg opts -> Doc opts 211 | arg a = parens $ hsep [line "\{argIdent a}", ":", a.doc] 212 | 213 | prettyArgFFI : CGArg -> Doc opts 214 | prettyArgFFI = argTypeFFI Open 215 | 216 | prettyArgAPI : Nat -> CGArg -> PrettyArg opts 217 | prettyArgAPI k a = 218 | let doc := argTypeAPI k Open a 219 | in MkPrettyArg (argName a) doc 220 | 221 | -------------------------------------------------------------------------------- 222 | -- Functions 223 | -------------------------------------------------------------------------------- 224 | 225 | funTypeFFI : (name : IdrisIdent) -> ReturnType -> Args -> Doc opts 226 | funTypeFFI n t as = typeDecl n (returnTypeFFI t) (map prettyArgFFI as) 227 | 228 | funType : (name : IdrisIdent) -> ReturnType -> Args -> Doc opts 229 | funType n t as = 230 | typeDecl n (returnTypeAPI t) (run 0 as [<] [<] [<]) 231 | 232 | where 233 | run : Nat -> Args -> (imp,aut,expl : SnocList $ Doc opts) -> List (Doc opts) 234 | run _ [] is aus es = is <>> aus <>> es <>> [] 235 | run k (a::as) is aus es = case CGArg.inheritance a of 236 | Just (n,_) => 237 | let k2 := S k 238 | pk2 := "t\{show k2}" 239 | impl := line "{auto 0 _ : JSType \{pk2}}" 240 | aut := line "{auto 0 _ : Elem \{n} (Types \{pk2})}" 241 | expl = arg (prettyArgAPI k2 a) 242 | in run k2 as (is :< impl) (aus :< aut) (es :< expl) 243 | Nothing => 244 | let expl := arg (prettyArgAPI k a) 245 | in run (S k) as is aus (es :< expl) 246 | 247 | export 248 | callbackFFI : 249 | (obj : Identifier) 250 | -> (name : IdrisIdent) 251 | -> (impl : String) 252 | -> (args : Args) 253 | -> (tpe : ReturnType) 254 | -> String 255 | callbackFFI o n impl as t = 256 | let cbTpe := functionTypeOnly (returnTypeFFI' "IO" t) (map prettyArgFFI as) 257 | retTpe := line "PrimIO \{o}" 258 | in render80 . indent 2 $ 259 | vsep 260 | [ line "" 261 | , line "export" 262 | , line "\{impl}" 263 | , typeDecl n retTpe [cbTpe] 264 | ] 265 | 266 | export 267 | callbackAPI : 268 | (obj : Identifier) 269 | -> (name : IdrisIdent) 270 | -> (prim : IdrisIdent) 271 | -> (args : Args) 272 | -> (tpe : ReturnType) 273 | -> String 274 | callbackAPI o n prim as t = 275 | let cbTpe := 276 | functionTypeOnly 277 | (returnTypeFFI' "IO" t) 278 | (map prettyArgFFI as) 279 | 280 | retTpe := line "JSIO \{o}" 281 | impl := line "\{n} cb = primJS $ \{prim} cb" 282 | 283 | in render80 . indent 2 $ 284 | vsep 285 | [ line "" 286 | , line "export" 287 | , typeDecl n retTpe [cbTpe] 288 | , impl 289 | ] 290 | 291 | export 292 | funFFI : 293 | (name : IdrisIdent) 294 | -> (impl : String) 295 | -> (args : Args) 296 | -> (tpe : ReturnType) 297 | -> String 298 | funFFI n impl as t = render80 . indent 2 $ 299 | vsep [line "", line "export", line impl, funTypeFFI n t as ] 300 | 301 | export 302 | namespacedIdent : (ns : Kind) -> (name : IdrisIdent) -> String 303 | namespacedIdent ns n = #""\#{kindToString ns}.\#{n}""# 304 | 305 | fun' : 306 | {opts : _} 307 | -> (ns : Kind) 308 | -> (name : IdrisIdent) 309 | -> (prim : IdrisIdent) 310 | -> (args : Args) 311 | -> (undefs : List String) 312 | -> (returnType : ReturnType) 313 | -> List (Doc opts) 314 | fun' ns name prim as us rt = 315 | let vs := take (length as) (unShadowingArgNames name) 316 | 317 | appVs := zipWith adjVal vs as ++ map line us 318 | 319 | primNS := "\{kindToString ns}.\{prim}" 320 | 321 | primCall := 322 | if sameType rt 323 | then "primJS" 324 | else "tryJS " ++ namespacedIdent ns name 325 | 326 | lhs := unwords $ "\{name}" :: vs 327 | 328 | firstLine := line "\{lhs} = \{primCall} $" 329 | 330 | rhs := prettyCon Open primNS appVs 331 | 332 | sl := firstLine <++> rhs 333 | 334 | impl := ifMultiline sl (vappend firstLine $ indent 2 rhs) 335 | 336 | in [line "", line "export", funType name rt as, impl] 337 | 338 | where 339 | adjVal : String -> CGArg -> Doc opts 340 | adjVal v a = 341 | -- If the same type is used at the FFI and the API, 342 | -- there is no need to convert the value. 343 | -- If the value should be upcast to a parent type (`inheritance` returns 344 | -- a `Just`), we upcast the value using a number of nested `map`s, 345 | -- corresponding to the number of functors around 346 | -- the type (at most two layers: `Optional` and `Maybe`), 347 | -- otherwise, we just use `toFFI` to convert it. 348 | case (sameType a, snd <$> inheritance a) of 349 | (True,_) => line v 350 | (False,Nothing) => parens ("toFFI" <++> line v) 351 | (False,Just Direct) => parens ("up" <++> line v) 352 | (False,Just May) => parens ("mayUp" <++> line v) 353 | (False,Just Opt) => parens ("optUp" <++> line v) 354 | (False,Just OptMay) => parens ("omyUp" <++> line v) 355 | 356 | export 357 | fun : 358 | (ns : Kind) 359 | -> (name : IdrisIdent) 360 | -> (prim : IdrisIdent) 361 | -> Args 362 | -> ReturnType 363 | -> String 364 | fun ns name prim as t = 365 | let -- mandatory arguments 366 | as2 := filter (not . isOptional) as 367 | undefs := List.replicate (length as `minus` length as2) "undef" 368 | 369 | mainName := if null undefs then name else name2 370 | 371 | funImpl := fun' ns mainName prim as [] t 372 | 373 | -- function without optional args 374 | funImpl2 := 375 | if null undefs 376 | then [] 377 | else fun' ns name prim as2 undefs t 378 | 379 | in render80 . indent 2 $ vsep (funImpl ++ funImpl2) 380 | 381 | where 382 | name2 : IdrisIdent 383 | name2 = case name of 384 | II v => fromString $ v ++ "'" 385 | Prim v => Prim (v ++ "'") 386 | Underscore v => fromString $ v ++ "'" 387 | -------------------------------------------------------------------------------- /src/Text/WebIDL/Codegen/Definitions.idr: -------------------------------------------------------------------------------- 1 | module Text.WebIDL.Codegen.Definitions 2 | 3 | import Data.List 4 | import Data.List.Elem 5 | import Data.SOP 6 | import Data.String 7 | import Text.WebIDL.Codegen.Args 8 | import Text.WebIDL.Codegen.Enum 9 | import Text.WebIDL.Codegen.Members 10 | import Text.WebIDL.Codegen.Rules 11 | import Text.WebIDL.Codegen.Types 12 | import public Text.WebIDL.Codegen.Util 13 | 14 | %default total 15 | 16 | -------------------------------------------------------------------------------- 17 | -- Imports 18 | -------------------------------------------------------------------------------- 19 | 20 | defImports : CGDomain -> String 21 | defImports d = """ 22 | import JS 23 | import Web.Internal.\{d.name}Prim 24 | import Web.Internal.Types 25 | """ 26 | 27 | typeImports : String 28 | typeImports = "import JS" 29 | 30 | -------------------------------------------------------------------------------- 31 | -- Data Declarations 32 | -------------------------------------------------------------------------------- 33 | 34 | extern : CGDomain -> String 35 | extern d = 36 | fastUnlines 37 | [ section "Interfaces" $ exts ext name d.ifaces 38 | , section "Dictionaries" $ exts extNoCast name d.dicts 39 | , section "Mixins" $ exts extNoCast name d.mixins 40 | , section "Callbacks" $ exts extNoCast name d.callbacks 41 | ] 42 | 43 | where 44 | extNoCast : String -> String 45 | extNoCast s = """ 46 | export data \{s} : Type where [external] 47 | 48 | export 49 | ToFFI \{s} \{s} where toFFI = id 50 | 51 | export 52 | FromFFI \{s} \{s} where fromFFI = Just 53 | """ 54 | 55 | ext : String -> String 56 | ext s = extNoCast s ++ "\n\n" ++ """ 57 | export 58 | SafeCast \{s} where 59 | safeCast = unsafeCastOnPrototypeName "\{s}" 60 | """ 61 | 62 | exts : 63 | (f : String -> String) 64 | -> (a -> Identifier) 65 | -> List a 66 | -> List String 67 | exts f g = map (("\n" ++) . f) . sort . map (value . g) 68 | 69 | -------------------------------------------------------------------------------- 70 | -- CallbackInterfaces 71 | -------------------------------------------------------------------------------- 72 | 73 | cbacks : (CGCallback -> List String) -> CGDomain -> String 74 | cbacks f = section "Callbacks" . map ns . sortBy (comparing name) . callbacks 75 | where ns : CGCallback -> String 76 | ns i = namespaced i.name (f i) 77 | 78 | callbacks : CGDomain -> String 79 | callbacks = cbacks go 80 | where go : CGCallback -> List String 81 | go cb = callback cb :: constants cb.constants 82 | 83 | primCallbacks : CGDomain -> String 84 | primCallbacks = cbacks (pure . primCallback) 85 | 86 | -------------------------------------------------------------------------------- 87 | -- JSType 88 | -------------------------------------------------------------------------------- 89 | 90 | jsTypes : List CGDomain -> String 91 | jsTypes ds = 92 | let ifs := sortBy (comparing name) (ds >>= ifaces) 93 | dics := sortBy (comparing name) (ds >>= dicts) 94 | in section "Inheritance" $ 95 | map (\i => jsType i.name i.super) ifs ++ 96 | map (\d => jsType d.name d.super) dics 97 | 98 | -------------------------------------------------------------------------------- 99 | -- Interfaces 100 | -------------------------------------------------------------------------------- 101 | 102 | ifaces' : (CGIface -> List String) -> CGDomain -> String 103 | ifaces' f = section "Interfaces" . map ns . sortBy (comparing name) . ifaces 104 | 105 | where 106 | ns : CGIface -> String 107 | ns i = namespaced i.name (f i) 108 | 109 | ifaces : CGDomain -> String 110 | ifaces = ifaces' $ \(MkIface n s cs fs) => constants cs ++ functions fs 111 | 112 | primIfaces : CGDomain -> String 113 | primIfaces = ifaces' (primFunctions . functions) 114 | 115 | -------------------------------------------------------------------------------- 116 | -- Dictionaries 117 | -------------------------------------------------------------------------------- 118 | 119 | dicts' : (CGDict -> List String) -> CGDomain -> String 120 | dicts' f = section "Dictionaries" . map ns . sortBy (comparing name) . dicts 121 | 122 | where 123 | ns : CGDict -> String 124 | ns d = namespaced d.name (f d) 125 | 126 | dicts : CGDomain -> String 127 | dicts = dicts' $ \(MkDict n s fs) => functions fs 128 | 129 | primDicts : CGDomain -> String 130 | primDicts = dicts' (primFunctions . functions) 131 | 132 | -------------------------------------------------------------------------------- 133 | -- Mixins 134 | -------------------------------------------------------------------------------- 135 | 136 | mixins' : (CGMixin -> List String) -> CGDomain -> String 137 | mixins' f = section "Mixins" . map ns . sortBy (comparing name) . mixins 138 | 139 | where 140 | ns : CGMixin -> String 141 | ns m = namespaced m.name (f m) 142 | 143 | mixins : CGDomain -> String 144 | mixins = mixins' $ \(MkMixin n cs fs) => constants cs ++ functions fs 145 | 146 | primMixins : CGDomain -> String 147 | primMixins = mixins' (primFunctions . functions) 148 | 149 | -------------------------------------------------------------------------------- 150 | -- Typedefs 151 | -------------------------------------------------------------------------------- 152 | 153 | export 154 | typedefs : List CGDomain -> String 155 | typedefs ds = 156 | """ 157 | module Web.Internal.Types 158 | 159 | import JS 160 | import public Web.Internal.AnimationTypes as Types 161 | import public Web.Internal.ClipboardTypes as Types 162 | import public Web.Internal.CssTypes as Types 163 | import public Web.Internal.CssomviewTypes as Types 164 | import public Web.Internal.DomTypes as Types 165 | import public Web.Internal.FetchTypes as Types 166 | import public Web.Internal.FileTypes as Types 167 | import public Web.Internal.GeometryTypes as Types 168 | import public Web.Internal.HtmlTypes as Types 169 | import public Web.Internal.IndexedDBTypes as Types 170 | import public Web.Internal.MediasourceTypes as Types 171 | import public Web.Internal.MediastreamTypes as Types 172 | import public Web.Internal.PermissionsTypes as Types 173 | import public Web.Internal.ServiceworkerTypes as Types 174 | import public Web.Internal.StreamsTypes as Types 175 | import public Web.Internal.SvgTypes as Types 176 | import public Web.Internal.UIEventsTypes as Types 177 | import public Web.Internal.UrlTypes as Types 178 | import public Web.Internal.VisibilityTypes as Types 179 | import public Web.Internal.WebglTypes as Types 180 | import public Web.Internal.WebidlTypes as Types 181 | import public Web.Internal.XhrTypes as Types 182 | 183 | %default total 184 | """ ++ "\n\n" ++ jsTypes ds 185 | 186 | -------------------------------------------------------------------------------- 187 | -- Codegen 188 | -------------------------------------------------------------------------------- 189 | -- 190 | export 191 | types : CGDomain -> String 192 | types d = 193 | """ 194 | module Web.Internal.\{d.name}Types 195 | 196 | \{typeImports} 197 | 198 | %default total 199 | 200 | \{enums d.enums} 201 | \{extern d} 202 | """ 203 | 204 | export 205 | primitives : CGDomain -> String 206 | primitives d = 207 | """ 208 | module Web.Internal.\{d.name}Prim 209 | 210 | import JS 211 | import Web.Internal.Types 212 | 213 | %default total 214 | 215 | \{primIfaces d} 216 | \{primMixins d} 217 | \{primDicts d} 218 | \{primCallbacks d} 219 | """ 220 | 221 | export 222 | definitions : CGDomain -> String 223 | definitions d = 224 | """ 225 | module Web.Raw.\{d.name} 226 | 227 | \{defImports d} 228 | 229 | %default total 230 | 231 | \{Definitions.ifaces d} 232 | \{Definitions.mixins d} 233 | \{Definitions.dicts d} 234 | \{Definitions.callbacks d} 235 | """ 236 | -------------------------------------------------------------------------------- /src/Text/WebIDL/Codegen/Enum.idr: -------------------------------------------------------------------------------- 1 | module Text.WebIDL.Codegen.Enum 2 | 3 | import Data.Refined 4 | import Data.List 5 | import Text.WebIDL.Codegen.Util 6 | 7 | %default total 8 | 9 | enum : {opts : _} -> Enum -> Doc opts 10 | enum (MkEnum _ pn vs) = 11 | let (s ::: ss) := map value vs 12 | (c ::: cs) := map toDataConstructor (s ::: ss) 13 | vals := the (List $ Doc opts) $ map (\sl => line "| \{sl}") cs 14 | sl := line "data \{pn} =" <++> sep (line "\{c}" :: vals) 15 | ml := 16 | vappend 17 | (line "data \{pn} =") 18 | (indent 2 $ vsep (indent 2 (line "\{c}") :: vals)) 19 | 20 | code := 21 | vsep 22 | [ empty 23 | , line "public export" 24 | , ifMultiline sl ml 25 | , empty 26 | , line "public export" 27 | , line "Show \{pn} where" 28 | , indent 2 $ vsep $ zipWith showImpl (c :: cs) (s :: ss) 29 | , empty 30 | , line "public export" 31 | , line "Eq \{pn} where" 32 | , indent 2 $ line "(==) = (==) `on` show" 33 | , empty 34 | , line "public export" 35 | , line "Ord \{pn} where" 36 | , indent 2 $ line "compare = compare `on` show" 37 | , empty 38 | , line "public export" 39 | , typeDecl "read" (line "Maybe \{pn}") [ line "String" ] 40 | 41 | , vsep $ zipWith readImpl (s :: ss) (c :: cs) 42 | , line "read _ = Nothing" 43 | , empty 44 | , line "export" 45 | , line "ToFFI \{pn} String where" 46 | , indent 2 $ line "toFFI = show" 47 | , empty 48 | , line "export" 49 | , line "FromFFI \{pn} String where" 50 | , indent 2 $ line "fromFFI = read" 51 | ] 52 | 53 | in vsep ["", line "namespace \{pn}", indent 2 code] 54 | 55 | where 56 | showImpl : String -> String -> Doc opts 57 | showImpl x y = line #"show \#{x} = "\#{y}""# 58 | 59 | readImpl : String -> String -> Doc opts 60 | readImpl x y = line #"read "\#{x}" = Just \#{y}"# 61 | 62 | export 63 | enums : List Enum -> String 64 | enums = section "Enums" . map (render80 . enum) 65 | -------------------------------------------------------------------------------- /src/Text/WebIDL/Codegen/Members.idr: -------------------------------------------------------------------------------- 1 | module Text.WebIDL.Codegen.Members 2 | 3 | import Data.List 4 | import Text.WebIDL.Codegen.Args 5 | import Text.WebIDL.Codegen.Rules 6 | import Text.WebIDL.Codegen.Types 7 | import Text.WebIDL.Codegen.Util 8 | import Text.WebIDL.Types 9 | 10 | %default total 11 | 12 | -------------------------------------------------------------------------------- 13 | -- Subtyping 14 | -------------------------------------------------------------------------------- 15 | 16 | export 17 | jsType : Identifier -> Supertypes -> String 18 | jsType n (MkSupertypes parents ms) = 19 | let mixins = sortedNubOn id ms 20 | 21 | in render80 $ 22 | vsep 23 | [ empty 24 | , line "public export" 25 | , line "JSType \{n} where" 26 | , indent 2 $ prettyCon Open "parents =" [list (map (line . value) parents)] 27 | , empty 28 | , indent 2 $ prettyCon Open "mixins =" [list (map (line . value) mixins)] 29 | ] 30 | 31 | -------------------------------------------------------------------------------- 32 | -- Constants 33 | -------------------------------------------------------------------------------- 34 | 35 | export 36 | constants : List CGConst -> List String 37 | constants = map (render80 . const) . sortBy (comparing name) 38 | 39 | where 40 | const : {opts : _} -> CGConst -> Doc opts 41 | const (MkConst t n v) = 42 | indent 2 $ 43 | vsep 44 | [ empty 45 | , line "public export" 46 | , line "\{n} :" <++> constTpe t 47 | , line "\{n} =" <++> prettyConst v 48 | ] 49 | 50 | -------------------------------------------------------------------------------- 51 | -- Callback Conversion 52 | -------------------------------------------------------------------------------- 53 | 54 | export 55 | primCallback : CGCallback -> String 56 | primCallback (MkCallback n _ t as) = 57 | callbackFFI n (primMarshallCallback n) (callbackFFI $ length as) as t 58 | 59 | export 60 | callback : CGCallback -> String 61 | callback (MkCallback n _ t as) = 62 | callbackAPI n (marshallCallback n) (primMarshallCallback n) as t 63 | 64 | -------------------------------------------------------------------------------- 65 | -- Attribute 66 | -------------------------------------------------------------------------------- 67 | 68 | attrImpl: 69 | {opts : _} 70 | -> (msg : Doc opts) 71 | -> (set : Doc opts) 72 | -> (get : Doc opts) 73 | -> (app : Doc opts) 74 | -> (arg : CGArg) 75 | -> (Doc opts, Doc opts) 76 | attrImpl msg s g a (Mandatory _ (Simple $ MaybeNull x)) = 77 | ( line "Attribute False Maybe" <++> ret App (Simple $ NotNull x) 78 | , prettyCon Open "fromNullablePrim" [msg,s,g,a] 79 | ) 80 | 81 | attrImpl msg s g a (Mandatory _ (Union $ MaybeNull x)) = 82 | ( line "Attribute False Maybe" <++> ret App (Union $ NotNull x) 83 | , prettyCon Open "fromNullablePrim" [msg,s,g,a] 84 | ) 85 | 86 | attrImpl msg s g a (Mandatory _ t) = 87 | ( line "Attribute True Prelude.id" <++> ret App t 88 | , prettyCon Open "fromPrim" [msg,s,g,a] 89 | ) 90 | 91 | attrImpl msg s g a (VarArg _ t) = 92 | ( line "Attribute True Prelude.id" <++> prettyCon App "VarArg" [ffi App t] 93 | , prettyCon Open "fromPrim" [msg,s,g,a] 94 | ) 95 | 96 | attrImpl msg s g a (Optional _ t d) = 97 | case deflt (safeCast t) App t d of 98 | Nothing => 99 | ( line "Attribute False Optional" <++> ret App t 100 | , prettyCon Open "fromUndefOrPrimNoDefault" [msg,s,g,a] 101 | ) 102 | Just x => 103 | ( line "Attribute True Optional" <++> ret App t 104 | , prettyCon Open "fromUndefOrPrim" [msg,s,g,x,a] 105 | ) 106 | 107 | attrRW : 108 | Nat 109 | -> AttributeName 110 | -> Kind 111 | -> CGArg 112 | -> ReturnType 113 | -> String 114 | attrRW k n o t rt = 115 | let implName := attrGetter k n 116 | primGet := line "\{primAttrGetter k n}" 117 | primSet := line "\{primAttrSetter k n}" 118 | msg := namespacedIdent o (fromString $ "get" ++ n.value) 119 | po := kindToString o 120 | up := if isParent o then "(v :> \{po})" else "v" 121 | 122 | (tpe,impl) := attrImpl (line msg) primGet primSet (line up) t 123 | funTpe := 124 | if isParent o 125 | then 126 | typeDecl 127 | implName 128 | tpe 129 | [ line "{auto 0 _ : JSType t}" 130 | , line "{auto 0 _ : Elem \{po} (Types t)}" 131 | , line "t" 132 | ] 133 | else typeDecl implName tpe [line "\{po}"] 134 | 135 | in render80 . indent 2 $ 136 | vsep 137 | [ empty 138 | , line "export" 139 | , funTpe 140 | , line "\{implName} v =" <++> impl 141 | ] 142 | 143 | -------------------------------------------------------------------------------- 144 | -- Functions 145 | -------------------------------------------------------------------------------- 146 | 147 | obj : Kind -> CGArg 148 | obj k = Mandatory (MkArgName "obj") (fromKind k) 149 | 150 | function : (Nat,CGFunction) -> String 151 | function (k,Getter o i t) = fun o (getter k) (primGetter k) [obj o, i] t 152 | 153 | function (k,Setter o i v) = 154 | fun o (setter k) (primSetter k) [obj o, i, v] Undefined 155 | 156 | function (k,Regular n o as t) = fun o (op k n) (primOp k n) (obj o :: as) t 157 | 158 | function (k,Static n o as t) = fun o (op k n) (primOp k n) as t 159 | 160 | function (k,Attribute n o t rt) = attrRW k n o t rt 161 | 162 | function (k,AttributeGet n o t) = 163 | fun o (attrGetter k n) (primAttrGetter k n) [obj o] t 164 | 165 | function (k,StaticAttributeSet n o t) = 166 | fun o (attrSetter k n) (primAttrSetter k n) [t] Undefined 167 | 168 | function (k,StaticAttributeGet n o t) = 169 | fun o (attrGetter k n) (primAttrGetter k n) [] t 170 | 171 | function (k,DictConstructor o as) = 172 | fun o (constr k) (primConstr k) as (fromKind o) 173 | 174 | function (k,Constructor o as) = 175 | fun o (constr k) (primConstr k) as (fromKind o) 176 | 177 | hasVarArg : Args -> Bool 178 | hasVarArg (VarArg _ _ :: []) = True 179 | hasVarArg [] = False 180 | hasVarArg (_ :: xs) = hasVarArg xs 181 | 182 | prim : (Nat,CGFunction) -> String 183 | prim (k,Getter o i t) = funFFI (primGetter k) getterFFI [obj o, i] t 184 | prim (k,Setter o i v) = funFFI (primSetter k) setterFFI [obj o, i, v] Undefined 185 | prim (k,Regular n o args t) = 186 | let as = obj o :: args 187 | in if hasVarArg args 188 | then funFFI (primOp k n) (funFFIVarArg n $ length args) as t 189 | else funFFI (primOp k n) (funFFI n $ length args) as t 190 | 191 | prim (k,Static n o as t) = 192 | if hasVarArg as 193 | then funFFI (primOp k n) (staticFunFFIVarArg o n $ length as) as t 194 | else funFFI (primOp k n) (staticFunFFI o n $ length as) as t 195 | 196 | prim (k,Attribute n o t rt) = 197 | fastUnlines 198 | [ funFFI (primAttrGetter k n) (attrGetFFI n) [obj o] rt 199 | , "" 200 | , funFFI (primAttrSetter k n) (attrSetFFI n) [obj o, t] Undefined 201 | ] 202 | 203 | prim (k,AttributeGet n o t) = 204 | funFFI (primAttrGetter k n) (attrGetFFI n) [obj o] t 205 | 206 | prim (k,StaticAttributeSet n o t) = 207 | funFFI (primAttrSetter k n) (staticAttrSetFFI o n) [t] Undefined 208 | 209 | prim (k,StaticAttributeGet n o t) = 210 | funFFI (primAttrGetter k n) (staticAttrGetFFI o n) [] t 211 | 212 | prim (k,DictConstructor o as) = 213 | funFFI (primConstr k) (dictConFFI $ map argName as) as (fromKind o) 214 | 215 | prim (k,Constructor o as) = 216 | if hasVarArg as 217 | then funFFI (primConstr k) (conFFIVarArg o $ length as) as (fromKind o) 218 | else funFFI (primConstr k) (conFFI o $ length as) as (fromKind o) 219 | 220 | -- Tags functions with an index if several function of the 221 | -- same priority (same kind of function and same name) exist, 222 | -- as these would lead to overloading issues. 223 | tagFunctions : List CGFunction -> List (Nat,CGFunction) 224 | tagFunctions = go 0 225 | 226 | where 227 | go : Nat -> List CGFunction -> List (Nat,CGFunction) 228 | go _ [] = [] 229 | go k (x :: []) = [(k,x)] 230 | go k (x :: t@(y :: ys)) = 231 | if priority x == priority y 232 | then (k,x) :: go (S k) t 233 | else (k,x) :: go 0 t 234 | 235 | export 236 | functions : List CGFunction -> List String 237 | functions = map function . tagFunctions . sortBy (comparing priority) 238 | 239 | export 240 | primFunctions : List CGFunction -> List String 241 | primFunctions = map prim . tagFunctions . sortBy (comparing priority) 242 | -------------------------------------------------------------------------------- /src/Text/WebIDL/Codegen/Rules.idr: -------------------------------------------------------------------------------- 1 | module Text.WebIDL.Codegen.Rules 2 | 3 | import Data.List 4 | import Data.List1 5 | import Data.List.Elem 6 | import Data.SortedSet 7 | import Text.WebIDL.Codegen.Util 8 | 9 | -------------------------------------------------------------------------------- 10 | -- Environment 11 | -------------------------------------------------------------------------------- 12 | 13 | parents : Domain -> List Identifier 14 | parents d = 15 | mapMaybe inherits d.interfaces ++ mapMaybe inherits d.dictionaries 16 | 17 | kinds : List Domain -> SortedMap Identifier Kind 18 | kinds ds = 19 | let ps = SortedSet.fromList $ ds >>= parents 20 | in SortedMap.fromList 21 | $ (ds >>= pairs name KEnum . enums) 22 | ++ (ds >>= pairs name KMixin . mixins) 23 | ++ (ds >>= pairs name (iface ps) . interfaces) 24 | ++ (ds >>= pairs name KDictionary . dictionaries) 25 | ++ (ds >>= pairs name KCallback . callbackInterfaces) 26 | ++ (ds >>= pairs name KCallback . callbacks) 27 | ++ (ds >>= pairs name KAlias . typedefs) 28 | where 29 | -- list of identifiers with their kinds 30 | pairs : 31 | (a -> Identifier) 32 | -> (Identifier -> Kind) 33 | -> List a 34 | -> List (Identifier,Kind) 35 | pairs name knd = map $ \v => (name v, knd $ name v) 36 | 37 | iface : SortedSet Identifier -> Identifier -> Kind 38 | iface ps i = KInterface (contains i ps) i 39 | 40 | ||| Calculate the environment from a list of domains. 41 | export 42 | env : Nat -> List Domain -> Env 43 | env k ds = 44 | let ks := kinds ds 45 | in MkEnv k ks jsTypes (aliases ks $ ds >>= typedefs) 46 | 47 | where 48 | -- calculates the mapping from type aliases to the 49 | -- types they represent 50 | aliases : 51 | SortedMap Identifier Kind 52 | -> List Typedef 53 | -> SortedMap Identifier (IdlTypeF ExtAttributeList Kind) 54 | aliases ks = SortedMap.fromList . map mkPair 55 | where 56 | kind : Identifier -> Kind 57 | kind i = fromMaybe (KOther i) $ lookup i ks 58 | 59 | mkPair : Typedef -> (Identifier,IdlTypeF ExtAttributeList Kind) 60 | mkPair (MkTypedef _ _ t n) = (n, map kind t) 61 | 62 | dictToType : Dictionary -> (Identifier,JSType) 63 | dictToType (MkDictionary _ n i _) = (n, MkJSType i Nil) 64 | 65 | interfaceToType : Interface -> (Identifier,JSType) 66 | interfaceToType (MkInterface _ n i _) = (n, MkJSType i Nil) 67 | 68 | mixin : 69 | SortedMap Identifier JSType 70 | -> Includes 71 | -> SortedMap Identifier JSType 72 | mixin ts (MkIncludes _ n incl) = 73 | case lookup n ts of 74 | Nothing => ts 75 | Just js => let js2 := {mixins $= (incl ::)} js in insert n js2 ts 76 | 77 | jsTypes : SortedMap Identifier JSType 78 | jsTypes = 79 | let types := 80 | (ds >>= map dictToType . dictionaries) ++ 81 | (ds >>= map interfaceToType . interfaces) 82 | 83 | includes := ds >>= includeStatements 84 | 85 | initialMap := SortedMap.fromList types 86 | 87 | in foldl mixin initialMap includes 88 | 89 | -------------------------------------------------------------------------------- 90 | -- Types 91 | -------------------------------------------------------------------------------- 92 | 93 | buff : BufferRelatedType -> SimpleType 94 | buff Uint8Array = Unchangeable "UInt8Array" 95 | buff Uint16Array = Unchangeable "UInt8Array" 96 | buff Uint32Array = Unchangeable "UInt8Array" 97 | buff Uint8ClampedArray = Unchangeable "UInt8ClampedArray" 98 | buff x = Unchangeable $ show x 99 | 100 | -- booleans are marshalled from Idris2 `Bool` to JS `Boolean` 101 | -- and back 102 | prim : PrimitiveType -> SimpleType 103 | prim Boolean = Boolean 104 | prim (Unsigned Short) = Primitive "Bits16" 105 | prim (Unsigned Long) = Primitive "Bits32" 106 | prim (Unsigned LongLong) = Primitive "JSBits64" 107 | prim (Signed Short) = Primitive "Int16" 108 | prim (Signed Long) = Primitive "Int32" 109 | prim (Signed LongLong) = Primitive "JSInt64" 110 | prim (Unrestricted x) = Primitive "Double" 111 | prim (Restricted x) = Primitive "Double" 112 | prim Undefined = Undef 113 | prim Byte = Primitive "Int8" 114 | prim Octet = Primitive "Bits8" 115 | prim BigInt = Primitive "Integer" 116 | 117 | string : StringType -> SimpleType 118 | string ByteString = Unchangeable "ByteString" 119 | string DOMString = Primitive "String" 120 | string USVString = Primitive "String" 121 | 122 | strTpe : StringType -> String 123 | strTpe ByteString = "ByteString" 124 | strTpe DOMString = "String" 125 | strTpe USVString = "String" 126 | 127 | parameters (e : Env) 128 | (dom : Domain) 129 | 130 | -- Lookup the kind of an identifier from the environment 131 | kind : Identifier -> Kind 132 | kind i = fromMaybe (KOther i) $ lookup i e.kinds 133 | 134 | mutual 135 | -- the most interesting part when unaliasing a type: 136 | -- here the aliases may be wrapped in an `I` data 137 | -- constructor, in which case we try to convert it 138 | -- to a distinguishable type. If that's not possible, 139 | -- we return the corresponding type wrapped in a `Left`. 140 | -- Otherwise we keep the distinguishable type 141 | -- (but keep unaliasing inner types, if any) 142 | uaD : DistinguishableF ExtAttributeList Kind -> Codegen CGType 143 | uaD i@(I $ KAlias x) = 144 | case lookup x e.aliases of 145 | Nothing => Left [UnresolvedAlias dom x] 146 | Just x => unalias x 147 | uaD (I k) = Right $ fromKind k 148 | uaD (Sequence x y) = simple . Array <$> unalias y 149 | uaD (FrozenArray x y) = simple . Array <$> unalias y 150 | uaD (ObservableArray x y) = simple . Array <$> unalias y 151 | uaD (Record x _ z) = simple . Record (strTpe x) <$> unalias z 152 | uaD (P p) = Right . simple $ prim p 153 | uaD (S s) = Right . simple $ string s 154 | uaD (B b) = Right . simple $ buff b 155 | uaD Object = Right . simple . Interface True $ 156 | MkIdent "Object" 157 | uaD Symbol = Right $ unchangeable "Symbol" 158 | 159 | uaU : 160 | UnionTypeF ExtAttributeList Kind 161 | -> Codegen (Nullable $ List1 SimpleType) 162 | uaU (UT f s r) = 163 | do (hf ::: tf) <- uaM f 164 | rest <- map join (traverse uaM (s ::: r)) 165 | 166 | let nullables = hf ::: (tf ++ forget rest) 167 | simples = map nullVal nullables 168 | 169 | if any isNullable nullables 170 | -- the result is nullable 171 | then pure $ MaybeNull simples 172 | -- the result is non-nullable 173 | else pure $ NotNull simples 174 | 175 | 176 | -- in case of a wrapped distinguishable type, 177 | -- we unalias it using `uaD` but keep the unaliased 178 | -- version only, if it is again distinguishable. 179 | uaM : UnionMemberTypeF ExtAttributeList Kind 180 | -> Codegen (List1 $ Nullable SimpleType) 181 | uaM (MkUnionMember a t) = 182 | do t2 <- uaD t 183 | case t2 of 184 | Any => Left [AnyInUnion dom] 185 | Promise x => Left [PromiseInUnion dom] 186 | Simple x => Right $ singleton x 187 | (Union $ MaybeNull xs) => Right $ map MaybeNull xs 188 | (Union $ NotNull xs) => Right $ map NotNull xs 189 | 190 | unalias : IdlTypeF ExtAttributeList Kind -> Codegen CGType 191 | unalias Any = Right Any 192 | unalias (D $ NotNull d) = uaD d 193 | unalias (U $ NotNull d) = Union <$> uaU d 194 | unalias (U $ MaybeNull d) = Union . nullable <$> uaU d 195 | unalias (Promise x) = Promise <$> unalias x 196 | unalias t@(D $ MaybeNull d) = 197 | do res <- uaD d 198 | case res of 199 | Any => Left [NullableAny dom] 200 | Simple x => pure . Simple $ nullable x 201 | Union x => pure . Union $ nullable x 202 | Promise x => Left [NullablePromise dom] 203 | 204 | -- calculate the aliased type from a type coming 205 | -- from the WebIDL parser 206 | -- the unaliased version of the type is only kept (in a `Just`) 207 | -- if it differs from the original type. 208 | tpe : IdlType -> Codegen CGType 209 | tpe t = let cgt = map kind t 210 | in unalias cgt 211 | 212 | -- convert an IDL type coming from the parser to 213 | -- a return type in the code generator 214 | rtpe : IdlType -> Codegen ReturnType 215 | rtpe (D $ NotNull $ P Undefined) = Right Undefined 216 | rtpe (D $ NotNull $ I $ MkIdent "void") = Right Undefined 217 | rtpe t = Def <$> tpe t 218 | 219 | constTpe : ConstType -> Codegen CGConstType 220 | constTpe (CI i) = 221 | case uaD (I $ kind i) of 222 | Left x => Left x 223 | Right (Simple $ NotNull $ Primitive s) => Right $ MkConstType s 224 | Right _ => Left [InvalidConstType dom] 225 | 226 | constTpe (CP p) = 227 | case prim p of 228 | Primitive s => Right $ MkConstType s 229 | _ => Left [InvalidConstType dom] 230 | 231 | const : Const -> Codegen CGConst 232 | const (MkConst t n v) = map (\t2 => MkConst t2 n v) (constTpe t) 233 | 234 | -------------------------------------------------------------------------------- 235 | -- Arguments 236 | -------------------------------------------------------------------------------- 237 | 238 | -- create an optional argument named "value" from 239 | -- a type coming from the parser 240 | optArg : IdlType -> Default -> Codegen CGArg 241 | optArg t d = [| Optional (pure $ MkArgName "value") (tpe t) (pure d) |] 242 | 243 | -- create an argument named "value" from 244 | -- a type coming from the parser 245 | valArg : IdlType -> Codegen CGArg 246 | valArg t = Mandatory (MkArgName "value") <$> tpe t 247 | 248 | -- convert an argument coming from the parser 249 | -- to one to be used in the code generator 250 | arg : Arg -> Codegen CGArg 251 | arg (MkArg _ t n) = Mandatory n <$> tpe t 252 | 253 | -- convert an argument coming from the parser 254 | -- to a vararg to be used in the code generator 255 | vararg : Arg -> Codegen CGArg 256 | vararg (MkArg _ t n) = VarArg n <$> tpe t 257 | 258 | -- convert an argument coming from the parser 259 | -- to an optional arg to be used in the code generator 260 | opt : OptArg -> Codegen CGArg 261 | opt (MkOptArg _ _ t n d) = [| Optional (pure n) (tpe t) (pure d) |] 262 | 263 | -- convert an argument list coming from the parser 264 | -- to a list of codegen args 265 | toArgs : ArgumentList -> Codegen Args 266 | toArgs (VarArg as v) = [| snoc (traverse arg as) (vararg v) |] 267 | toArgs (NoVarArg as os) = [| traverse arg as ++ traverse opt os |] 268 | 269 | -------------------------------------------------------------------------------- 270 | -- Inheritance 271 | -------------------------------------------------------------------------------- 272 | 273 | objectOnly : Supertypes 274 | objectOnly = MkSupertypes [MkIdent "Object"] [] 275 | 276 | ||| Calculates the supertypes and mixins for a given 277 | ||| identifier. 278 | ||| 279 | ||| @maxIterations : Maximal number of iterations. Without this, 280 | ||| the algorithm might loop forever in case of 281 | ||| cyclic dependencies. This value corresponds 282 | ||| to the maximal length of the inheritance chain. 283 | supertypes : Identifier -> Supertypes 284 | supertypes = run e.maxInheritance 285 | 286 | where 287 | run : Nat -> Identifier -> Supertypes 288 | run 0 i = objectOnly 289 | run (S k) i = 290 | case lookup i e.jsTypes of 291 | Nothing => objectOnly 292 | 293 | (Just $ MkJSType Nothing mixins) => 294 | { mixins := mixins } objectOnly 295 | 296 | (Just $ MkJSType (Just parent) mixins) => 297 | let MkSupertypes parents mixins2 = run k parent 298 | in MkSupertypes (parent :: parents) (mixins ++ mixins2) 299 | 300 | -------------------------------------------------------------------------------- 301 | -- Functions 302 | -------------------------------------------------------------------------------- 303 | 304 | op : Identifier -> Op a -> Codegen (List CGFunction) 305 | op n (MkOp _ _ Nothing _) = Left [RegularOpWithoutName dom n] 306 | op n (MkOp _ t (Just o) as) = 307 | map pure [| Regular (pure o) (pure $ kind n) (toArgs as) (rtpe t) |] 308 | 309 | static : Identifier -> Op a -> Codegen (List CGFunction) 310 | static n (MkOp _ _ Nothing _) = Left [RegularOpWithoutName dom n] 311 | static n (MkOp _ t (Just o) a) = 312 | map pure [| Static (pure o) (pure $ kind n) (toArgs a) (rtpe t) |] 313 | 314 | constr : Identifier -> ArgumentList -> Codegen (List CGFunction) 315 | constr name args = pure . Constructor (kind name) <$> toArgs args 316 | 317 | attrRO : Identifier -> Readonly Attribute -> Codegen (List CGFunction) 318 | attrRO o (MkRO $ MkAttribute _ t n) = 319 | pure . AttributeGet n (kind o) <$> rtpe t 320 | 321 | attr : Identifier -> Attribute -> Codegen (List CGFunction) 322 | attr obj (MkAttribute _ t n) = 323 | map pure [| Attribute (pure n) (pure $ kind obj) (valArg t) (rtpe t) |] 324 | 325 | str : Identifier -> Stringifier -> Codegen (List CGFunction) 326 | str o (Z v) = attr o v 327 | str o (S $ Z v) = attrRO o v 328 | str o (S $ S $ Z v) = op o v 329 | str o (S $ S $ S $ Z ()) = 330 | let name = Just $ MkOpName "toString" 331 | in op o (MkOp () domString name (NoVarArg [] [])) 332 | 333 | staticAttrRO : Identifier -> Readonly Attribute -> Codegen (List CGFunction) 334 | staticAttrRO o (MkRO $ MkAttribute _ t n) = 335 | pure . StaticAttributeGet n (kind o) <$> rtpe t 336 | 337 | staticAttr : Identifier -> Attribute -> Codegen (List CGFunction) 338 | staticAttr obj (MkAttribute _ t n) = 339 | let ak = kind obj 340 | in sequence [ StaticAttributeGet n ak <$> rtpe t 341 | , StaticAttributeSet n ak <$> valArg t 342 | ] 343 | 344 | dictCon : Kind -> List DictionaryMemberRest -> Codegen CGFunction 345 | dictCon o = go Nil Nil 346 | 347 | where 348 | go : Args -> Args -> List DictionaryMemberRest -> Codegen CGFunction 349 | go xs ys [] = pure $ DictConstructor o (reverse xs ++ reverse ys) 350 | go xs ys (Required _ t n :: zs) = 351 | do t2 <- tpe t 352 | go (Mandatory (MkArgName n.value) t2 :: xs) ys zs 353 | go xs ys (Optional t n d :: zs) = 354 | do t2 <- tpe t 355 | go xs (Optional (MkArgName n.value) t2 d :: ys) zs 356 | 357 | dictFuns : Dictionary -> Codegen (List CGFunction) 358 | dictFuns d = 359 | [| dictCon (kind d.name) (map snd d.members) :: 360 | (map join (traverse (fromMember . snd) d.members)) 361 | |] 362 | 363 | where 364 | fromMember : DictionaryMemberRest -> Codegen (List CGFunction) 365 | fromMember (Required _ t n) = 366 | let an := Right $ MkAttributeName n.value 367 | in map pure [| Attribute an (pure $ kind d.name) 368 | (valArg t) (rtpe t) |] 369 | 370 | fromMember (Optional t n def) = 371 | let an := Right $ MkAttributeName n.value 372 | cgt := map (`UndefOr` Just def) (tpe t) 373 | ak := Right $ kind d.name 374 | in map pure [| Attribute an ak (optArg t def) cgt |] 375 | 376 | mixinFuns : Mixin -> Codegen (List CGFunction) 377 | mixinFuns m = concat <$> traverse (fromMember . snd) m.members 378 | 379 | where 380 | fromMember : MixinMember -> Codegen (List CGFunction) 381 | fromMember (MConst _) = Right Nil 382 | fromMember (MOp o) = op m.name o 383 | fromMember (MStr s) = str m.name s 384 | fromMember (MAttrRO ro) = attrRO m.name ro 385 | fromMember (MAttr at) = attr m.name at 386 | 387 | ifaceFuns : Interface -> Codegen (List CGFunction) 388 | ifaceFuns i = concat <$> traverse (fromMember . snd) i.members 389 | 390 | where 391 | getter : IdlType -> ArgumentList -> Codegen (List CGFunction) 392 | getter t (NoVarArg [a] Nil) = do 393 | ag <- arg a 394 | rt <- rtpe t 395 | if isIndex (argType ag) 396 | then Right [Getter (kind i.name) ag rt] 397 | else Left [InvalidGetter dom i.name] 398 | 399 | getter _ _ = Left [InvalidGetter dom i.name] 400 | 401 | setter : IdlType -> ArgumentList -> Codegen (List CGFunction) 402 | setter t (NoVarArg [a,r] Nil) = do 403 | ag <- arg a 404 | rt <- rtpe t 405 | rg <- arg r 406 | if isIndex (argType ag) && isUndefined rt 407 | then Right [Setter (kind i.name) ag rg] 408 | else Left [InvalidSetter dom i.name] 409 | 410 | setter _ _ = Left [InvalidSetter dom i.name] 411 | 412 | -- getters and setters without a name are treated as indexed 413 | -- versions (special syntax in the FFI), all others are treated 414 | -- as regular operations 415 | fromOp : Operation -> Codegen (List CGFunction) 416 | fromOp (MkOp (Just Getter) t Nothing as) = getter t as 417 | fromOp (MkOp (Just Setter) t Nothing as) = setter t as 418 | fromOp (MkOp (Just Deleter) _ _ _ ) = Right Nil 419 | fromOp x = op i.name x 420 | 421 | fromPart : PartialInterfaceMember -> Codegen (List CGFunction) 422 | fromPart (IOp x) = fromOp x 423 | fromPart (IStr x) = str i.name x 424 | fromPart (IStatic $ Z x) = staticAttr i.name x 425 | fromPart (IStatic $ S $ Z x) = staticAttrRO i.name x 426 | fromPart (IStatic $ S $ S $ Z x) = static i.name x 427 | fromPart (IAttr x) = attr i.name x 428 | fromPart (IAttrRO x) = attrRO i.name x 429 | fromPart (IConst _) = Right Nil 430 | fromPart (IMap x) = Right Nil 431 | fromPart (ISet x) = Right Nil 432 | fromPart (IMapRO x) = Right Nil 433 | fromPart (ISetRO x) = Right Nil 434 | fromPart (IAttrInh x) = Right Nil 435 | fromPart (IIterable x y) = Right Nil 436 | fromPart (IAsync x y xs) = Right Nil 437 | 438 | fromMember : InterfaceMember -> Codegen (List CGFunction) 439 | fromMember (Z $ MkConstructor as) = constr i.name as 440 | fromMember (S $ Z p) = fromPart p 441 | fromMember (S $ S x) impossible 442 | 443 | ifaceConsts : Interface -> Codegen (List CGConst) 444 | ifaceConsts (MkInterface _ _ _ ms) = join <$> traverse (fromMember . snd) ms 445 | 446 | where 447 | fromMember : InterfaceMember -> Codegen (List CGConst) 448 | fromMember (S $ Z $ IConst x) = map pure $ const x 449 | fromMember _ = Right [] 450 | 451 | mixinConsts : Mixin -> Codegen (List CGConst) 452 | mixinConsts (MkMixin _ _ ms) = join <$> traverse (fromMember . snd) ms 453 | where 454 | fromMember : MixinMember -> Codegen (List CGConst) 455 | fromMember (MConst x) = map pure $ const x 456 | fromMember _ = Right [] 457 | 458 | callbackConsts : CallbackInterface -> Codegen (List CGConst) 459 | callbackConsts (MkCallbackInterface _ _ ms) = 460 | join <$> traverse (fromMember . snd) ms 461 | 462 | where 463 | fromMember : CallbackInterfaceMember -> Codegen (List CGConst) 464 | fromMember v = 465 | case extract Const v of 466 | Nothing => Right [] 467 | Just x => map pure $ const x 468 | 469 | export 470 | domain : Codegen CGDomain 471 | domain = 472 | [| MkDomain 473 | (pure dom.domain) 474 | callbacks 475 | (traverse dict dom.dictionaries) 476 | (pure dom.enums) 477 | (traverse iface dom.interfaces) 478 | (traverse mixin dom.mixins) 479 | |] 480 | 481 | where 482 | dict : Dictionary -> Codegen CGDict 483 | dict v@(MkDictionary _ n i _) = 484 | MkDict n (supertypes n) <$> dictFuns v 485 | 486 | iface : Interface -> Codegen CGIface 487 | iface v@(MkInterface _ n i _) = 488 | [| MkIface 489 | (pure n) 490 | (pure $ supertypes n) 491 | (ifaceConsts v) 492 | (ifaceFuns v) 493 | |] 494 | 495 | mixin : Mixin -> Codegen CGMixin 496 | mixin m = [| MkMixin (pure m.name) (mixinConsts m) (mixinFuns m) |] 497 | 498 | callback : Callback -> Codegen CGCallback 499 | callback c = 500 | [| MkCallback 501 | (pure c.name) 502 | (pure Nil) 503 | (rtpe c.type) 504 | (toArgs c.args) 505 | |] 506 | 507 | callbackIface : CallbackInterface -> Codegen CGCallback 508 | callbackIface v@(MkCallbackInterface _ n ms) = 509 | case mapMaybe (\(_,m) => extract RegularOperation m) ms of 510 | [MkOp () t _ a] => 511 | [| MkCallback (pure n) (callbackConsts v) (rtpe t) (toArgs a) |] 512 | xs => Left [CBInterfaceInvalidOps dom n (length xs)] 513 | 514 | callbacks : Codegen (List CGCallback) 515 | callbacks = 516 | [| traverse callback dom.callbacks ++ 517 | traverse callbackIface dom.callbackInterfaces 518 | |] 519 | -------------------------------------------------------------------------------- /src/Text/WebIDL/Codegen/Types.idr: -------------------------------------------------------------------------------- 1 | module Text.WebIDL.Codegen.Types 2 | 3 | import Derive.Prelude 4 | import public Data.SortedMap 5 | import Text.WebIDL.Types 6 | 7 | %default total 8 | %language ElabReflection 9 | 10 | -------------------------------------------------------------------------------- 11 | -- Kinds 12 | -------------------------------------------------------------------------------- 13 | 14 | ||| The kind of a WebIDL identifier. 15 | ||| 16 | ||| This is needed when converting external types to Idris2 types 17 | ||| in the code generator: Aliases need to be resolved, Enums 18 | ||| converted to their `String` representation, Callback arguments 19 | ||| are Idris2 functions that need to be converted to an external 20 | ||| type. 21 | public export 22 | data Kind : Type where 23 | KAlias : Identifier -> Kind 24 | KCallback : Identifier -> Kind 25 | KDictionary : Identifier -> Kind 26 | KEnum : Identifier -> Kind 27 | KInterface : (isParent : Bool) -> Identifier -> Kind 28 | KMixin : Identifier -> Kind 29 | KOther : Identifier -> Kind 30 | 31 | %runElab derive "Kind" [Eq,Show] 32 | 33 | public export 34 | isParent : Kind -> Bool 35 | isParent (KDictionary _) = True 36 | isParent (KInterface b _) = b 37 | isParent (KMixin _) = True 38 | isParent _ = False 39 | 40 | public export 41 | ident : Kind -> Identifier 42 | ident (KAlias x) = x 43 | ident (KCallback x) = x 44 | ident (KDictionary x) = x 45 | ident (KEnum x) = x 46 | ident (KInterface _ x) = x 47 | ident (KMixin x) = x 48 | ident (KOther x) = x 49 | 50 | public export 51 | kindToString : Kind -> String 52 | kindToString = value . ident 53 | 54 | public export 55 | data Wrapper = Direct | Opt | May | OptMay 56 | 57 | public export 58 | opt : Wrapper -> Wrapper 59 | opt Direct = Opt 60 | opt May = OptMay 61 | opt i = i 62 | 63 | public export 64 | may : Wrapper -> Wrapper 65 | may Direct = May 66 | may i = i 67 | 68 | -------------------------------------------------------------------------------- 69 | -- Types 70 | -------------------------------------------------------------------------------- 71 | public export 72 | data SimpleType : Type 73 | 74 | public export 75 | data CGType : Type 76 | 77 | data SimpleType : Type where 78 | ||| The undefined type (or () if it is a return type) 79 | Undef : SimpleType 80 | 81 | ||| `Boolean` at the FFI, `Bool` in the API. 82 | Boolean : SimpleType 83 | 84 | ||| A Web IDL interface. This has an instance of `SafeCast`, 85 | ||| and is being abstracted over when used in an argument 86 | ||| list in the API, but only, when the `isParent` flag is set to true. 87 | ||| If this flag is `False`, meaning that there are no subtypes of 88 | ||| this type, we do not abstract over the type to improve 89 | ||| type inference. 90 | Interface : (isParent : Bool) -> Identifier -> SimpleType 91 | 92 | ||| A dictionary, specifying a Javascript object with a 93 | ||| set of mandatory and optional attributes. 94 | ||| This is always abstracted over, since theoretically 95 | ||| every value with the same set of attributes is 96 | ||| a dictionary of the given type. 97 | ||| 98 | ||| The type of a dictionary cannot be verified at 99 | ||| runtime, therefore they have no instance of `SafeCast`. 100 | Dictionary : Identifier -> SimpleType 101 | 102 | ||| A Web IDL `Mixin` is a set of attributes and operations (functions) 103 | ||| shared by several types. A type includes a given mixin, if 104 | ||| a corresponding `includes` statement is provided in the spec. 105 | ||| 106 | ||| Mixins do not define new types, and whether a value implements 107 | ||| a given mixin can typcally not be verified at runtime, therefore 108 | ||| mixins come without an instance of `SafeCast`. 109 | ||| runtime, therefore they have no instance of `SafeCast`. 110 | Mixin : Identifier -> SimpleType 111 | 112 | ||| Primitive type or a wrapper of a primitive. 113 | ||| This is the same at the FFI and API and 114 | ||| has an instance of `SafeCast`. 115 | Primitive : String -> SimpleType 116 | 117 | ||| Types that do not change between FFI and API 118 | Unchangeable : String -> SimpleType 119 | 120 | ||| Enum type at the API, Strings at the FFI 121 | Enum : Identifier -> SimpleType 122 | 123 | ||| Some kind of Array 124 | Array : CGType -> SimpleType 125 | 126 | ||| Some kind of Record 127 | Record : String -> CGType -> SimpleType 128 | 129 | data CGType : Type where 130 | Any : CGType 131 | Promise : CGType -> CGType 132 | Simple : Nullable SimpleType -> CGType 133 | Union : Nullable (List1 SimpleType) -> CGType 134 | 135 | ||| True, if the type can be used as an index in a 136 | ||| WebIDL `Getter` or `Setter`, that is, it corresponds 137 | ||| to either an `unsigned long` or a `DOMString`. 138 | export 139 | isIndex : CGType -> Bool 140 | isIndex (Simple $ NotNull $ Primitive "String") = True 141 | isIndex (Simple $ NotNull $ Primitive "Bits32") = True 142 | isIndex _ = False 143 | 144 | namespace SimpleType 145 | ||| True, if the FFI representation of the given type 146 | ||| has a `SafeCast` implementation 147 | export 148 | safeCast : SimpleType -> Bool 149 | safeCast Undef = True 150 | safeCast Boolean = True 151 | safeCast (Interface _ x) = True 152 | safeCast (Dictionary _) = False 153 | safeCast (Mixin _) = False 154 | safeCast (Primitive x) = True 155 | safeCast (Unchangeable x) = False 156 | safeCast (Enum x) = True 157 | safeCast (Array x) = False 158 | safeCast (Record x y) = False 159 | 160 | ||| True, if the type uses the same representation in 161 | ||| the FFI and the API as a function argument 162 | export 163 | sameArgType : SimpleType -> Bool 164 | sameArgType Undef = True 165 | sameArgType Boolean = False 166 | sameArgType (Interface b _) = not b 167 | sameArgType (Dictionary _) = False 168 | sameArgType (Mixin _) = False 169 | sameArgType (Primitive t) = True 170 | sameArgType (Unchangeable _) = True 171 | sameArgType (Enum _) = False 172 | sameArgType (Array _) = True 173 | sameArgType (Record _ _) = True 174 | 175 | ||| True, if the type uses the same representation in 176 | ||| the FFI and the API as a return value. 177 | export 178 | sameRetType : SimpleType -> Bool 179 | sameRetType Undef = True 180 | sameRetType Boolean = False 181 | sameRetType (Interface _ _) = True 182 | sameRetType (Dictionary _) = True 183 | sameRetType (Mixin _) = True 184 | sameRetType (Primitive _) = True 185 | sameRetType (Unchangeable _) = True 186 | sameRetType (Enum _) = False 187 | sameRetType (Array _) = True 188 | sameRetType (Record _ _) = True 189 | 190 | export 191 | inheritance : SimpleType -> Maybe (Identifier,Wrapper) 192 | inheritance (Interface True x) = Just (x,Direct) 193 | inheritance (Dictionary x) = Just (x,Direct) 194 | inheritance (Mixin x) = Just (x,Direct) 195 | inheritance _ = Nothing 196 | 197 | namespace CGType 198 | 199 | public export 200 | simple : SimpleType -> CGType 201 | simple = Simple . NotNull 202 | 203 | public export 204 | unchangeable : String -> CGType 205 | unchangeable = simple . Unchangeable 206 | 207 | public export 208 | iface : Bool -> Identifier -> CGType 209 | iface b = simple . Interface b 210 | 211 | public export 212 | mixin : Identifier -> CGType 213 | mixin = simple . Mixin 214 | 215 | public export 216 | dict : Identifier -> CGType 217 | dict = simple . Dictionary 218 | 219 | ||| Wrapps the given kind in return type. 220 | export 221 | fromKind : Kind -> CGType 222 | fromKind (KAlias x) = unchangeable x.value 223 | fromKind (KCallback x) = unchangeable x.value 224 | fromKind (KDictionary x) = dict x 225 | fromKind (KEnum x) = Simple . NotNull $ Enum x 226 | fromKind (KInterface b x) = iface b x 227 | fromKind (KMixin x) = mixin x 228 | fromKind (KOther x) = unchangeable x.value 229 | 230 | ||| True, if the FFI representation of the given type 231 | ||| has a `SafeCast` implementation 232 | export 233 | safeCast : CGType -> Bool 234 | safeCast Any = True 235 | safeCast (Promise x) = False 236 | safeCast (Simple x) = safeCast $ nullVal x 237 | safeCast (Union _) = False 238 | 239 | ||| True, if the given type is the same in the API and 240 | ||| the FFI when used as an argument 241 | export 242 | sameArgType : CGType -> Bool 243 | sameArgType Any = False 244 | sameArgType (Promise x) = True 245 | sameArgType (Simple $ MaybeNull _) = False 246 | sameArgType (Simple $ NotNull x) = sameArgType x 247 | sameArgType (Union _) = False 248 | 249 | ||| True, if the given type is the same in the API and 250 | ||| the FFI when used as a return value 251 | export 252 | sameRetType : CGType -> Bool 253 | sameRetType Any = False 254 | sameRetType (Promise x) = True 255 | sameRetType (Simple $ MaybeNull _) = False 256 | sameRetType (Simple $ NotNull x) = sameRetType x 257 | sameRetType (Union $ MaybeNull _) = False 258 | sameRetType (Union $ NotNull xs) = not $ all safeCast xs 259 | 260 | export 261 | inheritance : CGType -> Maybe (Identifier,Wrapper) 262 | inheritance (Simple $ MaybeNull x) = map may <$> inheritance x 263 | inheritance (Simple $ NotNull x) = inheritance x 264 | inheritance _ = Nothing 265 | 266 | -------------------------------------------------------------------------------- 267 | -- ReturnType 268 | -------------------------------------------------------------------------------- 269 | 270 | ||| A function's return type. 271 | public export 272 | data ReturnType : Type where 273 | ||| This will be mapped to `()` in the codegen. 274 | Undefined : ReturnType 275 | 276 | ||| The attribute in question might not be defined 277 | ||| The return type will be wrapped in `UndefOr` in 278 | ||| the code generator. 279 | UndefOr : CGType -> Maybe Default -> ReturnType 280 | 281 | ||| Nothing special about the wrapped return type. 282 | Def : CGType -> ReturnType 283 | 284 | ||| Checks if the return type is `Undefined`. 285 | public export 286 | isUndefined : ReturnType -> Bool 287 | isUndefined Undefined = True 288 | isUndefined _ = False 289 | 290 | namespace ReturnType 291 | 292 | public export 293 | simple : SimpleType -> ReturnType 294 | simple = Def . simple 295 | 296 | public export 297 | unchangeable : String -> ReturnType 298 | unchangeable = Def . unchangeable 299 | 300 | ||| Wrapps the given kind in return type. 301 | export 302 | fromKind : Kind -> ReturnType 303 | fromKind = Def . CGType.fromKind 304 | 305 | ||| True, if the given FFI type has a `SafeCast` instance 306 | export 307 | safeCast : ReturnType -> Bool 308 | safeCast Undefined = True 309 | safeCast (UndefOr x _) = safeCast x 310 | safeCast (Def x) = safeCast x 311 | 312 | ||| True, if the given return type is the same in the API and 313 | ||| the FFI. 314 | export 315 | sameType : ReturnType -> Bool 316 | sameType Undefined = True 317 | sameType (UndefOr _ _) = False 318 | sameType (Def x) = sameRetType x 319 | 320 | -------------------------------------------------------------------------------- 321 | -- Constants 322 | -------------------------------------------------------------------------------- 323 | 324 | public export 325 | record CGConstType where 326 | constructor MkConstType 327 | primitive : String 328 | 329 | public export 330 | record CGConst where 331 | constructor MkConst 332 | type : CGConstType 333 | name : Identifier 334 | value : ConstValue 335 | 336 | -------------------------------------------------------------------------------- 337 | -- Arguments 338 | -------------------------------------------------------------------------------- 339 | 340 | ||| A function argument in the code generator. 341 | public export 342 | data CGArg : Type where 343 | ||| A mandatory function argument 344 | Mandatory : ArgumentName -> CGType -> CGArg 345 | 346 | ||| An optional function argument together with its 347 | ||| default value if the argument is `undefined`. 348 | Optional : ArgumentName -> CGType -> Default -> CGArg 349 | 350 | ||| A variadic function argument 351 | VarArg : ArgumentName -> CGType -> CGArg 352 | 353 | export 354 | argName : CGArg -> ArgumentName 355 | argName (Mandatory x _) = x 356 | argName (Optional x _ _) = x 357 | argName (VarArg x _) = x 358 | 359 | export 360 | argType : CGArg -> CGType 361 | argType (Mandatory _ y) = y 362 | argType (Optional _ y _) = y 363 | argType (VarArg _ y) = y 364 | 365 | export 366 | isOptional : CGArg -> Bool 367 | isOptional (Optional _ _ _) = True 368 | isOptional _ = False 369 | 370 | namespace CGArg 371 | 372 | ||| True, if the given FFI type has a `SafeCast` instance 373 | export 374 | safeCast : CGArg -> Bool 375 | safeCast (Mandatory _ t) = safeCast t 376 | safeCast (Optional _ t _) = safeCast t 377 | safeCast (VarArg _ _) = False 378 | 379 | ||| True, if the given argument type is the same in the API and 380 | ||| the FFI. 381 | export 382 | sameType : CGArg -> Bool 383 | sameType (Mandatory _ t) = sameArgType t 384 | sameType (Optional _ _ _) = False 385 | sameType (VarArg _ _) = False 386 | 387 | export 388 | inheritance : CGArg -> Maybe (Identifier,Wrapper) 389 | inheritance (Mandatory _ t) = inheritance t 390 | inheritance (Optional _ t _) = map opt <$> inheritance t 391 | inheritance (VarArg _ _) = Nothing 392 | 393 | public export 394 | Args : Type 395 | Args = List CGArg 396 | 397 | -------------------------------------------------------------------------------- 398 | -- Functions 399 | -------------------------------------------------------------------------------- 400 | 401 | ||| A function, for which we will generate some code. 402 | public export 403 | data CGFunction : Type where 404 | ||| A read-write attribute 405 | Attribute : 406 | (name : AttributeName) 407 | -> (obj : Kind) 408 | -> (tpe : CGArg) 409 | -> (ret : ReturnType) 410 | -> CGFunction 411 | 412 | ||| An attribute getter. 413 | AttributeGet : 414 | (name : AttributeName) 415 | -> (obj : Kind) 416 | -> (tpe : ReturnType) 417 | -> CGFunction 418 | 419 | ||| A static attribute setter. 420 | StaticAttributeSet : 421 | (name : AttributeName) 422 | -> (obj : Kind) 423 | -> (tpe : CGArg) 424 | -> CGFunction 425 | 426 | ||| A static attribute getter. 427 | StaticAttributeGet : 428 | (name : AttributeName) 429 | -> (obj : Kind) 430 | -> (tpe : ReturnType) 431 | -> CGFunction 432 | 433 | ||| An indexed getter. 434 | Getter : (obj : Kind) -> (index : CGArg) -> (tpe : ReturnType) -> CGFunction 435 | 436 | ||| An indexed setter. 437 | Setter : (obj : Kind) -> (index : CGArg) -> (value : CGArg) -> CGFunction 438 | 439 | ||| An interface constructor with (possibly) optional arguments. 440 | Constructor : (obj : Kind) -> (args : Args) -> CGFunction 441 | 442 | ||| An interface constructor with (possibly) optional arguments. 443 | DictConstructor : (obj : Kind) -> (args : Args) -> CGFunction 444 | 445 | ||| A regular function with (possibly) optional arguments. 446 | Regular : 447 | OperationName 448 | -> (obj : Kind) 449 | -> Args 450 | -> ReturnType 451 | -> CGFunction 452 | 453 | ||| A static function with (possibly) optional arguments. 454 | Static : 455 | OperationName 456 | -> (obj : Kind) 457 | -> Args 458 | -> ReturnType 459 | -> CGFunction 460 | 461 | ||| This is used for sorting lists of functions to 462 | ||| determine the order in which they appear 463 | ||| in the generated code. 464 | ||| 465 | ||| Attributes will come first, sorted by name, 466 | ||| setters, getters, and unsetter grouped together in 467 | ||| that order. 468 | ||| 469 | ||| All other functions come later and will be sorted by name. 470 | export 471 | priority : CGFunction -> (Nat,String,Nat) 472 | priority (DictConstructor n _) = (0,value (ident n),0) 473 | priority (Constructor n _) = (0,value (ident n),0) 474 | priority (StaticAttributeSet n _ _) = (1,show n,1) 475 | priority (StaticAttributeGet n _ _) = (1,show n,0) 476 | priority (Static n o _ _) = (2,n.value ++ value (ident o),0) 477 | priority (Getter _ _ _) = (3,"",0) 478 | priority (Setter _ _ _) = (3,"",1) 479 | priority (Attribute n _ _ _) = (4,show n,0) 480 | priority (AttributeGet n _ _) = (4,show n,1) 481 | priority (Regular n o _ _) = (5,n.value ++ value (ident o),0) 482 | 483 | -------------------------------------------------------------------------------- 484 | -- Inheritance 485 | -------------------------------------------------------------------------------- 486 | 487 | ||| An external, un-parameterized Javascript type, represented 488 | ||| by an identifier. Such a type comes with a parent 489 | ||| type (given as an `inheritance` value in the spec) 490 | ||| and a number of mixed in types. 491 | ||| 492 | ||| The actual name of the type is not included, as the set 493 | ||| of types is given in `Env` as a `SortedMap`. 494 | public export 495 | record JSType where 496 | constructor MkJSType 497 | parent : Maybe Identifier 498 | mixins : List Identifier 499 | 500 | ||| The parent types and mixins of a type. This is 501 | ||| used by the code generator to implement the 502 | ||| `JS.Inheritance.JSType` instances. 503 | public export 504 | record Supertypes where 505 | constructor MkSupertypes 506 | parents : List Identifier 507 | mixins : List Identifier 508 | 509 | -------------------------------------------------------------------------------- 510 | -- Domain 511 | -------------------------------------------------------------------------------- 512 | 513 | public export 514 | record CGDict where 515 | constructor MkDict 516 | name : Identifier 517 | super : Supertypes 518 | functions : List CGFunction 519 | 520 | public export 521 | record CGIface where 522 | constructor MkIface 523 | name : Identifier 524 | super : Supertypes 525 | constants : List CGConst 526 | functions : List CGFunction 527 | 528 | public export 529 | record CGMixin where 530 | constructor MkMixin 531 | name : Identifier 532 | constants : List CGConst 533 | functions : List CGFunction 534 | 535 | public export 536 | record CGCallback where 537 | constructor MkCallback 538 | name : Identifier 539 | constants : List CGConst 540 | type : ReturnType 541 | args : Args 542 | 543 | public export 544 | record CGDomain where 545 | constructor MkDomain 546 | name : String 547 | callbacks : List CGCallback 548 | dicts : List CGDict 549 | enums : List Enum 550 | ifaces : List CGIface 551 | mixins : List CGMixin 552 | 553 | export 554 | domainFunctions : CGDomain -> List CGFunction 555 | domainFunctions d = 556 | (d.dicts >>= functions) 557 | ++ (d.ifaces >>= functions) 558 | ++ (d.mixins >>= functions) 559 | 560 | -------------------------------------------------------------------------------- 561 | -- Environment 562 | -------------------------------------------------------------------------------- 563 | 564 | ||| Codegen environment. 565 | ||| 566 | ||| This includes a mapping from identifiers to the kinds 567 | ||| they represent, a mapping from identifiers to their 568 | ||| inheritance relations (`jsTypes`) and a mapping of 569 | ||| type aliases. 570 | ||| 571 | ||| The `maxInheritance` constant is used when calculating a 572 | ||| type's supertypes to avoid a potentially infinite loop. 573 | public export 574 | record Env where 575 | constructor MkEnv 576 | maxInheritance : Nat 577 | kinds : SortedMap Identifier Kind 578 | jsTypes : SortedMap Identifier JSType 579 | aliases : SortedMap Identifier (IdlTypeF ExtAttributeList Kind) 580 | 581 | -------------------------------------------------------------------------------- 582 | -- Codegen Errors 583 | -------------------------------------------------------------------------------- 584 | 585 | public export 586 | data CodegenErr : Type where 587 | AnyInUnion : Domain -> CodegenErr 588 | CBInterfaceInvalidOps : Domain -> Identifier -> Nat -> CodegenErr 589 | InvalidConstType : Domain -> CodegenErr 590 | InvalidGetter : Domain -> Identifier -> CodegenErr 591 | InvalidSetter : Domain -> Identifier -> CodegenErr 592 | NullableAny : Domain -> CodegenErr 593 | NullablePromise : Domain -> CodegenErr 594 | PromiseInUnion : Domain -> CodegenErr 595 | RegularOpWithoutName : Domain -> Identifier -> CodegenErr 596 | UnresolvedAlias : Domain -> Identifier -> CodegenErr 597 | 598 | public export 599 | Codegen : Type -> Type 600 | Codegen = Either (List CodegenErr) 601 | -------------------------------------------------------------------------------- /src/Text/WebIDL/Codegen/Util.idr: -------------------------------------------------------------------------------- 1 | module Text.WebIDL.Codegen.Util 2 | 3 | import Data.List 4 | import Data.Nat 5 | import Data.Stream 6 | import public Data.String 7 | import public Data.Vect 8 | import public Text.PrettyPrint.Bernardy 9 | import public Text.WebIDL.Codegen.Types 10 | import public Text.WebIDL.Types 11 | 12 | %default total 13 | 14 | export 15 | mapFirstChar : (Char -> Char) -> String -> String 16 | mapFirstChar f x = case unpack x of 17 | [] => "" 18 | h :: t => pack (f h :: t) 19 | 20 | -------------------------------------------------------------------------------- 21 | -- Sorted Lists 22 | -------------------------------------------------------------------------------- 23 | 24 | export 25 | sortedNubOn : Ord b => (a -> b) -> List a -> List a 26 | sortedNubOn f = nub . sortBy (comparing f) 27 | 28 | where 29 | nub : List a -> List a 30 | nub (x :: t@(y :: ys)) = if f x == f y then nub t else x :: nub t 31 | nub xs = xs 32 | 33 | -------------------------------------------------------------------------------- 34 | -- Modules 35 | -------------------------------------------------------------------------------- 36 | 37 | export 38 | moduleName : String -> String 39 | moduleName "uievents" = "UIEvents" 40 | moduleName s = mapFirstChar toUpper s 41 | 42 | -------------------------------------------------------------------------------- 43 | -- String Literals 44 | -------------------------------------------------------------------------------- 45 | 46 | export 47 | unquote : String -> List Char 48 | unquote = run . unpack 49 | 50 | where 51 | run : List Char -> List Char 52 | run [] = [] 53 | run ('\\' :: '"' :: cs) = '"' :: run cs 54 | run ('"' :: cs) = run cs 55 | run (c :: cs) = c :: run cs 56 | 57 | ||| Generates a data constructor from a string literal. 58 | ||| This is used for enums, where some values are not 59 | ||| valid idris identifiers. Some necessary adjustments 60 | ||| are hardcoded here. 61 | export 62 | toDataConstructor : String -> String 63 | toDataConstructor s = case unquote s of 64 | [] => "Empty" 65 | ['2','d'] => "TwoD" 66 | c :: cs => pack (toUpper c :: run cs) 67 | 68 | where 69 | run : List Char -> List Char 70 | run [] = [] 71 | run (x :: xs@(c :: cs)) = 72 | if isAlphaNum x then x :: run xs else toUpper c :: run cs 73 | run (c :: cs) = c :: run cs 74 | 75 | -------------------------------------------------------------------------------- 76 | -- Comments 77 | -------------------------------------------------------------------------------- 78 | 79 | export 80 | title : String -> String 81 | title n = """ 82 | -------------------------------------------------------------------------------- 83 | -- \{n} 84 | -------------------------------------------------------------------------------- 85 | """ 86 | 87 | export 88 | section : String -> List String -> String 89 | section _ Nil = "" 90 | section t ds = unlines ("" :: title t :: ds) 91 | 92 | -------------------------------------------------------------------------------- 93 | -- Namespaces Implementations 94 | -------------------------------------------------------------------------------- 95 | 96 | export 97 | namespaced : Identifier -> List String -> String 98 | namespaced _ [] = "" 99 | namespaced n ds = unlines $ "" :: "namespace \{n.value}" :: ds 100 | 101 | -------------------------------------------------------------------------------- 102 | -- Generating Functions 103 | -------------------------------------------------------------------------------- 104 | 105 | parameters {opts : LayoutOpts} 106 | 107 | export 108 | functionTypeOnly : (res : Doc opts) -> (args : List $ Doc opts) -> Doc opts 109 | functionTypeOnly res [] = parens $ "() ->" <++> res 110 | functionTypeOnly res (h::t) = 111 | let withArrows := map (line "->" <++>) (t ++ [res]) 112 | sl := parens (hsep $ h :: withArrows) 113 | ml := vsep $ (line "( " <+> h) :: withArrows ++ [line ")"] 114 | in ifMultiline sl ml 115 | 116 | export 117 | functionType : 118 | (name : IdrisIdent) 119 | -> (sep : String) 120 | -> (res : Doc opts) 121 | -> (args : List $ Doc opts) 122 | -> Doc opts 123 | functionType nm sep res [] = 124 | let head := line "\{nm} \{sep}" 125 | in ifMultiline (head <++> res) (vappend head $ indent 2 res) 126 | functionType nm sep res (h::t) = 127 | let head := line "\{nm} \{sep}" 128 | withArrows := map (line "->" <++>) (t ++ [res]) 129 | sl := hsep $ head :: h :: withArrows 130 | ml := vsep $ indent 3 h :: withArrows 131 | in ifMultiline sl (vappend head $ indent 2 ml) 132 | 133 | export 134 | typeDecl : 135 | (name : IdrisIdent) 136 | -> (res : Doc opts) 137 | -> (args : List $ Doc opts) 138 | -> Doc opts 139 | typeDecl n = functionType n ":" 140 | -- 141 | -------------------------------------------------------------------------------- 142 | -- Function Names 143 | -------------------------------------------------------------------------------- 144 | 145 | ix : Nat -> String 146 | ix Z = "" 147 | ix k = show k 148 | 149 | export 150 | primSetter : Nat -> IdrisIdent 151 | primSetter k = Prim . fromString $ "set" ++ ix k 152 | 153 | export 154 | setter : Nat -> IdrisIdent 155 | setter k = fromString $ "set" ++ ix k 156 | 157 | export 158 | primGetter : Nat -> IdrisIdent 159 | primGetter k = Prim . fromString $ "get" ++ ix k 160 | 161 | export 162 | getter : Nat -> IdrisIdent 163 | getter k = fromString $ "get" ++ ix k 164 | 165 | export 166 | primAttrSetter : Nat -> AttributeName -> IdrisIdent 167 | primAttrSetter k n = 168 | Prim $ fromString ("set" ++ mapFirstChar toUpper n.value ++ ix k) 169 | 170 | export 171 | attrSetter : Nat -> AttributeName -> IdrisIdent 172 | attrSetter k n = fromString $ "set" ++ mapFirstChar toUpper n.value ++ ix k 173 | 174 | export 175 | primAttrGetter : Nat -> AttributeName -> IdrisIdent 176 | primAttrGetter k n = Prim $ fromString (n.value ++ ix k) 177 | 178 | export 179 | attrGetter : Nat -> AttributeName -> IdrisIdent 180 | attrGetter k n = fromString $ n.value ++ ix k 181 | 182 | export 183 | primOp : Nat -> OperationName -> IdrisIdent 184 | primOp k n = Prim $ fromString (n.value ++ ix k) 185 | 186 | export 187 | op : Nat -> OperationName -> IdrisIdent 188 | op k n = fromString (n.value ++ ix k) 189 | 190 | export 191 | primConstr : Nat -> IdrisIdent 192 | primConstr k = Prim $ fromString ("new" ++ ix k) 193 | 194 | export 195 | constr : Nat -> IdrisIdent 196 | constr k = fromString ("new" ++ ix k) 197 | 198 | export 199 | marshallCallback : Identifier -> IdrisIdent 200 | marshallCallback i = fromString $ "to" ++ i.value 201 | 202 | export 203 | primMarshallCallback : Identifier -> IdrisIdent 204 | primMarshallCallback i = Prim . fromString $ "to" ++ i.value 205 | 206 | -------------------------------------------------------------------------------- 207 | -- Foreign Function Implementations 208 | -------------------------------------------------------------------------------- 209 | 210 | export 211 | argNames : Stream String 212 | argNames = 213 | "a" :: "b" :: "c" :: "d" :: "e" :: "f" :: "g" :: 214 | "h" :: "i" :: "j" :: "k" :: "l" :: "m" :: "n" :: 215 | "o" :: "p" :: "q" :: "r" :: "s" :: "t" :: "u" :: 216 | "v" :: "w" :: "y" :: "z" :: 217 | map (\v => "x" ++ show {ty = Integer} v) [1 ..] 218 | 219 | export 220 | unShadowingArgNames : IdrisIdent -> Stream String 221 | unShadowingArgNames i = go "\{i}" argNames 222 | where 223 | go : String -> Stream String -> Stream String 224 | go s (h :: t) = if s == h then t else h :: go s t 225 | 226 | foreignBrowser : String -> String 227 | foreignBrowser s = "%foreign \"browser:lambda:\{s}\"" 228 | 229 | export 230 | attrGetFFI : AttributeName -> String 231 | attrGetFFI n = foreignBrowser "x=>x.\{n.value}" 232 | 233 | export 234 | staticAttrGetFFI : Kind -> AttributeName -> String 235 | staticAttrGetFFI o n = 236 | foreignBrowser "()=>\{kindToString o}.\{n.value}" 237 | 238 | export 239 | attrSetFFI : AttributeName -> String 240 | attrSetFFI n = foreignBrowser "(x,v)=>{x.\{n.value} = v}" 241 | 242 | export 243 | staticAttrSetFFI : Kind -> AttributeName -> String 244 | staticAttrSetFFI o n = 245 | foreignBrowser "v=>{\{kindToString o}.\{n.value} = v}" 246 | 247 | export 248 | funFFI : OperationName -> Nat -> String 249 | funFFI n Z = foreignBrowser "x=>x.\{n.value}()" 250 | funFFI n k = 251 | let vs := take k argNames 252 | vals := fastConcat $ intersperse "," vs 253 | in foreignBrowser "(x,\{vals})=>x.\{n.value}(\{vals})" 254 | 255 | export 256 | funFFIVarArg : OperationName -> Nat -> String 257 | funFFIVarArg n k = 258 | let vs := take (pred k) argNames 259 | vals := fastConcat $ intersperse "," (vs ++ ["va"]) 260 | args := fastConcat $ intersperse "," (vs ++ ["...va()"]) 261 | in foreignBrowser "(x,\{vals})=>x.\{n.value}(\{args})" 262 | 263 | export 264 | staticFunFFI : Kind -> OperationName -> Nat -> String 265 | staticFunFFI o n Z = foreignBrowser "x=>x.\{n.value}()" 266 | staticFunFFI o n k = 267 | let vs := take k argNames 268 | vals := fastConcat $ intersperse "," vs 269 | in foreignBrowser "(\{vals})=>\{kindToString o}.\{n.value}(\{vals})" 270 | 271 | export 272 | staticFunFFIVarArg : Kind -> OperationName -> Nat -> String 273 | staticFunFFIVarArg o n k = 274 | let vs := take (pred k) argNames 275 | vals := fastConcat $ intersperse "," (vs ++ ["va"]) 276 | args := fastConcat $ intersperse "," (vs ++ ["...va()"]) 277 | in foreignBrowser "(\{vals})=>\{kindToString o}.\{n.value}(\{args})" 278 | 279 | export 280 | conFFI : Kind -> Nat -> String 281 | conFFI n k = 282 | let vs := take k argNames 283 | vals := fastConcat $ intersperse "," vs 284 | in foreignBrowser "(\{vals})=> new \{kindToString n}(\{vals})" 285 | 286 | export 287 | conFFIVarArg : Kind -> Nat -> String 288 | conFFIVarArg n k = 289 | let vs := take (pred k) argNames 290 | vals := fastConcat $ intersperse "," (vs ++ ["va"]) 291 | args := fastConcat $ intersperse "," (vs ++ ["...va()"]) 292 | in foreignBrowser "(\{vals})=> new \{kindToString n}(\{args})" 293 | 294 | export 295 | dictConFFI : List ArgumentName -> String 296 | dictConFFI ns = 297 | let vs := take (length ns) argNames 298 | vals := fastConcat $ intersperse "," vs 299 | fields := fastConcat $ intersperse "," (zipWith app vs ns) 300 | in foreignBrowser "(\{vals})=> ({\{fields}})" 301 | 302 | where 303 | app : String -> ArgumentName -> String 304 | app v a = a.value ++ ": " ++ v 305 | 306 | export 307 | getterFFI : String 308 | getterFFI = foreignBrowser "(o,x)=>o[x]" 309 | 310 | export 311 | setterFFI : String 312 | setterFFI = foreignBrowser "(o,x,v)=>o[x] = v" 313 | 314 | export 315 | callbackFFI : Nat -> String 316 | callbackFFI n = 317 | let vs := fastConcat $ intersperse "," $ take n argNames 318 | in foreignBrowser "x=>(\{vs})=>x(\{vs})()" 319 | 320 | -------------------------------------------------------------------------------- 321 | -- Pretty Printing 322 | -------------------------------------------------------------------------------- 323 | 324 | export %inline 325 | render80 : Doc (Opts 80) -> String 326 | render80 = render _ 327 | -------------------------------------------------------------------------------- /webidl.ipkg: -------------------------------------------------------------------------------- 1 | package webidl 2 | 3 | authors = "stefan-hoeck" 4 | version = 0.1.0 5 | sourcedir = "src" 6 | depends = base >= 0.6.0 7 | , parser-webidl 8 | , prettier 9 | , getopts 10 | 11 | main = Main 12 | executable = generateDomBindings 13 | 14 | modules = Text.WebIDL.Codegen 15 | , Text.WebIDL.Codegen.Args 16 | , Text.WebIDL.Codegen.Definitions 17 | , Text.WebIDL.Codegen.Enum 18 | , Text.WebIDL.Codegen.Members 19 | , Text.WebIDL.Codegen.Rules 20 | , Text.WebIDL.Codegen.Types 21 | , Text.WebIDL.Codegen.Util 22 | --------------------------------------------------------------------------------