Commit 336db8c8 authored by Robert Knight's avatar Robert Knight

Add a mechansim to allow the browser extension to pass config info to the app

Provide a way for the browser extension to pass config info to the app,
by running a content script which injects a <meta> tag into the page
with this form:

  <meta name="hypothesis-config" content="<JSON data>">

This configuration info is then merged with the result of the
hypothesisConfig() function, with the hypothesisConfig() function taking
priority.
parent 25b2516d
'use strict';
var annotationIDs = require('../util/annotation-ids');
var settings = require('../settings');
var docs = 'https://h.readthedocs.org/en/latest/hacking/customized-embedding.html';
......@@ -15,15 +16,12 @@ function config(window_) {
document.querySelector('link[type="application/annotator+html"]').href,
};
// Parse config from `<meta name="hypothesis-config" content="<JSON>">` tags
var configElement = window_.document
.querySelector('meta[name="hypothesis-config"]');
if (configElement) {
try {
Object.assign(options, JSON.parse(configElement.content));
} catch (err) {
console.warn('Could not parse Hypothesis config from', configElement);
}
// Parse config from `<script class="js-hypothesis-config">` tags
try {
Object.assign(options, settings(window_.document, 'js-hypothesis-config'));
} catch (err) {
console.warn('Could not parse settings from js-hypothesis-config tags',
err);
}
// Parse config from `window.hypothesisConfig` function
......
......@@ -3,26 +3,32 @@
var config = require('../config');
describe('annotator configuration', function () {
var fakeMetaConfig;
var fakeScriptConfig;
function fakeQuerySelector(selector) {
if (selector === 'link[type="application/annotator+html"]') {
return {href: 'app.html'};
} else if (selector === 'script.js-hypothesis-config' &&
fakeScriptConfig) {
return {textContent: fakeScriptConfig};
} else {
return null;
}
}
var fakeWindowBase = {
document: {
querySelector: sinon.spy(function (selector) {
if (selector === 'link[type="application/annotator+html"]') {
return {href: 'app.html'};
} else if (selector === 'meta[name="hypothesis-config"]' &&
fakeMetaConfig) {
return {content:fakeMetaConfig};
} else {
return null;
}
}),
querySelector: fakeQuerySelector,
querySelectorAll: function (selector) {
var match = fakeQuerySelector(selector);
return match ? [match] : [];
},
},
location: {hash: ''},
};
beforeEach(function () {
fakeMetaConfig = '';
fakeScriptConfig = '';
});
it('reads the app src from the link tag', function () {
......@@ -59,7 +65,7 @@ describe('annotator configuration', function () {
});
it('merges the config from the "hypothesis-config" meta tag', function () {
fakeMetaConfig = '{"annotations":"456"}';
fakeScriptConfig = '{"annotations":"456"}';
assert.deepEqual(config(fakeWindowBase), {
app: 'app.html',
annotations: '456',
......
......@@ -6,16 +6,20 @@ require('core-js/fn/object/assign');
* Return application configuration information from the host page.
*
* Exposes shared application settings, read from script tags with the
* class 'js-hypothesis-settings' which contain JSON content.
* class `settingsClass` which contain JSON content.
*
* If there are multiple such tags, the configuration from each is merged.
*
* @param {Document|Element} document - The root element to search for
* <script> settings tags.
* @param {string} settingsClass - The class name to match on <script> tags.
*/
function settings(document) {
function settings(document, settingsClass) {
if (!settingsClass) {
settingsClass = 'js-hypothesis-settings';
}
var settingsElements =
document.querySelectorAll('script.js-hypothesis-settings');
document.querySelectorAll('script.' + settingsClass);
var config = {};
for (var i=0; i < settingsElements.length; i++) {
......
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