• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2011 Apple 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
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26var LeaksViewer = {
27    loaded: function() {
28        this._loader = new LeaksLoader(this._didCountLeaksFiles.bind(this), this._didLoadLeaksFile.bind(this));
29        this._parser = new LeaksParser(this._didParseLeaksFile.bind(this));
30
31        this._loadingIndicator = document.getElementById("loading-indicator");
32        this._loadingIndicatorLabel = document.getElementById("loading-indicator-label");
33
34        this._profileView = new WebInspector.CPUProfileView({});
35        document.getElementById("main-panels").appendChild(this._profileView.element);
36        this._profileView.show();
37
38        // From WebInspector.Panel.prototype.show
39        var statusBarItems = this._profileView.statusBarItems;
40        if (statusBarItems) {
41            this._statusBarItemContainer = document.createElement("div");
42            for (var i = 0; i < statusBarItems.length; ++i)
43                this._statusBarItemContainer.appendChild(statusBarItems[i]);
44            document.getElementById("main-status-bar").appendChild(this._statusBarItemContainer);
45        }
46
47        var url;
48        var match = /url=([^&]+)/.exec(location.search);
49        if (match)
50            url = decodeURIComponent(match[1]);
51
52        if (url)
53            this._loadLeaksFromURL(url)
54        else
55            this._displayURLPrompt();
56    },
57
58    get filesLeftToParse() {
59        if (!('_filesLeftToParse' in this))
60            this._filesLeftToParse = 0;
61        return this._filesLeftToParse;
62    },
63
64    set filesLeftToParse(x) {
65        if (this._filesLeftToParse === x)
66            return;
67        this._filesLeftToParse = x;
68        this._loadingStatusChanged();
69    },
70
71    get loading() {
72        return this._isLoading;
73    },
74
75    set loading(x) {
76        if (this._isLoading === x)
77            return;
78        this._isLoading = x;
79        this._loadingStatusChanged();
80    },
81
82    get url() {
83        return this._url;
84    },
85
86    set url(x) {
87        if (this._url === x)
88            return;
89
90        this._url = x;
91        this._updateTitle();
92    },
93
94    urlPromptButtonClicked: function(e) {
95        this._urlChosenFromPrompt(document.getElementById("url").value);
96    },
97
98    _didCountLeaksFiles: function(fileCount) {
99        this._fileCount = fileCount;
100        this.filesLeftToParse = fileCount;
101    },
102
103    _didLoadLeaksFile: function(leaksText) {
104        this._parser.addLeaksFile(leaksText);
105    },
106
107    _didLoadRecentBuilds: function(builds) {
108        this._recentBuilds = builds;
109        this._updateURLPrompt();
110    },
111
112    _didParseLeaksFile: function(profile) {
113        if (--this.filesLeftToParse)
114            return;
115        ProfilerAgent.profileReady(profile);
116        this.loading = false;
117    },
118
119    _displayURLPrompt: function() {
120        document.getElementById("url-prompt-container").removeStyleClass("hidden");
121        document.getElementById("url").focus();
122        var loader = new RecentBuildsLoader(this._didLoadRecentBuilds.bind(this));
123        loader.start("SnowLeopard Intel Leaks", this._numberOfRecentBuildsToLoad);
124    },
125
126    _loadLeaksFromURL: function(url) {
127        this.url = url;
128        this.loading = true;
129
130        this._loader.start(this.url);
131    },
132
133    _loadingIndicatorText: function() {
134        var text = "Loading";
135        if (this.filesLeftToParse)
136            text += " " + (this._fileCount - this.filesLeftToParse + 1) + "/" + this._fileCount + " files";
137        text += "\u2026";
138        return text;
139    },
140
141    _loadingStatusChanged: function() {
142        this._setLoadingIndicatorHidden(!this.loading);
143        this._updateLoadingIndicatorLabel();
144        this._updateTitle();
145    },
146
147    _numberOfRecentBuildsToLoad: 10,
148
149    _setLoadingIndicatorHidden: function(hidden) {
150        if (hidden)
151            this._loadingIndicator.addStyleClass("hidden");
152        else
153            this._loadingIndicator.removeStyleClass("hidden");
154    },
155
156    _updateLoadingIndicatorLabel: function() {
157        this._loadingIndicatorLabel.innerText = this._loadingIndicatorText();
158    },
159
160    _updateTitle: function() {
161        var title = "Leaks Viewer \u2014 ";
162        if (this.loading)
163            title += "(" + this._loadingIndicatorText() + ") ";
164        title += this.url;
165        document.title = title;
166    },
167
168    _updateURLPrompt: function() {
169        var recentBuildsContainer = document.getElementById("recent-builds-container");
170        recentBuildsContainer.removeChildren();
171        if (this._recentBuilds && this._recentBuilds.length) {
172            var list = document.createElement("ol");
173            list.id = "recent-builds-list";
174
175            var self = this;
176            this._recentBuilds.forEach(function(build) {
177                var link = document.createElement("a");
178                link.href = document.location.href + "?url=" + encodeURIComponent(build.url);
179                link.addEventListener("click", function(e) {
180                    self._urlChosenFromPrompt(build.url);
181                    e.preventDefault();
182                });
183                link.appendChild(document.createTextNode("r" + build.revision + ": " + build.leakCount + " leaks"));
184                var item = document.createElement("li");
185                item.appendChild(link);
186
187                list.appendChild(item);
188            });
189
190            recentBuildsContainer.appendChild(list);
191        } else
192            recentBuildsContainer.appendChild(document.createTextNode("No recent leaky builds found."));
193    },
194
195    _urlChosenFromPrompt: function(url) {
196        this._loadLeaksFromURL(url);
197        document.getElementById("url-prompt-container").addStyleClass("hidden");
198    },
199
200};
201
202addEventListener("load", LeaksViewer.loaded.bind(LeaksViewer));
203