Changeset 109545 in webkit


Ignore:
Timestamp:
Mar 2, 2012 3:16:55 AM (12 years ago)
Author:
apavlov@chromium.org
Message:

Web Inspector: Implement suggestions in Watch Expressions
https://bugs.webkit.org/show_bug.cgi?id=79912

Source/WebCore:

Drive-by: make subproperties in ObjectPropertySections editable

Reviewed by Pavel Feldman.

  • inspector/front-end/ConsoleView.js:

(WebInspector.ConsoleView):
(WebInspector.ConsoleView.prototype.completionsForTextPrompt):

  • inspector/front-end/DatabaseQueryView.js:
  • inspector/front-end/ObjectPropertiesSection.js:

(WebInspector.ObjectPropertyTreeElement.prototype.onpopulate.callback):
(WebInspector.ObjectPropertyTreeElement.prototype.onpopulate):
(WebInspector.ObjectPropertyTreeElement.prototype.ondblclick):
(WebInspector.ObjectPropertyTreeElement.prototype.renderPromptAsBlock):
(WebInspector.ObjectPropertyTreeElement.prototype.elementAndValueToEdit):
(WebInspector.ObjectPropertyTreeElement.prototype.startEditing.blurListener):
(WebInspector.ObjectPropertyTreeElement.prototype.startEditing):
(WebInspector.ObjectPropertyTreeElement.prototype.editingEnded):
(WebInspector.ObjectPropertyTreeElement.prototype.editingCancelled):
(WebInspector.ObjectPropertyTreeElement.prototype.editingCommitted):
(WebInspector.ObjectPropertyTreeElement.prototype._promptKeyDown):
(WebInspector.ObjectPropertyPrompt):

  • inspector/front-end/StylesSidebarPane.js:
  • inspector/front-end/TextPrompt.js:

(WebInspector.TextPrompt.prototype.complete):

  • inspector/front-end/WatchExpressionsSidebarPane.js:

(WebInspector.WatchExpressionTreeElement.prototype.renderPromptAsBlock):
(WebInspector.WatchExpressionTreeElement.prototype.elementAndValueToEdit):
(WebInspector.WatchExpressionTreeElement.prototype.editingCancelled):

  • inspector/front-end/inspector.css:

(.watch-expressions > li.editing-sub-part .text-prompt):

LayoutTests:

Reviewed by Pavel Feldman.

  • http/tests/inspector/console-cd-completions.html:
  • inspector/debugger/debugger-completions-on-call-frame.html:
Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r109543 r109545  
     12012-03-01  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Web Inspector: Implement suggestions in Watch Expressions
     4        https://bugs.webkit.org/show_bug.cgi?id=79912
     5
     6        Reviewed by Pavel Feldman.
     7
     8        * http/tests/inspector/console-cd-completions.html:
     9        * inspector/debugger/debugger-completions-on-call-frame.html:
     10
    1112012-03-02  Antti Koivisto  <antti@apple.com>
    212
  • trunk/LayoutTests/http/tests/inspector/console-cd-completions.html

    r93769 r109545  
    2323
    2424
    25     WebInspector.consoleView._completions("", "myGlob", false, checkCompletions.bind(this));
     25    WebInspector.consoleView.completionsForExpression("", "myGlob", false, checkCompletions.bind(this));
    2626    function checkCompletions(completions)
    2727    {
  • trunk/LayoutTests/inspector/debugger/debugger-completions-on-call-frame.html

    r93769 r109545  
    2424    function step2()
    2525    {
    26         WebInspector.consoleView._completions("", "var", false, checkAgainstGolden.bind(this, [ "var1", "var2" ], [], step3));
     26        WebInspector.consoleView.completionsForExpression("", "var", false, checkAgainstGolden.bind(this, [ "var1", "var2" ], [], step3));
    2727    }
    2828
    2929    function step3()
    3030    {
    31         WebInspector.consoleView._completions("", "di", false, checkAgainstGolden.bind(this, [ "dir", "dirxml" ], [], step4));
     31        WebInspector.consoleView.completionsForExpression("", "di", false, checkAgainstGolden.bind(this, [ "dir", "dirxml" ], [], step4));
    3232    }
    3333
    3434    function step4()
    3535    {
    36         WebInspector.consoleView._completions("", "win", false, checkAgainstGolden.bind(this, [ "window" ], [], step5));
     36        WebInspector.consoleView.completionsForExpression("", "win", false, checkAgainstGolden.bind(this, [ "window" ], [], step5));
    3737    }
    3838
    3939    function step5()
    4040    {
    41         WebInspector.consoleView._completions("", "t", false, checkAgainstGolden.bind(this, [ "this" ], [], step6));
     41        WebInspector.consoleView.completionsForExpression("", "t", false, checkAgainstGolden.bind(this, [ "this" ], [], step6));
    4242    }
    4343
    4444    function step6()
    4545    {
    46         WebInspector.consoleView._completions("var1", "toExp", false, checkAgainstGolden.bind(this, [ "toExponential" ], [], step7));
     46        WebInspector.consoleView.completionsForExpression("var1", "toExp", false, checkAgainstGolden.bind(this, [ "toExponential" ], [], step7));
    4747    }
    4848
    4949    function step7()
    5050    {
    51         WebInspector.consoleView._completions("123", "toExp", false, checkAgainstGolden.bind(this, [], [ "toExponential" ], step8));
     51        WebInspector.consoleView.completionsForExpression("123", "toExp", false, checkAgainstGolden.bind(this, [], [ "toExponential" ], step8));
    5252    }
    5353
  • trunk/Source/WebCore/ChangeLog

    r109543 r109545  
     12012-03-01  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Web Inspector: Implement suggestions in Watch Expressions
     4        https://bugs.webkit.org/show_bug.cgi?id=79912
     5
     6        Drive-by: make subproperties in ObjectPropertySections editable
     7
     8        Reviewed by Pavel Feldman.
     9
     10        * inspector/front-end/ConsoleView.js:
     11        (WebInspector.ConsoleView):
     12        (WebInspector.ConsoleView.prototype.completionsForTextPrompt):
     13        * inspector/front-end/DatabaseQueryView.js:
     14        * inspector/front-end/ObjectPropertiesSection.js:
     15        (WebInspector.ObjectPropertyTreeElement.prototype.onpopulate.callback):
     16        (WebInspector.ObjectPropertyTreeElement.prototype.onpopulate):
     17        (WebInspector.ObjectPropertyTreeElement.prototype.ondblclick):
     18        (WebInspector.ObjectPropertyTreeElement.prototype.renderPromptAsBlock):
     19        (WebInspector.ObjectPropertyTreeElement.prototype.elementAndValueToEdit):
     20        (WebInspector.ObjectPropertyTreeElement.prototype.startEditing.blurListener):
     21        (WebInspector.ObjectPropertyTreeElement.prototype.startEditing):
     22        (WebInspector.ObjectPropertyTreeElement.prototype.editingEnded):
     23        (WebInspector.ObjectPropertyTreeElement.prototype.editingCancelled):
     24        (WebInspector.ObjectPropertyTreeElement.prototype.editingCommitted):
     25        (WebInspector.ObjectPropertyTreeElement.prototype._promptKeyDown):
     26        (WebInspector.ObjectPropertyPrompt):
     27        * inspector/front-end/StylesSidebarPane.js:
     28        * inspector/front-end/TextPrompt.js:
     29        (WebInspector.TextPrompt.prototype.complete):
     30        * inspector/front-end/WatchExpressionsSidebarPane.js:
     31        (WebInspector.WatchExpressionTreeElement.prototype.renderPromptAsBlock):
     32        (WebInspector.WatchExpressionTreeElement.prototype.elementAndValueToEdit):
     33        (WebInspector.WatchExpressionTreeElement.prototype.editingCancelled):
     34        * inspector/front-end/inspector.css:
     35        (.watch-expressions > li.editing-sub-part .text-prompt):
     36
    1372012-03-02  Antti Koivisto  <antti@apple.com>
    238
  • trunk/Source/WebCore/inspector/front-end/ConsoleView.js

    r104822 r109545  
    112112    this._linkifier = WebInspector.debuggerPresentationModel.createLinkifier();
    113113
    114     this.prompt = new WebInspector.TextPromptWithHistory(this.completions.bind(this), ExpressionStopCharacters + ".");
     114    this.prompt = new WebInspector.TextPromptWithHistory(this.completionsForTextPrompt.bind(this), ExpressionStopCharacters + ".");
    115115    this.prompt.setSuggestBoxEnabled("generic-suggest");
    116116    this.prompt.renderAsBlock();
     
    343343    },
    344344
    345     completions: function(wordRange, force, completionsReadyCallback)
     345    completionsForTextPrompt: function(textPrompt, wordRange, force, completionsReadyCallback)
    346346    {
    347347        // Pass less stop characters to rangeOfWord so the range will be a more complete expression.
    348         var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, ExpressionStopCharacters, this.promptElement, "backward");
     348        var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, ExpressionStopCharacters, textPrompt.proxyElement, "backward");
    349349        var expressionString = expressionRange.toString();
    350350        var prefix = wordRange.toString();
    351         this._completions(expressionString, prefix, force, completionsReadyCallback);
    352     },
    353 
    354     _completions: function(expressionString, prefix, force, completionsReadyCallback)
     351        this.completionsForExpression(expressionString, prefix, force, completionsReadyCallback);
     352    },
     353
     354    completionsForExpression: function(expressionString, prefix, force, completionsReadyCallback)
    355355    {
    356356        var lastIndex = expressionString.length - 1;
  • trunk/Source/WebCore/inspector/front-end/DatabaseQueryView.js

    r102977 r109545  
    6262    },
    6363   
    64     completions: function(wordRange, force, completionsReadyCallback)
     64    completions: function(textPrompt, wordRange, force, completionsReadyCallback)
    6565    {
    6666        var prefix = wordRange.toString().toLowerCase();
  • trunk/Source/WebCore/inspector/front-end/ObjectPropertiesSection.js

    r109536 r109545  
    193193                if (this.treeOutline.section.skipProto && properties[i].name === "__proto__")
    194194                    continue;
     195                properties[i].parentObject = this.property.value;
    195196                this.appendChild(new this.treeOutline.section.treeElementConstructor(properties[i]));
    196197            }
     
    202203    {
    203204        if (this.property.writable)
    204             this.startEditing();
     205            this.startEditing(event);
    205206    },
    206207
     
    305306    },
    306307
    307     startEditing: function()
    308     {
    309         if (WebInspector.isBeingEdited(this.valueElement) || !this.treeOutline.section.editable || this._readOnly)
     308    renderPromptAsBlock: function()
     309    {
     310        return false;
     311    },
     312
     313    /**
     314     * @param {Event=} event
     315     */
     316    elementAndValueToEdit: function(event)
     317    {
     318        return [this.valueElement, (typeof this.valueElement._originalTextContent === "string") ? this.valueElement._originalTextContent : undefined];
     319    },
     320
     321    startEditing: function(event)
     322    {
     323        var elementAndValueToEdit = this.elementAndValueToEdit(event);
     324        var elementToEdit = elementAndValueToEdit[0];
     325        var valueToEdit = elementAndValueToEdit[1];
     326
     327        if (WebInspector.isBeingEdited(elementToEdit) || !this.treeOutline.section.editable || this._readOnly)
    310328            return;
    311329
    312         var context = { expanded: this.expanded };
     330        // Edit original source.
     331        if (typeof valueToEdit !== "undefined")
     332            elementToEdit.textContent = valueToEdit;
     333
     334        var context = { expanded: this.expanded, elementToEdit: elementToEdit, previousContent: elementToEdit.textContent };
    313335
    314336        // Lie about our children to prevent expanding on double click and to collapse subproperties.
     
    317339        this.listItemElement.addStyleClass("editing-sub-part");
    318340
    319         // Edit original source.
    320         if (typeof this.valueElement._originalTextContent === "string")
    321             this.valueElement.textContent = this.valueElement._originalTextContent;
    322 
    323         var config = new WebInspector.EditingConfig(this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
    324         WebInspector.startEditing(this.valueElement, config);
     341        this._prompt = new WebInspector.ObjectPropertyPrompt(this.editingCommitted.bind(this, null, elementToEdit.textContent, context.previousContent, context), this.editingCancelled.bind(this, null, context), this.renderPromptAsBlock());
     342
     343        function blurListener()
     344        {
     345            this.editingCommitted(null, elementToEdit.textContent, context.previousContent, context);
     346        }
     347
     348        var proxyElement = this._prompt.attachAndStartEditing(elementToEdit, blurListener.bind(this));
     349        window.getSelection().setBaseAndExtent(elementToEdit, 0, elementToEdit, 1);
     350        proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this, context), false);
    325351    },
    326352
    327353    editingEnded: function(context)
    328354    {
     355        this._prompt.detach();
     356        delete this._prompt;
     357
    329358        this.listItemElement.scrollLeft = 0;
    330359        this.listItemElement.removeStyleClass("editing-sub-part");
     
    335364    editingCancelled: function(element, context)
    336365    {
     366        this.editingEnded(context);
    337367        this.update();
    338         this.editingEnded(context);
    339368    },
    340369
     
    344373            return this.editingCancelled(element, context); // nothing changed, so cancel
    345374
     375        this.editingEnded(context);
    346376        this.applyExpression(userInput, true);
    347 
    348         this.editingEnded(context);
     377    },
     378
     379    _promptKeyDown: function(context, event)
     380    {
     381        if (isEnterKey(event)) {
     382            event.stopPropagation();
     383            event.preventDefault();
     384            return this.editingCommitted(null, context.elementToEdit.textContent, context.previousContent, context);
     385        }
     386        if (event.keyIdentifier === "U+001B") { // Esc
     387            event.stopPropagation();
     388            return this.editingCancelled(null, context);
     389        }
    349390    },
    350391
     
    375416WebInspector.ObjectPropertyTreeElement.prototype.__proto__ = TreeElement.prototype;
    376417
     418/**
     419 * @constructor
     420 * @extends {TreeElement}
     421 */
    377422WebInspector.ArrayGroupingTreeElement = function(treeElementConstructor, properties, fromIndex, toIndex)
    378423{
     
    452497
    453498WebInspector.ArrayGroupingTreeElement.prototype.__proto__ = TreeElement.prototype;
     499
     500/**
     501 * @constructor
     502 * @extends {WebInspector.TextPrompt}
     503 * @param {boolean=} renderAsBlock
     504 */
     505WebInspector.ObjectPropertyPrompt = function(commitHandler, cancelHandler, renderAsBlock)
     506{
     507    const ExpressionStopCharacters = " =:[({;,!+-*/&|^<>."; // Same as in ConsoleView.js + "."
     508    WebInspector.TextPrompt.call(this, WebInspector.consoleView.completionsForTextPrompt.bind(WebInspector.consoleView), ExpressionStopCharacters);
     509    this.setSuggestBoxEnabled("generic-suggest");
     510    if (renderAsBlock)
     511        this.renderAsBlock();
     512}
     513
     514WebInspector.ObjectPropertyPrompt.prototype.__proto__ = WebInspector.TextPrompt.prototype;
  • trunk/Source/WebCore/inspector/front-end/StylesSidebarPane.js

    r109372 r109545  
    25842584    },
    25852585
    2586     _buildPropertyCompletions: function(wordRange, force, completionsReadyCallback)
     2586    _buildPropertyCompletions: function(textPrompt, wordRange, force, completionsReadyCallback)
    25872587    {
    25882588        var prefix = wordRange.toString().toLowerCase();
  • trunk/Source/WebCore/inspector/front-end/TextPrompt.js

    r108356 r109545  
    3131 * @constructor
    3232 * @extends WebInspector.Object
    33  * @param {function(Range, boolean, function(Array.<string>=))} completions
     33 * @param {function(WebInspector.TextPrompt, Range, boolean, function(Array.<string>=))} completions
    3434 * @param {string} stopCharacters
    3535 */
     
    384384
    385385        var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this._completionStopCharacters, this._element, "backward");
    386         this._loadCompletions(wordPrefixRange, force, this._completionsReady.bind(this, selection, auto, wordPrefixRange, !!reverse));
     386        this._loadCompletions(this, wordPrefixRange, force, this._completionsReady.bind(this, selection, auto, wordPrefixRange, !!reverse));
    387387    },
    388388
     
    749749 * @constructor
    750750 * @extends {WebInspector.TextPrompt}
    751  * @param {function(Range, boolean, function(Array.<string>=))} completions
     751 * @param {function(WebInspector.TextPrompt, Range, boolean, function(Array.<string>=))} completions
    752752 * @param {string} stopCharacters
    753753 */
  • trunk/Source/WebCore/inspector/front-end/WatchExpressionsSidebarPane.js

    r107821 r109545  
    345345    },
    346346
    347     startEditing: function()
    348     {
    349         if (WebInspector.isBeingEdited(this.nameElement) || !this.treeOutline.section.editable)
    350             return;
    351 
    352         this.nameElement.textContent = this.property.name.trim();
    353 
    354         var context = { expanded: this.expanded };
    355 
    356         // collapse temporarily, if required
    357         this.hasChildren = false;
    358 
    359         this.listItemElement.addStyleClass("editing-sub-part");
    360 
    361         WebInspector.startEditing(this.nameElement, new WebInspector.EditingConfig(this.editingCommitted.bind(this), this.editingCancelled.bind(this), context));
     347    renderPromptAsBlock: function()
     348    {
     349        return true;
     350    },
     351
     352    /**
     353     * @param {Event=} event
     354     */
     355    elementAndValueToEdit: function(event)
     356    {
     357        return [this.nameElement, this.property.name.trim()];
    362358    },
    363359
    364360    editingCancelled: function(element, context)
    365361    {
    366         if (!this.nameElement.textContent)
     362        if (!context.elementToEdit.textContent)
    367363            this.treeOutline.section.updateExpression(this, null);
    368364
    369         this.update();
    370         this.editingEnded(context);
     365        WebInspector.ObjectPropertyTreeElement.prototype.editingCancelled.call(this, element, context);
    371366    },
    372367
  • trunk/Source/WebCore/inspector/front-end/inspector.css

    r109372 r109545  
    13801380}
    13811381
    1382 .watch-expressions > li.editing-sub-part .name {
     1382.watch-expressions > li.editing-sub-part .text-prompt {
    13831383    display: block;
    13841384    width: 100%;
Note: See TracChangeset for help on using the changeset viewer.