diff --git a/web/eslint.config.js b/web/eslint.config.js
index 3be1b21708e2..daba5c146add 100644
--- a/web/eslint.config.js
+++ b/web/eslint.config.js
@@ -115,6 +115,10 @@ export default tseslint.config(
startLines: 1,
},
],
+ "jsdoc/check-tag-names": [
+ "error",
+ { definedTags: ["privateRemarks"] },
+ ],
},
settings: {
jsdoc: {
diff --git a/web/package-lock.json b/web/package-lock.json
index c007986d862c..dc0d829820ab 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -38,6 +38,7 @@
"stylelint-prettier": "^5.0.2",
"ts-loader": "^9.5.1",
"tsx": "^4.19.1",
+ "typedoc-plugin-mdn-links": "^3.3.2",
"typescript": "^5.6.2",
"typescript-eslint": "^8.8.0",
"webdriverio": "^8.40.0",
@@ -15823,6 +15824,15 @@
"typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x"
}
},
+ "node_modules/typedoc-plugin-mdn-links": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/typedoc-plugin-mdn-links/-/typedoc-plugin-mdn-links-3.3.2.tgz",
+ "integrity": "sha512-5CGxkdfsG4Yki6UsFOvVN8vWXXDb25SozOlyThk9Dq8JvKcUgY+Ra+cZvkFWs3hLlO4W8xpFbYQxNngCLf9MMA==",
+ "dev": true,
+ "peerDependencies": {
+ "typedoc": ">= 0.23.14 || 0.24.x || 0.25.x || 0.26.x"
+ }
+ },
"node_modules/typedoc/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
diff --git a/web/package.json b/web/package.json
index def98d269944..5190a2150f54 100644
--- a/web/package.json
+++ b/web/package.json
@@ -35,6 +35,7 @@
"stylelint-prettier": "^5.0.2",
"ts-loader": "^9.5.1",
"tsx": "^4.19.1",
+ "typedoc-plugin-mdn-links": "^3.3.2",
"typescript": "^5.6.2",
"typescript-eslint": "^8.8.0",
"webdriverio": "^8.40.0",
diff --git a/web/packages/core/src/build-info.ts b/web/packages/core/src/build-info.ts
index d6cf11db2ea4..7fda18c68e1d 100644
--- a/web/packages/core/src/build-info.ts
+++ b/web/packages/core/src/build-info.ts
@@ -1,5 +1,10 @@
/**
- * Stores build information. The string literals are replaced at compile time by `set_version.ts`.
+ * Stores build information about this specific version of the `ruffle-core` library .
+ *
+ * It does not represent the version of Ruffle that may be in use by the page (for example, if a browser extension overrides it).
+ *
+ * @privateRemarks
+ * This is generated at build time via `set_version.ts`.
*/
export const buildInfo = {
versionNumber: "%VERSION_NUMBER%",
diff --git a/web/packages/core/src/index.ts b/web/packages/core/src/index.ts
index d1086c308638..f7b900ea9026 100644
--- a/web/packages/core/src/index.ts
+++ b/web/packages/core/src/index.ts
@@ -1,19 +1,7 @@
-/**
- * This is the public API of the web version of Ruffle.
- *
- * Types should only be exported here if they are intended to be part of that public API, not internal.
- */
+export * as Setup from "./public/setup";
+
+export * as Config from "./public/config";
+
+export * as Player from "./public/player";
-export * from "./polyfills";
-export * from "./public-api";
-export * from "./version";
-export * from "./version-range";
-export * from "./config";
-export * from "./load-options";
export * from "./build-info";
-export * from "./swf-utils";
-export * from "./movie-metadata";
-export * from "./install";
-export * from "./public/flash";
-export * from "./public/legacy";
-export * from "./public/player";
diff --git a/web/packages/core/src/internal/builder.ts b/web/packages/core/src/internal/builder.ts
index c576b4cbda5d..f60083800441 100644
--- a/web/packages/core/src/internal/builder.ts
+++ b/web/packages/core/src/internal/builder.ts
@@ -1,5 +1,5 @@
import type { RuffleInstanceBuilder } from "../../dist/ruffle_web";
-import { BaseLoadOptions, Duration, SecsDuration } from "../load-options";
+import { BaseLoadOptions, Duration, SecsDuration } from "../public/config";
/**
* Checks if the given value is explicitly `T` (not null, not undefined)
diff --git a/web/packages/core/src/internal/internal-source-api.ts b/web/packages/core/src/internal/internal-source-api.ts
new file mode 100644
index 000000000000..ab4ddc9ac4aa
--- /dev/null
+++ b/web/packages/core/src/internal/internal-source-api.ts
@@ -0,0 +1,52 @@
+import { buildInfo } from "../build-info";
+import { pluginPolyfill, polyfill } from "../polyfills";
+import { PlayerElement } from "../public/player";
+import { registerElement } from "./register-element";
+import { RufflePlayerElement } from "./player/ruffle-player-element";
+import { InstallationOptions } from "../public/setup";
+
+/**
+ * The actual source API that describes this installation.
+ * This isn't part of the public API and may contain extra details.
+ */
+export const internalSourceApi = {
+ /**
+ * The version of this particular API, as a string in a semver compatible format.
+ */
+ version:
+ buildInfo.versionNumber + "+" + buildInfo.buildDate.substring(0, 10),
+
+ /**
+ * Start up the polyfills.
+ *
+ * Do not run polyfills for more than one Ruffle source at a time.
+ */
+ polyfill(): void {
+ polyfill();
+ },
+
+ /**
+ * Polyfill the plugin detection.
+ *
+ * This needs to run before any plugin detection script does.
+ */
+ pluginPolyfill(): void {
+ pluginPolyfill();
+ },
+
+ /**
+ * 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 {
+ const name = registerElement("ruffle-player", RufflePlayerElement);
+ return document.createElement(name) as RufflePlayerElement;
+ },
+
+ /**
+ * Options specified by the user of this library.
+ */
+ options: {} as InstallationOptions,
+};
diff --git a/web/packages/core/src/internal/player/inner.tsx b/web/packages/core/src/internal/player/inner.tsx
index 78a955a402ec..8884a3ba413a 100644
--- a/web/packages/core/src/internal/player/inner.tsx
+++ b/web/packages/core/src/internal/player/inner.tsx
@@ -7,8 +7,9 @@ import {
UnmuteOverlay,
URLLoadOptions,
WindowMode,
-} from "../../load-options";
-import type { MovieMetadata } from "../../movie-metadata";
+ DEFAULT_CONFIG,
+} from "../../public/config";
+import type { MovieMetadata } from "../../public/player";
import { ruffleShadowTemplate } from "../ui/shadow-template";
import { text, textAsParagraphs } from "../i18n";
import { swfFileName } from "../../swf-utils";
@@ -25,7 +26,6 @@ import { showPanicScreen } from "../ui/panic";
import { createRuffleBuilder } from "../../load-ruffle";
import { lookupElement } from "../register-element";
import { configureBuilder } from "../builder";
-import { DEFAULT_CONFIG } from "../../config";
const DIMENSION_REGEX = /^\s*(\d+(\.\d+)?(%)?)/;
@@ -42,7 +42,13 @@ declare global {
webkitCancelFullScreen?: () => void;
}
interface Element {
+ /**
+ * @ignore
+ */
webkitRequestFullscreen?: (options: unknown) => unknown;
+ /**
+ * @ignore
+ */
webkitRequestFullScreen?: (options: unknown) => unknown;
}
}
@@ -1592,7 +1598,7 @@ export class InnerPlayer {
// Then we have to close the context menu manually after the callback finishes.
this.hideContextMenu();
- }
+ };
if (this.contextMenuSupported) {
menuItem.addEventListener("click", itemAction);
menuItem.addEventListener("contextmenu", itemAction);
diff --git a/web/packages/core/src/internal/player/ruffle-embed-element.ts b/web/packages/core/src/internal/player/ruffle-embed-element.ts
index 4a1561d568cb..b96cdb4c7e89 100644
--- a/web/packages/core/src/internal/player/ruffle-embed-element.ts
+++ b/web/packages/core/src/internal/player/ruffle-embed-element.ts
@@ -12,7 +12,7 @@ import { isSwf } from "../../swf-utils";
* A polyfill html element.
*
* This specific class tries to polyfill existing `` tags,
- * and should not be used. Prefer [[RufflePlayer]] instead.
+ * and should not be used. Prefer {@link RufflePlayer} instead.
*
* @internal
*/
diff --git a/web/packages/core/src/internal/player/ruffle-object-element.ts b/web/packages/core/src/internal/player/ruffle-object-element.ts
index 5379a4fb1bb7..1caf0588d485 100644
--- a/web/packages/core/src/internal/player/ruffle-object-element.ts
+++ b/web/packages/core/src/internal/player/ruffle-object-element.ts
@@ -17,7 +17,7 @@ import { isSwf } from "../../swf-utils";
* @param obj Object to check
* @param key Key to find
* @param defaultValue Value if not found
- * @returns Value if found, else [[defaultValue]]
+ * @returns Value if found, else {@link defaultValue}
*/
function findCaseInsensitive(
obj: Record,
@@ -34,7 +34,7 @@ function findCaseInsensitive(
}
/**
- * Returns all flash params ([[HTMLParamElement]]) that are for the given object.
+ * Returns all flash params ({@link HTMLParamElement}) that are for the given object.
*
* @param elem Element to check.
* @returns A record of every parameter.
@@ -59,7 +59,7 @@ function paramsOf(elem: Element): Record {
* A polyfill html element.
*
* This specific class tries to polyfill existing `` tags,
- * and should not be used. Prefer [[RufflePlayer]] instead.
+ * and should not be used. Prefer {@link RufflePlayer} instead.
*
* @internal
*/
diff --git a/web/packages/core/src/internal/player/ruffle-player-element.tsx b/web/packages/core/src/internal/player/ruffle-player-element.tsx
index 81329b89a092..d9ac7596926f 100644
--- a/web/packages/core/src/internal/player/ruffle-player-element.tsx
+++ b/web/packages/core/src/internal/player/ruffle-player-element.tsx
@@ -1,14 +1,13 @@
-import type { DataLoadOptions, URLLoadOptions } from "../../load-options";
-import type { MovieMetadata } from "../../movie-metadata";
+import type { DataLoadOptions, URLLoadOptions } from "../../public/config";
+import type { MovieMetadata, PlayerElement } from "../../public/player";
import { InnerPlayer, ReadyState } from "./inner";
-import { Player } from "../../public/player";
/**
* The ruffle player element that should be inserted onto the page.
*
* This element will represent the rendered and intractable flash movie.
*/
-export class RufflePlayerElement extends HTMLElement implements Player {
+export class RufflePlayerElement extends HTMLElement implements PlayerElement {
#inner: InnerPlayer;
get onFSCommand(): ((command: string, args: string) => boolean) | null {
diff --git a/web/packages/core/src/load-ruffle.ts b/web/packages/core/src/load-ruffle.ts
index fa4b4c6821a8..6b474f61a9e4 100644
--- a/web/packages/core/src/load-ruffle.ts
+++ b/web/packages/core/src/load-ruffle.ts
@@ -11,7 +11,8 @@ import {
} from "wasm-feature-detect";
import type { RuffleInstanceBuilder, ZipWriter } from "../dist/ruffle_web";
import { setPolyfillsOnLoad } from "./js-polyfills";
-import { internalSourceApi } from "./source-api";
+
+import { internalSourceApi } from "./internal/internal-source-api";
type ProgressCallback = (bytesLoaded: number, bytesTotal: number) => void;
diff --git a/web/packages/core/src/polyfills.ts b/web/packages/core/src/polyfills.ts
index a3e8a4b606a9..eb5b58c5e609 100644
--- a/web/packages/core/src/polyfills.ts
+++ b/web/packages/core/src/polyfills.ts
@@ -2,7 +2,7 @@ import { RuffleObjectElement } from "./internal/player/ruffle-object-element";
import { RuffleEmbedElement } from "./internal/player/ruffle-embed-element";
import { installPlugin, FLASH_PLUGIN } from "./plugin-polyfill";
import { publicPath } from "./public-path";
-import type { DataLoadOptions, URLLoadOptions } from "./load-options";
+import type { DataLoadOptions, URLLoadOptions } from "./public/config";
import { isExtension } from "./current-script";
const globalConfig: DataLoadOptions | URLLoadOptions | object =
diff --git a/web/packages/core/src/public-path.ts b/web/packages/core/src/public-path.ts
index a546cd90baee..fb6576a68806 100644
--- a/web/packages/core/src/public-path.ts
+++ b/web/packages/core/src/public-path.ts
@@ -1,4 +1,4 @@
-import { BaseLoadOptions } from "./load-options";
+import { BaseLoadOptions } from "./public/config";
import { currentScriptURL, isExtension } from "./current-script";
/**
diff --git a/web/packages/core/src/config.ts b/web/packages/core/src/public/config/default.ts
similarity index 100%
rename from web/packages/core/src/config.ts
rename to web/packages/core/src/public/config/default.ts
diff --git a/web/packages/core/src/public/config/index.ts b/web/packages/core/src/public/config/index.ts
new file mode 100644
index 000000000000..5a1ae261d316
--- /dev/null
+++ b/web/packages/core/src/public/config/index.ts
@@ -0,0 +1,11 @@
+/**
+ * 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 * from "./default";
+export * from "./load-options";
diff --git a/web/packages/core/src/load-options.ts b/web/packages/core/src/public/config/load-options.ts
similarity index 99%
rename from web/packages/core/src/load-options.ts
rename to web/packages/core/src/public/config/load-options.ts
index ffd98b6cc2a3..8586c11373d3 100644
--- a/web/packages/core/src/load-options.ts
+++ b/web/packages/core/src/public/config/load-options.ts
@@ -676,7 +676,7 @@ export interface URLLoadOptions extends BaseLoadOptions {
/**
* The URL to load a movie from.
*
- * If there is a query portion of this URL, then default [[parameters]]
+ * If there is a query portion of this URL, then default {@link parameters}
* will be extracted from that.
*/
url: string;
diff --git a/web/packages/core/src/public/flash.ts b/web/packages/core/src/public/player/flash.ts
similarity index 87%
rename from web/packages/core/src/public/flash.ts
rename to web/packages/core/src/public/player/flash.ts
index 70bf94d7c330..64754bfbf1b4 100644
--- a/web/packages/core/src/public/flash.ts
+++ b/web/packages/core/src/public/player/flash.ts
@@ -1,5 +1,5 @@
/**
- * These are properties and methods that Flash added to its / tags.
+ * 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.
*
diff --git a/web/packages/core/src/public/player/index.ts b/web/packages/core/src/public/player/index.ts
new file mode 100644
index 000000000000..0ef102322544
--- /dev/null
+++ b/web/packages/core/src/public/player/index.ts
@@ -0,0 +1,10 @@
+/**
+ * The Player module contains the actual {@link PlayerElement} and the various interfaces that exist to interact with the player.
+ *
+ * @module
+ */
+
+export * from "./flash";
+export * from "./player-element";
+export * from "./movie-metadata";
+export * from "./legacy";
diff --git a/web/packages/core/src/public/legacy.ts b/web/packages/core/src/public/player/legacy.ts
similarity index 88%
rename from web/packages/core/src/public/legacy.ts
rename to web/packages/core/src/public/player/legacy.ts
index 0ca499d28e03..605c4d50e41b 100644
--- a/web/packages/core/src/public/legacy.ts
+++ b/web/packages/core/src/public/player/legacy.ts
@@ -1,6 +1,6 @@
-import { DataLoadOptions, URLLoadOptions } from "../load-options";
-import { MovieMetadata } from "../movie-metadata";
-import { ReadyState } from "../internal/player/inner";
+import { DataLoadOptions, URLLoadOptions } from "../config";
+import { MovieMetadata } from "./movie-metadata";
+import { ReadyState } from "../../internal/player/inner";
/**
* Legacy interface to the Ruffle API.
@@ -48,7 +48,7 @@ export interface LegacyRuffleAPI {
get metadata(): MovieMetadata | null;
/**
- * Reloads the player, as if you called {@link RufflePlayer.load} with the same config as the last time it was called.
+ * 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.
*/
@@ -61,13 +61,13 @@ export interface LegacyRuffleAPI {
*
* @param options One of the following:
* - A URL, passed as a string, which will load a URL with default options.
- * - A [[URLLoadOptions]] object, to load a URL with options.
- * - A [[DataLoadOptions]] object, to load data with 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 [[config]] field, which itself
+ * 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;
@@ -105,7 +105,7 @@ export interface LegacyRuffleAPI {
/**
* Checks if this player is allowed to be fullscreen by the browser.
*
- * @returns True if you may call [[enterFullscreen]].
+ * @returns True if you may call {@link enterFullscreen}.
*/
get fullscreenEnabled(): boolean;
@@ -127,7 +127,7 @@ export interface LegacyRuffleAPI {
/**
* Requests the browser to make this player fullscreen.
*
- * This is not guaranteed to succeed, please check [[fullscreenEnabled]] first.
+ * This is not guaranteed to succeed, please check {@link fullscreenEnabled} first.
*/
enterFullscreen(): void;
diff --git a/web/packages/core/src/movie-metadata.ts b/web/packages/core/src/public/player/movie-metadata.ts
similarity index 100%
rename from web/packages/core/src/movie-metadata.ts
rename to web/packages/core/src/public/player/movie-metadata.ts
diff --git a/web/packages/core/src/public/player.ts b/web/packages/core/src/public/player/player-element.ts
similarity index 57%
rename from web/packages/core/src/public/player.ts
rename to web/packages/core/src/public/player/player-element.ts
index 36956e2ca0b1..97b663382b6d 100644
--- a/web/packages/core/src/public/player.ts
+++ b/web/packages/core/src/public/player/player-element.ts
@@ -4,9 +4,9 @@ import { FlashAPI } from "./flash";
/**
* A Ruffle player's HTML element.
*
- * This is either created through `window.RufflePlayer.createPlayer()`, or polyfilled from a ``/`` tag.
+ * 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 Player extends HTMLElement, LegacyRuffleAPI, FlashAPI {}
+export interface PlayerElement extends HTMLElement, LegacyRuffleAPI, FlashAPI {}
diff --git a/web/packages/core/src/public/setup/index.ts b/web/packages/core/src/public/setup/index.ts
new file mode 100644
index 000000000000..eb86b3c22c21
--- /dev/null
+++ b/web/packages/core/src/public/setup/index.ts
@@ -0,0 +1,20 @@
+/**
+ * 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 * from "./public-api";
+export * from "./source-api";
+export * from "./install";
diff --git a/web/packages/core/src/install.ts b/web/packages/core/src/public/setup/install.ts
similarity index 96%
rename from web/packages/core/src/install.ts
rename to web/packages/core/src/public/setup/install.ts
index 1c5473cf7ebd..2254bd9d315d 100644
--- a/web/packages/core/src/install.ts
+++ b/web/packages/core/src/public/setup/install.ts
@@ -1,5 +1,6 @@
import { PublicAPI } from "./public-api";
-import { internalSourceApi } from "./source-api";
+
+import { internalSourceApi } from "../../internal/internal-source-api";
/**
* Options to use with this specific installation of Ruffle.
diff --git a/web/packages/core/src/public-api.ts b/web/packages/core/src/public/setup/public-api.ts
similarity index 95%
rename from web/packages/core/src/public-api.ts
rename to web/packages/core/src/public/setup/public-api.ts
index a65472cae1a1..7e7ac422428a 100644
--- a/web/packages/core/src/public-api.ts
+++ b/web/packages/core/src/public/setup/public-api.ts
@@ -1,15 +1,15 @@
-import { Version } from "./version";
-import { VersionRange } from "./version-range";
+import { Version } from "../../version";
+import { VersionRange } from "../../version-range";
import { SourceAPI } from "./source-api";
-import type { DataLoadOptions, URLLoadOptions } from "./load-options";
+import type { DataLoadOptions, URLLoadOptions } from "../config";
declare global {
interface Window {
/**
* The public API for generating a ruffle player.
* This may be a config holder, which will be converted to a
- * [[PublicAPI]] via [[installRuffle]], or an actual
- * [[PublicAPI]] instance itself.
+ * {@link PublicAPI} via {@link installRuffle}, or an actual
+ * {@link PublicAPI} instance itself.
*/
RufflePlayer?: PublicAPILike | PublicAPI;
}
@@ -18,8 +18,8 @@ declare global {
/**
* Represents a potential installation of a Ruffle public API.
*
- * Unlike [[PublicAPI]], this may come from any source, past or future.
- * It needs to be forwards compatible and convertible into a modern day [[PublicAPI]].
+ * 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;
diff --git a/web/packages/core/src/public/setup/source-api.ts b/web/packages/core/src/public/setup/source-api.ts
new file mode 100644
index 000000000000..0e88b4e25e83
--- /dev/null
+++ b/web/packages/core/src/public/setup/source-api.ts
@@ -0,0 +1,38 @@
+import { PlayerElement } from "../player";
+
+/**
+ * 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;
+}
diff --git a/web/packages/core/src/source-api.ts b/web/packages/core/src/source-api.ts
deleted file mode 100644
index 5ea1dc61ab9c..000000000000
--- a/web/packages/core/src/source-api.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { pluginPolyfill, polyfill } from "./polyfills";
-import { registerElement } from "./internal/register-element";
-import { RufflePlayerElement } from "./internal/player/ruffle-player-element";
-import { buildInfo } from "./build-info";
-import { InstallationOptions } from "./install";
-import { Player } from "./public/player";
-
-/**
- * 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 [[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(): Player;
-}
-
-/**
- * The actual source API that describes this installation.
- * This isn't part of the public API and may contain extra details.
- */
-export const internalSourceApi = {
- /**
- * The version of this particular API, as a string in a semver compatible format.
- */
- version:
- buildInfo.versionNumber + "+" + buildInfo.buildDate.substring(0, 10),
-
- /**
- * Start up the polyfills.
- *
- * Do not run polyfills for more than one Ruffle source at a time.
- */
- polyfill(): void {
- polyfill();
- },
-
- /**
- * Polyfill the plugin detection.
- *
- * This needs to run before any plugin detection script does.
- */
- pluginPolyfill(): void {
- pluginPolyfill();
- },
-
- /**
- * 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(): Player {
- const name = registerElement("ruffle-player", RufflePlayerElement);
- return document.createElement(name) as RufflePlayerElement;
- },
-
- /**
- * Options specified by the user of this library.
- */
- options: {} as InstallationOptions,
-};
diff --git a/web/packages/core/src/version-range.ts b/web/packages/core/src/version-range.ts
index db9ff17dbf7b..65ff105c0f4e 100644
--- a/web/packages/core/src/version-range.ts
+++ b/web/packages/core/src/version-range.ts
@@ -43,7 +43,7 @@ export class VersionRange {
* Constructs a range of versions as specified by the given requirements.
*
* If you wish to construct this object from a string representation,
- * then use [[fromRequirementString]].
+ * then use {@link fromRequirementString}.
*
* @param requirements Requirements to set this range by
*/
diff --git a/web/packages/core/src/version.ts b/web/packages/core/src/version.ts
index b4a3e186ec6f..b8fd6f33b600 100644
--- a/web/packages/core/src/version.ts
+++ b/web/packages/core/src/version.ts
@@ -5,7 +5,7 @@ export class Version {
/**
* Construct a Version from specific components.
*
- * If you wish to parse a string into a Version then please use [[fromSemver]].
+ * If you wish to parse a string into a Version then please use {@link fromSemver}.
*
* @param major The major version component.
* @param minor The minor version component.
diff --git a/web/packages/core/typedoc.json b/web/packages/core/typedoc.json
index 23f8cff4b40a..ff9f8bd599bc 100644
--- a/web/packages/core/typedoc.json
+++ b/web/packages/core/typedoc.json
@@ -2,5 +2,7 @@
"entryPoints": ["./src/index.ts"],
"excludePrivate": true,
"excludeProtected": true,
- "sort": "enum-member-source-order"
+ "excludeExternals": true,
+ "sort": "enum-member-source-order",
+ "plugin": ["typedoc-plugin-mdn-links"]
}
diff --git a/web/packages/demo/src/App.tsx b/web/packages/demo/src/App.tsx
index fec9df73b026..d0af1119e241 100644
--- a/web/packages/demo/src/App.tsx
+++ b/web/packages/demo/src/App.tsx
@@ -1,11 +1,11 @@
import { Player } from "./player.tsx";
import { useRef, useState, DragEvent, useCallback } from "react";
-import { BaseLoadOptions, MovieMetadata } from "ruffle-core";
+import type { Config, Player as RufflePlayer } from "ruffle-core";
import { Navbar } from "./navbar.tsx";
import { MetadataPanel } from "./metadata.tsx";
interface AppProperties {
- ruffleBaseConfig: BaseLoadOptions;
+ ruffleBaseConfig: Config.BaseLoadOptions;
allowUrlLoading: boolean;
allowSampleSwfs: boolean;
}
@@ -15,7 +15,9 @@ export function App({
allowUrlLoading,
allowSampleSwfs,
}: AppProperties) {
- const [metadata, setMetadata] = useState(null);
+ const [metadata, setMetadata] = useState(
+ null,
+ );
const [metadataVisible, setMetadataVisible] = useState(false);
const [selectedFilename, setSelectedFilename] = useState(
null,
@@ -33,9 +35,12 @@ export function App({
};
// useCallback because this will be called from useEffect, we need this function to not change
- const onSelectUrl = useCallback((url: string, options: BaseLoadOptions) => {
- player.current?.loadUrl(url, options);
- }, []);
+ const onSelectUrl = useCallback(
+ (url: string, options: Config.BaseLoadOptions) => {
+ player.current?.loadUrl(url, options);
+ },
+ [],
+ );
const onSelectFile = (file: File) => {
player.current?.loadFile(file);
diff --git a/web/packages/demo/src/main.tsx b/web/packages/demo/src/main.tsx
index 846c45ad35ba..0d8afe8a6dad 100644
--- a/web/packages/demo/src/main.tsx
+++ b/web/packages/demo/src/main.tsx
@@ -4,24 +4,18 @@ import "./common.css";
import "./lato.css";
import "./index.css";
import { App } from "./App.tsx";
-import {
- AutoPlay,
- Letterbox,
- LogLevel,
- installRuffle,
- UnmuteOverlay,
-} from "ruffle-core";
+import { Config, Setup } from "ruffle-core";
-installRuffle("local");
+Setup.installRuffle("local");
ReactDOM.createRoot(document.getElementById("root")!).render(
FP Version
{metadata
- ? swfToFlashVersion[metadata.swfVersion] ?? "Unknown"
+ ? (swfToFlashVersion[metadata.swfVersion] ?? "Unknown")
: ""}
diff --git a/web/packages/demo/src/navbar.tsx b/web/packages/demo/src/navbar.tsx
index cae8bac9b08c..18e5b7d8890d 100644
--- a/web/packages/demo/src/navbar.tsx
+++ b/web/packages/demo/src/navbar.tsx
@@ -7,7 +7,7 @@ import {
useState,
DragEvent,
} from "react";
-import { BaseLoadOptions } from "ruffle-core";
+import type { Config } from "ruffle-core";
import { DemoSwf, SampleSelection } from "./navbar/samples.tsx";
declare global {
@@ -25,7 +25,7 @@ interface NavbarProps {
allowSampleSwfs: boolean;
onToggleMetadata: () => void;
onReloadMovie: () => void;
- onSelectUrl: (url: string, options: BaseLoadOptions) => void;
+ onSelectUrl: (url: string, options: Config.BaseLoadOptions) => void;
onSelectFile: (file: File) => void;
selectedFilename: string | null;
setSelectedFilename: (value: string | null) => void;
diff --git a/web/packages/demo/src/navbar/samples.tsx b/web/packages/demo/src/navbar/samples.tsx
index f2fb15be988f..5ecd4f98a9f4 100644
--- a/web/packages/demo/src/navbar/samples.tsx
+++ b/web/packages/demo/src/navbar/samples.tsx
@@ -6,7 +6,7 @@ import {
useEffect,
useState,
} from "react";
-import { BaseLoadOptions } from "ruffle-core";
+import type { Config } from "ruffle-core";
type SampleCategory = "Animation" | "Game";
@@ -20,7 +20,7 @@ export interface DemoSwf {
title?: string;
author?: string;
authorLink?: string;
- config?: BaseLoadOptions;
+ config?: Config.BaseLoadOptions;
type: SampleCategory | null;
}
@@ -29,7 +29,7 @@ interface SampleSelectionProperties {
selectedSample: DemoSwf | null;
setSelectedSample: (value: DemoSwf | null) => void;
setSelectedFilename: (name: string | null) => void;
- onSelectUrl: (url: string, config: BaseLoadOptions) => void;
+ onSelectUrl: (url: string, config: Config.BaseLoadOptions) => void;
}
export function SampleSelection({
diff --git a/web/packages/demo/src/player.tsx b/web/packages/demo/src/player.tsx
index eb1f2cdfdd51..f58bb5074df7 100644
--- a/web/packages/demo/src/player.tsx
+++ b/web/packages/demo/src/player.tsx
@@ -1,16 +1,11 @@
import React, { ReactNode, DragEvent } from "react";
-import {
- PublicAPI,
- Player as RufflePlayer,
- MovieMetadata,
- BaseLoadOptions,
-} from "ruffle-core";
+import { Setup, Player as RufflePlayer, Config } from "ruffle-core";
export interface PlayerAttributes {
id?: string | undefined;
children?: ReactNode;
- onLoadedMetadata: (metadata: MovieMetadata) => void;
- baseConfig?: BaseLoadOptions;
+ onLoadedMetadata: (metadata: RufflePlayer.MovieMetadata) => void;
+ baseConfig?: Config.BaseLoadOptions;
onDragEnter: (event: DragEvent) => void;
onDragLeave: (event: DragEvent) => void;
onDragOver: (event: DragEvent) => void;
@@ -19,7 +14,7 @@ export interface PlayerAttributes {
export class Player extends React.Component {
private readonly container: React.RefObject;
- private player: RufflePlayer | null = null;
+ private player: RufflePlayer.PlayerElement | null = null;
// [NA] Ruffle has a bug where if you load a swf whilst it's already loading another swf, it breaks
// Combine this with React testing everything by loading things twice to catch bugs - well, they caught the bug for sure.
@@ -33,7 +28,7 @@ export class Player extends React.Component {
}
componentDidMount() {
- this.player = (window.RufflePlayer as PublicAPI)
+ this.player = (window.RufflePlayer as Setup.PublicAPI)
.newest()!
.createPlayer()!;
this.player.id = "player";
@@ -78,7 +73,7 @@ export class Player extends React.Component {
}
}
- loadUrl(url: string, options: BaseLoadOptions) {
+ loadUrl(url: string, options: Config.BaseLoadOptions) {
if (!this.isLoading) {
this.isLoading = true;
this.player
diff --git a/web/packages/extension/src/common.ts b/web/packages/extension/src/common.ts
index 19293db4804f..4dec1094742b 100644
--- a/web/packages/extension/src/common.ts
+++ b/web/packages/extension/src/common.ts
@@ -1,7 +1,7 @@
import * as utils from "./utils";
-import type { BaseLoadOptions } from "ruffle-core";
+import type { Config } from "ruffle-core";
-export interface Options extends BaseLoadOptions {
+export interface Options extends Config.BaseLoadOptions {
ruffleEnable: boolean;
ignoreOptout: boolean;
autostart: boolean;
diff --git a/web/packages/extension/src/messages.ts b/web/packages/extension/src/messages.ts
index 3d1d3b477948..9eda0b2caae9 100644
--- a/web/packages/extension/src/messages.ts
+++ b/web/packages/extension/src/messages.ts
@@ -1,8 +1,8 @@
-import { BaseLoadOptions } from "ruffle-core";
+import type { Config } from "ruffle-core";
export interface LoadMessage {
type: "load";
- config: BaseLoadOptions;
+ config: Config.BaseLoadOptions;
}
export interface PingMessage {
diff --git a/web/packages/extension/src/player.ts b/web/packages/extension/src/player.ts
index 7daeb91837d3..2a9e0df0e77d 100644
--- a/web/packages/extension/src/player.ts
+++ b/web/packages/extension/src/player.ts
@@ -1,11 +1,7 @@
import * as utils from "./utils";
-import { installRuffle, PublicAPI } from "ruffle-core";
-import type {
- Letterbox,
- Player,
- DataLoadOptions,
- URLLoadOptions,
-} from "ruffle-core";
+import { Setup } from "ruffle-core";
+
+import type { Config, Player } from "ruffle-core";
declare global {
interface Navigator {
@@ -17,9 +13,9 @@ declare global {
}
}
-installRuffle("local");
-const ruffle = (window.RufflePlayer as PublicAPI).newest()!;
-let player: Player;
+Setup.installRuffle("local");
+const ruffle = (window.RufflePlayer as Setup.PublicAPI).newest()!;
+let player: Player.PlayerElement;
const playerContainer = document.getElementById("player-container")!;
const overlay = document.getElementById("overlay")!;
@@ -39,7 +35,7 @@ const grant = document.getElementById("grant")! as HTMLButtonElement;
// This is the base config always used by the extension player.
// It has the highest priority and its options cannot be overwritten.
const baseExtensionConfig = {
- letterbox: "on" as Letterbox,
+ letterbox: "on" as Config.Letterbox,
forceScale: true,
forceAlign: true,
showSwfDownload: true,
@@ -102,7 +98,9 @@ function unload() {
}
}
-async function load(options: string | DataLoadOptions | URLLoadOptions) {
+async function load(
+ options: string | Config.DataLoadOptions | Config.URLLoadOptions,
+) {
unload();
player = ruffle.createPlayer();
player.id = "player";
diff --git a/web/packages/extension/src/ruffle.ts b/web/packages/extension/src/ruffle.ts
index ed518da3ba66..91e2ce4c9c87 100644
--- a/web/packages/extension/src/ruffle.ts
+++ b/web/packages/extension/src/ruffle.ts
@@ -1,4 +1,4 @@
-import { installRuffle } from "ruffle-core";
+import { Setup } from "ruffle-core";
import { Message } from "./messages";
function handleMessage(message: Message) {
@@ -15,7 +15,7 @@ function handleMessage(message: Message) {
...window.RufflePlayer.config,
openInNewTab,
};
- installRuffle("extension");
+ Setup.installRuffle("extension");
return {};
}
case "ping":
diff --git a/web/packages/extension/src/utils.ts b/web/packages/extension/src/utils.ts
index c2d3e1a25bbd..35815cf2ff55 100644
--- a/web/packages/extension/src/utils.ts
+++ b/web/packages/extension/src/utils.ts
@@ -1,8 +1,8 @@
import type { Options } from "./common";
-import { DEFAULT_CONFIG as CORE_DEFAULT_CONFIG } from "ruffle-core";
+import { Config } from "ruffle-core";
const DEFAULT_OPTIONS: Required = {
- ...CORE_DEFAULT_CONFIG,
+ ...Config.DEFAULT_CONFIG,
ruffleEnable: true,
ignoreOptout: false,
autostart: false,
diff --git a/web/packages/selfhosted/js/ruffle.js b/web/packages/selfhosted/js/ruffle.js
index c65550803584..b426b18458a3 100644
--- a/web/packages/selfhosted/js/ruffle.js
+++ b/web/packages/selfhosted/js/ruffle.js
@@ -1,7 +1,7 @@
// eslint-disable-next-line no-unused-vars
/* global __webpack_public_path__:writable */
-import { installRuffle } from "ruffle-core";
+import { Setup } from "ruffle-core";
let currentScriptURL = null;
@@ -46,7 +46,7 @@ function publicPath(config) {
return path;
}
-installRuffle("local", {
+Setup.installRuffle("local", {
onFirstLoad: () => {
__webpack_public_path__ = publicPath(window.RufflePlayer?.config);
},
diff --git a/web/packages/selfhosted/test/js_api/load.ts b/web/packages/selfhosted/test/js_api/load.ts
index f897570c9708..e083fc6e93cb 100644
--- a/web/packages/selfhosted/test/js_api/load.ts
+++ b/web/packages/selfhosted/test/js_api/load.ts
@@ -12,7 +12,7 @@ describe("RufflePlayer.load", () => {
const player = await browser.$("");
await browser.execute(async (playerElement) => {
// https://github.com/webdriverio/webdriverio/issues/6486
- const player = playerElement as unknown as Player;
+ const player = playerElement as unknown as Player.PlayerElement;
await player.load("/test_assets/example.swf");
}, player);
await playAndMonitor(browser, player);
diff --git a/web/packages/selfhosted/test/js_api/metadata.ts b/web/packages/selfhosted/test/js_api/metadata.ts
index eace4b07fdb2..8645af8259c2 100644
--- a/web/packages/selfhosted/test/js_api/metadata.ts
+++ b/web/packages/selfhosted/test/js_api/metadata.ts
@@ -12,7 +12,7 @@ describe("RufflePlayer.metadata", () => {
const player = await browser.$("");
const metadata = await browser.execute(
// https://github.com/webdriverio/webdriverio/issues/6486
- (player) => (player as unknown as Player).metadata,
+ (player) => (player as unknown as Player.PlayerElement).metadata,
player,
);
// [NA] Work around a chrome 87 bug where it's (somehow) adding extra data to this object
diff --git a/web/packages/selfhosted/test/utils.ts b/web/packages/selfhosted/test/utils.ts
index 8f8c7f1357bd..ba524c426b95 100644
--- a/web/packages/selfhosted/test/utils.ts
+++ b/web/packages/selfhosted/test/utils.ts
@@ -1,5 +1,5 @@
import { expect } from "chai";
-import { Player, PublicAPI } from "ruffle-core";
+import { Player, Setup } from "ruffle-core";
declare global {
interface Window {
@@ -7,8 +7,8 @@ declare global {
}
}
-declare module "ruffle-core" {
- interface Player {
+declare module "ruffle-core/dist/public/player" {
+ interface PlayerElement {
__ruffle_log__: string;
}
}
@@ -31,7 +31,7 @@ export async function isRufflePlayerLoaded(
(player) =>
// https://github.com/webdriverio/webdriverio/issues/6486
// TODO: How can we import ReadyState enum?
- (player as unknown as Player).readyState,
+ (player as unknown as Player.PlayerElement).readyState,
player,
)) === 2
);
@@ -103,7 +103,7 @@ export async function setupAndPlay(
) {
await browser.execute((playerElement) => {
// https://github.com/webdriverio/webdriverio/issues/6486
- const player = playerElement as unknown as Player;
+ const player = playerElement as unknown as Player.PlayerElement;
player.__ruffle_log__ = "";
player.traceObserver = (msg) => {
player.__ruffle_log__ += msg + "\n";
@@ -122,7 +122,8 @@ export async function getTraceOutput(
return (
(await browser.execute((player) => {
// https://github.com/webdriverio/webdriverio/issues/6486
- return (player as unknown as Player).__ruffle_log__;
+ return (player as unknown as Player.PlayerElement)
+ .__ruffle_log__;
}, player)) !== ""
);
},
@@ -134,7 +135,7 @@ export async function getTraceOutput(
// Get the output, and replace it with an empty string for any future test
return await browser.execute((playerElement) => {
// https://github.com/webdriverio/webdriverio/issues/6486
- const player = playerElement as unknown as Player;
+ const player = playerElement as unknown as Player.PlayerElement;
const log = player.__ruffle_log__;
player.__ruffle_log__ = "";
return log;
@@ -178,7 +179,7 @@ export function loadJsAPI(swf?: string) {
await injectRuffleAndWait(browser);
player = (await browser.execute(() => {
- const ruffle = (window.RufflePlayer as PublicAPI).newest();
+ const ruffle = (window.RufflePlayer as Setup.PublicAPI).newest();
const player = ruffle!.createPlayer();
const container = document.getElementById("test-container");
container!.appendChild(player);
@@ -190,7 +191,7 @@ export function loadJsAPI(swf?: string) {
await browser.execute(
async (player, swf) => {
// https://github.com/webdriverio/webdriverio/issues/6486
- await (player as unknown as Player).load(swf);
+ await (player as unknown as Player.PlayerElement).load(swf);
},
player,
swf,