123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- /*
- * Copyright (C) 2011 Google 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:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 THE COPYRIGHT
- * OWNER 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.
- */
- /**
- * @constructor
- * @extends {WebInspector.NativeBreakpointsSidebarPane}
- */
- WebInspector.DOMBreakpointsSidebarPane = function()
- {
- WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("DOM Breakpoints"));
- this._breakpointElements = {};
- this._breakpointTypes = {
- SubtreeModified: "subtree-modified",
- AttributeModified: "attribute-modified",
- NodeRemoved: "node-removed"
- };
- this._breakpointTypeLabels = {};
- this._breakpointTypeLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified");
- this._breakpointTypeLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified");
- this._breakpointTypeLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed");
- this._contextMenuLabels = {};
- this._contextMenuLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Subtree modifications" : "Subtree Modifications");
- this._contextMenuLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Attributes modifications" : "Attributes Modifications");
- this._contextMenuLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Node removal" : "Node Removal");
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
- }
- WebInspector.DOMBreakpointsSidebarPane.prototype = {
- _inspectedURLChanged: function(event)
- {
- this._breakpointElements = {};
- this._reset();
- var url = event.data;
- this._inspectedURL = url.removeURLFragment();
- },
- populateNodeContextMenu: function(node, contextMenu)
- {
- var nodeBreakpoints = {};
- for (var id in this._breakpointElements) {
- var element = this._breakpointElements[id];
- if (element._node === node)
- nodeBreakpoints[element._type] = true;
- }
- function toggleBreakpoint(type)
- {
- if (!nodeBreakpoints[type])
- this._setBreakpoint(node, type, true);
- else
- this._removeBreakpoint(node, type);
- this._saveBreakpoints();
- }
- var breakPointSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Break on..."));
- for (var key in this._breakpointTypes) {
- var type = this._breakpointTypes[key];
- var label = this._contextMenuLabels[type];
- breakPointSubMenu.appendCheckboxItem(label, toggleBreakpoint.bind(this, type), nodeBreakpoints[type]);
- }
- },
- createBreakpointHitStatusMessage: function(auxData, callback)
- {
- if (auxData.type === this._breakpointTypes.SubtreeModified) {
- var targetNodeObject = WebInspector.RemoteObject.fromPayload(auxData["targetNode"]);
- function didPushNodeToFrontend(targetNodeId)
- {
- if (targetNodeId)
- targetNodeObject.release();
- this._doCreateBreakpointHitStatusMessage(auxData, targetNodeId, callback);
- }
- targetNodeObject.pushNodeToFrontend(didPushNodeToFrontend.bind(this));
- } else
- this._doCreateBreakpointHitStatusMessage(auxData, null, callback);
- },
- _doCreateBreakpointHitStatusMessage: function (auxData, targetNodeId, callback)
- {
- var message;
- var typeLabel = this._breakpointTypeLabels[auxData.type];
- var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(auxData.nodeId);
- var substitutions = [typeLabel, linkifiedNode];
- var targetNode = "";
- if (targetNodeId)
- targetNode = WebInspector.DOMPresentationUtils.linkifyNodeById(targetNodeId);
- if (auxData.type === this._breakpointTypes.SubtreeModified) {
- if (auxData.insertion) {
- if (targetNodeId !== auxData.nodeId) {
- message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.";
- substitutions.push(targetNode);
- } else
- message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.";
- } else {
- message = "Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.";
- substitutions.push(targetNode);
- }
- } else
- message = "Paused on a \"%s\" breakpoint set on %s.";
- var element = document.createElement("span");
- var formatters = {
- s: function(substitution)
- {
- return substitution;
- }
- };
- function append(a, b)
- {
- if (typeof b === "string")
- b = document.createTextNode(b);
- element.appendChild(b);
- }
- WebInspector.formatLocalized(message, substitutions, formatters, "", append);
- callback(element);
- },
- _nodeRemoved: function(event)
- {
- var node = event.data.node;
- this._removeBreakpointsForNode(event.data.node);
- var children = node.children();
- if (!children)
- return;
- for (var i = 0; i < children.length; ++i)
- this._removeBreakpointsForNode(children[i]);
- this._saveBreakpoints();
- },
- _removeBreakpointsForNode: function(node)
- {
- for (var id in this._breakpointElements) {
- var element = this._breakpointElements[id];
- if (element._node === node)
- this._removeBreakpoint(element._node, element._type);
- }
- },
- _setBreakpoint: function(node, type, enabled)
- {
- var breakpointId = this._createBreakpointId(node.id, type);
- if (breakpointId in this._breakpointElements)
- return;
- var element = document.createElement("li");
- element._node = node;
- element._type = type;
- element.addEventListener("contextmenu", this._contextMenu.bind(this, node, type), true);
- var checkboxElement = document.createElement("input");
- checkboxElement.className = "checkbox-elem";
- checkboxElement.type = "checkbox";
- checkboxElement.checked = enabled;
- checkboxElement.addEventListener("click", this._checkboxClicked.bind(this, node, type), false);
- element._checkboxElement = checkboxElement;
- element.appendChild(checkboxElement);
- var labelElement = document.createElement("span");
- element.appendChild(labelElement);
- var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(node.id);
- linkifiedNode.addStyleClass("monospace");
- labelElement.appendChild(linkifiedNode);
- var description = document.createElement("div");
- description.className = "source-text";
- description.textContent = this._breakpointTypeLabels[type];
- labelElement.appendChild(description);
- var currentElement = this.listElement.firstChild;
- while (currentElement) {
- if (currentElement._type && currentElement._type < element._type)
- break;
- currentElement = currentElement.nextSibling;
- }
- this._addListElement(element, currentElement);
- this._breakpointElements[breakpointId] = element;
- if (enabled)
- DOMDebuggerAgent.setDOMBreakpoint(node.id, type);
- },
- _removeAllBreakpoints: function()
- {
- for (var id in this._breakpointElements) {
- var element = this._breakpointElements[id];
- this._removeBreakpoint(element._node, element._type);
- }
- this._saveBreakpoints();
- },
- _removeBreakpoint: function(node, type)
- {
- var breakpointId = this._createBreakpointId(node.id, type);
- var element = this._breakpointElements[breakpointId];
- if (!element)
- return;
- this._removeListElement(element);
- delete this._breakpointElements[breakpointId];
- if (element._checkboxElement.checked)
- DOMDebuggerAgent.removeDOMBreakpoint(node.id, type);
- },
- _contextMenu: function(node, type, event)
- {
- var contextMenu = new WebInspector.ContextMenu(event);
- function removeBreakpoint()
- {
- this._removeBreakpoint(node, type);
- this._saveBreakpoints();
- }
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove breakpoint" : "Remove Breakpoint"), removeBreakpoint.bind(this));
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove all DOM breakpoints" : "Remove All DOM Breakpoints"), this._removeAllBreakpoints.bind(this));
- contextMenu.show();
- },
- _checkboxClicked: function(node, type, event)
- {
- if (event.target.checked)
- DOMDebuggerAgent.setDOMBreakpoint(node.id, type);
- else
- DOMDebuggerAgent.removeDOMBreakpoint(node.id, type);
- this._saveBreakpoints();
- },
- highlightBreakpoint: function(auxData)
- {
- var breakpointId = this._createBreakpointId(auxData.nodeId, auxData.type);
- var element = this._breakpointElements[breakpointId];
- if (!element)
- return;
- this.expand();
- element.addStyleClass("breakpoint-hit");
- this._highlightedElement = element;
- },
- clearBreakpointHighlight: function()
- {
- if (this._highlightedElement) {
- this._highlightedElement.removeStyleClass("breakpoint-hit");
- delete this._highlightedElement;
- }
- },
- _createBreakpointId: function(nodeId, type)
- {
- return nodeId + ":" + type;
- },
- _saveBreakpoints: function()
- {
- var breakpoints = [];
- var storedBreakpoints = WebInspector.settings.domBreakpoints.get();
- for (var i = 0; i < storedBreakpoints.length; ++i) {
- var breakpoint = storedBreakpoints[i];
- if (breakpoint.url !== this._inspectedURL)
- breakpoints.push(breakpoint);
- }
- for (var id in this._breakpointElements) {
- var element = this._breakpointElements[id];
- breakpoints.push({ url: this._inspectedURL, path: element._node.path(), type: element._type, enabled: element._checkboxElement.checked });
- }
- WebInspector.settings.domBreakpoints.set(breakpoints);
- },
- restoreBreakpoints: function()
- {
- var pathToBreakpoints = {};
- /**
- * @param {string} path
- * @param {?DOMAgent.NodeId} nodeId
- */
- function didPushNodeByPathToFrontend(path, nodeId)
- {
- var node = nodeId ? WebInspector.domAgent.nodeForId(nodeId) : null;
- if (!node)
- return;
- var breakpoints = pathToBreakpoints[path];
- for (var i = 0; i < breakpoints.length; ++i)
- this._setBreakpoint(node, breakpoints[i].type, breakpoints[i].enabled);
- }
- var breakpoints = WebInspector.settings.domBreakpoints.get();
- for (var i = 0; i < breakpoints.length; ++i) {
- var breakpoint = breakpoints[i];
- if (breakpoint.url !== this._inspectedURL)
- continue;
- var path = breakpoint.path;
- if (!pathToBreakpoints[path]) {
- pathToBreakpoints[path] = [];
- WebInspector.domAgent.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
- }
- pathToBreakpoints[path].push(breakpoint);
- }
- },
- /**
- * @param {WebInspector.Panel} panel
- */
- createProxy: function(panel)
- {
- var proxy = new WebInspector.DOMBreakpointsSidebarPane.Proxy(this, panel);
- if (!this._proxies)
- this._proxies = [];
- this._proxies.push(proxy);
- return proxy;
- },
- onContentReady: function()
- {
- for (var i = 0; i != this._proxies.length; i++)
- this._proxies[i].onContentReady();
- },
- __proto__: WebInspector.NativeBreakpointsSidebarPane.prototype
- }
- /**
- * @constructor
- * @extends {WebInspector.SidebarPane}
- * @param {WebInspector.DOMBreakpointsSidebarPane} pane
- * @param {WebInspector.Panel} panel
- */
- WebInspector.DOMBreakpointsSidebarPane.Proxy = function(pane, panel)
- {
- WebInspector.View._assert(!pane.titleElement.firstChild, "Cannot create proxy for a sidebar pane with a toolbar");
- WebInspector.SidebarPane.call(this, pane.title());
- this.registerRequiredCSS("breakpointsList.css");
- this._wrappedPane = pane;
- this._panel = panel;
- this.bodyElement.remove();
- this.bodyElement = this._wrappedPane.bodyElement;
- }
- WebInspector.DOMBreakpointsSidebarPane.Proxy.prototype = {
- expand: function()
- {
- this._wrappedPane.expand();
- },
- onContentReady: function()
- {
- if (this._panel.isShowing())
- this._reattachBody();
- WebInspector.SidebarPane.prototype.onContentReady.call(this);
- },
- wasShown: function()
- {
- WebInspector.SidebarPane.prototype.wasShown.call(this);
- this._reattachBody();
- },
- _reattachBody: function()
- {
- if (this.bodyElement.parentNode !== this.element)
- this.element.appendChild(this.bodyElement);
- },
- __proto__: WebInspector.SidebarPane.prototype
- }
- /**
- * @type {?WebInspector.DOMBreakpointsSidebarPane}
- */
- WebInspector.domBreakpointsSidebarPane = null;
|