Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / about_tracing / record_selection_dialog.html
1 <!DOCTYPE html>
2 <!--
3 Copyright (c) 2013 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
6 -->
7 <link rel="import" href="/tracing/filter.html">
8 <link rel="import" href="/tvcm/utils.html">
9 <link rel="import" href="/tvcm/ui/overlay.html">
10 <link rel="import" href="/tvcm/ui/dom_helpers.html">
11 <link rel="import" href="/tvcm/ui/info_bar.html">
12
13 <template id="record-selection-dialog-template">
14   <style>
15   .categories-column-view {
16     display: -webkit-flex;
17     -webkit-flex-direction: column;
18     font-family: sans-serif;
19     max-height: 420px;
20     max-width: 640px;
21     min-height: 0;
22     min-width: 0;
23     opacity: 1;
24     transition: max-height 1s ease, max-width 1s ease, opacity 1s ease;
25     will-change: opacity;
26   }
27
28   .categories-column-view-hidden {
29     max-height: 0;
30     max-width: 0;
31     opacity: 0;
32     overflow: hidden;
33   }
34
35   .categories-selection {
36     display: -webkit-flex;
37     -webkit-flex-direction: row;
38   }
39
40   .category-presets {
41     padding: 4px;
42   }
43
44   .category-description {
45     color: #aaa;
46     font-size: small;
47     max-height: 1em;
48     opacity: 1;
49     padding-left: 4px;
50     padding-right: 4px;
51     text-align: right;
52     transition: max-height 1s ease, opacity 1s ease;
53     will-change: opacity;
54   }
55
56   .category-description-hidden {
57     max-height: 0;
58     opacity: 0;
59   }
60
61   .default-enabled-categories,
62   .default-disabled-categories {
63     -webkit-flex: 1 1 auto;
64     display: -webkit-flex;
65     -webkit-flex-direction: column;
66     padding: 4px;
67     width: 300px;
68   }
69
70   .default-enabled-categories > div,
71   .default-disabled-categories > div {
72     padding: 4px;
73   }
74
75   .tracing-modes {
76     -webkit-flex: 1 0 auto;
77     display: -webkit-flex;
78     -webkit-flex-direction: reverse;
79     padding: 4px;
80     border-bottom: 2px solid #ddd;
81     border-top: 2px solid #ddd;
82   }
83
84   .default-disabled-categories {
85     border-left: 2px solid #ddd;
86   }
87
88   .warning-default-disabled-categories {
89     display: inline-block;
90     font-weight: bold;
91     text-align: center;
92     color: #BD2E2E;
93     width: 2.0ex;
94     height: 2.0ex;
95     border-radius: 2.0ex;
96     border: 1px solid #BD2E2E;
97   }
98
99   .categories {
100     font-size: 80%;
101     padding: 10px;
102     overflow: auto;
103     max-height: 400px;
104     -webkit-flex: 1 1 auto;
105   }
106
107   .group-selectors {
108     font-size: 80%;
109     border-bottom: 1px solid #ddd;
110     padding-bottom: 6px;
111     -webkit-flex: 0 0 auto;
112   }
113
114   .group-selectors button {
115     padding: 1px;
116   }
117   </style>
118
119   <div class="record-selection-dialog">
120     <x-info-bar-group></x-info-bar-group>
121     <div class="category-presets">
122       Settings preset:
123     </div>
124     <div class="category-description"></div>
125     <div class="categories-column-view">
126       <div class="tracing-modes"></div>
127       <div class="categories-selection">
128         <div class="default-enabled-categories">
129           <div>Record&nbsp;Categories</div>
130           <div class="group-selectors">
131             Select
132             <button class="all-btn">All</button>
133             <button class="none-btn">None</button>
134           </div>
135           <div class="categories"></div>
136         </div>
137         <div class="default-disabled-categories">
138           <div>Disabled&nbsp;by&nbsp;Default&nbsp;Categories
139             <a class="warning-default-disabled-categories">!</a>
140           </div>
141           <div class="group-selectors">
142             Select
143             <button class="all-btn">All</button>
144             <button class="none-btn">None</button>
145           </div>
146           <div class="categories"></div>
147         </div>
148       </div>
149     </div>
150   </div>
151 </template>
152
153 <script>
154 'use strict';
155
156 /**
157  * @fileoverview RecordSelectionDialog presents the available categories
158  * to be enabled/disabled during tracing.
159  */
160 tvcm.exportTo('about_tracing', function() {
161   var THIS_DOC = document.currentScript.ownerDocument;
162   var RecordSelectionDialog = tvcm.ui.define('div');
163
164   var DEFAULT_PRESETS = [
165     {title: 'Web developer',
166       categoryFilter: ['blink', 'cc', 'net', 'v8']},
167     {title: 'Input latency',
168       categoryFilter: ['benchmark', 'input']},
169     {title: 'Rendering',
170       categoryFilter: ['blink', 'cc', 'gpu']},
171     {title: 'Javascript and rendering',
172       categoryFilter: ['blink', 'cc', 'gpu', 'v8']},
173     {title: 'Frame Viewer',
174       categoryFilter: ['blink', 'cc', 'gpu', 'v8',
175         'disabled-by-default-cc.debug']},
176     {title: 'Manually select settings',
177       categoryFilter: []}
178   ];
179   var DEFAULT_CONTINUOUS_TRACING = true;
180   var DEFAULT_SYSTEM_TRACING = false;
181   var DEFAULT_SAMPLING_TRACING = false;
182
183   RecordSelectionDialog.prototype = {
184     __proto__: tvcm.ui.Overlay.prototype,
185
186     decorate: function() {
187       tvcm.ui.Overlay.prototype.decorate.call(this);
188       this.title = 'Record a new trace...';
189
190       this.classList.add('record-dialog-overlay');
191
192       var node = tvcm.instantiateTemplate('#record-selection-dialog-template',
193           THIS_DOC);
194       this.appendChild(node);
195
196       this.recordButtonEl_ = document.createElement('button');
197       this.recordButtonEl_.textContent = 'Record';
198       this.recordButtonEl_.addEventListener(
199           'click',
200           this.onRecordButtonClicked_.bind(this));
201       this.recordButtonEl_.style.fontSize = '110%';
202       this.buttons.appendChild(this.recordButtonEl_);
203
204
205       this.categoriesView_ = this.querySelector('.categories-column-view');
206       this.presetsEl_ = this.querySelector('.category-presets');
207       this.presetsEl_.appendChild(tvcm.ui.createSelector(
208           this, 'currentlyChosenPreset',
209           'about_tracing.record_selection_dialog_preset',
210           DEFAULT_PRESETS[0].categoryFilter,
211           DEFAULT_PRESETS.map(function(p) {
212             return { label: p.title, value: p.categoryFilter };
213           })));
214
215
216       this.continuousTracingBn_ = tvcm.ui.createCheckBox(
217           undefined, undefined,
218           'recordSelectionDialog.useContinuousTracing', true,
219           'Continuous tracing');
220       this.systemTracingBn_ = tvcm.ui.createCheckBox(
221           undefined, undefined,
222           'recordSelectionDialog.useSystemTracing', true,
223           'System tracing');
224       this.samplingTracingBn_ = tvcm.ui.createCheckBox(
225           undefined, undefined,
226           'recordSelectionDialog.useSampling', false,
227           'State sampling');
228       this.tracingModesContainerEl_ = this.querySelector('.tracing-modes');
229       this.tracingModesContainerEl_.appendChild(this.continuousTracingBn_);
230       this.tracingModesContainerEl_.appendChild(this.systemTracingBn_);
231       this.tracingModesContainerEl_.appendChild(this.samplingTracingBn_);
232
233
234       this.enabledCategoriesContainerEl_ =
235           this.querySelector('.default-enabled-categories .categories');
236
237       this.disabledCategoriesContainerEl_ =
238           this.querySelector('.default-disabled-categories .categories');
239
240       this.createGroupSelectButtons_(
241           this.querySelector('.default-enabled-categories'));
242       this.createGroupSelectButtons_(
243           this.querySelector('.default-disabled-categories'));
244       this.createDefaultDisabledWarningDialog_(
245           this.querySelector('.warning-default-disabled-categories'));
246
247       // TODO(chrishenry): When used with tvcm.ui.Overlay (such as in
248       // chrome://tracing, this does not yet look quite right due to
249       // the 10px overlay content padding (but it's good enough).
250       this.infoBarGroup_ = this.querySelector('x-info-bar-group');
251       tvcm.ui.decorate(this.infoBarGroup_, tvcm.ui.InfoBarGroup);
252
253       this.addEventListener('visibleChange', this.onVisibleChange_.bind(this));
254     },
255
256     set supportsSystemTracing(s) {
257       if (s) {
258         this.systemTracingBn_.style.display = undefined;
259       } else {
260         this.systemTracingBn_.style.display = 'none';
261         this.useSystemTracing = false;
262       }
263     },
264
265     get useContinuousTracing() {
266       if (this.usingPreset_())
267         return DEFAULT_CONTINUOUS_TRACING;
268       return this.continuousTracingBn_.checked;
269     },
270     set useContinuousTracing(value) {
271       this.continuousTracingBn_.checked = !!value;
272     },
273
274     get useSystemTracing() {
275       if (this.usingPreset_())
276         return DEFAULT_SYSTEM_TRACING;
277       return this.systemTracingBn_.checked;
278     },
279     set useSystemTracing(value) {
280       this.systemTracingBn_.checked = !!value;
281     },
282     get useSampling() {
283       if (this.usingPreset_())
284         return DEFAULT_SAMPLING_TRACING;
285       return this.samplingTracingBn_.checked;
286     },
287     set useSampling(value) {
288       this.samplingTracingBn_.checked = !!value;
289     },
290
291     set categories(c) {
292       this.categories_ = c;
293
294       for (var i = 0; i < this.categories_.length; i++) {
295         var split = this.categories_[i].split(',');
296         this.categories_[i] = split.shift();
297         if (split.length > 0)
298           this.categories_ = this.categories_.concat(split);
299       }
300     },
301
302     set settings_key(k) {
303       this.settings_key_ = k;
304     },
305
306     set settings(s) {
307       throw new Error('Dont use this!');
308     },
309
310     usingPreset_: function() {
311       return this.currentlyChosenPreset_.length > 0;
312     },
313
314     get currentlyChosenPreset() {
315       return this.currentlyChosenPreset_;
316     },
317
318     set currentlyChosenPreset(preset) {
319       if (!(preset instanceof Array))
320         throw new Error('RecordSelectionDialog.currentlyChosenPreset:' +
321             ' preset must be an array.');
322       this.currentlyChosenPreset_ = preset;
323
324       var classList = this.categoriesView_.classList;
325       if (!this.usingPreset_())
326         classList.remove('categories-column-view-hidden');
327       else if (!classList.contains('categories-column-view-hidden'))
328         classList.add('categories-column-view-hidden');
329       this.updatePresetDescription_();
330     },
331
332     updatePresetDescription_: function() {
333       var description = this.querySelector('.category-description');
334       if (this.usingPreset_()) {
335         description.innerText = this.currentlyChosenPreset_;
336         description.classList.remove('category-description-hidden');
337       } else {
338         description.innerText = '';
339         if (!description.classList.contains('category-description-hidden'))
340           description.classList.add('category-description-hidden');
341       }
342     },
343
344     categoryFilter: function() {
345       if (this.usingPreset_()) {
346         var categories = [];
347         var allCategories = this.allCategories_();
348         for (var category in allCategories) {
349           var disabled = category.indexOf('disabled-by-default-') == 0;
350           if (this.currentlyChosenPreset_.indexOf(category) >= 0) {
351             if (disabled)
352               categories.push(category);
353           } else {
354             if (!disabled)
355               categories.push('-' + category);
356           }
357         }
358         return categories.join(',');
359       }
360
361       var categories = this.unselectedCategories_();
362       var categories_length = categories.length;
363       var negated_categories = [];
364       for (var i = 0; i < categories_length; ++i) {
365         // Skip any category with a , as it will cause issues when we negate.
366         // Both sides should have been added as separate categories, these can
367         // only come from settings.
368         if (categories[i].match(/,/))
369           continue;
370         negated_categories.push('-' + categories[i]);
371       }
372       categories = negated_categories.join(',');
373
374       var disabledCategories = this.enabledDisabledByDefaultCategories_();
375       disabledCategories = disabledCategories.join(',');
376
377       var results = [];
378       if (categories !== '')
379         results.push(categories);
380       if (disabledCategories !== '')
381         results.push(disabledCategories);
382       return results.join(',');
383     },
384
385     clickRecordButton: function() {
386       this.recordButtonEl_.click();
387     },
388
389     onRecordButtonClicked_: function() {
390       this.visible = false;
391       tvcm.dispatchSimpleEvent(this, 'recordclick');
392       return false;
393     },
394
395     collectInputs_: function(inputs, isChecked) {
396       var inputs_length = inputs.length;
397       var categories = [];
398       for (var i = 0; i < inputs_length; ++i) {
399         var input = inputs[i];
400         if (input.checked === isChecked)
401           categories.push(input.value);
402       }
403       return categories;
404     },
405
406     unselectedCategories_: function() {
407       var inputs =
408           this.enabledCategoriesContainerEl_.querySelectorAll('input');
409       return this.collectInputs_(inputs, false);
410     },
411
412     enabledDisabledByDefaultCategories_: function() {
413       var inputs =
414           this.disabledCategoriesContainerEl_.querySelectorAll('input');
415       return this.collectInputs_(inputs, true);
416     },
417
418     onVisibleChange_: function() {
419       if (this.visible)
420         this.updateForm_();
421     },
422
423     buildInputs_: function(inputs, checkedDefault, parent) {
424       var inputs_length = inputs.length;
425       for (var i = 0; i < inputs_length; i++) {
426         var category = inputs[i];
427
428         var inputEl = document.createElement('input');
429         inputEl.type = 'checkbox';
430         inputEl.id = category;
431         inputEl.value = category;
432
433         inputEl.checked = tvcm.Settings.get(
434             category, checkedDefault, this.settings_key_);
435         inputEl.onclick = this.updateSetting_.bind(this);
436
437         var labelEl = document.createElement('label');
438         labelEl.textContent = category.replace('disabled-by-default-', '');
439         labelEl.setAttribute('for', category);
440
441         var divEl = document.createElement('div');
442         divEl.appendChild(inputEl);
443         divEl.appendChild(labelEl);
444
445         parent.appendChild(divEl);
446       }
447     },
448
449     allCategories_: function() {
450       // Dedup the categories. We may have things in settings that are also
451       // returned when we query the category list.
452       var categorySet = {};
453       var allCategories =
454           this.categories_.concat(tvcm.Settings.keys(this.settings_key_));
455       var allCategoriesLength = allCategories.length;
456       for (var i = 0; i < allCategoriesLength; ++i)
457         categorySet[allCategories[i]] = true;
458       return categorySet;
459     },
460
461     updateForm_: function() {
462       this.enabledCategoriesContainerEl_.innerHTML = ''; // Clear old categories
463       this.disabledCategoriesContainerEl_.innerHTML = '';
464
465       this.recordButtonEl_.focus();
466
467       var allCategories = this.allCategories_();
468       var categories = [];
469       var disabledCategories = [];
470       for (var category in allCategories) {
471         if (category.indexOf('disabled-by-default-') == 0)
472           disabledCategories.push(category);
473         else
474           categories.push(category);
475       }
476       disabledCategories = disabledCategories.sort();
477       categories = categories.sort();
478
479       if (this.categories_.length == 0) {
480         this.infoBarGroup_.addMessage(
481             'No categories found; recording will use default categories.');
482       }
483
484       this.buildInputs_(categories, true, this.enabledCategoriesContainerEl_);
485
486       if (disabledCategories.length > 0) {
487         this.disabledCategoriesContainerEl_.hidden = false;
488         this.buildInputs_(disabledCategories, false,
489             this.disabledCategoriesContainerEl_);
490       }
491     },
492
493     updateSetting_: function(e) {
494       var checkbox = e.target;
495       tvcm.Settings.set(checkbox.value, checkbox.checked, this.settings_key_);
496     },
497
498     createGroupSelectButtons_: function(parent) {
499       var flipInputs = function(dir) {
500         var inputs = parent.querySelectorAll('input');
501         for (var i = 0; i < inputs.length; i++) {
502           if (inputs[i].checked === dir)
503             continue;
504           // click() is used so the settings will be correclty stored. Setting
505           // checked does not trigger the onclick (or onchange) callback.
506           inputs[i].click();
507         }
508       };
509
510       var allBtn = parent.querySelector('.all-btn');
511       allBtn.onclick = function(evt) {
512         flipInputs(true);
513         evt.preventDefault();
514       };
515
516       var noneBtn = parent.querySelector('.none-btn');
517       noneBtn.onclick = function(evt) {
518         flipInputs(false);
519         evt.preventDefault();
520       };
521     },
522
523     setWarningDialogOverlayText_: function(messages) {
524       var contentDiv = document.createElement('div');
525
526       for (var i = 0; i < messages.length; ++i) {
527         var messageDiv = document.createElement('div');
528         messageDiv.textContent = messages[i];
529         contentDiv.appendChild(messageDiv);
530       }
531       this.warningOverlay_.textContent = '';
532       this.warningOverlay_.appendChild(contentDiv);
533     },
534
535     createDefaultDisabledWarningDialog_: function(warningLink) {
536       function onClickHandler(evt) {
537         this.warningOverlay_ = tvcm.ui.Overlay();
538         this.warningOverlay_.title = 'Enabling Categories Warning...';
539         this.warningOverlay_.userCanClose = true;
540         this.warningOverlay_.visible = true;
541
542         this.setWarningDialogOverlayText_([
543           'Enabling the default disabled categories may have',
544           'performance and memory impact while tracing.'
545         ]);
546
547         evt.preventDefault();
548       }
549       warningLink.onclick = onClickHandler.bind(this);
550     }
551   };
552
553   return {
554     RecordSelectionDialog: RecordSelectionDialog
555   };
556 });
557 </script>