Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
e46c106c
Commit
e46c106c
authored
Mar 28, 2022
by
Lyza Danger Gardner
Committed by
Lyza Gardner
Mar 29, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Expand typing and comments for sidebar-config types
parent
dae7bed2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
98 additions
and
23 deletions
+98
-23
build-settings.js
src/sidebar/config/build-settings.js
+12
-10
host-config.js
src/sidebar/config/host-config.js
+2
-2
config.js
src/types/config.js
+84
-11
No files found.
src/sidebar/config/build-settings.js
View file @
e46c106c
...
@@ -4,6 +4,8 @@ import * as postMessageJsonRpc from '../util/postmessage-json-rpc';
...
@@ -4,6 +4,8 @@ import * as postMessageJsonRpc from '../util/postmessage-json-rpc';
/**
/**
* @typedef {import('../../types/config').ConfigFromHost} ConfigFromHost
* @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').ConfigFromSidebar} ConfigFromSidebar
* @typedef {import('../../types/config').RPCSettings} RPCSettings
* @typedef {import('../../types/config').RPCSettings} RPCSettings
* @typedef {import('../../types/config').SidebarSettings} SidebarSettings
* @typedef {import('../../types/config').SidebarSettings} SidebarSettings
...
@@ -71,9 +73,9 @@ function fetchServiceGroups(configFromHost, rpcSettings) {
...
@@ -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 `
Annotator
ConfigFromHost`, if any are present.
*
*
* @param {ConfigFrom
Host
} configFromHost
* @param {ConfigFrom
Annotator
} configFromHost
* @param {Window} window_
* @param {Window} window_
* @return {import('../../types/config').RPCSettings|null}
* @return {import('../../types/config').RPCSettings|null}
*/
*/
...
@@ -99,11 +101,11 @@ function buildRPCSettings(configFromHost, window_) {
...
@@ -99,11 +101,11 @@ function buildRPCSettings(configFromHost, window_) {
* Retrieve ConfigFromHost to use for settings from the ancestor frame indicated
* Retrieve ConfigFromHost to use for settings from the ancestor frame indicated
* in `rpcSettings`
* in `rpcSettings`
*
*
* @param {ConfigFrom
Host
} hostConfigFromURL
* @param {ConfigFrom
Annotator
} hostConfigFromURL
* @param {RPCSettings} rpcSettings
* @param {RPCSettings} rpcSettings
* @return {Promise<ConfigFrom
Host
>}
* @return {Promise<ConfigFrom
Embedder
>}
*/
*/
async
function
get
HostConfigByRPC
(
hostConfigFromURL
,
rpcSettings
)
{
async
function
get
EmbedderConfig
(
hostConfigFromURL
,
rpcSettings
)
{
const
hostConfigFromFrame
=
await
postMessageJsonRpc
.
call
(
const
hostConfigFromFrame
=
await
postMessageJsonRpc
.
call
(
rpcSettings
.
targetFrame
,
rpcSettings
.
targetFrame
,
rpcSettings
.
origin
,
rpcSettings
.
origin
,
...
@@ -140,21 +142,21 @@ async function getHostConfigByRPC(hostConfigFromURL, rpcSettings) {
...
@@ -140,21 +142,21 @@ async function getHostConfigByRPC(hostConfigFromURL, rpcSettings) {
* @return {Promise<SidebarSettings>} - The merged settings
* @return {Promise<SidebarSettings>} - The merged settings
*/
*/
export
async
function
buildSettings
(
configFromSidebar
,
window_
=
window
)
{
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
;
let
configFromHost
;
if
(
rpcSettings
)
{
if
(
rpcSettings
)
{
// The presence of RPCSettings indicates that we should
// The presence of RPCSettings indicates that we should
// source the ConfigFromHost from another frame, and potentially load
// source the ConfigFromHost from another frame, and potentially load
// the correct groups asynchronously as well.
// the correct groups asynchronously as well.
const
hostConfigFromFrame
=
await
get
HostConfigByRPC
(
const
hostConfigFromFrame
=
await
get
EmbedderConfig
(
hostConfigFromURL
,
annotatorConfigFromHost
,
rpcSettings
rpcSettings
);
);
configFromHost
=
fetchServiceGroups
(
hostConfigFromFrame
,
rpcSettings
);
configFromHost
=
fetchServiceGroups
(
hostConfigFromFrame
,
rpcSettings
);
}
else
{
}
else
{
configFromHost
=
hostConfigFromURL
;
configFromHost
=
annotatorConfigFromHost
;
}
}
/** @type {SidebarSettings} */
/** @type {SidebarSettings} */
...
...
src/sidebar/config/host-config.js
View file @
e46c106c
...
@@ -6,14 +6,14 @@ import {
...
@@ -6,14 +6,14 @@ import {
toString
,
toString
,
}
from
'../../shared/type-coercions'
;
}
from
'../../shared/type-coercions'
;
/** @typedef {import('../../types/config').ConfigFrom
Host} ConfigFromHost
*/
/** @typedef {import('../../types/config').ConfigFrom
Annotator} ConfigFromAnnotator
*/
/**
/**
* Return the app configuration specified by the frame embedding the Hypothesis
* Return the app configuration specified by the frame embedding the Hypothesis
* client.
* client.
*
*
* @param {Window} window
* @param {Window} window
* @return {ConfigFrom
Host
}
* @return {ConfigFrom
Annotator
}
*/
*/
export
function
hostPageConfig
(
window
)
{
export
function
hostPageConfig
(
window
)
{
const
config
=
parseConfigFragment
(
window
.
location
.
href
);
const
config
=
parseConfigFragment
(
window
.
location
.
href
);
...
...
src/types/config.js
View file @
e46c106c
...
@@ -3,9 +3,9 @@
...
@@ -3,9 +3,9 @@
*
*
* See https://h.readthedocs.io/projects/client/en/latest/publishers/config/#cmdoption-arg-services
* See https://h.readthedocs.io/projects/client/en/latest/publishers/config/#cmdoption-arg-services
*
*
* The `onXXX` functions may be set by the embedder of the client. The
*
The `onXXX` functions may be set by the embedder of the client. The
* `onXXXProvided` booleans are correspondingly set in the annotator if a
* `onXXXProvided` booleans are correspondingly set in the annotator if a
* particular function is provided.
*
particular function is provided.
*
*
* @typedef Service
* @typedef Service
* @prop {string} apiUrl
* @prop {string} apiUrl
...
@@ -54,13 +54,33 @@
...
@@ -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 {number} ancestorLevel
* @prop {string} origin
* @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
* This is the subset of keys from
* https://h.readthedocs.io/projects/client/en/latest/publishers/config/ which
* https://h.readthedocs.io/projects/client/en/latest/publishers/config/ which
...
@@ -77,8 +97,12 @@
...
@@ -77,8 +97,12 @@
* Theme properties (fonts, colors etc.)
* Theme properties (fonts, colors etc.)
* @prop {boolean} [enableExperimentalNewNoteButton] -
* @prop {boolean} [enableExperimentalNewNoteButton] -
* Whether to show the "New note" button on the "Page Notes" tab
* Whether to show the "New note" button on the "Page Notes" tab
* @prop {RequestConfigFromFrameOptions} [requestConfigFromFrame]
* @prop {EmbedderFrameConfig} [requestConfigFromFrame] - Allows annotator to
* Origin of the ancestor frame to request configuration from
* 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] -
* @prop {Service[]} [services] -
* Configuration for the annotation services that the client connects to
* Configuration for the annotation services that the client connects to
* @prop {string} [theme]
* @prop {string} [theme]
...
@@ -88,18 +112,67 @@
...
@@ -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
* @typedef RPCSettings
* @prop {Window} targetFrame
* @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
* `SidebarSettings` are created by merging "sidebar configuration"
* (filtered and validated) configuration from the host page with configuration
* (`ConfigFromSidebar`) with "host configuration" (either
* from h / the browser extension.
* `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
* @typedef {ConfigFromHost & ConfigFromSidebar & { rpc?: RPCSettings }} SidebarSettings
*/
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment