This repository has been archived by the owner on Dec 11, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 974
Stop losing pinned tabs in a window when adding or removing another pinned tab #10531
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,9 +15,7 @@ const {getPinnedTabsByWindowId} = require('../common/state/tabState') | |
const messages = require('../../js/constants/messages') | ||
const settings = require('../../js/constants/settings') | ||
const windowState = require('../common/state/windowState') | ||
const Immutable = require('immutable') | ||
const pinnedSitesState = require('../common/state/pinnedSitesState') | ||
const pinnedSitesUtil = require('../common/lib/pinnedSitesUtil') | ||
const windowActions = require('../../js/actions/windowActions') | ||
|
||
// TODO(bridiver) - set window uuid | ||
|
@@ -64,51 +62,44 @@ const updateWindow = (windowId, updateDefault = false) => { | |
} | ||
} | ||
|
||
const siteMatchesTab = (site, tab) => { | ||
const matchesLocation = getLocationIfPDF(tab.get('url')) === site.get('location') | ||
const matchesPartition = tab.get('partitionNumber', 0) === site.get('partitionNumber', 0) | ||
return matchesLocation && matchesPartition | ||
} | ||
|
||
const updatePinnedTabs = (win) => { | ||
if (win.webContents.browserWindowOptions.disposition === 'new-popup') { | ||
return | ||
} | ||
|
||
const appStore = require('../../js/stores/appStore') | ||
const state = appStore.getState() | ||
const windowId = win.id | ||
const pinnedSites = pinnedSitesState.getSites(state).map(site => pinnedSitesUtil.getPinnedSiteProps(site)) | ||
const pinnedTabs = getPinnedTabsByWindowId(state, windowId) | ||
|
||
pinnedSites.filter((site) => | ||
pinnedTabs.find((tab) => | ||
getLocationIfPDF(tab.get('url')) === site.get('location') && | ||
(tab.get('partitionNumber') || 0) === (site.get('partitionNumber') || 0))).forEach((site) => { | ||
win.__alreadyPinnedSites = win.__alreadyPinnedSites.add(site) | ||
const pinnedSites = pinnedSitesState.getSites(state) | ||
let pinnedWindowTabs = getPinnedTabsByWindowId(state, windowId) | ||
// sites are instructions of what should be pinned | ||
// tabs are sites our window already has pinned | ||
// for each site which should be pinned, find if it's already pinned | ||
for (const site of pinnedSites.values()) { | ||
const existingPinnedTabIdx = pinnedWindowTabs.findIndex(tab => siteMatchesTab(site, tab)) | ||
if (existingPinnedTabIdx !== -1) { | ||
// if it's already pinned we don't need to consider the tab in further searches | ||
pinnedWindowTabs = pinnedWindowTabs.remove(existingPinnedTabIdx) | ||
} else { | ||
// if it's not already pinned, create new pinned tab | ||
appActions.createTabRequested({ | ||
url: site.get('location'), | ||
partitionNumber: site.get('partitionNumber'), | ||
pinned: true, | ||
active: false, | ||
windowId | ||
}) | ||
|
||
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 commentThe reason will be displayed to describe this comment to others. Learn more. so this here was the actual bug; comparing site entries from There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
|
||
sitesToAdd.forEach((site) => { | ||
win.__alreadyPinnedSites = win.__alreadyPinnedSites.add(site) | ||
appActions.createTabRequested({ | ||
url: site.get('location'), | ||
partitionNumber: site.get('partitionNumber'), | ||
pinned: true, | ||
active: false, | ||
windowId | ||
}) | ||
}) | ||
|
||
const sitesToClose = win.__alreadyPinnedSites.filter((pinned) => | ||
!pinnedSites.find((site) => pinned.equals(site))) | ||
|
||
sitesToClose | ||
.forEach((site) => { | ||
const tab = pinnedTabs.find((tab) => | ||
tab.get('url') === site.get('location') && | ||
(tab.get('partitionNumber') || 0) === (site.get('partitionNumber') || 0)) | ||
if (tab) { | ||
appActions.tabCloseRequested(tab.get('tabId'), true) | ||
} | ||
win.__alreadyPinnedSites = win.__alreadyPinnedSites.remove(site) | ||
}) | ||
} | ||
} | ||
// all that's left for tabs are the ones that we should close | ||
for (const tab of pinnedWindowTabs) { | ||
appActions.tabCloseRequested(tab.get('tabId'), true) | ||
} | ||
} | ||
|
||
const api = { | ||
|
@@ -310,7 +301,6 @@ const api = { | |
setImmediate(() => { | ||
const win = currentWindows[windowId] | ||
if (win && !win.isDestroyed()) { | ||
win.__alreadyPinnedSites = new Immutable.Set() | ||
updatePinnedTabs(win) | ||
win.__ready = true | ||
} | ||
|
@@ -341,6 +331,19 @@ const api = { | |
} | ||
|
||
return windowState.WINDOW_ID_NONE | ||
}, | ||
|
||
privateMethods: () => { | ||
return process.env.NODE_ENV === 'test' | ||
? { | ||
cleanupWindow, | ||
getWindowState, | ||
getWindowValue, | ||
updateWindow, | ||
siteMatchesTab, | ||
updatePinnedTabs | ||
} | ||
: {} | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
/* global describe, it, before, beforeEach, after, afterEach */ | ||
const mockery = require('mockery') | ||
const sinon = require('sinon') | ||
const Immutable = require('immutable') | ||
const assert = require('assert') | ||
const fakeElectron = require('../../lib/fakeElectron') | ||
const fakeAdBlock = require('../../lib/fakeAdBlock') | ||
|
||
require('../../braveUnit') | ||
|
||
describe('window API unit tests', function () { | ||
let windows, appActions | ||
let appStore | ||
let defaultState, createTabState, tabCloseState | ||
|
||
before(function () { | ||
mockery.enable({ | ||
warnOnReplace: false, | ||
warnOnUnregistered: false, | ||
useCleanCache: true | ||
}) | ||
|
||
const tab1 = { | ||
id: 1, | ||
url: 'https://pinned-tab.com', | ||
partitionNumber: 0, | ||
windowId: 1, | ||
pinned: true | ||
} | ||
const pinned1 = { | ||
'https://pinned-tab.com|0|0': { | ||
location: 'https://pinned-tab.com', | ||
partitionNumber: 0, | ||
title: 'Brave Software - Example Pinned Tab', | ||
order: 1 | ||
} | ||
} | ||
const pinned2 = { | ||
'https://another-pinned-tab.com|0|0': { | ||
location: 'https://another-pinned-tab.com', | ||
partitionNumber: pinned1.partitionNumber, | ||
title: pinned1.title, | ||
order: pinned1.order | ||
} | ||
} | ||
|
||
defaultState = Immutable.fromJS({ | ||
pinnedSites: pinned1, | ||
tabs: [tab1] | ||
}) | ||
|
||
createTabState = Immutable.fromJS({ | ||
pinnedSites: pinned2, | ||
tabs: [tab1] | ||
}) | ||
|
||
tabCloseState = Immutable.fromJS({ | ||
pinnedSites: {}, | ||
tabs: [tab1] | ||
}) | ||
|
||
appStore = { | ||
getState: () => Immutable.fromJS(defaultState) | ||
} | ||
|
||
mockery.registerMock('electron', fakeElectron) | ||
mockery.registerMock('ad-block', fakeAdBlock) | ||
mockery.registerMock('../../js/stores/appStore', appStore) | ||
|
||
windows = require('../../../../app/browser/windows') | ||
appActions = require('../../../../js/actions/appActions') | ||
}) | ||
|
||
after(function () { | ||
mockery.disable() | ||
}) | ||
|
||
describe('privateMethods', function () { | ||
let updatePinnedTabs | ||
let createTabRequestedSpy, tabCloseRequestedSpy | ||
const win = { | ||
id: 1, | ||
webContents: { | ||
browserWindowOptions: { | ||
disposition: '' | ||
} | ||
} | ||
} | ||
|
||
before(function () { | ||
const methods = windows.privateMethods() | ||
updatePinnedTabs = methods.updatePinnedTabs | ||
}) | ||
beforeEach(function () { | ||
createTabRequestedSpy = sinon.spy(appActions, 'createTabRequested') | ||
tabCloseRequestedSpy = sinon.spy(appActions, 'tabCloseRequested') | ||
}) | ||
afterEach(function () { | ||
createTabRequestedSpy.restore() | ||
tabCloseRequestedSpy.restore() | ||
appStore.getState = () => Immutable.fromJS(defaultState) | ||
}) | ||
|
||
describe('updatePinnedTabs', function () { | ||
it('takes no action if pinnedSites list matches tab state', function () { | ||
updatePinnedTabs(win) | ||
assert.equal(createTabRequestedSpy.calledOnce, false) | ||
assert.equal(tabCloseRequestedSpy.calledOnce, false) | ||
}) | ||
|
||
it('calls `appActions.createTabRequested` for pinnedSites not in tab state', function () { | ||
appStore.getState = () => Immutable.fromJS(createTabState) | ||
updatePinnedTabs(win) | ||
assert.equal(createTabRequestedSpy.calledOnce, true) | ||
}) | ||
|
||
it('calls `appActions.tabCloseRequested` for items in tab state but not in pinnedSites', function () { | ||
appStore.getState = () => Immutable.fromJS(tabCloseState) | ||
updatePinnedTabs(win) | ||
assert.equal(tabCloseRequestedSpy.calledOnce, true) | ||
}) | ||
}) | ||
}) | ||
}) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.