Title: [222799] trunk/Source/WebInspectorUI
- Revision
- 222799
- Author
- [email protected]
- Date
- 2017-10-03 12:17:23 -0700 (Tue, 03 Oct 2017)
Log Message
Web Inspector: Styles Redesign: support editing of rule selectors
https://bugs.webkit.org/show_bug.cgi?id=177012
Reviewed by Matt Baker.
Clicking or focusing (by tabbing from another field) on a CSS selector should select the text and make the selector
field editable.
Keyboard behavior while editing:
- Enter should commit changes.
- Escape should discard changes.
- Tab should commit changes and navigate to the first property name.
- Shift-Tab should commit changes and navigate to the last rule's property value, if there's one.
* UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js:
(WI.SpreadsheetStyleProperty.prototype._update):
Add tabIndex so the keyboard navigation (Tab & Shift-Tab) to and from selectors works as expected.
* UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css:
(.spreadsheet-css-declaration .selector:focus,):
(.spreadsheet-css-declaration .selector.spreadsheet-selector-field):
(.spreadsheet-css-declaration .selector.spreadsheet-selector-field.editing):
* UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:
(WI.SpreadsheetCSSStyleDeclarationSection.prototype.get selectorEditable):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype.initialLayout):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype.layout):
Split layout into _renderOrigin and _renderSelector, so selector field can be updated separately
from everything else.
(WI.SpreadsheetCSSStyleDeclarationSection.prototype.cssStyleDeclarationTextEditorFocused):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype.spreadsheetSelectorFieldDidChange):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype.spreadsheetSelectorFieldDidDiscard):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype._discardSelectorChange):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype._renderSelector):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype._renderOrigin):
(WI.SpreadsheetSelectorField):
(WI.SpreadsheetSelectorField.prototype.get editing):
(WI.SpreadsheetSelectorField.prototype.startEditing):
(WI.SpreadsheetSelectorField.prototype.stopEditing):
(WI.SpreadsheetSelectorField.prototype._handleClick):
(WI.SpreadsheetSelectorField.prototype._handleFocus):
(WI.SpreadsheetSelectorField.prototype._handleBlur):
(WI.SpreadsheetSelectorField.prototype._handleKeyDown):
Modified Paths
Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (222798 => 222799)
--- trunk/Source/WebInspectorUI/ChangeLog 2017-10-03 19:09:16 UTC (rev 222798)
+++ trunk/Source/WebInspectorUI/ChangeLog 2017-10-03 19:17:23 UTC (rev 222799)
@@ -1,3 +1,50 @@
+2017-10-03 Nikita Vasilyev <[email protected]>
+
+ Web Inspector: Styles Redesign: support editing of rule selectors
+ https://bugs.webkit.org/show_bug.cgi?id=177012
+
+ Reviewed by Matt Baker.
+
+ Clicking or focusing (by tabbing from another field) on a CSS selector should select the text and make the selector
+ field editable.
+
+ Keyboard behavior while editing:
+ - Enter should commit changes.
+ - Escape should discard changes.
+ - Tab should commit changes and navigate to the first property name.
+ - Shift-Tab should commit changes and navigate to the last rule's property value, if there's one.
+
+ * UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js:
+ (WI.SpreadsheetStyleProperty.prototype._update):
+ Add tabIndex so the keyboard navigation (Tab & Shift-Tab) to and from selectors works as expected.
+
+ * UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css:
+ (.spreadsheet-css-declaration .selector:focus,):
+ (.spreadsheet-css-declaration .selector.spreadsheet-selector-field):
+ (.spreadsheet-css-declaration .selector.spreadsheet-selector-field.editing):
+ * UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype.get selectorEditable):
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype.initialLayout):
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype.layout):
+ Split layout into _renderOrigin and _renderSelector, so selector field can be updated separately
+ from everything else.
+
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype.cssStyleDeclarationTextEditorFocused):
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype.spreadsheetSelectorFieldDidChange):
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype.spreadsheetSelectorFieldDidDiscard):
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype._discardSelectorChange):
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype._renderSelector):
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype._renderOrigin):
+
+ (WI.SpreadsheetSelectorField):
+ (WI.SpreadsheetSelectorField.prototype.get editing):
+ (WI.SpreadsheetSelectorField.prototype.startEditing):
+ (WI.SpreadsheetSelectorField.prototype.stopEditing):
+ (WI.SpreadsheetSelectorField.prototype._handleClick):
+ (WI.SpreadsheetSelectorField.prototype._handleFocus):
+ (WI.SpreadsheetSelectorField.prototype._handleBlur):
+ (WI.SpreadsheetSelectorField.prototype._handleKeyDown):
+
2017-10-03 Matt Baker <[email protected]>
Web Inspector: Add View layout tests, make views more testable
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js (222798 => 222799)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js 2017-10-03 19:09:16 UTC (rev 222798)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js 2017-10-03 19:17:23 UTC (rev 222799)
@@ -180,10 +180,14 @@
this._valueElement.textContent = this._property.rawValue;
if (this._property.editable && this._property.enabled) {
+ this._nameElement.tabIndex = 1;
this._nameElement.contentEditable = "plaintext-only";
+ this._nameElement.spellcheck = false;
this._nameElement.addEventListener("input", this.debounce(WI.SpreadsheetStyleProperty.CommitCoalesceDelay)._handleNameChange);
+ this._valueElement.tabIndex = 1;
this._valueElement.contentEditable = "plaintext-only";
+ this._valueElement.spellcheck = false;
this._valueElement.addEventListener("input", this.debounce(WI.SpreadsheetStyleProperty.CommitCoalesceDelay)._handleValueChange);
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css (222798 => 222799)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css 2017-10-03 19:09:16 UTC (rev 222798)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css 2017-10-03 19:17:23 UTC (rev 222799)
@@ -79,6 +79,7 @@
color: hsl(0, 0%, 50%);
}
+.spreadsheet-css-declaration .selector:focus,
.spreadsheet-css-declaration .selector > .matched {
color: black;
}
@@ -92,3 +93,12 @@
height: 10px;
content: url(../Images/Locked.svg);
}
+
+.spreadsheet-css-declaration .selector.spreadsheet-selector-field {
+ outline-offset: -3px;
+}
+
+.spreadsheet-css-declaration .selector.spreadsheet-selector-field.editing {
+ box-shadow: hsla(0, 0%, 0%, 0.5) 0 1px 3px;
+ outline: none !important;
+}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js (222798 => 222799)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js 2017-10-03 19:09:16 UTC (rev 222798)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js 2017-10-03 19:17:23 UTC (rev 222799)
@@ -42,6 +42,11 @@
get style() { return this._style; }
+ get selectorEditable()
+ {
+ return this._style.editable && this._style.ownerRule;
+ }
+
initialLayout()
{
super.initialLayout();
@@ -57,6 +62,11 @@
this._selectorElement.classList.add("selector");
this._headerElement.append(this._selectorElement);
+ if (this.selectorEditable) {
+ this._selectorElement.tabIndex = 1;
+ this._selectorTextField = new WI.SpreadsheetSelectorField(this, this._selectorElement);
+ }
+
this._propertiesEditor = new WI.SpreadsheetCSSStyleDeclarationEditor(this, this._style);
this._propertiesEditor.element.classList.add("properties");
@@ -83,9 +93,45 @@
{
super.layout();
+ this._renderOrigin();
+ this._renderSelector();
+ }
+
+ cssStyleDeclarationTextEditorFocused()
+ {
+ if (this._delegate && typeof this._delegate.cssStyleDeclarationSectionEditorFocused === "function")
+ this._delegate.cssStyleDeclarationSectionEditorFocused(this);
+ }
+
+ spreadsheetSelectorFieldDidChange()
+ {
+ let selectorText = this._selectorElement.textContent.trim();
+ if (!selectorText || selectorText === this._style.ownerRule.selectorText) {
+ this._discardSelectorChange();
+ return;
+ }
+
+ this._style.ownerRule.singleFireEventListener(WI.CSSRule.Event.SelectorChanged, this._renderSelector, this);
+
+ this._style.ownerRule.selectorText = selectorText;
+ }
+
+ spreadsheetSelectorFieldDidDiscard()
+ {
+ this._discardSelectorChange();
+ }
+
+ // Private
+
+ _discardSelectorChange()
+ {
+ // Re-render selector for syntax highlighting.
+ this._renderSelector();
+ }
+
+ _renderSelector()
+ {
this._selectorElement.removeChildren();
- this._originElement.removeChildren();
-
this._selectorElements = [];
let appendSelector = (selector, matched) => {
@@ -145,6 +191,27 @@
} else
appendSelectorTextKnownToMatch(this._style.ownerRule.selectorText);
+ break;
+
+ case WI.CSSStyleDeclaration.Type.Inline:
+ this._selectorElement.textContent = WI.UIString("Style Attribute");
+ this._selectorElement.classList.add("style-attribute");
+ break;
+
+ case WI.CSSStyleDeclaration.Type.Attribute:
+ appendSelectorTextKnownToMatch(this._style.node.displayName);
+ break;
+ }
+ }
+
+ _renderOrigin()
+ {
+ this._originElement.removeChildren();
+
+ switch (this._style.type) {
+ case WI.CSSStyleDeclaration.Type.Rule:
+ console.assert(this._style.ownerRule);
+
if (this._style.ownerRule.sourceCodeLocation) {
let options = {
dontFloat: true,
@@ -194,39 +261,14 @@
this._originElement.title = WI.UIString("%s cannot be modified").format(styleTitle);
}
}
-
break;
- case WI.CSSStyleDeclaration.Type.Inline:
- this._selectorElement.textContent = WI.UIString("Style Attribute");
- this._selectorElement.classList.add("style-attribute");
- break;
-
case WI.CSSStyleDeclaration.Type.Attribute:
- appendSelectorTextKnownToMatch(this._style.node.displayName);
this._originElement.append(WI.UIString("HTML Attributes"));
break;
}
}
- cssStyleDeclarationTextEditorFocused()
- {
- if (this._delegate && typeof this._delegate.cssStyleDeclarationSectionEditorFocused === "function")
- this._delegate.cssStyleDeclarationSectionEditorFocused(this);
- }
-
- get locked()
- {
- return !this._style.editable;
- }
-
- get selectorEditable()
- {
- return this._style.editable && this._style.ownerRule;
- }
-
- // Private
-
_createMediaHeader()
{
if (!this._style.ownerRule)
@@ -252,3 +294,112 @@
};
WI.SpreadsheetCSSStyleDeclarationSection.MatchedSelectorElementStyleClassName = "matched";
+
+WI.SpreadsheetSelectorField = class SpreadsheetSelectorField
+{
+ constructor(delegate, element)
+ {
+ this._delegate = delegate;
+ this._element = element;
+ this._element.classList.add("spreadsheet-selector-field");
+
+ this._element.addEventListener("click", this._handleClick.bind(this));
+ this._element.addEventListener("focus", this._handleFocus.bind(this));
+ this._element.addEventListener("blur", this._handleBlur.bind(this));
+ this._element.addEventListener("keydown", this._handleKeyDown.bind(this));
+
+ this._editing = false;
+ }
+
+ // Public
+
+ get editing() { return this._editing; }
+
+ startEditing()
+ {
+ if (this._editing)
+ return;
+
+ this._editing = true;
+
+ let element = this._element;
+ element.classList.add("editing");
+ element.contentEditable = "plaintext-only";
+ element.spellcheck = false;
+ element.scrollIntoViewIfNeeded(false);
+
+ // Disable syntax highlighting.
+ element.textContent = element.textContent;
+
+ let selection = window.getSelection();
+ let range = document.createRange();
+ range.selectNodeContents(element);
+ selection.removeAllRanges();
+ selection.addRange(range);
+ }
+
+ stopEditing()
+ {
+ if (!this._editing)
+ return;
+
+ this._editing = false;
+ this._element.classList.remove("editing");
+ this._element.contentEditable = false;
+ }
+
+ // Private
+
+ _handleClick(event)
+ {
+ this.startEditing();
+ }
+
+ _handleFocus(event)
+ {
+ this.startEditing();
+ }
+
+ _handleBlur(event)
+ {
+ this.stopEditing();
+
+ if (this._delegate && typeof this._delegate.spreadsheetSelectorFieldDidChange === "function")
+ this._delegate.spreadsheetSelectorFieldDidChange();
+ }
+
+ _handleKeyDown(event)
+ {
+ if (event.key === "Enter" && !this._editing) {
+ event.stopImmediatePropagation();
+ event.preventDefault();
+
+ this.startEditing();
+ return;
+ }
+
+ if (event.key === "Enter" || event.key === "Tab") {
+ if (event.key === "Enter") {
+ event.stopImmediatePropagation();
+ event.preventDefault();
+ }
+
+ this.stopEditing();
+
+ if (this._delegate && typeof this._delegate.spreadsheetSelectorFieldDidChange === "function")
+ this._delegate.spreadsheetSelectorFieldDidChange();
+
+ return;
+ }
+
+ if (event.key === "Escape") {
+ event.stopImmediatePropagation();
+ event.preventDefault();
+
+ this.stopEditing();
+
+ if (this._delegate && typeof this._delegate.spreadsheetSelectorFieldDidDiscard === "function")
+ this._delegate.spreadsheetSelectorFieldDidDiscard();
+ }
+ }
+};
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes