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