Commit 3cb14c36 authored by Robert Knight's avatar Robert Knight

Add `injectClient` method to HypothesisInjector

Expose the existing logic for injecting the client into a target frame
in HypothesisInjector as a public `injectClient` method and modify it to
wait for the document to be loaded if necessary. This method will be
used by the guest class to inject the client into specific frames when
requested by the current integration.

In the case where the frame is discovered by `FrameObserver` this means
that `onDocumentReady(frame)` will be called twice. That's OK because
the second call will just complete immediately if the frame is already
ready.
parent 05b6a932
import { FrameObserver } from './frame-observer';
import { onDocumentReady, FrameObserver } from './frame-observer';
/**
* @typedef {import('../types/annotator').Destroyable} Destroyable
......@@ -22,7 +22,7 @@ export class HypothesisInjector {
this._config = config;
this._frameObserver = new FrameObserver(
element,
frame => this._addHypothesis(frame),
frame => this.injectClient(frame),
() => {}
);
}
......@@ -35,19 +35,23 @@ export class HypothesisInjector {
}
/**
* Inject Hypothesis client into a newly-discovered iframe.
* Inject Hypothesis client into a frame.
*
* IMPORTANT: This method requires that the iframe is "accessible"
* (frame.contentDocument|contentWindow is not null) and "ready" (DOM content
* has been loaded and parsed) before the method is called.
* (frame.contentDocument|contentWindow is not null).
*
* This waits for the frame to finish loading before injecting the client.
* See {@link onDocumentReady}.
*
* @param {HTMLIFrameElement} frame
*/
_addHypothesis(frame) {
async injectClient(frame) {
if (hasHypothesis(frame)) {
return;
}
await onDocumentReady(frame);
// Generate a random string to use as a frame ID. The format is not important.
const subFrameIdentifier = Math.random().toString().replace(/\D/g, '');
const injectedConfig = {
......
import { delay } from '../../../test-util/wait';
import { DEBOUNCE_WAIT, onDocumentReady } from '../../frame-observer';
import { HypothesisInjector } from '../../hypothesis-injector';
......@@ -10,8 +11,15 @@ describe('HypothesisInjector integration test', () => {
clientUrl: 'data:,Hypothesis', // empty data uri
};
function waitForFrameObserver() {
return new Promise(resolve => setTimeout(resolve, DEBOUNCE_WAIT + 10));
// Wait for `FrameObserver` to discover added or removed iframes.
async function waitForFrameObserver() {
await delay(DEBOUNCE_WAIT + 10);
}
// Wait for `HypothesisInjector.injectClient` to finish injecting the client
// into the page.
async function waitForInjectClient() {
await delay(0);
}
function getHypothesisScript(iframe) {
......@@ -55,13 +63,13 @@ describe('HypothesisInjector integration test', () => {
// Now initialize
createHypothesisInjector();
await onDocumentReady(validFrame);
await waitForInjectClient();
assert.isNotNull(
getHypothesisScript(validFrame),
'expected valid iframe to include the Hypothesis script'
);
await onDocumentReady(invalidFrame);
assert.isNull(
getHypothesisScript(invalidFrame),
'expected invalid iframe to not include the Hypothesis script'
......@@ -72,7 +80,7 @@ describe('HypothesisInjector integration test', () => {
const iframe = createAnnotatableIFrame();
createHypothesisInjector();
await onDocumentReady(iframe);
await waitForInjectClient();
const scriptElement = getHypothesisScript(iframe);
assert.isNotNull(
......@@ -107,7 +115,7 @@ describe('HypothesisInjector integration test', () => {
const iframe = createAnnotatableIFrame();
await waitForFrameObserver();
await onDocumentReady(iframe);
await waitForInjectClient();
assert.isNotNull(
getHypothesisScript(iframe),
'expected dynamically added iframe to include the Hypothesis script'
......@@ -119,7 +127,7 @@ describe('HypothesisInjector integration test', () => {
// Now initialize
createHypothesisInjector();
await onDocumentReady(iframe);
await waitForInjectClient();
assert.isNotNull(
getHypothesisScript(iframe),
......@@ -133,7 +141,7 @@ describe('HypothesisInjector integration test', () => {
assert.isNull(getHypothesisScript(iframe));
await waitForFrameObserver();
await onDocumentReady(iframe);
await waitForInjectClient();
assert.isNotNull(
getHypothesisScript(iframe),
......@@ -149,7 +157,7 @@ describe('HypothesisInjector integration test', () => {
const iframe = createAnnotatableIFrame();
await waitForFrameObserver();
await onDocumentReady(iframe);
await waitForInjectClient();
assert.isNotNull(
getHypothesisScript(iframe),
......@@ -163,7 +171,7 @@ describe('HypothesisInjector integration test', () => {
assert.isNull(getHypothesisScript(iframe));
await waitForFrameObserver();
await onDocumentReady(iframe);
await waitForInjectClient();
assert.isNotNull(
getHypothesisScript(iframe),
......
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