Commit 2d9b0253 authored by Eduardo Sanz García's avatar Eduardo Sanz García Committed by Eduardo

Move creation of the outer container element to `Adder`

`Notebook` and `Sidebar` components create `<hypothesis-...>` elements
that attach shadow DOMs. This PR makes the `Adder` class responsible of
creating its own outer element.
parent 0606bbcf
......@@ -83,24 +83,23 @@ export class Adder {
*
* The adder is initially hidden.
*
* @param {HTMLElement} container - The DOM element into which the adder will be created
* @param {HTMLElement} element - The DOM element into which the adder will be created
* @param {AdderOptions} options - Options object specifying `onAnnotate` and `onHighlight`
* event handlers.
*/
constructor(container, options) {
this._container = container;
this._shadowRoot = createShadowRoot(container);
constructor(element, options) {
this._outerContainer = document.createElement('hypothesis-adder');
element.appendChild(this._outerContainer);
this._shadowRoot = createShadowRoot(this._outerContainer);
// Set initial style
Object.assign(container.style, {
display: 'block',
Object.assign(this._outerContainer.style, {
// take position out of layout flow initially
position: 'absolute',
top: 0,
});
this._view = /** @type {Window} */ (container.ownerDocument.defaultView);
this._view = /** @type {Window} */ (element.ownerDocument.defaultView);
this._width = () => {
const firstChild = /** @type {Element} */ (this._shadowRoot.firstChild);
......@@ -139,6 +138,11 @@ export class Adder {
this._render();
}
destroy() {
render(null, this._shadowRoot); // First, unload the Preact component
this._outerContainer.remove();
}
/**
* Display the adder in the best position in order to target the
* selected text in `selectionRect`.
......@@ -297,12 +301,12 @@ export class Adder {
// Typically the adder is a child of the `<body>` and the NPA is the root
// `<html>` element. However page styling may make the `<body>` positioned.
// See https://github.com/hypothesis/client/issues/487.
const positionedAncestor = nearestPositionedAncestor(this._container);
const positionedAncestor = nearestPositionedAncestor(this._outerContainer);
const parentRect = positionedAncestor.getBoundingClientRect();
const zIndex = this._findZindex(left, top);
Object.assign(this._container.style, {
Object.assign(this._outerContainer.style, {
left: toPx(left - parentRect.left),
top: toPx(top - parentRect.top),
zIndex,
......
......@@ -116,11 +116,8 @@ export default class Guest {
this.element = element;
this._emitter = eventBus.createEmitter();
this.visibleHighlights = false;
this.adderToolbar = document.createElement('hypothesis-adder');
this.adderToolbar.style.display = 'none';
this.element.appendChild(this.adderToolbar);
this.adderCtrl = new Adder(this.adderToolbar, {
this.adder = new Adder(this.element, {
onAnnotate: async () => {
await this.createAnnotation();
/** @type {Selection} */ (document.getSelection()).removeAllRanges();
......@@ -336,7 +333,7 @@ export default class Guest {
this._removeElementEvents();
this.selectionObserver.disconnect();
this.adderToolbar.remove();
this.adder.destroy();
removeAllHighlights(this.element);
......@@ -626,12 +623,12 @@ export default class Guest {
this.selectedRanges = [range];
this._emitter.publish('hasSelectionChanged', true);
this.adderCtrl.annotationsForSelection = annotationsForSelection();
this.adderCtrl.show(focusRect, isBackwards);
this.adder.annotationsForSelection = annotationsForSelection();
this.adder.show(focusRect, isBackwards);
}
_onClearSelection() {
this.adderCtrl.hide();
this.adder.hide();
this.selectedRanges = [];
this._emitter.publish('hasSelectionChanged', false);
}
......
This diff is collapsed.
......@@ -10,6 +10,7 @@ class FakeAdder {
this.hide = sinon.stub();
this.show = sinon.stub();
this.destroy = sinon.stub();
this.options = options;
}
}
......@@ -958,12 +959,9 @@ describe('Guest', () => {
it('removes the adder toolbar', () => {
const guest = createGuest();
const adder = guest.element.querySelector('hypothesis-adder');
assert.equal(adder.parentElement, guest.element);
guest.destroy();
assert.isNull(adder.parentElement);
assert.calledOnce(FakeAdder.instance.destroy);
});
it('cleans up PDF integration', () => {
......
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