From 8d1d09e42d14d5ddb9f78aa38d59fb61a30ce8e1 Mon Sep 17 00:00:00 2001 From: CenTdemeern1 Date: Tue, 15 Oct 2024 22:33:43 +0200 Subject: [PATCH] Add Ruffle type definitions These can be replaced later when Ruffle API v1 releases with proper TypeScript definitions and such: https://github.com/ruffle-rs/ruffle/pull/17939 I am planning to do so myself when that happens. For now, Dinnerbone has graciously provided us with type definitions of the current API. Co-authored-by: Nathan Adams --- .../src/types/ruffle/config/default.d.ts | 2 + .../src/types/ruffle/config/index.d.ts | 10 + .../src/types/ruffle/config/load-options.d.ts | 620 ++++++++++++++++++ .../src/types/ruffle/player/flash.d.ts | 17 + .../src/types/ruffle/player/index.d.ts | 9 + .../src/types/ruffle/player/legacy.d.ts | 163 +++++ .../types/ruffle/player/movie-metadata.d.ts | 38 ++ .../types/ruffle/player/player-element.d.ts | 12 + .../src/types/ruffle/setup/index.d.ts | 19 + .../src/types/ruffle/setup/install.d.ts | 28 + .../src/types/ruffle/setup/public-api.d.ts | 133 ++++ .../src/types/ruffle/setup/source-api.d.ts | 34 + 12 files changed, 1085 insertions(+) create mode 100644 packages/frontend/src/types/ruffle/config/default.d.ts create mode 100644 packages/frontend/src/types/ruffle/config/index.d.ts create mode 100644 packages/frontend/src/types/ruffle/config/load-options.d.ts create mode 100644 packages/frontend/src/types/ruffle/player/flash.d.ts create mode 100644 packages/frontend/src/types/ruffle/player/index.d.ts create mode 100644 packages/frontend/src/types/ruffle/player/legacy.d.ts create mode 100644 packages/frontend/src/types/ruffle/player/movie-metadata.d.ts create mode 100644 packages/frontend/src/types/ruffle/player/player-element.d.ts create mode 100644 packages/frontend/src/types/ruffle/setup/index.d.ts create mode 100644 packages/frontend/src/types/ruffle/setup/install.d.ts create mode 100644 packages/frontend/src/types/ruffle/setup/public-api.d.ts create mode 100644 packages/frontend/src/types/ruffle/setup/source-api.d.ts diff --git a/packages/frontend/src/types/ruffle/config/default.d.ts b/packages/frontend/src/types/ruffle/config/default.d.ts new file mode 100644 index 0000000000..615255f41a --- /dev/null +++ b/packages/frontend/src/types/ruffle/config/default.d.ts @@ -0,0 +1,2 @@ +import type { BaseLoadOptions } from './load-options.d.ts'; +export declare const DEFAULT_CONFIG: Required; diff --git a/packages/frontend/src/types/ruffle/config/index.d.ts b/packages/frontend/src/types/ruffle/config/index.d.ts new file mode 100644 index 0000000000..9cb3783972 --- /dev/null +++ b/packages/frontend/src/types/ruffle/config/index.d.ts @@ -0,0 +1,10 @@ +/** + * The Config module contains all the types that Ruffle uses for movie configs. + * + * The main interface of interest here is {@link BaseLoadOptions}, which you can apply to `window.RufflePlayer.config` + * to set the default configuration of all players. + * + * @module + */ +export type * from './default.d.ts'; +export type * from './load-options.d.ts'; diff --git a/packages/frontend/src/types/ruffle/config/load-options.d.ts b/packages/frontend/src/types/ruffle/config/load-options.d.ts new file mode 100644 index 0000000000..8ed0aca03b --- /dev/null +++ b/packages/frontend/src/types/ruffle/config/load-options.d.ts @@ -0,0 +1,620 @@ +/** + * Represents the various types of auto-play behaviours that are supported. + */ +export declare enum AutoPlay { + /** + * The player should automatically play the movie as soon as it is loaded. + * + * If the browser does not support automatic audio, the movie will begin + * muted. + */ + On = "on", + /** + * The player should not attempt to automatically play the movie. + * + * This will leave it to the user or API to actually play when appropriate. + */ + Off = "off", + /** + * The player should automatically play the movie as soon as it is deemed + * "appropriate" to do so. + * + * The exact behaviour depends on the browser, but commonly requires some + * form of user interaction on the page in order to allow auto playing videos + * with sound. + */ + Auto = "auto" +} +/** + * Controls whether the content is letterboxed or pillarboxed when the + * player's aspect ratio does not match the movie's aspect ratio. + * + * When letterboxed, black bars will be rendered around the exterior + * margins of the content. + */ +export declare enum Letterbox { + /** + * The content will never be letterboxed. + */ + Off = "off", + /** + * The content will only be letterboxed if the content is running fullscreen. + */ + Fullscreen = "fullscreen", + /** + * The content will always be letterboxed. + */ + On = "on" +} +/** + * When the player is muted, this controls whether or not Ruffle will show a + * "click to unmute" overlay on top of the movie. + */ +export declare enum UnmuteOverlay { + /** + * Show an overlay explaining that the movie is muted. + */ + Visible = "visible", + /** + * Don't show an overlay and pretend that everything is fine. + */ + Hidden = "hidden" +} +/** + * Console logging level. + */ +export declare enum LogLevel { + Error = "error", + Warn = "warn", + Info = "info", + Debug = "debug", + Trace = "trace" +} +/** + * The window mode of a Ruffle player. + */ +export declare enum WindowMode { + /** + * The Flash content is rendered in its own window and layering is done with the browser's + * default behavior. + * + * In Ruffle, this mode functions like `WindowMode::Opaque` and will layer the Flash content + * together with other HTML elements. + */ + Window = "window", + /** + * The Flash content is layered together with other HTML elements, and the stage color is + * opaque. Content can render above or below Ruffle based on CSS rendering order. + */ + Opaque = "opaque", + /** + * The Flash content is layered together with other HTML elements, and the SWF stage color is + * transparent. Content beneath Ruffle will be visible through transparent areas. + */ + Transparent = "transparent", + /** + * Request compositing with hardware acceleration when possible. + * This mode has no effect in Ruffle and will function like `WindowMode.Opaque`. + */ + Direct = "direct", + /** + * Request a direct rendering path, bypassing browser compositing when possible. + * This mode has no effect in Ruffle and will function like `WindowMode::Opaque`. + */ + Gpu = "gpu" +} +/** + * The render backend of a Ruffle player. + * + * The available backends may change in future releases. + */ +export declare enum RenderBackend { + /** + * An [in-development API](https://caniuse.com/webgpu) that will be preferred if available in the future. + * Should behave the same as wgpu-webgl, except with lower overhead and thus better performance. + */ + WebGpu = "webgpu", + /** + * The most featureful and currently preferred backend. + * Rendering is done the same way as in the desktop app, then translated to WebGL on-the-fly. + */ + WgpuWebgl = "wgpu-webgl", + /** + * A vanilla WebGL backend. Was the default backend until the start of 2023, + * but is now used as a fallback for devices that do not support WebGL 2. + * Supports fewer features and has a faster initialization time; + * may be useful for content that does not need advanced features like bitmap drawing or blend modes. + */ + Webgl = "webgl", + /** + * The slowest and most basic backend, used as a fallback when all else fails. + * However, this is currently the only backend that accurately scales hairline strokes. + * If you notice excessively thick strokes in specific content, + * you may want to use the canvas renderer for that content until the issue is resolved. + */ + Canvas = "canvas" +} +/** + * Represents the various context menu options that are supported. + */ +export declare enum ContextMenu { + /** + * The context menu should appear when right-clicking or long-pressing + * the Ruffle instance. + */ + On = "on", + /** + * The context menu should only appear when right-clicking + * the Ruffle instance. + */ + RightClickOnly = "rightClickOnly", + /** + * The context menu should not appear when right-clicking or long-pressing + * the Ruffle instance. + */ + Off = "off" +} +/** + * Represents the player runtime to emulate. + */ +export declare enum PlayerRuntime { + /** + * Emulate Adobe AIR. + */ + AIR = "air", + /** + * Emulate Adobe Flash Player. + */ + FlashPlayer = "flashPlayer" +} +/** + * Non-negative duration in seconds. + */ +export type SecsDuration = number; +/** + * Deprecated duration type, use SecsDuration instead. + * Based on https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.new . + */ +export interface ObsoleteDuration { + secs: number; + nanos: number; +} +/** + * Any new duration-based setting should use 'number' or 'SecsDuration' for its type, + * instead of this type. + */ +export type Duration = SecsDuration | ObsoleteDuration; +/** + * The handling mode of links opening a new website. + */ +export declare enum OpenURLMode { + /** + * Allow all links to open a new website. + */ + Allow = "allow", + /** + * A confirmation dialog opens with every link trying to open a new website. + */ + Confirm = "confirm", + /** + * Deny all links to open a new website. + */ + Deny = "deny" +} +/** + * The networking API access mode of the Ruffle player. + */ +export declare enum NetworkingAccessMode { + /** + * All networking APIs are permitted in the SWF file. + */ + All = "all", + /** + * The SWF file may not call browser navigation or browser interaction APIs. + * + * The APIs navigateToURL(), fscommand() and ExternalInterface.call() are + * prevented in this mode. + */ + Internal = "internal", + /** + * The SWF file may not call browser navigation or browser interaction APIs + * and it cannot use any SWF-to-SWF communication APIs. + * + * Additionally to the ones in internal mode, the APIs sendToURL(), + * FileReference.download(), FileReference.upload(), Loader.load(), + * LocalConnection.connect(), LocalConnection.send(), NetConnection.connect(), + * NetStream.play(), Security.loadPolicyFile(), SharedObject.getLocal(), + * SharedObject.getRemote(), Socket.connect(), Sound.load(), URLLoader.load(), + * URLStream.load() and XMLSocket.connect() are prevented in this mode. + * + * This mode is not implemented yet. + */ + None = "none" +} +/** + * Represents a host, port and proxyUrl. Used when a SWF file tries to use a Socket. + */ +export interface SocketProxy { + /** + * Host used by the SWF. + */ + host: string; + /** + * Port used by the SWF. + */ + port: number; + /** + * The proxy URL to use when SWF file tries to connect to the specified host and port. + */ + proxyUrl: string; +} +/** + * Defines the names of the fonts to use for each "default" Flash device font. + * + * The name of each font provided will be used, in priority order. + * + * For example, defining `sans: ["Helvetica", "Arial"]` would use Helvetica if present, before trying Arial. + */ +export interface DefaultFonts { + /** + * `_sans`, a Sans-Serif font (similar to Helvetica or Arial) + */ + sans?: Array; + /** + * `_serif`, a Serif font (similar to Times Roman) + */ + serif?: Array; + /** + * `_typewriter`, a Monospace font (similar to Courier) + */ + typewriter?: Array; + /** + * `_ゴシック`, a Japanese Gothic font + */ + japaneseGothic?: Array; + /** + * `_等幅`, a Japanese Gothic Mono font + */ + japaneseGothicMono?: Array; + /** + * `_明朝`, a Japanese Mincho font + */ + japaneseMincho?: Array; +} +/** + * Any options used for loading a movie. + */ +export interface BaseLoadOptions { + /** + * If set to true, the movie is allowed to interact with the page through + * JavaScript, using a flash concept called `ExternalInterface`. + * + * This should only be enabled for movies you trust. + * + * @default false + */ + allowScriptAccess?: boolean; + /** + * Also known as "flashvars" - these are values that may be passed to + * and loaded by the movie. + * + * If a URL if specified when loading the movie, some parameters will + * be extracted by the query portion of that URL and then overwritten + * by any explicitly set here. + * + * @default {} + */ + parameters?: URLSearchParams | string | Record | null; + /** + * Controls the auto-play behaviour of Ruffle. + * + * @default AutoPlay.Auto + */ + autoplay?: AutoPlay; + /** + * Controls the background color of the player. + * Must be an HTML color (e.g. "#FFFFFF"). CSS colors are not allowed. + * `null` uses the background color of the SWF file. + * + * @default null + */ + backgroundColor?: string | null; + /** + * Controls letterbox behavior when the Flash container size does not + * match the movie size. + * + * @default Letterbox.Fullscreen + */ + letterbox?: Letterbox; + /** + * Controls the visibility of the unmute overlay when the player + * is started muted. + * + * @default UnmuteOverlay.Visible + */ + unmuteOverlay?: UnmuteOverlay; + /** + * Whether or not to auto-upgrade all embedded URLs to https. + * + * Flash content that embeds http urls will be blocked from + * accessing those urls by the browser when Ruffle is loaded + * in a https context. Set to `true` to automatically change + * `http://` to `https://` for all embedded URLs when Ruffle is + * loaded in an https context. + * + * @default true + */ + upgradeToHttps?: boolean; + /** + * Enable (true) or disable (false) Ruffle's built in compatibility rules. + * + * These are rules that may make some content work by deliberately changing + * behaviour, for example by rewriting requests or spoofing SWF urls if they + * rely on websites that no longer exist. + * + * @default true + */ + compatibilityRules?: boolean; + /** + * Favor using the real Adobe Flash Player over Ruffle if the browser supports it. + * + * @default true + */ + favorFlash?: boolean; + /** + * This is no longer used and does not affect anything. + * It is only kept for backwards compatibility. + * + * Previously: + * "Whether or not to display an overlay with a warning when + * loading a movie with unsupported content." + * + * @default true + * @deprecated + */ + warnOnUnsupportedContent?: boolean; + /** + * Console logging level. + * + * @default LogLevel.Error + */ + logLevel?: LogLevel; + /** + * If set to true, the context menu has an option to download + * the SWF. + * + * @default false + */ + showSwfDownload?: boolean; + /** + * Whether or not to show a context menu when right-clicking + * a Ruffle instance. + * + * @default ContextMenu.On + */ + contextMenu?: ContextMenu | boolean; + /** + * Whether or not to show a splash screen before the SWF has loaded with Ruffle (backwards-compatibility). + * + * @default true + */ + preloader?: boolean; + /** + * Whether or not to show a splash screen before the SWF has loaded with Ruffle. + * + * @default true + */ + splashScreen?: boolean; + /** + * Maximum amount of time a script can take before scripting + * is disabled. + * + * @default 15 + */ + maxExecutionDuration?: Duration; + /** + * Specifies the base directory or URL used to resolve all relative path statements in the SWF file. + * null means the current directory. + * + * @default null + */ + base?: string | null; + /** + * If set to true, the built-in context menu items are visible + * + * This is equivalent to Stage.showMenu. + * + * @default true + */ + menu?: boolean; + /** + * This is equivalent to Stage.align. + * + * @default "" + */ + salign?: string; + /** + * If set to true, movies are prevented from changing the stage alignment. + * + * @default false + */ + forceAlign?: boolean; + /** + * This is equivalent to Stage.quality. + * + * @default "high" + */ + quality?: string; + /** + * This is equivalent to Stage.scaleMode. + * + * @default "showAll" + */ + scale?: string; + /** + * If set to true, movies are prevented from changing the stage scale mode. + * + * @default false + */ + forceScale?: boolean; + /** + * If set to true, the Stage's displayState can be changed + * + * @default false + */ + allowFullscreen?: boolean; + /** + * Sets and locks the player's frame rate, overriding the movie's frame rate. + * + * @default null + */ + frameRate?: number | null; + /** + * The window mode of the Ruffle player. + * + * This setting controls how the Ruffle container is layered and rendered with other content on the page. + * + * @default WindowMode.Window + */ + wmode?: WindowMode; + /** + * The emulated version of the player. + * + * This controls the version that is reported to the movie. + * null means latest version. + * + * @default null + */ + playerVersion?: number | null; + /** + * The preferred render backend of the Ruffle player. + * + * This option should only be used for testing; + * the available backends may change in future releases. + * By default, Ruffle chooses the most featureful backend supported by the user's system, + * falling back to more basic backends if necessary. + * The available values in order of default preference are: + * "webgpu", "wgpu-webgl", "webgl", "canvas". + * + * @default null + */ + preferredRenderer?: RenderBackend | null; + /** + * The URL at which Ruffle can load its extra files (i.e. `.wasm`). + * + * @default null + */ + publicPath?: string | null; + /** + * Whether or not to enable polyfills on the page. + * + * Polyfills will look for "legacy" flash content like `` + * and `` elements, and replace them with compatible + * Ruffle elements. + * + * @default true + */ + polyfills?: boolean; + /** + * The handling mode of links opening a new website. + * + * @default OpenURLMode.Allow + */ + openUrlMode?: OpenURLMode; + /** + * Which flash networking APIs may be accessed. + * + * @default NetworkingAccessMode.All + */ + allowNetworking?: NetworkingAccessMode; + /** + * A function to call for opening content in a new tab. + * + * This is only used if the content cannot be loaded due to CORS, + * and the Extension version of Ruffle will override this to provide a local player. + * + * @default null + */ + openInNewTab?: ((swf: URL) => void) | null; + /** + * An array of SocketProxy objects. + * + * When a SWF tries to establish a Socket connection, Ruffle will search for + * a matching SocketProxy object in this array and use it to establish a WebSocket connection, + * through which all communication is tunneled through. + * + * When none are found, Ruffle will fail the connection gracefully. + * When multiple matching SocketProxy objects exist, the first one is used. + * + * @default [] + */ + socketProxy?: Array; + /** + * An array of font URLs to eagerly load and provide to Ruffle. + * + * These will be fetched by the browser as part of the loading of Flash content, which may slow down load times. + * + * Currently only SWFs are supported, and each font embedded within that SWF will be used as device font by Flash content. + * + * If any URL fails to load (either it's an invalid file, or a network error occurs), Ruffle will log an error but continue without it. + * + * @default [] + */ + fontSources?: Array; + /** + * The font names to use for each "default" Flash device font. + * + * @default {} + */ + defaultFonts?: DefaultFonts; + /** + * An array of origins that credentials may be sent to. + * Credentials are cookies, authorization headers, or TLS client certificates. + * + * Entries should include the protocol and host, for example `https://example.org` or `http://subdomain.example.org`. + * + * Cookies will always be sent to the same origin as the page the content was loaded on. + * If you configure this to send cookies to an origin but that origin does not configure CORS to allow it, + * then requests will start failing due to CORS. + * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials. + * + * This directly corresponds to https://developer.mozilla.org/en-US/docs/Web/API/fetch#credentials + * Every request will be `same-origin` unless specified here, in which case it will be `include`. + * + * @default [] + */ + credentialAllowList?: Array; + /** + * The player runtime to emulate + * + * This allows you to emulate Adobe AIR or Adobe Flash Player. + */ + playerRuntime?: PlayerRuntime; +} +/** + * Options to load a movie by URL. + */ +export interface URLLoadOptions extends BaseLoadOptions { + /** + * The URL to load a movie from. + * + * If there is a query portion of this URL, then default {@link parameters} + * will be extracted from that. + */ + url: string; +} +/** + * Options to load a movie by a data stream. + */ +export interface DataLoadOptions extends BaseLoadOptions { + /** + * The data to load a movie from. + */ + data: ArrayLike | ArrayBufferLike; + /** + * The filename of the SWF movie to provide to ActionScript. + * + * @default "movie.swf" + */ + swfFileName?: string; +} diff --git a/packages/frontend/src/types/ruffle/player/flash.d.ts b/packages/frontend/src/types/ruffle/player/flash.d.ts new file mode 100644 index 0000000000..64754bfbf1 --- /dev/null +++ b/packages/frontend/src/types/ruffle/player/flash.d.ts @@ -0,0 +1,17 @@ +/** + * These are properties and methods that Flash added to its `/` tags. + * These don't seem to be documented in full anywhere, and Ruffle adds them as we encounter some. + * You are discouraged from using these, and they exist only to support legacy websites from decades ago. + * + * Extra methods or properties may appear at any time, due to `ExternalInterface.addCallback()`. + * It may even overwrite existing methods or properties. + */ +export interface FlashAPI { + /** + * Returns the movies loaded process, in a percent from 0 to 100. + * Ruffle may just return 0 or 100. + * + * @returns a value from 0 to 100, inclusive. + */ + PercentLoaded(): number; +} diff --git a/packages/frontend/src/types/ruffle/player/index.d.ts b/packages/frontend/src/types/ruffle/player/index.d.ts new file mode 100644 index 0000000000..242ab86f43 --- /dev/null +++ b/packages/frontend/src/types/ruffle/player/index.d.ts @@ -0,0 +1,9 @@ +/** + * The Player module contains the actual {@link PlayerElement} and the various interfaces that exist to interact with the player. + * + * @module + */ +export type * from './flash.d.ts'; +export type * from './player-element.d.ts'; +export type * from './movie-metadata.d.ts'; +export type * from './legacy.d.ts'; diff --git a/packages/frontend/src/types/ruffle/player/legacy.d.ts b/packages/frontend/src/types/ruffle/player/legacy.d.ts new file mode 100644 index 0000000000..27fc5c0256 --- /dev/null +++ b/packages/frontend/src/types/ruffle/player/legacy.d.ts @@ -0,0 +1,163 @@ +import type { DataLoadOptions, URLLoadOptions } from '../config/index.d.ts'; +import type { MovieMetadata } from './movie-metadata.d.ts'; +/** + * Describes the loading state of an SWF movie. + */ +export enum ReadyState { + /** + * No movie is loaded, or no information is yet available about the movie. + */ + HaveNothing = 0, + /** + * The movie is still loading, but it has started playback, and metadata is available. + */ + Loading = 1, + /** + * The movie has completely loaded. + */ + Loaded = 2 +} +/** + * Legacy interface to the Ruffle API. + * + * These methods are deprecated and only exist for backwards compatibility. + * Due to the nature of Flash, they may be replaced at any time via ActionScript's `ExternalInterface` class. + */ +export interface LegacyRuffleAPI { + /** + * A movie can communicate with the hosting page using fscommand + * as long as script access is allowed. + * + * @param command A string passed to the host application for any use. + * @param args A string passed to the host application for any use. + * @returns True if the command was handled. + */ + onFSCommand: ((command: string, args: string) => boolean) | null; + /** + * Any configuration that should apply to this specific player. + * This will be defaulted with any global configuration. + */ + config: URLLoadOptions | DataLoadOptions | object; + /** + * The effective config loaded with the last call to `load()`. + * If no such call has been made, this will be `null`. + */ + readonly loadedConfig: URLLoadOptions | DataLoadOptions | null; + /** + * Indicates the readiness of the playing movie. + * + * @returns The `ReadyState` of the player. + */ + get readyState(): ReadyState; + /** + * The metadata of the playing movie (such as movie width and height). + * These are inherent properties stored in the SWF file and are not affected by runtime changes. + * For example, `metadata.width` is the width of the SWF file, and not the width of the Ruffle player. + * + * @returns The metadata of the movie, or `null` if the movie metadata has not yet loaded. + */ + get metadata(): MovieMetadata | null; + /** + * Reloads the player, as if you called {@link load} with the same config as the last time it was called. + * + * If this player has never been loaded, this method will return an error. + */ + reload(): Promise; + /** + * Loads a specified movie into this player. + * + * This will replace any existing movie that may be playing. + * + * @param options One of the following: + * - A URL, passed as a string, which will load a URL with default options. + * - A {@link URLLoadOptions} object, to load a URL with options. + * - A {@link DataLoadOptions} object, to load data with options. + * The options, if provided, must only contain values provided for this specific movie. + * They must not contain any default values, since those would overwrite other configuration + * settings with a lower priority (e.g. the general RufflePlayer config). + * + * The options will be defaulted by the {@link config} field, which itself + * is defaulted by a global `window.RufflePlayer.config`. + */ + load(options: string | URLLoadOptions | DataLoadOptions): Promise; + /** + * Plays or resumes the movie. + */ + play(): void; + /** + * Whether this player is currently playing. + * + * @returns True if this player is playing, false if it's paused or hasn't started yet. + */ + get isPlaying(): boolean; + /** + * Returns the master volume of the player. + * + * The volume is linear and not adapted for logarithmic hearing. + * + * @returns The volume. 1.0 is 100% volume. + */ + get volume(): number; + /** + * Sets the master volume of the player. + * + * The volume should be linear and not adapted for logarithmic hearing. + * + * @param value The volume. 1.0 is 100% volume. + */ + set volume(value: number); + /** + * Checks if this player is allowed to be fullscreen by the browser. + * + * @returns True if you may call {@link enterFullscreen}. + */ + get fullscreenEnabled(): boolean; + /** + * Checks if this player is currently fullscreen inside the browser. + * + * @returns True if it is fullscreen. + */ + get isFullscreen(): boolean; + /** + * Exported function that requests the browser to change the fullscreen state if + * it is allowed. + * + * @param isFull Whether to set to fullscreen or return to normal. + */ + setFullscreen(isFull: boolean): void; + /** + * Requests the browser to make this player fullscreen. + * + * This is not guaranteed to succeed, please check {@link fullscreenEnabled} first. + */ + enterFullscreen(): void; + /** + * Requests the browser to no longer make this player fullscreen. + */ + exitFullscreen(): void; + /** + * Pauses this player. + * + * No more frames, scripts or sounds will be executed. + * This movie will be considered inactive and will not wake up until resumed. + */ + pause(): void; + /** + * Sets a trace observer on this flash player. + * + * The observer will be called, as a function, for each message that the playing movie will "trace" (output). + * + * @param observer The observer that will be called for each trace. + */ + set traceObserver(observer: ((message: string) => void) | null); + /** + * Fetches the loaded SWF and downloads it. + */ + downloadSwf(): Promise; + /** + * Show a dismissible message in front of the player. + * + * @param message The message shown to the user. + */ + displayMessage(message: string): void; +} diff --git a/packages/frontend/src/types/ruffle/player/movie-metadata.d.ts b/packages/frontend/src/types/ruffle/player/movie-metadata.d.ts new file mode 100644 index 0000000000..f9fde87636 --- /dev/null +++ b/packages/frontend/src/types/ruffle/player/movie-metadata.d.ts @@ -0,0 +1,38 @@ +/** + * Metadata about a loaded SWF file. + */ +export interface MovieMetadata { + /** + * The width of the movie in pixels. + */ + readonly width: number; + /** + * The height of the movie in pixels. + */ + readonly height: number; + /** + * The frame rate of the movie in frames per second. + */ + readonly frameRate: number; + /** + * The number of frames on the root timeline of the movie. + */ + readonly numFrames: number; + /** + * The SWF version of the movie. + */ + readonly swfVersion: number; + /** + * The background color of the movie as a hex string, such as "#FFFFFF". + * May be `null` if the background color is unavailable. + */ + readonly backgroundColor: string | null; + /** + * Whether this movie is an ActionScript 3.0 movie. + */ + readonly isActionScript3: boolean; + /** + * Uncompressed length in bytes. + */ + readonly uncompressedLength: number; +} diff --git a/packages/frontend/src/types/ruffle/player/player-element.d.ts b/packages/frontend/src/types/ruffle/player/player-element.d.ts new file mode 100644 index 0000000000..04d24e558f --- /dev/null +++ b/packages/frontend/src/types/ruffle/player/player-element.d.ts @@ -0,0 +1,12 @@ +import type { LegacyRuffleAPI } from './legacy.d.ts'; +import type { FlashAPI } from './flash.d.ts'; +/** + * A Ruffle player's HTML element. + * + * This is either created through `window.RufflePlayer.latest().createPlayer()`, or polyfilled from a ``/`` tag. + * + * In addition to usual HTML attributes, this player contains methods and properties that belong to both + * the **Flash JS API** and **legacy Ruffle API**s. + */ +export interface PlayerElement extends HTMLElement, LegacyRuffleAPI, FlashAPI { +} diff --git a/packages/frontend/src/types/ruffle/setup/index.d.ts b/packages/frontend/src/types/ruffle/setup/index.d.ts new file mode 100644 index 0000000000..40d2e7cd71 --- /dev/null +++ b/packages/frontend/src/types/ruffle/setup/index.d.ts @@ -0,0 +1,19 @@ +/** + * The Setup module contains the interfaces and methods needed to install Ruffle onto a page, + * and create a {@link PlayerElement} with the latest version of Ruffle available. + * + * This is primarily relevant to users of `ruffle-core` as a npm module, as the "selfhosted" version of Ruffle preinstalls itself, + * and without type checking the interfaces here are of limited use. + * + * For users of `ruffle-core` as a npm module, you are encouraged to call {@link installRuffle} once during page load to + * make the `ruffle-core` library register itself as a version of Ruffle on the page. + * + * Multiple sources of Ruffle may exist - for example, the Ruffle browser extension also installs itself on page load. + * For this reason, you are required to call `window.RufflePlayer.latest()` (for example) to grab the latest {@link SourceAPI}, + * from which you can create a {@link PlayerElement} via {@link SourceAPI.createPlayer}. + * + * @module + */ +export type * from './public-api.d.ts'; +export type * from './source-api.d.ts'; +export type * from './install.d.ts'; diff --git a/packages/frontend/src/types/ruffle/setup/install.d.ts b/packages/frontend/src/types/ruffle/setup/install.d.ts new file mode 100644 index 0000000000..13ffaa64b9 --- /dev/null +++ b/packages/frontend/src/types/ruffle/setup/install.d.ts @@ -0,0 +1,28 @@ +/** + * Options to use with this specific installation of Ruffle. + * + * This is mostly to provide a way to configure environmental settings, like using + * `onFirstLoad` to potentially configure webpack prior to loading wasm files. + */ +export interface InstallationOptions { + /** + * A callback to be run before the very first time Ruffle is loaded. + * This may be used to configure a bundler prior to asset loading. + */ + onFirstLoad?: () => void; +} +/** + * Install this version of Ruffle into the current page. + * + * Multiple (or zero) versions of Ruffle may be installed at the same time, + * and you should use `window.RufflePlayer.newest()` or similar to access the appropriate + * installation at time of use. + * + * @param sourceName The name of this particular + * Ruffle source. Common convention is "local" for websites that bundle their own Ruffle, + * "extension" for browser extensions, and something else for other use cases. + * Names are unique, and last-installed will replace earlier installations with the same name, + * regardless of what those installations are or which version they represent. + * @param options Any options used to configure this specific installation of Ruffle. + */ +export declare function installRuffle(sourceName: string, options?: InstallationOptions): void; diff --git a/packages/frontend/src/types/ruffle/setup/public-api.d.ts b/packages/frontend/src/types/ruffle/setup/public-api.d.ts new file mode 100644 index 0000000000..e03e909242 --- /dev/null +++ b/packages/frontend/src/types/ruffle/setup/public-api.d.ts @@ -0,0 +1,133 @@ +import type { SourceAPI } from './source-api.d.ts'; +import type { DataLoadOptions, URLLoadOptions } from '../config/index.d.ts'; +declare global { + interface Window { + /** + * The public API for generating a ruffle player. + * This may be a config holder, which will be converted to a + * {@link PublicAPI} via {@link installRuffle}, or an actual + * {@link PublicAPI} instance itself. + */ + RufflePlayer?: PublicAPILike | PublicAPI; + } +} +/** + * Represents a potential installation of a Ruffle public API. + * + * Unlike {@link PublicAPI}, this may come from any source, past or future. + * It needs to be forwards compatible and convertible into a modern day {@link PublicAPI}. + */ +export interface PublicAPILike { + config?: DataLoadOptions | URLLoadOptions | object; + sources?: Record; + invoked?: boolean; + newestName?: string | null; + superseded?(): void; +} +/** + * Represents the Ruffle public API. + * + * The public API exists primarily to allow multiple installations of Ruffle on a + * page (e.g. an extension install and a local one) to cooperate. In an ideal + * situation, all Ruffle sources on the page install themselves into a single + * public API, and then the public API picks the newest version by default. + * + * This API *is* versioned, in case we need to upgrade it. However, it must be + * backwards- and forwards-compatible with all known sources. + */ +export declare class PublicAPI implements PublicAPILike { + /** + * The configuration object used when Ruffle is instantiated. + */ + config: DataLoadOptions | URLLoadOptions | object; + sources: Record; + invoked: boolean; + newestName: string | null; + /** + * Construct the Ruffle public API. + * + * Do not use this function to negotiate a public API. Instead, use + * `public_api` to register your Ruffle source with an existing public API + * if it exists. + * + * Constructing a Public API will also trigger it to initialize Ruffle once + * the page loads, if the API has not already been superseded. + * + * @param prev What used to be in the public API slot. + * + * This is used to upgrade from a prior version of the public API, or from + * a user-defined configuration object placed in the public API slot. + */ + constructor(prev?: PublicAPILike | null); + /** + * The version of the public API. + * + * This is *not* the version of Ruffle itself. + * + * This allows a page with an old version of the Public API to be upgraded + * to a new version of the API. The public API is intended to be changed + * very infrequently, if at all, but this provides an escape mechanism for + * newer Ruffle sources to upgrade older installations. + * + * @returns The version of this public API. + */ + get version(): string; + /** + * Determine the name of the newest registered source in the Public API. + * + * @returns The name of the source, or `null` if no source + * has yet to be registered. + */ + newestSourceName(): string | null; + /** + * Negotiate and start Ruffle. + * + * This function reads the config parameter to determine which polyfills + * should be enabled. If the configuration parameter is missing, then we + * use a built-in set of defaults sufficient to fool sites with static + * content and weak plugin detection. + */ + init(): void; + /** + * Look up the newest Ruffle source and return it's API. + * + * @returns An instance of the Source API. + */ + newest(): SourceAPI | null; + /** + * Look up a specific Ruffle version (or any version satisfying a given set + * of requirements) and return it's API. + * + * @param requirementString A set of semantic version requirement + * strings that the player version must satisfy. + * @returns An instance of the Source API, if one or more + * sources satisfied the requirement. + */ + satisfying(requirementString: string): SourceAPI | null; + /** + * Look up the newest Ruffle version compatible with the `local` source, if + * it's installed. Otherwise, use the latest version. + * + * @returns An instance of the Source API + */ + localCompatible(): SourceAPI | null; + /** + * Look up the newest Ruffle version with the exact same version as the + * `local` source, if it's installed. Otherwise, use the latest version. + * + * @returns An instance of the Source API + */ + local(): SourceAPI | null; + /** + * Indicates that this version of the public API has been superseded by a + * newer version. + * + * This should only be called by a newer version of the Public API. + * Identical versions of the Public API should not supersede older versions + * of that same API. + * + * Unfortunately, we can't disable polyfills after-the-fact, so this + * only lets you disable the init event... + */ + superseded(): void; +} diff --git a/packages/frontend/src/types/ruffle/setup/source-api.d.ts b/packages/frontend/src/types/ruffle/setup/source-api.d.ts new file mode 100644 index 0000000000..2ebad17113 --- /dev/null +++ b/packages/frontend/src/types/ruffle/setup/source-api.d.ts @@ -0,0 +1,34 @@ +import type { PlayerElement } from '../player/index.d.ts'; +/** + * Represents this particular version of Ruffle. + * + * Multiple APIs can be instantiated from different sources; e.g. an "extension" + * version, versus a "local" version. This expresses to the Public API + * negotiator (see {@link PublicAPI}) what this particular version of Ruffle is and + * how to control it. + */ +export interface SourceAPI { + /** + * The version of this particular API, as a string in a semver compatible format. + */ + version: string; + /** + * Start up the polyfills. + * + * Do not run polyfills for more than one Ruffle source at a time. + */ + polyfill(): void; + /** + * Polyfill the plugin detection. + * + * This needs to run before any plugin detection script does. + */ + pluginPolyfill(): void; + /** + * Create a Ruffle player element using this particular version of Ruffle. + * + * @returns The player element. This is a DOM element that may be inserted + * into the current page as you wish. + */ + createPlayer(): PlayerElement; +}