Changeset 61514 in webkit


Ignore:
Timestamp:
Jun 20, 2010 3:32:05 PM (14 years ago)
Author:
eric@webkit.org
Message:

2010-06-20 Nikita Vasilyev <me@elv1s.ru>

Reviewed by Joseph Pecoraro.

Web Inspector: Auto-completion for CSS property names in Styles pane
https://bugs.webkit.org/show_bug.cgi?id=17374

Added autocompletion for CSS properties. A suggestion for a property
shows when you type. You can also cycle through known property names
using the Up and Down arrow keys.

  • WebCore.gypi:
  • inspector/front-end/CSSCompletions.js: Added. (WebInspector.CSSCompletions): (WebInspector.CSSCompletions.startsWith): (WebInspector.CSSCompletions.firstStartsWith): (WebInspector.CSSCompletions._firstIndexOfPrefix): (WebInspector.CSSCompletions.next): (WebInspector.CSSCompletions.previous): (WebInspector.CSSCompletions._closest):
  • inspector/front-end/StylesSidebarPane.js: (WebInspector.StylePropertyTreeElement.prototype):
  • inspector/front-end/WebKit.qrc:
  • inspector/front-end/inspector.html:
  • inspector/front-end/utilities.js: (Text.prototype.select): ():
Location:
trunk/WebCore
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r61511 r61514  
     12010-06-20  Nikita Vasilyev  <me@elv1s.ru>
     2
     3        Reviewed by Joseph Pecoraro.
     4
     5        Web Inspector: Auto-completion for CSS property names in Styles pane
     6        https://bugs.webkit.org/show_bug.cgi?id=17374
     7
     8        Added autocompletion for CSS properties. A suggestion for a property
     9        shows when you type. You can also cycle through known property names
     10        using the Up and Down arrow keys.
     11
     12        * WebCore.gypi:
     13        * inspector/front-end/CSSCompletions.js: Added.
     14        (WebInspector.CSSCompletions):
     15        (WebInspector.CSSCompletions.startsWith):
     16        (WebInspector.CSSCompletions.firstStartsWith):
     17        (WebInspector.CSSCompletions._firstIndexOfPrefix):
     18        (WebInspector.CSSCompletions.next):
     19        (WebInspector.CSSCompletions.previous):
     20        (WebInspector.CSSCompletions._closest):
     21        * inspector/front-end/StylesSidebarPane.js:
     22        (WebInspector.StylePropertyTreeElement.prototype):
     23        * inspector/front-end/WebKit.qrc:
     24        * inspector/front-end/inspector.html:
     25        * inspector/front-end/utilities.js:
     26        (Text.prototype.select):
     27        ():
     28
    1292010-06-14  Dimitri Glazkov  <dglazkov@chromium.org>
    230
  • trunk/WebCore/WebCore.gypi

    r61511 r61514  
    39053905            'inspector/front-end/ContextMenu.js',
    39063906            'inspector/front-end/CookieItemsView.js',
     3907            'inspector/front-end/CSSCompletions.js',
    39073908            'inspector/front-end/CSSStyleModel.js',
    39083909            'inspector/front-end/Database.js',
  • trunk/WebCore/inspector/front-end/StylesSidebarPane.js

    r61494 r61514  
    13191319    },
    13201320
     1321    restoreNameElement: function()
     1322    {
     1323        // Restore <span class="webkit-css-property"> if it doesn't yet exist or was accidentally deleted.
     1324        if (this.nameElement === this.listItemElement.querySelector(".webkit-css-property"))
     1325            return;
     1326
     1327        this.nameElement = document.createElement("span");
     1328        this.nameElement.className = "webkit-css-property";
     1329        this.nameElement.textContent = "";
     1330        this.listItemElement.insertBefore(this.nameElement, this.listItemElement.firstChild);
     1331    },
     1332
    13211333    startEditing: function(selectElement)
    13221334    {
     
    13281340            return;
    13291341
    1330         var context = { expanded: this.expanded, hasChildren: this.hasChildren, keyDownListener: this.editingKeyDown.bind(this) };
     1342        var context = {
     1343            expanded: this.expanded,
     1344            hasChildren: this.hasChildren,
     1345            keyDownListener: this.editingKeyDown.bind(this),
     1346            keyPressListener: this.editingKeyPress.bind(this)
     1347        };
    13311348
    13321349        // Lie about our children to prevent expanding on double click and to collapse shorthands.
     
    13371354
    13381355        this.listItemElement.addEventListener("keydown", context.keyDownListener, false);
     1356        this.listItemElement.addEventListener("keypress", context.keyPressListener, false);
    13391357
    13401358        WebInspector.startEditing(this.listItemElement, this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
    13411359        window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
     1360    },
     1361
     1362    editingKeyPress: function(event)
     1363    {
     1364        var selection = window.getSelection();
     1365        var colonIndex = this.listItemElement.textContent.indexOf(":");
     1366        var selectionLeftOffset = event.target.selectionLeftOffset;
     1367
     1368        if (colonIndex < 0 || selectionLeftOffset <= colonIndex) {
     1369            // Complete property names.
     1370            var character = event.data.toLowerCase();
     1371            if (character && /[a-z-]/.test(character)) {
     1372                var prefix = selection.anchorNode.textContent.substring(0, selection.anchorOffset);
     1373                var property = WebInspector.CSSCompletions.firstStartsWith(prefix + character);
     1374
     1375                if (!selection.isCollapsed)
     1376                    selection.deleteFromDocument();
     1377
     1378                this.restoreNameElement();
     1379
     1380                if (property) {
     1381                    if (property !== this.nameElement.textContent)
     1382                        this.nameElement.textContent = property;
     1383                    this.nameElement.firstChild.select(prefix.length + 1);
     1384                    event.preventDefault();
     1385                }
     1386            }
     1387        } else {
     1388            // FIXME: This should complete property values.
     1389        }
    13421390    },
    13431391
     
    14001448
    14011449            replacementString = prefix + number + suffix;
     1450        } else if (selection.containsNode(this.nameElement, true)) {
     1451            var prefix = selectionRange.startContainer.textContent.substring(0, selectionRange.startOffset);
     1452            var property;
     1453
     1454            if (event.keyIdentifier === "Up")
     1455                property = WebInspector.CSSCompletions.previous(wordString, prefix);
     1456            else if (event.keyIdentifier === "Down")
     1457                property = WebInspector.CSSCompletions.next(wordString, prefix);
     1458
     1459            var startOffset = selectionRange.startOffset;
     1460            if (property) {
     1461                this.nameElement.textContent = property;
     1462                this.nameElement.firstChild.select(startOffset);
     1463            }
     1464            event.preventDefault();
     1465            return;
    14021466        } else {
    1403             // FIXME: this should cycle through known keywords for the current property name.
    1404             return;
     1467            // FIXME: this should cycle through known keywords for the current property value.
    14051468        }
    14061469
     
    14381501            this.expand();
    14391502        this.listItemElement.removeEventListener("keydown", context.keyDownListener, false);
     1503        this.listItemElement.removeEventListener("keypress", context.keyPressListener, false);
    14401504        delete this.originalCSSText;
    14411505    },
  • trunk/WebCore/inspector/front-end/WebKit.qrc

    r60681 r61514  
    2020    <file>ContextMenu.js</file>
    2121    <file>CookieItemsView.js</file>
     22    <file>CSSCompletions.js</file>
    2223    <file>CSSStyleModel.js</file>
    2324    <file>Database.js</file>
  • trunk/WebCore/inspector/front-end/inspector.html

    r60680 r61514  
    8383    <script type="text/javascript" src="EventListenersSidebarPane.js"></script>
    8484    <script type="text/javascript" src="Color.js"></script>
     85    <script type="text/javascript" src="CSSCompletions.js"></script>
    8586    <script type="text/javascript" src="StylesSidebarPane.js"></script>
    8687    <script type="text/javascript" src="PanelEnablerView.js"></script>
  • trunk/WebCore/inspector/front-end/utilities.js

    r60682 r61514  
    328328    return elementOffset;
    329329}
     330
     331KeyboardEvent.prototype.__defineGetter__("data", function()
     332{
     333    // Emulate "data" attribute from DOM 3 TextInput event.
     334    // See http://www.w3.org/TR/DOM-Level-3-Events/#events-Events-TextEvent-data
     335    switch (this.type) {
     336        case "keypress":
     337            if (!this.ctrlKey && !this.metaKey)
     338                return String.fromCharCode(this.charCode);
     339            else
     340                return "";
     341        case "keydown":
     342        case "keyup":
     343            if (!this.ctrlKey && !this.metaKey && !this.altKey)
     344                return String.fromCharCode(this.which);
     345            else
     346                return "";
     347    }
     348});
     349
     350Text.prototype.select = function(start, end)
     351{
     352    start = start || 0;
     353    end = end || this.textContent.length;
     354
     355    if (start < 0)
     356        start = end + start;
     357
     358    var selection = window.getSelection();
     359    selection.removeAllRanges();
     360    var range = document.createRange();
     361    range.setStart(this, start);
     362    range.setEnd(this, end);
     363    selection.addRange(range);
     364    return this;
     365}
     366
     367Element.prototype.__defineGetter__("selectionLeftOffset", function() {
     368    // Calculate selection offset relative to the current element.
     369
     370    var selection = window.getSelection();
     371    if (!selection.containsNode(this, true))
     372        return null;
     373
     374    var leftOffset = selection.anchorOffset;
     375    var node = selection.anchorNode;
     376
     377    while (node !== this) {
     378        while (node.previousSibling) {
     379            node = node.previousSibling;
     380            leftOffset += node.textContent.length;
     381        }
     382        node = node.parentNode;
     383    }
     384
     385    return leftOffset;
     386});
    330387
    331388Node.prototype.isWhitespace = isNodeWhitespace;
     
    673730}
    674731
     732Array.convert = function(list)
     733{
     734    // Cast array-like object to an array.
     735    return Array.prototype.slice.call(list);
     736}
     737
    675738function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction)
    676739{
Note: See TracChangeset for help on using the changeset viewer.