Changeset 194717 in webkit
- Timestamp:
- Jan 7, 2016 1:27:48 PM (8 years ago)
- Location:
- trunk/Source/WebInspectorUI
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebInspectorUI/ChangeLog
r194704 r194717 1 2016-01-07 Devin Rousso <dcrousso+webkit@gmail.com> 2 3 Web Inspector: Make creating new rules in the Styles sidebar simpler 4 https://bugs.webkit.org/show_bug.cgi?id=152726 5 6 Reviewed by Timothy Hatcher. 7 8 When creating a new rules of any kind, first look to see if it already exists in 9 another rule that has no properties. If found, focus/select it instead of creating 10 a new rule. Otherwise, create the new rule like normal. 11 12 Also changed the way in which previously-focused sections/tree-items are saved 13 to rely upon the selector of the new rule and whether the section for that rule 14 is empty and an inspector rule. 15 16 * Localizations/en.lproj/localizedStrings.js: 17 18 * UserInterface/Models/CSSStyleDeclaration.js: 19 (WebInspector.CSSStyleDeclaration.prototype.isInspectorRule): 20 Returns true if the style is an inspector rule. 21 22 (WebInspector.CSSStyleDeclaration.prototype.hasProperties): 23 Returns true if the style has CSS properties. 24 25 * UserInterface/Models/DOMNodeStyles.js: 26 (WebInspector.DOMNodeStyles.prototype.rulesForSelector.ruleHasSelector): 27 (WebInspector.DOMNodeStyles.prototype.rulesForSelector): 28 Returns a list of CSSRule that match the given selector and are not 29 in media queries. 30 31 * UserInterface/Views/BoxModelDetailsSectionRow.js: 32 (WebInspector.BoxModelDetailsSectionRow.prototype._updateMetrics): 33 34 * UserInterface/Views/CSSStyleDeclarationSection.js: 35 (WebInspector.CSSStyleDeclarationSection.prototype._handleContextMenuEvent): 36 37 * UserInterface/Views/CSSStyleDeclarationTextEditor.js: 38 (WebInspector.CSSStyleDeclarationTextEditor.prototype.commentAllProperties): 39 40 * UserInterface/Views/RulesStyleDetailsPanel.js: 41 (WebInspector.RulesStyleDetailsPanel.prototype.refresh.appendStyleSection): 42 (WebInspector.RulesStyleDetailsPanel.prototype.refresh.cssStyleDeclarationSectionEditorFocused): 43 Now saves the newly focused section as the previously-focused section. 44 45 (WebInspector.RulesStyleDetailsPanel.prototype.cssStyleDeclarationSectionFocusNewInspectorRuleWithSelector): 46 Renamed from cssStyleDeclarationSectionFocusNextNewInspectorRule. Now needs 47 a selector argument. 48 49 (WebInspector.RulesStyleDetailsPanel.prototype.newRuleButtonClicked): 50 (WebInspector.RulesStyleDetailsPanel.prototype.sectionForStyle): 51 Returns the first section that has a style with matching selector. 52 53 (WebInspector.RulesStyleDetailsPanel.prototype.focusEmptySectionWithStyle): 54 Finds the section corresponding to the given style and, if empty, focuses it. 55 56 (WebInspector.RulesStyleDetailsPanel.prototype.nodeStylesRefreshed): 57 No longer clears the previously-focused section. 58 59 * UserInterface/Views/VisualStyleSelectorSection.js: 60 (WebInspector.VisualStyleSelectorSection): 61 (WebInspector.VisualStyleSelectorSection.prototype.update.createSelectorItem): 62 (WebInspector.VisualStyleSelectorSection.prototype.update): 63 (WebInspector.VisualStyleSelectorSection.prototype.treeItemForStyle): 64 Returns the first tree item that has a style with matching selector. 65 66 (WebInspector.VisualStyleSelectorSection.prototype.selectEmptyStyleTreeItem): 67 Finds the tree item corresponding to the given style and, if empty, selects it. 68 69 (WebInspector.VisualStyleSelectorSection.prototype._addNewRule): 70 71 * UserInterface/Views/VisualStyleSelectorTreeItem.js: 72 (WebInspector.VisualStyleSelectorTreeItem): 73 Now requires a delegate object. 74 75 (WebInspector.VisualStyleSelectorTreeItem.prototype._handleContextMenuEvent): 76 1 77 2016-01-06 Joseph Pecoraro <pecoraro@apple.com> 2 78 -
trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
r194686 r194717 300 300 localizedStrings["Float and Clear"] = "Float and Clear"; 301 301 localizedStrings["Flows"] = "Flows"; 302 localizedStrings["Focus %s Rule"] = "Focus %s Rule"; 302 303 localizedStrings["Focused"] = "Focused"; 303 304 localizedStrings["Font"] = "Font"; … … 552 553 localizedStrings["Secure"] = "Secure"; 553 554 localizedStrings["Security Issue"] = "Security Issue"; 555 localizedStrings["Select %s Rule"] = "Select %s Rule"; 554 556 localizedStrings["Selected"] = "Selected"; 555 557 localizedStrings["Selected Element"] = "Selected Element"; -
trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js
r190528 r194717 333 333 } 334 334 335 isInspectorRule() 336 { 337 return this._ownerRule && this._ownerRule.type === WebInspector.CSSStyleSheet.Type.Inspector; 338 } 339 340 hasProperties() 341 { 342 return !!this._properties.length; 343 } 344 335 345 // Protected 336 346 -
trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js
r194547 r194717 269 269 } 270 270 271 rulesForSelector(selector) 272 { 273 selector = selector || this._node.appropriateSelectorFor(true); 274 275 function ruleHasSelector(rule) { 276 return !rule.mediaList.length && rule.selectorText === selector; 277 } 278 279 let rules = this._matchedRules.filter(ruleHasSelector); 280 281 for (let id in this._pseudoElements) 282 rules = rules.concat(this._pseudoElements[id].matchedRules.filter(ruleHasSelector)); 283 284 return rules; 285 } 286 271 287 get matchedRules() 272 288 { -
trunk/Source/WebInspectorUI/UserInterface/Views/BoxModelDetailsSectionRow.js
r188138 r194717 194 194 var boxes = ["content", "padding", "border", "margin", "position"]; 195 195 196 if (!style. properties.length) {196 if (!style.hasProperties()) { 197 197 this.showEmptyMessage(); 198 198 return; -
trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.js
r194547 r194717 445 445 446 446 contextMenu.appendItem(WebInspector.UIString("Duplicate Selector"), () => { 447 if (this._delegate && typeof this._delegate.cssStyleDeclarationSectionFocusNextNewInspectorRule === "function") 448 this._delegate.cssStyleDeclarationSectionFocusNextNewInspectorRule(); 447 if (this._delegate && typeof this._delegate.focusEmptySectionWithStyle === "function") { 448 let existingRules = this._style.nodeStyles.rulesForSelector(this._currentSelectorText); 449 for (let rule of existingRules) { 450 if (this._delegate.focusEmptySectionWithStyle(rule.style)) 451 return; 452 } 453 } 454 455 if (this._delegate && typeof this._delegate.cssStyleDeclarationSectionFocusNewInspectorRuleWithSelector === "function") 456 this._delegate.cssStyleDeclarationSectionFocusNewInspectorRuleWithSelector(this._currentSelectorText); 449 457 450 458 this._style.nodeStyles.addRule(this._currentSelectorText); … … 465 473 this._style.node.setPseudoClassEnabled(pseudoClass, true); 466 474 467 if (this._delegate && typeof this._delegate.cssStyleDeclarationSectionFocusNextNewInspectorRule === "function") 468 this._delegate.cssStyleDeclarationSectionFocusNextNewInspectorRule(); 469 470 if (this._style.ownerRule) { 471 let pseudoSelectors = this._style.ownerRule.selectors.map((selector) => selector.text + pseudoClassSelector); 472 this._style.nodeStyles.addRule(pseudoSelectors.join(",")); 473 } else 474 this._style.nodeStyles.addRule(this._currentSelectorText + pseudoClassSelector); 475 let selector; 476 if (this._style.ownerRule) 477 selector = this._style.ownerRule.selectors.map((selector) => selector.text + pseudoClassSelector).join(", "); 478 else 479 selector = this._currentSelectorText + pseudoClassSelector; 480 481 if (this._delegate && typeof this._delegate.cssStyleDeclarationSectionFocusNewInspectorRuleWithSelector === "function") 482 this._delegate.cssStyleDeclarationSectionFocusNewInspectorRuleWithSelector(selector); 483 484 this._style.nodeStyles.addRule(selector); 475 485 }); 476 486 } … … 481 491 const styleText = "content: \"\";"; 482 492 483 contextMenu.appendItem(WebInspector.UIString("Create %s Rule").format(pseudoElementSelector), () => { 484 if (this._delegate && typeof this._delegate.cssStyleDeclarationSectionFocusNextNewInspectorRule === "function") 485 this._delegate.cssStyleDeclarationSectionFocusNextNewInspectorRule(); 486 487 if (this._style.ownerRule) { 488 let pseudoSelectors = this._style.ownerRule.selectors.map((selector) => selector.text + pseudoElementSelector); 489 this._style.nodeStyles.addRule(pseudoSelectors.join(","), styleText); 490 } else 491 this._style.nodeStyles.addRule(this._currentSelectorText + pseudoElementSelector, styleText); 493 let existingSection = null; 494 if (this._delegate && typeof this._delegate.sectionForStyle === "function") { 495 let existingRules = this._style.nodeStyles.rulesForSelector(this._currentSelectorText + pseudoElementSelector); 496 if (existingRules.length) { 497 // There shouldn't really ever be more than one pseudo-element rule 498 // that is not in a media query. As such, just focus the first rule 499 // on the assumption that it is the only one necessary. 500 existingSection = this._delegate.sectionForStyle(existingRules[0].style); 501 } 502 } 503 504 let title = existingSection ? WebInspector.UIString("Focus %s Rule") : WebInspector.UIString("Create %s Rule"); 505 contextMenu.appendItem(title.format(pseudoElementSelector), () => { 506 if (existingSection) { 507 existingSection.focus(); 508 return; 509 } 510 511 let selector; 512 if (this._style.ownerRule) 513 selector = this._style.ownerRule.selectors.map((selector) => selector.text + pseudoElementSelector).join(", "); 514 else 515 selector = this._currentSelectorText + pseudoElementSelector; 516 517 if (this._delegate && typeof this._delegate.cssStyleDeclarationSectionFocusNewInspectorRuleWithSelector === "function") 518 this._delegate.cssStyleDeclarationSectionFocusNewInspectorRuleWithSelector(selector); 519 520 this._style.nodeStyles.addRule(selector, styleText); 492 521 }); 493 522 } -
trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js
r194568 r194717 339 339 commentAllProperties() 340 340 { 341 if (!this._style. properties.length)341 if (!this._style.hasProperties()) 342 342 return false; 343 343 -
trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js
r192784 r194717 154 154 section.refresh(); 155 155 156 if ( this._focusNextNewInspectorRule && style.ownerRule && style.ownerRule.type === WebInspector.CSSStyleSheet.Type.Inspector) {156 if (style.isInspectorRule() && this._newInspectorRuleSelector === style.selectorText && !style.hasProperties()) { 157 157 this._previousFocusedSection = section; 158 delete this._focusNextNewInspectorRule;158 this._newInspectorRuleSelector = null; 159 159 } 160 160 … … 312 312 } 313 313 314 cssStyleDeclarationSectionEditorFocused( ignoredSection)315 { 316 for ( varsection of this._sections) {317 if (section !== ignoredSection)314 cssStyleDeclarationSectionEditorFocused(focusedSection) 315 { 316 for (let section of this._sections) { 317 if (section !== focusedSection) 318 318 section.clearSelection(); 319 319 } 320 this._previousFocusedSection = focusedSection; 320 321 } 321 322 … … 378 379 } 379 380 380 cssStyleDeclarationSectionFocusNe xtNewInspectorRule()381 { 382 this._ focusNextNewInspectorRule = true;381 cssStyleDeclarationSectionFocusNewInspectorRuleWithSelector(selector) 382 { 383 this._newInspectorRuleSelector = selector; 383 384 } 384 385 … … 388 389 return; 389 390 390 this._focusNextNewInspectorRule = true; 391 this.nodeStyles.addRule(); 391 for (let existingRule of this.nodeStyles.rulesForSelector()) { 392 if (this.focusEmptySectionWithStyle(existingRule.style)) 393 return; 394 } 395 396 this._newInspectorRuleSelector = this.nodeStyles.node.appropriateSelectorFor(true); 397 this.nodeStyles.addRule(this._newInspectorRuleSelector); 398 } 399 400 sectionForStyle(style) 401 { 402 if (style.__rulesSection) 403 return style.__rulesSection; 404 405 for (let section of this._sections) { 406 if (section.style === style) 407 return section; 408 } 409 return null; 410 } 411 412 focusEmptySectionWithStyle(style) 413 { 414 if (style.hasProperties()) 415 return false; 416 417 let section = this.sectionForStyle(style); 418 if (!section) 419 return false; 420 421 section.focus(); 422 return true; 392 423 } 393 424 … … 432 463 } 433 464 434 if (this._previousFocusedSection && this._visible) {465 if (this._previousFocusedSection && this._visible) 435 466 this._previousFocusedSection.focus(); 436 this._previousFocusedSection = null;437 }438 467 } 439 468 -
trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleSelectorSection.js
r194644 r194717 58 58 this._selectors.addEventListener(WebInspector.TreeOutline.Event.SelectionDidChange, this._selectorChanged, this); 59 59 60 this._ focusNextNewInspectorRule = false;60 this._newInspectorRuleSelector = null; 61 61 62 62 let addGlyphElement = useSVGSymbol("Images/Plus13.svg", "visual-style-selector-section-add-rule", WebInspector.UIString("Click to add a new rule.")); … … 97 97 98 98 function createSelectorItem(style, title, subtitle) { 99 let selector = new WebInspector.VisualStyleSelectorTreeItem( style, title, subtitle);99 let selector = new WebInspector.VisualStyleSelectorTreeItem(this, style, title, subtitle); 100 100 selector.addEventListener(WebInspector.VisualStyleSelectorTreeItem.Event.StyleTextReset, this._styleTextReset, this); 101 101 selector.addEventListener(WebInspector.VisualStyleSelectorTreeItem.Event.CheckboxChanged, this._treeElementCheckboxToggled, this); 102 102 this._selectors.appendChild(selector); 103 103 104 if ( this._focusNextNewInspectorRule && style.ownerRule && style.ownerRule.type === WebInspector.CSSStyleSheet.Type.Inspector) {104 if (style.isInspectorRule() && this._newInspectorRuleSelector === style.selectorText && !style.hasProperties()) { 105 105 selector.select(true); 106 106 selector.element.scrollIntoView(); 107 107 this._nodeStyles[WebInspector.VisualStyleSelectorSection.LastSelectedRuleSymbol] = style; 108 this._ focusNextNewInspectorRule = false;108 this._newInspectorRuleSelector = null; 109 109 return; 110 110 } … … 202 202 } 203 203 204 this._ focusNextNewInspectorRule = false;204 this._newInspectorRuleSelector = null; 205 205 } 206 206 … … 211 211 212 212 return this._selectors.selectedTreeElement.representedObject; 213 } 214 215 treeItemForStyle(style) 216 { 217 for (let item of this._selectors.children) { 218 if (item.representedObject === style) 219 return item; 220 } 221 return null; 222 } 223 224 selectEmptyStyleTreeItem(style) 225 { 226 if (style.hasProperties()) 227 return false; 228 229 let treeItem = this.treeItemForStyle(style); 230 if (!treeItem) 231 return false; 232 233 treeItem.select(true, true); 234 return true; 213 235 } 214 236 … … 243 265 _addNewRule(event) 244 266 { 245 if (!this._nodeStyles) 246 return; 247 248 this._nodeStyles.addRule(); 249 this._focusNextNewInspectorRule = true; 267 if (!this._nodeStyles || this._nodeStyles.node.isInShadowTree()) 268 return; 269 270 let selector = this.currentStyle().selectorText; 271 let existingRules = this._nodeStyles.rulesForSelector(selector); 272 for (let rule of existingRules) { 273 if (this.selectEmptyStyleTreeItem(rule.style)) 274 return; 275 } 276 277 this._newInspectorRuleSelector = selector; 278 this._nodeStyles.addRule(selector); 250 279 } 251 280 -
trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleSelectorTreeItem.js
r194547 r194717 26 26 WebInspector.VisualStyleSelectorTreeItem = class VisualStyleSelectorTreeItem extends WebInspector.GeneralTreeElement 27 27 { 28 constructor( style, title, subtitle)28 constructor(delegate, style, title, subtitle) 29 29 { 30 30 let iconClassName; … … 58 58 super(["visual-style-selector-item", iconClassName], title, subtitle, style); 59 59 60 this._delegate = delegate; 61 60 62 this._iconClassName = iconClassName; 61 63 this._lastValue = title; … … 142 144 }); 143 145 144 contextMenu.appendItem(WebInspector.UIString("Reset"), () => { 145 this.representedObject.resetText(); 146 this.dispatchEventToListeners(WebInspector.VisualStyleSelectorTreeItem.Event.StyleTextReset); 147 }); 146 if (this.representedObject.modified) { 147 contextMenu.appendItem(WebInspector.UIString("Reset"), () => { 148 this.representedObject.resetText(); 149 this.dispatchEventToListeners(WebInspector.VisualStyleSelectorTreeItem.Event.StyleTextReset); 150 }); 151 } 148 152 149 153 if (!this.representedObject.ownerRule) … … 170 174 contextMenu.appendItem(WebInspector.UIString("Add %s Rule").format(pseudoClassSelector), () => { 171 175 this.representedObject.node.setPseudoClassEnabled(pseudoClass, true); 172 173 if (this.representedObject.ownerRule) { 174 let pseudoSelectors = this.representedObject.ownerRule.selectors.map((selector) => selector.text + pseudoClassSelector); 175 this.representedObject.nodeStyles.addRule(pseudoSelectors.join(",")); 176 } else 177 this.representedObject.nodeStyles.addRule(this._currentSelectorText + pseudoClassSelector); 176 let pseudoSelectors = this.representedObject.ownerRule.selectors.map((selector) => selector.text + pseudoClassSelector); 177 this.representedObject.nodeStyles.addRule(pseudoSelectors.join(", ")); 178 178 }); 179 179 } … … 184 184 const styleText = "content: \"\";"; 185 185 186 contextMenu.appendItem(WebInspector.UIString("Create %s Rule").format(pseudoElementSelector), () => { 187 if (this.representedObject.ownerRule) { 188 let pseudoSelectors = this.representedObject.ownerRule.selectors.map((selector) => selector.text + pseudoElementSelector); 189 this.representedObject.nodeStyles.addRule(pseudoSelectors.join(","), styleText); 190 } else 191 this.representedObject.nodeStyles.addRule(this._currentSelectorText + pseudoElementSelector, styleText); 186 let existingTreeItem = null; 187 if (this._delegate && typeof this._delegate.treeItemForStyle === "function") { 188 let selectorText = this.representedObject.ownerRule.selectorText; 189 let existingRules = this.representedObject.nodeStyles.rulesForSelector(selectorText + pseudoElementSelector); 190 if (existingRules.length) { 191 // There shouldn't really ever be more than one pseudo-element rule 192 // that is not in a media query. As such, just focus the first rule 193 // on the assumption that it is the only one necessary. 194 existingTreeItem = this._delegate.treeItemForStyle(existingRules[0].style); 195 } 196 } 197 198 let title = existingTreeItem ? WebInspector.UIString("Select %s Rule") : WebInspector.UIString("Create %s Rule"); 199 contextMenu.appendItem(title.format(pseudoElementSelector), () => { 200 if (existingTreeItem) { 201 existingTreeItem.select(true, true); 202 return; 203 } 204 205 let pseudoSelectors = this.representedObject.ownerRule.selectors.map((selector) => selector.text + pseudoElementSelector); 206 this.representedObject.nodeStyles.addRule(pseudoSelectors.join(", "), styleText); 192 207 }); 193 208 }
Note: See TracChangeset
for help on using the changeset viewer.