-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make highlight visibility state work in a multi-guest world #3830
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3830 +/- ##
==========================================
+ Coverage 98.96% 98.98% +0.02%
==========================================
Files 211 211
Lines 7903 7906 +3
Branches 1867 1868 +1
==========================================
+ Hits 7821 7826 +5
+ Misses 82 80 -2
Continue to review full report at Codecov.
|
// Ensure that the highlight for the newly-created annotation is visible. | ||
// Currently we only support a single, shared visibility state for all highlights | ||
// in all frames, so this will make all existing highlights visible too. | ||
this._hostRPC.call('showHighlights'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To recap the sequence of events here when creating a new highlight while the "Show highlights" control is disabled:
- The guest will create a new annotation and send it to the sidebar via a
beforeCreateAnnotation
request - The sidebar sends a
showHighlights
request to the host frame - The host frame updates the "Show highlights" control and then sends a
setHighlightsVisible
request back to the sidebar app - The sidebar app will relay the
setHighlightsVisible
request to all connected guests, so that the highlight visibility is the same in all of them - The guests handle the
setHighlightsVisible
request and show or hide highlights in their respective frames
This might seem rather roundabout, but steps 3-5 are the same as when toggling the "Show highlights" control manually, so we avoid having multiple code paths to handle keeping the state in sync across all frames.
In future if we have a direct guest <-> host channel for each guest, we might be able to eliminate the relaying of the setHighlightsVisible
message through the sidebar app. CC @esanzgar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have been thinking about guest-host
channel too, while working on #3838 and realising about the relaying of certain messages host -> sidebar -> guest.
I would support the creation of guest-host
channel.
@@ -239,6 +244,9 @@ export default class Sidebar { | |||
sidebarTrigger(document.body, () => this.open()); | |||
features.init(this._sidebarRPC); | |||
|
|||
this._sidebarRPC.on('showHighlights', () => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
showHighlights
is a new event type that is sent from the sidebar
to the host
frame.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. These lines reported errors as expected after a rebase and I've updated the types.
setHighlightsVisible(visible) { | ||
this.toolbar.highlightsVisible = visible; | ||
|
||
// Notify sidebar app of change which will in turn reflect state to guest frames. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Notify sidebar app of change which will in turn reflect state to guest frames. | |
// Notify sidebar frame of change which will in turn reflect state to guest frames. |
src/annotator/test/sidebar-test.js
Outdated
|
||
const call = fakeBridge.call | ||
.getCalls() | ||
.find(args => args[0] === 'setHighlightsVisible' && args[1] === true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fakeBridge.call
is not invoked at all, with either true
or false
argument:
.find(args => args[0] === 'setHighlightsVisible' && args[1] === true); | |
.find(args => args[0] === 'setHighlightsVisible'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fakeBridge.call is not invoked at all, with either true or false argument:
It is called with the sidebarOpened
message. I discovered there is a neverCalledWith
assertion which can simplify this check though.
@@ -67,6 +67,9 @@ export class FrameSyncService { | |||
// Set of tags of annotations that are currently loaded into the frame | |||
const inFrame = new Set(); | |||
|
|||
/** Whether highlights are visible in guest frames. */ | |||
this._highlightsVisible = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A single state for all the guest frames.
describe('#setShowHighlights', () => { | ||
it('sets a flag indicating that highlights are visible', () => { | ||
store.setShowHighlights(true); | ||
assert.isTrue(store.getState().viewer.visibleHighlights); | ||
}); | ||
|
||
it('sets a flag indicating that highlights are not visible', () => { | ||
store.setShowHighlights(false); | ||
assert.isFalse(store.getState().viewer.visibleHighlights); | ||
}); | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a little confuse by the previous uses of the store
. Was this old code or has the reliance of the store
been disable in the PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was old code that was no longer used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tested the PR and it works as explained.
94fb864
to
47e35ef
Compare
There was an action to set this state but it was never read anywhere.
Make the client's highlight visibility state work in a sane way in scenarios where there are multiple guests, or the main guest frame is not the host frame. Previously there were several problems in these scenarios: - It was unclear which component of the application "owned" the highlight visibility state. The state in the sidebar could be changed as a result of the `highlightsVisibleChanged` event emitted by a Guest, as well as the user toggling highlight controls in the sidebar. - In the sidebar's `open` and `close` methods it directly set the highlight visibility in the main guest if the `showHighlights` setting was set to `whenSidebarOpen`. This meant that it didn't work for guests that were not in the main frame. - Guest frames could be configured with different `showHighlights` settings. In this case it was unclear what should happen. This commit resolves this by making the `Sidebar` class in the host frame the central owner of this state. It handles configuring the initial state based on the `showHighlights` configuration setting, and reflecting this state to the sidebar application which in turn reflects it to guest frames. The initial visibility of highlights in a guest frame is synchronized with this state when the guest frame connects to the sidebar. This state is updated by the `Sidebar` class when: - The user toggles the highlight visibility control in the sidebar - A new highlight or annotation is created in a guest frame - The sidebar opens and closes, if the `showHighlights` configuration was set to `whenSidebarOpen` Additionally the inconsistency of `setHighlightsVisible` vs `setVisibleHighlights` in identifier and event names has been resolved by using `setHighlightsVisible`/`highlightsVisible` everywhere. Part of #3798
Change the logic for making highlights visible when creating a new annotation, so that it works if the annotation was created in a non-host frame. This is done by moving the logic from the `beforeAnnotationCreated` handler in the Sidebar class, which was only called for annotations in the host frame, to the `beforeCreateAnnotation` handler in FrameSyncService, which is called for all frames. The sidebar app will then send a request to show highlights to the host frame, which will update the sidebar's controls and then relay the request to guest frames.
e63c074
to
7f2c0b8
Compare
Make the client's highlight visibility state work in a sane way in
scenarios where there are multiple guests, or the main guest frame is not the
host frame. Previously there were several problems in these scenarios:
It was unclear which component of the application "owned" the
highlight visibility state. The state in the sidebar could be changed
as a result of the
highlightsVisibleChanged
event emitted by aGuest, as well as the user toggling highlight controls in the
sidebar. This confusion created scenarios where the state could get out of sync with the sidebar in some guests.
In the sidebar's
open
andclose
methods it directly set thehighlight visibility in the main guest if the
showHighlights
setting was set to
whenSidebarOpen
. This meant that it didn't workfor guests that were not in the main frame.
Guest frames could be configured with different
showHighlights
settings. In this case it was unclear what should happen.
This commit resolves this by making the
Sidebar
class in the hostframe the central owner of this state. It handles configuring the
initial state based on the
showHighlights
configuration setting, andreflecting this state to the sidebar application which in turn reflects
it to guest frames. The initial visibility of highlights in a guest
frame is synchronized with this state when the guest frame connects to
the sidebar. This state is updated by the
Sidebar
class when:showHighlights
configurationwas set to
whenSidebarOpen
Additionally the inconsistency of
setHighlightsVisible
vssetVisibleHighlights
in identifier and event names has been resolved byusing
setHighlightsVisible
/highlightsVisible
everywhere.Part of #3798
Testing:
dev-server/documents/html/parent-frame.mustache
and verify that visibility of highlights correctly changes when opening and closing the sidebar:A related scenario that doesn't work yet is that making a highlight or annotation in the child frame when highlights are hidden does not show highlights.(Edit: This is now resolved. See second commit.)