Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

web: Shuffle the ruffle-core API and improve typedocs #18153

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions web/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ export default tseslint.config(
startLines: 1,
},
],
"jsdoc/check-tag-names": [
"error",
{ definedTags: ["privateRemarks"] },
],
},
settings: {
jsdoc: {
Expand Down
10 changes: 10 additions & 0 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
7 changes: 6 additions & 1 deletion web/packages/core/src/build-info.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
/**
* Stores build information. The string literals are replaced at compile time by `set_version.ts`.
* Stores build information about <b>this specific version of the `ruffle-core` library</b>.
*
* 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%",
Expand Down
22 changes: 5 additions & 17 deletions web/packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -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";
2 changes: 1 addition & 1 deletion web/packages/core/src/internal/builder.ts
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
52 changes: 52 additions & 0 deletions web/packages/core/src/internal/internal-source-api.ts
Original file line number Diff line number Diff line change
@@ -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,
};
14 changes: 10 additions & 4 deletions web/packages/core/src/internal/player/inner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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+)?(%)?)/;

Expand All @@ -42,7 +42,13 @@ declare global {
webkitCancelFullScreen?: () => void;
}
interface Element {
/**
* @ignore
*/
webkitRequestFullscreen?: (options: unknown) => unknown;
/**
* @ignore
*/
webkitRequestFullScreen?: (options: unknown) => unknown;
}
}
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { isSwf } from "../../swf-utils";
* A polyfill html element.
*
* This specific class tries to polyfill existing `<embed>` tags,
* and should not be used. Prefer [[RufflePlayer]] instead.
* and should not be used. Prefer {@link RufflePlayer} instead.
*
* @internal
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, string>,
Expand All @@ -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.
Expand All @@ -59,7 +59,7 @@ function paramsOf(elem: Element): Record<string, string> {
* A polyfill html element.
*
* This specific class tries to polyfill existing `<object>` tags,
* and should not be used. Prefer [[RufflePlayer]] instead.
* and should not be used. Prefer {@link RufflePlayer} instead.
*
* @internal
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
3 changes: 2 additions & 1 deletion web/packages/core/src/load-ruffle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion web/packages/core/src/polyfills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
2 changes: 1 addition & 1 deletion web/packages/core/src/public-path.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BaseLoadOptions } from "./load-options";
import { BaseLoadOptions } from "./public/config";
import { currentScriptURL, isExtension } from "./current-script";

/**
Expand Down
11 changes: 11 additions & 0 deletions web/packages/core/src/public/config/index.ts
Original file line number Diff line number Diff line change
@@ -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";
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* These are properties and methods that Flash added to its <embed>/<object> tags.
* These are properties and methods that Flash added to its `<embed>/<object>` 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.
*
Expand Down
10 changes: 10 additions & 0 deletions web/packages/core/src/public/player/index.ts
Original file line number Diff line number Diff line change
@@ -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";
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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.
*/
Expand All @@ -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<void>;
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<embed>`/`<object>` tag.
* This is either created through `window.RufflePlayer.latest().createPlayer()`, or polyfilled from a `<embed>`/`<object>` 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 {}
20 changes: 20 additions & 0 deletions web/packages/core/src/public/setup/index.ts
Original file line number Diff line number Diff line change
@@ -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";
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
Loading