Commit df10f49e authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Add customizable side-by-side mode to HTMLIntegration

parent 6aeeed8c
......@@ -5,6 +5,7 @@ import type {
FeatureFlags,
Integration,
SidebarLayout,
SideBySideOptions,
} from '../../types/annotator';
import type { Selector } from '../../types/api';
import { anchor, describe } from '../anchoring/html';
......@@ -36,8 +37,9 @@ export class HTMLIntegration extends TinyEmitter implements Integration {
private _htmlMeta: HTMLMetadata;
private _prevURI: string;
/** Whether to attempt to resize the document to fit alongside sidebar. */
private _sideBySideEnabled: boolean;
/** Controls how we resize the document to fit alongside sidebar. */
private _sideBySideOptions: SideBySideOptions;
private _sideBySideFlagEnabled: boolean;
/**
* Whether the document is currently being resized to fit alongside an
......@@ -53,9 +55,11 @@ export class HTMLIntegration extends TinyEmitter implements Integration {
constructor({
features,
container = document.body,
sideBySideOptions,
}: {
features: FeatureFlags;
container?: HTMLElement;
sideBySideOptions?: SideBySideOptions;
}) {
super();
......@@ -65,7 +69,9 @@ export class HTMLIntegration extends TinyEmitter implements Integration {
this._htmlMeta = new HTMLMetadata();
this._prevURI = this._htmlMeta.uri();
this._sideBySideEnabled = this.features.flagEnabled('html_side_by_side');
this._sideBySideFlagEnabled =
this.features.flagEnabled('html_side_by_side');
this._sideBySideOptions = sideBySideOptions ?? { mode: 'auto' };
this._sideBySideActive = false;
this._lastLayout = null;
......@@ -92,9 +98,9 @@ export class HTMLIntegration extends TinyEmitter implements Integration {
});
this._flagsChanged = () => {
const sideBySide = features.flagEnabled('html_side_by_side');
if (sideBySide !== this._sideBySideEnabled) {
this._sideBySideEnabled = sideBySide;
const sideBySideEnabled = features.flagEnabled('html_side_by_side');
if (sideBySideEnabled !== this._sideBySideFlagEnabled) {
this._sideBySideFlagEnabled = sideBySideEnabled;
// `fitSideBySide` is normally called by Guest when the sidebar layout
// changes. When the feature flag changes, we need to re-run the method.
......@@ -156,7 +162,8 @@ export class HTMLIntegration extends TinyEmitter implements Integration {
const maximumWidthToFit = window.innerWidth - layout.width;
const active =
this._sideBySideEnabled &&
this._sideBySideFlagEnabled &&
this._sideBySideOptions.mode === 'auto' &&
layout.expanded &&
maximumWidthToFit >= MIN_HTML_WIDTH;
......
......@@ -64,8 +64,8 @@ describe('HTMLIntegration', () => {
$imports.$restore();
});
function createIntegration() {
return new HTMLIntegration({ features });
function createIntegration(sideBySideOptions) {
return new HTMLIntegration({ features, sideBySideOptions });
}
it('implements `anchor` and `destroy` using HTML anchoring', async () => {
......@@ -380,6 +380,18 @@ describe('HTMLIntegration', () => {
features.update({ html_side_by_side: false });
assert.isFalse(isSideBySideActive());
});
it('manual side-by-side is not changed by enabled feature flag', () => {
features.update({ html_side_by_side: true });
const integration = createIntegration({ mode: 'manual' });
integration.fitSideBySide({ expanded: true, width: sidebarWidth });
assert.isFalse(isSideBySideActive());
// Even if the feature flag is enabled, side-by-side stays disabled/manual
features.update({ html_side_by_side: true });
assert.isFalse(isSideBySideActive());
});
});
describe('#getMetadata', () => {
......
......@@ -336,3 +336,16 @@ export type DocumentInfo = {
*/
persistent: boolean;
};
/**
* `auto`: The client will decide if side-by-side is enabled. If enabled, it
* will apply some heuristics to determine how the content is affected.
* This is default value.
* `manual`: The host app wants to manually take full control of side-by-side,
* effectively disabling the logic in client.
*/
export type SideBySideMode = 'auto' | 'manual';
export type SideBySideOptions = {
mode: SideBySideMode;
};
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