From c1dcaf8c48f47b476268d0d79ea0f6d9011c6c79 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 1 Mar 2010 16:10:31 -0500 Subject: [PATCH] Bug 546273 - Form Assistant misses focus on profiles.yahoo.com [r=mark.finkle] --- mobile/chrome/content/browser-ui.js | 12 +- mobile/chrome/tests/Makefile.in | 3 + .../chrome/tests/browser_FormAssistant.html | 43 +++++++ mobile/chrome/tests/browser_FormAssistant.js | 109 ++++++++++++++++++ mobile/chrome/tests/browser_bookmarks.js | 36 ++---- .../chrome/tests/browser_bookmarks_folders.js | 11 +- mobile/chrome/tests/browser_bookmarks_star.js | 28 +---- mobile/chrome/tests/browser_bookmarks_tags.js | 28 +---- mobile/chrome/tests/browser_select.js | 15 --- mobile/chrome/tests/head.js | 25 ++++ 10 files changed, 208 insertions(+), 102 deletions(-) create mode 100644 mobile/chrome/tests/browser_FormAssistant.html create mode 100644 mobile/chrome/tests/browser_FormAssistant.js create mode 100644 mobile/chrome/tests/head.js diff --git a/mobile/chrome/content/browser-ui.js b/mobile/chrome/content/browser-ui.js index fc1dd33e1659..7f274a526454 100644 --- a/mobile/chrome/content/browser-ui.js +++ b/mobile/chrome/content/browser-ui.js @@ -1068,6 +1068,7 @@ var BookmarkList = { }; var FormHelper = { + _open: false, _nodes: null, get _container() { delete this._container; @@ -1143,7 +1144,7 @@ var FormHelper = { if (this._isValidSelectElement(aElement) || aElement instanceof HTMLTextAreaElement) return this._isElementVisible(aElement); - if (aElement instanceof HTMLInputElement) { + if (aElement instanceof HTMLInputElement || aElement instanceof HTMLButtonElement) { let ignoreInputElements = ["checkbox", "radio", "hidden", "reset", "button"]; let isValidElement = (ignoreInputElements.indexOf(aElement.type) == -1); if (!isValidElement) @@ -1160,8 +1161,12 @@ var FormHelper = { }, _isElementVisible: function(aElement) { + let style = aElement.ownerDocument.defaultView.getComputedStyle(aElement, null); + let isVisible = (style.getPropertyValue("visibility") != "hidden"); + let isOpaque = (style.getPropertyValue("opacity") != 0); + let rect = aElement.getBoundingClientRect(); - return (rect.height != 0 || rect.width != 0); + return isVisible && isOpaque && (rect.height != 0 || rect.width != 0); }, _getAll: function() { @@ -1357,6 +1362,9 @@ var FormHelper = { if (aElement instanceof HTMLInputElement && formExceptions.indexOf(aElement.type) != -1) return false; + if (aElement instanceof HTMLButtonElement || (aElement.getAttribute("role") == "button" && aElement.hasAttribute("tabindex"))) + return false; + return this._isValidElement(aElement); } }; diff --git a/mobile/chrome/tests/Makefile.in b/mobile/chrome/tests/Makefile.in index 61e136381060..e2ba1a3832e5 100644 --- a/mobile/chrome/tests/Makefile.in +++ b/mobile/chrome/tests/Makefile.in @@ -45,6 +45,7 @@ include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/rules.mk _BROWSER_FILES = \ + head.js \ browser_mainui.js \ browser_tabs.js \ browser_bookmarks.js \ @@ -52,9 +53,11 @@ _BROWSER_FILES = \ browser_bookmarks_tags.js \ browser_select.js \ browser_rect.js \ + browser_FormAssistant.js \ browser_blank_01.html \ browser_blank_02.html \ browser_select.html \ + browser_FormAssistant.html \ $(NULL) libs:: $(_BROWSER_FILES) diff --git a/mobile/chrome/tests/browser_FormAssistant.html b/mobile/chrome/tests/browser_FormAssistant.html new file mode 100644 index 000000000000..307b3bd2e709 --- /dev/null +++ b/mobile/chrome/tests/browser_FormAssistant.html @@ -0,0 +1,43 @@ + + + Browser Form Assistant + + + + + + + + + + text + +
click here
+ + + + dumb type + + +
div
+ + + + + + + + + + + + + + + + diff --git a/mobile/chrome/tests/browser_FormAssistant.js b/mobile/chrome/tests/browser_FormAssistant.js new file mode 100644 index 000000000000..6e55aabc6594 --- /dev/null +++ b/mobile/chrome/tests/browser_FormAssistant.js @@ -0,0 +1,109 @@ +let testURL = "chrome://mochikit/content/browser/mobile/chrome/browser_FormAssistant.html"; +let newTab = null; +let container = null; + +function test() { + // This test is async + waitForExplicitFinish(); + + // Add new tab to hold the page + newTab = Browser.addTab(testURL, true); + BrowserUI.closeAutoComplete(true); + + // Wait for the tab to load, then do the test + waitFor(onTabLoaded, function() { return newTab._loading == false;}); +} + +function onTabLoaded() { + container = document.getElementById("form-helper-container"); + testMouseEvents(); +} + +function testMouseEvents() { + // Sending a synthesized event directly on content should not work - we + // don't want web content to be able to open the form helper without the + // user consent, so we have to pass throught the canvas tile-container + EventUtils.sendMouseEvent({type: "click"}, "root", newTab.browser.contentWindow); + is(FormHelper._open, false, "Form Assistant should stay closed"); + + let element = newTab.browser.contentDocument.querySelector("*[tabindex='0']"); + EventUtils.synthesizeMouseForContent(element, 1, 1, {}, window); + + // XXX because InputHandler hold us for at least 400ms we should wait a bit here + setTimeout (function() { + ok(FormHelper._open, "Form Assistant should be open"); + testShowUIForElements(); + }, 1700); +}; + +function testShowUIForElements() { + let doc = newTab.browser.contentDocument; + + ok(FormHelper.canShowUIFor(doc.querySelector("*[tabindex='1']")), "canShowUI for input type='text'"); + ok(FormHelper.canShowUIFor(doc.querySelector("*[tabindex='2']")), "canShowUI for input type='password'"); + is(FormHelper.canShowUIFor(doc.querySelector("*[tabindex='3']")), false, "!canShowUI for input type='submit'"); + is(FormHelper.canShowUIFor(doc.querySelector("*[tabindex='4']")), false, "!canShowUI for input type='file'"); + is(FormHelper.canShowUIFor(doc.querySelector("*[tabindex='5']")), false, "!canShowUI for input button type='submit'"); + is(FormHelper.canShowUIFor(doc.querySelector("*[tabindex='6']")), false, "!canShowUI for div@role='button'"); + is(FormHelper.canShowUIFor(doc.querySelector("*[tabindex='7']")), false, "!canShowUI for input type='image'"); + + testTabIndexNavigation(); +}; + +function testTabIndexNavigation() { + // Open the Form Helper + let firstElement = newTab.browser.contentDocument.getElementById("root"); + FormHelper.open(firstElement); + is(container.hidden, false, "Form Assistant should be open"); + + FormHelper.goToPrevious(); + let element = newTab.browser.contentDocument.querySelector("*[tabindex='0']"); + isnot(FormHelper.getCurrentElement(), element, "Focus should not have changed"); + + FormHelper.goToNext(); + element = newTab.browser.contentDocument.querySelector("*[tabindex='2']"); + is(FormHelper.getCurrentElement(), element, "Focus should be on element with tab-index : 2"); + + FormHelper.goToPrevious(); + element = newTab.browser.contentDocument.querySelector("*[tabindex='1']"); + is(FormHelper.getCurrentElement(), element, "Focus should be on element with tab-index : 1"); + + FormHelper.goToNext(); + FormHelper.goToNext(); + FormHelper.goToNext(); + FormHelper.goToNext(); + FormHelper.goToNext(); + FormHelper.goToNext(); + + element = newTab.browser.contentDocument.querySelector("*[tabindex='7']"); + is(FormHelper.getCurrentElement(), element, "Focus should be on element with tab-index : 7"); + + FormHelper.goToNext(); + element = newTab.browser.contentDocument.querySelector("*[tabindex='0']"); + is(FormHelper.getCurrentElement(), element, "Focus should be on element with tab-index : 0"); + + FormHelper.goToNext(); + element = newTab.browser.contentDocument.getElementById("next"); + is(FormHelper.getCurrentElement(), element, "Focus should be on element with #id: next"); + + FormHelper.goToNext(); + FormHelper.goToNext(); + FormHelper.goToNext(); + FormHelper.goToNext(); + + element = newTab.browser.contentDocument.getElementById("last"); + is(FormHelper.getCurrentElement(), element, "Focus should be on element with #id: last"); + + FormHelper.goToNext(); + is(FormHelper.getCurrentElement(), element, "Focus should be on element with #id: last"); + + FormHelper.close(); + is(container.hidden, true, "Form Assistant should be close"); + + // Close our tab when finished + Browser.closeTab(newTab); + + // We must finialize the tests + finish(); +}; + diff --git a/mobile/chrome/tests/browser_bookmarks.js b/mobile/chrome/tests/browser_bookmarks.js index ce5a03d1d50e..8daa5fa00cdc 100644 --- a/mobile/chrome/tests/browser_bookmarks.js +++ b/mobile/chrome/tests/browser_bookmarks.js @@ -3,8 +3,7 @@ * code in mobile/chrome/content in terms of integration with Places * component, specifically for bookmark management. */ - -var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); + var testURL_01 = "chrome://mochikit/content/browser/mobile/chrome/browser_blank_01.html"; var testURL_02 = "chrome://mochikit/content/browser/mobile/chrome/browser_blank_02.html"; @@ -66,7 +65,7 @@ gTests.push({ var starbutton = document.getElementById("tool-star"); starbutton.click(); - var bookmarkItem = PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_01)); + var bookmarkItem = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)); ok(bookmarkItem != -1, testURL_01 + " should be added."); Browser.closeTab(gCurrentTest._currenttab); @@ -149,9 +148,9 @@ gTests.push({ var donebutton = document.getAnonymousElementByAttribute(bookmarkitem, "anonid", "done-button"); donebutton.click(); - var bookmark = PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_01)); + var bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)); is(bookmark, -1, testURL_01 + " should no longer in bookmark"); - bookmark = PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_02)); + bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)); isnot(bookmark, -1, testURL_02 + " is in bookmark"); BookmarkList.close(); @@ -176,7 +175,7 @@ gTests.push({ }, onBookmarksReady: function() { - var bookmark = PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_02)); + var bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)); is(PlacesUtils.bookmarks.getItemTitle(bookmark), "Browser Blank Page 01", "Title remains the same."); var bookmarkitems = document.getElementById("bookmark-items"); @@ -190,7 +189,7 @@ gTests.push({ var donebutton = document.getAnonymousElementByAttribute(bookmarkitem, "anonid", "done-button"); donebutton.click(); - isnot(PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_02)), -1, testURL_02 + " is still in bookmark."); + isnot(PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)), -1, testURL_02 + " is still in bookmark."); is(PlacesUtils.bookmarks.getItemTitle(bookmark), newtitle, "Title is changed."); BookmarkList.close(); @@ -227,9 +226,9 @@ gTests.push({ var removebutton = document.getAnonymousElementByAttribute(gCurrentTest.bookmarkitem, "anonid", "remove-button"); removebutton.click(); - var bookmark = PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_02)); + var bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)); ok(bookmark == -1, testURL_02 + " should no longer in bookmark"); - bookmark = PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_01)); + bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)); ok(bookmark == -1, testURL_01 + " should no longer in bookmark"); BookmarkList.close(); @@ -237,22 +236,3 @@ gTests.push({ runNextTest(); } }); - -//------------------------------------------------------------------------------ -// Helpers -function uri(spec) { - return ioService.newURI(spec, null, null); -} - -function waitFor(callback, test, timeout) { - if (test()) { - callback(); - return; - } - - timeout = timeout || Date.now(); - if (Date.now() - timeout > 1000) - throw "waitFor timeout"; - setTimeout(waitFor, 50, callback, test, timeout); -} - diff --git a/mobile/chrome/tests/browser_bookmarks_folders.js b/mobile/chrome/tests/browser_bookmarks_folders.js index 34dc5a0b5340..a09c741387c9 100644 --- a/mobile/chrome/tests/browser_bookmarks_folders.js +++ b/mobile/chrome/tests/browser_bookmarks_folders.js @@ -4,7 +4,6 @@ * component, specifically for bookmark management. */ -var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); var thread = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager).currentThread; var testURL_02 = "chrome://mochikit/content/browser/mobile/chrome/browser_blank_02.html"; var chromeWindow = window; @@ -36,10 +35,10 @@ var gCurrentTest = null; function test() { // test testing dependencies ok(isnot, "Mochitest must be in context"); - ok(ioService, "nsIIOService must be in context"); ok(thread, "nsIThreadManager must be in context"); ok(PlacesUtils, "PlacesUtils must be in context"); ok(EventUtils, "EventUtils must be in context"); + ok(gIOService, "nsIIOService must be in context"); ok(chromeWindow, "ChromeWindow must be in context"); ok(true, "*** Starting test browser_bookmark_folders.js\n"); @@ -205,7 +204,7 @@ gTests.push({ var donebutton = chromeWindow.document.getAnonymousElementByAttribute(folderitem, "anonid", "done-button"); donebutton.click(); - var bookmarkitemid = PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_02)); + var bookmarkitemid = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)); is(PlacesUtils.bookmarks.getFolderIdForItem(bookmarkitemid), BookmarkList.mobileRoot, "bookmark starts off in root"); // Move bookmark @@ -340,9 +339,3 @@ gTests.push({ }, }); - -//------------------------------------------------------------------------------ -// Helpers -function uri(spec) { - return ioService.newURI(spec, null, null); -} diff --git a/mobile/chrome/tests/browser_bookmarks_star.js b/mobile/chrome/tests/browser_bookmarks_star.js index c26257ecea4e..bbc0d7343ced 100644 --- a/mobile/chrome/tests/browser_bookmarks_star.js +++ b/mobile/chrome/tests/browser_bookmarks_star.js @@ -4,7 +4,6 @@ * component, specifically for bookmark management. */ -var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); var testURL_01 = "chrome://mochikit/content/browser/mobile/chrome/browser_blank_01.html"; var testURL_02 = "chrome://mochikit/content/browser/mobile/chrome/browser_blank_02.html"; @@ -159,7 +158,7 @@ gTests.push({ }, onEditorDone: function() { - var tagsarray = PlacesUtils.tagging.getTagsForURI(uri(testURL_02), {}); + var tagsarray = PlacesUtils.tagging.getTagsForURI(makeURI(testURL_02), {}); is(tagsarray.length, 4, "All tags are added."); BrowserUI.closeTab(this._currenttab); @@ -211,8 +210,8 @@ gTests.push({ }, onEditorDone: function() { - isnot(PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_01)), -1, testURL_01 + " is now bookmarked"); - is(PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_02)), -1, testURL_02 + " is no longer bookmarked"); + isnot(PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)), -1, testURL_01 + " is now bookmarked"); + is(PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)), -1, testURL_02 + " is no longer bookmarked"); BrowserUI.closeTab(this._currenttab); @@ -246,7 +245,7 @@ gTests.push({ var removebutton = document.getElementById("bookmark-popup-remove"); removebutton.click(); - var bookmark = PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_01)); + var bookmark = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_01)); ok(bookmark == -1, testURL_01 + " should no longer in bookmark"); BrowserUI.closeTab(this._currenttab); @@ -254,22 +253,3 @@ gTests.push({ runNextTest(); } }); - -//------------------------------------------------------------------------------ -// Helpers -function uri(spec) { - return ioService.newURI(spec, null, null); -} - -function waitFor(callback, test, timeout) { - if (test()) { - callback(); - return; - } - - timeout = timeout || Date.now(); - if (Date.now() - timeout > 1000) - throw "waitFor timeout"; - setTimeout(waitFor, 50, callback, test, timeout); -} - diff --git a/mobile/chrome/tests/browser_bookmarks_tags.js b/mobile/chrome/tests/browser_bookmarks_tags.js index 9b238e962cb5..22a8824b944c 100644 --- a/mobile/chrome/tests/browser_bookmarks_tags.js +++ b/mobile/chrome/tests/browser_bookmarks_tags.js @@ -4,7 +4,6 @@ * component, specifically for bookmark management. */ -var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); var testURL_01 = "chrome://mochikit/content/browser/mobile/chrome/browser_blank_01.html"; var testURL_02 = "chrome://mochikit/content/browser/mobile/chrome/browser_blank_02.html"; @@ -63,7 +62,7 @@ gTests.push({ var starbutton = document.getElementById("tool-star"); starbutton.click(); - var bookmarkItem = PlacesUtils.getMostRecentBookmarkForURI(uri(testURL_02)); + var bookmarkItem = PlacesUtils.getMostRecentBookmarkForURI(makeURI(testURL_02)); ok(bookmarkItem != -1, testURL_02 + " should be added."); BookmarkList.show(); @@ -83,7 +82,7 @@ gTests.push({ var donebutton = document.getAnonymousElementByAttribute(bookmarkitem, "anonid", "done-button"); donebutton.click(); - var tagsarray = PlacesUtils.tagging.getTagsForURI(uri(testURL_02), {}); + var tagsarray = PlacesUtils.tagging.getTagsForURI(makeURI(testURL_02), {}); is(tagsarray.length, 4, "All tags are associated with specified bookmark"); BookmarkList.close(); @@ -123,7 +122,7 @@ gTests.push({ is(untaggeduri, "", "Old tag is not associated with any bookmark"); taggeduri = PlacesUtils.tagging.getURIsForTag("edited-tag-three"); is(taggeduri[0].spec, testURL_02, "New tag is added to bookmark"); - var tagsarray = PlacesUtils.tagging.getTagsForURI(uri(testURL_02), {}); + var tagsarray = PlacesUtils.tagging.getTagsForURI(makeURI(testURL_02), {}); is(tagsarray.length, 4, "Bookmark still has same number of tags"); BookmarkList.close(); @@ -159,7 +158,7 @@ gTests.push({ var untaggeduri = PlacesUtils.tagging.getURIsForTag("edited-tag-three"); is(untaggeduri, "", "Old tag is not associated with any bookmark"); - var tagsarray = PlacesUtils.tagging.getTagsForURI(uri(testURL_02), {}); + var tagsarray = PlacesUtils.tagging.getTagsForURI(makeURI(testURL_02), {}); is(tagsarray.length, 3, "Tag is successfully deleted"); BookmarkList.close(); @@ -167,22 +166,3 @@ gTests.push({ runNextTest(); } }); - -//------------------------------------------------------------------------------ -// Helpers -function uri(spec) { - return ioService.newURI(spec, null, null); -} - -function waitFor(callback, test, timeout) { - if (test()) { - callback(); - return; - } - - timeout = timeout || Date.now(); - if (Date.now() - timeout > 1000) - throw "waitFor timeout"; - setTimeout(waitFor, 50, callback, test, timeout); -} - diff --git a/mobile/chrome/tests/browser_select.js b/mobile/chrome/tests/browser_select.js index db07a48a631e..1cc8aa1468aa 100644 --- a/mobile/chrome/tests/browser_select.js +++ b/mobile/chrome/tests/browser_select.js @@ -39,18 +39,3 @@ function onUIReady() { // We must finialize the tests finish(); } - -//------------------------------------------------------------------------------ -// Helpers -function waitFor(callback, test, timeout) { - if (test()) { - callback(); - return; - } - - timeout = timeout || Date.now(); - if (Date.now() - timeout > 1000) - throw "waitFor timeout"; - setTimeout(waitFor, 50, callback, test, timeout); -} - diff --git a/mobile/chrome/tests/head.js b/mobile/chrome/tests/head.js new file mode 100644 index 000000000000..76ff478a7ec3 --- /dev/null +++ b/mobile/chrome/tests/head.js @@ -0,0 +1,25 @@ +/*============================================================================= + Common Helpers functions +=============================================================================*/ +function waitFor(callback, test, timeout) { + if (test()) { + callback(); + return; + } + + timeout = timeout || Date.now(); + if (Date.now() - timeout > 1000) + throw "waitFor timeout"; + setTimeout(waitFor, 50, callback, test, timeout); +}; + +function makeURI(spec) { + return gIOService.newURI(spec, null, null); +}; + +EventUtils.synthesizeMouseForContent = function synthesizeMouseForContent(aElement, aOffsetX, aOffsetY, aEvent, aWindow) { + let container = document.getElementById("tile-container"); + let rect = container.getBoundingClientRect(); + + EventUtils.synthesizeMouse(aElement, rect.left + aOffsetX, rect.top + aOffsetY, aEvent, aWindow); +};