Bug 564012 - Form helper can't navigate in nested frames [r=mfinkle]
authorVivien Nicolas <21@vingtetun.org>
Fri, 04 Jun 2010 10:58:33 +0200
changeset 66255 afcf364f27a4365af5df4cc7a78014fb8da02151
parent 66254 379721949c5c1054eab782f7198bea1757ce0ce2
child 66256 eebcb76a1babaf676aacc2b790cbcf4601d1e743
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs564012
Bug 564012 - Form helper can't navigate in nested frames [r=mfinkle]
mobile/chrome/content/browser-ui.js
mobile/chrome/tests/browser_FormAssistant.js
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -1531,24 +1531,35 @@ var FormHelper = {
 
     let isVisible = (style.getPropertyValue("visibility") != "hidden");
     let isOpaque = (style.getPropertyValue("opacity") != 0);
 
     let rect = aElement.getBoundingClientRect();
     return isVisible && isOpaque && (rect.height != 0 || rect.width != 0);
   },
 
+  _getAllDocuments: function formHelper_getAllDocuments(aDocument, aResult) {
+    /** Recursively find all documents, including root document. */
+    aResult.push(aDocument);
+    let frames = aDocument.defaultView.frames;
+    if (!frames)
+      return aResult;
+
+    for (let i = 0; i < frames.length; i++)
+      this._getAllDocuments(frames[i].document, aResult);
+
+    return aResult;
+  },
+
   _getAll: function() {
     let elements = [];
 
-    // get all the documents
-    let documents = [getBrowser().contentDocument];
-    let iframes = getBrowser().contentDocument.querySelectorAll("iframe, frame");
-    for (let i = 0; i < iframes.length; i++)
-      documents.push(iframes[i].contentDocument);
+    // Retrieve all the nested iframes
+    let documents = [];
+    this._getAllDocuments(getBrowser().contentDocument, documents);
 
     for (let i = 0; i < documents.length; i++) {
       let nodes = documents[i].querySelectorAll("input, button, select, textarea, [role=button]");
       nodes = this._filterRadioButtons(nodes).filter(this._isValidElement, this);
       elements = elements.concat(nodes);
     }
 
     function orderByTabIndex(a, b) {
@@ -1873,17 +1884,17 @@ var FormHelper = {
       let bv = Browser._browserView;
       let scroll = BrowserView.Util.getContentScrollOffset(Browser.selectedBrowser);
       let caret = new Rect(scroll.x + rect.left, scroll.y + rect.top, rect.width, rect.height);
       return caret;
     }
     
     return null;
   },
-  
+
   _getOffsetForCaret: function formHelper_getOffsetForCaret(aCaretRect, aRect) {
     // Determine if we need to move left or right to bring the caret into view
     let deltaX = 0;
     if (aCaretRect.right > aRect.right)
       deltaX = aCaretRect.right - aRect.right;
     if (aCaretRect.left < aRect.left)
       deltaX = aCaretRect.left - aRect.left;
       
--- a/mobile/chrome/tests/browser_FormAssistant.js
+++ b/mobile/chrome/tests/browser_FormAssistant.js
@@ -1,9 +1,10 @@
-let testURL = "chrome://mochikit/content/browser/mobile/chrome/browser_FormAssistant.html";
+let testURL = "chrome://mochikit/content/browser/browser_FormAssistant.html";
+testURL = testURL.replace("chrome://mochikit/content/browser/", "file:///home/steakdepapillon/Devel/fennec/mobilebase/mobile/_tests/testing/mochitest/browser/mobile/chrome/");
 let newTab = null;
 let container = null;
 
 function test() {
   // This test is async
   waitForExplicitFinish();
 
   // Add new tab to hold the <FormAssistant> page
@@ -104,15 +105,46 @@ function testTabIndexNavigation() {
   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();
+  navigateIntoNestedFrames();
 };
 
+function navigateIntoNestedFrames() {
+  let doc = newTab.browser.contentDocument;
+
+  let iframe = doc.createElement("iframe");
+  iframe.setAttribute("src", "data:text/html;charset=utf-8,%3Ciframe%20src%3D%22data%3Atext/html%3Bcharset%3Dutf-8%2C%253Cinput%253E%253Cbr%253E%253Cinput%253E%250A%22%3E%3C/iframe%3E");
+  iframe.setAttribute("width", "300");
+  iframe.setAttribute("height", "100");
+
+  iframe.addEventListener("load", function() {
+    iframe.removeEventListener("load", arguments.callee, false);
+
+    let elements = iframe.contentDocument
+                         .querySelector("iframe").contentDocument
+                         .getElementsByTagName("input");
+
+    FormHelper.open(elements[0]);
+    ok(FormHelper._getPrevious(), "It should be possible to access to the previous field");
+    ok(FormHelper._getNext(), "It should be possible to access to the next field");
+    FormHelper.goToNext();
+    ok(!FormHelper._getNext(), "It should not be possible to access to the next field");
+
+    doc.body.removeChild(iframe);
+
+    // Close the form assistant
+    FormHelper.close();
+
+    // Close our tab when finished
+    Browser.closeTab(newTab);
+
+    // We must finialize the tests
+    finish();
+  }, false);
+  doc.body.appendChild(iframe);
+};
+