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