Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: Source/devtools/front_end/elements/ElementsPanel.js

Issue 1304173004: Devtools UI: Add node-specific actions into a ghost toolbar in DOM (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | Source/devtools/front_end/elements/ElementsTreeElement.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> 3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
4 * Copyright (C) 2009 Joseph Pecoraro 4 * Copyright (C) 2009 Joseph Pecoraro
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 9 *
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 this._splitWidget.show(this.element); 44 this._splitWidget.show(this.element);
45 45
46 this._searchableView = new WebInspector.SearchableView(this); 46 this._searchableView = new WebInspector.SearchableView(this);
47 this._searchableView.setMinimumSize(25, 28); 47 this._searchableView.setMinimumSize(25, 28);
48 this._searchableView.setPlaceholder(WebInspector.UIString("Find by string, s elector, or XPath")); 48 this._searchableView.setPlaceholder(WebInspector.UIString("Find by string, s elector, or XPath"));
49 var stackElement = this._searchableView.element; 49 var stackElement = this._searchableView.element;
50 50
51 this._contentElement = createElement("div"); 51 this._contentElement = createElement("div");
52 var crumbsContainer = createElement("div"); 52 var crumbsContainer = createElement("div");
53 this._showLayoutEditor = false; 53 this._showLayoutEditor = false;
54 if (Runtime.experiments.isEnabled("materialDesign")) { 54 if (Runtime.experiments.isEnabled("materialDesign"))
55 this._toolbar = this._createElementsToolbar(); 55 this._initializeActionsToolbar();
56 var toolbar = stackElement.createChild("div", "elements-topbar hbox");
57 toolbar.appendChild(this._toolbar.element);
58 }
59 stackElement.appendChild(this._contentElement); 56 stackElement.appendChild(this._contentElement);
60 stackElement.appendChild(crumbsContainer); 57 stackElement.appendChild(crumbsContainer);
61 58
62 this._elementsPanelTreeOutilneSplit = new WebInspector.SplitWidget(false, tr ue, "treeOutlineAnimationTimelineWidget", 300, 300); 59 this._elementsPanelTreeOutilneSplit = new WebInspector.SplitWidget(false, tr ue, "treeOutlineAnimationTimelineWidget", 300, 300);
63 this._elementsPanelTreeOutilneSplit.hideSidebar(); 60 this._elementsPanelTreeOutilneSplit.hideSidebar();
64 this._elementsPanelTreeOutilneSplit.setMainWidget(this._searchableView); 61 this._elementsPanelTreeOutilneSplit.setMainWidget(this._searchableView);
65 this._splitWidget.setMainWidget(this._elementsPanelTreeOutilneSplit); 62 this._splitWidget.setMainWidget(this._elementsPanelTreeOutilneSplit);
66 63
67 this._contentElement.id = "elements-content"; 64 this._contentElement.id = "elements-content";
68 // FIXME: crbug.com/425984 65 // FIXME: crbug.com/425984
(...skipping 27 matching lines...) Expand all
96 this._updateSidebarPosition(); 93 this._updateSidebarPosition();
97 this._loadSidebarViews(); 94 this._loadSidebarViews();
98 95
99 /** @type {!Array.<!WebInspector.ElementsTreeOutline>} */ 96 /** @type {!Array.<!WebInspector.ElementsTreeOutline>} */
100 this._treeOutlines = []; 97 this._treeOutlines = [];
101 /** @type {!Map.<!WebInspector.DOMModel, !WebInspector.ElementsTreeOutline>} */ 98 /** @type {!Map.<!WebInspector.DOMModel, !WebInspector.ElementsTreeOutline>} */
102 this._modelToTreeOutline = new Map(); 99 this._modelToTreeOutline = new Map();
103 WebInspector.targetManager.observeTargets(this); 100 WebInspector.targetManager.observeTargets(this);
104 WebInspector.moduleSetting("showUAShadowDOM").addChangeListener(this._showUA ShadowDOMChanged.bind(this)); 101 WebInspector.moduleSetting("showUAShadowDOM").addChangeListener(this._showUA ShadowDOMChanged.bind(this));
105 WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspec tor.DOMModel.Events.DocumentUpdated, this._documentUpdatedEvent, this); 102 WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspec tor.DOMModel.Events.DocumentUpdated, this._documentUpdatedEvent, this);
106 if (Runtime.experiments.isEnabled("materialDesign"))
107 WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebIn spector.DOMModel.Events.MarkersChanged, this._updateToolbarButtons, this);
108 WebInspector.extensionServer.addEventListener(WebInspector.ExtensionServer.E vents.SidebarPaneAdded, this._extensionSidebarPaneAdded, this); 103 WebInspector.extensionServer.addEventListener(WebInspector.ExtensionServer.E vents.SidebarPaneAdded, this._extensionSidebarPaneAdded, this);
109 } 104 }
110 105
111 WebInspector.ElementsPanel._elementsSidebarViewTitleSymbol = Symbol("title"); 106 WebInspector.ElementsPanel._elementsSidebarViewTitleSymbol = Symbol("title");
112 107
113 WebInspector.ElementsPanel.prototype = { 108 WebInspector.ElementsPanel.prototype = {
114 /**
115 * @return {!WebInspector.Toolbar}
116 */
117 _createElementsToolbar: function()
118 {
119 var toolbar = new WebInspector.ExtensibleToolbar("elements-toolbar");
120 toolbar.element.classList.add("elements-toolbar");
121 this._hideElementButton = new WebInspector.ToolbarButton(WebInspector.UI String("Hide element"), "visibility-off-toolbar-item");
122 this._hideElementButton.setAction("elements.hide-element");
123 toolbar.appendToolbarItem(this._hideElementButton);
124
125 this._editAsHTMLButton = new WebInspector.ToolbarButton(WebInspector.UIS tring("Edit as HTML"), "edit-toolbar-item");
126 this._editAsHTMLButton.setAction("elements.edit-as-html");
127 toolbar.appendToolbarItem(this._editAsHTMLButton);
128 toolbar.appendSeparator();
129
130 this._forceElementStateButton = new WebInspector.ToolbarMenuButton(WebIn spector.UIString("Force element state"), "pin-toolbar-item", this._showForceElem entStateMenu.bind(this));
131 toolbar.appendToolbarItem(this._forceElementStateButton);
132 this._breakpointsButton = new WebInspector.ToolbarMenuButton(WebInspecto r.UIString("Toggle breakpoints"), "add-breakpoint-toolbar-item", this._showBreak pointsMenu.bind(this));
133 toolbar.appendToolbarItem(this._breakpointsButton);
134
135 toolbar.appendSeparator();
136 if (Runtime.experiments.isEnabled("layoutEditor") && !Runtime.queryParam ("remoteFrontend")) {
137 this._layoutEditorButton = new WebInspector.ToolbarButton(WebInspect or.UIString("Toggle Layout Editor"), "layout-editor-toolbar-item");
138 toolbar.appendToolbarItem(this._layoutEditorButton);
139 this._layoutEditorButton.addEventListener("click", this._toggleLayou tEditor, this);
140 toolbar.appendSeparator();
141 }
142 return toolbar;
143 },
144
145 _toggleHideElement: function() 109 _toggleHideElement: function()
146 { 110 {
147 var node = this.selectedDOMNode(); 111 var node = this.selectedDOMNode();
148 var treeOutline = this._treeOutlineForNode(node); 112 var treeOutline = this._treeOutlineForNode(node);
149 if (!node || !treeOutline) 113 if (!node || !treeOutline)
150 return; 114 return;
151 treeOutline.toggleHideElement(node); 115 treeOutline.toggleHideElement(node);
152 }, 116 },
153 117
154 _updateToolbarButtons: function()
155 {
156 if (!Runtime.experiments.isEnabled("materialDesign"))
157 return;
158 var node = this.selectedDOMNode();
159 if (!node)
160 return;
161 var classText = node.getAttribute("class");
162 var treeOutline = this._treeOutlineForNode(node);
163 this._hideElementButton.setToggled(treeOutline && treeOutline.isToggledT oHidden(node));
164 this._editAsHTMLButton.setToggled(false);
165 this._breakpointsButton.setEnabled(!node.pseudoType());
166 this._breakpointsButton.setToggled(WebInspector.domBreakpointsSidebarPan e.hasBreakpoints(node));
167 this._forceElementStateButton.setEnabled(node.nodeType() === Node.ELEMEN T_NODE && !node.pseudoType());
168 this._forceElementStateButton.setToggled(!!WebInspector.CSSStyleModel.fr omNode(node).pseudoState(node).length);
169 },
170
171 _toggleEditAsHTML: function() 118 _toggleEditAsHTML: function()
172 { 119 {
173 var node = this.selectedDOMNode(); 120 var node = this.selectedDOMNode();
174 var treeOutline = this._treeOutlineForNode(node); 121 var treeOutline = this._treeOutlineForNode(node);
175 if (!node || !treeOutline) 122 if (!node || !treeOutline)
176 return; 123 return;
177 124
178 var startEditing = true; 125 var startEditing = true;
179 if (Runtime.experiments.isEnabled("materialDesign")) { 126 if (Runtime.experiments.isEnabled("materialDesign")) {
180 startEditing = !this._editAsHTMLButton.toggled(); 127 startEditing = !this._editAsHTMLButton.toggled();
181 this._editAsHTMLButton.setToggled(startEditing); 128 this._editAsHTMLButton.setToggled(startEditing);
182 } 129 }
183 treeOutline.toggleEditAsHTML(node, startEditing, this._updateToolbarButt ons.bind(this)); 130 treeOutline.toggleEditAsHTML(node, startEditing, this._updateActionsTool barButtons.bind(this, node));
184 }, 131 },
185 132
186 /** 133 /**
187 * @param {!WebInspector.ContextMenu} contextMenu 134 * @param {!WebInspector.ContextMenu} contextMenu
188 */ 135 */
189 _showBreakpointsMenu: function(contextMenu) 136 _showBreakpointsMenu: function(contextMenu)
190 { 137 {
191 var node = this.selectedDOMNode(); 138 var node = this.selectedDOMNode();
192 if (!node) 139 if (!node)
193 return; 140 return;
194 WebInspector.domBreakpointsSidebarPane.populateNodeContextMenu(node, con textMenu, false); 141 WebInspector.domBreakpointsSidebarPane.populateNodeContextMenu(node, con textMenu, false);
195 }, 142 },
196 143
197 /** 144 /**
198 * @param {!WebInspector.ContextMenu} contextMenu 145 * @param {!WebInspector.ContextMenu} contextMenu
199 */ 146 */
200 _showForceElementStateMenu: function(contextMenu) 147 _showForceElementStateMenu: function(contextMenu)
201 { 148 {
202 var node = this.selectedDOMNode(); 149 var node = this.selectedDOMNode();
203 if (!node) 150 if (!node)
204 return; 151 return;
205 WebInspector.ElementsTreeElement.populateForcedPseudoStateItems(contextM enu, node); 152 WebInspector.ElementsTreeElement.populateForcedPseudoStateItems(contextM enu, node);
206 }, 153 },
207 154
155 _initializeActionsToolbar: function()
pfeldman 2015/09/16 21:53:14 Move this above for a better diff.
156 {
157 this._nodeActionsElement = createElementWithClass("div", "node-actions-c ontainer");
158 var button = this._nodeActionsElement.createChild("div", "node-actions-t oggle");
159 button.addEventListener("click", this._toggleActionsToolbar.bind(this, n ull));
160 this._nodeActionsToolbar = new WebInspector.Toolbar();
161 this._nodeActionsElement.appendChild(this._nodeActionsToolbar.element);
162 this._nodeActionsElement.addEventListener("mousedown", consumeEvent);
163 WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebIn spector.DOMModel.Events.MarkersChanged, this._markersChanged, this);
164
165 this._nodeActionsToolbar.element.classList.add("node-actions-toolbar");
166 this._hideElementButton = new WebInspector.ToolbarButton(WebInspector.UI String("Hide element"), "visibility-off-toolbar-item");
167 this._hideElementButton.setAction("elements.hide-element");
168 this._nodeActionsToolbar.appendToolbarItem(this._hideElementButton);
169 this._forceElementStateButton = new WebInspector.ToolbarMenuButton(WebIn spector.UIString("Force element state"), "pin-toolbar-item", this._showForceElem entStateMenu.bind(this));
170 this._nodeActionsToolbar.appendToolbarItem(this._forceElementStateButton );
171 this._breakpointsButton = new WebInspector.ToolbarMenuButton(WebInspecto r.UIString("Toggle breakpoints"), "add-breakpoint-toolbar-item", this._showBreak pointsMenu.bind(this));
172 this._nodeActionsToolbar.appendToolbarItem(this._breakpointsButton);
173 this._nodeActionsToolbar.appendSeparator();
174 this._editAsHTMLButton = new WebInspector.ToolbarButton(WebInspector.UIS tring("Edit as HTML"), "edit-toolbar-item");
175 this._editAsHTMLButton.setAction("elements.edit-as-html");
176 this._nodeActionsToolbar.appendToolbarItem(this._editAsHTMLButton);
177 },
178
179 /**
180 * @param {!WebInspector.DOMNode} node
181 */
182 _updateActionsToolbarButtons: function(node)
pfeldman 2015/09/16 21:53:14 Move this back for a better diff.
183 {
184 if (!Runtime.experiments.isEnabled("materialDesign"))
185 return;
186 var classText = node.getAttribute("class");
187 var treeOutline = this._treeOutlineForNode(node);
188 this._hideElementButton.setToggled(treeOutline && treeOutline.isToggledT oHidden(node));
189 this._editAsHTMLButton.setToggled(false);
190 this._breakpointsButton.setEnabled(!node.pseudoType());
191 this._breakpointsButton.setToggled(WebInspector.domBreakpointsSidebarPan e.hasBreakpoints(node));
192 this._forceElementStateButton.setEnabled(node.nodeType() === Node.ELEMEN T_NODE && !node.pseudoType());
193 this._forceElementStateButton.setToggled(!!WebInspector.CSSStyleModel.fr omNode(node).pseudoState(node).length);
194 },
195
196 /**
197 * @param {!WebInspector.DOMNode} node
198 */
199 _updateActions: function(node)
200 {
201 if (!Runtime.experiments.isEnabled("materialDesign"))
202 return;
203 var actionsToolbar = this._nodeActionsElement;
pfeldman 2015/09/16 21:53:14 get those later - you don't need them for non-elem
204 var treeElement = this._treeOutlineForNode(node).selectedTreeElement;
205
206 if (node.nodeType() !== Node.ELEMENT_NODE) {
207 this._nodeActionsElement.remove();
208 return;
209 }
210
211 if (treeElement.selected && node.nodeType() === Node.ELEMENT_NODE && act ionsToolbar._node !== node) {
pfeldman 2015/09/16 21:53:14 this is already true.
pfeldman 2015/09/16 21:53:14 we use __node when we bind properties to elements.
212 treeElement.gutterElement().appendChild(actionsToolbar);
213 if (this._forceShowActions) {
pfeldman 2015/09/16 21:53:14 why do we need this flag?
samli 2015/09/16 22:12:53 This lets us auto-show the toolbar if there is a m
214 this._toggleActionsToolbar(false);
215 delete this._forceShowActions;
216 }
217 this._ensureActionsToolbarVisible();
218 actionsToolbar._node = node;
219 }
220
221 if (actionsToolbar._node === node) {
222 if (!this._actionsToolbarVisible() && !this._forceShowActions && nod e.markers().length) {
223 this._toggleActionsToolbar(true);
224 this._forceShowActions = true;
225 }
226 }
227 },
228
229 /**
230 * @param {?boolean} toggled
231 */
232 _toggleActionsToolbar: function(toggled)
233 {
234 if (!this._nodeActionsElement)
235 return;
236 if (toggled === null)
237 toggled = !this._actionsToolbarVisible();
238 this._nodeActionsElement.classList.toggle("expanded", toggled);
239 this._ensureActionsToolbarVisible();
240 },
241
242 _ensureActionsToolbarVisible: function()
243 {
244 if (!this._actionsToolbarVisible())
pfeldman 2015/09/16 21:53:14 ensureVisible bails about it actionsToolbar is not
samli 2015/09/16 22:12:53 Renamed.
245 return;
246 var toolbarElement = this._nodeActionsToolbar.element;
247 if (toolbarElement.totalOffsetTop() < this.element.totalOffsetTop()) {
248 toolbarElement.style.top = this._nodeActionsElement.parentElement.of fsetHeight + "px";
249 toolbarElement.classList.add("node-actions-toolbar-below");
250 } else {
251 toolbarElement.style.top = "";
252 toolbarElement.classList.remove("node-actions-toolbar-below");
253 }
254 },
255
256 /**
257 * @return {boolean}
258 */
259 _actionsToolbarVisible: function()
260 {
261 return this._nodeActionsElement.classList.contains("expanded");
262 },
263
264 /**
265 * @param {!WebInspector.Event} event
266 */
267 _markersChanged: function(event)
268 {
269 var node = /** @type {!WebInspector.DOMNode} */ (event.data);
270 if (node !== this.selectedDOMNode())
271 return;
272 this._updateActions(node);
273 this._updateActionsToolbarButtons(node);
274 },
275
208 _loadSidebarViews: function() 276 _loadSidebarViews: function()
209 { 277 {
210 var extensions = self.runtime.extensions("@WebInspector.Widget"); 278 var extensions = self.runtime.extensions("@WebInspector.Widget");
211 279
212 for (var i = 0; i < extensions.length; ++i) { 280 for (var i = 0; i < extensions.length; ++i) {
213 var descriptor = extensions[i].descriptor(); 281 var descriptor = extensions[i].descriptor();
214 if (descriptor["location"] !== "elements-panel") 282 if (descriptor["location"] !== "elements-panel")
215 continue; 283 continue;
216 284
217 var title = WebInspector.UIString(descriptor["title"]); 285 var title = WebInspector.UIString(descriptor["title"]);
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 if (!selectedNode && this._lastValidSelectedNode) 456 if (!selectedNode && this._lastValidSelectedNode)
389 this._selectedPathOnReset = this._lastValidSelectedNode.path(); 457 this._selectedPathOnReset = this._lastValidSelectedNode.path();
390 458
391 this._breadcrumbs.setSelectedNode(selectedNode); 459 this._breadcrumbs.setSelectedNode(selectedNode);
392 460
393 WebInspector.context.setFlavor(WebInspector.DOMNode, selectedNode); 461 WebInspector.context.setFlavor(WebInspector.DOMNode, selectedNode);
394 462
395 if (selectedNode) { 463 if (selectedNode) {
396 selectedNode.setAsInspectedNode(); 464 selectedNode.setAsInspectedNode();
397 this._lastValidSelectedNode = selectedNode; 465 this._lastValidSelectedNode = selectedNode;
466 this._updateActions(selectedNode);
467 this._updateActionsToolbarButtons(selectedNode);
398 } 468 }
399 WebInspector.notifications.dispatchEventToListeners(WebInspector.Notific ationService.Events.SelectedNodeChanged); 469 WebInspector.notifications.dispatchEventToListeners(WebInspector.Notific ationService.Events.SelectedNodeChanged);
400 this._selectedNodeChangedForTest(); 470 this._selectedNodeChangedForTest();
401 if (Runtime.experiments.isEnabled("materialDesign"))
402 this._updateToolbarButtons();
403 }, 471 },
404 472
405 _selectedNodeChangedForTest: function() { }, 473 _selectedNodeChangedForTest: function() { },
406 474
407 _reset: function() 475 _reset: function()
408 { 476 {
409 delete this.currentQuery; 477 delete this.currentQuery;
410 }, 478 },
411 479
412 /** 480 /**
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 setWidgetBelowDOM: function(widget) 1149 setWidgetBelowDOM: function(widget)
1082 { 1150 {
1083 if (widget) { 1151 if (widget) {
1084 this._elementsPanelTreeOutilneSplit.setSidebarWidget(widget); 1152 this._elementsPanelTreeOutilneSplit.setSidebarWidget(widget);
1085 this._elementsPanelTreeOutilneSplit.showBoth(true); 1153 this._elementsPanelTreeOutilneSplit.showBoth(true);
1086 } else { 1154 } else {
1087 this._elementsPanelTreeOutilneSplit.hideSidebar(true); 1155 this._elementsPanelTreeOutilneSplit.hideSidebar(true);
1088 } 1156 }
1089 }, 1157 },
1090 1158
1091 _toggleLayoutEditor: function()
1092 {
1093 this._showLayoutEditor = !this._showLayoutEditor;
1094 this._layoutEditorButton.setToggled(this._showLayoutEditor);
1095 var targets = WebInspector.targetManager.targets();
1096
1097 if (this._showLayoutEditor)
1098 WebInspector.inspectElementModeController.disable();
1099 else
1100 WebInspector.inspectElementModeController.enable();
1101
1102 var mode = this._showLayoutEditor ? DOMAgent.InspectMode.ShowLayoutEdito r : DOMAgent.InspectMode.None;
1103 for (var domModel of WebInspector.DOMModel.instances())
1104 domModel.setInspectMode(mode);
1105 },
1106
1107 __proto__: WebInspector.Panel.prototype 1159 __proto__: WebInspector.Panel.prototype
1108 } 1160 }
1109 1161
1110 /** 1162 /**
1111 * @constructor 1163 * @constructor
1112 * @implements {WebInspector.ContextMenu.Provider} 1164 * @implements {WebInspector.ContextMenu.Provider}
1113 */ 1165 */
1114 WebInspector.ElementsPanel.ContextMenuProvider = function() 1166 WebInspector.ElementsPanel.ContextMenuProvider = function()
1115 { 1167 {
1116 } 1168 }
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 WebInspector.ElementsPanel.HiddenMarkerDecorator.prototype = { 1327 WebInspector.ElementsPanel.HiddenMarkerDecorator.prototype = {
1276 /** 1328 /**
1277 * @override 1329 * @override
1278 * @param {!WebInspector.DOMNode} node 1330 * @param {!WebInspector.DOMNode} node
1279 * @return {?{title: string, color: string}} 1331 * @return {?{title: string, color: string}}
1280 */ 1332 */
1281 decorate: function(node) 1333 decorate: function(node)
1282 { 1334 {
1283 return { color: "#555", title: WebInspector.UIString("Element is hidden" ) }; 1335 return { color: "#555", title: WebInspector.UIString("Element is hidden" ) };
1284 } 1336 }
1285 } 1337 }
OLDNEW
« no previous file with comments | « no previous file | Source/devtools/front_end/elements/ElementsTreeElement.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698