Home | History | Annotate | Download | only in analysis
      1 // Copyright (c) 2013 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 Displays an analysis of the selection.
      9  */
     10 base.requireStylesheet('tracing.analysis.analysis_view');
     11 
     12 base.require('base.guid');
     13 base.require('tracing.analysis.analysis_results');
     14 base.require('tracing.analysis.analyze_selection');
     15 base.require('tracing.analysis.default_object_view');
     16 base.require('tracing.analysis.object_instance_view');
     17 base.require('tracing.analysis.object_snapshot_view');
     18 base.require('tracing.analysis.slice_view');
     19 base.require('tracing.analysis.util');
     20 base.require('ui');
     21 base.exportTo('tracing.analysis', function() {
     22 
     23   var AnalysisView = ui.define('div');
     24 
     25   AnalysisView.prototype = {
     26     __proto__: HTMLDivElement.prototype,
     27 
     28     decorate: function() {
     29       this.className = 'analysis-view';
     30 
     31       this.currentView_ = undefined;
     32       this.currentSelection_ = undefined;
     33       this.selections_ = [];
     34       this.guid_ = base.GUID.allocate();
     35 
     36       window.addEventListener('popstate', this.onPopState.bind(this));
     37     },
     38 
     39     changeViewType: function(viewType) {
     40       if (this.currentView_ instanceof viewType)
     41         return;
     42       this.textContent = '';
     43       try {
     44         this.currentView_ = new viewType();
     45         this.appendChild(this.currentView_);
     46       } catch (e) {
     47         this.currentView_ = undefined;
     48         throw e;
     49       }
     50       if (this.currentView_ instanceof tracing.analysis. AnalysisResults)
     51         this.classList.remove('viewing-object');
     52       else
     53         this.classList.add('viewing-object');
     54     },
     55 
     56     get currentView() {
     57       return this.currentView_;
     58     },
     59 
     60     get selection() {
     61       return this.currentSelection_;
     62     },
     63 
     64     set selection(selection) {
     65       this.selections_.push(selection);
     66 
     67       var state = {
     68         view_guid: this.guid_,
     69         selection_guid: selection.guid
     70       };
     71       window.history.pushState(state);
     72 
     73       this.processSelection(selection);
     74     },
     75 
     76     clearSelectionHistory: function() {
     77       this.selections_ = [];
     78     },
     79 
     80     onPopState: function(event) {
     81       if ((event.state === null) ||
     82           (event.state.view_guid !== this.guid_))
     83         return;
     84 
     85       var idx;
     86       for (idx = 0; idx < this.selections_.length; ++idx) {
     87         if (this.selections_[idx].guid === event.state.selection_guid)
     88           break;
     89       }
     90 
     91       if (idx >= this.selections_.length)
     92         return;
     93 
     94       this.processSelection(this.selections_[idx]);
     95       event.stopPropagation();
     96     },
     97 
     98     processSelection: function(selection) {
     99       var hitsByType = selection.getHitsOrganizedByType();
    100       if (selection.length == 1 &&
    101           hitsByType.counterSamples.length == 0) {
    102         if (this.tryToProcessSelectionUsingCustomViewer(selection[0]))
    103           return;
    104       }
    105 
    106       this.changeViewType(tracing.analysis.AnalysisResults);
    107       this.currentView.clear();
    108       this.currentSelection_ = selection;
    109       tracing.analysis.analyzeHitsByType(this.currentView, hitsByType);
    110     },
    111 
    112     tryToProcessSelectionUsingCustomViewer: function(hit) {
    113       var obj;
    114       var typeName;
    115       var viewBaseType;
    116       var defaultViewType;
    117       var viewProperty;
    118       var obj = hit.modelObject;
    119       if (hit instanceof tracing.SelectionObjectSnapshotHit) {
    120         typeName = obj.objectInstance.typeName;
    121         viewBaseType = tracing.analysis.ObjectSnapshotView;
    122         defaultViewType = tracing.analysis.DefaultObjectSnapshotView;
    123       } else if (hit instanceof tracing.SelectionObjectInstanceHit) {
    124         typeName = obj.typeName;
    125         viewBaseType = tracing.analysis.ObjectInstanceView;
    126         defaultViewType = tracing.analysis.DefaultObjectInstanceView;
    127       } else if (hit instanceof tracing.SelectionSliceHit) {
    128         typeName = obj.title;
    129         viewBaseType = tracing.analysis.SliceView;
    130         defaultViewType = undefined;
    131       } else {
    132         return false;
    133       }
    134 
    135       var customViewInfo = viewBaseType.getViewInfo(typeName);
    136 
    137       var viewType = customViewInfo ?
    138           customViewInfo.constructor : defaultViewType;
    139 
    140       // Some view types don't have default viewers. In those cases, we fall
    141       // back to the standard analysis sytem.
    142       if (!viewType)
    143         return false;
    144 
    145       this.changeViewType(viewType);
    146       this.currentView.modelObject = obj;
    147       return true;
    148     }
    149   };
    150 
    151   return {
    152     AnalysisView: AnalysisView
    153   };
    154 });
    155