Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Unified Diff: third_party/WebKit/Source/devtools/front_end/timeline/TimelineLandingPage.js

Issue 2557973002: DevTools: Introduce Landing page for Timeline panel. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/timeline/TimelineLandingPage.js
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLandingPage.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLandingPage.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6c232755cccb197fd1042e8c4bd22c1dae33bda
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLandingPage.js
@@ -0,0 +1,213 @@
+// Copyright 2016 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.
+
+Timeline.Perspective = class {
+ /**
+ * @param {string} id
+ * @param {string} title
+ * @param {string} description
+ * @param {!Array<string>=} visibleOptions
+ */
+ constructor(id, title, description, visibleOptions) {
+ this.id = id;
+ this.title = title;
+ this.description = description;
+ /** @type {!Object<string, !Timeline.Perspective.Config>} */
+ this.settings = {
caseq 2016/12/07 20:17:29 Why do we make the base class aware of all possibl
alph 2016/12/08 07:22:45 Done.
+ 'network': {
+ value: false,
+ title: Common.UIString('Network'),
+ description: Common.UIString('Capture network requests information.'),
+ setting: 'timelineCaptureNetwork'
caseq 2016/12/07 20:17:29 I wonder whether we should better use actual insta
alph 2016/12/08 07:22:45 I want it to be a config template. No objects allo
+ },
+ 'javascript': {
+ value: true,
+ title: Common.UIString('JavaScript'),
+ description: Common.UIString('Use sampling CPU profiler to collect JavaScript stacks.'),
+ setting: 'timelineEnableJSSampling'
+ },
+ 'screenshots': {
+ value: false,
+ title: Common.UIString('Screenshots'),
+ description:
+ Common.UIString('Collect page screenshots, so you can observe how the page was evolving during recording.'),
+ setting: 'timelineCaptureFilmStrip'
+ },
+ 'paints': {
+ value: false,
+ title: Common.UIString('Paints'),
+ description: Common.UIString(
+ 'Capture graphics layer positions and rasterization draw calls (moderate performance overhead).'),
+ setting: 'timelineCaptureLayersAndPictures'
+ },
+ 'memory': {
+ value: true,
+ title: Common.UIString('Memory'),
+ description: Common.UIString('Capture memory information on every timeline event.'),
+ setting: 'timelineCaptureMemory'
+ },
+ 'reload': {
+ value: false,
+ title: Common.UIString('Auto Reload'),
+ description: Common.UIString('Automatically reload page when recoring has started.')
+ }
+ };
+ this._visibleOptions = visibleOptions || [];
+ }
+
+ /**
+ * @param {!Element} parent
+ */
+ appendElements(parent) {
+ for (let id of this._visibleOptions) {
+ const config = this.settings[id];
+ this._createSettingCheckBox(parent, id, config);
+ }
+ }
+
+ /**
+ * @param {!Element} parent
+ * @param {string} id
+ * @param {!Timeline.Perspective.Config} config
+ */
+ _createSettingCheckBox(parent, id, config) {
+ const setting = config.setting ? Common.settings.createSetting(config.setting, config.value) : null;
+ const div = parent.createChild('div', 'recording-setting');
+ const checkbox = div.createChild('input');
+ checkbox.setAttribute('type', 'checkbox');
+ checkbox.setAttribute('id', id);
+ if (setting ? setting.get() : config.value)
+ checkbox.setAttribute('checked', true);
+ if (setting)
+ checkbox.addEventListener('change', event => setting.set(event.target.checked));
+ const label = div.createChild('label');
+ label.setAttribute('for', id);
+ label.textContent = config.title;
+ if (config.description)
+ div.createChild('div', 'recording-setting-description').textContent = config.description;
+ }
+
+ action() {
+ UI.actionRegistry.action('timeline.toggle-recording').execute();
+ }
+};
+
+/** @typedef {!{value: boolean, title: string, description: string, setting: ?string}} */
+Timeline.Perspective.Config;
+
+Timeline.LoadPerspective = class extends Timeline.Perspective {
+ constructor() {
+ super(
+ Timeline.TimelinePanel.Perspectives.Load, Common.UIString('Page Load'),
+ Common.UIString(
+ 'Page Load mode allows you to analyze how fast the page is loaded and becomes responsive.\n' +
+ 'In this mode the page is automatically reloaded right after the recording has started. ' +
+ 'During recording it collects information about network requests, screen state updates, ' +
+ 'and CPU threads acivity along with JavaScript stacks. ' +
+ 'Recording is stopped automatically shortly after the page processes load event.'),
+ ['screenshots']);
+ this.settings.network.value = true;
+ this.settings.reload.value = true;
+ this.settings.screenshots.value = true;
+ }
+
+ /**
+ * @override
+ */
+ action() {
+ SDK.targetManager.reloadPage();
+ }
+};
+
+Timeline.ResponsivenessPerspective = class extends Timeline.Perspective {
+ constructor() {
+ super(
+ Timeline.TimelinePanel.Perspectives.Responsiveness, Common.UIString('Responsiveness'),
+ Common.UIString('Record page responsiveness.'), ['screenshots']);
+ this.settings.network.value = true;
+ }
+};
+
+Timeline.JavaScriptPerspective = class extends Timeline.Perspective {
+ constructor() {
+ super(
+ Timeline.TimelinePanel.Perspectives.JavaScript, Common.UIString('JavaScript'),
+ Common.UIString('Record JavaScript execution profile.'));
+ }
+};
+
+Timeline.CustomPerspective = class extends Timeline.Perspective {
+ constructor() {
+ super(
+ Timeline.TimelinePanel.Perspectives.Custom, Common.UIString('Custom'),
+ Common.UIString('Advanced mode that allows you to customize recording options.'),
+ ['network', 'javascript', 'screenshots', 'memory', 'paints']);
+ }
+};
+
+Timeline.LandingPage = class extends UI.VBox {
+ constructor() {
+ super(true);
+ this.registerRequiredCSS('ui_lazy/dialog.css');
+ this.registerRequiredCSS('timeline/timelineLandingPage.css');
+ this.contentElement.classList.add('timeline-landing-page', 'fill');
+ const headerDiv = this.contentElement.createChild('div', 'timeline-perspective-header-bar');
+ this._perspectiveSetting = Common.settings.createSetting('timelinePerspective', 'load');
+ this._perspectiveSetting.addChangeListener(this._updatePerspective, this);
+
+ this._perspectives = [
+ Timeline.LoadPerspective, Timeline.ResponsivenessPerspective, Timeline.JavaScriptPerspective,
+ Timeline.CustomPerspective
+ ].map(cls => new cls());
caseq 2016/12/07 20:17:29 let's just call constructors expecitly.
alph 2016/12/08 07:22:45 Done.
+ this._inputByPerspective = new Map();
+ for (const perspective of this._perspectives) {
+ const div = headerDiv.createChild('div', 'timeline-perspective-header');
caseq 2016/12/07 20:17:29 Does this fail gracefully when the window is too n
alph 2016/12/08 07:22:45 Done.
+ const input = div.createChild('input');
+ input.setAttribute('type', 'radio');
+ input.setAttribute('name', 'perspective-select');
+ input.setAttribute('id', perspective.id);
+ input.setAttribute('value', perspective.id);
+ input.addEventListener('change', event => this._perspectiveSetting.set(event.target.id));
+ const label = div.createChild('label');
+ label.setAttribute('for', perspective.id);
+ label.textContent = perspective.title;
+ if (perspective.id === this._perspectiveSetting.get())
+ input.checked = true;
+ this._inputByPerspective.set(perspective.id, input);
+ }
+
+ this._bodyDiv = this.contentElement.createChild('div', 'timeline-perspective-body');
+ const footer = this.contentElement.createChild('div', 'timeline-perspective-footer');
+ const actionButton = footer.createChild('button');
+ actionButton.textContent = Common.UIString('Start');
+ actionButton.addEventListener('click', this._onAction.bind(this));
+ this._updatePerspective();
+ }
+
+ dispose() {
+ this._perspectiveSetting.removeChangeListener(this._updatePerspective, this);
caseq 2016/12/07 20:17:29 why do you need it?
alph 2016/12/08 07:22:45 Done.
+ }
+
+ /**
+ * @return {!Timeline.Perspective}
+ */
+ _currentPerspective() {
+ const id = this._perspectiveSetting.get();
+ return this._perspectives.find(p => p.id === id) || this._perspectives[0];
+ }
+
+ _updatePerspective() {
+ const perspective = this._currentPerspective();
+ const input = this._inputByPerspective.get(perspective.id);
+ if (input && !input.checked)
+ input.checked = true;
+ this._bodyDiv.removeChildren();
+ this._bodyDiv.createChild('div', 'timeline-perspective-description').textContent = perspective.description;
+ perspective.appendElements(this._bodyDiv);
+ }
+
+ _onAction() {
+ this._currentPerspective().action();
+ }
+};

Powered by Google App Engine
This is Rietveld 408576698