Home | History | Annotate | Download | only in src
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 'use strict';
      6 
      7 /**
      8  * @fileoverview ProfilingView glues the TimelineView control to
      9  * TracingController.
     10  */
     11 base.requireStylesheet('profiling_view');
     12 base.require('timeline_view');
     13 base.require('tracing_controller');
     14 base.exportTo('tracing', function() {
     15   /**
     16    * ProfilingView
     17    * @constructor
     18    * @extends {HTMLDivElement}
     19    */
     20   var ProfilingView = base.ui.define('div');
     21 
     22   ProfilingView.prototype = {
     23     __proto__: HTMLDivElement.prototype,
     24 
     25     traceEvents_: [],
     26     systemTraceEvents_: [],
     27 
     28     decorate: function() {
     29       this.classList.add('profiling-view');
     30 
     31       // make the <list>/add/save/record element
     32       this.recordBn_ = document.createElement('button');
     33       this.recordBn_.className = 'record';
     34       this.recordBn_.textContent = 'Record';
     35       this.recordBn_.addEventListener('click', this.onRecord_.bind(this));
     36 
     37       this.saveBn_ = document.createElement('button');
     38       this.saveBn_.textContent = 'Save';
     39       this.saveBn_.addEventListener('click', this.onSave_.bind(this));
     40 
     41       this.loadBn_ = document.createElement('button');
     42       this.loadBn_.textContent = 'Load';
     43       this.loadBn_.addEventListener('click', this.onLoad_.bind(this));
     44 
     45       this.systemTracingBn_ = document.createElement('input');
     46       this.systemTracingBn_.type = 'checkbox';
     47       this.systemTracingBn_.checked = false;
     48 
     49       this.systemTracingLabelEl_ = document.createElement('label');
     50       this.systemTracingLabelEl_.textContent = 'System events';
     51       this.systemTracingLabelEl_.appendChild(this.systemTracingBn_);
     52       this.systemTracingLabelEl_.style.display = 'none';
     53       this.systemTracingLabelEl_.style.marginLeft = '16px';
     54 
     55       this.timelineView_ = new tracing.TimelineView();
     56       this.timelineView_.leftControls.appendChild(this.recordBn_);
     57       this.timelineView_.leftControls.appendChild(this.saveBn_);
     58       this.timelineView_.leftControls.appendChild(this.loadBn_);
     59       this.timelineView_.leftControls.appendChild(this.systemTracingLabelEl_);
     60 
     61       this.appendChild(this.timelineView_);
     62 
     63       document.addEventListener('keypress', this.onKeypress_.bind(this));
     64 
     65       this.refresh_();
     66     },
     67 
     68     didSetTracingController_: function(value, oldValue) {
     69       if (oldValue)
     70         throw new Error('Can only set tracing controller once.');
     71 
     72       if (this.tracingController_.supportsSystemTracing) {
     73         this.systemTracingLabelEl_.style.display = 'block';
     74         this.systemTracingBn_.checked = true;
     75       } else {
     76         this.systemTracingLabelEl_.style.display = 'none';
     77       }
     78 
     79       this.refresh_();
     80     },
     81 
     82     refresh_: function() {
     83       if (!this.tracingController_)
     84         return;
     85 
     86       var traceEvents = this.tracingController_.traceEvents;
     87       var hasEvents = traceEvents && traceEvents.length;
     88 
     89       this.saveBn_.disabled = !hasEvents;
     90 
     91       if (!hasEvents) return;
     92 
     93       var traces = [traceEvents];
     94       if (this.tracingController_.systemTraceEvents.length)
     95         traces.push(this.tracingController_.systemTraceEvents);
     96 
     97       var m = new tracing.TimelineModel();
     98       m.importTraces(traces, true);
     99       this.timelineView_.model = m;
    100     },
    101 
    102     onKeypress_: function(event) {
    103       if (event.keyCode == 114 && !this.tracingController_.isTracingEnabled &&
    104           document.activeElement.nodeName != 'INPUT') {
    105         this.onRecord_();
    106       }
    107     },
    108 
    109     get timelineView() {
    110       return this.timelineView_;
    111     },
    112 
    113     ///////////////////////////////////////////////////////////////////////////
    114 
    115     onRecord_: function() {
    116       var that = this;
    117       var tc = this.tracingController_;
    118       tc.beginTracing(this.systemTracingBn_.checked);
    119       function response() {
    120         that.refresh_();
    121         setTimeout(function() {
    122           tc.removeEventListener('traceEnded', response);
    123         }, 0);
    124       }
    125       tc.addEventListener('traceEnded', response);
    126     },
    127 
    128     ///////////////////////////////////////////////////////////////////////////
    129 
    130     onSave_: function() {
    131       this.overlayEl_ = new tracing.Overlay();
    132       this.overlayEl_.className = 'profiling-overlay';
    133 
    134       var labelEl = document.createElement('div');
    135       labelEl.className = 'label';
    136       labelEl.textContent = 'Saving...';
    137       this.overlayEl_.appendChild(labelEl);
    138       this.overlayEl_.visible = true;
    139 
    140       var that = this;
    141       var tc = this.tracingController_;
    142       function response() {
    143         that.overlayEl_.visible = false;
    144         that.overlayEl_ = undefined;
    145         setTimeout(function() {
    146           tc.removeEventListener('saveTraceFileComplete', response);
    147           tc.removeEventListener('saveTraceFileCanceled', response);
    148         }, 0);
    149       }
    150       tc.addEventListener('saveTraceFileComplete', response);
    151       tc.addEventListener('saveTraceFileCanceled', response);
    152       tc.beginSaveTraceFile();
    153     },
    154 
    155     ///////////////////////////////////////////////////////////////////////////
    156 
    157     onLoad_: function() {
    158       this.overlayEl_ = new tracing.Overlay();
    159       this.overlayEl_.className = 'profiling-overlay';
    160 
    161       var labelEl = document.createElement('div');
    162       labelEl.className = 'label';
    163       labelEl.textContent = 'Loading...';
    164       this.overlayEl_.appendChild(labelEl);
    165       this.overlayEl_.visible = true;
    166 
    167       var that = this;
    168       var tc = this.tracingController_;
    169       this.tracingController_.beginLoadTraceFile();
    170       function response(e) {
    171         that.overlayEl_.visible = false;
    172         that.overlayEl_ = undefined;
    173         if (e.type == 'loadTraceFileComplete')
    174           that.refresh_();
    175         setTimeout(function() {
    176           tc.removeEventListener('loadTraceFileComplete', response);
    177           tc.removeEventListener('loadTraceFileCanceled', response);
    178         }, 0);
    179       }
    180 
    181       tc.addEventListener('loadTraceFileComplete', response);
    182       tc.addEventListener('loadTraceFileCanceled', response);
    183     }
    184   };
    185 
    186   base.defineProperty(ProfilingView, 'tracingController', base.PropertyKind.JS,
    187       ProfilingView.prototype.didSetTracingController_);
    188 
    189   return {
    190     ProfilingView: ProfilingView
    191   };
    192 });
    193