diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d940b07..ae2da9c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +### 0.20.0 + +* Added binding for `HTMLVideoElement` +* Added binding for `HTMLMediaElement` +* Added binding for `MediaError` +* Added binding for `AudioTrack` +* Added binding for `AudioTrackList` +* Added binding for `TextTrack` +* Added binding for `TextTrackList` +* Added binding for `TextTrackCue` +* Added binding for `TextTrackCueList` +* Added binding for `VideoTrack` +* Added binding for `VideoTrackList` +* Added binding for `TimeRanges` + ### 0.19.2 * Removed peer dependency on `bsdoc` diff --git a/package.json b/package.json index 48b01682..0c995415 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bs-webapi", - "version": "0.19.2", + "version": "0.20.0", "description": "Reason + BuckleScript bindings to DOM", "repository": { "type": "git", diff --git a/src/Webapi.re b/src/Webapi.re index 00ccfa56..6a604c91 100644 --- a/src/Webapi.re +++ b/src/Webapi.re @@ -23,6 +23,24 @@ module Iterator = FormData.Iterator; module Performance = Webapi__Performance; +/** @since 0.20.0 */ +module AudioTrack = Webapi__AudioTrack; +/** @since 0.20.0 */ +module AudioTrackList = Webapi__AudioTrackList; + +/** @since 0.20.0 */ +module TextTrack = Webapi__TextTrack; +/** @since 0.20.0 */ +module TextTrackList = Webapi__TextTrackList; + +/** @since 0.20.0 */ +module VideoTrack = Webapi__VideoTrack; +/** @since 0.20.0 */ +module VideoTrackList = Webapi__VideoTrackList; + +/** @since 0.20.0 */ +module TimeRanges = Webapi__TimeRanges; + /** @since 0.19.0 */ module ReadableStream = Webapi__ReadableStream; diff --git a/src/Webapi/Dom/Webapi__Dom__HtmlMediaElement.re b/src/Webapi/Dom/Webapi__Dom__HtmlMediaElement.re new file mode 100644 index 00000000..a90478a2 --- /dev/null +++ b/src/Webapi/Dom/Webapi__Dom__HtmlMediaElement.re @@ -0,0 +1,139 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement + */ +module Impl = (T: {type t;}) => { + type t_htmlMediaElement = T.t; + + type mediaProvider; // TODO: one of MediaStream, MediaSource, or Blob + + /** Properties */ + [@bs.get] external buffered: t_htmlMediaElement => Webapi__TimeRanges.t = "buffered"; + + // This is part of the recommendation spec + // type mediaController; // TODO + // [@bs.get] [@bs.return nullable] external controller: t_htmlMediaElement => option(mediaController) = "controller"; + // [@bs.set] external setController: (t_htmlMediaElement, mediaController) => unit = "controller"; + + [@bs.get] external controls: t_htmlMediaElement => bool = "controls"; + [@bs.set] external setControls: (t_htmlMediaElement, bool) => unit = "controls"; + + /** One or more of "nodownload", "nofullscreen", and "noremoteplayback" */ + [@bs.get] external controlsList: t_htmlMediaElement => Dom.domTokenList = "controlsList"; + + [@bs.get] [@bs.return nullable] external crossOrigin: t_htmlMediaElement => option(string) = "crossOrigin"; + [@bs.set] + external setCrossOrigin: + ( + t_htmlMediaElement, + [@bs.string] [ | `anonymous | [@bs.as "use-credentials"] `useCredentials | [@bs.as ""] `empty] + ) => + unit = + "crossOrigin"; + + [@bs.get] external currentSrc: t_htmlMediaElement => string = "currentSrc"; + + [@bs.get] external currentTime: t_htmlMediaElement => float = "currentTime"; + [@bs.set] external setCurrentTime: (t_htmlMediaElement, float) => unit = "currentTime"; + + [@bs.get] external defaultMuted: t_htmlMediaElement => bool = "defaultMuted"; + [@bs.set] external setDefaultMuted: (t_htmlMediaElement, bool) => unit = "defaultMuted"; + + [@bs.get] external defaultPlaybackRate: t_htmlMediaElement => float = "defaultPlaybackRate"; + [@bs.set] external setDefaultPlaybackRate: (t_htmlMediaElement, float) => unit = "defaultPlaybackRate"; + + [@bs.get] external disableRemotePlayback: t_htmlMediaElement => bool = "disableRemotePlayback"; + [@bs.set] external setDisableRemotePlayback: (t_htmlMediaElement, bool) => unit = "disableRemotePlayback"; + + [@bs.get] external duration: t_htmlMediaElement => float = "duration"; + [@bs.get] external ended: t_htmlMediaElement => bool = "ended"; + [@bs.get] [@bs.return nullable] external error: t_htmlMediaElement => option(Webapi__Dom__MediaError.t) = "error"; + + [@bs.get] external loop: t_htmlMediaElement => bool = "loop"; + [@bs.set] external setLoop: (t_htmlMediaElement, bool) => unit = "loop"; + + // [@bs.get] external mediaGroup: t_htmlMediaElement => string = "mediaGroup"; // Not well supported + // [@bs.set] external setMediaGroup: (t_htmlMediaElement, string) => unit = "mediaGroup"; // Not well supported + + [@bs.get] external muted: t_htmlMediaElement => bool = "muted"; + [@bs.set] external setMuted: (t_htmlMediaElement, bool) => unit = "muted"; + + type mediaNetworkState = + | NetworkEmpty // 0 + | NetworkIdle // 1 + | NetworkLoading // 2 + | NetworkNoSource; // 3 + + let decodeNetworkState = fun + | 0 => Some(NetworkEmpty) + | 1 => Some(NetworkIdle) + | 2 => Some(NetworkLoading) + | 3 => Some(NetworkNoSource) + | _ => None; + + [@bs.get] external _networkState: t_htmlMediaElement => int = "networkState"; + let networkState = t_htmlMediaElement => _networkState(t_htmlMediaElement) |> decodeNetworkState; + + [@bs.get] external paused: t_htmlMediaElement => bool = "paused"; + + [@bs.get] external playbackRate: t_htmlMediaElement => float = "playbackRate"; + [@bs.set] external setPlaybackRate: (t_htmlMediaElement, float) => unit = "playbackRate"; + + [@bs.get] external played: t_htmlMediaElement => Webapi__TimeRanges.t = "played"; + [@bs.get] external preload: t_htmlMediaElement => string = "preload"; + + type readyStateEnum = + | HaveNothing + | HaveMetadata + | HaveCurrentData + | HaveFutureData + | HaveEnoughData; + + let decodeReadyState = fun + | 0 => Some(HaveNothing) + | 1 => Some(HaveMetadata) + | 2 => Some(HaveCurrentData) + | 3 => Some(HaveFutureData) + | 4 => Some(HaveEnoughData) + | _ => None; + + [@bs.get] external _readyState: t_htmlMediaElement => int = "readyState"; + let readyState = t => _readyState(t) |> decodeReadyState; + + [@bs.get] external seekable: t_htmlMediaElement => Webapi__TimeRanges.t = "seekable"; + [@bs.get] external seeking: t_htmlMediaElement => bool = "seeking"; + // [@bs.get] external sinkId: t_htmlMediaElement => string = "sinkId"; // experimental + + [@bs.get] external src: t_htmlMediaElement => string = "src"; + [@bs.set] external setSrc: (t_htmlMediaElement, string) => unit = "src"; + + [@bs.get] [@bs.return nullable] external srcObject: t_htmlMediaElement => option(mediaProvider) = "srcObject"; + + [@bs.get] external audioTracks: t_htmlMediaElement => Webapi__AudioTrackList.t = "textTracks"; + [@bs.get] external textTracks: t_htmlMediaElement => Webapi__TextTrackList.t = "textTracks"; + + // [@bs.get] external videoTracks: t_htmlMediaElement => Webapi__VideoTrackList.t = "videoTracks"; // Not widely available + + [@bs.get] external volume: t_htmlMediaElement => float = "volume"; + [@bs.set] external setVolume: (t_htmlMediaElement, float) => unit = "volume"; + + /** Methods */ + + [@bs.send] external addTextTrack: (t_htmlMediaElement, Webapi__TextTrack.textTrackKind, ~label: string, ~language: string, unit) => Webapi__TextTrack.t = "addTextTrack"; + + // return is one of "probably", "maybe", or "" + [@bs.send] external canPlayType: (t_htmlMediaElement, string) => string = "canPlayType"; + // [@bs.send] external fastSeek: (t_htmlMediaElement, float) => unit = "fastSeek"; // experimental + [@bs.send] external load: t_htmlMediaElement => unit = "load"; + [@bs.send] external pause: t_htmlMediaElement => unit = "pause"; + [@bs.send] external play: t_htmlMediaElement => Js.Promise.t(unit) = "play"; + + // [@bs.send] external getStartDate: t_htmlMediaElement => Js.Date.t = "getStartDate"; // not supported? +}; + +type t; // TODO: Dom.htmlMediaElement + +include Webapi__Dom__EventTarget.Impl({type nonrec t = t;}); +include Webapi__Dom__Node.Impl({type nonrec t = t;}); +include Webapi__Dom__Element.Impl({type nonrec t = t;}); +include Webapi__Dom__HtmlElement.Impl({type nonrec t = t;}); +include Impl({type nonrec t = t;}); diff --git a/src/Webapi/Dom/Webapi__Dom__HtmlVideoElement.re b/src/Webapi/Dom/Webapi__Dom__HtmlVideoElement.re new file mode 100644 index 00000000..c6fd2e83 --- /dev/null +++ b/src/Webapi/Dom/Webapi__Dom__HtmlVideoElement.re @@ -0,0 +1,32 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#htmlvideoelement + */ +module Impl = (T: {type t;}) => { + type t_htmlVideoElement = T.t; + + external unsafeOfElement: Dom.element => t_htmlVideoElement = "%identity"; + + let ofElement = (el): option(t_htmlVideoElement) => switch(Webapi__Dom__Element.tagName(el)) { + | "VIDEO" => el->unsafeOfElement->Some + | _ => None + }; + + /** Properties */ + [@bs.get] external height: t_htmlVideoElement => int = "height"; + [@bs.set] external setHeight: (t_htmlVideoElement, int) => unit = "height"; + [@bs.get] external poster: t_htmlVideoElement => string = "poster"; + [@bs.set] external setPoster: (t_htmlVideoElement, string) => unit = "poster"; + [@bs.get] external videoHeight: t_htmlVideoElement => int = "videoHeight"; + [@bs.get] external videoWidth: t_htmlVideoElement => int = "videoWidth"; + [@bs.get] external width: t_htmlVideoElement => int = "width"; + [@bs.set] external setWidth: (t_htmlVideoElement, int) => unit = "width"; +}; + +type t; // TODO: Dom.htmlVideoElement + +include Webapi__Dom__EventTarget.Impl({ type nonrec t = t; }); +include Webapi__Dom__Node.Impl({ type nonrec t = t; }); +include Webapi__Dom__Element.Impl({ type nonrec t = t; }); +include Webapi__Dom__HtmlElement.Impl({ type nonrec t = t; }); +include Webapi__Dom__HtmlMediaElement.Impl({ type nonrec t = t; }); +include Impl({ type nonrec t = t; }); diff --git a/src/Webapi/Dom/Webapi__Dom__MediaError.re b/src/Webapi/Dom/Webapi__Dom__MediaError.re new file mode 100644 index 00000000..321603dc --- /dev/null +++ b/src/Webapi/Dom/Webapi__Dom__MediaError.re @@ -0,0 +1,23 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#mediaerror + */ +type t; + +type errorType = + | ERR_ABORTED + | ERR_NETWORK + | ERR_DECODE + | ERR_SRC_NOT_SUPPORTED; + +let decodeErrorType = fun + | 1 => Some(ERR_ABORTED) + | 2 => Some(ERR_NETWORK) + | 3 => Some(ERR_DECODE) + | 4 => Some(ERR_SRC_NOT_SUPPORTED) + | _ => None; + +/** Properties */ + +[@bs.get] external _code: t => int = "code"; +let code = t => _code(t) |> decodeErrorType; +[@bs.get] external message: t => string = "message"; diff --git a/src/Webapi/TextTrack/Webapi__TextTrack__TextTrackCue.re b/src/Webapi/TextTrack/Webapi__TextTrack__TextTrackCue.re new file mode 100644 index 00000000..26a8b0b3 --- /dev/null +++ b/src/Webapi/TextTrack/Webapi__TextTrack__TextTrackCue.re @@ -0,0 +1,17 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#texttrackcue + */ +type t; + +include Webapi__Dom__EventTarget.Impl({ type nonrec t = t; }); + +// FIXME: circular dep +// [@bs.get] [@bs.return nullable] external track: t => option(Webapi__TextTrack.t) = "track"; +[@bs.get] external id: t => string = "id"; +[@bs.set] external setId: (t, string) => unit = "id"; +[@bs.get] external startTime: t => float = "startTime"; +[@bs.set] external setStartTime: (t, float) => unit = "startTime"; +[@bs.get] external endTime: t => float = "endTime"; +[@bs.set] external setEndTime: (t, float) => unit = "endTime"; +[@bs.get] external pauseOnExit: t => bool = "pauseOnExit"; +[@bs.set] external setPauseOnExit: (t, bool) => unit = "pauseOnExit"; diff --git a/src/Webapi/TextTrack/Webapi__TextTrack__TextTrackCueList.re b/src/Webapi/TextTrack/Webapi__TextTrack__TextTrackCueList.re new file mode 100644 index 00000000..d0b15ebe --- /dev/null +++ b/src/Webapi/TextTrack/Webapi__TextTrack__TextTrackCueList.re @@ -0,0 +1,11 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#texttrackcuelist + */ +type t; + +/** Properties */ +[@bs.get] external length: t => int = "length"; +[@bs.get_index] [@bs.return nullable] external get: (t, int) => option(Webapi__TextTrack__TextTrackCue.t) = ""; + +/** Methods */ +[@bs.send] [@bs.return nullable] external getCueById: (t, string) => option(Webapi__TextTrack__TextTrackCue.t) = "getCueById"; diff --git a/src/Webapi/Webapi__AudioTrack.re b/src/Webapi/Webapi__AudioTrack.re new file mode 100644 index 00000000..1c4a5e10 --- /dev/null +++ b/src/Webapi/Webapi__AudioTrack.re @@ -0,0 +1,14 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#audiotrack + */ +type t; + +/** Properties */ + +[@bs.get] external id: t => string = "id"; +[@bs.get] external kind: t => string = "kind"; +[@bs.get] external label: t => string = "label"; +[@bs.get] external language: t => string = "language"; + +[@bs.get] external enabled: t => bool = "enabled"; +[@bs.set] external setEnabled: (t, bool) => unit = "enabled"; diff --git a/src/Webapi/Webapi__AudioTrackList.re b/src/Webapi/Webapi__AudioTrackList.re new file mode 100644 index 00000000..15a6c871 --- /dev/null +++ b/src/Webapi/Webapi__AudioTrackList.re @@ -0,0 +1,14 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#audiotracklist + */ +type t; +include Webapi__Dom__EventTarget.Impl({ type nonrec t = t; }); + +/** Properties */ + +[@bs.get] external length: t => float = "length"; +[@bs.get_index] external get: (t, int) => option(Webapi__AudioTrack.t) = ""; + +/** Methods */ + +[@bs.send] [@bs.return nullable] external getTrackById: (t, string) => option(Webapi__AudioTrack.t) = "getTrackById"; diff --git a/src/Webapi/Webapi__Dom.re b/src/Webapi/Webapi__Dom.re index 8d658660..4e4813f7 100644 --- a/src/Webapi/Webapi__Dom.re +++ b/src/Webapi/Webapi__Dom.re @@ -29,11 +29,14 @@ module HtmlElement = Webapi__Dom__HtmlElement; module HtmlFormElement = Webapi__Dom__HtmlFormElement; module HtmlImageElement = Webapi__Dom__HtmlImageElement; module HtmlInputElement = Webapi__Dom__HtmlInputElement; +module HtmlMediaElement = Webapi__Dom__HtmlMediaElement; +module HtmlVideoElement = Webapi__Dom__HtmlVideoElement; module IdbVersionChangeEvent = Webapi__Dom__IdbVersionChangeEvent; module Image = Webapi__Dom__Image; module InputEvent = Webapi__Dom__InputEvent; module KeyboardEvent = Webapi__Dom__KeyboardEvent; module Location = Webapi__Dom__Location; +module MediaError = Webapi__Dom__MediaError; module MouseEvent = Webapi__Dom__MouseEvent; module MutationObserver = Webapi__Dom__MutationObserver; module MutationRecord = Webapi__Dom__MutationRecord; @@ -130,7 +133,6 @@ include Webapi__Dom__Types; HTMLLIElement HTMLLinkElement HTMLMapElement - HTMLMediaElement HTMLMenuElement HTMLMetaElement HTMLMeterElement @@ -164,7 +166,6 @@ include Webapi__Dom__Types; HTMLTrackElement HTMLUListElement HTMLUnknownElement - HTMLVideoElement /* Other interfaces */ CanvasRenderingContext2D diff --git a/src/Webapi/Webapi__TextTrack.re b/src/Webapi/Webapi__TextTrack.re new file mode 100644 index 00000000..c6d56ec9 --- /dev/null +++ b/src/Webapi/Webapi__TextTrack.re @@ -0,0 +1,33 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#texttrack + */ +type t; +include Webapi__Dom__EventTarget.Impl({ type nonrec t = t; }); + +/** @since 0.20.0 */ +module TextTrackCueList = Webapi__TextTrack__TextTrackCueList; +/** @since 0.20.0 */ +module TextTrackCue = Webapi__TextTrack__TextTrackCue; + +// TODO: string enum for +// enum TextTrackMode { "disabled", "hidden", "showing" }; +// enum TextTrackKind { "subtitles", "captions", "descriptions", "chapters", "metadata" }; +type textTrackMode = string; +type textTrackKind = string; + +/** Properties */ + +[@bs.get] external activeCues: t => option(TextTrackCueList.t) = "activeCues"; +[@bs.get] external cues: t => option(TextTrackCueList.t) = "cues"; +[@bs.get] external id: t => string = "id"; +[@bs.get] external inBandMetadataTrackDispatchType: t => option(string) = "inBandMetadataTrackDispatchType"; +[@bs.get] external kind: t => textTrackKind = "kind"; +[@bs.get] external label: t => string = "label"; +[@bs.get] external language: t => string = "language"; +[@bs.get] external mode: t => textTrackMode = "mode"; +[@bs.set] external setMode: (t, textTrackMode) => unit = "mode"; + +/** Methods */ + +[@bs.send] external addCue: (t, TextTrackCue.t) => unit = "addCue"; +[@bs.send] external removeCue: (t, TextTrackCue.t) => unit = "removeCue"; diff --git a/src/Webapi/Webapi__TextTrackList.re b/src/Webapi/Webapi__TextTrackList.re new file mode 100644 index 00000000..097151d1 --- /dev/null +++ b/src/Webapi/Webapi__TextTrackList.re @@ -0,0 +1,10 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#texttracklist + */ + +type t; +include Webapi__Dom__EventTarget.Impl({ type nonrec t = t; }); + +[@bs.get] external length: t => float = "length"; +[@bs.get_index] external get: (t, int) => option(Webapi__TextTrack.t) = ""; +[@bs.send] [@bs.return nullable] external getTrackById: (t, string) => option(Webapi__TextTrack.t) = "getTrackById"; diff --git a/src/Webapi/Webapi__TimeRanges.re b/src/Webapi/Webapi__TimeRanges.re new file mode 100644 index 00000000..dcfb24b0 --- /dev/null +++ b/src/Webapi/Webapi__TimeRanges.re @@ -0,0 +1,21 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#timeranges + */ + +type t; + +/** Properties */ + +[@bs.get] external length: t => int = "length"; + +/** Methods */ + +/** + * Throws an "IndexSizeError" DOMException if the index is out of range. + */ +[@bs.send] external startExn: (t, int) => int = "start"; + +/** + * Throws an "IndexSizeError" DOMException if the index is out of range. + */ +[@bs.send] external endExn: (t, int) => int = "end"; diff --git a/src/Webapi/Webapi__VideoTrack.re b/src/Webapi/Webapi__VideoTrack.re new file mode 100644 index 00000000..606202f2 --- /dev/null +++ b/src/Webapi/Webapi__VideoTrack.re @@ -0,0 +1,17 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#videotrack + */ +type t; + +/** Properties */ + +[@bs.get] external selected: t => bool = "selected"; +[@bs.set] external setSelected: (t, bool) => unit = "selected"; +[@bs.get] external id: t => string = "id"; +[@bs.get] external kind: t => string = "kind"; +[@bs.get] external label: t => string = "label"; +[@bs.get] external language: t => string = "language"; + +// Not widely available, recommendation status +// type t_sourceBuffer; +// [@bs.get] external sourceBuffer: t => t_sourceBuffer = "sourceBuffer"; diff --git a/src/Webapi/Webapi__VideoTrackList.re b/src/Webapi/Webapi__VideoTrackList.re new file mode 100644 index 00000000..7d2b3455 --- /dev/null +++ b/src/Webapi/Webapi__VideoTrackList.re @@ -0,0 +1,15 @@ +/** + * Spec: https://html.spec.whatwg.org/multipage/media.html#videotracklist + */ +type t; +include Webapi__Dom__EventTarget.Impl({ type nonrec t = t; }); + +/** Properties */ + +[@bs.get] external length: t => float = "length"; +[@bs.get] external selectedIndex: t => float = "selectedIndex"; +[@bs.get_index] external get: (t, int) => option(Webapi__VideoTrack.t) = ""; + +/** Methods */ + +[@bs.send] [@bs.return nullable] external getTrackById: (t, string) => option(Webapi__VideoTrack.t) = "getTrackById"; diff --git a/tests/Webapi/Dom/Webapi__Dom__HtmlVideoElement__test.re b/tests/Webapi/Dom/Webapi__Dom__HtmlVideoElement__test.re new file mode 100644 index 00000000..7f344e6f --- /dev/null +++ b/tests/Webapi/Dom/Webapi__Dom__HtmlVideoElement__test.re @@ -0,0 +1,213 @@ +open Webapi__Dom; +open Webapi__Dom__HtmlVideoElement; + +let el = Document.createElement("video", document) + |> ofElement + |> Belt.Option.getUnsafe; + +let body = Document.asHtmlDocument(document) +-> Belt.Option.flatMap(HtmlDocument.body) +-> Belt.Option.getUnsafe; + +Element.appendChild(el |> Obj.magic |> Element.asNode, body); + +let test = buffered(el); +Js.log2("Webapi.Dom.HtmlVideoElement.buffered:", test); + +let test = controls(el); +Js.log2("Webapi.Dom.HtmlVideoElement.controls:", test); + +let test = setControls(el, true); +Js.log2("Webapi.Dom.HtmlVideoElement.setControls:", test); + +let test = controlsList(el); +Js.log2("Webapi.Dom.HtmlVideoElement.controlsList:", test); + +let test = crossOrigin(el); +Js.log2("Webapi.Dom.HtmlVideoElement.crossOrigin:", test); + +let test = setCrossOrigin(el, `empty); +Js.log2("Webapi.Dom.HtmlVideoElement.setCrossOrigin:", test); + +let test = currentSrc(el); +Js.log2("Webapi.Dom.HtmlVideoElement.currentSrc:", test); + +let test = currentTime(el); +Js.log2("Webapi.Dom.HtmlVideoElement.currentTime:", test); + +let test = setCurrentTime(el, 0.1); +Js.log2("Webapi.Dom.HtmlVideoElement.setCurrentTime:", test); + +let test = defaultMuted(el); +Js.log2("Webapi.Dom.HtmlVideoElement.defaultMuted:", test); + +let test = setDefaultMuted(el, true); +Js.log2("Webapi.Dom.HtmlVideoElement.setDefaultMuted:", test); + +let test = defaultPlaybackRate(el); +Js.log2("Webapi.Dom.HtmlVideoElement.defaultPlaybackRate:", test); + +let test = setDefaultPlaybackRate(el, 1.25); +Js.log2("Webapi.Dom.HtmlVideoElement.setDefaultPlaybackRate:", test); + +let test = disableRemotePlayback(el); +Js.log2("Webapi.Dom.HtmlVideoElement.disableRemotePlayback:", test); + +let test = setDisableRemotePlayback(el, true); +Js.log2("Webapi.Dom.HtmlVideoElement.setDisableRemotePlayback:", test); + +let test = duration(el); +Js.log2("Webapi.Dom.HtmlVideoElement.duration:", test); + +let test = ended(el); +Js.log2("Webapi.Dom.HtmlVideoElement.ended:", test); + +let test = error(el); +Js.log2("Webapi.Dom.HtmlVideoElement.error:", test); + +let test = loop(el); +Js.log2("Webapi.Dom.HtmlVideoElement.loop:", test); + +let test = setLoop(el, true); +Js.log2("Webapi.Dom.HtmlVideoElement.setLoop:", test); + +let test = muted(el); +Js.log2("Webapi.Dom.HtmlVideoElement.muted:", test); + +let test = setMuted(el, false); +Js.log2("Webapi.Dom.HtmlVideoElement.setMuted:", test); + +let test = networkState(el); +Js.log2("Webapi.Dom.HtmlVideoElement.networkState:", test); + +let test = paused(el); +Js.log2("Webapi.Dom.HtmlVideoElement.paused:", test); + +let test = playbackRate(el); +Js.log2("Webapi.Dom.HtmlVideoElement.playbackRate:", test); + +let test = setPlaybackRate(el, 0.1); +Js.log2("Webapi.Dom.HtmlVideoElement.setPlaybackRate:", test); + +let test = played(el); +Js.log2("Webapi.Dom.HtmlVideoElement.played:", test); + +let test = preload(el); +Js.log2("Webapi.Dom.HtmlVideoElement.preload:", test); + +let test = readyState(el); +Js.log2("Webapi.Dom.HtmlVideoElement.readyState:", test); + +let test = seekable(el); +Js.log2("Webapi.Dom.HtmlVideoElement.seekable:", test); + +let test = seeking(el); +Js.log2("Webapi.Dom.HtmlVideoElement.seeking:", test); + +let test = src(el); +Js.log2("Webapi.Dom.HtmlVideoElement.src:", test); + +let test = setSrc(el, "#"); +Js.log2("Webapi.Dom.HtmlVideoElement.setSrc:", test); + +let test = srcObject(el); +Js.log2("Webapi.Dom.HtmlVideoElement.srcObject:", test); + +let test = audioTracks(el); +Js.log2("Webapi.Dom.HtmlVideoElement.audioTracks:", test); + +let len = Webapi.AudioTrackList.length(test); +Js.log2("Webapi.AudioTrackList.length:", len); +let track = Webapi.AudioTrackList.get(test, 0); +Js.log2("Webapi.AudioTrackList.get:", track); +let track = Webapi.AudioTrackList.getTrackById(test, "1"); +Js.log2("Webapi.AudioTrackList.getTrackById:", track); + +let test = textTracks(el); +Js.log2("Webapi.Dom.HtmlVideoElement.textTracks:", test); + +let len = Webapi.TextTrackList.length(test); +Js.log2("Webapi.TextTrackList.length:", len); +let track = addTextTrack(el, "subtitles", ~label="My Text Track", ~language="en-US", ()); +Js.log2("Webapi.Dom.HtmlVideoElement.addTextTrack:", track); +let track = Webapi.TextTrackList.get(test, 0) -> Belt.Option.getUnsafe; +Js.log2("Webapi.TextTrackList.get:", track); + +let test2 = Webapi.TextTrack.id(track); +Js.log2("Webapi.TextTrack.id:", test2); +let test2 = Webapi.TextTrack.inBandMetadataTrackDispatchType(track); +Js.log2("Webapi.TextTrack.inBandMetadataTrackDispatchType:", test2); +let test2 = Webapi.TextTrack.kind(track); +Js.log2("Webapi.TextTrack.kind:", test2); +let test2 = Webapi.TextTrack.label(track); +Js.log2("Webapi.TextTrack.label:", test2); +let test2 = Webapi.TextTrack.language(track); +Js.log2("Webapi.TextTrack.language:", test2); +let test2 = Webapi.TextTrack.mode(track); +Js.log2("Webapi.TextTrack.mode:", test2); +let test2 = Webapi.TextTrack.setMode(track, "hidden"); +Js.log2("Webapi.TextTrack.setMode:", test2); + +let cues = Webapi.TextTrack.cues(track) -> Belt.Option.getUnsafe; +Js.log2("Webapi.TextTrack.cues:", cues); + +let activeCues = Webapi.TextTrack.activeCues(track) -> Belt.Option.getUnsafe; +Js.log2("Webapi.TextTrack.activeCues:", cues); + +let len = Webapi.TextTrack.TextTrackCueList.length(cues); +Js.log2("Webapi.TextTrack.TextTrackCueList.length:", len); +let len = Webapi.TextTrack.TextTrackCueList.length(activeCues); +Js.log2("Webapi.TextTrack.TextTrackCueList.length:", len); + +let track = Webapi.TextTrackList.getTrackById(test, ""); +Js.log2("Webapi.TextTrackList.getTrackById:", track); + +let track = Webapi.TextTrackList.length(test); +Js.log2("Webapi.TextTrackList.length:", track); + +// not well supported + +// let test = videoTracks(el); +// Js.log2("Webapi.Dom.HtmlVideoElement.videoTracks:", test); + +// let len = Webapi.VideoTrackList.length(test); +// Js.log2("Webapi.VideoTrackList.length:", len); +// let track = Webapi.VideoTrackList.get(test, 0); +// Js.log2("Webapi.VideoTrackList.get:", track); +// let track = Webapi.VideoTrackList.getTrackById(test, "1"); +// Js.log2("Webapi.VideoTrackList.getTrackById:", track); + +let test = volume(el); +Js.log2("Webapi.Dom.HtmlVideoElement.volume:", test); + +let test = setVolume(el, 1.0); +Js.log2("Webapi.Dom.HtmlVideoElement.setVolume:", test); + +let test = canPlayType(el, "video/webm"); +Js.log2("Webapi.Dom.HtmlVideoElement.canPlayType:", test); + +let test = load(el); +Js.log2("Webapi.Dom.HtmlVideoElement.load:", test); + +let test = pause(el); +Js.log2("Webapi.Dom.HtmlVideoElement.pause:", test); + +let test = play(el); +Js.log2("Webapi.Dom.HtmlVideoElement.play:", test); + +let test = setHeight(el, 100); +Js.log2("Webapi.Dom.HtmlVideoElement.setHeight:", test); +let test = height(el); +Js.log2("Webapi.Dom.HtmlVideoElement.height:", test); +let test = poster(el); +Js.log2("Webapi.Dom.HtmlVideoElement.poster:", test); +let test = setPoster(el, "foo"); +Js.log2("Webapi.Dom.HtmlVideoElement.setPoster:", test); +let test = videoHeight(el); +Js.log2("Webapi.Dom.HtmlVideoElement.videoHeight:", test); +let test = videoWidth(el); +Js.log2("Webapi.Dom.HtmlVideoElement.videoWidth:", test); +let test = setWidth(el, 100); +Js.log2("Webapi.Dom.HtmlVideoElement.setWidth:", test); +let test = width(el); +Js.log2("Webapi.Dom.HtmlVideoElement.width:", test);