1 /* 2 * Copyright (C) 2008 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. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 /** 27 * @constructor 28 * @implements {WebInspector.EventTarget} 29 */ 30 WebInspector.Object = function() { 31 } 32 33 WebInspector.Object.prototype = { 34 /** 35 * @param {string} eventType 36 * @param {function(!WebInspector.Event)} listener 37 * @param {!Object=} thisObject 38 */ 39 addEventListener: function(eventType, listener, thisObject) 40 { 41 if (!listener) 42 console.assert(false); 43 44 if (!this._listeners) 45 this._listeners = {}; 46 if (!this._listeners[eventType]) 47 this._listeners[eventType] = []; 48 this._listeners[eventType].push({ thisObject: thisObject, listener: listener }); 49 }, 50 51 /** 52 * @param {string} eventType 53 * @param {function(!WebInspector.Event)} listener 54 * @param {!Object=} thisObject 55 */ 56 removeEventListener: function(eventType, listener, thisObject) 57 { 58 console.assert(listener); 59 60 if (!this._listeners || !this._listeners[eventType]) 61 return; 62 var listeners = this._listeners[eventType]; 63 for (var i = 0; i < listeners.length; ++i) { 64 if (listeners[i].listener === listener && listeners[i].thisObject === thisObject) 65 listeners.splice(i--, 1); 66 } 67 68 if (!listeners.length) 69 delete this._listeners[eventType]; 70 }, 71 72 removeAllListeners: function() 73 { 74 delete this._listeners; 75 }, 76 77 /** 78 * @param {string} eventType 79 * @return {boolean} 80 */ 81 hasEventListeners: function(eventType) 82 { 83 if (!this._listeners || !this._listeners[eventType]) 84 return false; 85 return true; 86 }, 87 88 /** 89 * @param {string} eventType 90 * @param {*=} eventData 91 * @return {boolean} 92 */ 93 dispatchEventToListeners: function(eventType, eventData) 94 { 95 if (!this._listeners || !this._listeners[eventType]) 96 return false; 97 98 var event = new WebInspector.Event(this, eventType, eventData); 99 var listeners = this._listeners[eventType].slice(0); 100 for (var i = 0; i < listeners.length; ++i) { 101 listeners[i].listener.call(listeners[i].thisObject, event); 102 if (event._stoppedPropagation) 103 break; 104 } 105 106 return event.defaultPrevented; 107 } 108 } 109 110 /** 111 * @constructor 112 * @param {!WebInspector.EventTarget} target 113 * @param {string} type 114 * @param {*=} data 115 */ 116 WebInspector.Event = function(target, type, data) 117 { 118 this.target = target; 119 this.type = type; 120 this.data = data; 121 this.defaultPrevented = false; 122 this._stoppedPropagation = false; 123 } 124 125 WebInspector.Event.prototype = { 126 stopPropagation: function() 127 { 128 this._stoppedPropagation = true; 129 }, 130 131 preventDefault: function() 132 { 133 this.defaultPrevented = true; 134 }, 135 136 /** 137 * @param {boolean=} preventDefault 138 */ 139 consume: function(preventDefault) 140 { 141 this.stopPropagation(); 142 if (preventDefault) 143 this.preventDefault(); 144 } 145 } 146 147 /** 148 * @constructor 149 * @extends {WebInspector.Object} 150 */ 151 WebInspector.Lock = function() 152 { 153 this._count = 0; // Reentrant. 154 } 155 156 /** 157 * @enum {string} 158 */ 159 WebInspector.Lock.Events = { 160 StateChanged: "StateChanged" 161 } 162 163 WebInspector.Lock.prototype = { 164 /** 165 * @return {boolean} 166 */ 167 isAcquired: function() 168 { 169 return !!this._count; 170 }, 171 172 acquire: function() 173 { 174 if (++this._count === 1) 175 this.dispatchEventToListeners(WebInspector.Lock.Events.StateChanged); 176 }, 177 178 release: function() 179 { 180 --this._count; 181 if (this._count < 0) { 182 console.error("WebInspector.Lock acquire/release calls are unbalanced " + new Error().stack); 183 return; 184 } 185 if (!this._count) 186 this.dispatchEventToListeners(WebInspector.Lock.Events.StateChanged); 187 }, 188 189 __proto__: WebInspector.Object.prototype 190 } 191 192 /** 193 * @interface 194 */ 195 WebInspector.EventTarget = function() 196 { 197 } 198 199 WebInspector.EventTarget.prototype = { 200 /** 201 * @param {string} eventType 202 * @param {function(!WebInspector.Event)} listener 203 * @param {!Object=} thisObject 204 */ 205 addEventListener: function(eventType, listener, thisObject) { }, 206 207 /** 208 * @param {string} eventType 209 * @param {function(!WebInspector.Event)} listener 210 * @param {!Object=} thisObject 211 */ 212 removeEventListener: function(eventType, listener, thisObject) { }, 213 214 removeAllListeners: function() { }, 215 216 /** 217 * @param {string} eventType 218 * @return {boolean} 219 */ 220 hasEventListeners: function(eventType) { }, 221 222 /** 223 * @param {string} eventType 224 * @param {*=} eventData 225 * @return {boolean} 226 */ 227 dispatchEventToListeners: function(eventType, eventData) { }, 228 } 229