Commit e46c106c authored by Lyza Danger Gardner's avatar Lyza Danger Gardner Committed by Lyza Gardner

Expand typing and comments for sidebar-config types

parent dae7bed2
......@@ -4,6 +4,8 @@ import * as postMessageJsonRpc from '../util/postmessage-json-rpc';
/**
* @typedef {import('../../types/config').ConfigFromHost} ConfigFromHost
* @typedef {import('../../types/config').ConfigFromAnnotator} ConfigFromAnnotator
* @typedef {import('../../types/config').ConfigFromEmbedder} ConfigFromEmbedder
* @typedef {import('../../types/config').ConfigFromSidebar} ConfigFromSidebar
* @typedef {import('../../types/config').RPCSettings} RPCSettings
* @typedef {import('../../types/config').SidebarSettings} SidebarSettings
......@@ -71,9 +73,9 @@ function fetchServiceGroups(configFromHost, rpcSettings) {
}
/**
* Derive RPC settings from the provided `ConfigFromHost`, if any are present.
* Derive RPC settings from the provided `AnnotatorConfigFromHost`, if any are present.
*
* @param {ConfigFromHost} configFromHost
* @param {ConfigFromAnnotator} configFromHost
* @param {Window} window_
* @return {import('../../types/config').RPCSettings|null}
*/
......@@ -99,11 +101,11 @@ function buildRPCSettings(configFromHost, window_) {
* Retrieve ConfigFromHost to use for settings from the ancestor frame indicated
* in `rpcSettings`
*
* @param {ConfigFromHost} hostConfigFromURL
* @param {ConfigFromAnnotator} hostConfigFromURL
* @param {RPCSettings} rpcSettings
* @return {Promise<ConfigFromHost>}
* @return {Promise<ConfigFromEmbedder>}
*/
async function getHostConfigByRPC(hostConfigFromURL, rpcSettings) {
async function getEmbedderConfig(hostConfigFromURL, rpcSettings) {
const hostConfigFromFrame = await postMessageJsonRpc.call(
rpcSettings.targetFrame,
rpcSettings.origin,
......@@ -140,21 +142,21 @@ async function getHostConfigByRPC(hostConfigFromURL, rpcSettings) {
* @return {Promise<SidebarSettings>} - The merged settings
*/
export async function buildSettings(configFromSidebar, window_ = window) {
const hostConfigFromURL = hostPageConfig(window);
const annotatorConfigFromHost = hostPageConfig(window);
const rpcSettings = buildRPCSettings(hostConfigFromURL, window_);
const rpcSettings = buildRPCSettings(annotatorConfigFromHost, window_);
let configFromHost;
if (rpcSettings) {
// The presence of RPCSettings indicates that we should
// source the ConfigFromHost from another frame, and potentially load
// the correct groups asynchronously as well.
const hostConfigFromFrame = await getHostConfigByRPC(
hostConfigFromURL,
const hostConfigFromFrame = await getEmbedderConfig(
annotatorConfigFromHost,
rpcSettings
);
configFromHost = fetchServiceGroups(hostConfigFromFrame, rpcSettings);
} else {
configFromHost = hostConfigFromURL;
configFromHost = annotatorConfigFromHost;
}
/** @type {SidebarSettings} */
......
......@@ -6,14 +6,14 @@ import {
toString,
} from '../../shared/type-coercions';
/** @typedef {import('../../types/config').ConfigFromHost} ConfigFromHost */
/** @typedef {import('../../types/config').ConfigFromAnnotator} ConfigFromAnnotator */
/**
* Return the app configuration specified by the frame embedding the Hypothesis
* client.
*
* @param {Window} window
* @return {ConfigFromHost}
* @return {ConfigFromAnnotator}
*/
export function hostPageConfig(window) {
const config = parseConfigFragment(window.location.href);
......
......@@ -54,13 +54,33 @@
*/
/**
* @typedef RequestConfigFromFrameOptions
* May be provided by `ConfigFromAnnotator` to configure a known ancestor
* frame as the "embedder" frame. `ConfigFromEmbedder` will be requested from
* this frame, and additional messaging (via postMessage) may be configured
* between the sidebar frame and this embedder frame.
*
* @typedef EmbedderFrameConfig
* @prop {number} ancestorLevel
* @prop {string} origin
*/
/**
* Configuration set by the embedder of the client and used by the sidebar.
* An "embedder frame" may provide configuration to be notified (via JSON RPC)
* of qualifying annotation activity from the sidebar frame.
*
* @typedef {'create'|'save'|'delete'} AnnotationActivityEvent
*
* @typedef ReportAnnotationActivityConfig
* @prop {string} method - Name of method to call in embedder frame on
* qualifying annotation activity
* @prop {AnnotationActivityEvent[]} events - Which events to notify about
*
*/
/**
* Configuration provided by the annotator ("host frame") as
* `ConfigFromAnnotator` OR by an ancestor ("embedder frame") as
* `ConfigFromEmbedder`.
*
* This is the subset of keys from
* https://h.readthedocs.io/projects/client/en/latest/publishers/config/ which
......@@ -77,8 +97,12 @@
* Theme properties (fonts, colors etc.)
* @prop {boolean} [enableExperimentalNewNoteButton] -
* Whether to show the "New note" button on the "Page Notes" tab
* @prop {RequestConfigFromFrameOptions} [requestConfigFromFrame]
* Origin of the ancestor frame to request configuration from
* @prop {EmbedderFrameConfig} [requestConfigFromFrame] - Allows annotator to
* designate an ancestor frame from which configuration should be requested.
* Only valid when provided by annotator ("host frame").
* @prop {ReportAnnotationActivityConfig} [reportActivity] - Allows embedder to
* receive notifications on qualifying annotation activity. Only valid when
* provided by ancestor ("embedder frame").
* @prop {Service[]} [services] -
* Configuration for the annotation services that the client connects to
* @prop {string} [theme]
......@@ -88,18 +112,67 @@
*/
/**
* RPC settings derived from `ConfigFromHost['requestConfigFromFrame']`
* Settings derived from `ConfigFromAnnotator["requestConfigFromFrame"]`.
* These settings allow `ConfigFromEmbedder` to be requested from the
* designated frame, and allows subsequent communication between the sidebar
* and embedder frames.
*
* @typedef RPCSettings
* @prop {Window} targetFrame
* @prop {RequestConfigFromFrameOptions['origin']} origin
* @prop {EmbedderFrameConfig['origin']} origin
*/
/**
* The `settings` object used in the sidebar app that is a result of merging
* (filtered and validated) configuration from the host page with configuration
* from h / the browser extension.
* `SidebarSettings` are created by merging "sidebar configuration"
* (`ConfigFromSidebar`) with "host configuration" (either
* `ConfigFromAnnotator` OR `ConfigFromEmbedder`).
*
* In all cases, the annotator ("host frame") provides `ConfigFromAnnotator`
* to the sidebar frame by encoding values into a URL fragment on the sidebar
* frame's `src` attribute.
*
* In most cases, `SidebarSettings` combine `ConfigFromAnnotator` with
* `ConfigFromSidebar`:
*
* +--------------------------------------------+
* | host frame (annotator) |
* | +-----------------------+ |
* | | sidebar frame | |
* | | | |
* | <ConfigFromAnnotator> => iframe.src | |
* | | | |
* | | | |
* | | | |
* | | <ConfigFromSidebar> | |
* | +-----------------------+ |
* +--------------------------------------------+
*
* In some cases (e.g. LMS), host configuration should instead be provided by an
* ancestor ("embedder") frame. This is signaled by the presence of a valid
* `requestConfigFromFrame` object on `ConfigFromAnnotator`.
*
* `ConfigFromEmbedder` will then be requested from the designated embedder
* frame and combined with `ConfigFromSidebar` to produce `SidebarSettings`:
*
* +------------------------------------------------------------------------+
* | embedder frame |
* | +------------------------------------------+ |
* | | host frame (annotator) | |
* | | +---------------------+ | |
* | | | sidebar frame | | |
* | | | | | |
* | | <ConfigFromAnnotator> => iframe.src | | |
* | | requestConfigFromFrame | | |
* | | | | | |
* | | | | | |
* | | | <====postMessage====> <ConfigFromEmbedder> |
* | | | <ConfigFromSidebar> | | |
* | | +---------------------+ | |
* | +------------------------------------------+ |
* +------------------------------------------------------------------------+
*
* @typedef {Omit<ConfigFromHost, "reportActivity">} ConfigFromAnnotator
* @typedef {Omit<ConfigFromHost, "requestConfigFromFrame">} ConfigFromEmbedder
* @typedef {ConfigFromHost & ConfigFromSidebar & { rpc?: RPCSettings }} SidebarSettings
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment