Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(704)

Unified Diff: chrome/browser/resources/tracing/timeline.js

Issue 8359025: Tons of timeline tweaks (Closed)
Patch Set: Fixen Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/tracing/timeline.js
diff --git a/chrome/browser/resources/tracing/timeline.js b/chrome/browser/resources/tracing/timeline.js
index eecf3ab0063d5d1323fa12dfc5ee10e3b1af2691..6479a5f4bcce2be78d64a7092ed5c44680c0c08c 100644
--- a/chrome/browser/resources/tracing/timeline.js
+++ b/chrome/browser/resources/tracing/timeline.js
@@ -167,13 +167,17 @@ cr.define('tracing', function() {
this.dragBox_ = this.ownerDocument.createElement('div');
this.dragBox_.className = 'timeline-drag-box';
this.appendChild(this.dragBox_);
+ this.hideDragBox_();
// The following code uses a setInterval to monitor the timeline control
// for size changes. This is so that we can keep the canvas' bitmap size
// correctly synchronized with its presentation size.
// TODO(nduca): detect this in a more efficient way, e.g. iframe hack.
this.lastSize_ = this.clientWidth + 'x' + this.clientHeight;
- this.ownerDocument.defaultView.setInterval(function() {
+ this.checkForResizeInterval_ =
+ this.ownerDocument.defaultView.setInterval(function() {
+ if (!this.isAttachedToDocument_)
+ return;
var curSize = this.clientWidth + 'x' + this.clientHeight;
if (this.clientWidth && curSize != this.lastSize_) {
this.lastSize_ = curSize;
@@ -181,18 +185,43 @@ cr.define('tracing', function() {
}
}.bind(this), 250);
- document.addEventListener('keypress', this.onKeypress_.bind(this));
- document.addEventListener('keydown', this.onKeydown_.bind(this));
- document.addEventListener('mousedown', this.onMouseDown_.bind(this));
- document.addEventListener('mousemove', this.onMouseMove_.bind(this));
- document.addEventListener('mouseup', this.onMouseUp_.bind(this));
- document.addEventListener('dblclick', this.onDblClick_.bind(this));
+ this.bindEventListener_(document, 'keypress', this.onKeypress_, this);
+ this.bindEventListener_(document, 'keydown', this.onKeydown_, this);
+ this.bindEventListener_(document, 'mousedown', this.onMouseDown_, this);
+ this.bindEventListener_(document, 'mousemove', this.onMouseMove_, this);
+ this.bindEventListener_(document, 'mouseup', this.onMouseUp_, this);
+ this.bindEventListener_(document, 'dblclick', this.onDblClick_, this);
this.lastMouseViewPos_ = {x: 0, y: 0};
this.selection_ = [];
},
+ /**
+ * Wraps the stanard addEventListener but automatically binds the provided
James Hawkins 2011/11/10 01:06:13 s/stanard/standard/
nduca 2011/11/10 02:24:35 Done.
+ * func to the provided target, tracking the resulting closure. When detach
+ * is called, these listeners will be automatically removed.
+ */
+ bindEventListener_: function(object, event, func, target) {
+ if (!this.boundListeners_)
+ this.boundListeners_ = [];
+ var boundFunc = func.bind(target);
+ this.boundListeners_.push({object: object,
+ event: event,
+ boundFunc: boundFunc});
+ object.addEventListener(event, boundFunc);
+ },
+
+ detach: function() {
+ for (var i = 0; i < this.boundListeners_.length; ++i) {
+ var binding = this.boundListeners_[i];
+ binding.object.removeEventListener(binding.event, binding.boundFunc);
+ }
+ this.boundListeners_ = undefined;
+ window.clearInterval(this.checkForResizeInterval_);
+ this.checkForResizeInterval_ = undefined;
+ },
+
get model() {
return this.model_;
},
@@ -205,20 +234,44 @@ cr.define('tracing', function() {
}
this.model_ = model;
- // Create tracks.
- this.tracks_.textContent = '';
+ // Create tracks and measure their heading size.
var threads = model.getAllThreads();
- threads.sort(tracing.TimelineThread.compare);
+ var maxHeadingWidth = 0;
+ var tracks = [];
+ var measuringStick = new tracing.MeasuringStick();
+ var headingEl = document.createElement('div');
+ headingEl.style.position = 'fixed';
+ headingEl.className = 'timeline-slice-track-title';
for (var tI = 0; tI < threads.length; tI++) {
var thread = threads[tI];
var track = new TimelineThreadTrack();
track.thread = thread;
track.viewport = this.viewport_;
- this.tracks_.appendChild(track);
+ tracks.push(track);
+ headingEl.textContent = track.heading;
+ var w = measuringStick.measure(headingEl).width;
+ // Limit heading width to 300px.
+ if (w > 300)
+ w = 300;
+ if (w > maxHeadingWidth)
+ maxHeadingWidth = w;
+ }
+ maxHeadingWidth += maxHeadingWidth + 4;
James Hawkins 2011/11/10 01:06:13 What is the 4 about?
nduca 2011/11/10 02:24:35 Its some extra padding to make things look less cr
+ // Attach tracks and set width.
+ this.tracks_.textContent = '';
+ threads.sort(tracing.TimelineThread.compare);
+ for (var tI = 0; tI < tracks.length; tI++) {
+ var track = tracks[tI];
+ track.headingWidth = maxHeadingWidthWithUnit + 'px';
+ this.tracks_.appendChild(track);
}
- this.needsViewportReset_ = true;
+ if (this.isAttachedToDocument_) {
James Hawkins 2011/11/10 01:06:13 nit: No braces for single-line blocks.
nduca 2011/11/10 02:24:35 Done.
+ this.onResize();
+ } else {
+ this.needsViewportReset_ = true;
+ }
},
viewportChange_: function() {
@@ -229,27 +282,46 @@ cr.define('tracing', function() {
if (this.invalidatePending_)
return;
this.invalidatePending_ = true;
- window.setTimeout(function() {
- this.invalidatePending_ = false;
- this.redrawAllTracks_();
- }.bind(this), 0);
+ if (this.isAttachedToDocument_)
+ window.setTimeout(function() {
+ this.invalidatePending_ = false;
+ this.redrawAllTracks_();
+ }.bind(this), 0);
+ },
+
+ /**
+ * @return {boolean} Whether the current timeline is attached to the
+ * document.
+ */
+ get isAttachedToDocument_() {
+ var cur = this;
+ while (cur.parentNode)
+ cur = cur.parentNode;
+ return cur == this.ownerDocument;
},
onResize: function() {
+ if (!this.isAttachedToDocument_)
+ throw 'Not attached to document!';
for (var i = 0; i < this.tracks_.children.length; ++i) {
var track = this.tracks_.children[i];
track.onResize();
}
+ if (this.invalidatePending_) {
+ this.invalidatePending_ = false;
+ this.redrawAllTracks_();
+ }
},
redrawAllTracks_: function() {
if (this.needsViewportReset_ && this.clientWidth != 0) {
+ if (!this.isAttachedToDocument_)
+ throw 'Not attached to document!';
this.needsViewportReset_ = false;
/* update viewport */
var rangeTimestamp = this.model_.maxTimestamp -
this.model_.minTimestamp;
var w = this.firstCanvas.width;
- console.log('viewport was reset with w=', w);
var scaleX = w / rangeTimestamp;
var panX = -this.model_.minTimestamp;
this.viewport_.setPanAndScale(panX, scaleX);
@@ -266,10 +338,18 @@ cr.define('tracing', function() {
}
},
+ get listenToKeys_() {
+ if (this.parentElement.parentElement.tabIndex >= 0)
+ return document.activeElement == this.parentElement.parentElement;
+ return true;
+ },
+
onKeypress_: function(e) {
var vp = this.viewport_;
if (!this.firstCanvas)
return;
+ if (!this.listenToKeys_)
+ return;
var viewWidth = this.firstCanvas.clientWidth;
var curMouseV, curCenterW;
switch (e.keyCode) {
@@ -316,6 +396,8 @@ cr.define('tracing', function() {
// Not all keys send a keypress.
onKeydown_: function(e) {
+ if (!this.listenToKeys_)
+ return;
switch (e.keyCode) {
case 37: // left arrow
this.selectPrevious_(e);
@@ -326,11 +408,13 @@ cr.define('tracing', function() {
e.preventDefault();
break;
case 9: // TAB
- if (e.shiftKey)
- this.selectPrevious_(e);
- else
- this.selectNext_(e);
- e.preventDefault();
+ if (this.parentElement.parentElement.tabIndex == -1) {
+ if (e.shiftKey)
+ this.selectPrevious_(e);
+ else
+ this.selectNext_(e);
+ e.preventDefault();
+ }
break;
}
},
@@ -373,8 +457,8 @@ cr.define('tracing', function() {
for (i = 0; i < this.selection_.length; ++i) {
adjoining = undefined;
this.selection_[i].slice.selected = false;
- var track = this.selection_[i].track;
- var slice = this.selection_[i].slice;
+ track = this.selection_[i].track;
+ slice = this.selection_[i].slice;
if (slice) {
if (forwardp)
adjoining = track.pickNext(slice);
@@ -394,42 +478,55 @@ cr.define('tracing', function() {
},
get keyHelp() {
- return 'Keyboard shortcuts:\n' +
+ var help = 'Keyboard shortcuts:\n' +
' w/s : Zoom in/out (with shift: go faster)\n' +
' a/d : Pan left/right\n' +
' e : Center on mouse\n' +
- ' g/G : Shows grid at the start/end of the selected task\n' +
- ' <-,^TAB : Select previous event on current timeline\n' +
- ' ->, TAB : Select next event on current timeline\n' +
- '\n' +
- 'Dbl-click to zoom in; Shift dbl-click to zoom out\n';
+ ' g/G : Shows grid at the start/end of the selected task\n';
+ if (this.parentElement.parentElement.tabIndex)
James Hawkins 2011/11/10 01:06:13 nit: Multi-line blocks must have braces.
nduca 2011/11/10 02:24:35 Done.
+ help += ' <- : Select previous event on current timeline\n' +
+ ' -> : Select next event on current timeline\n';
+ else
+ help += ' <-,^TAB : Select previous event on current timeline\n' +
+ ' ->, TAB : Select next event on current timeline\n';
+ help +=
+ '\n' +
+ 'Dbl-click to zoom in; Shift dbl-click to zoom out\n';
+ return help;
},
get selection() {
return this.selection_;
},
+ set selection(var sel) {
+ // Clear old selection.
+ for (i = 0; i < this.selection_.length; ++i) {
James Hawkins 2011/11/10 01:06:13 nit: No braces for single-line blocks.
nduca 2011/11/10 02:24:35 Done.
+ this.selection_[i].slice.selected = false;
+ }
+
+ this.selection_ = sel;
+
+ this.selection_ = selection;
+ cr.dispatchSimpleEvent(this, 'selectionChange');
+ for (i = 0; i < this.selection_.length; ++i) {
James Hawkins 2011/11/10 01:06:13 nit: No braces for single-line blocks.
nduca 2011/11/10 02:24:35 Done.
+ this.selection_[i].slice.selected = true;
+ }
+ this.invalidate(); // Cause tracks to redraw.
+ }
+
get firstCanvas() {
return this.tracks_.firstChild ?
this.tracks_.firstChild.firstCanvas : undefined;
},
- showDragBox_: function() {
- this.dragBox_.hidden = false;
- },
-
hideDragBox_: function() {
this.dragBox_.style.left = '-1000px';
this.dragBox_.style.top = '-1000px';
this.dragBox_.style.width = 0;
this.dragBox_.style.height = 0;
- this.dragBox_.hidden = true;
- },
-
- get dragBoxVisible_() {
- return this.dragBox_.hidden == false;
},
setDragBoxPosition_: function(eDown, eCur) {
@@ -490,6 +587,8 @@ cr.define('tracing', function() {
this.dragBeginEvent_ = e;
e.preventDefault();
+ if (this.parentElement.parentElement.tabIndex)
+ this.parentElement.parentElement.focus();
},
onMouseMove_: function(e) {
@@ -504,12 +603,6 @@ cr.define('tracing', function() {
// Remember position. Used during keyboard zooming.
this.lastMouseViewPos_ = pos;
- // Initiate the drag box if needed.
- if (this.dragBeginEvent_ && !this.dragBoxVisible_) {
- this.showDragBox_();
- this.setDragBoxPosition_(e, e);
- }
-
// Update the drag box
if (this.dragBeginEvent_) {
this.setDragBoxPosition_(this.dragBeginEvent_, e);
@@ -535,11 +628,6 @@ cr.define('tracing', function() {
var loWX = this.viewport_.xViewToWorld(loX - canv.offsetLeft);
var hiWX = this.viewport_.xViewToWorld(hiX - canv.offsetLeft);
- // Clear old selection.
- for (i = 0; i < this.selection_.length; ++i) {
- this.selection_[i].slice.selected = false;
- }
-
// Figure out what has been hit.
var selection = [];
function addHit(type, track, slice) {
@@ -557,12 +645,7 @@ cr.define('tracing', function() {
}
}
// Activate the new selection.
- this.selection_ = selection;
- cr.dispatchSimpleEvent(this, 'selectionChange');
- for (i = 0; i < this.selection_.length; ++i) {
- this.selection_[i].slice.selected = true;
- }
- this.invalidate(); // Cause tracks to redraw.
+ this.selection = selection;
}
},

Powered by Google App Engine
This is Rietveld 408576698