1<!DOCTYPE html>
2<html>
3<!--
4Copyright (c) 2011 The Chromium Authors. All rights reserved.
5Use of this source code is governed by a BSD-style license that can be
6found in the LICENSE file.
7-->
8<head>
9<title>Simple Embedded Viewer</title>
10<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
11
12<script src="/components/webcomponentsjs/webcomponents.js"></script>
13
14<link rel="import" href="/components/polymer/polymer.html">
15<link rel="import" href="/tracing/base/timing.html">
16<link rel="import" href="/tracing/base/xhr.html">
17<link rel="import" href="/tracing/importer/import.html">
18<link rel="import" href="/tracing/ui/extras/full_config.html">
19<link rel="import" href="/tracing/ui/timeline_view.html">
20
21<style>
22  html,
23  body {
24    height: 100%;
25  }
26
27  body {
28    -webkit-flex-direction: column;
29    display: -webkit-flex;
30    margin: 0;
31    padding: 0;
32  }
33
34  body > tr-ui-timeline-view {
35    -webkit-flex: 1 1 auto;
36    min-height: 0;
37  }
38  body > tr-ui-timeline-view:focus {
39    outline: none;
40  }
41</style>
42</head>
43<body>
44  <tr-ui-timeline-view>
45    <track-view-container id='track_view_container'></track-view-container>
46  </tr-ui-timeline-view>
47
48  <script>
49  'use strict';
50
51  var Timing = tr.b.Timing;
52  var timelineViewEl;
53  var selectEl;
54
55  function loadTraces(filenames, onTracesLoaded) {
56    var loadTracesMakedTimer = Timing.mark('TraceImport', 'loadTraces');
57    var traces = [];
58    for (var i = 0; i < filenames.length; i++) {
59      traces.push(undefined);
60    }
61    var numTracesPending = filenames.length;
62
63    filenames.forEach(function(filename, i) {
64      getAsync(filename, function(trace) {
65        traces[i] = trace;
66        numTracesPending--;
67        if (numTracesPending == 0) {
68          loadTracesMakedTimer.end();
69          onTracesLoaded(filenames, traces);
70        }
71      });
72    });
73  }
74
75
76  function getAsync(url, cb) {
77    return tr.b.getAsync(url).then(cb);
78  }
79
80  function createViewFromTraces(filenames, traces) {
81    var createViewFromTracesTimer = Timing.mark(
82        'TraceImport', 'createViewFromTraces');
83    var m = new tr.Model();
84
85    var trackDetailedModelStatsEl =
86        tr.b.findDeepElementMatching(document.body,
87                                     '#track-detailed-model-stats');
88    var importOptions = new tr.importer.ImportOptions();
89    importOptions.trackDetailedModelStats = trackDetailedModelStatsEl.checked;
90    var i = new tr.importer.Import(m, importOptions);
91    var p = i.importTracesWithProgressDialog(traces);
92
93    p.then(
94      function() {
95        timelineViewEl.model = m;
96        timelineViewEl.updateDocumentFavicon();
97        timelineViewEl.globalMode = true;
98        timelineViewEl.viewTitle = '';
99        createViewFromTracesTimer.end();
100      },
101      function(err) {
102        var overlay = new tr.ui.b.Overlay();
103        overlay.textContent = tr.b.normalizeException(err).message;
104        overlay.title = 'Import error';
105        overlay.visible = true;
106        createViewFromTracesTimer.end();
107      });
108  }
109
110  function onSelectionChange() {
111    window.location.hash = '#' + selectEl[selectEl.selectedIndex].value;
112  }
113
114  function onHashChange() {
115    var file = window.location.hash.substr(1);
116    if (selectEl[selectEl.selectedIndex].value != file) {
117      for (var i = 0; i < selectEl.children.length; i++) {
118        if (selectEl.children[i].value === file) {
119          selectEl.selectedIndex = i;
120          break;
121        }
122      }
123    }
124    reload();
125  }
126
127  function cleanFilename(file) {
128    var m = /\/tracing\/test_data\/(.+)/.exec(file);
129    var rest = m[1];
130
131    function upcase(letter) {
132      return ' ' + letter.toUpperCase();
133    }
134
135    return rest.replace(/_/g, ' ')
136               .replace(/\.[^\.]*$/, '')
137               .replace(/ ([a-z])/g, upcase)
138               .replace(/^[a-z]/, upcase);
139  }
140
141  function reload() {
142    loadTraces([window.location.hash.substr(1)], createViewFromTraces);
143  }
144
145  window.addEventListener('hashchange', onHashChange);
146
147  function onLoad() {
148    var onLoadTimer = Timing.mark('TraceImport', 'onLoad');
149    timelineViewEl = document.querySelector('tr-ui-timeline-view');
150    timelineViewEl.globalMode = true;
151
152
153    selectEl = document.createElement('select');
154    timelineViewEl.leftControls.appendChild(selectEl);
155
156    getAsync('/tracing/test_data/__file_list__', function(data) {
157      var files = JSON.parse(data);
158      for (var i = 0; i < files.length; ++i) {
159        var opt = document.createElement('option');
160        opt.value = files[i];
161        opt.textContent = cleanFilename(files[i]);
162        selectEl.appendChild(opt);
163      }
164      selectEl.selectedIndex = 0;
165      selectEl.onchange = onSelectionChange;
166
167      if (!window.location.hash) {
168        // This will trigger an onHashChange so no need to reload directly.
169        window.location.hash = '#' + selectEl[selectEl.selectedIndex].value;
170      } else {
171        onHashChange();
172      }
173    }).then(onLoadTimer.end.call(this));
174
175    var trackDetailedModelStatsEl = tr.ui.b.createCheckBox(
176        this, 'trackDetailedModelStats',
177        'traceViewer.trackDetailedModelStats', false,
178        'Detailed file size stats',
179        onHashChange);
180    trackDetailedModelStatsEl.id = 'track-detailed-model-stats';
181    timelineViewEl.leftControls.appendChild(trackDetailedModelStatsEl);
182  }
183
184  window.addEventListener('load', onLoad);
185  </script>
186</body>
187</html>
188