| <!DOCTYPE html> |
| <!-- |
| Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style license that can be |
| found in the LICENSE file. |
| --> |
| |
| <link rel="import" href="/base/polymer_utils.html"> |
| <link rel="import" href="/base/iteration_helpers.html"> |
| <link rel="import" href="/core/analysis/tab_view.html"> |
| <link rel="import" href="/core/analysis/analysis_sub_view.html"> |
| |
| <!-- Sub Views. --> |
| <link rel="import" href="/core/analysis/single_thread_slice_sub_view.html"> |
| <link rel="import" href="/core/analysis/multi_thread_slice_sub_view.html"> |
| |
| <link rel="import" href="/core/analysis/single_async_slice_sub_view.html"> |
| <link rel="import" href="/core/analysis/multi_async_slice_sub_view.html"> |
| |
| <link rel="import" href="/core/analysis/single_cpu_slice_sub_view.html"> |
| <link rel="import" href="/core/analysis/multi_cpu_slice_sub_view.html"> |
| |
| <link rel="import" href="/core/analysis/single_thread_time_slice_sub_view.html"> |
| <link rel="import" href="/core/analysis/multi_thread_time_slice_sub_view.html"> |
| |
| <link rel="import" href="/core/analysis/single_instant_event_sub_view.html"> |
| <link rel="import" href="/core/analysis/multi_instant_event_sub_view.html"> |
| |
| <link rel="import" href="/core/analysis/counter_sample_sub_view.html"> |
| |
| <link rel="import" href="/core/analysis/single_flow_event_sub_view.html"> |
| <link rel="import" href="/core/analysis/multi_flow_event_sub_view.html"> |
| |
| <link rel="import" href="/core/analysis/single_object_instance_sub_view.html"> |
| <link rel="import" href="/core/analysis/single_object_snapshot_sub_view.html"> |
| <link rel="import" href="/core/analysis/multi_object_sub_view.html"> |
| |
| <link rel="import" href="/core/analysis/single_sample_sub_view.html"> |
| <link rel="import" href="/core/analysis/multi_sample_sub_view.html"> |
| |
| <link rel="import" |
| href="/core/analysis/single_interaction_record_sub_view.html"> |
| <link rel="import" |
| href="/core/analysis/multi_interaction_record_sub_view.html"> |
| |
| <link rel="import" href="/core/analysis/alert_sub_view.html"> |
| |
| <link rel="import" |
| href="/core/analysis/single_frame_sub_view.html"> |
| <link rel="import" |
| href="/core/analysis/multi_frame_sub_view.html"> |
| |
| <link rel="import" |
| href="/core/analysis/single_process_memory_dump_sub_view.html"> |
| <link rel="import" |
| href="/core/analysis/multi_process_memory_dump_sub_view.html"> |
| <link rel="import" |
| href="/core/analysis/single_global_memory_dump_sub_view.html"> |
| <link rel="import" href="/core/analysis/multi_global_memory_dump_sub_view.html"> |
| |
| <!-- |
| @fileoverview A component used to display an analysis of a selection, |
| using custom elements specialized for different event types. |
| --> |
| <polymer-element name="tv-c-a-analysis-view"> |
| <template> |
| <style> |
| :host { |
| background-color: white; |
| display: flex; |
| flex-direction: column; |
| height: 275px; |
| overflow: auto; |
| } |
| |
| :host(.tall-mode) { |
| height: 525px; |
| } |
| |
| ::content > * { |
| flex: 1 0 auto; |
| } |
| </style> |
| <content></content> |
| </template> |
| <script> |
| 'use strict'; |
| (function() { |
| var EventRegistry = tv.c.trace_model.EventRegistry; |
| |
| Polymer({ |
| ready: function() { |
| this.tabView_ = document.createElement( |
| 'tracing-analysis-tab-view'); |
| this.tabView_.style.flex = '1 1 auto'; |
| this.appendChild(this.tabView_); |
| this.selectionController_ = undefined; |
| this.onSelectedTabChange_ = this.onSelectedTabChange_.bind(this); |
| this.onSelectionChanged_ = this.onSelectionChanged_.bind(this); |
| |
| this.lastSeenSelection_ = new tv.c.Selection(); |
| }, |
| |
| set tallMode(value) { |
| if (value) |
| this.classList.add('tall-mode'); |
| else |
| this.classList.remove('tall-mode'); |
| }, |
| |
| get tallMode() { |
| return this.classList.contains('tall-mode'); |
| }, |
| |
| get tabView() { |
| return this.tabView_; |
| }, |
| |
| get selectionController() { |
| return this.selectionController_; |
| }, |
| |
| set selectionController(selectionController) { |
| if (this.selectionController) { |
| this.selectionController_.removeEventListener( |
| 'change', this.onSelectionChanged_); |
| } |
| this.selectionController_ = selectionController; |
| if (this.selectionController) { |
| this.selectionController_.addEventListener( |
| 'change', this.onSelectionChanged_); |
| } |
| this.onSelectionChanged_(); |
| }, |
| |
| get selection() { |
| return this.selectionController_.selection; |
| }, |
| |
| onSelectionChanged_: function(e) { |
| var selection = this.selectionController_.selection; |
| |
| var selectionHasSameValue = this.lastSeenSelection_.equals(selection); |
| this.lastSeenSelection_ = selection; |
| if (selectionHasSameValue) |
| return; |
| |
| var lastSelectedTabTagName; |
| var lastSelectedTabTypeName; |
| if (this.tabView_.selectedTab) { |
| lastSelectedTabTagName = this.tabView_.selectedTab.tagName; |
| lastSelectedTabTypeName = this.tabView_.selectedTab._eventTypeName; |
| } |
| |
| this.tallMode = false; |
| |
| var previouslySelectedTab = this.tabView_.selectedTab; |
| this.tabView_.removeEventListener( |
| 'selected-tab-change', this.onSelectedTabChange_); |
| this.tabView_.textContent = ''; |
| if (selection.length == 0) { |
| this.tabView_.tabStripHeadingText = 'Nothing selected. Tap stuff.'; |
| } else if (selection.length == 1) { |
| this.tabView_.tabStripHeadingText = '1 item selected: '; |
| } else { |
| this.tabView_.tabStripHeadingText = selection.length + |
| ' items selected: '; |
| } |
| |
| var eventsByBaseTypeName = selection.getEventsOrganizedByBaseType(true); |
| |
| var numBaseTypesToAnalyze = tv.b.dictionaryLength(eventsByBaseTypeName); |
| for (var eventTypeName in eventsByBaseTypeName) { |
| var subSelection = eventsByBaseTypeName[eventTypeName]; |
| var subView = this.createSubViewForSelection_( |
| eventTypeName, subSelection); |
| // Store the eventTypeName for future tab restoration. |
| subView._eventTypeName = eventTypeName; |
| this.tabView_.appendChild(subView); |
| |
| subView.selection = subSelection; |
| } |
| |
| // Restore the tab type that was previously selected. First try by tag |
| // name. |
| var tab; |
| if (lastSelectedTabTagName) |
| tab = this.tabView_.querySelector(lastSelectedTabTagName); |
| |
| // If that fails, look for a tab with that typeName. |
| if (!tab && lastSelectedTabTypeName) { |
| var tab = tv.b.findFirstInArray( |
| this.tabView_.children, function(tab) { |
| return tab._eventTypeName === lastSelectedTabTypeName; |
| }); |
| } |
| // If all else fails, pick the first tab. |
| if (!tab) |
| tab = this.tabView_.firstChild; |
| |
| this.tabView_.selectedTab = tab; |
| if (this.tabView_.selectedTab !== previouslySelectedTab) |
| this.onSelectedTabChange_(); |
| |
| this.tabView_.addEventListener( |
| 'selected-tab-change', this.onSelectedTabChange_); |
| }, |
| |
| createSubViewForSelection_: function(eventTypeName, subSelection) { |
| // Find. |
| var eventTypeInfo = EventRegistry.getEventTypeInfoByTypeName( |
| eventTypeName); |
| var singleMode = subSelection.length == 1; |
| var tagName; |
| if (subSelection.length === 1) |
| tagName = eventTypeInfo.metadata.singleViewElementName; |
| else |
| tagName = eventTypeInfo.metadata.multiViewElementName; |
| |
| if (!tv.b.getPolymerElementNamed(tagName)) |
| throw new Error('Element not registered: ' + tagName); |
| |
| // Create. |
| var subView = document.createElement(tagName); |
| |
| // Set label. |
| var camelLabel; |
| if (subSelection.length === 1) |
| camelLabel = EventRegistry.getUserFriendlySingularName(eventTypeName); |
| else |
| camelLabel = EventRegistry.getUserFriendlyPluralName(eventTypeName); |
| subView.tabLabel = camelLabel + ' (' + subSelection.length + ')'; |
| |
| return subView; |
| }, |
| |
| onSelectedTabChange_: function() { |
| var selectionController = this.selectionController_; |
| if (this.tabView_.selectedTab) { |
| var selectedTab = this.tabView_.selectedTab; |
| this.tallMode = selectedTab.requiresTallView; |
| if (selectionController) { |
| var rlth = selectedTab.relatedEventsToHighlight; |
| selectionController.changeAnalysisViewRelatedEvents(rlth); |
| } |
| } else { |
| this.tallMode = false; |
| if (selectionController) |
| selectionController.changeAnalysisViewRelatedEvents(undefined); |
| } |
| } |
| }); |
| })(); |
| </script> |
| </polymer-element> |