Home | History | Annotate | Download | only in elements
      1 /*
      2  * Copyright (C) 2007 Apple Inc.  All rights reserved.
      3  * Copyright (C) 2009 Joseph Pecoraro
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1.  Redistributions of source code must retain the above copyright
     10  *     notice, this list of conditions and the following disclaimer.
     11  * 2.  Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     15  *     its contributors may be used to endorse or promote products derived
     16  *     from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 /**
     31  * @constructor
     32  * @extends {WebInspector.SidebarPane}
     33  */
     34 WebInspector.EventListenersSidebarPane = function()
     35 {
     36     WebInspector.SidebarPane.call(this, WebInspector.UIString("Event Listeners"));
     37     this.bodyElement.classList.add("events-pane");
     38 
     39     this.sections = [];
     40 
     41     var refreshButton = document.createElement("button");
     42     refreshButton.className = "pane-title-button refresh";
     43     refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
     44     refreshButton.title = WebInspector.UIString("Refresh");
     45     this.titleElement.appendChild(refreshButton);
     46 
     47     this.settingsSelectElement = document.createElement("select");
     48     this.settingsSelectElement.className = "select-filter";
     49 
     50     var option = document.createElement("option");
     51     option.value = "all";
     52     option.label = WebInspector.UIString("All Nodes");
     53     this.settingsSelectElement.appendChild(option);
     54 
     55     option = document.createElement("option");
     56     option.value = "selected";
     57     option.label = WebInspector.UIString("Selected Node Only");
     58     this.settingsSelectElement.appendChild(option);
     59 
     60     var filter = WebInspector.settings.eventListenersFilter.get();
     61     if (filter === "all")
     62         this.settingsSelectElement[0].selected = true;
     63     else if (filter === "selected")
     64         this.settingsSelectElement[1].selected = true;
     65     this.settingsSelectElement.addEventListener("click", function(event) { event.consume() }, false);
     66     this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);
     67 
     68     this.titleElement.appendChild(this.settingsSelectElement);
     69 
     70     this._linkifier = new WebInspector.Linkifier();
     71 }
     72 
     73 WebInspector.EventListenersSidebarPane._objectGroupName = "event-listeners-sidebar-pane";
     74 
     75 WebInspector.EventListenersSidebarPane.prototype = {
     76     /**
     77      * @param {?WebInspector.DOMNode} node
     78      */
     79     update: function(node)
     80     {
     81         RuntimeAgent.releaseObjectGroup(WebInspector.EventListenersSidebarPane._objectGroupName);
     82         this._linkifier.reset();
     83 
     84         var body = this.bodyElement;
     85         body.removeChildren();
     86         this.sections = [];
     87 
     88         var self = this;
     89         /**
     90          * @param {?Array.<!WebInspector.DOMModel.EventListener>} eventListeners
     91          */
     92         function callback(eventListeners)
     93         {
     94             if (!eventListeners)
     95                 return;
     96 
     97             var selectedNodeOnly = "selected" === WebInspector.settings.eventListenersFilter.get();
     98             var sectionNames = [];
     99             var sectionMap = {};
    100             for (var i = 0; i < eventListeners.length; ++i) {
    101                 var eventListener = eventListeners[i];
    102                 if (selectedNodeOnly && (node.id !== eventListener.payload().nodeId))
    103                     continue;
    104                 if (/^function _inspectorCommandLineAPI_logEvent\(/.test(eventListener.payload().handlerBody.toString()))
    105                     continue; // ignore event listeners generated by monitorEvent
    106                 var type = eventListener.payload().type;
    107                 var section = sectionMap[type];
    108                 if (!section) {
    109                     section = new WebInspector.EventListenersSection(type, node.id, self._linkifier);
    110                     sectionMap[type] = section;
    111                     sectionNames.push(type);
    112                     self.sections.push(section);
    113                 }
    114                 section.addListener(eventListener);
    115             }
    116 
    117             if (sectionNames.length === 0) {
    118                 var div = document.createElement("div");
    119                 div.className = "info";
    120                 div.textContent = WebInspector.UIString("No Event Listeners");
    121                 body.appendChild(div);
    122                 return;
    123             }
    124 
    125             sectionNames.sort();
    126             for (var i = 0; i < sectionNames.length; ++i) {
    127                 var section = sectionMap[sectionNames[i]];
    128                 body.appendChild(section.element);
    129             }
    130         }
    131 
    132         if (node)
    133             node.eventListeners(WebInspector.EventListenersSidebarPane._objectGroupName, callback);
    134         this._selectedNode = node;
    135     },
    136 
    137     willHide: function()
    138     {
    139         delete this._selectedNode;
    140     },
    141 
    142     _refreshButtonClicked: function()
    143     {
    144         if (!this._selectedNode)
    145             return;
    146         this.update(this._selectedNode);
    147     },
    148 
    149     _changeSetting: function()
    150     {
    151         var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
    152         WebInspector.settings.eventListenersFilter.set(selectedOption.value);
    153         this.update(this._selectedNode);
    154     },
    155 
    156     __proto__: WebInspector.SidebarPane.prototype
    157 }
    158 
    159 /**
    160  * @constructor
    161  * @extends {WebInspector.PropertiesSection}
    162  */
    163 WebInspector.EventListenersSection = function(title, nodeId, linkifier)
    164 {
    165     this.eventListeners = [];
    166     this._nodeId = nodeId;
    167     this._linkifier = linkifier;
    168     WebInspector.PropertiesSection.call(this, title);
    169 
    170     // Changed from a Properties List
    171     this.propertiesElement.remove();
    172     delete this.propertiesElement;
    173     delete this.propertiesTreeOutline;
    174 
    175     this._eventBars = document.createElement("div");
    176     this._eventBars.className = "event-bars";
    177     this.element.appendChild(this._eventBars);
    178 }
    179 
    180 WebInspector.EventListenersSection.prototype = {
    181     /**
    182      * @param {!WebInspector.DOMModel.EventListener} eventListener
    183      */
    184     addListener: function(eventListener)
    185     {
    186         var eventListenerBar = new WebInspector.EventListenerBar(eventListener, this._nodeId, this._linkifier);
    187         this._eventBars.appendChild(eventListenerBar.element);
    188     },
    189 
    190     __proto__: WebInspector.PropertiesSection.prototype
    191 }
    192 
    193 /**
    194  * @constructor
    195  * @extends {WebInspector.ObjectPropertiesSection}
    196  * @param {!WebInspector.DOMModel.EventListener} eventListener
    197  * @param {!DOMAgent.NodeId} nodeId
    198  * @param {!WebInspector.Linkifier} linkifier
    199  */
    200 WebInspector.EventListenerBar = function(eventListener, nodeId, linkifier)
    201 {
    202     var target = eventListener.target();
    203     WebInspector.ObjectPropertiesSection.call(this, target.runtimeModel.createRemoteObjectFromPrimitiveValue(""));
    204 
    205     this._runtimeModel = target.runtimeModel;
    206     this._eventListener = eventListener;
    207     this._nodeId = nodeId;
    208     this._setNodeTitle();
    209     this._setFunctionSubtitle(linkifier);
    210     this.editable = false;
    211     this.element.className = "event-bar"; /* Changed from "section" */
    212     this.headerElement.classList.add("source-code");
    213     this.propertiesElement.className = "event-properties properties-tree source-code"; /* Changed from "properties" */
    214 }
    215 
    216 WebInspector.EventListenerBar.prototype = {
    217     update: function()
    218     {
    219         /**
    220          * @param {?WebInspector.RemoteObject} nodeObject
    221          * @this {WebInspector.EventListenerBar}
    222          */
    223         function updateWithNodeObject(nodeObject)
    224         {
    225             var properties = [];
    226             var payload = this._eventListener.payload();
    227 
    228             properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("type", payload.type));
    229             properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("useCapture", payload.useCapture));
    230             properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("isAttribute", payload.isAttribute));
    231             if (nodeObject)
    232                 properties.push(new WebInspector.RemoteObjectProperty("node", nodeObject));
    233             if (typeof payload.handler !== "undefined") {
    234                 var remoteObject = this._runtimeModel.createRemoteObject(payload.handler);
    235                 properties.push(new WebInspector.RemoteObjectProperty("handler", remoteObject));
    236             }
    237             properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("listenerBody", payload.handlerBody));
    238             if (payload.sourceName)
    239                 properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("sourceName", payload.sourceName));
    240             properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("lineNumber", payload.location.lineNumber + 1));
    241 
    242             this.updateProperties(properties);
    243         }
    244         this._eventListener.node().resolveToObject(WebInspector.EventListenersSidebarPane._objectGroupName, updateWithNodeObject.bind(this));
    245     },
    246 
    247     _setNodeTitle: function()
    248     {
    249         var node = this._eventListener.node();
    250         if (!node)
    251             return;
    252 
    253         if (node.nodeType() === Node.DOCUMENT_NODE) {
    254             this.titleElement.textContent = "document";
    255             return;
    256         }
    257 
    258         if (node.id === this._nodeId) {
    259             this.titleElement.textContent = WebInspector.DOMPresentationUtils.simpleSelector(node);
    260             return;
    261         }
    262 
    263         this.titleElement.removeChildren();
    264         this.titleElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node));
    265     },
    266 
    267     _setFunctionSubtitle: function(linkifier)
    268     {
    269         this.subtitleElement.removeChildren();
    270         this.subtitleElement.appendChild(linkifier.linkifyRawLocation(this._eventListener.location()));
    271     },
    272 
    273     __proto__: WebInspector.ObjectPropertiesSection.prototype
    274 }
    275