Changeset 142610 in webkit


Ignore:
Timestamp:
Feb 12, 2013 6:04:08 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Web Inspector: separate SuggestBox from TextPrompt
https://bugs.webkit.org/show_bug.cgi?id=109430

Patch by Andrey Lushnikov <lushnikov@chromium.org> on 2013-02-12
Reviewed by Alexander Pavlov.

Create WebInspector.SuggestBoxDelegate interface and
refactor TextPrompt to use this interface. Separate SuggestBox into
WebInspector.SuggestBox namespace and put it into its own file.

No new tests: no change in behaviour.

  • WebCore.gypi:
  • WebCore.vcproj/WebCore.vcproj:
  • inspector/compile-front-end.py:
  • inspector/front-end/SuggestBox.js: Added.

(WebInspector.SuggestBoxDelegate):
(WebInspector.SuggestBoxDelegate.prototype.applySuggestion):
(WebInspector.SuggestBoxDelegate.prototype.acceptSuggestion):
(WebInspector.SuggestBoxDelegate.prototype.userEnteredText):
(WebInspector.SuggestBox):
(WebInspector.SuggestBox.prototype.get visible):
(WebInspector.SuggestBox.prototype.get hasSelection):
(WebInspector.SuggestBox.prototype._onscrollresize):
(WebInspector.SuggestBox.prototype._updateBoxPositionWithExistingAnchor):
(WebInspector.SuggestBox.prototype._updateBoxPosition):
(WebInspector.SuggestBox.prototype._onboxmousedown):
(WebInspector.SuggestBox.prototype.hide):
(WebInspector.SuggestBox.prototype.removeFromElement):
(WebInspector.SuggestBox.prototype._applySuggestion):
(WebInspector.SuggestBox.prototype.acceptSuggestion):
(WebInspector.SuggestBox.prototype._selectClosest):
(WebInspector.SuggestBox.prototype.updateSuggestions):
(WebInspector.SuggestBox.prototype._onItemMouseDown):
(WebInspector.SuggestBox.prototype._createItemElement):
(WebInspector.SuggestBox.prototype._updateItems):
(WebInspector.SuggestBox.prototype._selectItem):
(WebInspector.SuggestBox.prototype._canShowBox):
(WebInspector.SuggestBox.prototype._rememberRowCountPerViewport):
(WebInspector.SuggestBox.prototype._completionsReady):
(WebInspector.SuggestBox.prototype.upKeyPressed):
(WebInspector.SuggestBox.prototype.downKeyPressed):
(WebInspector.SuggestBox.prototype.pageUpKeyPressed):
(WebInspector.SuggestBox.prototype.pageDownKeyPressed):
(WebInspector.SuggestBox.prototype.enterKeyPressed):
(WebInspector.SuggestBox.prototype.tabKeyPressed):

  • inspector/front-end/TextPrompt.js:

(WebInspector.TextPrompt.prototype.userEnteredText):
(WebInspector.TextPrompt.prototype._attachInternal):
(WebInspector.TextPrompt.prototype._completionsReady):
(WebInspector.TextPrompt.prototype.applySuggestion):
(WebInspector.TextPrompt.prototype._applySuggestion):
(WebInspector.TextPrompt.prototype.enterKeyPressed):
(WebInspector.TextPrompt.prototype.upKeyPressed):
(WebInspector.TextPrompt.prototype.downKeyPressed):
(WebInspector.TextPrompt.prototype.pageUpKeyPressed):
(WebInspector.TextPrompt.prototype.pageDownKeyPressed):

  • inspector/front-end/WebKit.qrc:
  • inspector/front-end/inspector.html:
Location:
trunk/Source/WebCore
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r142608 r142610  
     12013-02-12  Andrey Lushnikov  <lushnikov@chromium.org>
     2
     3        Web Inspector: separate SuggestBox from TextPrompt
     4        https://bugs.webkit.org/show_bug.cgi?id=109430
     5
     6        Reviewed by Alexander Pavlov.
     7
     8        Create WebInspector.SuggestBoxDelegate interface and
     9        refactor TextPrompt to use this interface. Separate SuggestBox into
     10        WebInspector.SuggestBox namespace and put it into its own file.
     11
     12        No new tests: no change in behaviour.
     13
     14        * WebCore.gypi:
     15        * WebCore.vcproj/WebCore.vcproj:
     16        * inspector/compile-front-end.py:
     17        * inspector/front-end/SuggestBox.js: Added.
     18        (WebInspector.SuggestBoxDelegate):
     19        (WebInspector.SuggestBoxDelegate.prototype.applySuggestion):
     20        (WebInspector.SuggestBoxDelegate.prototype.acceptSuggestion):
     21        (WebInspector.SuggestBoxDelegate.prototype.userEnteredText):
     22        (WebInspector.SuggestBox):
     23        (WebInspector.SuggestBox.prototype.get visible):
     24        (WebInspector.SuggestBox.prototype.get hasSelection):
     25        (WebInspector.SuggestBox.prototype._onscrollresize):
     26        (WebInspector.SuggestBox.prototype._updateBoxPositionWithExistingAnchor):
     27        (WebInspector.SuggestBox.prototype._updateBoxPosition):
     28        (WebInspector.SuggestBox.prototype._onboxmousedown):
     29        (WebInspector.SuggestBox.prototype.hide):
     30        (WebInspector.SuggestBox.prototype.removeFromElement):
     31        (WebInspector.SuggestBox.prototype._applySuggestion):
     32        (WebInspector.SuggestBox.prototype.acceptSuggestion):
     33        (WebInspector.SuggestBox.prototype._selectClosest):
     34        (WebInspector.SuggestBox.prototype.updateSuggestions):
     35        (WebInspector.SuggestBox.prototype._onItemMouseDown):
     36        (WebInspector.SuggestBox.prototype._createItemElement):
     37        (WebInspector.SuggestBox.prototype._updateItems):
     38        (WebInspector.SuggestBox.prototype._selectItem):
     39        (WebInspector.SuggestBox.prototype._canShowBox):
     40        (WebInspector.SuggestBox.prototype._rememberRowCountPerViewport):
     41        (WebInspector.SuggestBox.prototype._completionsReady):
     42        (WebInspector.SuggestBox.prototype.upKeyPressed):
     43        (WebInspector.SuggestBox.prototype.downKeyPressed):
     44        (WebInspector.SuggestBox.prototype.pageUpKeyPressed):
     45        (WebInspector.SuggestBox.prototype.pageDownKeyPressed):
     46        (WebInspector.SuggestBox.prototype.enterKeyPressed):
     47        (WebInspector.SuggestBox.prototype.tabKeyPressed):
     48        * inspector/front-end/TextPrompt.js:
     49        (WebInspector.TextPrompt.prototype.userEnteredText):
     50        (WebInspector.TextPrompt.prototype._attachInternal):
     51        (WebInspector.TextPrompt.prototype._completionsReady):
     52        (WebInspector.TextPrompt.prototype.applySuggestion):
     53        (WebInspector.TextPrompt.prototype._applySuggestion):
     54        (WebInspector.TextPrompt.prototype.enterKeyPressed):
     55        (WebInspector.TextPrompt.prototype.upKeyPressed):
     56        (WebInspector.TextPrompt.prototype.downKeyPressed):
     57        (WebInspector.TextPrompt.prototype.pageUpKeyPressed):
     58        (WebInspector.TextPrompt.prototype.pageDownKeyPressed):
     59        * inspector/front-end/WebKit.qrc:
     60        * inspector/front-end/inspector.html:
     61
    1622013-02-12  Bruno de Oliveira Abinader  <bruno.abinader@basyskom.com>
    263
  • trunk/Source/WebCore/WebCore.gypi

    r142573 r142610  
    52785278            'inspector/front-end/StatusBarButton.js',
    52795279            'inspector/front-end/StylesSourceMapping.js',
     5280            'inspector/front-end/SuggestBox.js',
    52805281            'inspector/front-end/TabbedPane.js',
    52815282            'inspector/front-end/TestController.js',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r142535 r142610  
    7777177771                                </File>
    7777277772                                <File
     77773                                        RelativePath="..\inspector\front-end\SuggestBox.js"
     77774                                        >
     77775                                </File>
     77776                                <File
    7777377777                                        RelativePath="..\inspector\front-end\TextPrompt.js"
    7777477778                                        >
  • trunk/Source/WebCore/inspector/compile-front-end.py

    r142474 r142610  
    152152            "SidebarView.js",
    153153            "StatusBarButton.js",
     154            "SuggestBox.js",
    154155            "TabbedPane.js",
    155156            "TextEditor.js",
  • trunk/Source/WebCore/inspector/front-end/TextPrompt.js

    r135683 r142610  
    3131 * @constructor
    3232 * @extends WebInspector.Object
     33 * @implements {WebInspector.SuggestBoxDelegate}
    3334 * @param {function(Element, Range, boolean, function(Array.<string>, number=))} completions
    3435 * @param {string=} stopCharacters
     
    5253
    5354WebInspector.TextPrompt.prototype = {
     55    userEnteredText: function()
     56    {
     57        return this._userEnteredText;
     58    },
     59
    5460    get proxyElement()
    5561    {
     
    118124
    119125        if (typeof this._suggestBoxClassName === "string")
    120             this._suggestBox = new WebInspector.TextPrompt.SuggestBox(this, this._element, this._suggestBoxClassName);
     126            this._suggestBox = new WebInspector.SuggestBox(this, this._element, this._suggestBoxClassName);
    121127
    122128        return this.proxyElement;
     
    521527            }
    522528        } else
    523             this.applySuggestion(completionText, completions.length > 1, originalWordPrefixRange);
     529            this._applySuggestion(completionText, completions.length > 1, originalWordPrefixRange);
    524530    },
    525531
     
    539545
    540546    /**
    541      * @param {Range=} originalPrefixRange
    542      */
    543     applySuggestion: function(completionText, isIntermediateSuggestion, originalPrefixRange)
     547     * @param {string} completionText
     548     * @param {boolean=} isIntermediateSuggestion
     549     */
     550    applySuggestion: function(completionText, isIntermediateSuggestion)
     551    {
     552        this._applySuggestion(completionText, isIntermediateSuggestion);
     553    },
     554
     555    /**
     556     * @param {string} completionText
     557     * @param {boolean=} isIntermediateSuggestion
     558     * @param {Range} originalPrefixRange
     559     */
     560    _applySuggestion: function(completionText, isIntermediateSuggestion, originalPrefixRange)
    544561    {
    545562        var wordPrefixLength;
     
    718735    {
    719736        if (this.isSuggestBoxVisible())
    720             return this._suggestBox.enterKeyPressed(event);
     737            return this._suggestBox.enterKeyPressed();
    721738
    722739        return false;
     
    726743    {
    727744        if (this.isSuggestBoxVisible())
    728             return this._suggestBox.upKeyPressed(event);
     745            return this._suggestBox.upKeyPressed();
    729746
    730747        return false;
     
    734751    {
    735752        if (this.isSuggestBoxVisible())
    736             return this._suggestBox.downKeyPressed(event);
     753            return this._suggestBox.downKeyPressed();
    737754
    738755        return false;
     
    742759    {
    743760        if (this.isSuggestBoxVisible())
    744             return this._suggestBox.pageUpKeyPressed(event);
     761            return this._suggestBox.pageUpKeyPressed();
    745762
    746763        return false;
     
    750767    {
    751768        if (this.isSuggestBoxVisible())
    752             return this._suggestBox.pageDownKeyPressed(event);
     769            return this._suggestBox.pageDownKeyPressed();
    753770
    754771        return false;
     
    927944}
    928945
    929 /**
    930  * @constructor
    931  */
    932 WebInspector.TextPrompt.SuggestBox = function(textPrompt, inputElement, className)
    933 {
    934     this._textPrompt = textPrompt;
    935     this._inputElement = inputElement;
    936     this._length = 0;
    937     this._selectedIndex = -1;
    938     this._selectedElement = null;
    939     this._boundOnScroll = this._onscrollresize.bind(this, true);
    940     this._boundOnResize = this._onscrollresize.bind(this, false);
    941     window.addEventListener("scroll", this._boundOnScroll, true);
    942     window.addEventListener("resize", this._boundOnResize, true);
    943 
    944     this._bodyElement = inputElement.ownerDocument.body;
    945     this._element = inputElement.ownerDocument.createElement("div");
    946     this._element.className = "suggest-box " + (className || "");
    947     this._element.addEventListener("mousedown", this._onboxmousedown.bind(this), true);
    948     this.containerElement = this._element.createChild("div", "container");
    949     this.contentElement = this.containerElement.createChild("div", "content");
    950 }
    951 
    952 WebInspector.TextPrompt.SuggestBox.prototype = {
    953     get visible()
    954     {
    955         return !!this._element.parentElement;
    956     },
    957 
    958     get hasSelection()
    959     {
    960         return !!this._selectedElement;
    961     },
    962 
    963     _onscrollresize: function(isScroll, event)
    964     {
    965         if (isScroll && this._element.isAncestor(event.target) || !this.visible)
    966             return;
    967         this._updateBoxPositionWithExistingAnchor();
    968     },
    969 
    970     _updateBoxPositionWithExistingAnchor: function()
    971     {
    972         this._updateBoxPosition(this._anchorBox);
    973     },
    974 
    975     /**
    976      * @param {AnchorBox} anchorBox
    977      */
    978     _updateBoxPosition: function(anchorBox)
    979     {
    980         // Measure the content element box.
    981         this.contentElement.style.display = "inline-block";
    982         document.body.appendChild(this.contentElement);
    983         this.contentElement.positionAt(0, 0);
    984         var contentWidth = this.contentElement.offsetWidth;
    985         var contentHeight = this.contentElement.offsetHeight;
    986         this.contentElement.style.display = "block";
    987         this.containerElement.appendChild(this.contentElement);
    988 
    989         // Lay out the suggest-box relative to the anchorBox.
    990         this._anchorBox = anchorBox;
    991         const spacer = 6;
    992 
    993         const suggestBoxPaddingX = 21;
    994         var maxWidth = document.body.offsetWidth - anchorBox.x - spacer;
    995         var width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
    996         var paddedWidth = contentWidth + suggestBoxPaddingX;
    997         var boxX = anchorBox.x;
    998         if (width < paddedWidth) {
    999             // Shift the suggest box to the left to accommodate the content without trimming to the BODY edge.
    1000             maxWidth = document.body.offsetWidth - spacer;
    1001             width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
    1002             boxX = document.body.offsetWidth - width;
    1003         }
    1004 
    1005         const suggestBoxPaddingY = 2;
    1006         var boxY;
    1007         var aboveHeight = anchorBox.y;
    1008         var underHeight = document.body.offsetHeight - anchorBox.y - anchorBox.height;
    1009         var maxHeight = Math.max(underHeight, aboveHeight) - spacer;
    1010         var height = Math.min(contentHeight, maxHeight - suggestBoxPaddingY) + suggestBoxPaddingY;
    1011         if (underHeight >= aboveHeight) {
    1012             // Locate the suggest box under the anchorBox.
    1013             boxY = anchorBox.y + anchorBox.height;
    1014             this._element.removeStyleClass("above-anchor");
    1015             this._element.addStyleClass("under-anchor");
    1016         } else {
    1017             // Locate the suggest box above the anchorBox.
    1018             boxY = anchorBox.y - height;
    1019             this._element.removeStyleClass("under-anchor");
    1020             this._element.addStyleClass("above-anchor");
    1021         }
    1022 
    1023         this._element.positionAt(boxX, boxY);
    1024         this._element.style.width = width + "px";
    1025         this._element.style.height = height + "px";
    1026     },
    1027 
    1028     _onboxmousedown: function(event)
    1029     {
    1030         event.preventDefault();
    1031     },
    1032 
    1033     hide: function()
    1034     {
    1035         if (!this.visible)
    1036             return;
    1037 
    1038         this._element.parentElement.removeChild(this._element);
    1039         delete this._selectedElement;
    1040     },
    1041 
    1042     removeFromElement: function()
    1043     {
    1044         window.removeEventListener("scroll", this._boundOnScroll, true);
    1045         window.removeEventListener("resize", this._boundOnResize, true);
    1046         this.hide();
    1047     },
    1048 
    1049     /**
    1050      * @param {string=} text
    1051      * @param {boolean=} isIntermediateSuggestion
    1052      */
    1053     _applySuggestion: function(text, isIntermediateSuggestion)
    1054     {
    1055         if (!this.visible || !(text || this._selectedElement))
    1056             return false;
    1057 
    1058         var suggestion = text || this._selectedElement.textContent;
    1059         if (!suggestion)
    1060             return false;
    1061 
    1062         this._textPrompt.applySuggestion(suggestion, isIntermediateSuggestion);
    1063         return true;
    1064     },
    1065 
    1066     /**
    1067      * @param {string=} text
    1068      */
    1069     acceptSuggestion: function(text)
    1070     {
    1071         var result = this._applySuggestion(text, false);
    1072         this.hide();
    1073         if (!result)
    1074             return false;
    1075 
    1076         this._textPrompt.acceptSuggestion();
    1077 
    1078         return true;
    1079     },
    1080 
    1081     /**
    1082      * @param {number} shift
    1083      * @param {boolean=} isCircular
    1084      * @return {boolean} is changed
    1085      */
    1086     _selectClosest: function(shift, isCircular)
    1087     {
    1088         if (!this._length)
    1089             return false;
    1090 
    1091         var index = this._selectedIndex + shift;
    1092 
    1093         if (isCircular)
    1094             index = (this._length + index) % this._length;
    1095         else
    1096             index = Number.constrain(index, 0, this._length - 1);
    1097 
    1098         this._selectItem(index);
    1099         this._applySuggestion(undefined, true);
    1100         return true;
    1101     },
    1102 
    1103     /**
    1104      * @param {AnchorBox} anchorBox
    1105      * @param {Array.<string>=} completions
    1106      * @param {number=} selectedIndex
    1107      * @param {boolean=} canShowForSingleItem
    1108      */
    1109     updateSuggestions: function(anchorBox, completions, selectedIndex, canShowForSingleItem)
    1110     {
    1111         if (this._suggestTimeout) {
    1112             clearTimeout(this._suggestTimeout);
    1113             delete this._suggestTimeout;
    1114         }
    1115         this._completionsReady(anchorBox, completions, selectedIndex, canShowForSingleItem);
    1116     },
    1117 
    1118     _onItemMouseDown: function(text, event)
    1119     {
    1120         this.acceptSuggestion(text);
    1121         event.consume(true);
    1122     },
    1123 
    1124     _createItemElement: function(prefix, text)
    1125     {
    1126         var element = document.createElement("div");
    1127         element.className = "suggest-box-content-item source-code";
    1128         element.tabIndex = -1;
    1129         if (prefix && prefix.length && !text.indexOf(prefix)) {
    1130             var prefixElement = element.createChild("span", "prefix");
    1131             prefixElement.textContent = prefix;
    1132             var suffixElement = element.createChild("span", "suffix");
    1133             suffixElement.textContent = text.substring(prefix.length);
    1134         } else {
    1135             var suffixElement = element.createChild("span", "suffix");
    1136             suffixElement.textContent = text;
    1137         }
    1138         element.addEventListener("mousedown", this._onItemMouseDown.bind(this, text), false);
    1139         return element;
    1140     },
    1141 
    1142     /**
    1143      * @param {Array.<string>=} items
    1144      * @param {number=} selectedIndex
    1145      */
    1146     _updateItems: function(items, selectedIndex)
    1147     {
    1148         this._length = items.length;
    1149         this.contentElement.removeChildren();
    1150 
    1151         var userEnteredText = this._textPrompt._userEnteredText;
    1152         for (var i = 0; i < items.length; ++i) {
    1153             var item = items[i];
    1154             var currentItemElement = this._createItemElement(userEnteredText, item);
    1155             this.contentElement.appendChild(currentItemElement);
    1156         }
    1157 
    1158         this._selectedElement = null;
    1159         if (typeof selectedIndex === "number")
    1160             this._selectItem(selectedIndex);
    1161     },
    1162 
    1163     /**
    1164      * @param {number} index
    1165      */
    1166     _selectItem: function(index)
    1167     {
    1168         if (this._selectedElement)
    1169             this._selectedElement.classList.remove("selected");
    1170 
    1171         this._selectedIndex = index;
    1172         this._selectedElement = this.contentElement.children[index];
    1173         this._selectedElement.classList.add("selected");
    1174 
    1175         this._selectedElement.scrollIntoViewIfNeeded(false);
    1176     },
    1177 
    1178     /**
    1179      * @param {Array.<string>=} completions
    1180      * @param {boolean=} canShowForSingleItem
    1181      */
    1182     _canShowBox: function(completions, canShowForSingleItem)
    1183     {
    1184         if (!completions || !completions.length)
    1185             return false;
    1186 
    1187         if (completions.length > 1)
    1188             return true;
    1189 
    1190         // Do not show a single suggestion if it is the same as user-entered prefix, even if allowed to show single-item suggest boxes.
    1191         return canShowForSingleItem && completions[0] !== this._textPrompt._userEnteredText;
    1192     },
    1193 
    1194     _rememberRowCountPerViewport: function()
    1195     {
    1196         if (!this.contentElement.firstChild)
    1197             return;
    1198 
    1199         this._rowCountPerViewport = Math.floor(this.containerElement.offsetHeight / this.contentElement.firstChild.offsetHeight);
    1200     },
    1201 
    1202     /**
    1203      * @param {AnchorBox} anchorBox
    1204      * @param {Array.<string>=} completions
    1205      * @param {number=} selectedIndex
    1206      * @param {boolean=} canShowForSingleItem
    1207      */
    1208     _completionsReady: function(anchorBox, completions, selectedIndex, canShowForSingleItem)
    1209     {
    1210         if (this._canShowBox(completions, canShowForSingleItem)) {
    1211             this._updateItems(completions, selectedIndex);
    1212             this._updateBoxPosition(anchorBox);
    1213             if (!this.visible)
    1214                 this._bodyElement.appendChild(this._element);
    1215             this._rememberRowCountPerViewport();
    1216         } else
    1217             this.hide();
    1218     },
    1219 
    1220     upKeyPressed: function(event)
    1221     {
    1222         return this._selectClosest(-1, true);
    1223     },
    1224 
    1225     downKeyPressed: function(event)
    1226     {
    1227         return this._selectClosest(1, true);
    1228     },
    1229 
    1230     pageUpKeyPressed: function(event)
    1231     {
    1232         return this._selectClosest(-this._rowCountPerViewport, false);
    1233     },
    1234 
    1235     pageDownKeyPressed: function(event)
    1236     {
    1237         return this._selectClosest(this._rowCountPerViewport, false);
    1238     },
    1239 
    1240     enterKeyPressed: function(event)
    1241     {
    1242         var hasSelectedItem = !!this._selectedElement;
    1243         this.acceptSuggestion();
    1244 
    1245         // Report the event as non-handled if there is no selected item,
    1246         // to commit the input or handle it otherwise.
    1247         return hasSelectedItem;
    1248     },
    1249 
    1250     tabKeyPressed: function(event)
    1251     {
    1252         return this.enterKeyPressed(event);
    1253     }
    1254 }
  • trunk/Source/WebCore/inspector/front-end/WebKit.qrc

    r142474 r142610  
    198198    <file>StylesSourceMapping.js</file>
    199199    <file>StylesSidebarPane.js</file>
     200    <file>SuggestBox.js</file>
    200201    <file>TabbedEditorContainer.js</file>
    201202    <file>TabbedPane.js</file>
  • trunk/Source/WebCore/inspector/front-end/inspector.html

    r142474 r142610  
    5757    <script type="text/javascript" src="SoftContextMenu.js"></script>
    5858    <script type="text/javascript" src="KeyboardShortcut.js"></script>
     59    <script type="text/javascript" src="SuggestBox.js"></script>
    5960    <script type="text/javascript" src="TextPrompt.js"></script>
    6061    <script type="text/javascript" src="Popover.js"></script>
Note: See TracChangeset for help on using the changeset viewer.