author | Rob Campbell <rcampbell@mozilla.com> |
Sat, 01 Feb 2014 08:22:45 -0500 | |
changeset 166453 | 5becc145339321827983e5612d5aa488b9517be1 |
parent 166452 | 41ac71fd705e126e1e1f4c2323db8245bf0be4db |
child 166454 | 9f1c9cf5040f917d2c2f866f3f743ab10edfd5a3 |
push id | 26127 |
push user | philringnalda@gmail.com |
push date | Sun, 02 Feb 2014 17:11:12 +0000 |
treeherder | mozilla-central@2918a9e625b4 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | msucan |
bugs | 962531 |
milestone | 29.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/devtools/shared/autocomplete-popup.js +++ b/browser/devtools/shared/autocomplete-popup.js @@ -449,16 +449,27 @@ AutocompletePopup.prototype = { * Getter for the number of items in the popup. * @type number */ get itemCount() { return this._list.childNodes.length; }, /** + * Getter for the height of each item in the list. + * + * @private + * + * @type number + */ + get _itemHeight() { + return this._list.selectedItem.clientHeight; + }, + + /** * Select the next item in the list. * * @return object * The newly selected item object. */ selectNextItem: function AP_selectNextItem() { if (this.selectedIndex < (this.itemCount - 1)) { @@ -470,31 +481,64 @@ AutocompletePopup.prototype = { return this.selectedItem; }, /** * Select the previous item in the list. * * @return object - * The newly selected item object. + * The newly-selected item object. */ selectPreviousItem: function AP_selectPreviousItem() { if (this.selectedIndex > 0) { this.selectedIndex--; } else { this.selectedIndex = this.itemCount - 1; } return this.selectedItem; }, /** + * Select the top-most item in the next page of items or + * the last item in the list. + * + * @return object + * The newly-selected item object. + */ + selectNextPageItem: function AP_selectNextPageItem() + { + let itemsPerPane = Math.floor(this._list.scrollHeight / this._itemHeight); + let nextPageIndex = this.selectedIndex + itemsPerPane + 1; + this.selectedIndex = nextPageIndex > this.itemCount - 1 ? + this.itemCount - 1 : nextPageIndex; + + return this.selectedItem; + }, + + /** + * Select the bottom-most item in the previous page of items, + * or the first item in the list. + * + * @return object + * The newly-selected item object. + */ + selectPreviousPageItem: function AP_selectPreviousPageItem() + { + let itemsPerPane = Math.floor(this._list.scrollHeight / this._itemHeight); + let prevPageIndex = this.selectedIndex - itemsPerPane - 1; + this.selectedIndex = prevPageIndex < 0 ? 0 : prevPageIndex; + + return this.selectedItem; + }, + + /** * Focuses the richlistbox. */ focus: function AP_focus() { this._list.focus(); }, /**
--- a/browser/devtools/webconsole/test/browser_console_keyboard_accessibility.js +++ b/browser/devtools/webconsole/test/browser_console_keyboard_accessibility.js @@ -17,29 +17,39 @@ function test() openConsole(null, consoleOpened); }, true); function consoleOpened(aHud) { hud = aHud; ok(hud, "Web Console opened"); - content.console.log("foobarz1"); + info("dump some spew into the console for scrolling"); + for (let i = 0; i < 100; i++) + content.console.log("foobarz" + i); waitForMessages({ webconsole: hud, messages: [{ - text: "foobarz1", + text: "foobarz99", category: CATEGORY_WEBDEV, severity: SEVERITY_LOG, }], }).then(onConsoleMessage); } function onConsoleMessage() { + let currentPosition = hud.outputNode.parentNode.scrollTop; + EventUtils.synthesizeKey("VK_PAGE_UP", {}); + isnot(hud.outputNode.parentNode.scrollTop, currentPosition, "scroll position changed after page up"); + + currentPosition = hud.outputNode.parentNode.scrollTop; + EventUtils.synthesizeKey("VK_PAGE_DOWN", {}); + ok(hud.outputNode.parentNode.scrollTop > currentPosition, "scroll position now at bottom"); + hud.jsterm.once("messages-cleared", onClear); info("try ctrl-l to clear output"); EventUtils.synthesizeKey("l", { ctrlKey: true }); } function onClear() { is(hud.outputNode.textContent.indexOf("foobarz1"), -1, "output cleared");
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js +++ b/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js @@ -86,16 +86,28 @@ function consoleOpened(aHud) { EventUtils.synthesizeKey("VK_UP", {}); is(popup.selectedIndex, 0, "index 0 is selected"); is(popup.selectedItem.label, "watch", "watch is selected"); is(completeNode.value, prefix + "watch", "completeNode.value holds watch"); + let currentSelectionIndex = popup.selectedIndex; + + EventUtils.synthesizeKey("VK_PAGE_DOWN", {}); + + ok(popup.selectedIndex > currentSelectionIndex, + "Index is greater after PGDN"); + + currentSelectionIndex = popup.selectedIndex; + EventUtils.synthesizeKey("VK_PAGE_UP", {}); + + ok(popup.selectedIndex < currentSelectionIndex, "Index is less after Page UP"); + info("press Tab and wait for popup to hide"); popup._panel.addEventListener("popuphidden", popupHideAfterTab, false); EventUtils.synthesizeKey("VK_TAB", {}); }, false); info("wait for completion: window.foobarBug585991."); jsterm.setInputValue("window.foobarBug585991"); EventUtils.synthesizeKey(".", {});
--- a/browser/devtools/webconsole/webconsole.js +++ b/browser/devtools/webconsole/webconsole.js @@ -2656,18 +2656,16 @@ WebConsoleFrame.prototype = { if (aEvent.detail != 1 || aEvent.button != 0) { return; } aEvent.preventDefault(); // If this event started with a mousedown event and it ends at a different // location, we consider this text selection. - // Add a fuzz modifier of two pixels in any direction to account for sloppy - // clicking. if (mousedown && (this._startX != aEvent.clientX) && (this._startY != aEvent.clientY)) { this._startX = this._startY = undefined; return; } @@ -3058,16 +3056,18 @@ JSTerm.prototype = { * Getter for the debugger WebConsoleClient. * @type object */ get webConsoleClient() this.hud.webConsoleClient, COMPLETE_FORWARD: 0, COMPLETE_BACKWARD: 1, COMPLETE_HINT_ONLY: 2, + COMPLETE_PAGEUP: 3, + COMPLETE_PAGEDOWN: 4, /** * Initialize the JSTerminal UI. */ init: function JST_init() { let autocompleteOptions = { onSelect: this.onAutocompleteSelect.bind(this), @@ -3919,16 +3919,50 @@ JSTerm.prototype = { else if (this.canCaretGoNext()) { inputUpdated = this.historyPeruse(HISTORY_FORWARD); } if (inputUpdated) { aEvent.preventDefault(); } break; + case Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP: + if (this.autocompletePopup.isOpen) { + inputUpdated = this.complete(this.COMPLETE_PAGEUP); + if (inputUpdated) { + this._autocompletePopupNavigated = true; + } + } + else { + this.hud.outputNode.parentNode.scrollTop = + Math.max(0, + this.hud.outputNode.parentNode.scrollTop - + this.hud.outputNode.parentNode.clientHeight + ); + } + aEvent.preventDefault(); + break; + + case Ci.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN: + if (this.autocompletePopup.isOpen) { + inputUpdated = this.complete(this.COMPLETE_PAGEDOWN); + if (inputUpdated) { + this._autocompletePopupNavigated = true; + } + } + else { + this.hud.outputNode.parentNode.scrollTop = + Math.min(this.hud.outputNode.parentNode.scrollHeight, + this.hud.outputNode.parentNode.scrollTop + + this.hud.outputNode.parentNode.clientHeight + ); + } + aEvent.preventDefault(); + break; + case Ci.nsIDOMKeyEvent.DOM_VK_HOME: case Ci.nsIDOMKeyEvent.DOM_VK_END: case Ci.nsIDOMKeyEvent.DOM_VK_LEFT: if (this.autocompletePopup.isOpen || this.lastCompletion.value) { this.clearCompletion(); } break; @@ -4090,16 +4124,20 @@ JSTerm.prototype = { * completions is used. If the value changed, then the first possible * completion is used and the selection is set from the current * cursor position to the end of the completed text. * If there is only one possible completion, then this completion * value is used and the cursor is put at the end of the completion. * - this.COMPLETE_BACKWARD: Same as this.COMPLETE_FORWARD but if the * value stayed the same as the last time the function was called, * then the previous completion of all possible completions is used. + * - this.COMPLETE_PAGEUP: Scroll up one page if available or select the first + * item. + * - this.COMPLETE_PAGEDOWN: Scroll down one page if available or select the + * last item. * - this.COMPLETE_HINT_ONLY: If there is more than one possible * completion and the input value stayed the same compared to the * last time this function was called, then the same completion is * used again. If there is only one possible completion, then * the inputNode.value is set to this value and the selection is set * from the current cursor position to the end of the completed text. * @param function aCallback * Optional function invoked when the autocomplete properties are @@ -4143,16 +4181,22 @@ JSTerm.prototype = { accepted = true; } else if (aType == this.COMPLETE_BACKWARD) { popup.selectPreviousItem(); } else if (aType == this.COMPLETE_FORWARD) { popup.selectNextItem(); } + else if (aType == this.COMPLETE_PAGEUP) { + popup.selectPreviousPageItem(); + } + else if (aType == this.COMPLETE_PAGEDOWN) { + popup.selectNextPageItem(); + } aCallback && aCallback(this); this.emit("autocomplete-updated"); return accepted || popup.itemCount > 0; }, /** * Update the completion result. This operation is performed asynchronously by