зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1129454 - 2 - Adds a global play/pause button to the animation panel; r=vp
This commit is contained in:
Родитель
20f47d548f
Коммит
b9102ef3d3
|
@ -40,10 +40,11 @@ let startup = Task.async(function*(inspector) {
|
|||
throw new Error("AnimationsPanel was not loaded in the animationinspector window");
|
||||
}
|
||||
|
||||
yield promise.all([
|
||||
AnimationsController.initialize(),
|
||||
AnimationsPanel.initialize()
|
||||
]).then(null, Cu.reportError);
|
||||
// Startup first initalizes the controller and then the panel, in sequence.
|
||||
// If you want to know when everything's ready, do:
|
||||
// AnimationsPanel.once(AnimationsPanel.PANEL_INITIALIZED)
|
||||
yield AnimationsController.initialize();
|
||||
yield AnimationsPanel.initialize();
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -51,23 +52,20 @@ let startup = Task.async(function*(inspector) {
|
|||
* widget when loading/unloading the iframe into the tab.
|
||||
*/
|
||||
let shutdown = Task.async(function*() {
|
||||
yield promise.all([
|
||||
AnimationsController.destroy(),
|
||||
// Don't assume that AnimationsPanel is defined here, it's in another file.
|
||||
typeof AnimationsPanel !== "undefined"
|
||||
? AnimationsPanel.destroy()
|
||||
: promise.resolve()
|
||||
]).then(() => {
|
||||
gToolbox = gInspector = null;
|
||||
}, Cu.reportError);
|
||||
yield AnimationsController.destroy();
|
||||
// Don't assume that AnimationsPanel is defined here, it's in another file.
|
||||
if (typeof AnimationsPanel !== "undefined") {
|
||||
yield AnimationsPanel.destroy()
|
||||
}
|
||||
gToolbox = gInspector = null;
|
||||
});
|
||||
|
||||
// This is what makes the sidebar widget able to load/unload the panel.
|
||||
function setPanel(panel) {
|
||||
return startup(panel);
|
||||
return startup(panel).catch(Cu.reportError);
|
||||
}
|
||||
function destroy() {
|
||||
return shutdown();
|
||||
return shutdown().catch(Cu.reportError);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,6 +99,8 @@ let AnimationsController = {
|
|||
|
||||
let target = gToolbox.target;
|
||||
this.animationsFront = new AnimationsFront(target.client, target.form);
|
||||
// Not all server versions provide a way to pause all animations at once.
|
||||
this.hasToggleAll = yield target.actorHasMethod("animations", "toggleAll");
|
||||
|
||||
this.onPanelVisibilityChange = this.onPanelVisibilityChange.bind(this);
|
||||
this.onNewNodeFront = this.onNewNodeFront.bind(this);
|
||||
|
@ -186,6 +186,17 @@ let AnimationsController = {
|
|||
done();
|
||||
}),
|
||||
|
||||
/**
|
||||
* Toggle (pause/play) all animations in the current target.
|
||||
*/
|
||||
toggleAll: function() {
|
||||
if (!this.hasToggleAll) {
|
||||
return promis.resolve();
|
||||
}
|
||||
|
||||
return this.animationsFront.toggleAll().catch(Cu.reportError);
|
||||
},
|
||||
|
||||
// AnimationPlayerFront objects are managed by this controller. They are
|
||||
// retrieved when refreshAnimationPlayers is called, stored in the
|
||||
// animationPlayers array, and destroyed when refreshAnimationPlayers is
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
<script type="application/javascript;version=1.8" src="chrome://browser/content/devtools/theme-switching.js"/>
|
||||
</head>
|
||||
<body class="theme-sidebar devtools-monospace" role="application">
|
||||
<div id="toolbar" class="theme-toolbar">
|
||||
<span class="label">&allAnimations;</span>
|
||||
<button id="toggle-all" standalone="true" class="devtools-button"></button>
|
||||
</div>
|
||||
<div id="players" class="theme-toolbar"></div>
|
||||
<div id="error-message">
|
||||
<p>&invalidElement;</p>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
let AnimationsPanel = {
|
||||
UI_UPDATED_EVENT: "ui-updated",
|
||||
PANEL_INITIALIZED: "panel-initialized",
|
||||
|
||||
initialize: Task.async(function*() {
|
||||
if (this.initialized) {
|
||||
|
@ -21,16 +22,27 @@ let AnimationsPanel = {
|
|||
this.playersEl = document.querySelector("#players");
|
||||
this.errorMessageEl = document.querySelector("#error-message");
|
||||
this.pickerButtonEl = document.querySelector("#element-picker");
|
||||
this.toggleAllButtonEl = document.querySelector("#toggle-all");
|
||||
|
||||
// If the server doesn't support toggling all animations at once, hide the
|
||||
// whole bottom toolbar.
|
||||
if (!AnimationsController.hasToggleAll) {
|
||||
document.querySelector("#toolbar").style.display = "none";
|
||||
}
|
||||
|
||||
let hUtils = gToolbox.highlighterUtils;
|
||||
this.togglePicker = hUtils.togglePicker.bind(hUtils);
|
||||
this.onPickerStarted = this.onPickerStarted.bind(this);
|
||||
this.onPickerStopped = this.onPickerStopped.bind(this);
|
||||
this.createPlayerWidgets = this.createPlayerWidgets.bind(this);
|
||||
this.toggleAll = this.toggleAll.bind(this);
|
||||
this.onTabNavigated = this.onTabNavigated.bind(this);
|
||||
|
||||
this.startListeners();
|
||||
|
||||
this.initialized.resolve();
|
||||
|
||||
this.emit(this.PANEL_INITIALIZED);
|
||||
}),
|
||||
|
||||
destroy: Task.async(function*() {
|
||||
|
@ -47,6 +59,7 @@ let AnimationsPanel = {
|
|||
yield this.destroyPlayerWidgets();
|
||||
|
||||
this.playersEl = this.errorMessageEl = null;
|
||||
this.toggleAllButtonEl = this.pickerButtonEl = null;
|
||||
|
||||
this.destroyed.resolve();
|
||||
}),
|
||||
|
@ -54,25 +67,35 @@ let AnimationsPanel = {
|
|||
startListeners: function() {
|
||||
AnimationsController.on(AnimationsController.PLAYERS_UPDATED_EVENT,
|
||||
this.createPlayerWidgets);
|
||||
|
||||
this.pickerButtonEl.addEventListener("click", this.togglePicker, false);
|
||||
gToolbox.on("picker-started", this.onPickerStarted);
|
||||
gToolbox.on("picker-stopped", this.onPickerStopped);
|
||||
|
||||
this.toggleAllButtonEl.addEventListener("click", this.toggleAll, false);
|
||||
gToolbox.target.on("navigate", this.onTabNavigated);
|
||||
},
|
||||
|
||||
stopListeners: function() {
|
||||
AnimationsController.off(AnimationsController.PLAYERS_UPDATED_EVENT,
|
||||
this.createPlayerWidgets);
|
||||
|
||||
this.pickerButtonEl.removeEventListener("click", this.togglePicker, false);
|
||||
gToolbox.off("picker-started", this.onPickerStarted);
|
||||
gToolbox.off("picker-stopped", this.onPickerStopped);
|
||||
|
||||
this.toggleAllButtonEl.removeEventListener("click", this.toggleAll, false);
|
||||
gToolbox.target.off("navigate", this.onTabNavigated);
|
||||
},
|
||||
|
||||
displayErrorMessage: function() {
|
||||
this.errorMessageEl.style.display = "block";
|
||||
this.playersEl.style.display = "none";
|
||||
},
|
||||
|
||||
hideErrorMessage: function() {
|
||||
this.errorMessageEl.style.display = "none";
|
||||
this.playersEl.style.display = "block";
|
||||
},
|
||||
|
||||
onPickerStarted: function() {
|
||||
|
@ -83,6 +106,29 @@ let AnimationsPanel = {
|
|||
this.pickerButtonEl.removeAttribute("checked");
|
||||
},
|
||||
|
||||
toggleAll: Task.async(function*() {
|
||||
let btnClass = this.toggleAllButtonEl.classList;
|
||||
|
||||
// Toggling all animations is async and it may be some time before each of
|
||||
// the current players get their states updated, so toggle locally too, to
|
||||
// avoid the timelines from jumping back and forth.
|
||||
if (this.playerWidgets) {
|
||||
let currentWidgetStateChange = [];
|
||||
for (let widget of this.playerWidgets) {
|
||||
currentWidgetStateChange.push(btnClass.contains("paused")
|
||||
? widget.play() : widget.pause());
|
||||
}
|
||||
yield promise.all(currentWidgetStateChange).catch(Cu.reportError);
|
||||
}
|
||||
|
||||
btnClass.toggle("paused");
|
||||
yield AnimationsController.toggleAll();
|
||||
}),
|
||||
|
||||
onTabNavigated: function() {
|
||||
this.toggleAllButtonEl.classList.remove("paused");
|
||||
},
|
||||
|
||||
createPlayerWidgets: Task.async(function*() {
|
||||
let done = gInspector.updating("animationspanel");
|
||||
|
||||
|
@ -307,12 +353,15 @@ PlayerWidget.prototype = {
|
|||
* switched to the right state, and the timeline animation is stopped.
|
||||
*/
|
||||
pause: function() {
|
||||
if (this.player.state.playState === "finished") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Switch to the right className on the element right away to avoid waiting
|
||||
// for the next state update to change the playPause icon.
|
||||
this.updateWidgetState({playState: "paused"});
|
||||
return this.player.pause().then(() => {
|
||||
this.stopTimelineAnimation();
|
||||
});
|
||||
this.stopTimelineAnimation();
|
||||
return this.player.pause();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -321,6 +370,10 @@ PlayerWidget.prototype = {
|
|||
* switched to the right state, and the timeline animation is started.
|
||||
*/
|
||||
play: function() {
|
||||
if (this.player.state.playState === "finished") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Switch to the right className on the element right away to avoid waiting
|
||||
// for the next state update to change the playPause icon.
|
||||
this.updateWidgetState({playState: "running"});
|
||||
|
|
|
@ -21,5 +21,9 @@ support-files =
|
|||
[browser_animation_shows_player_on_valid_node.js]
|
||||
[browser_animation_timeline_animates.js]
|
||||
[browser_animation_timeline_waits_for_delay.js]
|
||||
[browser_animation_toggle_button_resets_on_navigate.js]
|
||||
[browser_animation_toggle_button_toggles_animations.js]
|
||||
[browser_animation_toggle_button_updates_playerWidgets.js]
|
||||
[browser_animation_toolbar_exists.js]
|
||||
[browser_animation_ui_updates_when_animation_changes.js]
|
||||
[browser_animation_ui_updates_when_animation_data_changes.js]
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that a page navigation resets the state of the global toggle button.
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
|
||||
let {inspector, panel} = yield openAnimationInspector();
|
||||
|
||||
ok(!panel.toggleAllButtonEl.classList.contains("paused"),
|
||||
"The toggle button is in its running state by default");
|
||||
|
||||
info("Toggle all animations, so that they pause");
|
||||
yield panel.toggleAll();
|
||||
ok(panel.toggleAllButtonEl.classList.contains("paused"),
|
||||
"The toggle button now is in its paused state");
|
||||
|
||||
info("Reloading the page");
|
||||
let onNewRoot = inspector.once("new-root");
|
||||
yield reloadTab();
|
||||
yield onNewRoot;
|
||||
yield inspector.once("inspector-updated");
|
||||
|
||||
ok(!panel.toggleAllButtonEl.classList.contains("paused"),
|
||||
"The toggle button is back in its running state");
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the main toggle button actually toggles animations.
|
||||
// This test doesn't need to be extra careful about checking that *all*
|
||||
// animations have been paused (including inside iframes) because there's an
|
||||
// actor test in /toolkit/devtools/server/tests/browser/ that does this.
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
|
||||
let {inspector, panel} = yield openAnimationInspector();
|
||||
|
||||
info("Click the toggle button");
|
||||
yield panel.toggleAll();
|
||||
yield checkState("paused");
|
||||
|
||||
info("Click again the toggle button");
|
||||
yield panel.toggleAll();
|
||||
yield checkState("running");
|
||||
});
|
||||
|
||||
function* checkState(state) {
|
||||
for (let selector of [".animated", ".multi", ".long"]) {
|
||||
let playState = yield getAnimationPlayerState(selector);
|
||||
is(playState, state, "The animation on node " + selector + " is " + state);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that pressing the main toggle button also updates the displayed
|
||||
// player widgets.
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
|
||||
let {inspector, panel} = yield openAnimationInspector();
|
||||
|
||||
info("Select an animated node");
|
||||
yield selectNode(".animated", inspector);
|
||||
let widget = panel.playerWidgets[0];
|
||||
|
||||
info("Click the toggle button to pause all animations");
|
||||
let onRefresh = widget.player.once(widget.player.AUTO_REFRESH_EVENT);
|
||||
yield panel.toggleAll();
|
||||
yield onRefresh;
|
||||
|
||||
info("Checking the selected node's animation player widget's state");
|
||||
is(widget.player.state.playState, "paused", "The player front's state is paused");
|
||||
ok(widget.el.classList.contains("paused"), "The widget's UI is in paused state");
|
||||
|
||||
info("Click the toggle button to play all animations");
|
||||
onRefresh = widget.player.once(widget.player.AUTO_REFRESH_EVENT);
|
||||
yield panel.toggleAll();
|
||||
yield onRefresh;
|
||||
|
||||
info("Checking the selected node's animation player widget's state again");
|
||||
is(widget.player.state.playState, "running", "The player front's state is running");
|
||||
ok(widget.el.classList.contains("running"), "The widget's UI is in running state");
|
||||
});
|
|
@ -0,0 +1,26 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the animation panel has a top toolbar that contains the play/pause
|
||||
// button and that is displayed at all times.
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
|
||||
let {inspector, panel, window} = yield openAnimationInspector();
|
||||
let doc = window.document;
|
||||
|
||||
let toolbar = doc.querySelector("#toolbar");
|
||||
ok(toolbar, "The panel contains the toolbar element");
|
||||
ok(toolbar.querySelector("#toggle-all"), "The toolbar contains the toggle button");
|
||||
ok(isNodeVisible(toolbar), "The toolbar is visible");
|
||||
|
||||
info("Select an animated node");
|
||||
yield selectNode(".animated", inspector);
|
||||
|
||||
toolbar = doc.querySelector("#toolbar");
|
||||
ok(toolbar, "The panel still contains the toolbar element");
|
||||
ok(isNodeVisible(toolbar), "The toolbar is still visible");
|
||||
});
|
|
@ -44,3 +44,20 @@ addMessageListener("Test:SetNodeStyle", function(msg) {
|
|||
|
||||
sendAsyncMessage("Test:SetNodeStyle");
|
||||
});
|
||||
|
||||
/**
|
||||
* Get the current playState of an animation player on a given node.
|
||||
* @param {Object} data
|
||||
* - {Number} animationIndex The index of the node's animationPlayers to check
|
||||
* @param {Object} objects
|
||||
* - {DOMNode} node The node to check
|
||||
*/
|
||||
addMessageListener("Test:GetAnimationPlayerState", function(msg) {
|
||||
let {animationIndex} = msg.data;
|
||||
let {node} = msg.objects;
|
||||
|
||||
let player = node.getAnimationPlayers()[animationIndex];
|
||||
player.ready.then(() => {
|
||||
sendAsyncMessage("Test:GetAnimationPlayerState", player.playState);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,6 +18,7 @@ waitForExplicitFinish();
|
|||
const TEST_URL_ROOT = "http://example.com/browser/browser/devtools/animationinspector/test/";
|
||||
const ROOT_TEST_DIR = getRootDirectory(gTestPath);
|
||||
const FRAME_SCRIPT_URL = ROOT_TEST_DIR + "doc_frame_script.js";
|
||||
const COMMON_FRAME_SCRIPT_URL = "chrome://browser/content/devtools/frame-script-utils.js";
|
||||
|
||||
// Auto clean-up when a test ends
|
||||
registerCleanupFunction(function*() {
|
||||
|
@ -63,6 +64,9 @@ function addTab(url) {
|
|||
info("Loading the helper frame script " + FRAME_SCRIPT_URL);
|
||||
browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
|
||||
|
||||
info("Loading the helper frame script " + COMMON_FRAME_SCRIPT_URL);
|
||||
browser.messageManager.loadFrameScript(COMMON_FRAME_SCRIPT_URL, false);
|
||||
|
||||
browser.addEventListener("load", function onload() {
|
||||
browser.removeEventListener("load", onload, true);
|
||||
info("URL '" + url + "' loading complete");
|
||||
|
@ -73,6 +77,13 @@ function addTab(url) {
|
|||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the current tab location.
|
||||
*/
|
||||
function reloadTab() {
|
||||
return executeInContent("devtools:test:reload", {}, {}, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple DOM node accesor function that takes either a node or a string css
|
||||
* selector as argument and returns the corresponding node
|
||||
|
@ -148,10 +159,7 @@ let openAnimationInspector = Task.async(function*() {
|
|||
let win = inspector.sidebar.getWindowForTab("animationinspector");
|
||||
let {AnimationsController, AnimationsPanel} = win;
|
||||
|
||||
yield promise.all([
|
||||
AnimationsController.initialized,
|
||||
AnimationsPanel.initialized
|
||||
]);
|
||||
yield AnimationsPanel.once(AnimationsPanel.PANEL_INITIALIZED);
|
||||
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
|
@ -283,6 +291,16 @@ let togglePlayPauseButton = Task.async(function*(widget) {
|
|||
yield widget.player.once(widget.player.AUTO_REFRESH_EVENT);
|
||||
});
|
||||
|
||||
/**
|
||||
* Get the current playState of an animation player on a given node.
|
||||
*/
|
||||
let getAnimationPlayerState = Task.async(function*(selector, animationIndex=0) {
|
||||
let playState = yield executeInContent("Test:GetAnimationPlayerState",
|
||||
{animationIndex},
|
||||
{node: getNode(selector)});
|
||||
return playState;
|
||||
});
|
||||
|
||||
/**
|
||||
* Is the given node visible in the page (rendered in the frame tree).
|
||||
* @param {DOMNode}
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
<!-- 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/. -->
|
||||
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/. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE : FILE This file contains the Animations panel strings.
|
||||
- The Animations panel is part of the Inspector sidebar -->
|
||||
The Animations panel is part of the Inspector sidebar -->
|
||||
|
||||
<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
|
||||
- keep it in English, or another language commonly spoken among web developers.
|
||||
- You want to make that choice consistent across the developer tools.
|
||||
- A good criteria is the language in which you'd find the best
|
||||
- documentation on web development on the web. -->
|
||||
keep it in English, or another language commonly spoken among web
|
||||
developers. You want to make that choice consistent across the developer
|
||||
tools. A good criteria is the language in which you'd find the best
|
||||
documentation on web development on the web. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE (title): This is the label shown in the sidebar tab -->
|
||||
<!ENTITY title "Animations">
|
||||
<!ENTITY title "Animations">
|
||||
|
||||
<!-- LOCALIZATION NOTE (invalidElement): This is the label shown in the panel
|
||||
- when an invalid node is currently selected in the inspector. -->
|
||||
<!ENTITY invalidElement "No animations were found for the current element.">
|
||||
when an invalid node is currently selected in the inspector. -->
|
||||
<!ENTITY invalidElement "No animations were found for the current element.">
|
||||
|
||||
<!-- LOCALIZATION NOTE (selectElement): This is the label shown in the panel
|
||||
- when an invalid node is currently selected in the inspector, to invite the
|
||||
- user to select a new node by clicking on the element-picker icon. -->
|
||||
<!ENTITY selectElement "Pick another element from the page.">
|
||||
when an invalid node is currently selected in the inspector, to invite the
|
||||
user to select a new node by clicking on the element-picker icon. -->
|
||||
<!ENTITY selectElement "Pick another element from the page.">
|
||||
|
||||
<!-- LOCALIZATION NOTE (allAnimations): This is the label shown at the bottom of
|
||||
the panel, in a toolbar, to let the user know the toolbar applies to all
|
||||
animations, not just the ones applying to the current element. -->
|
||||
<!ENTITY allAnimations "All animations">
|
||||
|
|
|
@ -1,25 +1,65 @@
|
|||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display : flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
color: var(--theme-content-color3);
|
||||
}
|
||||
|
||||
/* The top toolbar, containing the toggle-all button */
|
||||
|
||||
#toolbar {
|
||||
border-bottom: 1px solid var(--theme-splitter-color);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
#toolbar .label {
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
#toggle-all {
|
||||
border-width: 0px 1px;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
/* The error message, shown when an invalid/unanimated element is selected */
|
||||
|
||||
#error-message {
|
||||
margin-top: 10%;
|
||||
padding-top: 10%;
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
|
||||
/* The error message is hidden by default */
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Element picker button */
|
||||
/* The animation players container */
|
||||
|
||||
#element-picker {
|
||||
#players {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Element picker and toggle-all buttons */
|
||||
|
||||
#element-picker,
|
||||
#toggle-all {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#element-picker::before {
|
||||
#element-picker::before,
|
||||
#toggle-all::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 16px;
|
||||
|
@ -31,16 +71,33 @@ body {
|
|||
background-image: url("chrome://browser/skin/devtools/command-pick.png");
|
||||
}
|
||||
|
||||
#toggle-all::before {
|
||||
background-image: url("debugger-pause.png");
|
||||
}
|
||||
|
||||
#element-picker[checked]::before {
|
||||
background-position: -48px 0;
|
||||
filter: none; /* Icon is blue when checked, don't invert for light theme */
|
||||
}
|
||||
|
||||
#toggle-all.paused::before {
|
||||
background-image: url("debugger-play.png");
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
#element-picker::before {
|
||||
#element-picker::before,
|
||||
#toggle-all::before {
|
||||
background-image: url("chrome://browser/skin/devtools/command-pick@2x.png");
|
||||
background-size: 64px;
|
||||
}
|
||||
|
||||
#toggle-all::before {
|
||||
background-image: url("debugger-pause@2x.png");
|
||||
}
|
||||
|
||||
#toggle-all.paused::before {
|
||||
background-image: url("debugger-play@2x.png");
|
||||
}
|
||||
}
|
||||
|
||||
/* Disabled playerWidget when the animation has ended */
|
||||
|
@ -54,7 +111,6 @@ body {
|
|||
|
||||
.animation-title {
|
||||
background-color: var(--theme-toolbar-background);
|
||||
color: var(--theme-content-color3);
|
||||
border-bottom: 1px solid var(--theme-splitter-color);
|
||||
padding: 1px 4px;
|
||||
word-wrap: break-word;
|
||||
|
|
Загрузка…
Ссылка в новой задаче