[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-10851-g50815da
apavlov at chromium.org
apavlov at chromium.org
Wed Dec 22 18:30:57 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 1faa001a91894b278135f71d9d1ff2d640ca9ddf
Author: apavlov at chromium.org <apavlov at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Dec 13 15:06:26 2010 +0000
2010-12-08 Alexander Pavlov <apavlov at chromium.org>
Reviewed by Joseph Pecoraro.
Web Inspector: Enable CSS property editing name/value-wise (like Firebug does)
https://bugs.webkit.org/show_bug.cgi?id=50565
For CSS property editing, the property name and value have become two fields separated
by a colon (rather than one field containing the full property text.) A user can tab
between the name and value fields forward and backward. A colon typed in the name field
and a semicolon in the value field (unless found inside a string) act as a Tab and focus
the next editable field (while applying the entire property value.)
Now a user can tab through all editable styles for an element, even across rule boundaries.
WebCore:
* inspector/front-end/BreakpointsSidebarPane.js:
(WebInspector.XHRBreakpointsSidebarPane.prototype._startEditingBreakpoint):
* inspector/front-end/DataGrid.js:
(WebInspector.DataGrid.prototype._startEditingColumnOfDataGridNode):
(WebInspector.DataGrid.prototype._startEditing):
* inspector/front-end/ElementsTreeOutline.js:
(WebInspector.ElementsTreeElement.prototype._startEditingAttribute):
(WebInspector.ElementsTreeElement.prototype._startEditingTextNode):
(WebInspector.ElementsTreeElement.prototype._startEditingTagName):
(WebInspector.ElementsTreeElement.prototype._startEditingAsHTML):
* inspector/front-end/MetricsSidebarPane.js:
(WebInspector.MetricsSidebarPane.prototype.startEditing):
* inspector/front-end/ObjectPropertiesSection.js:
(WebInspector.ObjectPropertyTreeElement.prototype.startEditing):
* inspector/front-end/Section.js:
(WebInspector.Section):
(WebInspector.Section.prototype.get subtitleAsTextForTest):
(WebInspector.Section.prototype.get nextSibling):
(WebInspector.Section.prototype.get previousSibling):
* inspector/front-end/SourceFrame.js:
(WebInspector.SourceFrame.prototype._editBreakpointCondition):
* inspector/front-end/StylesSidebarPane.js:
(WebInspector.StylePropertiesSection.prototype.nextEditableSibling):
(WebInspector.StylePropertiesSection.prototype.previousEditableSibling):
(WebInspector.StylePropertiesSection.prototype.addNewBlankProperty):
(WebInspector.StylePropertiesSection.prototype.startEditingSelector):
(WebInspector.StylePropertiesSection.prototype.editingSelectorCommitted):
(WebInspector.StylePropertyTreeElement.prototype.):
(WebInspector.StylePropertyTreeElement.prototype):
* inspector/front-end/TextViewer.js:
(WebInspector.TextViewer.prototype._handleDoubleClick):
* inspector/front-end/WatchExpressionsSidebarPane.js:
(WebInspector.WatchExpressionTreeElement.prototype.startEditing):
* inspector/front-end/inspector.css:
(.child-editing):
* inspector/front-end/inspector.js:
(WebInspector.startEditing.defaultFinishHandler):
(WebInspector.startEditing):
* inspector/front-end/treeoutline.js:
(TreeElement.prototype.select):
LayoutTests:
* inspector/console-dir.html:
* inspector/styles-add-blank-property.html:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@73913 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 723267b..a58f503 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-12-08 Alexander Pavlov <apavlov at chromium.org>
+
+ Reviewed by Joseph Pecoraro.
+
+ Web Inspector: Enable CSS property editing name/value-wise (like Firebug does)
+ https://bugs.webkit.org/show_bug.cgi?id=50565
+
+ * inspector/console-dir.html:
+ * inspector/styles-add-blank-property.html:
+
2010-12-13 W. James MacLean <wjmaclean at chromium.org>
Reviewed by Csaba Osztrogonác.
diff --git a/LayoutTests/inspector/console-dir.html b/LayoutTests/inspector/console-dir.html
index 53f7dbe..192f710 100755
--- a/LayoutTests/inspector/console-dir.html
+++ b/LayoutTests/inspector/console-dir.html
@@ -37,9 +37,9 @@ function frontend_expandAndDumpConsoleMessages(testController)
var element = messages[i].toMessageElement();
var node = element.traverseNextNode(element);
while (node) {
- if (node.sectionForTest) {
- messages[i].section = node.sectionForTest;
- node.sectionForTest.expanded = true;
+ if (node._section) {
+ messages[i].section = node._section;
+ node._section.expanded = true;
break;
}
node = node.traverseNextNode(element);
diff --git a/LayoutTests/inspector/styles-add-blank-property.html b/LayoutTests/inspector/styles-add-blank-property.html
index 013c311..fd36a95 100644
--- a/LayoutTests/inspector/styles-add-blank-property.html
+++ b/LayoutTests/inspector/styles-add-blank-property.html
@@ -39,8 +39,9 @@ function frontend_dumpInspectedStyle(testController)
var evt = document.createEvent("KeyboardEvent");
evt.initKeyboardEvent("keydown", true /* can bubble */, true /* can cancel */, null /* view */, "Enter", "");
- treeElement.listItemElement.textContent = "text-decoration: none";
- treeElement.listItemElement.dispatchEvent(evt);
+ treeElement.nameElement.textContent = "text-decoration";
+ treeElement.valueElement.textContent = "none";
+ treeElement.nameElement.dispatchEvent(evt);
testController.runAfterPendingDispatches(frontend_dumpResults.bind(this, testController));
}
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index e071fce..84c0627 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,59 @@
+2010-12-08 Alexander Pavlov <apavlov at chromium.org>
+
+ Reviewed by Joseph Pecoraro.
+
+ Web Inspector: Enable CSS property editing name/value-wise (like Firebug does)
+ https://bugs.webkit.org/show_bug.cgi?id=50565
+
+ For CSS property editing, the property name and value have become two fields separated
+ by a colon (rather than one field containing the full property text.) A user can tab
+ between the name and value fields forward and backward. A colon typed in the name field
+ and a semicolon in the value field (unless found inside a string) act as a Tab and focus
+ the next editable field (while applying the entire property value.)
+
+ Now a user can tab through all editable styles for an element, even across rule boundaries.
+
+ * inspector/front-end/BreakpointsSidebarPane.js:
+ (WebInspector.XHRBreakpointsSidebarPane.prototype._startEditingBreakpoint):
+ * inspector/front-end/DataGrid.js:
+ (WebInspector.DataGrid.prototype._startEditingColumnOfDataGridNode):
+ (WebInspector.DataGrid.prototype._startEditing):
+ * inspector/front-end/ElementsTreeOutline.js:
+ (WebInspector.ElementsTreeElement.prototype._startEditingAttribute):
+ (WebInspector.ElementsTreeElement.prototype._startEditingTextNode):
+ (WebInspector.ElementsTreeElement.prototype._startEditingTagName):
+ (WebInspector.ElementsTreeElement.prototype._startEditingAsHTML):
+ * inspector/front-end/MetricsSidebarPane.js:
+ (WebInspector.MetricsSidebarPane.prototype.startEditing):
+ * inspector/front-end/ObjectPropertiesSection.js:
+ (WebInspector.ObjectPropertyTreeElement.prototype.startEditing):
+ * inspector/front-end/Section.js:
+ (WebInspector.Section):
+ (WebInspector.Section.prototype.get subtitleAsTextForTest):
+ (WebInspector.Section.prototype.get nextSibling):
+ (WebInspector.Section.prototype.get previousSibling):
+ * inspector/front-end/SourceFrame.js:
+ (WebInspector.SourceFrame.prototype._editBreakpointCondition):
+ * inspector/front-end/StylesSidebarPane.js:
+ (WebInspector.StylePropertiesSection.prototype.nextEditableSibling):
+ (WebInspector.StylePropertiesSection.prototype.previousEditableSibling):
+ (WebInspector.StylePropertiesSection.prototype.addNewBlankProperty):
+ (WebInspector.StylePropertiesSection.prototype.startEditingSelector):
+ (WebInspector.StylePropertiesSection.prototype.editingSelectorCommitted):
+ (WebInspector.StylePropertyTreeElement.prototype.):
+ (WebInspector.StylePropertyTreeElement.prototype):
+ * inspector/front-end/TextViewer.js:
+ (WebInspector.TextViewer.prototype._handleDoubleClick):
+ * inspector/front-end/WatchExpressionsSidebarPane.js:
+ (WebInspector.WatchExpressionTreeElement.prototype.startEditing):
+ * inspector/front-end/inspector.css:
+ (.child-editing):
+ * inspector/front-end/inspector.js:
+ (WebInspector.startEditing.defaultFinishHandler):
+ (WebInspector.startEditing):
+ * inspector/front-end/treeoutline.js:
+ (TreeElement.prototype.select):
+
2010-12-13 Yael Aharon <yael.aharon at nokia.com>
Unreviewed.
diff --git a/WebCore/inspector/front-end/BreakpointsSidebarPane.js b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
index 47194da..e794b82 100644
--- a/WebCore/inspector/front-end/BreakpointsSidebarPane.js
+++ b/WebCore/inspector/front-end/BreakpointsSidebarPane.js
@@ -145,7 +145,10 @@ WebInspector.XHRBreakpointsSidebarPane.prototype = {
var commitHandler = this._hideEditBreakpointDialog.bind(this, inputElement, true, breakpointItem);
var cancelHandler = this._hideEditBreakpointDialog.bind(this, inputElement, false, breakpointItem);
- WebInspector.startEditing(inputElement, commitHandler, cancelHandler);
+ WebInspector.startEditing(inputElement, {
+ commitHandler: commitHandler,
+ cancelHandler: cancelHandler
+ });
},
_hideEditBreakpointDialog: function(inputElement, accept, breakpointItem)
diff --git a/WebCore/inspector/front-end/DataGrid.js b/WebCore/inspector/front-end/DataGrid.js
index 902062c..52995d4 100644
--- a/WebCore/inspector/front-end/DataGrid.js
+++ b/WebCore/inspector/front-end/DataGrid.js
@@ -169,7 +169,11 @@ WebInspector.DataGrid.prototype = {
this._editingNode.select();
var element = this._editingNode._element.children[column];
- WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
+ WebInspector.startEditing(element, {
+ context: element.textContent,
+ commitHandler: this._editingCommitted.bind(this),
+ cancelHandler: this._editingCancelled.bind(this)
+ });
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},
@@ -191,7 +195,11 @@ WebInspector.DataGrid.prototype = {
return this._startEditingColumnOfDataGridNode(this._editingNode, 0);
this._editing = true;
- WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
+ WebInspector.startEditing(element, {
+ context: element.textContent,
+ commitHandler: this._editingCommitted.bind(this),
+ cancelHandler: this._editingCancelled.bind(this)
+ });
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},
diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js
index 02a7911..919c8f6 100644
--- a/WebCore/inspector/front-end/ElementsTreeOutline.js
+++ b/WebCore/inspector/front-end/ElementsTreeOutline.js
@@ -872,7 +872,11 @@ WebInspector.ElementsTreeElement.prototype = {
// Remove zero-width spaces that were added by nodeTitleInfo.
removeZeroWidthSpaceRecursive(attribute);
- this._editing = WebInspector.startEditing(attribute, this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);
+ this._editing = WebInspector.startEditing(attribute, {
+ context: attributeName,
+ commitHandler: this._attributeEditingCommitted.bind(this),
+ cancelHandler: this._editingCancelled.bind(this)
+ });
window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1);
return true;
@@ -883,7 +887,11 @@ WebInspector.ElementsTreeElement.prototype = {
if (WebInspector.isBeingEdited(textNode))
return true;
- this._editing = WebInspector.startEditing(textNode, this._textNodeEditingCommitted.bind(this), this._editingCancelled.bind(this));
+ this._editing = WebInspector.startEditing(textNode, {
+ context: null,
+ commitHandler: this._textNodeEditingCommitted.bind(this),
+ cancelHandler: this._editingCancelled.bind(this)
+ });
window.getSelection().setBaseAndExtent(textNode, 0, textNode, 1);
return true;
@@ -926,7 +934,11 @@ WebInspector.ElementsTreeElement.prototype = {
tagNameElement.addEventListener('keyup', keyupListener, false);
- this._editing = WebInspector.startEditing(tagNameElement, editingComitted.bind(this), editingCancelled.bind(this), tagName);
+ this._editing = WebInspector.startEditing(tagNameElement, {
+ context: tagName,
+ commitHandler: editingComitted.bind(this),
+ cancelHandler: editingCancelled.bind(this)
+ });
window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1);
return true;
},
@@ -980,7 +992,12 @@ WebInspector.ElementsTreeElement.prototype = {
this.updateSelection();
}
- this._editing = WebInspector.startEditing(this._htmlEditElement, commit.bind(this), dispose.bind(this), null, true);
+ this._editing = WebInspector.startEditing(this._htmlEditElement, {
+ context: null,
+ commitHandler: commit.bind(this),
+ cancelHandler: dispose.bind(this),
+ multiline: true
+ });
},
_attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection)
diff --git a/WebCore/inspector/front-end/MetricsSidebarPane.js b/WebCore/inspector/front-end/MetricsSidebarPane.js
index 3784ce8..3c0f315 100644
--- a/WebCore/inspector/front-end/MetricsSidebarPane.js
+++ b/WebCore/inspector/front-end/MetricsSidebarPane.js
@@ -175,7 +175,11 @@ WebInspector.MetricsSidebarPane.prototype = {
var context = { box: box, styleProperty: styleProperty };
- WebInspector.startEditing(targetElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
+ WebInspector.startEditing(targetElement, {
+ context: context,
+ commitHandler: this.editingCommitted.bind(this),
+ cancelHandler: this.editingCancelled.bind(this)
+ });
},
editingCancelled: function(element, context)
diff --git a/WebCore/inspector/front-end/ObjectPropertiesSection.js b/WebCore/inspector/front-end/ObjectPropertiesSection.js
index 64e214f..e4794f3 100644
--- a/WebCore/inspector/front-end/ObjectPropertiesSection.js
+++ b/WebCore/inspector/front-end/ObjectPropertiesSection.js
@@ -238,7 +238,11 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
this.listItemElement.addStyleClass("editing-sub-part");
- WebInspector.startEditing(this.valueElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
+ WebInspector.startEditing(this.valueElement, {
+ context: context,
+ commitHandler: this.editingCommitted.bind(this),
+ cancelHandler: this.editingCancelled.bind(this)
+ });
},
editingEnded: function(context)
diff --git a/WebCore/inspector/front-end/Section.js b/WebCore/inspector/front-end/Section.js
index a186d43..5caa78b 100644
--- a/WebCore/inspector/front-end/Section.js
+++ b/WebCore/inspector/front-end/Section.js
@@ -31,7 +31,7 @@ WebInspector.Section = function(title, subtitle)
{
this.element = document.createElement("div");
this.element.className = "section";
- this.element.sectionForTest = this;
+ this.element._section = this;
this.headerElement = document.createElement("div");
this.headerElement.className = "header";
@@ -85,15 +85,15 @@ WebInspector.Section.prototype = {
this.subtitleElement.textContent = x;
},
- get subtitleAsTextForTest()
- {
- var result = this.subtitleElement.textContent;
- var child = this.subtitleElement.querySelector("[data-uncopyable]");
- if (child) {
- var linkData = child.getAttribute("data-uncopyable");
- if (linkData)
- result += linkData;
- }
+ get subtitleAsTextForTest()
+ {
+ var result = this.subtitleElement.textContent;
+ var child = this.subtitleElement.querySelector("[data-uncopyable]");
+ if (child) {
+ var linkData = child.getAttribute("data-uncopyable");
+ if (linkData)
+ result += linkData;
+ }
return result;
},
@@ -124,6 +124,26 @@ WebInspector.Section.prototype = {
}
},
+ get nextSibling()
+ {
+ var curElement = this.element;
+ do {
+ curElement = curElement.nextSibling;
+ } while (curElement && !curElement._section);
+
+ return curElement ? curElement._section : null;
+ },
+
+ get previousSibling()
+ {
+ var curElement = this.element;
+ do {
+ curElement = curElement.previousSibling;
+ } while (curElement && !curElement._section);
+
+ return curElement ? curElement._section : null;
+ },
+
expand: function()
{
if (this._expanded)
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js
index 557837d..ab03807 100644
--- a/WebCore/inspector/front-end/SourceFrame.js
+++ b/WebCore/inspector/front-end/SourceFrame.js
@@ -705,7 +705,11 @@ WebInspector.SourceFrame.prototype = {
var dismissedHandler = dismissed.bind(this);
this._conditionEditorElement.addEventListener("blur", dismissedHandler, false);
- WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler);
+ WebInspector.startEditing(this._conditionEditorElement, {
+ context: null,
+ commitHandler: committed.bind(this),
+ cancelHandler: dismissedHandler
+ });
this._conditionEditorElement.value = breakpoint.condition;
this._conditionEditorElement.select();
},
diff --git a/WebCore/inspector/front-end/StylesSidebarPane.js b/WebCore/inspector/front-end/StylesSidebarPane.js
index db72486..a3d79c1 100644
--- a/WebCore/inspector/front-end/StylesSidebarPane.js
+++ b/WebCore/inspector/front-end/StylesSidebarPane.js
@@ -704,6 +704,26 @@ WebInspector.StylePropertiesSection.prototype = {
return true;
},
+ nextEditableSibling: function()
+ {
+ var curSection = this;
+ do {
+ curSection = curSection.nextSibling;
+ } while (curSection && !curSection.editable);
+
+ return curSection;
+ },
+
+ previousEditableSibling: function()
+ {
+ var curSection = this;
+ do {
+ curSection = curSection.previousSibling;
+ } while (curSection && !curSection.editable);
+
+ return curSection;
+ },
+
update: function(full)
{
if (full) {
@@ -795,6 +815,7 @@ WebInspector.StylePropertiesSection.prototype = {
this.propertiesTreeOutline.appendChild(item);
item.listItemElement.textContent = "";
item._newProperty = true;
+ item.updateTitle();
return item;
},
@@ -875,22 +896,35 @@ WebInspector.StylePropertiesSection.prototype = {
if (WebInspector.isBeingEdited(element))
return;
- WebInspector.startEditing(this._selectorElement, this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this), null);
+ WebInspector.startEditing(this._selectorElement, {
+ context: null,
+ commitHandler: this.editingSelectorCommitted.bind(this),
+ cancelHandler: this.editingSelectorCancelled.bind(this)
+ });
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},
editingSelectorCommitted: function(element, newContent, oldContent, context, moveDirection)
{
function moveToNextIfNeeded() {
- if (!moveDirection || moveDirection !== "forward")
+ if (!moveDirection)
return;
- this.expand();
- if (this.propertiesTreeOutline.children.length === 0)
- this.addNewBlankProperty().startEditing();
- else {
- var item = this.propertiesTreeOutline.children[0]
- item.startEditing(item.valueElement);
+ if (moveDirection === "forward") {
+ this.expand();
+ if (this.propertiesTreeOutline.children.length === 0)
+ this.addNewBlankProperty().startEditing();
+ else {
+ var item = this.propertiesTreeOutline.children[0]
+ item.startEditing(item.nameElement);
+ }
+ } else {
+ var previousSection = this.previousEditableSibling();
+ if (!previousSection)
+ return;
+
+ previousSection.expand();
+ previousSection.addNewBlankProperty().startEditing();
}
}
@@ -1346,8 +1380,11 @@ WebInspector.StylePropertyTreeElement.prototype = {
this.listItemElement.appendChild(valueElement);
this.listItemElement.appendChild(document.createTextNode(";"));
- if (!this.parsedOk)
+ if (!this.parsedOk) {
+ // Avoid having longhands under an invalid shorthand.
+ this.hasChildren = false;
this.listItemElement.addStyleClass("not-parsed-ok");
+ }
if (this.property.inactive)
this.listItemElement.addStyleClass("inactive");
@@ -1460,60 +1497,146 @@ WebInspector.StylePropertyTreeElement.prototype = {
if (this.parent.shorthand)
return;
- if (WebInspector.isBeingEdited(this.listItemElement) || (this.treeOutline.section && !this.treeOutline.section.editable))
+ if (this.treeOutline.section && !this.treeOutline.section.editable)
+ return;
+
+ if (!selectElement)
+ selectElement = this.nameElement; // No arguments passed in - edit the name element by default.
+ else
+ selectElement = selectElement.enclosingNodeOrSelfWithClass("webkit-css-property") || selectElement.enclosingNodeOrSelfWithClass("value");
+
+ var isEditingName = selectElement === this.nameElement;
+ if (!isEditingName && selectElement !== this.valueElement) {
+ // Double-click in the LI - start editing value.
+ isEditingName = false;
+ selectElement = this.valueElement;
+ }
+
+ if (WebInspector.isBeingEdited(selectElement))
return;
var context = {
expanded: this.expanded,
hasChildren: this.hasChildren,
- keyDownListener: this.editingKeyDown.bind(this),
- keyPressListener: this.editingKeyPress.bind(this)
+ keyDownListener: isEditingName ? this.editingNameKeyDown.bind(this) : this.editingValueKeyDown.bind(this),
+ keyPressListener: isEditingName ? this.editingNameKeyPress.bind(this) : this.editingValueKeyPress.bind(this),
+ isEditingName: isEditingName,
};
// Lie about our children to prevent expanding on double click and to collapse shorthands.
this.hasChildren = false;
- if (!selectElement)
- selectElement = this.listItemElement;
+ selectElement.addEventListener("keydown", context.keyDownListener, false);
+ selectElement.addEventListener("keypress", context.keyPressListener, false);
+ if (selectElement.parentElement)
+ selectElement.parentElement.addStyleClass("child-editing");
+ selectElement.textContent = selectElement.textContent; // remove color swatch and the like
+
+ function shouldCommitValueSemicolon(text, cursorPosition)
+ {
+ // FIXME: should this account for semicolons inside comments?
+ var openQuote = "";
+ for (var i = 0; i < cursorPosition; ++i) {
+ var ch = text[i];
+ if (ch === "\\" && openQuote !== "")
+ ++i; // skip next character inside string
+ else if (!openQuote && (ch === "\"" || ch === "'"))
+ openQuote = ch;
+ else if (openQuote === ch)
+ openQuote = "";
+ }
+ return !openQuote;
+ }
- this.listItemElement.addEventListener("keydown", context.keyDownListener, false);
- this.listItemElement.addEventListener("keypress", context.keyPressListener, false);
+ function nameValueFinishHandler(context, isEditingName, event)
+ {
+ // FIXME: the ":"/";" detection does not work for non-US layouts due to the event being keydown rather than keypress.
+ var isFieldInputTerminated = (event.keyCode === WebInspector.KeyboardShortcut.Keys.Semicolon.code) &&
+ (isEditingName ? event.shiftKey : (!event.shiftKey && shouldCommitValueSemicolon(event.target.textContent, event.target.selectionLeftOffset)));
+ if (isEnterKey(event) || isFieldInputTerminated) {
+ // Enter or colon (for name)/semicolon outside of string (for value).
+ event.preventDefault();
+ return "move-forward";
+ } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code)
+ return "cancel";
+ else if (event.keyIdentifier === "U+0009") // Tab key.
+ return "move-" + (event.shiftKey ? "backward" : "forward");
+ }
- WebInspector.startEditing(this.listItemElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
+ WebInspector.startEditing(selectElement, {
+ context: context,
+ commitHandler: this.editingCommitted.bind(this),
+ cancelHandler: this.editingCancelled.bind(this),
+ customFinishHandler: nameValueFinishHandler.bind(this, context, isEditingName)
+ });
window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
},
- editingKeyPress: function(event)
+ editingNameKeyPress: function(event)
{
- var selection = window.getSelection();
- var colonIndex = this.listItemElement.textContent.indexOf(":");
- var selectionLeftOffset = event.target.selectionLeftOffset;
-
- if (colonIndex < 0 || selectionLeftOffset <= colonIndex) {
- // Complete property names.
- var character = event.data.toLowerCase();
- if (character && /[a-z-]/.test(character)) {
- var prefix = selection.anchorNode.textContent.substring(0, selection.anchorOffset);
- var property = WebInspector.CSSCompletions.firstStartsWith(prefix + character);
-
- if (!selection.isCollapsed)
- selection.deleteFromDocument();
-
- this.restoreNameElement();
-
- if (property) {
- if (property !== this.nameElement.textContent)
- this.nameElement.textContent = property;
- this.nameElement.firstChild.select(prefix.length + 1);
- event.preventDefault();
- }
+ // Complete property names.
+ var character = event.data.toLowerCase();
+ if (character && /[a-z-]/.test(character)) {
+ var selection = window.getSelection();
+ var prefix = selection.anchorNode.textContent.substring(0, selection.anchorOffset);
+ var property = WebInspector.CSSCompletions.firstStartsWith(prefix + character);
+
+ if (!selection.isCollapsed)
+ selection.deleteFromDocument();
+
+ this.restoreNameElement();
+
+ if (property) {
+ if (property !== this.nameElement.textContent)
+ this.nameElement.textContent = property;
+ this.nameElement.firstChild.select(prefix.length + 1);
+ event.preventDefault();
}
- } else {
- // FIXME: This should complete property values.
}
},
- editingKeyDown: function(event)
+ editingValueKeyPress: function(event)
+ {
+ // FIXME: This should complete property values.
+ },
+
+ editingNameKeyDown: function(event)
+ {
+ var showNext;
+ if (event.keyIdentifier === "Up")
+ showNext = false;
+ else if (event.keyIdentifier === "Down")
+ showNext = true;
+ else
+ return;
+
+ var selection = window.getSelection();
+ if (!selection.rangeCount)
+ return;
+
+ var selectionRange = selection.getRangeAt(0);
+ if (selectionRange.commonAncestorContainer !== this.nameElement && !selectionRange.commonAncestorContainer.isDescendant(this.nameElement))
+ return;
+
+ const styleValueDelimeters = " \t\n\"':;,/()";
+ var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.nameElement);
+ var wordString = wordRange.toString();
+ var prefix = selectionRange.startContainer.textContent.substring(0, selectionRange.startOffset);
+ var property;
+
+ if (showNext)
+ property = WebInspector.CSSCompletions.next(wordString, prefix);
+ else
+ property = WebInspector.CSSCompletions.previous(wordString, prefix);
+
+ if (property) {
+ this.nameElement.textContent = property;
+ this.nameElement.firstChild.select(selectionRange.startOffset);
+ }
+ event.preventDefault();
+ },
+
+ editingValueKeyDown: function(event)
{
var arrowKeyPressed = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down");
var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
@@ -1525,33 +1648,11 @@ WebInspector.StylePropertyTreeElement.prototype = {
return;
var selectionRange = selection.getRangeAt(0);
- if (selectionRange.commonAncestorContainer !== this.listItemElement && !selectionRange.commonAncestorContainer.isDescendant(this.listItemElement))
+ if (selectionRange.commonAncestorContainer !== this.valueElement && !selectionRange.commonAncestorContainer.isDescendant(this.valueElement))
return;
- // If there are several properties in the text, do not handle increments/decrements.
- var text = event.target.textContent.trim();
- var openQuote;
- var wasEscape = false;
- // Exclude the last character from the check since it is allowed to be ";".
- for (var i = 0; i < text.length - 1; ++i) {
- var ch = text.charAt(i);
- if (ch === "\\") {
- wasEscape = true;
- continue;
- }
- if (ch === ";" && !openQuote)
- return; // Do not handle name/value shifts if the property is compound.
- if ((ch === "'" || ch === "\"") && !wasEscape) {
- if (!openQuote)
- openQuote = ch;
- else if (ch === openQuote)
- openQuote = null;
- }
- wasEscape = false;
- }
-
const styleValueDelimeters = " \t\n\"':;,/()";
- var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.listItemElement);
+ var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, styleValueDelimeters, this.valueElement);
var wordString = wordRange.toString();
var replacementString = wordString;
@@ -1593,22 +1694,6 @@ WebInspector.StylePropertyTreeElement.prototype = {
}
replacementString = prefix + number + suffix;
- } else if (selection.containsNode(this.nameElement, true)) {
- var prefix = selectionRange.startContainer.textContent.substring(0, selectionRange.startOffset);
- var property;
-
- if (event.keyIdentifier === "Up")
- property = WebInspector.CSSCompletions.previous(wordString, prefix);
- else if (event.keyIdentifier === "Down")
- property = WebInspector.CSSCompletions.next(wordString, prefix);
-
- var startOffset = selectionRange.startOffset;
- if (property) {
- this.nameElement.textContent = property;
- this.nameElement.firstChild.select(startOffset);
- }
- event.preventDefault();
- return;
} else {
// FIXME: this should cycle through known keywords for the current property value.
}
@@ -1632,7 +1717,9 @@ WebInspector.StylePropertyTreeElement.prototype = {
// if the editing is canceled and before each apply.
this.originalPropertyText = this.property.propertyText;
}
- this.applyStyleText(this.listItemElement.textContent);
+
+ // Synthesize property text disregarding any comments, custom whitespace etc.
+ this.applyStyleText(this.nameElement.textContent + ": " + this.valueElement.textContent);
},
editingEnded: function(context)
@@ -1640,8 +1727,12 @@ WebInspector.StylePropertyTreeElement.prototype = {
this.hasChildren = context.hasChildren;
if (context.expanded)
this.expand();
- this.listItemElement.removeEventListener("keydown", context.keyDownListener, false);
- this.listItemElement.removeEventListener("keypress", context.keyPressListener, false);
+ var editedElement = context.isEditingName ? this.nameElement : this.valueElement;
+ editedElement.removeEventListener("keydown", context.keyDownListener, false);
+ editedElement.removeEventListener("keypress", context.keyPressListener, false);
+ if (editedElement.parentElement)
+ editedElement.parentElement.removeStyleClass("child-editing");
+
delete this.originalPropertyText;
},
@@ -1661,61 +1752,96 @@ WebInspector.StylePropertyTreeElement.prototype = {
editingCommitted: function(element, userInput, previousContent, context, moveDirection)
{
this.editingEnded(context);
+ var isEditingName = context.isEditingName;
// Determine where to move to before making changes
- var newProperty, moveToPropertyName, moveToSelector;
+ var createNewProperty, moveToPropertyName, moveToSelector;
var moveTo = this;
- do {
- moveTo = (moveDirection === "forward" ? moveTo.nextSibling : moveTo.previousSibling);
- } while(moveTo && !moveTo.selectable);
-
- if (moveTo)
- moveToPropertyName = moveTo.name;
- else if (moveDirection === "forward")
- newProperty = true;
- else if (moveDirection === "backward" && this.treeOutline.section.rule)
- moveToSelector = true;
+ var moveToOther = (isEditingName ^ (moveDirection === "forward"));
+ var abandonNewProperty = this._newProperty && !userInput && (moveToOther || isEditingName);
+ if (moveDirection === "forward" && !isEditingName || moveDirection === "backward" && isEditingName) {
+ do {
+ moveTo = (moveDirection === "forward" ? moveTo.nextSibling : moveTo.previousSibling);
+ } while(moveTo && !moveTo.selectable);
+
+ if (moveTo)
+ moveToPropertyName = moveTo.name;
+ else if (moveDirection === "forward" && (!this._newProperty || userInput))
+ createNewProperty = true;
+ else if (moveDirection === "backward" && this.treeOutline.section.rule)
+ moveToSelector = true;
+ }
- // Make the Changes and trigger the moveToNextCallback after updating
+ // Make the Changes and trigger the moveToNextCallback after updating.
var blankInput = /^\s*$/.test(userInput);
- if (userInput !== previousContent || (this._newProperty && blankInput)) { // only if something changed, or adding a new style and it was blank
- this.treeOutline.section._afterUpdate = moveToNextCallback.bind(this, this._newProperty, !blankInput);
- this.applyStyleText(userInput, true);
- } else
- moveToNextCallback(this._newProperty, false, this.treeOutline.section, false);
+ var shouldCommitNewProperty = this._newProperty && (moveToOther || (!moveDirection && !isEditingName) || (isEditingName && blankInput));
- // The Callback to start editing the next property
+ if ((userInput !== previousContent && !this._newProperty) || shouldCommitNewProperty) {
+ this.treeOutline.section._afterUpdate = moveToNextCallback.bind(this, this._newProperty, !blankInput, this.treeOutline.section);
+ var propertyText;
+ if (blankInput || (this._newProperty && /^\s*$/.test(this.valueElement.textContent)))
+ propertyText = "";
+ else {
+ if (isEditingName)
+ propertyText = userInput + ": " + this.valueElement.textContent;
+ else
+ propertyText = this.nameElement.textContent + ": " + userInput;
+ }
+ this.applyStyleText(propertyText, true);
+ } else {
+ if (!this._newProperty)
+ this.updateTitle();
+ moveToNextCallback(this._newProperty, false, this.treeOutline.section);
+ }
+
+ var moveToIndex = moveTo && this.treeOutline ? this.treeOutline.children.indexOf(moveTo) : -1;
+
+ // The Callback to start editing the next/previous property/selector.
function moveToNextCallback(alreadyNew, valueChanged, section)
{
if (!moveDirection)
return;
- // User just tabbed through without changes
+ // User just tabbed through without changes.
if (moveTo && moveTo.parent) {
- moveTo.startEditing(moveTo.valueElement);
+ moveTo.startEditing(!isEditingName ? moveTo.nameElement : moveTo.valueElement);
return;
}
- // User has made a change then tabbed, wiping all the original treeElements,
- // recalculate the new treeElement for the same property we were going to edit next
- // FIXME(apavlov): this will not work for multiple same-named properties in a style
- // (the first one will always be returned).
+ // User has made a change then tabbed, wiping all the original treeElements.
+ // Recalculate the new treeElement for the same property we were going to edit next.
if (moveTo && !moveTo.parent) {
- var treeElement = section.findTreeElementWithName(moveToPropertyName);
- if (treeElement)
- treeElement.startEditing(treeElement.valueElement);
- return;
+ var propertyElements = section.propertiesTreeOutline.children;
+ if (moveDirection === "forward" && blankInput && !isEditingName)
+ --moveToIndex;
+ if (moveToIndex >= propertyElements.length && !this._newProperty)
+ createNewProperty = true;
+ else {
+ var treeElement = moveToIndex >= 0 ? propertyElements[moveToIndex] : null;
+ if (treeElement) {
+ treeElement.startEditing(!isEditingName ? treeElement.nameElement : treeElement.valueElement);
+ return;
+ } else if (!alreadyNew)
+ moveToSelector = true;
+ }
}
- // Create a new attribute in this section
- if (newProperty) {
- if (alreadyNew && !valueChanged)
+ // Create a new attribute in this section (or move to next editable selector if possible).
+ if (createNewProperty) {
+ if (alreadyNew && !valueChanged && (isEditingName ^ (moveDirection === "backward")))
return;
section.addNewBlankProperty().startEditing();
return;
}
+ if (abandonNewProperty) {
+ var sectionToEdit = moveDirection === "backward" ? section : section.nextEditableSibling();
+ if (sectionToEdit && sectionToEdit.rule)
+ sectionToEdit.startEditingSelector();
+ return;
+ }
+
if (moveToSelector)
section.startEditingSelector();
}
@@ -1725,16 +1851,13 @@ WebInspector.StylePropertyTreeElement.prototype = {
{
var section = this.treeOutline.section;
var elementsPanel = WebInspector.panels.elements;
- styleText = styleText.replace(/\s/g, " ").trim(); // replace with whitespace.
+ styleText = styleText.replace(/\s/g, " ").trim(); // Replace with whitespace.
var styleTextLength = styleText.length;
- if (!styleTextLength && updateInterface) {
- if (this._newProperty) {
- // The user deleted everything, so remove the tree element and update.
- this.parent.removeChild(this);
- section.afterUpdate();
- return;
- } else
- delete section._afterUpdate;
+ if (!styleTextLength && updateInterface && this._newProperty) {
+ // The user deleted everything, so remove the tree element and update.
+ this.parent.removeChild(this);
+ section.afterUpdate();
+ return;
}
function callback(newStyle)
diff --git a/WebCore/inspector/front-end/TextViewer.js b/WebCore/inspector/front-end/TextViewer.js
index 9ad5e49..f116dea 100644
--- a/WebCore/inspector/front-end/TextViewer.js
+++ b/WebCore/inspector/front-end/TextViewer.js
@@ -268,7 +268,12 @@ WebInspector.TextViewer.prototype = {
var oldContent = lineRow.lastChild.innerHTML;
var cancelEditingCallback = this._cancelEditingLine.bind(this, lineRow.lastChild, oldContent);
var commitEditingCallback = this._commitEditingLine.bind(this, lineRow.lineNumber, lineRow.lastChild, cancelEditingCallback);
- this._editingLine = WebInspector.startEditing(lineRow.lastChild, commitEditingCallback, cancelEditingCallback, null, true);
+ this._editingLine = WebInspector.startEditing(lineRow.lastChild, {
+ context: null,
+ commitHandler: commitEditingCallback,
+ cancelHandler: cancelEditingCallback,
+ multiline: true
+ });
},
_commitEditingLine: function(lineNumber, element, cancelEditingCallback)
diff --git a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js
index 44063a3..a01046b 100644
--- a/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js
+++ b/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js
@@ -240,7 +240,11 @@ WebInspector.WatchExpressionTreeElement.prototype = {
this.listItemElement.addStyleClass("editing-sub-part");
- WebInspector.startEditing(this.nameElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
+ WebInspector.startEditing(this.nameElement, {
+ context: context,
+ commitHandler: this.editingCommitted.bind(this),
+ cancelHandler: this.editingCancelled.bind(this)
+ });
},
editingCancelled: function(element, context)
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 965689b..c908427 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -1424,6 +1424,12 @@ body.inactive .placard.selected {
text-decoration: none !important;
}
+.child-editing {
+ color: black !important;
+ text-decoration: none !important;
+ overflow: visible !important;
+}
+
.editing br {
display: none;
}
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 8e165dc..e0d8e65 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -1915,13 +1915,23 @@ WebInspector.isEditingAnyField = function()
return this.__editing;
}
-WebInspector.startEditing = function(element, committedCallback, cancelledCallback, context, multiline)
+// Available config fields (all optional):
+// context: Object - an arbitrary context object to be passed to the commit and cancel handlers
+// commitHandler: Function - handles editing "commit" outcome
+// cancelHandler: Function - handles editing "cancel" outcome
+// customFinishHandler: Function - custom finish handler for the editing session (invoked on keydown)
+// multiline: Boolean - whether the edited element is multiline
+WebInspector.startEditing = function(element, config)
{
if (element.__editing)
return;
element.__editing = true;
WebInspector.__editing = true;
+ config = config || {};
+ var committedCallback = config.commitHandler;
+ var cancelledCallback = config.cancelHandler;
+ var context = config.context;
var oldText = getContent(element);
var moveDirection = "";
@@ -1977,20 +1987,36 @@ WebInspector.startEditing = function(element, committedCallback, cancelledCallba
committedCallback(this, getContent(this), oldText, context, moveDirection);
}
- function keyDownEventListener(event) {
+ function defaultFinishHandler(event)
+ {
var isMetaOrCtrl = WebInspector.isMac() ?
event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
- if (isEnterKey(event) && (!multiline || isMetaOrCtrl)) {
+ if (isEnterKey(event) && (!config.multiline || isMetaOrCtrl))
+ return "commit";
+ else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code)
+ return "cancel";
+ else if (event.keyIdentifier === "U+0009") // Tab key
+ return "move-" + (event.shiftKey ? "backward" : "forward");
+ }
+
+ function keyDownEventListener(event)
+ {
+ var handler = config.customFinishHandler || defaultFinishHandler;
+ var result = handler(event);
+ if (result === "commit") {
editingCommitted.call(element);
event.preventDefault();
event.stopPropagation();
- } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
+ } else if (result === "cancel") {
editingCancelled.call(element);
event.preventDefault();
event.stopPropagation();
- } else if (event.keyIdentifier === "U+0009") // Tab key
- moveDirection = (event.shiftKey ? "backward" : "forward");
+ } else if (result && result.indexOf("move-") === 0) {
+ moveDirection = result.substring(5);
+ if (event.keyIdentifier !== "U+0009")
+ blurEventListener();
+ }
}
element.addEventListener("blur", blurEventListener, false);
diff --git a/WebCore/inspector/front-end/treeoutline.js b/WebCore/inspector/front-end/treeoutline.js
index a1e052f..27bc839 100644
--- a/WebCore/inspector/front-end/treeoutline.js
+++ b/WebCore/inspector/front-end/treeoutline.js
@@ -821,6 +821,10 @@ TreeElement.prototype.select = function(supressOnSelect, selectedByUser)
this.selected = true;
this.treeOutline._childrenListNode.focus();
+
+ // Focusing on another node may detach "this" from tree.
+ if (!this.treeOutline)
+ return;
this.treeOutline.selectedTreeElement = this;
if (this._listItemNode)
this._listItemNode.addStyleClass("selected");
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list