Index: tracing/tracing/ui/analysis/analysis_view.html |
diff --git a/tracing/tracing/ui/analysis/analysis_view.html b/tracing/tracing/ui/analysis/analysis_view.html |
index 677ec7a30039941c4e3f7d786da1b0a7f0c60e6b..d5724aa70bc4958577e5870e29acfeae758a94bb 100644 |
--- a/tracing/tracing/ui/analysis/analysis_view.html |
+++ b/tracing/tracing/ui/analysis/analysis_view.html |
@@ -79,25 +79,73 @@ using custom elements specialized for different event types. |
(function() { |
var EventRegistry = tr.model.EventRegistry; |
+ /** Returns the label that goes next to the list of tabs. */ |
+ function getTabStripLabel(numEvents) { |
+ if (numEvents === 0) |
+ return 'Nothing selected. Tap stuff.'; |
+ else if (numEvents === 1) |
+ return '1 item selected.'; |
+ return numEvents + ' items selected.'; |
+ } |
+ |
+ /** |
+ * Returns the tab label for the analysis sub-view associated with the |
+ * specified event type and number of events. |
+ */ |
+ function getTabLabel(eventTypeName, numEvents) { |
+ var camelLabel = numEvents === 1 ? |
+ EventRegistry.getUserFriendlySingularName(eventTypeName) : |
+ EventRegistry.getUserFriendlyPluralName(eventTypeName); |
+ return camelLabel + ' (' + numEvents + ')'; |
+ } |
+ |
+ /** |
+ * Returns the HTML tag for the analysis sub-view associated with the |
+ * specified event type and number of events. |
+ */ |
+ function getSubViewTagName(eventTypeName, numEvents) { |
+ var eventTypeInfo = |
+ EventRegistry.getEventTypeInfoByTypeName(eventTypeName); |
+ return numEvents === 1 ? |
+ eventTypeInfo.metadata.singleViewElementName : |
+ eventTypeInfo.metadata.multiViewElementName; |
+ } |
+ |
+ /** |
+ * Returns a new analysis sub-view for the selection and throws an error if no |
+ * such sub-view exists. |
+ */ |
+ function createSubView(eventTypeName, selection) { |
+ var subView = document.createElement( |
+ getSubViewTagName(eventTypeName, selection.length)); |
+ |
+ // Unregistered elements with valid names (i.e. names that have a hyphen |
+ // in them) inherit from HTMLElement. Unregistered elements with |
+ // invalid names inherit from HTMLUnknownElement. |
+ if (subView.constructor === HTMLElement || |
+ subView.constructor === HTMLUnknownElement) |
+ throw new Error('Element not registered: ' + tagName); |
+ |
+ subView.tabLabel = getTabLabel(eventTypeName, selection.length); |
+ subView.selection = selection; |
+ return subView; |
+ } |
+ |
Polymer({ |
is: 'tr-ui-a-analysis-view', |
ready: function() { |
- this.tabView_ = document.createElement('tr-ui-a-tab-view'); |
- this.tabView_.style.flex = '1 1 auto'; |
- Polymer.dom(this).appendChild(this.tabView_); |
this.brushingStateController_ = undefined; |
- this.onSelectedTabChange_ = this.onSelectedTabChange_.bind(this); |
- this.onSelectionChanged_ = this.onSelectionChanged_.bind(this); |
+ this.lastSelection_ = undefined; |
+ this.tabView_ = document.createElement('tr-ui-a-tab-view'); |
+ this.tabView_.addEventListener( |
+ 'selected-tab-change', this.onSelectedSubViewChanged_.bind(this)); |
- this.lastSeenSelection_ = new tr.model.EventSet(); |
+ Polymer.dom(this).appendChild(this.tabView_); |
}, |
set tallMode(value) { |
- if (value) |
- Polymer.dom(this).classList.add('tall-mode'); |
- else |
- Polymer.dom(this).classList.remove('tall-mode'); |
+ Polymer.dom(this).classList.toggle('tall-mode', value); |
}, |
get tallMode() { |
@@ -113,15 +161,19 @@ using custom elements specialized for different event types. |
}, |
set brushingStateController(brushingStateController) { |
- if (this.brushingStateController) { |
+ if (this.brushingStateController_) { |
this.brushingStateController_.removeEventListener( |
- 'change', this.onSelectionChanged_); |
+ 'change', this.onSelectionChanged_.bind(this)); |
} |
+ |
this.brushingStateController_ = brushingStateController; |
if (this.brushingStateController) { |
this.brushingStateController_.addEventListener( |
- 'change', this.onSelectionChanged_); |
+ 'change', this.onSelectionChanged_.bind(this)); |
} |
+ |
+ // The new brushing controller may have a different selection than the |
+ // last one, so we have to refresh the subview. |
this.onSelectionChanged_(); |
}, |
@@ -130,131 +182,40 @@ using custom elements specialized for different event types. |
}, |
onSelectionChanged_: function(e) { |
- var selection = this.brushingStateController_.selection; |
- |
- var selectionHasSameValue = this.lastSeenSelection_.equals(selection); |
- this.lastSeenSelection_ = selection; |
- if (selectionHasSameValue) |
+ if (this.lastSelection_ && this.selection.equals(this.lastSelection_)) |
return; |
- |
- var lastSelectedTabTagName; |
- var lastSelectedTabTypeName; |
- if (this.tabView_.selectedTab) { |
- lastSelectedTabTagName = this.tabView_.selectedTab.tagName; |
- lastSelectedTabTypeName = this.tabView_.selectedTab._eventTypeName; |
- } |
+ this.lastSelection_ = this.selection; |
this.tallMode = false; |
+ this.tabView_.clearSubViews(); |
- var previouslySelectedTab = this.tabView_.selectedTab; |
- this.tabView_.removeEventListener( |
- 'selected-tab-change', this.onSelectedTabChange_); |
- |
- var previousSubViews = {}; |
- for (var i = 0; i < Polymer.dom(this.tabView_).children.length; i++) { |
- var previousSubView = Polymer.dom(this.tabView_).children[i]; |
- previousSubViews[previousSubView._eventTypeName] = previousSubView; |
- } |
- |
- this.tabView_.saveTabStates(); |
- Polymer.dom(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 = tr.b.dictionaryLength(eventsByBaseTypeName); |
- for (var eventTypeName in eventsByBaseTypeName) { |
- var subSelection = eventsByBaseTypeName[eventTypeName]; |
- var subView = this.createSubViewForSelection_( |
- eventTypeName, subSelection, previousSubViews[eventTypeName]); |
- // Store the eventTypeName for future tab restoration. |
- subView._eventTypeName = eventTypeName; |
- Polymer.dom(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 = Polymer.dom(this.tabView_).querySelector(lastSelectedTabTagName); |
- |
- // If that fails, look for a tab with that typeName. |
- if (!tab && lastSelectedTabTypeName) { |
- var tab = tr.b.findFirstInArray( |
- Polymer.dom(this.tabView_).children, function(tab) { |
- return tab._eventTypeName === lastSelectedTabTypeName; |
- }); |
- } |
- // If all else fails, pick the first tab. |
- if (!tab) |
- tab = Polymer.dom(this.tabView_).firstChild; |
- |
- this.tabView_.selectedTab = tab; |
- this.onSelectedTabChange_(); |
+ this.tabView_.label = getTabStripLabel(this.selection.length); |
+ var eventsByBaseTypeName = |
+ this.selection.getEventsOrganizedByBaseType(true); |
- this.tabView_.addEventListener( |
- 'selected-tab-change', this.onSelectedTabChange_); |
+ tr.b.iterItems(eventsByBaseTypeName, function(eventTypeName, events) { |
+ var subView = createSubView(eventTypeName, events); |
+ this.tabView_.addSubView(subView); |
+ }, this); |
}, |
- createSubViewForSelection_: function(eventTypeName, subSelection, |
- previousSubView) { |
- // 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 (!tr.ui.b.getPolymerElementNamed(tagName)) |
- // throw new Error('Element not registered: ' + tagName); |
+ onSelectedSubViewChanged_: function() { |
+ var selectedSubView = this.tabView_.selectedSubView; |
- // Create if necessary. |
- var subView; |
- if (previousSubView && |
- previousSubView.tagName === tagName.toUpperCase()) |
- subView = previousSubView; |
- else |
- subView = document.createElement(tagName); |
- |
- if (subView.constructor === HTMLElement) |
- throw new Error('Element not registered: ' + tagName); |
- // Set label. |
- var camelLabel; |
- if (subSelection.length === 1) |
- camelLabel = EventRegistry.getUserFriendlySingularName(eventTypeName); |
- else |
- camelLabel = EventRegistry.getUserFriendlyPluralName(eventTypeName); |
- subView.tabLabel = camelLabel + ' (' + subSelection.length + ')'; |
+ if (!selectedSubView) { |
+ this.tallMode = false; |
+ this.maybeChangeRelatedEvents_(undefined); |
+ return; |
+ } |
- return subView; |
+ this.tallMode = selectedSubView.requiresTallView; |
+ this.maybeChangeRelatedEvents_(selectedSubView.relatedEventsToHighlight); |
}, |
- onSelectedTabChange_: function() { |
- var brushingStateController = this.brushingStateController_; |
- if (this.tabView_.selectedTab) { |
- var selectedTab = this.tabView_.selectedTab; |
- this.tallMode = selectedTab.requiresTallView; |
- if (brushingStateController) { |
- var rlth = selectedTab.relatedEventsToHighlight; |
- brushingStateController.changeAnalysisViewRelatedEvents(rlth); |
- } |
- } else { |
- this.tallMode = false; |
- if (brushingStateController) |
- brushingStateController.changeAnalysisViewRelatedEvents(undefined); |
- } |
+ /** Changes the highlighted related events if possible. */ |
+ maybeChangeRelatedEvents_: function(events) { |
+ if (this.brushingStateController) |
+ this.brushingStateController.changeAnalysisViewRelatedEvents(events); |
} |
}); |
})(); |