From 451cf043428643a4ff81529cae2667575ba121e6 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Tue, 30 May 2017 16:01:52 -0700 Subject: [PATCH] Saves computed styles in the state Resolves #9149 Auditors: Test Plan: --- app/browser/reducers/windowsReducer.js | 3 ++ app/common/constants/computedStyles.js | 35 +++++++++++++++++ app/common/lib/windowsUtil.js | 38 ++++++++++++++++++- app/common/state/windowState.js | 7 ++++ .../components/download/downloadsBar.js | 10 +++++ app/renderer/components/frame/frame.js | 8 ++-- app/renderer/components/window.js | 10 +++++ docs/state.md | 1 + js/actions/appActions.js | 8 ++++ js/constants/appConstants.js | 3 +- 10 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 app/common/constants/computedStyles.js diff --git a/app/browser/reducers/windowsReducer.js b/app/browser/reducers/windowsReducer.js index e0591042b58..69d549c6b2c 100644 --- a/app/browser/reducers/windowsReducer.js +++ b/app/browser/reducers/windowsReducer.js @@ -66,6 +66,9 @@ const windowsReducer = (state, action, immutableAction) => { case windowConstants.WINDOW_SHOULD_OPEN_DEV_TOOLS: windows.openDevTools(action.get('windowId')) break + case appConstants.APP_WINDOW_COMPUTED_STYLES: + state = windowState.updateComputedStyles(state, action) + break } return state } diff --git a/app/common/constants/computedStyles.js b/app/common/constants/computedStyles.js new file mode 100644 index 00000000000..c1ec4324776 --- /dev/null +++ b/app/common/constants/computedStyles.js @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const computedStyles = { + 'bookmark-item': [ + 'max-width', + 'padding', + 'margin', + 'font-size' + ], + 'bookmark-item-chevron': [ + 'margin' + ], + 'bookmarks-toolbar': [ + 'padding' + ], + 'default': [ + 'font-family' + ], + 'download-bar': [ + 'buttons', + 'height', + 'padding' + ], + 'download-item': [ + 'margin', + 'width' + ], + 'navbar': [ + 'height' + ] +} + +module.exports = computedStyles diff --git a/app/common/lib/windowsUtil.js b/app/common/lib/windowsUtil.js index c15f82e9bde..e8cd53b696d 100644 --- a/app/common/lib/windowsUtil.js +++ b/app/common/lib/windowsUtil.js @@ -3,11 +3,47 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ const Immutable = require('immutable') +const computedStyles = require('../constants/computedStyles') +const windowState = require('../state/windowState') +const appActions = require('../../../js/actions/appActions') +const {getCurrentWindowId} = require('../../renderer/currentWindow') -module.exports.getPinnedSiteProps = site => { +const getPinnedSiteProps = site => { return Immutable.fromJS({ location: site.get('location'), order: site.get('order'), partitionNumber: site.get('partitionNumber') || 0 }) } + +const getComputedStyleData = (root) => { + const result = {} + + Object.keys(computedStyles).forEach(group => { + computedStyles[group].forEach(prop => { + const value = `--${group}-${prop}` + result[value] = root.getPropertyValue(value).trim() + }) + }) + + return result +} + +const getComputedProperty = (state, property) => { + const currentWindowIndex = windowState.getWindowIndexByWindowId(state, getCurrentWindowId()) + + return state.getIn(['windows', currentWindowIndex, 'computedStyles', property]) +} + +const updateComputedStyles = () => { + const root = window.getComputedStyle(document.querySelector(':root')) + const computedValues = getComputedStyleData(root) + appActions.updateComputedStyles(getCurrentWindowId(), computedValues) +} + +module.exports = { + getPinnedSiteProps, + getComputedStyleData, + getComputedProperty, + updateComputedStyles +} diff --git a/app/common/state/windowState.js b/app/common/state/windowState.js index a8e3c375c54..892858f170c 100644 --- a/app/common/state/windowState.js +++ b/app/common/state/windowState.js @@ -148,6 +148,13 @@ const api = { return state.set('windows', windows.delete(index).insert(index, windowValue)) }, + updateComputedStyles: (state, action) => { + const windowIndex = api.getWindowIndexByWindowId(state, action.get('windowId')) + return state.mergeDeepIn(['windows', windowIndex], { + computedStyles: action.get('values') + }) + }, + getWindows: (state) => { state = validateState(state) return state.get('windows') diff --git a/app/renderer/components/download/downloadsBar.js b/app/renderer/components/download/downloadsBar.js index 1173d11c09e..642ea392282 100644 --- a/app/renderer/components/download/downloadsBar.js +++ b/app/renderer/components/download/downloadsBar.js @@ -15,6 +15,7 @@ const webviewActions = require('../../../../js/actions/webviewActions') // Utils const contextMenus = require('../../../../js/contextMenus') +const windowsUtils = require('../../../common/lib/windowsUtil') class DownloadsBar extends ImmutableComponent { constructor () { @@ -25,6 +26,15 @@ class DownloadsBar extends ImmutableComponent { windowActions.setDownloadsToolbarVisible(false) webviewActions.setWebviewFocused() } + + componentDidMount () { + windowsUtils.updateComputedStyles() + } + + componentWillUnmount () { + windowsUtils.updateComputedStyles() + } + render () { const getComputedStyle = require('../../getComputedStyle') const downloadItemWidth = Number.parseInt(getComputedStyle('--download-item-width'), 10) diff --git a/app/renderer/components/frame/frame.js b/app/renderer/components/frame/frame.js index d647bda2f97..b93c94e4908 100644 --- a/app/renderer/components/frame/frame.js +++ b/app/renderer/components/frame/frame.js @@ -47,6 +47,7 @@ const {isFocused} = require('../../currentWindow') const debounce = require('../../../../js/lib/debounce') const locale = require('../../../../js/l10n') const imageUtil = require('../../../../js/lib/imageUtil') +const windowsUtil = require('../../../common/lib/windowsUtil') // Constants const settings = require('../../../../js/constants/settings') @@ -509,11 +510,7 @@ class Frame extends React.Component { e.stopPropagation() }) this.webview.addEventListener('update-target-url', (e) => { - if (!this.root) { - this.root = window.getComputedStyle(document.querySelector(':root')) - this.downloadsBarHeight = Number.parseInt(this.root.getPropertyValue('--downloads-bar-height'), 10) - } - let nearBottom = e.y > (window.innerHeight - 150 - this.downloadsBarHeight) + let nearBottom = e.y > (window.innerHeight - 150 - this.props.downloadsBarHeight) let mouseOnLeft = e.x < (window.innerWidth / 2) let showOnRight = nearBottom && mouseOnLeft windowActions.setLinkHoverPreview(e.url, showOnRight) @@ -960,6 +957,7 @@ class Frame extends React.Component { props.allSiteSettings = allSiteSettings // TODO (nejc) can be improved even more props.tabUrl = tab && tab.get('url') props.partitionNumber = frame.get('partitionNumber') + props.downloadsBarHeight = Number.parseInt(windowsUtil.getComputedProperty(state, '--download-bar-padding'), 10) return Object.assign({}, ownProps, props) } diff --git a/app/renderer/components/window.js b/app/renderer/components/window.js index 07a1b65e340..d77cfc76de6 100644 --- a/app/renderer/components/window.js +++ b/app/renderer/components/window.js @@ -21,8 +21,10 @@ const appActions = require('../../../js/actions/appActions') // Utils const cx = require('../../../js/lib/classSet') +const windowsUtils = require('../../common/lib/windowsUtil') const {getPlatformStyles} = require('../../common/lib/platformUtil') const {getCurrentWindowId} = require('../currentWindow') +const throttle = require('../../../js/lib/throttle') window.appActions = appActions @@ -45,6 +47,7 @@ class Window extends React.Component { this.onChange = this.onChange.bind(this) this.onAppStateChange = this.onAppStateChange.bind(this) + this.updateComputedStyles = throttle(this.updateComputedStyles.bind(this), 66) windowStore.addChangeListener(this.onChange) appStoreRenderer.addChangeListener(this.onAppStateChange) } @@ -93,11 +96,14 @@ class Window extends React.Component { componentDidMount () { appActions.windowReady(getCurrentWindowId()) + this.updateComputedStyles() + window.addEventListener('resize', this.updateComputedStyles) } componentWillUnmount () { windowStore.removeChangeListener(this.onChange) appStoreRenderer.removeChangeListener(this.onAppStateChange) + window.removeEventListener('resize', this.updateComputedStyles) } shouldComponentUpdate (nextProps, nextState) { @@ -127,6 +133,10 @@ class Window extends React.Component { }) }) } + + updateComputedStyles () { + windowsUtils.updateComputedStyles() + } } Window.propTypes = { appState: PropTypes.object, frames: PropTypes.array, initWindowState: PropTypes.object } diff --git a/docs/state.md b/docs/state.md index 4e07eecaa37..2e519803ea5 100644 --- a/docs/state.md +++ b/docs/state.md @@ -355,6 +355,7 @@ AppStore }, windows: [{ // persistent properties + computedStyles: object, // all computed styles defined in computedStyles.js focused: boolean, height: number, left: number, diff --git a/js/actions/appActions.js b/js/actions/appActions.js index 9715034b900..f59965e3eab 100644 --- a/js/actions/appActions.js +++ b/js/actions/appActions.js @@ -1411,6 +1411,14 @@ const appActions = { dispatch({ actionType: appConstants.APP_UPDATE_LOG_OPENED }) + }, + + updateComputedStyles: function (windowId, values) { + dispatch({ + actionType: appConstants.APP_WINDOW_COMPUTED_STYLES, + windowId, + values + }) } } diff --git a/js/constants/appConstants.js b/js/constants/appConstants.js index 2c46754f24c..b6041cb42ba 100644 --- a/js/constants/appConstants.js +++ b/js/constants/appConstants.js @@ -131,7 +131,8 @@ const appConstants = { APP_REMOVE_PASSWORD: _, /** @param {Object} passwordDetail */ APP_REMOVE_PASSWORD_SITE: _, /** @param {Object} passwordDetail */ APP_CLEAR_PASSWORDS: _, - APP_UPDATE_LOG_OPENED: _ + APP_UPDATE_LOG_OPENED: _, + APP_WINDOW_COMPUTED_STYLES: _ } module.exports = mapValuesByKeys(appConstants)