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);
+};