summaryrefslogtreecommitdiff
path: root/Source/WebInspectorUI/UserInterface/Base/Object.js
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebInspectorUI/UserInterface/Base/Object.js
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebInspectorUI/UserInterface/Base/Object.js')
-rw-r--r--Source/WebInspectorUI/UserInterface/Base/Object.js229
1 files changed, 229 insertions, 0 deletions
diff --git a/Source/WebInspectorUI/UserInterface/Base/Object.js b/Source/WebInspectorUI/UserInterface/Base/Object.js
new file mode 100644
index 000000000..2a91983af
--- /dev/null
+++ b/Source/WebInspectorUI/UserInterface/Base/Object.js
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2008, 2013 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.Object = class WebInspectorObject
+{
+ constructor()
+ {
+ this._listeners = null;
+ }
+
+ // Static
+
+ static addEventListener(eventType, listener, thisObject)
+ {
+ thisObject = thisObject || null;
+
+ console.assert(eventType, "Object.addEventListener: invalid event type ", eventType, "(listener: ", listener, "thisObject: ", thisObject, ")");
+ if (!eventType)
+ return null;
+
+ console.assert(listener, "Object.addEventListener: invalid listener ", listener, "(event type: ", eventType, "thisObject: ", thisObject, ")");
+ if (!listener)
+ return null;
+
+ if (!this._listeners)
+ this._listeners = new Map();
+
+ let listenersTable = this._listeners.get(eventType);
+ if (!listenersTable) {
+ listenersTable = new ListMultimap();
+ this._listeners.set(eventType, listenersTable);
+ }
+
+ listenersTable.add(thisObject, listener);
+ return listener;
+ }
+
+ static singleFireEventListener(eventType, listener, thisObject)
+ {
+ let wrappedCallback = function() {
+ this.removeEventListener(eventType, wrappedCallback, null);
+ listener.apply(thisObject, arguments);
+ }.bind(this);
+
+ this.addEventListener(eventType, wrappedCallback, null);
+ return wrappedCallback;
+ }
+
+ static removeEventListener(eventType, listener, thisObject)
+ {
+ eventType = eventType || null;
+ listener = listener || null;
+ thisObject = thisObject || null;
+
+ if (!this._listeners)
+ return;
+
+ if (thisObject && !eventType) {
+ this._listeners.forEach(function(listenersTable) {
+ let listenerPairs = listenersTable.toArray();
+ for (let i = 0, length = listenerPairs.length; i < length; ++i) {
+ let existingThisObject = listenerPairs[i][0];
+ if (existingThisObject === thisObject)
+ listenersTable.deleteAll(existingThisObject);
+ }
+ });
+
+ return;
+ }
+
+ let listenersTable = this._listeners.get(eventType);
+ if (!listenersTable || listenersTable.size === 0)
+ return;
+
+ let didDelete = listenersTable.delete(thisObject, listener);
+ console.assert(didDelete, "removeEventListener cannot remove " + eventType.toString() + " because it doesn't exist.");
+ }
+
+ static awaitEvent(eventType)
+ {
+ let wrapper = new WebInspector.WrappedPromise;
+ this.singleFireEventListener(eventType, (event) => wrapper.resolve(event));
+ return wrapper.promise;
+ }
+
+ // Only used by tests.
+ static hasEventListeners(eventType)
+ {
+ if (!this._listeners)
+ return false;
+
+ let listenersTable = this._listeners.get(eventType);
+ return listenersTable && listenersTable.size > 0;
+ }
+
+ // This should only be used within regression tests to detect leaks.
+ static retainedObjectsWithPrototype(proto)
+ {
+ let results = new Set;
+
+ if (this._listeners) {
+ this._listeners.forEach(function(listenersTable, eventType) {
+ listenersTable.forEach(function(pair) {
+ let thisObject = pair[0];
+ if (thisObject instanceof proto)
+ results.add(thisObject);
+ });
+ });
+ }
+
+ return results;
+ }
+
+ // Public
+
+ addEventListener() { return WebInspector.Object.addEventListener.apply(this, arguments); }
+ singleFireEventListener() { return WebInspector.Object.singleFireEventListener.apply(this, arguments); }
+ removeEventListener() { return WebInspector.Object.removeEventListener.apply(this, arguments); }
+ awaitEvent() { return WebInspector.Object.awaitEvent.apply(this, arguments); }
+ hasEventListeners() { return WebInspector.Object.hasEventListeners.apply(this, arguments); }
+ retainedObjectsWithPrototype() { return WebInspector.Object.retainedObjectsWithPrototype.apply(this, arguments); }
+
+ dispatchEventToListeners(eventType, eventData)
+ {
+ let event = new WebInspector.Event(this, eventType, eventData);
+
+ function dispatch(object)
+ {
+ if (!object || event._stoppedPropagation)
+ return;
+
+ let listenerTypesMap = object._listeners;
+ if (!listenerTypesMap || !object.hasOwnProperty("_listeners"))
+ return;
+
+ console.assert(listenerTypesMap instanceof Map);
+
+ let listenersTable = listenerTypesMap.get(eventType);
+ if (!listenersTable)
+ return;
+
+ // Make a copy with slice so mutations during the loop doesn't affect us.
+ let listeners = listenersTable.toArray();
+
+ // Iterate over the listeners and call them. Stop if stopPropagation is called.
+ for (let i = 0, length = listeners.length; i < length; ++i) {
+ let [thisObject, listener] = listeners[i];
+ listener.call(thisObject, event);
+ if (event._stoppedPropagation)
+ break;
+ }
+ }
+
+ // Dispatch to listeners of this specific object.
+ dispatch(this);
+
+ // Allow propagation again so listeners on the constructor always have a crack at the event.
+ event._stoppedPropagation = false;
+
+ // Dispatch to listeners on all constructors up the prototype chain, including the immediate constructor.
+ let constructor = this.constructor;
+ while (constructor) {
+ dispatch(constructor);
+
+ if (!constructor.prototype.__proto__)
+ break;
+
+ constructor = constructor.prototype.__proto__.constructor;
+ }
+
+ return event.defaultPrevented;
+ }
+};
+
+WebInspector.Event = class Event
+{
+ constructor(target, type, data)
+ {
+ this.target = target;
+ this.type = type;
+ this.data = data;
+ this.defaultPrevented = false;
+ this._stoppedPropagation = false;
+ }
+
+ stopPropagation()
+ {
+ this._stoppedPropagation = true;
+ }
+
+ preventDefault()
+ {
+ this.defaultPrevented = true;
+ }
+};
+
+WebInspector.notifications = new WebInspector.Object;
+
+WebInspector.Notification = {
+ GlobalModifierKeysDidChange: "global-modifiers-did-change",
+ PageArchiveStarted: "page-archive-started",
+ PageArchiveEnded: "page-archive-ended",
+ ExtraDomainsActivated: "extra-domains-activated",
+ TabTypesChanged: "tab-types-changed",
+ DebugUIEnabledDidChange: "debug-ui-enabled-did-change",
+ VisibilityStateDidChange: "visibility-state-did-change",
+};