Home | History | Annotate | Download | only in LeaksViewer
      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 
     26 var 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 
    202 addEventListener("load", LeaksViewer.loaded.bind(LeaksViewer));
    203