Skip to content

Commit

Permalink
Allow host page to signal to client when content is ready to anchor
Browse files Browse the repository at this point in the history
Allow the host page to pass a `contentReady` promise to the client, which it
will resolve once the content is rendered and the client should be able to
anchor annotations. This enables the host page to load the client concurrently
with fetching document content, only blocking the client at the point where it
needs to anchor annotations.

Fixes #5568
  • Loading branch information
robertknight committed Jul 18, 2023
1 parent 57fa3b2 commit 44486d5
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/annotator/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ function configurationKeys(context: Context): string[] {
annotator: [
'clientUrl',
'contentInfoBanner',
'contentReady',
'subFrameIdentifier',
'sideBySide',
],
Expand Down Expand Up @@ -120,6 +121,11 @@ const configDefinitions: ConfigDefinitionMap = {
defaultValue: null,
getValue: getHostPageSetting,
},
contentReady: {
allowInBrowserExt: true,
defaultValue: null,
getValue: getHostPageSetting,
},
enableExperimentalNewNoteButton: {
allowInBrowserExt: false,
defaultValue: null,
Expand Down
4 changes: 4 additions & 0 deletions src/annotator/config/test/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ describe('annotator/config/index', () => {
bucketContainerSelector: null,
clientUrl: 'fakeValue',
contentInfoBanner: null,
contentReady: 'fakeValue',
enableExperimentalNewNoteButton: null,
externalContainerSelector: null,
focus: null,
Expand Down Expand Up @@ -116,6 +117,7 @@ describe('annotator/config/index', () => {
bucketContainerSelector: 'fakeValue',
clientUrl: 'fakeValue',
contentInfoBanner: 'fakeValue',
contentReady: 'fakeValue',
enableExperimentalNewNoteButton: 'fakeValue',
externalContainerSelector: 'fakeValue',
focus: 'fakeValue',
Expand Down Expand Up @@ -175,6 +177,7 @@ describe('annotator/config/index', () => {
bucketContainerSelector: null,
clientUrl: null,
contentInfoBanner: null,
contentReady: null,
enableExperimentalNewNoteButton: null,
externalContainerSelector: null,
focus: null,
Expand Down Expand Up @@ -233,6 +236,7 @@ describe('annotator/config/index', () => {
expectedKeys: [
'clientUrl',
'contentInfoBanner',
'contentReady',
'subFrameIdentifier',
'sideBySide',
],
Expand Down
18 changes: 18 additions & 0 deletions src/annotator/guest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ export type GuestConfig = {
/** Configures a banner or other indicators showing where the content has come from. */
contentInfoBanner?: ContentInfoConfig;

/**
* Promise that the guest should wait for before it attempts to anchor
* annotations.
*/
contentReady?: Promise<void>;

sideBySide?: SideBySideOptions;
};

Expand Down Expand Up @@ -191,6 +197,12 @@ export class Guest extends TinyEmitter implements Annotator, Destroyable {
/** Promise that resolves when feature flags are received from the sidebar. */
private _featureFlagsReceived: Promise<void>;

/**
* Promise that the guest will wait for before attempting to anchor
* annotations.
*/
private _contentReady?: Promise<void>;

private _adder: Adder;
private _clusterToolbar?: HighlightClusterController;
private _hostFrame: Window;
Expand Down Expand Up @@ -252,6 +264,7 @@ export class Guest extends TinyEmitter implements Annotator, Destroyable {
super();

this.element = element;
this._contentReady = config.contentReady;
this._hostFrame = hostFrame;
this._highlightsVisible = false;
this._isAdderVisible = false;
Expand Down Expand Up @@ -603,6 +616,11 @@ export class Guest extends TinyEmitter implements Annotator, Destroyable {
* re-anchoring the annotation.
*/
async anchor(annotation: AnnotationData): Promise<Anchor[]> {
if (this._contentReady) {
await this._contentReady;
this._contentReady = undefined;
}

/**
* Resolve an annotation's selectors to a concrete range.
*/
Expand Down
21 changes: 21 additions & 0 deletions src/annotator/test/guest-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1336,6 +1336,27 @@ describe('Guest', () => {

assert.lengthOf(guest.anchors, 0);
});

it('waits for content to be ready before anchoring', async () => {
const events = [];
fakeIntegration.anchor = async () => {
events.push('fakeIntegration.anchor');
return range;
};
const contentReady = delay(1).then(() => {
events.push('contentReady');
});

const guest = createGuest({ contentReady });

const annotation = {
$tag: 'tag1',
target: [{ selector: [{ type: 'TextQuoteSelector', exact: 'hello' }] }],
};
await guest.anchor(annotation);

assert.deepEqual(events, ['contentReady', 'fakeIntegration.anchor']);
});
});

describe('#detach', () => {
Expand Down

0 comments on commit 44486d5

Please sign in to comment.