Skip to content

Commit

Permalink
Splits sites object in the app state
Browse files Browse the repository at this point in the history
Resolves brave#1646
Resolves brave#1856
Resolves brave#2655
Resolves brave#2771
Resolves brave#3646
Resolves brave#3694
Resolves brave#4224
Resolves brave#4260
Resolves brave#4833
Resolves brave#4868
Resolves brave#4929
Resolves brave#5072
Resolves brave#5699
Resolves brave#5382
Resolves brave#6104
Resolves brave#6108
Resolves brave#6585
Resolves brave#8022
Resolves brave#9301
Resolves brave#9326
Resolves brave#9978
Resolves brave#10026

Auditors:

Test Plan:
  • Loading branch information
NejcZdovc authored and dfperry5 committed Aug 18, 2017
1 parent 9723563 commit 33861b7
Show file tree
Hide file tree
Showing 105 changed files with 5,049 additions and 4,824 deletions.
111 changes: 57 additions & 54 deletions app/browser/api/topSites.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,36 @@
const Immutable = require('immutable')
const appActions = require('../../../js/actions/appActions')
const debounce = require('../../../js/lib/debounce')
const siteUtil = require('../../../js/state/siteUtil')
const historyState = require('../../common/state/historyState')
const bookmarkLocationCache = require('../../common/cache/bookmarkLocationCache')
const newTabData = require('../../../js/data/newTabData')
const {isSourceAboutUrl} = require('../../../js/lib/appUrlUtil')
const aboutNewTabMaxEntries = 100
let appStore

let minCountOfTopSites
let minAccessOfTopSites

const compareSites = (site1, site2) => {
if (!site1 || !site2) return false
return site1.get('location') === site2.get('location') &&
site1.get('partitionNumber') === site2.get('partitionNumber')
}
const staticData = Immutable.fromJS(newTabData.topSites)

const pinnedTopSites = (state) => {
return (state.getIn(['about', 'newtab', 'pinnedTopSites']) || Immutable.List()).setSize(18)
return state.getIn(['about', 'newtab', 'pinnedTopSites'], Immutable.List())
}

const ignoredTopSites = (state) => {
return state.getIn(['about', 'newtab', 'ignoredTopSites']) || Immutable.List()
return state.getIn(['about', 'newtab', 'ignoredTopSites'], Immutable.List())
}

const isPinned = (state, siteProps) => {
return pinnedTopSites(state).filter((site) => compareSites(site, siteProps)).size > 0
const isPinned = (state, siteKey) => {
return pinnedTopSites(state).find(site => site.get('key') === siteKey)
}

const isIgnored = (state, siteProps) => {
return ignoredTopSites(state).filter((site) => compareSites(site, siteProps)).size > 0
const isIgnored = (state, siteKey) => {
return ignoredTopSites(state).includes(siteKey)
}

const sortCountDescending = (left, right) => {
const leftCount = left.get('count') || 0
const rightCount = right.get('count') || 0
const leftCount = left.get('count', 0)
const rightCount = right.get('count', 0)
if (leftCount < rightCount) {
return 1
}
Expand Down Expand Up @@ -74,35 +71,44 @@ const removeDuplicateDomains = (list) => {
})
}

const calculateTopSites = (clearCache) => {
const calculateTopSites = (clearCache, withoutDebounce = false) => {
if (clearCache) {
clearTopSiteCacheData()
}
startCalculatingTopSiteData()
if (withoutDebounce) {
getTopSiteData()
} else {
debouncedGetTopSiteData()
}
}

/**
* TopSites are defined by users for the new tab page. Pinned sites are attached to their positions
* in the grid, and the non pinned indexes are populated with newly accessed sites
*/
const startCalculatingTopSiteData = debounce(() => {
const getTopSiteData = () => {
if (!appStore) {
appStore = require('../../../js/stores/appStore')
}
const state = appStore.getState()
// remove folders; sort by visit count; enforce a max limit
const sites = (state.get('sites') ? state.get('sites').toList() : new Immutable.List())
.filter((site) => !siteUtil.isFolder(site) &&
!siteUtil.isImportedBookmark(site) &&
!isSourceAboutUrl(site.get('location')) &&
let sites = historyState.getSites(state)
.filter((site, key) => !isSourceAboutUrl(site.get('location')) &&
!isPinned(state, key) &&
!isIgnored(state, key) &&
(minCountOfTopSites === undefined || (site.get('count') || 0) >= minCountOfTopSites) &&
(minAccessOfTopSites === undefined || (site.get('lastAccessedTime') || 0) >= minAccessOfTopSites))
(minAccessOfTopSites === undefined || (site.get('lastAccessedTime') || 0) >= minAccessOfTopSites)
)
.sort(sortCountDescending)
.slice(0, aboutNewTabMaxEntries)
.map((site, key) => {
const bookmarkKey = bookmarkLocationCache.getCacheKey(state, site.get('location'))

site = site.set('bookmarked', !bookmarkKey.isEmpty())
site = site.set('key', key)
return site
})
.toList()

for (let i = 0; i < sites.size; i++) {
const count = sites.getIn([i, 'count']) || 0
const access = sites.getIn([i, 'lastAccessedTime']) || 0
const count = sites.getIn([i, 'count'], 0)
const access = sites.getIn([i, 'lastAccessedTime'], 0)
if (minCountOfTopSites === undefined || count < minCountOfTopSites) {
minCountOfTopSites = count
}
Expand All @@ -111,33 +117,30 @@ const startCalculatingTopSiteData = debounce(() => {
}
}

// Filter out pinned and ignored sites
let unpinnedSites = sites.filter((site) => !(isPinned(state, site) || isIgnored(state, site)))
unpinnedSites = removeDuplicateDomains(unpinnedSites)

// Merge the pinned and unpinned lists together
// Pinned items have priority because the position is important
let gridSites = pinnedTopSites(state).map((pinnedSite) => {
// Fetch latest siteDetail objects from appState.sites using location/partition
if (pinnedSite) {
const matches = sites.filter((site) => compareSites(site, pinnedSite))
if (matches.size > 0) return matches.first()
}
// Default to unpinned items
const firstSite = unpinnedSites.first()
unpinnedSites = unpinnedSites.shift()
return firstSite
})

// Include up to [aboutNewTabMaxEntries] entries so that folks
// can ignore sites and have new items fill those empty spaces
if (unpinnedSites.size > 0) {
gridSites = gridSites.concat(unpinnedSites)
// remove duplicate domains
// we only keep uniques host names
sites = removeDuplicateDomains(sites)

if (sites.size < 18) {
const preDefined = staticData
.filter((site) => {
return !isPinned(state, site.get('key')) && !isIgnored(state, site.get('key'))
})
.map(site => {
const bookmarkKey = bookmarkLocationCache.getCacheKey(state, site.get('location'))
return site.set('bookmarked', !bookmarkKey.isEmpty())
})
sites = sites.concat(preDefined)
}

const finalData = gridSites.filter((site) => site != null)
appActions.topSiteDataAvailable(finalData)
}, 5 * 1000)
appActions.topSiteDataAvailable(sites)
}

/**
* TopSites are defined by users for the new tab page. Pinned sites are attached to their positions
* in the grid, and the non pinned indexes are populated with newly accessed sites
*/
const debouncedGetTopSiteData = debounce(() => getTopSiteData(), 5 * 1000)

const clearTopSiteCacheData = () => {
minCountOfTopSites = undefined
Expand Down
49 changes: 26 additions & 23 deletions app/browser/bookmarksExporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,23 @@ const electron = require('electron')
const dialog = electron.dialog
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const getSetting = require('../../js/settings').getSetting

// State
const bookmarksState = require('../common/state/bookmarksState')

// Constants
const settings = require('../../js/constants/settings')
const siteTags = require('../../js/constants/siteTags')
const siteUtil = require('../../js/state/siteUtil')
const isWindows = process.platform === 'win32'

// Utils
const {getSetting} = require('../../js/settings')
const platformUtil = require('../common/lib/platformUtil')
const bookmarkFoldersUtil = require('../common/lib/bookmarkFoldersUtil')
const bookmarkUtil = require('../common/lib/bookmarkUtil')

const indentLength = 2
const indentType = ' '

function showDialog (sites) {
const showDialog = (state) => {
const focusedWindow = BrowserWindow.getFocusedWindow()
const fileName = moment().format('DD_MM_YYYY') + '.html'
const defaultPath = path.join(getSetting(settings.DEFAULT_DOWNLOAD_SAVE_PATH) || app.getPath('downloads'), fileName)
Expand All @@ -34,44 +42,39 @@ function showDialog (sites) {
}]
}, (fileName) => {
if (fileName) {
personal = createBookmarkArray(sites)
other = createBookmarkArray(sites, -1, false)
personal = createBookmarkArray(state)
other = createBookmarkArray(state, -1, false)
fs.writeFileSync(fileName, createBookmarkHTML(personal, other))
}
})
}

function createBookmarkArray (sites, parentFolderId, first = true, depth = 1) {
const filteredBookmarks = parentFolderId
? sites.filter((site) => site.get('parentFolderId') === parentFolderId)
: sites.filter((site) => !site.get('parentFolderId'))
const createBookmarkArray = (state, parentFolderId = 0, first = true, depth = 1) => {
const bookmarks = bookmarksState.getBookmarksWithFolders(state, parentFolderId)
let payload = []
let title
let indentFirst = indentType.repeat(depth * indentLength)
let indentNext = (!first) ? indentFirst : indentType.repeat((depth + 1) * indentLength)

if (first) payload.push(`${indentFirst}<DL><p>`)

filteredBookmarks.forEach((site) => {
if (site.get('tags').includes(siteTags.BOOKMARK) && site.get('location')) {
title = site.get('customTitle') || site.get('title') || site.get('location')
for (let site of bookmarks) {
if (bookmarkUtil.isBookmark(site) && site.get('location')) {
title = site.get('title', site.get('location'))
payload.push(`${indentNext}<DT><A HREF="${site.get('location')}">${title}</A>`)
} else if (siteUtil.isFolder(site)) {
const folderId = site.get('folderId')

title = site.get('customTitle') || site.get('title')
payload.push(`${indentNext}<DT><H3>${title}</H3>`)
payload = payload.concat(createBookmarkArray(sites, folderId, true, (depth + 1)))
} else if (bookmarkFoldersUtil.isFolder(site)) {
payload.push(`${indentNext}<DT><H3>${site.get('title')}</H3>`)
payload = payload.concat(createBookmarkArray(state, site.get('folderId'), true, (depth + 1)))
}
})
}

if (first) payload.push(`${indentFirst}</DL><p>`)

return payload
}

function createBookmarkHTML (personal, other) {
const breakTag = (isWindows) ? '\r\n' : '\n'
const createBookmarkHTML = (personal, other) => {
const breakTag = (platformUtil.isWindows()) ? '\r\n' : '\n'
const title = 'Bookmarks'

return `<!DOCTYPE NETSCAPE-Bookmark-file-1>
Expand Down
43 changes: 9 additions & 34 deletions app/browser/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const appConstants = require('../../js/constants/appConstants')
const windowConstants = require('../../js/constants/windowConstants')
const messages = require('../../js/constants/messages')
const settings = require('../../js/constants/settings')
const siteTags = require('../../js/constants/siteTags')

// State
const {getByTabId} = require('../common/state/tabState')
Expand All @@ -35,8 +34,8 @@ const frameStateUtil = require('../../js/state/frameStateUtil')
const menuUtil = require('../common/lib/menuUtil')
const {getSetting} = require('../../js/settings')
const locale = require('../locale')
const {isLocationBookmarked} = require('../../js/state/siteUtil')
const platformUtil = require('../common/lib/platformUtil')
const bookmarkUtil = require('../common/lib/bookmarkUtil')
const isDarwin = platformUtil.isDarwin()
const isLinux = platformUtil.isLinux()
const isWindows = platformUtil.isWindows()
Expand Down Expand Up @@ -376,7 +375,7 @@ const updateRecentlyClosedMenuItems = (state) => {
}

const isCurrentLocationBookmarked = (state) => {
return isLocationBookmarked(state, currentLocation)
return bookmarkUtil.isLocationBookmarked(state, currentLocation)
}

const createBookmarksSubmenu = (state) => {
Expand Down Expand Up @@ -406,7 +405,7 @@ const createBookmarksSubmenu = (state) => {
CommonMenu.exportBookmarksMenuItem()
]

const bookmarks = menuUtil.createBookmarkTemplateItems(state.get('sites'))
const bookmarks = menuUtil.createBookmarkTemplateItems(state)
if (bookmarks.length > 0) {
submenu.push(CommonMenu.separatorMenuItem)
submenu = submenu.concat(bookmarks)
Expand Down Expand Up @@ -693,38 +692,14 @@ const doAction = (state, action) => {
}
break
}
case appConstants.APP_APPLY_SITE_RECORDS:
if (action.records && action.records.find((record) => record.objectData === 'bookmark')) {
createMenu(state)
}
break
case appConstants.APP_ADD_SITE:
case appConstants.APP_ADD_BOOKMARK:
case appConstants.APP_EDIT_BOOKMARK:
{
if (action.tag === siteTags.BOOKMARK || action.tag === siteTags.BOOKMARK_FOLDER) {
createMenu(state)
} else if (action.siteDetail && action.siteDetail.constructor === Immutable.List && action.tag === undefined) {
let shouldRebuild = false
action.siteDetail.forEach((site) => {
const tag = site.getIn(['tags', 0])
if (tag === siteTags.BOOKMARK || tag === siteTags.BOOKMARK_FOLDER) {
shouldRebuild = true
}
})
if (shouldRebuild) {
createMenu(state)
}
}
break
}
case appConstants.APP_REMOVE_SITE:
{
if (action.tag === siteTags.BOOKMARK || action.tag === siteTags.BOOKMARK_FOLDER) {
createMenu(state)
}
break
}
case appConstants.APP_REMOVE_BOOKMARK:
case appConstants.APP_ADD_BOOKMARK_FOLDER:
case appConstants.APP_EDIT_BOOKMARK_FOLDER:
case appConstants.APP_REMOVE_BOOKMARK_FOLDER:
createMenu(state)
break
case appConstants.APP_ON_CLEAR_BROWSING_DATA:
{
const defaults = state.get('clearBrowsingDataDefaults')
Expand Down
Loading

0 comments on commit 33861b7

Please sign in to comment.