Skip to content

Commit

Permalink
Merge Host and Sidebar classes
Browse files Browse the repository at this point in the history
The `Host` class is never constructed directly and only has one
subclass, `Sidebar`. There wasn't a clear separation of responsibilities between
`Host` and `Sidebar`. This commit therefore moves the functionality of `Host` into
`Sidebar` and merges the tests.
  • Loading branch information
robertknight committed Oct 21, 2020
1 parent d2f8816 commit 11542d1
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 244 deletions.
110 changes: 0 additions & 110 deletions src/annotator/host.js

This file was deleted.

121 changes: 119 additions & 2 deletions src/annotator/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import sidebarTrigger from './sidebar-trigger';
import events from '../shared/bridge-events';
import features from './features';

import Host from './host';
import Guest from './guest';
import { ToolbarController } from './toolbar';

/**
Expand All @@ -24,14 +24,130 @@ const defaultConfig = {
},
};

export default class Sidebar extends Host {
/**
* Create the JSON-serializable subset of annotator configuration that should
* be passed to the sidebar application.
*/
function createSidebarConfig(config) {
const sidebarConfig = { ...config };

// Some config settings are not JSON-stringifiable (e.g. JavaScript
// functions) and will be omitted when the config is JSON-stringified.
// Add a JSON-stringifiable option for each of these so that the sidebar can
// at least know whether the callback functions were provided or not.
if (sidebarConfig.services?.length > 0) {
const service = sidebarConfig.services[0];
if (service.onLoginRequest) {
service.onLoginRequestProvided = true;
}
if (service.onLogoutRequest) {
service.onLogoutRequestProvided = true;
}
if (service.onSignupRequest) {
service.onSignupRequestProvided = true;
}
if (service.onProfileRequest) {
service.onProfileRequestProvided = true;
}
if (service.onHelpRequest) {
service.onHelpRequestProvided = true;
}
}

// Remove several annotator-only properties.
//
// nb. We don't currently strip all the annotator-only properties here.
// That's OK because validation / filtering happens in the sidebar app itself.
// It just results in unnecessary content in the sidebar iframe's URL string.
['sidebarAppUrl', 'pluginClasses'].forEach(key => delete sidebarConfig[key]);

return sidebarConfig;
}

/**
* Create the iframe that will load the sidebar application.
*
* @return {HTMLIFrameElement}
*/
function createSidebarIframe(config) {
const sidebarConfig = createSidebarConfig(config);
const configParam =
'config=' + encodeURIComponent(JSON.stringify(sidebarConfig));
const sidebarAppSrc = config.sidebarAppUrl + '#' + configParam;

const sidebarFrame = document.createElement('iframe');
sidebarFrame.setAttribute('name', 'hyp_sidebar_frame');

// Enable media in annotations to be shown fullscreen
sidebarFrame.setAttribute('allowfullscreen', '');

sidebarFrame.setAttribute('seamless', '');
sidebarFrame.src = sidebarAppSrc;
sidebarFrame.title = 'Hypothesis annotation viewer';
sidebarFrame.className = 'h-sidebar-iframe';

return sidebarFrame;
}

/**
* The `Sidebar` class creates the sidebar application iframe and its container,
* as well as the adjacent controls.
*/
export default class Sidebar extends Guest {
constructor(element, config) {
if (config.theme === 'clean' || config.externalContainerSelector) {
delete config.pluginClasses.BucketBar;
}

let externalContainer = null;

if (config.externalContainerSelector) {
externalContainer = document.querySelector(
config.externalContainerSelector
);
}

let externalFrame;
let frame;

if (externalContainer) {
externalFrame = externalContainer;
} else {
frame = document.createElement('div');
frame.style.display = 'none';
frame.className = 'annotator-frame annotator-outer';

if (config.theme === 'clean') {
frame.classList.add('annotator-frame--drop-shadow-enabled');
}

element.appendChild(frame);
}

const sidebarFrame = createSidebarIframe(config);

super(element, { ...defaultConfig, ...config });

this.externalFrame = externalFrame;
this.frame = frame;
(frame || externalFrame).appendChild(sidebarFrame);

this.subscribe('panelReady', () => {
// Show the UI
if (this.frame) {
this.frame.style.display = '';
}
});

this.subscribe('beforeAnnotationCreated', annotation => {
// When a new non-highlight annotation is created, focus
// the sidebar so that the text editor can be focused as
// soon as the annotation card appears
if (!annotation.$highlight) {
/** @type {Window} */ (sidebarFrame.contentWindow).focus();
}
});

if (
config.openSidebar ||
config.annotations ||
Expand Down Expand Up @@ -95,6 +211,7 @@ export default class Sidebar extends Host {

destroy() {
this._hammerManager?.destroy();
this.frame?.remove();
super.destroy();
}

Expand Down
127 changes: 0 additions & 127 deletions src/annotator/test/host-test.js

This file was deleted.

Loading

0 comments on commit 11542d1

Please sign in to comment.