зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1087877 - [timeline] User should be able to filter out any type of marker. r=vporof
This commit is contained in:
Родитель
77d594ab26
Коммит
4406c2c5e0
|
@ -1429,6 +1429,7 @@ pref("devtools.timeline.enabled", true);
|
|||
#else
|
||||
pref("devtools.timeline.enabled", false);
|
||||
#endif
|
||||
pref("devtools.timeline.hiddenMarkers", "[]");
|
||||
|
||||
// Enable perftools via build command
|
||||
#ifdef MOZ_DEVTOOLS_PERFTOOLS
|
||||
|
|
|
@ -616,14 +616,19 @@ AbstractCanvasGraph.prototype = {
|
|||
|
||||
/**
|
||||
* Updates this graph to reflect the new dimensions of the parent node.
|
||||
*
|
||||
* @param boolean options.force
|
||||
* Force redrawing everything
|
||||
*/
|
||||
refresh: function() {
|
||||
refresh: function(options={}) {
|
||||
let bounds = this._parent.getBoundingClientRect();
|
||||
let newWidth = this.fixedWidth || bounds.width;
|
||||
let newHeight = this.fixedHeight || bounds.height;
|
||||
|
||||
// Prevent redrawing everything if the graph's width & height won't change.
|
||||
if (this._width == newWidth * this._pixelRatio &&
|
||||
// Prevent redrawing everything if the graph's width & height won't change,
|
||||
// except if force=true.
|
||||
if (!options.force &&
|
||||
this._width == newWidth * this._pixelRatio &&
|
||||
this._height == newHeight * this._pixelRatio) {
|
||||
this.emit("refresh-cancelled");
|
||||
return;
|
||||
|
|
|
@ -6,6 +6,7 @@ support-files =
|
|||
|
||||
[browser_timeline_aaa_run_first_leaktest.js]
|
||||
[browser_timeline_blueprint.js]
|
||||
[browser_timeline_filters.js]
|
||||
[browser_timeline_overview-initial-selection-01.js]
|
||||
[browser_timeline_overview-initial-selection-02.js]
|
||||
[browser_timeline_overview-update.js]
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests markers filtering mechanism.
|
||||
*/
|
||||
|
||||
let test = Task.async(function*() {
|
||||
let { target, panel } = yield initTimelinePanel(SIMPLE_URL);
|
||||
let { $, $$, TimelineController, TimelineView } = panel.panelWin;
|
||||
|
||||
yield TimelineController.toggleRecording();
|
||||
ok(true, "Recording has started.");
|
||||
|
||||
yield waitUntil(() => {
|
||||
// Wait until we get 3 different markers.
|
||||
let markers = TimelineController.getMarkers();
|
||||
return markers.some(m => m.name == "Styles") &&
|
||||
markers.some(m => m.name == "Reflow") &&
|
||||
markers.some(m => m.name == "Paint");
|
||||
});
|
||||
|
||||
yield TimelineController.toggleRecording();
|
||||
|
||||
let overview = TimelineView.markersOverview;
|
||||
|
||||
// Select everything
|
||||
overview.setSelection({ start: 0, end: overview.width })
|
||||
|
||||
$("#filter-button").click();
|
||||
|
||||
let menuItem1 = $("menuitem[marker-type=Styles]");
|
||||
let menuItem2 = $("menuitem[marker-type=Reflow]");
|
||||
let menuItem3 = $("menuitem[marker-type=Paint]");
|
||||
|
||||
let originalHeight = overview.fixedHeight;
|
||||
|
||||
ok($(".waterfall-marker-bar[type=Styles]"), "Found at least one 'Styles' marker");
|
||||
ok($(".waterfall-marker-bar[type=Reflow]"), "Found at least one 'Reflow' marker");
|
||||
ok($(".waterfall-marker-bar[type=Paint]"), "Found at least one 'Paint' marker");
|
||||
|
||||
let heightBefore = overview.fixedHeight;
|
||||
EventUtils.synthesizeMouseAtCenter(menuItem1, {type: "mouseup"}, panel.panelWin);
|
||||
yield once(menuItem1, "command");
|
||||
// A row is 11px. See markers-overview.js
|
||||
is(overview.fixedHeight, heightBefore - 11, "Overview is smaller");
|
||||
ok(!$(".waterfall-marker-bar[type=Styles]"), "No 'Styles' marker");
|
||||
ok($(".waterfall-marker-bar[type=Reflow]"), "Found at least one 'Reflow' marker");
|
||||
ok($(".waterfall-marker-bar[type=Paint]"), "Found at least one 'Paint' marker");
|
||||
|
||||
heightBefore = overview.fixedHeight;
|
||||
EventUtils.synthesizeMouseAtCenter(menuItem2, {type: "mouseup"}, panel.panelWin);
|
||||
yield once(menuItem2, "command");
|
||||
is(overview.fixedHeight, heightBefore - 11, "Overview is smaller");
|
||||
ok(!$(".waterfall-marker-bar[type=Styles]"), "No 'Styles' marker");
|
||||
ok(!$(".waterfall-marker-bar[type=Reflow]"), "No 'Reflow' marker");
|
||||
ok($(".waterfall-marker-bar[type=Paint]"), "Found at least one 'Paint' marker");
|
||||
|
||||
heightBefore = overview.fixedHeight;
|
||||
EventUtils.synthesizeMouseAtCenter(menuItem3, {type: "mouseup"}, panel.panelWin);
|
||||
yield once(menuItem3, "command");
|
||||
is(overview.fixedHeight, heightBefore - 11, "Overview is smaller");
|
||||
ok(!$(".waterfall-marker-bar[type=Styles]"), "No 'Styles' marker");
|
||||
ok(!$(".waterfall-marker-bar[type=Reflow]"), "No 'Reflow' marker");
|
||||
ok(!$(".waterfall-marker-bar[type=Paint]"), "No 'Paint' marker");
|
||||
|
||||
for (let item of [menuItem1, menuItem2, menuItem3]) {
|
||||
EventUtils.synthesizeMouseAtCenter(item, {type: "mouseup"}, panel.panelWin);
|
||||
yield once(item, "command");
|
||||
}
|
||||
|
||||
ok($(".waterfall-marker-bar[type=Styles]"), "Found at least one 'Styles' marker");
|
||||
ok($(".waterfall-marker-bar[type=Reflow]"), "Found at least one 'Reflow' marker");
|
||||
ok($(".waterfall-marker-bar[type=Paint]"), "Found at least one 'Paint' marker");
|
||||
|
||||
is(overview.fixedHeight, originalHeight, "Overview restored");
|
||||
|
||||
$(".waterfall-marker-bar[type=Styles]");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
});
|
|
@ -129,4 +129,45 @@ function waitUntil(predicate, interval = 10) {
|
|||
waitUntil(predicate).then(() => deferred.resolve(true));
|
||||
}, interval);
|
||||
return deferred.promise;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until next tick.
|
||||
*/
|
||||
function nextTick() {
|
||||
let def = promise.defer();
|
||||
executeSoon(() => def.resolve())
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for eventName on target.
|
||||
* @param {Object} target An observable object that either supports on/off or
|
||||
* addEventListener/removeEventListener
|
||||
* @param {String} eventName
|
||||
* @param {Boolean} useCapture Optional, for addEventListener/removeEventListener
|
||||
* @return A promise that resolves when the event has been handled
|
||||
*/
|
||||
function once(target, eventName, useCapture=false) {
|
||||
info("Waiting for event: '" + eventName + "' on " + target + ".");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
for (let [add, remove] of [
|
||||
["addEventListener", "removeEventListener"],
|
||||
["addListener", "removeListener"],
|
||||
["on", "off"]
|
||||
]) {
|
||||
if ((add in target) && (remove in target)) {
|
||||
target[add](eventName, function onEvent(...aArgs) {
|
||||
info("Got event: '" + eventName + "' on " + target + ".");
|
||||
target[remove](eventName, onEvent, useCapture);
|
||||
deferred.resolve.apply(deferred, aArgs);
|
||||
}, useCapture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
|||
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm");
|
||||
Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
|
||||
|
||||
devtools.lazyRequireGetter(this, "promise");
|
||||
devtools.lazyRequireGetter(this, "EventEmitter",
|
||||
|
@ -20,6 +21,8 @@ devtools.lazyRequireGetter(this, "Waterfall",
|
|||
"devtools/timeline/waterfall", true);
|
||||
devtools.lazyRequireGetter(this, "MarkerDetails",
|
||||
"devtools/timeline/marker-details", true);
|
||||
devtools.lazyRequireGetter(this, "TIMELINE_BLUEPRINT",
|
||||
"devtools/timeline/global", true);
|
||||
|
||||
devtools.lazyImporter(this, "CanvasGraphUtils",
|
||||
"resource:///modules/devtools/Graphs.jsm");
|
||||
|
@ -30,6 +33,14 @@ devtools.lazyImporter(this, "PluralForm",
|
|||
const OVERVIEW_UPDATE_INTERVAL = 200;
|
||||
const OVERVIEW_INITIAL_SELECTION_RATIO = 0.15;
|
||||
|
||||
/**
|
||||
* Preference for devtools.timeline.hiddenMarkers.
|
||||
* Stores which markers should be hidden.
|
||||
*/
|
||||
const Prefs = new ViewHelpers.Prefs("devtools.timeline", {
|
||||
hiddenMarkers: ["Json", "hiddenMarkers"]
|
||||
});
|
||||
|
||||
// The panel's window global is an EventEmitter firing the following events:
|
||||
const EVENTS = {
|
||||
// When a recording is started or stopped, via the `stopwatch` button.
|
||||
|
@ -250,8 +261,9 @@ let TimelineView = {
|
|||
* Initialization function, called when the tool is started.
|
||||
*/
|
||||
initialize: Task.async(function*() {
|
||||
this.markersOverview = new MarkersOverview($("#markers-overview"));
|
||||
this.waterfall = new Waterfall($("#timeline-waterfall"), $("#timeline-pane"));
|
||||
let blueprint = this._getFilteredBluePrint();
|
||||
this.markersOverview = new MarkersOverview($("#markers-overview"), blueprint);
|
||||
this.waterfall = new Waterfall($("#timeline-waterfall"), $("#timeline-pane"), blueprint);
|
||||
this.markerDetails = new MarkerDetails($("#timeline-waterfall-details"), $("#timeline-waterfall-container > splitter"));
|
||||
|
||||
this._onSelecting = this._onSelecting.bind(this);
|
||||
|
@ -265,7 +277,10 @@ let TimelineView = {
|
|||
this.waterfall.on("unselected", this._onMarkerSelected);
|
||||
|
||||
yield this.markersOverview.ready();
|
||||
|
||||
yield this.waterfall.recalculateBounds();
|
||||
|
||||
this._buildFilterPopup();
|
||||
}),
|
||||
|
||||
/**
|
||||
|
@ -434,7 +449,101 @@ let TimelineView = {
|
|||
_onRefresh: function() {
|
||||
this.waterfall.recalculateBounds();
|
||||
this.updateWaterfall();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Rebuild a blueprint without hidden markers.
|
||||
*/
|
||||
_getFilteredBluePrint: function() {
|
||||
let hiddenMarkers = Prefs.hiddenMarkers;
|
||||
let filteredBlueprint = Cu.cloneInto(TIMELINE_BLUEPRINT, {});
|
||||
let maybeRemovedGroups = new Set();
|
||||
let removedGroups = new Set();
|
||||
|
||||
// 1. Remove hidden markers from the blueprint.
|
||||
|
||||
for (let hiddenMarkerName of hiddenMarkers) {
|
||||
maybeRemovedGroups.add(filteredBlueprint[hiddenMarkerName].group);
|
||||
delete filteredBlueprint[hiddenMarkerName];
|
||||
}
|
||||
|
||||
// 2. Get a list of all the groups that will be removed.
|
||||
|
||||
for (let removedGroup of maybeRemovedGroups) {
|
||||
let markerNames = Object.keys(filteredBlueprint);
|
||||
let allGroupsRemoved = markerNames.every(e => filteredBlueprint[e].group != removedGroup);
|
||||
if (allGroupsRemoved) {
|
||||
removedGroups.add(removedGroup);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Offset groups.
|
||||
|
||||
for (let removedGroup of removedGroups) {
|
||||
for (let [, markerDetails] of Iterator(filteredBlueprint)) {
|
||||
if (markerDetails.group > removedGroup) {
|
||||
markerDetails.group--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filteredBlueprint;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* When the list of hidden markers changes, update waterfall
|
||||
* and overview.
|
||||
*/
|
||||
_onHiddenMarkersChanged: function(e) {
|
||||
let menuItems = $$("#timelineFilterPopup menuitem[marker-type]:not([checked])");
|
||||
let hiddenMarkers = Array.map(menuItems, e => e.getAttribute("marker-type"));
|
||||
|
||||
Prefs.hiddenMarkers = hiddenMarkers;
|
||||
let blueprint = this._getFilteredBluePrint();
|
||||
|
||||
this.waterfall.setBlueprint(blueprint);
|
||||
this.updateWaterfall();
|
||||
|
||||
this.markersOverview.setBlueprint(blueprint);
|
||||
this.markersOverview.refresh({ force: true });
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates the filter popup.
|
||||
*/
|
||||
_buildFilterPopup: function() {
|
||||
let popup = $("#timelineFilterPopup");
|
||||
let button = $("#filter-button");
|
||||
|
||||
popup.addEventListener("popupshowing", () => button.setAttribute("open", "true"));
|
||||
popup.addEventListener("popuphiding", () => button.removeAttribute("open"));
|
||||
|
||||
this._onHiddenMarkersChanged = this._onHiddenMarkersChanged.bind(this);
|
||||
|
||||
for (let [markerName, markerDetails] of Iterator(TIMELINE_BLUEPRINT)) {
|
||||
let menuitem = document.createElement("menuitem");
|
||||
menuitem.setAttribute("closemenu", "none");
|
||||
menuitem.setAttribute("type", "checkbox");
|
||||
menuitem.setAttribute("marker-type", markerName);
|
||||
menuitem.setAttribute("label", markerDetails.label);
|
||||
menuitem.setAttribute("flex", "1");
|
||||
menuitem.setAttribute("align", "center");
|
||||
|
||||
menuitem.addEventListener("command", this._onHiddenMarkersChanged);
|
||||
|
||||
if (Prefs.hiddenMarkers.indexOf(markerName) == -1) {
|
||||
menuitem.setAttribute("checked", "true");
|
||||
}
|
||||
|
||||
// Style used by pseudo element ::before in timeline.css.in
|
||||
let bulletStyle = `--bullet-bg: ${markerDetails.fill};`
|
||||
bulletStyle += `--bullet-border: ${markerDetails.stroke}`;
|
||||
menuitem.setAttribute("style", bulletStyle);
|
||||
|
||||
popup.appendChild(menuitem);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
<script src="chrome://browser/content/devtools/theme-switching.js"/>
|
||||
<script type="application/javascript" src="timeline.js"/>
|
||||
|
||||
<popupset id="timelinePopupset">
|
||||
<menupopup id="timelineFilterPopup" position="after_start"/>
|
||||
</popupset>
|
||||
|
||||
<vbox class="theme-body" flex="1">
|
||||
<toolbar id="timeline-toolbar"
|
||||
class="devtools-toolbar">
|
||||
|
@ -27,6 +31,10 @@
|
|||
class="devtools-toolbarbutton"
|
||||
oncommand="TimelineController.toggleRecording()"
|
||||
tooltiptext="&timelineUI.recordButton.tooltip;"/>
|
||||
<toolbarbutton id="filter-button"
|
||||
popup="timelineFilterPopup"
|
||||
class="devtools-toolbarbutton"
|
||||
tooltiptext="&timelineUI.filterButton.tooltip;"/>
|
||||
<checkbox id="memory-checkbox"
|
||||
label="&timelineUI.memoryCheckbox.label;"
|
||||
oncommand="TimelineController.updateMemoryRecording()"
|
||||
|
|
|
@ -16,13 +16,11 @@ Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
|
|||
|
||||
loader.lazyRequireGetter(this, "L10N",
|
||||
"devtools/timeline/global", true);
|
||||
loader.lazyRequireGetter(this, "TIMELINE_BLUEPRINT",
|
||||
"devtools/timeline/global", true);
|
||||
|
||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
const OVERVIEW_HEADER_HEIGHT = 14; // px
|
||||
const OVERVIEW_BODY_HEIGHT = 55; // 11px * 5 groups
|
||||
const OVERVIEW_ROW_HEIGHT = 11; // row height
|
||||
|
||||
const OVERVIEW_BACKGROUND_COLOR = "#fff";
|
||||
const OVERVIEW_CLIPHEAD_LINE_COLOR = "#666";
|
||||
|
@ -50,13 +48,16 @@ const OVERVIEW_GROUP_ALTERNATING_BACKGROUND = "rgba(0,0,0,0.05)";
|
|||
*
|
||||
* @param nsIDOMNode parent
|
||||
* The parent node holding the overview.
|
||||
* @param Object blueprint
|
||||
* List of names and colors defining markers.
|
||||
*/
|
||||
function MarkersOverview(parent, ...args) {
|
||||
function MarkersOverview(parent, blueprint, ...args) {
|
||||
AbstractCanvasGraph.apply(this, [parent, "markers-overview", ...args]);
|
||||
this.once("ready", () => {
|
||||
// Set the list of names, properties and colors used to paint this overview.
|
||||
this.setBlueprint(TIMELINE_BLUEPRINT);
|
||||
|
||||
// Set the list of names, properties and colors used to paint this overview.
|
||||
this.setBlueprint(blueprint);
|
||||
|
||||
this.once("ready", () => {
|
||||
// Populate this overview with some dummy initial data.
|
||||
this.setData({ interval: { startTime: 0, endTime: 1000 }, markers: [] });
|
||||
});
|
||||
|
@ -68,14 +69,14 @@ MarkersOverview.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
|||
selectionBackgroundColor: OVERVIEW_SELECTION_BACKGROUND_COLOR,
|
||||
selectionStripesColor: OVERVIEW_SELECTION_STRIPES_COLOR,
|
||||
headerHeight: OVERVIEW_HEADER_HEIGHT,
|
||||
bodyHeight: OVERVIEW_BODY_HEIGHT,
|
||||
rowHeight: OVERVIEW_ROW_HEIGHT,
|
||||
groupPadding: OVERVIEW_GROUP_VERTICAL_PADDING,
|
||||
|
||||
/**
|
||||
* Compute the height of the overview.
|
||||
*/
|
||||
get fixedHeight() {
|
||||
return this.headerHeight + this.bodyHeight;
|
||||
return this.headerHeight + this.rowHeight * (this._lastGroup + 1);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -119,14 +120,17 @@ MarkersOverview.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
|
|||
// draw all markers sharing the same style at once.
|
||||
|
||||
for (let marker of markers) {
|
||||
this._paintBatches.get(marker.name).batch.push(marker);
|
||||
let markerType = this._paintBatches.get(marker.name);
|
||||
if (markerType) {
|
||||
markerType.batch.push(marker);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate each group's height, and the time-based scaling.
|
||||
|
||||
let totalGroups = this._lastGroup + 1;
|
||||
let headerHeight = this.headerHeight * this._pixelRatio;
|
||||
let groupHeight = this.bodyHeight * this._pixelRatio / totalGroups;
|
||||
let groupHeight = this.rowHeight * this._pixelRatio;
|
||||
let groupPadding = this.groupPadding * this._pixelRatio;
|
||||
|
||||
let totalTime = (endTime - startTime) || 0;
|
||||
|
|
|
@ -12,8 +12,6 @@ const {Ci, Cu} = require("chrome");
|
|||
|
||||
loader.lazyRequireGetter(this, "L10N",
|
||||
"devtools/timeline/global", true);
|
||||
loader.lazyRequireGetter(this, "TIMELINE_BLUEPRINT",
|
||||
"devtools/timeline/global", true);
|
||||
|
||||
loader.lazyImporter(this, "setNamedTimeout",
|
||||
"resource:///modules/devtools/ViewHelpers.jsm");
|
||||
|
@ -50,8 +48,10 @@ const WATERFALL_ROWCOUNT_ONPAGEUPDOWN = 10;
|
|||
* The parent node holding the waterfall.
|
||||
* @param nsIDOMNode container
|
||||
* The container node that key events should be bound to.
|
||||
* @param Object blueprint
|
||||
* List of names and colors defining markers.
|
||||
*/
|
||||
function Waterfall(parent, container) {
|
||||
function Waterfall(parent, container, blueprint) {
|
||||
EventEmitter.decorate(this);
|
||||
|
||||
this._parent = parent;
|
||||
|
@ -75,7 +75,7 @@ function Waterfall(parent, container) {
|
|||
|
||||
// Lazy require is a bit slow, and these are hot objects.
|
||||
this._l10n = L10N;
|
||||
this._blueprint = TIMELINE_BLUEPRINT;
|
||||
this._blueprint = blueprint
|
||||
this._setNamedTimeout = setNamedTimeout;
|
||||
this._clearNamedTimeout = clearNamedTimeout;
|
||||
|
||||
|
@ -120,6 +120,14 @@ Waterfall.prototype = {
|
|||
this.selectRow(this._selectedRowIdx);
|
||||
},
|
||||
|
||||
/**
|
||||
* List of names and colors used to paint markers.
|
||||
* @see TIMELINE_BLUEPRINT in timeline/widgets/global.js
|
||||
*/
|
||||
setBlueprint: function(blueprint) {
|
||||
this._blueprint = blueprint;
|
||||
},
|
||||
|
||||
/**
|
||||
* Keybindings.
|
||||
*/
|
||||
|
@ -251,6 +259,10 @@ Waterfall.prototype = {
|
|||
if (!isMarkerInRange(marker, startTime, endTime)) {
|
||||
continue;
|
||||
}
|
||||
if (!(marker.name in this._blueprint)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only build and display a finite number of markers initially, to
|
||||
// preserve a snappy UI. After a certain delay, continue building the
|
||||
// outstanding markers while there's (hopefully) no user interaction.
|
||||
|
|
|
@ -19,15 +19,19 @@
|
|||
- as a label to signal that a recording is in progress. -->
|
||||
<!ENTITY timelineUI.recordLabel "Recording…">
|
||||
|
||||
<!-- LOCALIZATION NOTE (timelineUI.timelineUI.memoryCheckbox.label): This string
|
||||
<!-- LOCALIZATION NOTE (timelineUI.memoryCheckbox.label): This string
|
||||
- is displayed next to a checkbox determining whether or not memory
|
||||
- measurements are enabled. -->
|
||||
<!ENTITY timelineUI.memoryCheckbox.label "Memory">
|
||||
|
||||
<!-- LOCALIZATION NOTE (timelineUI.timelineUI.memoryCheckbox.tooltip): This string
|
||||
<!-- LOCALIZATION NOTE (timelineUI.memoryCheckbox.tooltip): This string
|
||||
- is displayed next to the memory checkbox -->
|
||||
<!ENTITY timelineUI.memoryCheckbox.tooltip "Enable memory measurements">
|
||||
|
||||
<!-- LOCALIZATION NOTE (timelineUI.filterButton.tooltip): This string
|
||||
- is displayed next to the filter button-->
|
||||
<!ENTITY timelineUI.filterButton.tooltip "Select what data to display">
|
||||
|
||||
<!-- LOCALIZATION NOTE (timelineUI.emptyNotice1/2): This is the label shown
|
||||
- in the timeline view when empty. -->
|
||||
<!ENTITY timelineUI.emptyNotice1 "Click on the">
|
||||
|
|
|
@ -270,6 +270,7 @@ browser.jar:
|
|||
* skin/classic/browser/devtools/profiler.css (devtools/profiler.css)
|
||||
* skin/classic/browser/devtools/performance.css (devtools/performance.css)
|
||||
* skin/classic/browser/devtools/timeline.css (devtools/timeline.css)
|
||||
skin/classic/browser/devtools/timeline-filter.svg (../shared/devtools/images/timeline-filter.svg)
|
||||
* skin/classic/browser/devtools/scratchpad.css (devtools/scratchpad.css)
|
||||
* skin/classic/browser/devtools/shadereditor.css (devtools/shadereditor.css)
|
||||
* skin/classic/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
|
|
|
@ -396,6 +396,7 @@ browser.jar:
|
|||
* skin/classic/browser/devtools/profiler.css (devtools/profiler.css)
|
||||
* skin/classic/browser/devtools/performance.css (devtools/performance.css)
|
||||
* skin/classic/browser/devtools/timeline.css (devtools/timeline.css)
|
||||
skin/classic/browser/devtools/timeline-filter.svg (../shared/devtools/images/timeline-filter.svg)
|
||||
* skin/classic/browser/devtools/scratchpad.css (devtools/scratchpad.css)
|
||||
* skin/classic/browser/devtools/shadereditor.css (devtools/shadereditor.css)
|
||||
* skin/classic/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
x="0px" y="0px"
|
||||
width="16" height="16"
|
||||
viewBox="0 0 16 16"
|
||||
enable-background="new 0 0 16 16"
|
||||
xml:space="preserve">
|
||||
<style>
|
||||
use:not(:target) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
use {
|
||||
fill: #EDF0F1;
|
||||
}
|
||||
|
||||
use[id$="-disabled"] {
|
||||
fill-opacity: 0.5;
|
||||
}
|
||||
|
||||
use[id$="-open"] {
|
||||
fill: #3BACE5;
|
||||
}
|
||||
|
||||
</style>
|
||||
<defs style="display:none">
|
||||
<path id="filter-shape"
|
||||
d="M 2,2 v 3 l 5,4 v 6 h 2 v -6 l 5,-4 v -3 L 14,2 z"/>
|
||||
</defs>
|
||||
<use id="filter" xlink:href="#filter-shape"/>
|
||||
<use id="filter-disabled" xlink:href="#filter-shape"/>
|
||||
<use id="filter-open" xlink:href="#filter-shape"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 941 B |
|
@ -5,6 +5,7 @@
|
|||
|
||||
#record-button {
|
||||
list-style-image: url(profiler-stopwatch.svg);
|
||||
min-width: 24px;
|
||||
}
|
||||
|
||||
#record-button[checked] {
|
||||
|
@ -15,6 +16,35 @@
|
|||
visibility: hidden;
|
||||
}
|
||||
|
||||
#memory-checkbox .checkbox-label {
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
#filter-button {
|
||||
list-style-image: url(timeline-filter.svg#filter);
|
||||
min-width: 24px;
|
||||
}
|
||||
|
||||
#filter-button[disabled] {
|
||||
list-style-image: url(timeline-filter.svg#filter-disabled);
|
||||
}
|
||||
|
||||
#filter-button[open] {
|
||||
list-style-image: url(timeline-filter.svg#filter-open);
|
||||
}
|
||||
|
||||
#timelineFilterPopup > menuitem:before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
margin: 0 8px;
|
||||
border: 1px solid;
|
||||
border-radius: 1px;
|
||||
background-color: var(--bullet-bg);
|
||||
border-color: var(--bullet-border);
|
||||
}
|
||||
|
||||
.notice-container {
|
||||
font-size: 120%;
|
||||
padding-bottom: 35vh;
|
||||
|
@ -185,7 +215,6 @@
|
|||
.marker-details-bullet {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
margin: 0 8px;
|
||||
border: 1px solid;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
|
|
@ -161,25 +161,25 @@
|
|||
}
|
||||
|
||||
/* Button States */
|
||||
.theme-dark .devtools-toolbarbutton:hover,
|
||||
.theme-dark #toolbox-buttons .devtools-toolbarbutton[text-as-image]:hover,
|
||||
.theme-dark .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]):hover {
|
||||
.theme-dark .devtools-toolbarbutton:not([disabled]):hover,
|
||||
.theme-dark #toolbox-buttons .devtools-toolbarbutton:not([disabled])[text-as-image]:hover,
|
||||
.theme-dark .devtools-toolbarbutton:not([disabled])[label]:not([text-as-image]):not([type=menu-button]):hover {
|
||||
background: rgba(0, 0, 0, .3); /* Splitters */
|
||||
}
|
||||
.theme-light .devtools-toolbarbutton:hover,
|
||||
.theme-light #toolbox-buttons .devtools-toolbarbutton[text-as-image]:hover,
|
||||
.theme-light .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]):hover {
|
||||
.theme-light .devtools-toolbarbutton:not([disabled]):hover,
|
||||
.theme-light #toolbox-buttons .devtools-toolbarbutton:not([disabled])[text-as-image]:hover,
|
||||
.theme-light .devtools-toolbarbutton:not([disabled])[label]:not([text-as-image]):not([type=menu-button]):hover {
|
||||
background: rgba(170, 170, 170, .3); /* Splitters */
|
||||
}
|
||||
|
||||
.theme-dark .devtools-toolbarbutton:hover:active,
|
||||
.theme-dark #toolbox-buttons .devtools-toolbarbutton[text-as-image]:hover:active,
|
||||
.theme-dark .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]):hover:active {
|
||||
.theme-dark .devtools-toolbarbutton:not([disabled]):hover:active,
|
||||
.theme-dark #toolbox-buttons .devtools-toolbarbutton:not([disabled])[text-as-image]:hover:active,
|
||||
.theme-dark .devtools-toolbarbutton:not([disabled])[label]:not([text-as-image]):not([type=menu-button]):hover:active {
|
||||
background: rgba(0, 0, 0, .4); /* Splitters */
|
||||
}
|
||||
.theme-light .devtools-toolbarbutton:hover:active,
|
||||
.theme-light #toolbox-buttons .devtools-toolbarbutton[text-as-image]:hover:active,
|
||||
.theme-light .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]):hover:active {
|
||||
.theme-light .devtools-toolbarbutton:not([disabled]):hover:active,
|
||||
.theme-light #toolbox-buttons .devtools-toolbarbutton:not([disabled])[text-as-image]:hover:active,
|
||||
.theme-light .devtools-toolbarbutton:not([disabled])[label]:not([text-as-image]):not([type=menu-button]):hover:active {
|
||||
background: rgba(170, 170, 170, .4); /* Splitters */
|
||||
}
|
||||
|
||||
|
|
|
@ -306,6 +306,7 @@ browser.jar:
|
|||
* skin/classic/browser/devtools/profiler.css (devtools/profiler.css)
|
||||
* skin/classic/browser/devtools/performance.css (devtools/performance.css)
|
||||
* skin/classic/browser/devtools/timeline.css (devtools/timeline.css)
|
||||
skin/classic/browser/devtools/timeline-filter.svg (../shared/devtools/images/timeline-filter.svg)
|
||||
* skin/classic/browser/devtools/scratchpad.css (devtools/scratchpad.css)
|
||||
* skin/classic/browser/devtools/shadereditor.css (devtools/shadereditor.css)
|
||||
skin/classic/browser/devtools/storage.css (../shared/devtools/storage.css)
|
||||
|
@ -753,6 +754,7 @@ browser.jar:
|
|||
* skin/classic/aero/browser/devtools/profiler.css (devtools/profiler.css)
|
||||
* skin/classic/aero/browser/devtools/performance.css (devtools/performance.css)
|
||||
* skin/classic/aero/browser/devtools/timeline.css (devtools/timeline.css)
|
||||
skin/classic/aero/browser/devtools/timeline-filter.svg (../shared/devtools/images/timeline-filter.svg)
|
||||
* skin/classic/aero/browser/devtools/scratchpad.css (devtools/scratchpad.css)
|
||||
* skin/classic/aero/browser/devtools/shadereditor.css (devtools/shadereditor.css)
|
||||
* skin/classic/aero/browser/devtools/splitview.css (../shared/devtools/splitview.css)
|
||||
|
|
Загрузка…
Ссылка в новой задаче