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