-
Notifications
You must be signed in to change notification settings - Fork 975
Stop losing pinned tabs in a window when adding or removing another pinned tab #10531
Conversation
Codecov Report
@@ Coverage Diff @@
## master #10531 +/- ##
==========================================
+ Coverage 54.17% 54.39% +0.22%
==========================================
Files 246 246
Lines 21374 21350 -24
Branches 3316 3317 +1
==========================================
+ Hits 11579 11614 +35
+ Misses 9795 9736 -59
|
@petemill this will solve a lot of problems with pinned tabs, thank you. Can you please add some test coverage for this new code and use cases? |
app/browser/windows.js
Outdated
@@ -62,51 +61,44 @@ const updateWindow = (windowId) => { | |||
} | |||
} | |||
|
|||
const siteMatchesTab = (site, tab) => { | |||
const matchesLocation = getLocationIfPDF(tab.get('url')) === site.get('location') | |||
const matchesPartition = (tab.get('partitionNumber') || 0) === (site.get('partitionNumber') || 0) |
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.
you could use Immutable's notSetValue parameter instead of ||
. https://facebook.github.io/immutable-js/docs/#/Map/get
Note to reviewers: let's see if this PR closes #9763 |
I'm pretty sure #9763 is a duplicate of #10510 and #9635 @bsclifton. #3760 is more generic about all the issues with losing pinned tabs and #10037 is about unpinning something and seeing the behavior, compared to the others which only mention steps to pin. But essentially they are caused by the same issue. |
app/browser/windows.js
Outdated
for (const tab of pinnedTabs.values()) { | ||
const shouldBePinned = tabsWithSites.has(tab) | ||
if (!shouldBePinned) { | ||
appActions.tabCloseRequested(tab.get('tabId'), 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.
In what case will require us to manually close tab?
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.
@darkdh this happens when you have > 1 window open, you then unpin a tab in window 1. This code calls upon window 2+ to close the previously-pinned tab. Whether or not this is what we want to happen I guess is beyond the scope of this bug fix, since that is the previous functionality. I myself have noticed some edge-cases that could end up with losing user webview state in a tab, but I'll log a separate issue for that...
6248c7c
to
f912e34
Compare
@NejcZdovc I added more info about what caused this bug - it's the fact that the previously-pinned sites were being stored as Immutable Maps, which were then equality compared to the incoming updated list. Often, the same site would not match one in the 'cache', because some other property changed (such as the I'm in the process of adding a webdriver test for this case. |
f912e34
to
a9443d5
Compare
Test added and described in description. Ready for next round of review. |
a9443d5
to
f9a6772
Compare
app/common/lib/pinnedSitesUtil.js
Outdated
|
||
let location = siteDetail.get('location') | ||
const getKeyFromLocation = (location, partitionNumber) => { |
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.
Not sure why we need to move this in to the new function. You could just create Immutable.Map() in your test (as far as I can see is that the only place that you use it).
const key = pinnedSitesUtil. getKey(Immutable.fromJS({
location: 'something',
partitionNumber: 1
}))
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.
@NejcZdovc the aim here was to avoid having 2+ separate places where this format of string 'key' for pinned tabs is defined (${location}|${parititionNumber}
). The action onPinnedTabReorder
requires this key, the generation of which which was previously hidden inside another function.
Here, I expose the getKey
function from one place, so that if we want to change that format (perhaps introduce a new property, or change the separator charactor, etc) it is controlled by a single function.
Now that I've explained the why, I'm happy to change it - maybe I can get it from the existing state, or the DOM, or something...
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.
Do we have it defined in two places? 😃 I am not aware of it. For pinnedSites we have only one getKey and format AFAIK
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.
Well there would be if I added a new place here 😀 , but I've taken your advice and instead made copies of the 'SiteDetail' structure the original function requires.
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.
++
f9a6772
to
a8e12ab
Compare
some of the pinned tab tests are failing but i don't know offhand if they are intermittent failures. i'll restart the travis job. https://travis-ci.org/brave/browser-laptop/jobs/269271637 update: looks like the same pinnedTab tests fail locally on master and this branch, so they are probably unrelated failures. |
this seems highly likely to conflict with @bbondy's changes |
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.
test plan worked
}) | ||
|
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 (the new implementation) is definitely a lot easier to read; so basically we're just comparing the sites entries to the pinned tab app state.
- entries in sites AND app state are noop (they already exist, no action needed)
- entries in sites and NOT in app state are created
- entries NOT in sites which are in app state are closed
}) | ||
|
||
const sitesToAdd = pinnedSites.filter((site) => | ||
!win.__alreadyPinnedSites.find((pinned) => pinned.equals(site))) |
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.
so this here was the actual bug; comparing site entries from pinnedSites
to the ones in __alreadyPinnedSites
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, though mainly on the previous L100 when determining which should be closed. The bug could have been remedied by hacking that line, but the __alreadyPinnedSites cache wasn't helping much and was growing in size on each call because of L82, so seemed better to rewrite.
…inned tab Fix brave#3760, fix brave#9635, fix brave#10037, fix brave#10510, and possibly addresses brave#10117 The previous code resulted in tabs being marked as no longer required to be pinned, and closed prematurely. This mostly occured after a pinned-tab reordering - afterwards, when pinning or unpinning a tab, all previously pinned tabs with a new order would be closed. Sometimes this appeared like a 'crash' when the window closed because all the tabs had been (undesirably) closed.
Auditors: @petemill Test Plan: `npm run unittest -- --grep="window API unit tests"`
869ad09
to
4ced9dd
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.
Changes look good! 😄 I added some unit tests if you wanted to check them out
Thanks all for your review and thanks @bsclifton for adding new unit tests for that module! |
Fixes #3760
Fixes #9635
Fixes #10037
Fixes #10510
Possibly addresses: #10117 and #10179
The previous code resulted in tabs being marked as no longer required to be pinned, and closed prematurely. This happened because it maintained a 'cache' of pinned sites (as Immutable Maps), and was using
.equals
to the incoming list of sites. Whilst Immutable Map's.equals()
(and.is()
) compare properties of two Maps, the incoming objects are often not equal to the object seen in the past, even though it represents the same 'site'. For example, if we re-order a site, it will have a different Order property.In these situations, when pinning a tab, all or some previously pinned tabs (ones that had any property change) would be closed. Sometimes this appeared like a 'crash' when the window closed because all the tabs had been (undesirably) closed.
Request review from those involved in Issues: @bsclifton @LaurenWags @luixxiul
Submitter Checklist:
git rebase -i
to squash commits (if needed).Test Plan:
Case 1 (#9635)
Steps to reproduce:
Case 2 (#10037)
Steps to reproduce:
Case 3 (#10510)
Automated Test:
Created new test - pinnedTabs -> Moving pinned tabs -> reorders pins without forgetting about them
Fails on master:
Succeeds with this PR:
Reviewer Checklist:
Tests