Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) IBM Corp. 2009 All rights reserved. | 2 * Copyright (C) IBM Corp. 2009 All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 /** | 31 /** |
| 32 * @constructor | 32 * @constructor |
| 33 * @extends {WebInspector.SidebarPane} | 33 * @extends {WebInspector.SidebarPane} |
| 34 */ | 34 */ |
| 35 WebInspector.WatchExpressionsSidebarPane = function() | 35 WebInspector.WatchExpressionsSidebarPane = function() |
| 36 { | 36 { |
| 37 WebInspector.SidebarPane.call(this, WebInspector.UIString("Watch Expressions ")); | 37 WebInspector.SidebarPane.call(this, WebInspector.UIString("Watch Expressions ")); |
| 38 | 38 |
| 39 this.section = new WebInspector.WatchExpressionsSection(); | 39 this._requiresUpdate = true; |
| 40 this.bodyElement.appendChild(this.section.element); | 40 /** @type {!Array.<!WebInspector.WatchExpression>} */ |
| 41 this._watchExpressions = []; | |
| 42 | |
| 43 | |
| 44 this.bodyElement.classList.add("vbox"); | |
|
pfeldman
2015/02/18 20:51:00
add("vbox", "watch-expressions")
sergeyv
2015/02/19 10:53:46
Done.
| |
| 45 this.bodyElement.classList.add("watch-expressions"); | |
| 46 this.bodyElement.addEventListener("contextmenu", this._contextMenu.bind(this ), false); | |
| 41 | 47 |
| 42 var refreshButton = this.titleElement.createChild("button", "pane-title-butt on refresh"); | 48 var refreshButton = this.titleElement.createChild("button", "pane-title-butt on refresh"); |
| 43 refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this ), false); | 49 refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this ), false); |
| 44 refreshButton.title = WebInspector.UIString("Refresh"); | 50 refreshButton.title = WebInspector.UIString("Refresh"); |
| 45 | 51 |
| 46 var addButton = this.titleElement.createChild("button", "pane-title-button a dd"); | 52 var addButton = this.titleElement.createChild("button", "pane-title-button a dd"); |
| 47 addButton.addEventListener("click", this._addButtonClicked.bind(this), false ); | 53 addButton.addEventListener("click", this._addButtonClicked.bind(this), false ); |
| 48 addButton.title = WebInspector.UIString("Add watch expression"); | 54 addButton.title = WebInspector.UIString("Add watch expression"); |
| 49 | |
| 50 this._requiresUpdate = true; | |
| 51 WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this.refreshExpressions, this); | 55 WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this.refreshExpressions, this); |
| 52 } | 56 } |
| 53 | 57 |
| 54 WebInspector.WatchExpressionsSidebarPane.prototype = { | 58 WebInspector.WatchExpressionsSidebarPane.prototype = { |
| 55 wasShown: function() | 59 wasShown: function() |
| 56 { | 60 { |
| 57 this._refreshExpressionsIfNeeded(); | 61 this._refreshExpressionsIfNeeded(); |
| 58 }, | 62 }, |
| 59 | 63 |
| 60 refreshExpressions: function() | 64 refreshExpressions: function() |
| 61 { | 65 { |
| 62 this._requiresUpdate = true; | 66 this._requiresUpdate = true; |
| 63 this._refreshExpressionsIfNeeded(); | 67 this._refreshExpressionsIfNeeded(); |
| 64 }, | 68 }, |
| 65 | 69 |
| 66 /** | 70 /** |
| 67 * @param {string} expression | 71 * @param {string} expressionString |
| 68 */ | 72 */ |
| 69 addExpression: function(expression) | 73 addExpression: function(expressionString) |
| 70 { | 74 { |
| 71 this.section.addExpression(expression); | |
| 72 this.expand(); | 75 this.expand(); |
| 76 if (this._requiresUpdate) { | |
| 77 this._rebuildWatchExpressions(); | |
| 78 delete this._requiresUpdate; | |
| 79 } | |
| 80 this._createWatchExpression(expressionString); | |
| 81 this._saveExpressions(); | |
| 82 }, | |
| 83 | |
| 84 _saveExpressions: function() | |
| 85 { | |
| 86 var toSave = []; | |
| 87 for (var i = 0; i < this._watchExpressions.length; i++) | |
| 88 if (this._watchExpressions[i].expression()) | |
| 89 toSave.push(this._watchExpressions[i].expression()); | |
| 90 | |
| 91 WebInspector.settings.watchExpressions.set(toSave); | |
| 73 }, | 92 }, |
| 74 | 93 |
| 75 _refreshExpressionsIfNeeded: function() | 94 _refreshExpressionsIfNeeded: function() |
| 76 { | 95 { |
| 77 if (this._requiresUpdate && this.isShowing()) { | 96 if (this._requiresUpdate && this.isShowing()) { |
| 78 this.section.update(); | 97 this._rebuildWatchExpressions(); |
| 79 delete this._requiresUpdate; | 98 delete this._requiresUpdate; |
| 80 } else | 99 } else |
| 81 this._requiresUpdate = true; | 100 this._requiresUpdate = true; |
| 82 }, | 101 }, |
| 83 | 102 |
| 103 /** | |
| 104 * @param {?Event} event | |
| 105 */ | |
| 84 _addButtonClicked: function(event) | 106 _addButtonClicked: function(event) |
| 85 { | 107 { |
| 86 event.consume(); | 108 if (event) |
| 109 event.consume(true); | |
| 87 this.expand(); | 110 this.expand(); |
| 88 this.section.addNewExpressionAndEdit(); | 111 this._createWatchExpression(null).startEditing(); |
| 89 }, | 112 }, |
| 90 | 113 |
| 114 /** | |
| 115 * @param {!Event} event | |
| 116 */ | |
| 91 _refreshButtonClicked: function(event) | 117 _refreshButtonClicked: function(event) |
| 92 { | 118 { |
| 93 event.consume(); | 119 event.consume(); |
| 94 this.refreshExpressions(); | 120 this.refreshExpressions(); |
| 95 }, | 121 }, |
| 96 | 122 |
| 123 _rebuildWatchExpressions: function() | |
| 124 { | |
| 125 this.bodyElement.removeChildren(); | |
| 126 this._watchExpressions = []; | |
| 127 this._emptyElement = this.bodyElement.createChild("div", "info"); | |
| 128 this._emptyElement.textContent = WebInspector.UIString("No Watch Express ions"); | |
| 129 var watchExpressionStrings = WebInspector.settings.watchExpressions.get( ); | |
| 130 for (var i = 0; i < watchExpressionStrings.length; ++i) { | |
| 131 var expression = watchExpressionStrings[i]; | |
| 132 if (!expression) | |
| 133 continue; | |
| 134 | |
| 135 this._createWatchExpression(expression); | |
| 136 } | |
| 137 }, | |
| 138 | |
| 139 /** | |
| 140 * @param {?string} expression | |
| 141 * @return {!WebInspector.WatchExpression} | |
| 142 */ | |
| 143 _createWatchExpression: function(expression) | |
| 144 { | |
| 145 this._emptyElement.classList.add("hidden"); | |
| 146 var watchExpression = new WebInspector.WatchExpression(expression); | |
| 147 watchExpression.addEventListener(WebInspector.WatchExpression.Events.Exp ressionUpdated, this._watchExpressionUpdated.bind(this)); | |
| 148 this.bodyElement.appendChild(watchExpression.element()); | |
| 149 this._watchExpressions.push(watchExpression); | |
| 150 return watchExpression; | |
| 151 }, | |
| 152 | |
| 153 /** | |
| 154 * @param {!WebInspector.Event} event | |
| 155 */ | |
| 156 _watchExpressionUpdated: function(event) | |
| 157 { | |
| 158 var watchExpression = /** @type {!WebInspector.WatchExpression} */ (even t.target); | |
| 159 if (!watchExpression.expression()) { | |
| 160 this._watchExpressions.remove(watchExpression); | |
| 161 this.bodyElement.removeChild(watchExpression.element()); | |
| 162 this._emptyElement.classList.toggle("hidden", !!this._watchExpressio ns.length); | |
| 163 } | |
| 164 | |
| 165 this._saveExpressions(); | |
| 166 }, | |
| 167 | |
| 168 /** | |
| 169 * @param {!Event} event | |
| 170 */ | |
| 171 _contextMenu: function(event) | |
| 172 { | |
| 173 var contextMenu = new WebInspector.ContextMenu(event); | |
| 174 this._populateContextMenu(contextMenu, event); | |
| 175 contextMenu.show(); | |
| 176 }, | |
| 177 | |
| 178 /** | |
| 179 * @param {!WebInspector.ContextMenu} contextMenu | |
| 180 * @param {!Event} event | |
| 181 */ | |
| 182 _populateContextMenu: function(contextMenu, event) | |
| 183 { | |
| 184 var isEditing = false; | |
| 185 for (var watchExpression of this._watchExpressions) | |
| 186 isEditing |= watchExpression.isEditing(); | |
| 187 | |
| 188 if (!isEditing) | |
| 189 contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^watch ^expression"), this._addButtonClicked.bind(this)); | |
| 190 | |
| 191 if (this._watchExpressions.length > 1) | |
| 192 contextMenu.appendItem(WebInspector.UIString.capitalize("Delete ^all ^watch ^expressions"), this._deleteAllButtonClicked.bind(this)); | |
| 193 | |
| 194 for (var watchExpression of this._watchExpressions) | |
| 195 if (watchExpression.element().containsEventPoint(event)) | |
| 196 watchExpression._populateContextMenu(contextMenu, event); | |
| 197 }, | |
| 198 | |
| 199 _deleteAllButtonClicked: function() | |
| 200 { | |
| 201 this._watchExpressions = []; | |
| 202 this._saveExpressions(); | |
| 203 this._rebuildWatchExpressions(); | |
| 204 }, | |
| 205 | |
| 97 __proto__: WebInspector.SidebarPane.prototype | 206 __proto__: WebInspector.SidebarPane.prototype |
| 98 } | 207 } |
| 99 | 208 |
| 100 /** | 209 /** |
| 101 * @constructor | 210 * @constructor |
| 102 * @extends {WebInspector.PropertiesSection} | 211 * @extends {WebInspector.Object} |
| 212 * @param {?string} expression | |
| 103 */ | 213 */ |
| 104 WebInspector.WatchExpressionsSection = function() | 214 WebInspector.WatchExpression = function(expression) |
| 105 { | 215 { |
| 106 this._watchObjectGroupId = "watch-group"; | 216 this._expression = expression; |
| 107 | 217 this._element = createElementWithClass("div", "watch-expression monospace"); |
| 108 WebInspector.PropertiesSection.call(this, ""); | 218 this._editing = false; |
| 109 this.treeElementConstructor = WebInspector.ObjectPropertyTreeElement; | 219 |
| 110 this.skipProto = false; | 220 this._createWatchExpression(null, false); |
| 111 | 221 this.update(); |
| 112 this.emptyElement = createElementWithClass("div", "info"); | |
| 113 this.emptyElement.textContent = WebInspector.UIString("No Watch Expressions" ); | |
| 114 | |
| 115 /** @type {!Array.<string>} */ | |
| 116 this.watchExpressions = WebInspector.settings.watchExpressions.get(); | |
| 117 | |
| 118 this.headerElement.className = "hidden"; | |
| 119 this.editable = true; | |
| 120 this.expand(); | |
| 121 this.propertiesElement.classList.add("watch-expressions"); | |
| 122 | |
| 123 this.element.addEventListener("mousemove", this._mouseMove.bind(this), true) ; | |
| 124 this.element.addEventListener("mouseleave", this._mouseLeave.bind(this), tru e); | |
| 125 this.element.addEventListener("dblclick", this._sectionDoubleClick.bind(this ), false); | |
| 126 this.emptyElement.addEventListener("contextmenu", this._emptyElementContextM enu.bind(this), false); | |
| 127 } | 222 } |
| 128 | 223 |
| 129 WebInspector.WatchExpressionsSection.NewWatchExpression = "\xA0"; | 224 WebInspector.WatchExpression._watchObjectGroupId = "watch-group"; |
| 130 | 225 |
| 131 WebInspector.WatchExpressionsSection.prototype = { | 226 WebInspector.WatchExpression.Events = { |
| 132 /** | 227 ExpressionUpdated: "ExpressionUpdated" |
| 133 * @param {!Event=} e | 228 } |
| 134 */ | 229 |
| 135 update: function(e) | 230 WebInspector.WatchExpression.prototype = { |
| 136 { | 231 |
| 137 if (e) | 232 /** |
| 138 e.consume(); | 233 * @return {!Element} |
| 139 | 234 */ |
| 140 /*** | 235 element: function() |
| 141 * @param {string} expression | 236 { |
| 142 * @param {number} watchIndex | 237 return this._element; |
| 143 * @param {?WebInspector.RemoteObject} result | 238 }, |
| 144 * @param {boolean} wasThrown | 239 |
| 145 * @this {WebInspector.WatchExpressionsSection} | 240 /** |
| 146 */ | 241 * @return {?string} |
| 147 function appendResult(expression, watchIndex, result, wasThrown) | 242 */ |
| 148 { | 243 expression: function() |
| 149 if (!result) | 244 { |
| 150 return; | 245 return this._expression; |
| 151 | 246 }, |
| 152 var property = new WebInspector.RemoteObjectProperty(expression, res ult); | 247 |
| 153 property.watchIndex = watchIndex; | 248 update: function() |
| 154 property.wasThrown = wasThrown; | 249 { |
| 155 | |
| 156 // To clarify what's going on here: | |
| 157 // In the outer function, we calculate the number of properties | |
| 158 // that we're going to be updating, and set that in the | |
| 159 // propertyCount variable. | |
| 160 // In this function, we test to see when we are processing the | |
| 161 // last property, and then call the superclass's updateProperties() | |
| 162 // method to get all the properties refreshed at once. | |
| 163 properties.push(property); | |
| 164 | |
| 165 if (properties.length == propertyCount) { | |
| 166 this.updateProperties(properties); | |
| 167 | |
| 168 // check to see if we just added a new watch expression, | |
| 169 // which will always be the last property | |
| 170 if (this._newExpressionAdded) { | |
| 171 delete this._newExpressionAdded; | |
| 172 | |
| 173 var treeElement = this.findAddedTreeElement(); | |
| 174 if (treeElement) | |
| 175 treeElement.startEditing(); | |
| 176 } | |
| 177 | |
| 178 // Force displaying delete button for hovered element. | |
| 179 if (this._lastMouseMovePageY) | |
| 180 this._updateHoveredElement(this._lastMouseMovePageY); | |
| 181 } | |
| 182 } | |
| 183 | |
| 184 // TODO: pass exact injected script id. | |
| 185 WebInspector.targetManager.targets().forEach(function(target) { target.r untimeAgent().releaseObjectGroup(this._watchObjectGroupId); }, this); | |
| 186 var properties = []; | |
| 187 | |
| 188 // Count the properties, so we known when to call this.updateProperties( ) | |
| 189 // in appendResult() | |
| 190 var propertyCount = 0; | |
| 191 for (var i = 0; i < this.watchExpressions.length; ++i) { | |
| 192 if (!this.watchExpressions[i]) | |
| 193 continue; | |
| 194 ++propertyCount; | |
| 195 } | |
| 196 | |
| 197 // Now process all the expressions, since we have the actual count, | |
| 198 // which is checked in the appendResult inner function. | |
| 199 var currentExecutionContext = WebInspector.context.flavor(WebInspector.E xecutionContext); | 250 var currentExecutionContext = WebInspector.context.flavor(WebInspector.E xecutionContext); |
| 200 if (currentExecutionContext) { | 251 if (currentExecutionContext && this._expression) |
| 201 for (var i = 0; i < this.watchExpressions.length; ++i) { | 252 currentExecutionContext.evaluate(this._expression, WebInspector.Watc hExpression._watchObjectGroupId, false, true, false, false, this._createWatchExp ression.bind(this)); |
| 202 var expression = this.watchExpressions[i]; | 253 }, |
| 203 if (!expression) | 254 |
| 204 continue; | 255 startEditing: function() |
| 205 | 256 { |
| 206 currentExecutionContext.evaluate(expression, this._watchObjectGr oupId, false, true, false, false, appendResult.bind(this, expression, i)); | 257 this._editing = true; |
| 207 } | 258 this._element.removeChild(this._objectPresentationElement); |
| 208 } | 259 var newDiv = this._element.createChild("div"); |
| 209 | 260 newDiv.textContent = this._nameElement.textContent; |
| 210 if (!propertyCount) { | 261 this._textPrompt = new WebInspector.ObjectPropertyPrompt(); |
| 211 this.element.appendChild(this.emptyElement); | 262 this._textPrompt.renderAsBlock(); |
| 212 this.propertiesElement.remove(); | 263 var proxyElement = this._textPrompt.attachAndStartEditing(newDiv, this._ finishEditing.bind(this, this._expression)); |
| 213 this.propertiesTreeOutline.removeChildren(); | 264 proxyElement.classList.add("watch-expression-text-prompt-proxy"); |
| 265 proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false); | |
| 266 this._element.getComponentSelection().setBaseAndExtent(newDiv, 0, newDiv , 1); | |
| 267 }, | |
| 268 | |
| 269 /** | |
| 270 * @return {boolean} | |
| 271 */ | |
| 272 isEditing: function() | |
| 273 { | |
| 274 return !!this._editing; | |
| 275 }, | |
| 276 | |
| 277 /** | |
| 278 * @param {?string} newExpression | |
| 279 * @param {!Event} event | |
| 280 */ | |
| 281 _finishEditing: function(newExpression, event) | |
| 282 { | |
| 283 if (event) | |
| 284 event.consume(true); | |
| 285 | |
| 286 this._editing = false; | |
| 287 this._textPrompt.detach(); | |
| 288 delete this._textPrompt; | |
| 289 this._element.removeChildren(); | |
| 290 this._element.appendChild(this._objectPresentationElement); | |
| 291 this._updateExpression(newExpression); | |
| 292 }, | |
| 293 | |
| 294 /** | |
| 295 * @param {!Event} event | |
| 296 */ | |
| 297 _dblClickOnWatchExpression: function(event) | |
| 298 { | |
| 299 event.consume(); | |
| 300 if (!this.isEditing()) | |
| 301 this.startEditing(); | |
| 302 }, | |
| 303 | |
| 304 /** | |
| 305 * @param {?string} newExpression | |
| 306 */ | |
| 307 _updateExpression: function(newExpression) | |
| 308 { | |
| 309 this._expression = newExpression; | |
| 310 this.update(); | |
| 311 this.dispatchEventToListeners(WebInspector.WatchExpression.Events.Expres sionUpdated); | |
| 312 }, | |
| 313 | |
| 314 /** | |
| 315 * @param {!Event} event | |
| 316 */ | |
| 317 _deleteWatchExpression: function(event) | |
| 318 { | |
| 319 event.consume(true); | |
| 320 this._updateExpression(null); | |
| 321 }, | |
| 322 | |
| 323 /** | |
| 324 * @param {?WebInspector.RemoteObject} result | |
| 325 * @param {boolean} wasThrown | |
| 326 */ | |
| 327 _createWatchExpression: function(result, wasThrown) | |
| 328 { | |
| 329 this._result = result; | |
| 330 | |
| 331 var titleElement = createElementWithClass("div", "watch-expression-title "); | |
| 332 this._nameElement = WebInspector.ObjectPropertiesSection.createNameEleme nt(this._expression); | |
| 333 if (wasThrown || !result) { | |
| 334 this._valueElement = createElementWithClass("span", "console-formatt ed-undefined value"); | |
| 335 titleElement.classList.add("dimmed"); | |
| 336 this._valueElement.textContent = WebInspector.UIString("<not availab le>"); | |
| 214 } else { | 337 } else { |
| 215 this.element.appendChild(this.propertiesElement); | 338 this._valueElement = WebInspector.ObjectPropertiesSection.createValu eElement(result, wasThrown, titleElement); |
| 216 this.emptyElement.remove(); | 339 } |
| 217 } | 340 var separatorElement = createElementWithClass("span", "separator"); |
| 218 }, | 341 separatorElement.textContent = ": "; |
| 219 | 342 titleElement.appendChildren(this._nameElement, separatorElement, this._v alueElement); |
| 220 /** | 343 |
| 221 * @param {!Array.<!WebInspector.RemoteObjectProperty>} properties | 344 if (!wasThrown && result && result.hasChildren) { |
| 222 */ | 345 var objectPropertiesSection = new WebInspector.ObjectPropertiesSecti on(result, titleElement); |
| 223 updateProperties: function(properties) | 346 this._objectPresentationElement = objectPropertiesSection.element; |
| 224 { | 347 objectPropertiesSection.headerElement.addEventListener("click", this ._onSectionClick.bind(this, objectPropertiesSection), false); |
| 225 this.propertiesTreeOutline.removeChildren(); | 348 objectPropertiesSection.doNotExpandOnTitleClick(); |
| 226 WebInspector.ObjectPropertyTreeElement.populateWithProperties(this.prope rtiesTreeOutline, properties, [], | 349 this._installHover(objectPropertiesSection.headerElement); |
| 227 WebInspector.WatchExpressionTreeElement, WebInspector.WatchExpressio nsSection.CompareProperties, false, null); | |
| 228 | |
| 229 this.propertiesForTest = properties; | |
| 230 }, | |
| 231 | |
| 232 /** | |
| 233 * @param {string} expression | |
| 234 */ | |
| 235 addExpression: function(expression) | |
| 236 { | |
| 237 this.watchExpressions.push(expression); | |
| 238 this.saveExpressions(); | |
| 239 this.update(); | |
| 240 }, | |
| 241 | |
| 242 addNewExpressionAndEdit: function() | |
| 243 { | |
| 244 this._newExpressionAdded = true; | |
| 245 this.watchExpressions.push(WebInspector.WatchExpressionsSection.NewWatch Expression); | |
| 246 this.update(); | |
| 247 }, | |
| 248 | |
| 249 _sectionDoubleClick: function(event) | |
| 250 { | |
| 251 if (event.target !== this.element && event.target !== this.propertiesEle ment && event.target !== this.emptyElement) | |
| 252 return; | |
| 253 event.consume(); | |
| 254 this.addNewExpressionAndEdit(); | |
| 255 }, | |
| 256 | |
| 257 /** | |
| 258 * @param {!WebInspector.ObjectPropertyTreeElement} element | |
| 259 * @param {?string} value | |
| 260 */ | |
| 261 updateExpression: function(element, value) | |
| 262 { | |
| 263 if (value === null) { | |
| 264 var index = element.property.watchIndex; | |
| 265 this.watchExpressions.splice(index, 1); | |
| 266 } else { | 350 } else { |
| 267 this.watchExpressions[element.property.watchIndex] = value; | 351 this._objectPresentationElement = this._element.createChild("div", " primitive-value"); |
| 268 } | 352 this._objectPresentationElement.appendChild(titleElement); |
| 269 this.saveExpressions(); | 353 this._installHover(this._objectPresentationElement); |
| 270 this.update(); | 354 } |
| 271 }, | 355 |
| 272 | 356 this._element.removeChildren(); |
| 273 _deleteAllExpressions: function() | 357 this._element.appendChild(this._objectPresentationElement); |
| 274 { | 358 this._element.addEventListener("dblclick", this._dblClickOnWatchExpressi on.bind(this)); |
| 275 this.watchExpressions = []; | 359 }, |
| 276 this.saveExpressions(); | 360 |
| 277 this.update(); | 361 /** |
| 278 }, | 362 * @param {!Element} hoverableElement |
| 279 | 363 */ |
| 280 /** | 364 _installHover: function(hoverableElement) |
| 281 * @return {?TreeElement} | 365 { |
| 282 */ | |
| 283 findAddedTreeElement: function() | |
| 284 { | |
| 285 var children = this.propertiesTreeOutline.children; | |
| 286 for (var i = 0; i < children.length; ++i) { | |
| 287 if (children[i].property.name === WebInspector.WatchExpressionsSecti on.NewWatchExpression) | |
| 288 return children[i]; | |
| 289 } | |
| 290 return null; | |
| 291 }, | |
| 292 | |
| 293 /** | |
| 294 * @return {number} | |
| 295 */ | |
| 296 saveExpressions: function() | |
| 297 { | |
| 298 var toSave = []; | |
| 299 for (var i = 0; i < this.watchExpressions.length; i++) | |
| 300 if (this.watchExpressions[i]) | |
| 301 toSave.push(this.watchExpressions[i]); | |
| 302 | |
| 303 WebInspector.settings.watchExpressions.set(toSave); | |
| 304 return toSave.length; | |
| 305 }, | |
| 306 | |
| 307 _mouseMove: function(e) | |
| 308 { | |
| 309 if (this.propertiesElement.firstChild) | |
| 310 this._updateHoveredElement(e.pageY); | |
| 311 }, | |
| 312 | |
| 313 _mouseLeave: function() | |
| 314 { | |
| 315 if (this._hoveredElement) { | |
| 316 this._hoveredElement.classList.remove("hovered"); | |
| 317 delete this._hoveredElement; | |
| 318 } | |
| 319 delete this._lastMouseMovePageY; | |
| 320 }, | |
| 321 | |
| 322 _updateHoveredElement: function(pageY) | |
| 323 { | |
| 324 var candidateElement = this.propertiesElement.firstChild; | |
| 325 while (true) { | |
| 326 var next = candidateElement.nextSibling; | |
| 327 while (next && !next.clientHeight) | |
| 328 next = next.nextSibling; | |
| 329 if (!next || next.totalOffsetTop() > pageY) | |
| 330 break; | |
| 331 candidateElement = next; | |
| 332 } | |
| 333 | |
| 334 if (this._hoveredElement !== candidateElement) { | |
| 335 if (this._hoveredElement) | |
| 336 this._hoveredElement.classList.remove("hovered"); | |
| 337 if (candidateElement) | |
| 338 candidateElement.classList.add("hovered"); | |
| 339 this._hoveredElement = candidateElement; | |
| 340 } | |
| 341 | |
| 342 this._lastMouseMovePageY = pageY; | |
| 343 }, | |
| 344 | |
| 345 _emptyElementContextMenu: function(event) | |
| 346 { | |
| 347 var contextMenu = new WebInspector.ContextMenu(event); | |
| 348 contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^watch ^exp ression"), this.addNewExpressionAndEdit.bind(this)); | |
| 349 contextMenu.show(); | |
| 350 }, | |
| 351 | |
| 352 __proto__: WebInspector.PropertiesSection.prototype | |
| 353 } | |
| 354 | |
| 355 /** | |
| 356 * @param {!WebInspector.RemoteObjectProperty} propertyA | |
| 357 * @param {!WebInspector.RemoteObjectProperty} propertyB | |
| 358 * @return {number} | |
| 359 */ | |
| 360 WebInspector.WatchExpressionsSection.CompareProperties = function(propertyA, pro pertyB) | |
| 361 { | |
| 362 if (propertyA.watchIndex == propertyB.watchIndex) | |
| 363 return 0; | |
| 364 else if (propertyA.watchIndex < propertyB.watchIndex) | |
| 365 return -1; | |
| 366 else | |
| 367 return 1; | |
| 368 } | |
| 369 | |
| 370 /** | |
| 371 * @constructor | |
| 372 * @extends {WebInspector.ObjectPropertyTreeElement} | |
| 373 * @param {!WebInspector.RemoteObjectProperty} property | |
| 374 */ | |
| 375 WebInspector.WatchExpressionTreeElement = function(property) | |
| 376 { | |
| 377 WebInspector.ObjectPropertyTreeElement.call(this, property); | |
| 378 } | |
| 379 | |
| 380 WebInspector.WatchExpressionTreeElement.prototype = { | |
| 381 /** | |
| 382 * @override | |
| 383 * @return {*} | |
| 384 */ | |
| 385 elementIdentity: function() | |
| 386 { | |
| 387 return this.property.name; | |
| 388 }, | |
| 389 | |
| 390 update: function() | |
| 391 { | |
| 392 WebInspector.ObjectPropertyTreeElement.prototype.update.call(this); | |
| 393 | |
| 394 if (this.property.wasThrown) { | |
| 395 this.valueElement.textContent = WebInspector.UIString("<not availabl e>"); | |
| 396 this.listItemElement.classList.add("dimmed"); | |
| 397 } else { | |
| 398 this.listItemElement.classList.remove("dimmed"); | |
| 399 } | |
| 400 | |
| 401 var deleteButton = createElementWithClass("button", "delete-button"); | 366 var deleteButton = createElementWithClass("button", "delete-button"); |
| 402 deleteButton.title = WebInspector.UIString("Delete watch expression"); | 367 deleteButton.title = WebInspector.UIString("Delete watch expression"); |
| 403 deleteButton.addEventListener("click", this._deleteButtonClicked.bind(th is), false); | 368 deleteButton.addEventListener("click", this._deleteWatchExpression.bind( this), false); |
| 404 this.listItemElement.addEventListener("contextmenu", this._contextMenu.b ind(this), false); | 369 hoverableElement.insertBefore(deleteButton, hoverableElement.firstChild) ; |
| 405 this.listItemElement.insertBefore(deleteButton, this.listItemElement.fir stChild); | 370 hoverableElement.addEventListener("mousemove", this._mouseMove.bind(this ), true); |
| 371 hoverableElement.addEventListener("mouseleave", this._mouseLeave.bind(th is), true); | |
| 372 }, | |
| 373 | |
| 374 /** | |
| 375 * @param {!WebInspector.ObjectPropertiesSection} objectPropertiesSection | |
| 376 * @param {!Event} event | |
| 377 */ | |
| 378 _onSectionClick: function(objectPropertiesSection, event) | |
| 379 { | |
| 380 event.consume(true); | |
| 381 if (event.detail == 1) { | |
| 382 this._preventClickTimeout = setTimeout(handleClick, 333); | |
|
pfeldman
2015/02/18 20:51:00
You don't need this anymore.
sergeyv
2015/02/19 10:53:46
We still need this to correctly handle dbl click
| |
| 383 } else { | |
| 384 clearTimeout(this._preventClickTimeout); | |
| 385 delete this._preventClickTimeout; | |
| 386 } | |
| 387 | |
| 388 function handleClick() | |
| 389 { | |
| 390 if (objectPropertiesSection.expanded) | |
| 391 objectPropertiesSection.collapse(); | |
| 392 else | |
| 393 objectPropertiesSection.expand(); | |
| 394 } | |
| 395 }, | |
| 396 | |
| 397 /** | |
| 398 * @param {!Event} event | |
| 399 */ | |
| 400 _promptKeyDown: function(event) | |
| 401 { | |
| 402 if (isEnterKey(event)) { | |
| 403 this._finishEditing(this._textPrompt.text(), event); | |
| 404 return; | |
| 405 } | |
| 406 if (event.keyIdentifier === "U+001B") { // Esc | |
| 407 this._finishEditing(this._expression, event); | |
| 408 return; | |
| 409 } | |
| 406 }, | 410 }, |
| 407 | 411 |
| 408 /** | 412 /** |
| 409 * @param {!WebInspector.ContextMenu} contextMenu | 413 * @param {!WebInspector.ContextMenu} contextMenu |
| 410 * @override | 414 * @param {!Event} event |
| 411 */ | 415 */ |
| 412 populateContextMenu: function(contextMenu) | 416 _populateContextMenu: function(contextMenu, event) |
| 413 { | 417 { |
| 414 if (!this.isEditing()) { | 418 if (!this.isEditing()) |
| 415 contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^watch ^expression"), this.treeOutline.section.addNewExpressionAndEdit.bind(this.treeOu tline.section)); | 419 contextMenu.appendItem(WebInspector.UIString.capitalize("Delete ^wat ch ^expression"), this._updateExpression.bind(this, null)); |
| 416 contextMenu.appendItem(WebInspector.UIString.capitalize("Delete ^wat ch ^expression"), this._deleteButtonClicked.bind(this, null)); | 420 |
| 417 } | 421 if (!this.isEditing() && this._result && (this._result.type === "number" || this._result.type === "string")) |
| 418 if (this.treeOutline.section.watchExpressions.length > 1) | |
| 419 contextMenu.appendItem(WebInspector.UIString.capitalize("Delete ^all ^watch ^expressions"), this._deleteAllButtonClicked.bind(this)); | |
| 420 if (!this.isEditing() && (this.property.value.type === "number" || this. property.value.type === "string")) | |
| 421 contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^value "), this._copyValueButtonClicked.bind(this)); | 422 contextMenu.appendItem(WebInspector.UIString.capitalize("Copy ^value "), this._copyValueButtonClicked.bind(this)); |
| 422 }, | 423 |
| 423 | 424 if (this._valueElement.containsEventPoint(event)) |
| 424 _contextMenu: function(event) | 425 contextMenu.appendApplicableItems(this._result); |
| 425 { | |
| 426 var contextMenu = new WebInspector.ContextMenu(event); | |
| 427 this.populateContextMenu(contextMenu); | |
| 428 contextMenu.show(); | |
| 429 }, | |
| 430 | |
| 431 _deleteAllButtonClicked: function() | |
| 432 { | |
| 433 this.treeOutline.section._deleteAllExpressions(); | |
| 434 }, | |
| 435 | |
| 436 _deleteButtonClicked: function(event) | |
| 437 { | |
| 438 if (event) | |
| 439 event.consume(); | |
| 440 this.treeOutline.section.updateExpression(this, null); | |
| 441 }, | 426 }, |
| 442 | 427 |
| 443 _copyValueButtonClicked: function() | 428 _copyValueButtonClicked: function() |
| 444 { | 429 { |
| 445 InspectorFrontendHost.copyText(this.valueElement.textContent); | 430 InspectorFrontendHost.copyText(this._valueElement.textContent); |
| 446 }, | 431 }, |
| 447 | 432 |
| 448 /** | 433 _mouseMove: function() |
| 449 * @override | 434 { |
| 450 * @return {boolean} | 435 this._element.classList.add("hovered"); |
|
pfeldman
2015/02/18 20:51:00
why not :hover style?
sergeyv
2015/02/19 10:53:46
Done.
| |
| 451 */ | 436 }, |
| 452 renderPromptAsBlock: function() | 437 |
| 453 { | 438 _mouseLeave: function() |
| 454 return true; | 439 { |
| 455 }, | 440 this._element.classList.remove("hovered"); |
| 456 | 441 }, |
| 457 /** | 442 |
| 458 * @override | 443 __proto__: WebInspector.Object.prototype |
| 459 * @return {{element: !Element, value: (string|undefined)}} | |
| 460 */ | |
| 461 elementAndValueToEdit: function() | |
| 462 { | |
| 463 return { element: this.nameElement, value: this.property.name.trim() }; | |
| 464 }, | |
| 465 | |
| 466 /** | |
| 467 * @override | |
| 468 */ | |
| 469 editingCancelled: function(element, context) | |
| 470 { | |
| 471 if (!context.elementToEdit.textContent) | |
| 472 this.treeOutline.section.updateExpression(this, null); | |
| 473 | |
| 474 WebInspector.ObjectPropertyTreeElement.prototype.editingCancelled.call(t his, element, context); | |
| 475 }, | |
| 476 | |
| 477 /** | |
| 478 * @override | |
| 479 * @param {string} expression | |
| 480 */ | |
| 481 applyExpression: function(expression) | |
| 482 { | |
| 483 expression = expression.trim(); | |
| 484 this.property.name = expression || null; | |
| 485 this.treeOutline.section.updateExpression(this, expression); | |
| 486 }, | |
| 487 | |
| 488 __proto__: WebInspector.ObjectPropertyTreeElement.prototype | |
| 489 } | 444 } |
| OLD | NEW |