Commit 2c835031 authored by Robert Knight's avatar Robert Knight

Use same frame ID for each VitalSource content frame

Use the same "vitalsource-content" frame ID for each VitalSource guest
frame. When a chapter navigation occurs, this will enable the sidebar to
associate the new guest, for the new chapter, with the `Frame` object in
the store for the previous guest.

This also gives the frame a more helpful human-readable ID for debugging
purposes.
parent eaa11014
...@@ -68,8 +68,10 @@ function hasHypothesis(iframe) { ...@@ -68,8 +68,10 @@ function hasHypothesis(iframe) {
* *
* @param {HTMLIFrameElement} frame * @param {HTMLIFrameElement} frame
* @param {InjectConfig} config - * @param {InjectConfig} config -
* @param {string} [frameId] - The ID for the guest frame. If none is provided,
* the guest will use a new randomly-generated ID.
*/ */
export async function injectClient(frame, config) { export async function injectClient(frame, config, frameId) {
if (hasHypothesis(frame)) { if (hasHypothesis(frame)) {
return; return;
} }
...@@ -94,8 +96,7 @@ export async function injectClient(frame, config) { ...@@ -94,8 +96,7 @@ export async function injectClient(frame, config) {
notebookAppUrl, notebookAppUrl,
sidebarAppUrl, sidebarAppUrl,
// Generate a random string to use as a frame ID. The format is not important. subFrameIdentifier: frameId ?? generateHexString(10),
subFrameIdentifier: generateHexString(10),
}; };
const configElement = document.createElement('script'); const configElement = document.createElement('script');
......
...@@ -137,7 +137,12 @@ describe('annotator/integrations/vitalsource', () => { ...@@ -137,7 +137,12 @@ describe('annotator/integrations/vitalsource', () => {
it('injects client into content frame', async () => { it('injects client into content frame', async () => {
await waitFor(() => fakeInjectClient.called); await waitFor(() => fakeInjectClient.called);
assert.calledWith(fakeInjectClient, fakeViewer.contentFrame, fakeConfig); assert.calledWith(
fakeInjectClient,
fakeViewer.contentFrame,
fakeConfig,
'vitalsource-content'
);
}); });
[ [
......
...@@ -220,7 +220,7 @@ export class VitalSourceInjector { ...@@ -220,7 +220,7 @@ export class VitalSourceInjector {
!body.querySelector('#page-content'); !body.querySelector('#page-content');
if (isBookContent) { if (isBookContent) {
injectClient(frame, config); injectClient(frame, config, 'vitalsource-content');
} }
}); });
}; };
......
...@@ -68,6 +68,13 @@ describe('HypothesisInjector integration test', () => { ...@@ -68,6 +68,13 @@ describe('HypothesisInjector integration test', () => {
container.remove(); container.remove();
}); });
function extractClientConfig(frame) {
const configElement = frame.contentDocument.querySelector(
'.js-hypothesis-config'
);
return JSON.parse(configElement.textContent);
}
describe('injectClient', () => { describe('injectClient', () => {
it('configures client', async () => { it('configures client', async () => {
const frame = document.createElement('iframe'); const frame = document.createElement('iframe');
...@@ -75,10 +82,7 @@ describe('HypothesisInjector integration test', () => { ...@@ -75,10 +82,7 @@ describe('HypothesisInjector integration test', () => {
await injectClient(frame, { clientUrl: 'https://hyp.is' }); await injectClient(frame, { clientUrl: 'https://hyp.is' });
const configElement = frame.contentDocument.querySelector( const config = extractClientConfig(frame);
'.js-hypothesis-config'
);
const config = JSON.parse(configElement.textContent);
assert.match(config.subFrameIdentifier, /[a-f0-9]+/); assert.match(config.subFrameIdentifier, /[a-f0-9]+/);
assert.notOk(config.assetRoot); assert.notOk(config.assetRoot);
...@@ -86,6 +90,20 @@ describe('HypothesisInjector integration test', () => { ...@@ -86,6 +90,20 @@ describe('HypothesisInjector integration test', () => {
assert.notOk(config.sidebarAppUrl); assert.notOk(config.sidebarAppUrl);
}); });
it('configures client with specified frame ID', async () => {
const frame = document.createElement('iframe');
container.append(frame);
await injectClient(
frame,
{ clientUrl: 'https://hyp.is' },
'some-frame-id'
);
const config = extractClientConfig(frame);
assert.equal(config.subFrameIdentifier, 'some-frame-id');
});
it('copies client asset locations from host frame', async () => { it('copies client asset locations from host frame', async () => {
hostJSONConfig = { hostJSONConfig = {
clientUrl: 'chrome-extension://abc/client/build/boot.js', clientUrl: 'chrome-extension://abc/client/build/boot.js',
......
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