-
Notifications
You must be signed in to change notification settings - Fork 204
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
Only send annotations to matching frame #4131
Conversation
Codecov Report
@@ Coverage Diff @@
## master #4131 +/- ##
=======================================
Coverage 99.08% 99.09%
=======================================
Files 219 219
Lines 8229 8249 +20
Branches 1919 1923 +4
=======================================
+ Hits 8154 8174 +20
Misses 75 75
Continue to review full report at Codecov.
|
I'm seeing an issue when testing this branch with VitalSource using the browser extension. The guest frame appears to be receiving an |
It looks like what is happening here is that chapter content loads in several phases:
If the client gets injected into the new frame after step 2, then it gets unloaded in step 3 and doesn't get re-injected, because the VitalSource integration only monitors for creation of iframes, not navigation of existing iframes. |
e34cffb
to
0247587
Compare
6ded1d1
to
752da85
Compare
let frameIdentifier = /** @type {string|null} */ ( | ||
`temp-${this._nextGuestId}` | ||
); | ||
this._guestRPC.set(frameIdentifier, guestRPC); |
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.
In this PR I have not changed how frame IDs are allocated. If we change this in future so that frame IDs are either allocated entirely within the sidebar or in such a way that we can know them as soon as the guest connects, then we can simplify this code.
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.
In the future, we could easily add a capability to PortFinder#discover
to send a frame identifier.
Alternatively, if gathering the information for the documentInfoChanged
event is slow, the frame identifier could be send using a new event (decoupled from documentInfoChanged
). The frame identifier that are currently sending via documentInfoChanged
is immediately available in the guest 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.
In the future, we could easily add a capability to PortFinder#discover to send a frame identifier.
Yes. That's definitely one possibility.
Regarding the VitalSource comments above, this was addressed by #4145. |
0247587
to
06df56a
Compare
254ee79
to
9765327
Compare
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.
It looks good. I left a couple of comments.
src/sidebar/services/frame-sync.js
Outdated
@@ -36,6 +36,30 @@ export function formatAnnot({ $tag, target, uri }) { | |||
}; | |||
} | |||
|
|||
/** | |||
* Return the frame in `frames` which best matches `ann`. |
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.
* Return the frame in `frames` which best matches `ann`. | |
* Return the frame which best matches the annotation. |
src/sidebar/services/frame-sync.js
Outdated
// Choose the frame whose URL exactly matches this annotation. If there is | ||
// none, we'll use the main 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.
I think these couple of lines should be included in the functions's documentation.
let frameIdentifier = /** @type {string|null} */ ( | ||
`temp-${this._nextGuestId}` | ||
); | ||
this._guestRPC.set(frameIdentifier, guestRPC); |
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.
In the future, we could easily add a capability to PortFinder#discover
to send a frame identifier.
Alternatively, if gathering the information for the documentInfoChanged
event is slow, the frame identifier could be send using a new event (decoupled from documentInfoChanged
). The frame identifier that are currently sending via documentInfoChanged
is immediately available in the guest frame.
When the sidebar is connected to multiple guest frames it will send all incoming annotations to all frames. The result is typically that the annotation will anchor in one frame and orphan in the others. Depending on what order this happens in, the annotation will non-deterministically show up as an Annotation or Orphan in the sidebar. In order to determine which frames an annotation should be sent to in all cases, we'd either need the backend to return information about which search URIs an annotation matches or make a separate search request for each frame and record the associated frame with the results. This will require some significant refactoring of the annotation search service. As an interim step, make `FrameSyncService` send annotations only to a single frame based on matching URL, with a fallback to sending to the main frame if there is no exact match. This will work as expected for most pages, and is at least deterministic when it does fail. When we have a solution for being able to match annotations to frames more generally, we can adapt this code to use it. This is a partial solution to #3992.
9765327
to
989be8c
Compare
Depends on #4129
When the sidebar is connected to multiple guest frames it will send all
incoming annotations to all frames. The result is typically that the
annotation will anchor in one frame and orphan in the others. Depending
on what order this happens in, the annotation will non-deterministically
show up as an Annotation or Orphan in the sidebar.
In order to determine which frames an annotation should be sent to in
all cases, we'd either need the backend to return information about which
search URIs an annotation matches or make a separate search request for
each frame and record the associated frame with the results. This
will require some significant refactoring of the annotation search
service.
As an interim step, make
FrameSyncService
send annotations only to asingle frame based on matching URL, with a fallback to sending to the
main frame if there is no exact match. This will work as expected for
most pages, and is at least deterministic when it does fail. When we
have a solution for being able to match annotations to frames more
generally, we can adapt this code to use it.
This is a partial solution to #3992.
TODO:
Testing:
In one of the dev server test pages that contains an annotation-enabled iframe, try annotating the host frame (if possible) and the iframe, and then reload the page several times.
On master, annotations may sometimes appear in the "Orphans" tab. On this branch, all the annotations should consistently anchor in the expected frame.