From bb01d0ac70e0f4d0e37bf9f0d5fa45c4568feba9 Mon Sep 17 00:00:00 2001 From: Daisuke Akatsuka Date: Fri, 15 Jun 2018 13:38:27 +0900 Subject: [PATCH] Bug 1456828 - Part 2: Apply ProgressInspectionPanel to animations. r=gl MozReview-Commit-ID: 7It2CibH3oa --HG-- extra : rebase_source : a1e0cce1f9c0af731cb0e6d29c70e9ce20e4d5ea --- .../components/AnimationListContainer.js | 105 ++++++++++++++---- .../components/AnimationListHeader.js | 60 ---------- .../components/AnimationTimelineTickItem.js | 32 ------ .../components/AnimationTimelineTickList.js | 101 ----------------- .../inspector/animation/components/moz.build | 3 - ...owser_animation_animation-timeline-tick.js | 24 ++-- devtools/client/themes/animation.css | 77 ++----------- 7 files changed, 101 insertions(+), 301 deletions(-) delete mode 100644 devtools/client/inspector/animation/components/AnimationListHeader.js delete mode 100644 devtools/client/inspector/animation/components/AnimationTimelineTickItem.js delete mode 100644 devtools/client/inspector/animation/components/AnimationTimelineTickList.js diff --git a/devtools/client/inspector/animation/components/AnimationListContainer.js b/devtools/client/inspector/animation/components/AnimationListContainer.js index 8295ed7d199f..3decae46ad9a 100644 --- a/devtools/client/inspector/animation/components/AnimationListContainer.js +++ b/devtools/client/inspector/animation/components/AnimationListContainer.js @@ -6,11 +6,20 @@ const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); -const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); +const { connect } = require("devtools/client/shared/vendor/react-redux"); const dom = require("devtools/client/shared/vendor/react-dom-factories"); +const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); +const ReactDOM = require("devtools/client/shared/vendor/react-dom"); const AnimationList = createFactory(require("./AnimationList")); -const AnimationListHeader = createFactory(require("./AnimationListHeader")); +const CurrentTimeScrubberController = + createFactory(require("./CurrentTimeScrubberController")); +const ProgressInspectionPanel = createFactory(require("./ProgressInspectionPanel")); + +const { findOptimalTimeInterval } = require("../utils/utils"); + +// The minimum spacing between 2 time graduation headers in the timeline (px). +const TIME_GRADUATION_MIN_SPACING = 40; class AnimationListContainer extends PureComponent { static get propTypes() { @@ -32,6 +41,44 @@ class AnimationListContainer extends PureComponent { }; } + constructor(props) { + super(props); + + this.state = { + // tick labels and lines on the progress inspection panel + ticks: [], + }; + } + + componentDidMount() { + this.updateState(this.props); + } + + componentWillReceiveProps(nextProps) { + this.updateState(nextProps); + } + + updateState(props) { + const { timeScale } = props; + const tickLinesEl = ReactDOM.findDOMNode(this).querySelector(".tick-lines"); + const width = tickLinesEl.offsetWidth; + const animationDuration = timeScale.getDuration(); + const minTimeInterval = TIME_GRADUATION_MIN_SPACING * animationDuration / width; + const intervalLength = findOptimalTimeInterval(minTimeInterval); + const intervalWidth = intervalLength * width / animationDuration; + const tickCount = width / intervalWidth; + + const ticks = []; + + for (let i = 0; i <= tickCount; i++) { + const position = i * intervalWidth * 100 / width; + const label = timeScale.formatTime(timeScale.distanceToRelativeTime(position)); + ticks.push({ position, label }); + } + + this.setState({ ticks }); + } + render() { const { addAnimationsCurrentTimeListener, @@ -49,36 +96,48 @@ class AnimationListContainer extends PureComponent { simulateAnimation, timeScale, } = this.props; + const { ticks } = this.state; return dom.div( { className: "animation-list-container" }, - AnimationListHeader( + ProgressInspectionPanel( { - addAnimationsCurrentTimeListener, - removeAnimationsCurrentTimeListener, - setAnimationsCurrentTime, - timeScale, - } - ), - AnimationList( - { - animations, - emitEventForTest, - getAnimatedPropertyMap, - getNodeFromActor, - onHideBoxModelHighlighter, - onShowBoxModelHighlighterForNode, - selectAnimation, - setHighlightedNode, - setSelectedNode, - simulateAnimation, - timeScale, + indicator: CurrentTimeScrubberController( + { + addAnimationsCurrentTimeListener, + removeAnimationsCurrentTimeListener, + setAnimationsCurrentTime, + timeScale, + } + ), + list: AnimationList( + { + animations, + emitEventForTest, + getAnimatedPropertyMap, + getNodeFromActor, + onHideBoxModelHighlighter, + onShowBoxModelHighlighterForNode, + selectAnimation, + setHighlightedNode, + setSelectedNode, + simulateAnimation, + timeScale, + } + ), + ticks, } ) ); } } -module.exports = AnimationListContainer; +const mapStateToProps = state => { + return { + sidebarWidth: state.animations.sidebarSize ? state.animations.sidebarSize.width : 0 + }; +}; + +module.exports = connect(mapStateToProps)(AnimationListContainer); diff --git a/devtools/client/inspector/animation/components/AnimationListHeader.js b/devtools/client/inspector/animation/components/AnimationListHeader.js deleted file mode 100644 index 16a8c281ac1d..000000000000 --- a/devtools/client/inspector/animation/components/AnimationListHeader.js +++ /dev/null @@ -1,60 +0,0 @@ -/* 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/. */ - -"use strict"; - -const { createFactory, PureComponent } = - require("devtools/client/shared/vendor/react"); -const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); -const dom = require("devtools/client/shared/vendor/react-dom-factories"); - -const AnimationTimelineTickList = createFactory(require("./AnimationTimelineTickList")); -const CurrentTimeScrubberController = - createFactory(require("./CurrentTimeScrubberController")); - -class AnimationListHeader extends PureComponent { - static get propTypes() { - return { - addAnimationsCurrentTimeListener: PropTypes.func.isRequired, - removeAnimationsCurrentTimeListener: PropTypes.func.isRequired, - setAnimationsCurrentTime: PropTypes.func.isRequired, - timeScale: PropTypes.object.isRequired, - }; - } - - render() { - const { - addAnimationsCurrentTimeListener, - removeAnimationsCurrentTimeListener, - setAnimationsCurrentTime, - timeScale, - } = this.props; - - return dom.div( - { - className: "animation-list-header" - }, - dom.div( - { - className: "devtools-toolbar" - } - ), - AnimationTimelineTickList( - { - timeScale - } - ), - CurrentTimeScrubberController( - { - addAnimationsCurrentTimeListener, - removeAnimationsCurrentTimeListener, - setAnimationsCurrentTime, - timeScale, - } - ) - ); - } -} - -module.exports = AnimationListHeader; diff --git a/devtools/client/inspector/animation/components/AnimationTimelineTickItem.js b/devtools/client/inspector/animation/components/AnimationTimelineTickItem.js deleted file mode 100644 index b5290a9c24fd..000000000000 --- a/devtools/client/inspector/animation/components/AnimationTimelineTickItem.js +++ /dev/null @@ -1,32 +0,0 @@ -/* 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/. */ - -"use strict"; - -const { PureComponent } = require("devtools/client/shared/vendor/react"); -const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); -const dom = require("devtools/client/shared/vendor/react-dom-factories"); - -class AnimationTimeTickItem extends PureComponent { - static get propTypes() { - return { - position: PropTypes.number.isRequired, - timeTickLabel: PropTypes.string.isRequired, - }; - } - - render() { - const { position, timeTickLabel } = this.props; - - return dom.div( - { - className: "animation-timeline-tick-item", - style: { left: `${ position }%` } - }, - timeTickLabel - ); - } -} - -module.exports = AnimationTimeTickItem; diff --git a/devtools/client/inspector/animation/components/AnimationTimelineTickList.js b/devtools/client/inspector/animation/components/AnimationTimelineTickList.js deleted file mode 100644 index a073942f4737..000000000000 --- a/devtools/client/inspector/animation/components/AnimationTimelineTickList.js +++ /dev/null @@ -1,101 +0,0 @@ -/* 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/. */ - -"use strict"; - -const { Component, createFactory } = require("devtools/client/shared/vendor/react"); -const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); -const dom = require("devtools/client/shared/vendor/react-dom-factories"); -const { connect } = require("devtools/client/shared/vendor/react-redux"); -const ReactDOM = require("devtools/client/shared/vendor/react-dom"); - -const AnimationTimelineTickItem = createFactory(require("./AnimationTimelineTickItem")); - -const { findOptimalTimeInterval } = require("../utils/utils"); - -// The minimum spacing between 2 time graduation headers in the timeline (px). -const TIME_GRADUATION_MIN_SPACING = 40; - -class AnimationTimelineTickList extends Component { - static get propTypes() { - return { - sidebarWidth: PropTypes.number.isRequired, - timeScale: PropTypes.object.isRequired, - }; - } - - constructor(props) { - super(props); - - this.state = { - tickList: [], - }; - } - - componentDidMount() { - this.updateTickList(this.props); - } - - componentWillReceiveProps(nextProps) { - this.updateTickList(nextProps); - } - - shouldComponentUpdate(nextProps, nextState) { - if (this.state.tickList.length !== nextState.tickList.length) { - return true; - } - - for (let i = 0; i < this.state.tickList.length; i++) { - const currentTickItem = this.state.tickList[i]; - const nextTickItem = nextState.tickList[i]; - - if (currentTickItem.timeTickLabel !== nextTickItem.timeTickLabel) { - return true; - } - } - - return false; - } - - updateTickList(props) { - const { timeScale } = props; - const tickListEl = ReactDOM.findDOMNode(this); - const width = tickListEl.offsetWidth; - const animationDuration = timeScale.getDuration(); - const minTimeInterval = TIME_GRADUATION_MIN_SPACING * animationDuration / width; - const intervalLength = findOptimalTimeInterval(minTimeInterval); - const intervalWidth = intervalLength * width / animationDuration; - const tickCount = width / intervalWidth; - const intervalPositionPercentage = 100 * intervalWidth / width; - - const tickList = []; - for (let i = 0; i <= tickCount; i++) { - const position = i * intervalPositionPercentage; - const timeTickLabel = - timeScale.formatTime(timeScale.distanceToRelativeTime(position)); - tickList.push({ position, timeTickLabel }); - } - - this.setState({ tickList }); - } - - render() { - const { tickList } = this.state; - - return dom.div( - { - className: "animation-timeline-tick-list" - }, - tickList.map(tickItem => AnimationTimelineTickItem(tickItem)) - ); - } -} - -const mapStateToProps = state => { - return { - sidebarWidth: state.animations.sidebarSize ? state.animations.sidebarSize.width : 0 - }; -}; - -module.exports = connect(mapStateToProps)(AnimationTimelineTickList); diff --git a/devtools/client/inspector/animation/components/moz.build b/devtools/client/inspector/animation/components/moz.build index 2a704f358e44..f07afe9432b3 100644 --- a/devtools/client/inspector/animation/components/moz.build +++ b/devtools/client/inspector/animation/components/moz.build @@ -18,10 +18,7 @@ DevToolsModules( 'AnimationItem.js', 'AnimationList.js', 'AnimationListContainer.js', - 'AnimationListHeader.js', 'AnimationTarget.js', - 'AnimationTimelineTickItem.js', - 'AnimationTimelineTickList.js', 'AnimationToolbar.js', 'App.js', 'CurrentTimeLabel.js', diff --git a/devtools/client/inspector/animation/test/browser_animation_animation-timeline-tick.js b/devtools/client/inspector/animation/test/browser_animation_animation-timeline-tick.js index c67981bf02fc..533dfb81f4ef 100644 --- a/devtools/client/inspector/animation/test/browser_animation_animation-timeline-tick.js +++ b/devtools/client/inspector/animation/test/browser_animation_animation-timeline-tick.js @@ -5,8 +5,8 @@ // Test for following timeline tick items. // * animation list header elements existence -// * timeline tick item elements existence -// * count and label of timeline tick elements changing by the sidebar width +// * tick labels elements existence +// * count and text of tick label elements changing by the sidebar width const TimeScale = require("devtools/client/inspector/animation/utils/timescale"); const { findOptimalTimeInterval } = @@ -29,27 +29,24 @@ add_task(async function() { ok(listHeaderEl, "The header element should be in animation list container element"); info("Checking time tick item elements existence"); - assertTimelineTickItems(timeScale, listContainerEl); - const timelineTickItemLength = - listContainerEl.querySelectorAll(".animation-timeline-tick-item").length; + assertTickLabels(timeScale, listContainerEl); + const timelineTickItemLength = listContainerEl.querySelectorAll(".tick-label").length; info("Checking timeline tick item elements after enlarge sidebar width"); await setSidebarWidth("100%", inspector); - assertTimelineTickItems(timeScale, listContainerEl); - ok(timelineTickItemLength < - listContainerEl.querySelectorAll(".animation-timeline-tick-item").length, + assertTickLabels(timeScale, listContainerEl); + ok(timelineTickItemLength < listContainerEl.querySelectorAll(".tick-label").length, "The timeline tick item elements should increase"); }); /** - * Assert timeline tick item's position and label. + * Assert tick label's position and label. * * @param {TimeScale} - timeScale * @param {Element} - listContainerEl */ -function assertTimelineTickItems(timeScale, listContainerEl) { - const timelineTickListEl = - listContainerEl.querySelector(".animation-timeline-tick-list"); +function assertTickLabels(timeScale, listContainerEl) { + const timelineTickListEl = listContainerEl.querySelector(".tick-labels"); ok(timelineTickListEl, "The animation timeline tick list element should be in header"); @@ -59,8 +56,7 @@ function assertTimelineTickItems(timeScale, listContainerEl) { const interval = findOptimalTimeInterval(minTimeInterval); const expectedTickItem = Math.ceil(animationDuration / interval); - const timelineTickItemEls = - timelineTickListEl.querySelectorAll(".animation-timeline-tick-item"); + const timelineTickItemEls = timelineTickListEl.querySelectorAll(".tick-label"); is(timelineTickItemEls.length, expectedTickItem, "The expected number of timeline ticks were found"); diff --git a/devtools/client/themes/animation.css b/devtools/client/themes/animation.css index 07c1b62bbc3f..d0e489c64be9 100644 --- a/devtools/client/themes/animation.css +++ b/devtools/client/themes/animation.css @@ -12,6 +12,7 @@ --fill-color-cssanimation: var(--theme-contrast-background); --fill-color-csstransition: var(--theme-highlight-blue); --fill-color-scriptanimation: var(--theme-graphs-green); + --graph-height: 30px; --graph-right-offset: 10px; --keyframe-marker-shadow-color: #c4c4c4; --pause-image: url(chrome://devtools/skin/images/pause.svg); @@ -88,10 +89,7 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch /* Animation List Container */ .animation-list-container { - height: 100%; - overflow-y: auto; - overflow-x: hidden; - position: relative; + overflow: hidden; width: 100%; -moz-user-select: none; } @@ -100,50 +98,10 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch cursor: col-resize; } -/* Animation List Header */ -.animation-list-header { - display: grid; - grid-template-columns: var(--sidebar-width) calc(100% - var(--sidebar-width) - var(--graph-right-offset)) var(--graph-right-offset); - line-height: var(--devtools-toolbar-height); - min-height: 100%; - padding: 0; - pointer-events: none; - position: sticky; - top: 0; - z-index: 2; -} - -.animation-list-header .devtools-toolbar { - position: absolute; - width: 100%; -} - -/* Animation Timeline Tick List */ -.animation-timeline-tick-list { - grid-column: 2/3; - height: 100%; - position: relative; -} - -.animation-timeline-tick-item { - height: 100%; - position: absolute; -} - -.animation-timeline-tick-item::before { - border-left: var(--tick-line-style); - content: ""; - height: 100%; - position: absolute; -} - /* Current Time Scrubber */ .current-time-scrubber-controller { grid-column: 2 / 3; - height: 100%; - padding: 0; - position: absolute; - width: 100%; + z-index: 2; } .current-time-scrubber-controller::before { @@ -163,7 +121,6 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch pointer-events: auto; position: absolute; width: 12px; - z-index: 1; } .current-time-scrubber::before { @@ -186,22 +143,7 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch width: 0; } -/* Animation List */ -.animation-list { - list-style-type: none; - margin: 0; - padding: 0; - position: absolute; - top: var(--devtools-toolbar-height); - width: 100%; -} - /* Animation Item */ -.animation-item { - display: flex; - height: 30px; -} - .animation-item:nth-child(2n+1) { background-color: var(--animation-even-background-color); } @@ -229,9 +171,9 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch .animation-target { align-items: center; display: flex; - height: 100%; + grid-column: 1 / 2; + height: var(--graph-height); padding-left: 4px; - width: var(--sidebar-width); } /* Reps component */ @@ -259,10 +201,10 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch /* Summary Graph */ .animation-summary-graph { cursor: pointer; - height: 100%; + grid-column: 2 / 3; + height: var(--graph-height); padding-top: 5px; position: relative; - width: calc(100% - var(--sidebar-width) - var(--graph-right-offset)); } .animation-summary-graph.compositor::after { @@ -277,7 +219,6 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch top: 5px; width: 15px; -moz-context-properties: fill; - z-index: 1; } .animation-summary-graph-path { @@ -382,7 +323,7 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch height: 100%; overflow: hidden; width: 100%; - z-index: 1; + z-index: 2; } .animation-detail-header { @@ -527,7 +468,7 @@ select.playback-rate-selector.devtools-button:not(:empty):not(:disabled):not(.ch /* Animated Property Item */ .animated-property-item { display: flex; - height: 30px; + height: var(--graph-height); } .animated-property-item:nth-child(2n+1) {