Commit e8617749 authored by Kyle Keating's avatar Kyle Keating Committed by Kyle Keating

Change configFrom() to configDefinitions()

The main difference is that configFrom returned config key:value pairs, but now configDefinitions returns key:object pairs. Where the object may hold additional flags and methods for each specific config value. Currently the only method included is valueFn() which gets the value from its source. Others will follow.
parent 5ee67ff9
...@@ -3,6 +3,14 @@ import { toBoolean } from '../../shared/type-coercions'; ...@@ -3,6 +3,14 @@ import { toBoolean } from '../../shared/type-coercions';
/** /**
* @typedef {'sidebar'|'notebook'|'annotator'|'all'} AppContext * @typedef {'sidebar'|'notebook'|'annotator'|'all'} AppContext
*
* @typedef ConfigDefinition
* @prop {() => any} valueFn -
* Method to retrieve the value from the incoming source
*/
/**
* @typedef {Record<string, ConfigDefinition>} ConfigDefinitionMap
*/ */
/** /**
...@@ -60,60 +68,90 @@ function configurationKeys(appContext) { ...@@ -60,60 +68,90 @@ function configurationKeys(appContext) {
} }
/** /**
* Reads the Hypothesis configuration from the environment. * The definition for configuration sources, their default values
* * @return {ConfigDefinitionMap}
* @param {string[]} settingsKeys - List of settings that should be returned.
* @param {Window} window_ - The Window object to read config from.
*/ */
function configFrom(settingsKeys, window_) { function configDefinitions(settings) {
const settings = settingsFrom(window_); return {
const allConfigSettings = { annotations: {
annotations: settings.annotations, valueFn: () => settings.annotations,
appType: settings.hostPageSetting('appType', { },
allowInBrowserExt: true, appType: {
}), valueFn: () =>
branding: settings.hostPageSetting('branding'), settings.hostPageSetting('appType', {
allowInBrowserExt: true,
}),
},
branding: {
valueFn: () => settings.hostPageSetting('branding'),
},
// URL of the client's boot script. Used when injecting the client into // URL of the client's boot script. Used when injecting the client into
// child iframes. // child iframes.
clientUrl: settings.clientUrl, clientUrl: {
enableExperimentalNewNoteButton: settings.hostPageSetting( valueFn: () => settings.clientUrl,
'enableExperimentalNewNoteButton' },
), enableExperimentalNewNoteButton: {
experimental: settings.hostPageSetting('experimental', { valueFn: () =>
defaultValue: {}, settings.hostPageSetting('enableExperimentalNewNoteButton'),
}), },
group: settings.group, experimental: {
focus: settings.hostPageSetting('focus'), valueFn: () =>
theme: settings.hostPageSetting('theme'), settings.hostPageSetting('experimental', {
usernameUrl: settings.hostPageSetting('usernameUrl'), defaultValue: {},
onLayoutChange: settings.hostPageSetting('onLayoutChange'), }),
openSidebar: settings.hostPageSetting('openSidebar', { },
allowInBrowserExt: true, group: {
// Coerce value to a boolean because it may come from via as a string valueFn: () => settings.group,
coerce: toBoolean, },
}), focus: {
query: settings.query, valueFn: () => settings.hostPageSetting('focus'),
requestConfigFromFrame: settings.hostPageSetting('requestConfigFromFrame'), },
services: settings.hostPageSetting('services'), theme: {
showHighlights: settings.showHighlights, valueFn: () => settings.hostPageSetting('theme'),
notebookAppUrl: settings.notebookAppUrl, },
sidebarAppUrl: settings.sidebarAppUrl, usernameUrl: {
// Subframe identifier given when a frame is being embedded into valueFn: () => settings.hostPageSetting('usernameUrl'),
},
onLayoutChange: {
valueFn: () => settings.hostPageSetting('onLayoutChange'),
},
openSidebar: {
valueFn: () =>
settings.hostPageSetting('openSidebar', {
allowInBrowserExt: true,
coerce: toBoolean,
}),
},
query: {
valueFn: () => settings.query,
},
requestConfigFromFrame: {
valueFn: () => settings.hostPageSetting('requestConfigFromFrame'),
},
services: {
valueFn: () => settings.hostPageSetting('services'),
},
showHighlights: {
valueFn: () => settings.showHighlights,
},
notebookAppUrl: {
valueFn: () => settings.notebookAppUrl,
},
sidebarAppUrl: {
valueFn: () => settings.sidebarAppUrl,
},
// Sub-frame identifier given when a frame is being embedded into
// by a top level client // by a top level client
subFrameIdentifier: settings.hostPageSetting('subFrameIdentifier', { subFrameIdentifier: {
allowInBrowserExt: true, valueFn: () =>
}), settings.hostPageSetting('subFrameIdentifier', {
externalContainerSelector: settings.hostPageSetting( allowInBrowserExt: true,
'externalContainerSelector' }),
), },
externalContainerSelector: {
valueFn: () => settings.hostPageSetting('externalContainerSelector'),
},
}; };
// Only return what we asked for
const resultConfig = {};
settingsKeys.forEach(key => {
resultConfig[key] = allConfigSettings[key];
});
return resultConfig;
} }
/** /**
...@@ -122,9 +160,17 @@ function configFrom(settingsKeys, window_) { ...@@ -122,9 +160,17 @@ function configFrom(settingsKeys, window_) {
* @param {AppContext} [appContext] - The name of the app. * @param {AppContext} [appContext] - The name of the app.
*/ */
export function getConfig(appContext = 'annotator', window_ = window) { export function getConfig(appContext = 'annotator', window_ = window) {
const settings = settingsFrom(window_);
const configDefs = configDefinitions(settings);
const config = {};
// Filter the config based on the application context as some config values // Filter the config based on the application context as some config values
// may be inappropriate or erroneous for some applications. // may be inappropriate or erroneous for some applications.
const filteredKeys = configurationKeys(appContext); let filteredKeys = configurationKeys(appContext);
const config = configFrom(filteredKeys, window_); filteredKeys.forEach(name => {
const configDef = configDefs[name];
// Get the value from the configuration source and run through an optional coerce method
config[name] = configDef.valueFn();
});
return config; return config;
} }
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