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

Remove adder by clicking once on a different frame

Before this PR, when there was two frames, A and B, if the adder was in
frame A, it was necessary to __double click__ on frame B to remove the
adder and the selection from frame A.

After this PR, __a single click__  on frame B removes the adder and text
selection from frame A. This behaviour is similar to what happens on a
single frame scenario, where a single click removes the adder and the
selection.
parent cd64340e
......@@ -15,7 +15,7 @@ import {
} from './highlighter';
import { createIntegration } from './integrations';
import * as rangeUtil from './range-util';
import { SelectionObserver } from './selection-observer';
import { SelectionObserver, selectedRange } from './selection-observer';
import { findClosestOffscreenAnchor } from './util/buckets';
import { normalizeURI } from './util/url';
......@@ -303,8 +303,10 @@ export class Guest {
async _connectHost() {
this._hostRPC.on('clearSelection', () => {
this._informHostOnNextSelectionClear = false;
removeTextSelection();
if (selectedRange(document)) {
this._informHostOnNextSelectionClear = false;
removeTextSelection();
}
});
this._hostRPC.on('createAnnotation', () => this.createAnnotation());
......
......@@ -6,7 +6,7 @@ import { ListenerCollection } from '../shared/listener-collection';
* @param {Document} document
* @return {Range|null}
*/
function selectedRange(document) {
export function selectedRange(document) {
const selection = document.getSelection();
if (!selection || selection.rangeCount === 0) {
return null;
......
......@@ -43,6 +43,7 @@ describe('Guest', () => {
let fakePortFinder;
let FakePortRPC;
let fakePortRPCs;
let fakeSelectedRange;
const createGuest = (config = {}) => {
const element = document.createElement('div');
......@@ -151,6 +152,8 @@ describe('Guest', () => {
}
}
fakeSelectedRange = sinon.stub();
$imports.$mock({
'../shared/messaging': {
PortFinder: sinon.stub().returns(fakePortFinder),
......@@ -170,6 +173,7 @@ describe('Guest', () => {
'./range-util': rangeUtil,
'./selection-observer': {
SelectionObserver: FakeSelectionObserver,
selectedRange: fakeSelectedRange,
},
'./util/buckets': {
findClosestOffscreenAnchor: fakeFindClosestOffscreenAnchor,
......@@ -672,26 +676,51 @@ describe('Guest', () => {
assert.calledWith(hostRPC().call, 'textUnselected');
});
it('unselects text if another iframe has made a selection', () => {
const removeAllRanges = sandbox.stub();
sandbox.stub(document, 'getSelection').returns({ removeAllRanges });
const guest = createGuest();
guest.selectedRanges = [1];
context('on "clearSelection" RPC event', () => {
it('if guest has selected text, clears the selection', () => {
const removeAllRanges = sandbox.stub();
sandbox.stub(document, 'getSelection').returns({ removeAllRanges });
const guest = createGuest();
guest.selectedRanges = [1];
simulateSelectionWithText();
hostRPC().call.resetHistory();
emitHostEvent('clearSelection');
// Guest has text selected
simulateSelectionWithText();
fakeSelectedRange.returns({});
assert.calledOnce(removeAllRanges);
notifySelectionChanged(null); // removing the text selection triggers the selection observer
hostRPC().call.resetHistory();
emitHostEvent('clearSelection');
assert.equal(guest.selectedRanges.length, 0);
assert.notCalled(hostRPC().call);
assert.calledOnce(removeAllRanges);
notifySelectionChanged(null); // removing the text selection triggers the selection observer
// On next selection clear it should be inform the host.
notifySelectionChanged(null);
assert.calledOnce(hostRPC().call);
assert.calledWithExactly(hostRPC().call, 'textUnselected');
assert.equal(guest.selectedRanges.length, 0);
assert.notCalled(hostRPC().call);
// On next selection clear it should be inform the host.
notifySelectionChanged(null);
assert.calledOnce(hostRPC().call);
assert.calledWithExactly(hostRPC().call, 'textUnselected');
});
it('if guest has no text selected, does nothing', () => {
const removeAllRanges = sandbox.stub();
sandbox.stub(document, 'getSelection').returns({ removeAllRanges });
const guest = createGuest();
guest.selectedRanges = [1];
// Guest has no text selected
fakeSelectedRange.returns(null);
hostRPC().call.resetHistory();
emitHostEvent('clearSelection');
assert.notCalled(removeAllRanges);
// On next selection clear it should be inform the host.
notifySelectionChanged(null);
assert.calledOnce(hostRPC().call);
assert.calledWithExactly(hostRPC().call, 'textUnselected');
});
});
});
......
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