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

Update the position of the adder on window.resize

This PR makes the adder to reposition when the adder is visible and the
window is resized. In this way the adder is always close to the selected
text.

Closes #3194
parent 7b8ac776
...@@ -117,6 +117,7 @@ export default class Guest { ...@@ -117,6 +117,7 @@ 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._isAdderVisible = false;
this.adder = new Adder(this.element, { this.adder = new Adder(this.element, {
onAnnotate: async () => { onAnnotate: async () => {
...@@ -221,6 +222,8 @@ export default class Guest { ...@@ -221,6 +222,8 @@ export default class Guest {
this.focusAnnotations([]); this.focusAnnotations([]);
} }
}); });
this._listeners.add(window, 'resize', () => this._repositionAdder());
} }
/** /**
...@@ -246,6 +249,19 @@ export default class Guest { ...@@ -246,6 +249,19 @@ export default class Guest {
); );
} }
/**
* Shift the position of the adder on window 'resize' events
*/
_repositionAdder() {
if (this._isAdderVisible === false) {
return;
}
const range = window.getSelection()?.getRangeAt(0);
if (range) {
this._onSelection(range);
}
}
_setupInitialState(config) { _setupInitialState(config) {
this._emitter.publish('panelReady'); this._emitter.publish('panelReady');
this.setVisibleHighlights(config.showHighlights === 'always'); this.setVisibleHighlights(config.showHighlights === 'always');
...@@ -600,10 +616,12 @@ export default class Guest { ...@@ -600,10 +616,12 @@ export default class Guest {
this._emitter.publish('hasSelectionChanged', true); this._emitter.publish('hasSelectionChanged', true);
this.adder.annotationsForSelection = annotationsForSelection(); this.adder.annotationsForSelection = annotationsForSelection();
this._isAdderVisible = true;
this.adder.show(focusRect, isBackwards); this.adder.show(focusRect, isBackwards);
} }
_onClearSelection() { _onClearSelection() {
this._isAdderVisible = false;
this.adder.hide(); this.adder.hide();
this.selectedRanges = []; this.selectedRanges = [];
this._emitter.publish('hasSelectionChanged', false); this._emitter.publish('hasSelectionChanged', false);
......
...@@ -45,14 +45,18 @@ describe('Guest', () => { ...@@ -45,14 +45,18 @@ describe('Guest', () => {
let PDFIntegration; let PDFIntegration;
let fakePDFIntegration; let fakePDFIntegration;
let guests;
const createGuest = (config = {}) => { const createGuest = (config = {}) => {
const element = document.createElement('div'); const element = document.createElement('div');
const eventBus = new EventBus(); const eventBus = new EventBus();
return new Guest(element, eventBus, { ...guestConfig, ...config }); const guest = new Guest(element, eventBus, { ...guestConfig, ...config });
guests.push(guest);
return guest;
}; };
beforeEach(() => { beforeEach(() => {
guests = [];
FakeAdder.instance = null; FakeAdder.instance = null;
guestConfig = {}; guestConfig = {};
highlighter = { highlighter = {
...@@ -125,6 +129,7 @@ describe('Guest', () => { ...@@ -125,6 +129,7 @@ describe('Guest', () => {
}); });
afterEach(() => { afterEach(() => {
guests.forEach(guest => guest.destroy());
sandbox.restore(); sandbox.restore();
$imports.$restore(); $imports.$restore();
}); });
...@@ -307,7 +312,7 @@ describe('Guest', () => { ...@@ -307,7 +312,7 @@ describe('Guest', () => {
it('allows the default scroll behaviour to be prevented', () => { it('allows the default scroll behaviour to be prevented', () => {
const highlight = document.createElement('span'); const highlight = document.createElement('span');
const guest = createGuest(); const guest = createGuest();
const fakeRange = sinon.stub(); const fakeRange = sandbox.stub();
guest.anchors = [ guest.anchors = [
{ {
annotation: { $tag: 'tag1' }, annotation: { $tag: 'tag1' },
...@@ -332,11 +337,11 @@ describe('Guest', () => { ...@@ -332,11 +337,11 @@ describe('Guest', () => {
annotation: { $tag: 'tag1' }, annotation: { $tag: 'tag1' },
highlights: [highlight], highlights: [highlight],
range: { range: {
toRange: sinon.stub().throws(new Error('Something went wrong')), toRange: sandbox.stub().throws(new Error('Something went wrong')),
}, },
}, },
]; ];
const eventEmitted = sinon.stub(); const eventEmitted = sandbox.stub();
guest.element.addEventListener('scrolltorange', eventEmitted); guest.element.addEventListener('scrolltorange', eventEmitted);
emitGuestEvent('scrollToAnnotation', 'tag1'); emitGuestEvent('scrollToAnnotation', 'tag1');
...@@ -478,6 +483,25 @@ describe('Guest', () => { ...@@ -478,6 +483,25 @@ describe('Guest', () => {
guest.crossframe.call.resetHistory(); guest.crossframe.call.resetHistory();
} }
}); });
it('does not reposition the adder on window "resize" event if the adder is hidden', () => {
sandbox.stub(guest, '_repositionAdder').callThrough();
sandbox.stub(guest, '_onSelection'); // Calling _onSelect makes the adder to reposition
window.dispatchEvent(new Event('resize'));
assert.called(guest._repositionAdder);
assert.notCalled(guest._onSelection);
});
it('reposition the adder on window "resize" event if the adder is shown', () => {
sandbox.stub(guest, '_repositionAdder').callThrough();
sandbox.stub(guest, '_onSelection'); // Calling _onSelect makes the adder to reposition
guest._isAdderVisible = true;
sandbox.stub(window, 'getSelection').returns({ getRangeAt: () => true });
window.dispatchEvent(new Event('resize'));
assert.called(guest._onSelection);
});
}); });
describe('when the selection changes', () => { describe('when the selection changes', () => {
...@@ -544,7 +568,7 @@ describe('Guest', () => { ...@@ -544,7 +568,7 @@ describe('Guest', () => {
it('emits `hasSelectionChanged` event with argument `true` if selection is non-empty', () => { it('emits `hasSelectionChanged` event with argument `true` if selection is non-empty', () => {
const guest = createGuest(); const guest = createGuest();
const callback = sinon.stub(); const callback = sandbox.stub();
guest._emitter.subscribe('hasSelectionChanged', callback); guest._emitter.subscribe('hasSelectionChanged', callback);
simulateSelectionWithText(); simulateSelectionWithText();
...@@ -554,7 +578,7 @@ describe('Guest', () => { ...@@ -554,7 +578,7 @@ describe('Guest', () => {
it('emits `hasSelectionChanged` event with argument `false` if selection is empty', () => { it('emits `hasSelectionChanged` event with argument `false` if selection is empty', () => {
const guest = createGuest(); const guest = createGuest();
const callback = sinon.stub(); const callback = sandbox.stub();
guest._emitter.subscribe('hasSelectionChanged', callback); guest._emitter.subscribe('hasSelectionChanged', callback);
simulateSelectionWithoutText(); simulateSelectionWithoutText();
...@@ -568,7 +592,7 @@ describe('Guest', () => { ...@@ -568,7 +592,7 @@ describe('Guest', () => {
// `createAnnotation` tests. // `createAnnotation` tests.
it('creates a new annotation if "Annotate" is clicked', async () => { it('creates a new annotation if "Annotate" is clicked', async () => {
const guest = createGuest(); const guest = createGuest();
const callback = sinon.stub(); const callback = sandbox.stub();
guest._emitter.subscribe('beforeAnnotationCreated', callback); guest._emitter.subscribe('beforeAnnotationCreated', callback);
await FakeAdder.instance.options.onAnnotate(); await FakeAdder.instance.options.onAnnotate();
...@@ -578,7 +602,7 @@ describe('Guest', () => { ...@@ -578,7 +602,7 @@ describe('Guest', () => {
it('creates a new highlight if "Highlight" is clicked', async () => { it('creates a new highlight if "Highlight" is clicked', async () => {
const guest = createGuest(); const guest = createGuest();
const callback = sinon.stub(); const callback = sandbox.stub();
guest._emitter.subscribe('beforeAnnotationCreated', callback); guest._emitter.subscribe('beforeAnnotationCreated', callback);
await FakeAdder.instance.options.onHighlight(); await FakeAdder.instance.options.onHighlight();
...@@ -686,7 +710,7 @@ describe('Guest', () => { ...@@ -686,7 +710,7 @@ describe('Guest', () => {
it('triggers a "beforeAnnotationCreated" event', async () => { it('triggers a "beforeAnnotationCreated" event', async () => {
const guest = createGuest(); const guest = createGuest();
const callback = sinon.stub(); const callback = sandbox.stub();
guest._emitter.subscribe('beforeAnnotationCreated', callback); guest._emitter.subscribe('beforeAnnotationCreated', callback);
const annotation = await guest.createAnnotation(); const annotation = await guest.createAnnotation();
...@@ -830,7 +854,6 @@ describe('Guest', () => { ...@@ -830,7 +854,6 @@ describe('Guest', () => {
it('syncs annotations to the sidebar', () => { it('syncs annotations to the sidebar', () => {
const guest = createGuest(); const guest = createGuest();
guest.crossframe = { sync: sinon.stub() };
const annotation = {}; const annotation = {};
return guest.anchor(annotation).then(() => { return guest.anchor(annotation).then(() => {
assert.called(guest.crossframe.sync); assert.called(guest.crossframe.sync);
...@@ -840,7 +863,7 @@ describe('Guest', () => { ...@@ -840,7 +863,7 @@ describe('Guest', () => {
it('emits an `anchorsChanged` event', async () => { it('emits an `anchorsChanged` event', async () => {
const guest = createGuest(); const guest = createGuest();
const annotation = {}; const annotation = {};
const anchorsChanged = sinon.stub(); const anchorsChanged = sandbox.stub();
guest._emitter.subscribe('anchorsChanged', anchorsChanged); guest._emitter.subscribe('anchorsChanged', anchorsChanged);
await guest.anchor(annotation); await guest.anchor(annotation);
...@@ -924,7 +947,7 @@ describe('Guest', () => { ...@@ -924,7 +947,7 @@ describe('Guest', () => {
const guest = createGuest(); const guest = createGuest();
const annotation = {}; const annotation = {};
guest.anchors.push({ annotation }); guest.anchors.push({ annotation });
const anchorsChanged = sinon.stub(); const anchorsChanged = sandbox.stub();
guest._emitter.subscribe('anchorsChanged', anchorsChanged); guest._emitter.subscribe('anchorsChanged', anchorsChanged);
guest.detach(annotation); guest.detach(annotation);
......
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