Home | History | Annotate | Download | only in front-end
      1 /*
      2  * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
      3  * Copyright (C) 2008, 2009 Anthony Ricaud <rik (at) webkit.org>
      4  * Copyright (C) 2009 Google Inc. All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *
     10  * 1.  Redistributions of source code must retain the above copyright
     11  *     notice, this list of conditions and the following disclaimer.
     12  * 2.  Redistributions in binary form must reproduce the above copyright
     13  *     notice, this list of conditions and the following disclaimer in the
     14  *     documentation and/or other materials provided with the distribution.
     15  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     16  *     its contributors may be used to endorse or promote products derived
     17  *     from this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 WebInspector.TimelineGrid = function()
     32 {
     33     this.element = document.createElement("div");
     34 
     35     this._itemsGraphsElement = document.createElement("div");
     36     this._itemsGraphsElement.id = "resources-graphs";
     37     this.element.appendChild(this._itemsGraphsElement);
     38 
     39     this._dividersElement = document.createElement("div");
     40     this._dividersElement.className = "resources-dividers";
     41     this.element.appendChild(this._dividersElement);
     42 
     43     this._eventDividersElement = document.createElement("div");
     44     this._eventDividersElement.className = "resources-event-dividers";
     45     this.element.appendChild(this._eventDividersElement);
     46 
     47     this._dividersLabelBarElement = document.createElement("div");
     48     this._dividersLabelBarElement.className = "resources-dividers-label-bar";
     49     this.element.appendChild(this._dividersLabelBarElement);
     50 }
     51 
     52 WebInspector.TimelineGrid.prototype = {
     53     get itemsGraphsElement()
     54     {
     55         return this._itemsGraphsElement;
     56     },
     57 
     58 
     59     updateDividers: function(force, calculator, paddingLeft)
     60     {
     61         var dividerCount = Math.round(this._dividersElement.offsetWidth / 64);
     62         var slice = calculator.boundarySpan / dividerCount;
     63         if (!force && this._currentDividerSlice === slice)
     64             return false;
     65 
     66         if (typeof paddingLeft !== "number")
     67             paddingLeft = 0;
     68         this._currentDividerSlice = slice;
     69 
     70         // Reuse divider elements and labels.
     71         var divider = this._dividersElement.firstChild;
     72         var dividerLabelBar = this._dividersLabelBarElement.firstChild;
     73 
     74         var dividersLabelBarElementClientWidth = this._dividersLabelBarElement.clientWidth;
     75         var clientWidth = dividersLabelBarElementClientWidth - paddingLeft;
     76         for (var i = paddingLeft ? 0 : 1; i <= dividerCount; ++i) {
     77             if (!divider) {
     78                 divider = document.createElement("div");
     79                 divider.className = "resources-divider";
     80                 this._dividersElement.appendChild(divider);
     81 
     82                 dividerLabelBar = document.createElement("div");
     83                 dividerLabelBar.className = "resources-divider";
     84                 var label = document.createElement("div");
     85                 label.className = "resources-divider-label";
     86                 dividerLabelBar._labelElement = label;
     87                 dividerLabelBar.appendChild(label);
     88                 this._dividersLabelBarElement.appendChild(dividerLabelBar);
     89                 dividersLabelBarElementClientWidth = this._dividersLabelBarElement.clientWidth;
     90             }
     91 
     92             if (i === (paddingLeft ? 0 : 1)) {
     93                 divider.addStyleClass("first");
     94                 dividerLabelBar.addStyleClass("first");
     95             } else {
     96                 divider.removeStyleClass("first");
     97                 dividerLabelBar.removeStyleClass("first");
     98             }
     99 
    100             if (i === dividerCount) {
    101                 divider.addStyleClass("last");
    102                 dividerLabelBar.addStyleClass("last");
    103             } else {
    104                 divider.removeStyleClass("last");
    105                 dividerLabelBar.removeStyleClass("last");
    106             }
    107 
    108             var left = paddingLeft + clientWidth * (i / dividerCount);
    109             var percentLeft = 100 * left / dividersLabelBarElementClientWidth;
    110             this._setDividerAndBarLeft(divider, dividerLabelBar, percentLeft);
    111 
    112             if (!isNaN(slice))
    113                 dividerLabelBar._labelElement.textContent = calculator.formatValue(slice * i);
    114             else
    115                 dividerLabelBar._labelElement.textContent = "";
    116 
    117             divider = divider.nextSibling;
    118             dividerLabelBar = dividerLabelBar.nextSibling;
    119         }
    120 
    121         // Remove extras.
    122         while (divider) {
    123             var nextDivider = divider.nextSibling;
    124             this._dividersElement.removeChild(divider);
    125             divider = nextDivider;
    126         }
    127         while (dividerLabelBar) {
    128             var nextDivider = dividerLabelBar.nextSibling;
    129             this._dividersLabelBarElement.removeChild(dividerLabelBar);
    130             dividerLabelBar = nextDivider;
    131         }
    132         return true;
    133     },
    134 
    135     _setDividerAndBarLeft: function(divider, dividerLabelBar, percentLeft)
    136     {
    137         var percentStyleLeft = parseFloat(divider.style.left);
    138         if (!isNaN(percentStyleLeft) && Math.abs(percentStyleLeft - percentLeft) < 0.1)
    139             return;
    140         divider.style.left = percentLeft + "%";
    141         dividerLabelBar.style.left = percentLeft + "%";
    142     },
    143 
    144     addEventDivider: function(divider)
    145     {
    146         this._eventDividersElement.appendChild(divider);
    147     },
    148 
    149     addEventDividers: function(dividers)
    150     {
    151         this.element.removeChild(this._eventDividersElement);
    152         for (var i = 0; i < dividers.length; ++i)
    153             if (dividers[i])
    154                 this._eventDividersElement.appendChild(dividers[i]);
    155         this.element.appendChild(this._eventDividersElement);
    156     },
    157 
    158     removeEventDividers: function()
    159     {
    160         this._eventDividersElement.removeChildren();
    161     },
    162 
    163     hideEventDividers: function()
    164     {
    165         this._eventDividersElement.addStyleClass("hidden");
    166     },
    167 
    168     showEventDividers: function()
    169     {
    170         this._eventDividersElement.removeStyleClass("hidden");
    171     },
    172 
    173     setScrollAndDividerTop: function(scrollTop, dividersTop)
    174     {
    175         this._dividersElement.style.top = scrollTop + "px";
    176         this._eventDividersElement.style.top = scrollTop + "px";
    177         this._dividersLabelBarElement.style.top = dividersTop + "px";
    178     }
    179 }
    180