Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / AuditLauncherView.js
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 /**
32  * @constructor
33  * @param {!WebInspector.AuditController} auditController
34  * @extends {WebInspector.VBox}
35  */
36 WebInspector.AuditLauncherView = function(auditController)
37 {
38     WebInspector.VBox.call(this);
39     this.setMinimumSize(100, 25);
40
41     this._auditController = auditController;
42
43     this._categoryIdPrefix = "audit-category-item-";
44     this._auditRunning = false;
45
46     this.element.classList.add("audit-launcher-view");
47     this.element.classList.add("panel-enabler-view");
48
49     this._contentElement = document.createElement("div");
50     this._contentElement.className = "audit-launcher-view-content";
51     this.element.appendChild(this._contentElement);
52     this._boundCategoryClickListener = this._categoryClicked.bind(this);
53
54     this._resetResourceCount();
55
56     this._sortedCategories = [];
57
58     this._headerElement = document.createElement("h1");
59     this._headerElement.className = "no-audits";
60     this._headerElement.textContent = WebInspector.UIString("No audits to run");
61     this._contentElement.appendChild(this._headerElement);
62
63     WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
64     WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
65
66     var defaultSelectedAuditCategory = {};
67     defaultSelectedAuditCategory[WebInspector.AuditLauncherView.AllCategoriesKey] = true;
68     this._selectedCategoriesSetting = WebInspector.settings.createSetting("selectedAuditCategories", defaultSelectedAuditCategory);
69 }
70
71 WebInspector.AuditLauncherView.AllCategoriesKey = "__AllCategories";
72
73 WebInspector.AuditLauncherView.prototype = {
74     _resetResourceCount: function()
75     {
76         this._loadedResources = 0;
77         this._totalResources = 0;
78     },
79
80     _onRequestStarted: function(event)
81     {
82         var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
83         // Ignore long-living WebSockets for the sake of progress indicator, as we won't be waiting them anyway.
84         if (request.type === WebInspector.resourceTypes.WebSocket)
85             return;
86         ++this._totalResources;
87         this._updateResourceProgress();
88     },
89
90     _onRequestFinished: function(event)
91     {
92         var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
93         // See resorceStarted for details.
94         if (request.type === WebInspector.resourceTypes.WebSocket)
95             return;
96         ++this._loadedResources;
97         this._updateResourceProgress();
98     },
99
100     /**
101      * @param {!WebInspector.AuditCategory} category
102      */
103     addCategory: function(category)
104     {
105         if (!this._sortedCategories.length)
106             this._createLauncherUI();
107
108         var selectedCategories = this._selectedCategoriesSetting.get();
109         var categoryElement = this._createCategoryElement(category.displayName, category.id);
110         category._checkboxElement = categoryElement.firstChild;
111         if (this._selectAllCheckboxElement.checked || selectedCategories[category.displayName]) {
112             category._checkboxElement.checked = true;
113             ++this._currentCategoriesCount;
114         }
115
116         /**
117          * @param {!WebInspector.AuditCategory} a
118          * @param {!WebInspector.AuditCategory} b
119          * @return {number}
120          */
121         function compareCategories(a, b)
122         {
123             var aTitle = a.displayName || "";
124             var bTitle = b.displayName || "";
125             return aTitle.localeCompare(bTitle);
126         }
127         var insertBefore = insertionIndexForObjectInListSortedByFunction(category, this._sortedCategories, compareCategories);
128         this._categoriesElement.insertBefore(categoryElement, this._categoriesElement.children[insertBefore]);
129         this._sortedCategories.splice(insertBefore, 0, category);
130         this._selectedCategoriesUpdated();
131     },
132
133     /**
134      * @param {boolean} auditRunning
135      */
136     _setAuditRunning: function(auditRunning)
137     {
138         if (this._auditRunning === auditRunning)
139             return;
140         this._auditRunning = auditRunning;
141         this._updateButton();
142         this._toggleUIComponents(this._auditRunning);
143         if (this._auditRunning)
144             this._startAudit();
145         else
146             this._stopAudit();
147     },
148
149     _startAudit: function()
150     {
151         var catIds = [];
152         for (var category = 0; category < this._sortedCategories.length; ++category) {
153             if (this._sortedCategories[category]._checkboxElement.checked)
154                 catIds.push(this._sortedCategories[category].id);
155         }
156
157         this._resetResourceCount();
158         this._progressIndicator = new WebInspector.ProgressIndicator();
159         this._buttonContainerElement.appendChild(this._progressIndicator.element);
160         this._displayResourceLoadingProgress = true;
161
162         /**
163          * @this {WebInspector.AuditLauncherView}
164          */
165         function onAuditStarted()
166         {
167             this._displayResourceLoadingProgress = false;
168         }
169         this._auditController.initiateAudit(catIds, this._progressIndicator, this._auditPresentStateElement.checked, onAuditStarted.bind(this), this._setAuditRunning.bind(this, false));
170     },
171
172     _stopAudit: function()
173     {
174         this._displayResourceLoadingProgress = false;
175         this._progressIndicator.cancel();
176         this._progressIndicator.done();
177         delete this._progressIndicator;
178     },
179
180     /**
181      * @param {boolean} disable
182      */
183     _toggleUIComponents: function(disable)
184     {
185         this._selectAllCheckboxElement.disabled = disable;
186         this._categoriesElement.disabled = disable;
187         this._auditPresentStateElement.disabled = disable;
188         this._auditReloadedStateElement.disabled = disable;
189     },
190
191     _launchButtonClicked: function(event)
192     {
193         this._setAuditRunning(!this._auditRunning);
194     },
195
196     _clearButtonClicked: function()
197     {
198         this._auditController.clearResults();
199     },
200
201     /**
202      * @param {boolean} checkCategories
203      * @param {boolean=} userGesture
204      */
205     _selectAllClicked: function(checkCategories, userGesture)
206     {
207         var childNodes = this._categoriesElement.childNodes;
208         for (var i = 0, length = childNodes.length; i < length; ++i)
209             childNodes[i].firstChild.checked = checkCategories;
210         this._currentCategoriesCount = checkCategories ? this._sortedCategories.length : 0;
211         this._selectedCategoriesUpdated(userGesture);
212     },
213
214     _categoryClicked: function(event)
215     {
216         this._currentCategoriesCount += event.target.checked ? 1 : -1;
217         this._selectAllCheckboxElement.checked = this._currentCategoriesCount === this._sortedCategories.length;
218         this._selectedCategoriesUpdated(true);
219     },
220
221     /**
222      * @param {string} title
223      * @param {string} id
224      */
225     _createCategoryElement: function(title, id)
226     {
227         var labelElement = document.createElement("label");
228         labelElement.id = this._categoryIdPrefix + id;
229
230         var element = document.createElement("input");
231         element.type = "checkbox";
232         if (id !== "")
233             element.addEventListener("click", this._boundCategoryClickListener, false);
234         labelElement.appendChild(element);
235         labelElement.appendChild(document.createTextNode(title));
236         labelElement.__displayName = title;
237
238         return labelElement;
239     },
240
241     _createLauncherUI: function()
242     {
243         this._headerElement = document.createElement("h1");
244         this._headerElement.textContent = WebInspector.UIString("Select audits to run");
245
246         for (var child = 0; child < this._contentElement.children.length; ++child)
247             this._contentElement.removeChild(this._contentElement.children[child]);
248
249         this._contentElement.appendChild(this._headerElement);
250
251         /**
252          * @param {?Event} event
253          * @this {WebInspector.AuditLauncherView}
254          */
255         function handleSelectAllClick(event)
256         {
257             this._selectAllClicked(event.target.checked, true);
258         }
259         var categoryElement = this._createCategoryElement(WebInspector.UIString("Select All"), "");
260         categoryElement.id = "audit-launcher-selectall";
261         this._selectAllCheckboxElement = categoryElement.firstChild;
262         this._selectAllCheckboxElement.checked = this._selectedCategoriesSetting.get()[WebInspector.AuditLauncherView.AllCategoriesKey];
263         this._selectAllCheckboxElement.addEventListener("click", handleSelectAllClick.bind(this), false);
264         this._contentElement.appendChild(categoryElement);
265
266         this._categoriesElement = this._contentElement.createChild("fieldset", "audit-categories-container");
267         this._currentCategoriesCount = 0;
268
269         this._contentElement.createChild("div", "flexible-space");
270
271         this._buttonContainerElement = this._contentElement.createChild("div", "button-container");
272
273         var labelElement = this._buttonContainerElement.createChild("label");
274         this._auditPresentStateElement = labelElement.createChild("input");
275         this._auditPresentStateElement.name = "audit-mode";
276         this._auditPresentStateElement.type = "radio";
277         this._auditPresentStateElement.checked = true;
278         this._auditPresentStateLabelElement = document.createTextNode(WebInspector.UIString("Audit Present State"));
279         labelElement.appendChild(this._auditPresentStateLabelElement);
280
281         labelElement = this._buttonContainerElement.createChild("label");
282         this._auditReloadedStateElement = labelElement.createChild("input");
283         this._auditReloadedStateElement.name = "audit-mode";
284         this._auditReloadedStateElement.type = "radio";
285         labelElement.appendChild(document.createTextNode("Reload Page and Audit on Load"));
286
287         this._launchButton = this._buttonContainerElement.createChild("button");
288         this._launchButton.textContent = WebInspector.UIString("Run");
289         this._launchButton.addEventListener("click", this._launchButtonClicked.bind(this), false);
290
291         this._clearButton = this._buttonContainerElement.createChild("button");
292         this._clearButton.textContent = WebInspector.UIString("Clear");
293         this._clearButton.addEventListener("click", this._clearButtonClicked.bind(this), false);
294
295         this._selectAllClicked(this._selectAllCheckboxElement.checked);
296     },
297
298     _updateResourceProgress: function()
299     {
300         if (this._displayResourceLoadingProgress)
301             this._progressIndicator.setTitle(WebInspector.UIString("Loading (%d of %d)", this._loadedResources, this._totalResources));
302     },
303
304     /**
305      * @param {boolean=} userGesture
306      */
307     _selectedCategoriesUpdated: function(userGesture)
308     {
309         // Save present categories only upon user gesture to clean up junk from past versions and removed extensions.
310         // Do not remove old categories if not handling a user gesture, as there's chance categories will be added
311         // later during start-up.
312         var selectedCategories = userGesture ? {} : this._selectedCategoriesSetting.get();
313         var childNodes = this._categoriesElement.childNodes;
314         for (var i = 0, length = childNodes.length; i < length; ++i)
315             selectedCategories[childNodes[i].__displayName] = childNodes[i].firstChild.checked;
316         selectedCategories[WebInspector.AuditLauncherView.AllCategoriesKey] = this._selectAllCheckboxElement.checked;
317         this._selectedCategoriesSetting.set(selectedCategories);
318         this._updateButton();
319     },
320
321     _updateButton: function()
322     {
323         this._launchButton.textContent = this._auditRunning ? WebInspector.UIString("Stop") : WebInspector.UIString("Run");
324         this._launchButton.disabled = !this._currentCategoriesCount;
325     },
326
327     __proto__: WebInspector.VBox.prototype
328 }