merge to tip
authorDoug Turner <dougt@meer.net>
Thu, 30 Oct 2008 14:43:10 -0700
changeset 21123 316376732261849097266d9716ce80209ad888f5
parent 21122 56e84df2b796149eebc23b7101db43d916b8ffc1 (current diff)
parent 21121 9d236c675d0bff1202b79db0edbecd6652adac75 (diff)
child 21124 2a5a08ab330498246befc0288b8e894ab2f2d38d
push id3332
push userdougt@mozilla.com
push dateThu, 30 Oct 2008 21:43:36 +0000
treeherdermozilla-central@316376732261 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.1b2pre
merge to tip
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -1680,46 +1680,44 @@ PRInt32 nsHyperTextAccessible::GetCaretL
   PRInt32 caretOffset, returnOffsetUnused;
   domSel->GetFocusOffset(&caretOffset);
   nsFrameSelection::HINT hint = frameSelection->GetHint();
   nsIFrame *caretFrame = frameSelection->GetFrameForNodeOffset(caretContent, caretOffset,
                                                                hint, &returnOffsetUnused);
   NS_ENSURE_TRUE(caretFrame, -1);
 
   PRInt32 lineNumber = 1;
-  nsCOMPtr<nsILineIterator> lineIterForCaret;
+  nsAutoLineIterator lineIterForCaret;
   nsCOMPtr<nsIContent> hyperTextContent = do_QueryInterface(mDOMNode);
   while (caretFrame) {
     if (hyperTextContent == caretFrame->GetContent()) {
       return lineNumber; // Must be in a single line hyper text, there is no line iterator
     }
     nsIFrame *parentFrame = caretFrame->GetParent();
     if (!parentFrame)
       break;
 
     // Add lines for the sibling frames before the caret
     nsIFrame *sibling = parentFrame->GetFirstChild(nsnull);
     while (sibling && sibling != caretFrame) {
-      nsCOMPtr<nsILineIterator> lineIterForSibling = do_QueryInterface(sibling);
+      nsAutoLineIterator lineIterForSibling = sibling->GetLineIterator();
       if (lineIterForSibling) {
-        PRInt32 addLines;
         // For the frames before that grab all the lines
-        lineIterForSibling->GetNumLines(&addLines);
+        PRInt32 addLines = lineIterForSibling->GetNumLines();
         lineNumber += addLines;
       }
       sibling = sibling->GetNextSibling();
     }
 
     // Get the line number relative to the container with lines
     if (!lineIterForCaret) {   // Add the caret line just once
-      lineIterForCaret = do_QueryInterface(parentFrame);
+      lineIterForCaret = parentFrame->GetLineIterator();
       if (lineIterForCaret) {
         // Ancestor of caret
-        PRInt32 addLines;
-        lineIterForCaret->FindLineContaining(caretFrame, &addLines);
+        PRInt32 addLines = lineIterForCaret->FindLineContaining(caretFrame);
         lineNumber += addLines;
       }
     }
 
     caretFrame = parentFrame;
   }
 
   NS_NOTREACHED("DOM ancestry had this hypertext but frame ancestry didn't");
--- a/browser/base/content/browser-context.inc
+++ b/browser/base/content/browser-context.inc
@@ -103,16 +103,21 @@
                 label="&reloadImageCmd.label;"
                 accesskey="&reloadImageCmd.accesskey;"
                 oncommand="gContextMenu.reloadImage();"/>
       <menuitem id="context-viewimage"
                 label="&viewImageCmd.label;"
                 accesskey="&viewImageCmd.accesskey;"
                 oncommand="gContextMenu.viewMedia(event);"
                 onclick="checkForMiddleClick(this, event);"/>
+      <menuitem id="context-viewvideo"
+                label="&viewVideoCmd.label;"
+                accesskey="&viewVideoCmd.accesskey;"
+                oncommand="gContextMenu.viewMedia(event);"
+                onclick="checkForMiddleClick(this, event);"/>
 #ifdef CONTEXT_COPY_IMAGE_CONTENTS
       <menuitem id="context-copyimage-contents"
                 label="&copyImageContentsCmd.label;"
                 accesskey="&copyImageContentsCmd.accesskey;"
                 oncommand="goDoCommand('cmd_copyImageContents');"/>
 #endif
       <menuitem id="context-copyimage"
                 label="&copyImageCmd.label;"
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -223,16 +223,18 @@ nsContextMenu.prototype = {
     // Reload image depends on an image that's not fully loaded
     this.showItem("context-reloadimage", (this.onImage && !this.onCompletedImage));
 
     // View image depends on having an image that's not standalone
     // (or is in a frame), or a canvas.
     this.showItem("context-viewimage", (this.onImage &&
                   (!this.onStandaloneImage || this.inFrame)) || this.onCanvas);
 
+    this.showItem("context-viewvideo", this.onVideo);
+
     // View background image depends on whether there is one.
     this.showItem("context-viewbgimage", shouldShow);
     this.showItem("context-sep-viewbgimage", shouldShow);
     document.getElementById("context-viewbgimage")
             .disabled = !this.hasBGImage;
   },
 
   initMiscItems: function CM_initMiscItems() {
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -67,16 +67,21 @@ include $(topsrcdir)/config/rules.mk
                  browser_getshortcutoruri.js \
                  browser_page_style_menu.js \
                  page_style_sample.html \
                  browser_ctrlTab.js \
                  browser_selectTabAtIndex.js \
                  browser_gestureSupport.js \
                  browser_feed_tab.js \
                  feed_tab.html \
+                 browser_pluginnotification.js \
+                 plugin_unknown.html \
+                 plugin_test.html \
+                 plugin_both.html \
+                 plugin_both2.html \
     $(NULL)
 
 ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
 _BROWSER_FILES += browser_customize.js \
     $(NULL)
 endif
 
 libs:: $(_TEST_FILES)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_pluginnotification.js
@@ -0,0 +1,196 @@
+const gTestRoot = "chrome://mochikit/content/browser/browser/base/content/test/";
+
+var gTestBrowser = null;
+var gNextTest = null;
+
+function get_test_plugin() {
+  var ph = Components.classes["@mozilla.org/plugin/host;1"]
+                     .getService(Components.interfaces.nsIPluginHost);
+  var tags = ph.getPluginTags({});
+  
+  // Find the test plugin
+  for (var i = 0; i < tags.length; i++) {
+    if (tags[i].name == "Test Plug-in")
+      return tags[i];
+  }
+}
+
+// This listens for the next opened window and checks it is of the right url.
+// opencallback is called when the new window is fully loaded
+// closecallback is called when the window is closed
+function WindowOpenListener(url, opencallback, closecallback) {
+  this.url = url;
+  this.opencallback = opencallback;
+  this.closecallback = closecallback;
+
+  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+                     .getService(Components.interfaces.nsIWindowMediator);
+  wm.addListener(this);
+}
+
+WindowOpenListener.prototype = {
+  url: null,
+  opencallback: null,
+  closecallback: null,
+  window: null,
+  domwindow: null,
+
+  handleEvent: function(event) {
+    is(this.domwindow.document.location.href, this.url, "Should have opened the correct window");
+
+    this.domwindow.removeEventListener("load", this, false);
+    // Allow any other load handlers to execute
+    var self = this;
+    executeSoon(function() { self.opencallback(self.domwindow); } );
+  },
+
+  onWindowTitleChange: function(window, title) {
+  },
+
+  onOpenWindow: function(window) {
+    if (this.window)
+      return;
+
+    this.window = window;
+    this.domwindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                           .getInterface(Components.interfaces.nsIDOMWindowInternal);
+    this.domwindow.addEventListener("load", this, false);
+  },
+
+  onCloseWindow: function(window) {
+    if (this.window != window)
+      return;
+
+    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+                       .getService(Components.interfaces.nsIWindowMediator);
+    wm.removeListener(this);
+    this.opencallback = null;
+    this.window = null;
+    this.domwindow = null;
+
+    // Let the window close complete
+    executeSoon(this.closecallback);
+    this.closecallback = null;
+  }
+};
+
+function test() {
+  waitForExplicitFinish();
+
+  var newTab = gBrowser.addTab();
+  gBrowser.selectedTab = newTab;
+  gTestBrowser = gBrowser.selectedBrowser;
+  gTestBrowser.addEventListener("load", pageLoad, true);
+  prepareTest(test1, gTestRoot + "plugin_unknown.html");
+}
+
+function finishTest() {
+  gTestBrowser.removeEventListener("load", pageLoad, true);
+  gBrowser.removeCurrentTab();
+  window.focus();
+  finish();
+}
+
+function pageLoad() {
+  // The plugin events are async dispatched and can come after the load event
+  // This just allows the events to fire before we then go on to test the states
+  executeSoon(gNextTest);
+}
+
+function prepareTest(nextTest, url) {
+  gNextTest = nextTest;
+  gTestBrowser.contentWindow.location = url;
+}
+
+// Tests a page with an unknown plugin in it.
+function test1() {
+  var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+  ok(notificationBox.getNotificationWithValue("missing-plugins"), "Test 1, Should have displayed the missing plugin notification");
+  ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 1, Should not have displayed the blocked plugin notification");
+  ok(gTestBrowser.missingPlugins, "Test 1, Should be a missing plugin list");
+  ok("application/x-unknown" in gTestBrowser.missingPlugins, "Test 1, Should know about application/x-unknown");
+  ok(!("application/x-test" in gTestBrowser.missingPlugins), "Test 1, Should not know about application/x-test");
+
+  var plugin = get_test_plugin();
+  ok(plugin, "Should have a test plugin");
+  plugin.disabled = false;
+  plugin.blocklisted = false;
+  prepareTest(test2, gTestRoot + "plugin_test.html");
+}
+
+// Tests a page with a working plugin in it.
+function test2() {
+  var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+  ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 2, Should not have displayed the missing plugin notification");
+  ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 2, Should not have displayed the blocked plugin notification");
+  ok(!gTestBrowser.missingPlugins, "Test 2, Should not be a missing plugin list");
+
+  var plugin = get_test_plugin();
+  ok(plugin, "Should have a test plugin");
+  plugin.disabled = true;
+  prepareTest(test3, gTestRoot + "plugin_test.html");
+}
+
+// Tests a page with a disabled plugin in it.
+function test3() {
+  var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+  ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 3, Should not have displayed the missing plugin notification");
+  ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 3, Should not have displayed the blocked plugin notification");
+  ok(!gTestBrowser.missingPlugins, "Test 3, Should not be a missing plugin list");
+
+  new WindowOpenListener("chrome://mozapps/content/extensions/extensions.xul", test4, prepareTest5);
+
+  EventUtils.synthesizeMouse(gTestBrowser.contentDocument.getElementById("test"),
+                             0, 0, {}, gTestBrowser.contentWindow);
+}
+
+function test4(win) {
+  is(win.gView, "plugins", "Should have displayed the plugins pane");
+  win.close();
+}
+
+function prepareTest5() {
+  var plugin = get_test_plugin();
+  plugin.disabled = false;
+  plugin.blocklisted = true;
+  prepareTest(test5, gTestRoot + "plugin_test.html");
+}
+
+// Tests a page with a blocked plugin in it.
+function test5() {
+  var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+  ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 5, Should not have displayed the missing plugin notification");
+  ok(notificationBox.getNotificationWithValue("blocked-plugins"), "Test 5, Should have displayed the blocked plugin notification");
+  ok(gTestBrowser.missingPlugins, "Test 5, Should be a missing plugin list");
+  ok("application/x-test" in gTestBrowser.missingPlugins, "Test 5, Should know about application/x-test");
+  ok(!("application/x-unknown" in gTestBrowser.missingPlugins), "Test 5, Should not know about application/x-unknown");
+
+  prepareTest(test6, gTestRoot + "plugin_both.html");
+}
+
+// Tests a page with a blocked and unknown plugin in it.
+function test6() {
+  var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+  ok(notificationBox.getNotificationWithValue("missing-plugins"), "Test 6, Should have displayed the missing plugin notification");
+  ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 6, Should not have displayed the blocked plugin notification");
+  ok(gTestBrowser.missingPlugins, "Test 6, Should be a missing plugin list");
+  ok("application/x-unknown" in gTestBrowser.missingPlugins, "Test 6, Should know about application/x-unknown");
+  ok("application/x-test" in gTestBrowser.missingPlugins, "Test 6, Should know about application/x-test");
+
+  prepareTest(test7, gTestRoot + "plugin_both2.html");
+}
+
+// Tests a page with a blocked and unknown plugin in it (alternate order to above).
+function test7() {
+  var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+  ok(notificationBox.getNotificationWithValue("missing-plugins"), "Test 7, Should have displayed the missing plugin notification");
+  ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 7, Should not have displayed the blocked plugin notification");
+  ok(gTestBrowser.missingPlugins, "Test 7, Should be a missing plugin list");
+  ok("application/x-unknown" in gTestBrowser.missingPlugins, "Test 7, Should know about application/x-unknown");
+  ok("application/x-test" in gTestBrowser.missingPlugins, "Test 7, Should know about application/x-test");
+
+  var plugin = get_test_plugin();
+  plugin.disabled = false;
+  plugin.blocklisted = false;
+  finishTest();
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugin_both.html
@@ -0,0 +1,6 @@
+<html>
+<body>
+<embed id="unknown" style="width: 100px; height: 100px" type="application/x-unknown">
+<embed id="test" style="width: 100px; height: 100px" type="application/x-test">
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugin_both2.html
@@ -0,0 +1,6 @@
+<html>
+<body>
+<embed id="test" style="width: 100px; height: 100px" type="application/x-test">
+<embed id="unknown" style="width: 100px; height: 100px" type="application/x-unknown">
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugin_test.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<embed id="test" style="width: 100px; height: 100px" type="application/x-test">
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugin_unknown.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+<embed id="unknown" style="width: 100px; height: 100px" type="application/x-unknown">
+</body>
+</html>
--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -235,16 +235,17 @@ function runTest(testNum) {
         break;
 
     case 8:
         // Context menu for a video
         checkContextMenu(["context-media-play",
                           "context-media-mute",
                           "context-media-showcontrols",
                           "---",
+                          "context-viewvideo",
                           "context-copyvideourl",
                           "---",
                           "context-savevideo",
                           "context-sendvideo"]);
         closeContextMenu();
         openContextMenuFor(iframe); // Invoke context menu for next test.
         break;
 
--- a/browser/components/places/src/nsPlacesImportExportService.cpp
+++ b/browser/components/places/src/nsPlacesImportExportService.cpp
@@ -339,33 +339,32 @@ public:
   nsresult Init(PRBool aAllowRootChanges,
                 nsINavBookmarksService* bookmarkService,
                 PRInt64 aFolder,
                 PRBool aIsImportDefaults);
 
   NS_DECL_ISUPPORTS
 
   // nsIContentSink (superclass of nsIHTMLContentSink)
-  NS_IMETHOD WillTokenize() { return NS_OK; }
+  NS_IMETHOD WillParse() { return NS_OK; }
   NS_IMETHOD WillBuildModel() { return NS_OK; }
   NS_IMETHOD DidBuildModel() { return NS_OK; }
   NS_IMETHOD WillInterrupt() { return NS_OK; }
   NS_IMETHOD WillResume() { return NS_OK; }
   NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
   virtual void FlushPendingNotifications(mozFlushType aType) { }
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
   virtual nsISupports *GetTarget() { return nsnull; }
 
   // nsIHTMLContentSink
   NS_IMETHOD OpenHead() { return NS_OK; }
   NS_IMETHOD BeginContext(PRInt32 aPosition) { return NS_OK; }
   NS_IMETHOD EndContext(PRInt32 aPosition) { return NS_OK; }
   NS_IMETHOD IsEnabled(PRInt32 aTag, PRBool* aReturn)
     { *aReturn = PR_TRUE; return NS_OK; }
-  NS_IMETHOD WillProcessTokens() { return NS_OK; }
   NS_IMETHOD DidProcessTokens() { return NS_OK; }
   NS_IMETHOD WillProcessAToken() { return NS_OK; }
   NS_IMETHOD DidProcessAToken() { return NS_OK; }
   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
   NS_IMETHOD AddComment(const nsIParserNode& aNode) { return NS_OK; }
   NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode) { return NS_OK; }
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -232,16 +232,18 @@
 <!ENTITY viewPageInfoCmd.label        "View Page Info">
 <!ENTITY viewPageInfoCmd.accesskey    "I">
 <!ENTITY viewFrameInfoCmd.label       "View Frame Info">
 <!ENTITY viewFrameInfoCmd.accesskey   "I">
 <!ENTITY reloadImageCmd.label         "Reload Image">
 <!ENTITY reloadImageCmd.accesskey     "R">
 <!ENTITY viewImageCmd.label           "View Image">
 <!ENTITY viewImageCmd.accesskey       "I">
+<!ENTITY viewVideoCmd.label           "View Video">
+<!ENTITY viewVideoCmd.accesskey       "I">
 <!ENTITY viewBGImageCmd.label         "View Background Image">
 <!ENTITY viewBGImageCmd.accesskey     "w">
 <!ENTITY setDesktopBackgroundCmd.label      "Set As Desktop Background…">
 <!ENTITY setDesktopBackgroundCmd.accesskey  "S">
 <!ENTITY bookmarkPageCmd2.label       "Bookmark This Page">
 <!ENTITY bookmarkPageCmd2.accesskey   "m">
 <!ENTITY bookmarkThisLinkCmd.label      "Bookmark This Link">
 <!ENTITY bookmarkThisLinkCmd.accesskey  "L">
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -695,29 +695,29 @@ ifneq (,$(DIRS)$(TOOL_DIRS)$(PARALLEL_DI
 	+$(LOOP_OVER_PARALLEL_DIRS)
 	+$(LOOP_OVER_DIRS)
 	+$(LOOP_OVER_TOOL_DIRS)
 endif
 
 ifdef PARALLEL_DIRS
 export:: $(PARALLEL_SUBMAKEFILES) | $(PARALLEL_DIRS_export)
 
-$(PARALLEL_DIRS_export):: %_export:
-	+$(MAKE) -C $* export
+$(PARALLEL_DIRS_export):: %_export: %
+	+$(MAKE) -C $< export
 endif
 
 export:: $(SUBMAKEFILES) $(MAKE_DIRS) $(if $(EXPORTS)$(XPIDLSRCS)$(SDK_HEADERS)$(SDK_XPIDLSRCS),$(PUBLIC)) $(if $(SDK_HEADERS)$(SDK_XPIDLSRCS),$(SDK_PUBLIC)) $(if $(XPIDLSRCS),$(IDL_DIR)) $(if $(SDK_XPIDLSRCS),$(SDK_IDL_DIR))
 	+$(LOOP_OVER_DIRS)
 	+$(LOOP_OVER_TOOL_DIRS)
 
 ifdef PARALLEL_DIRS
 tools:: $(PARALLEL_SUBMAKEFILES) | $(PARALLEL_DIRS_tools)
 
-$(PARALLEL_DIRS_tools):: %_tools:
-	+$(MAKE) -C $* tools
+$(PARALLEL_DIRS_tools):: %_tools: %
+	+$(MAKE) -C $< tools
 endif
 
 tools:: $(SUBMAKEFILES) $(MAKE_DIRS)
 	+$(LOOP_OVER_DIRS)
 ifdef TOOL_DIRS
 	@$(EXIT_ON_ERROR) \
 	$(foreach dir,$(TOOL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) libs; ) true
 endif
@@ -745,18 +745,18 @@ endif # LIBRARY_NAME
 LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
 HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
 DSO_LDOPTS_DEPS = $(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS))
 
 ##############################################
 ifdef PARALLEL_DIRS
 libs:: $(PARALLEL_SUBMAKEFILES) | $(PARALLEL_DIRS_libs)
 
-$(PARALLEL_DIRS_libs):: %_libs:
-	+$(MAKE) -C $* libs
+$(PARALLEL_DIRS_libs):: %_libs: %
+	+$(MAKE) -C $< libs
 endif
 
 libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
 ifndef NO_DIST_INSTALL
 ifdef LIBRARY
 ifdef EXPORT_LIBRARY # Stage libs that will be linked into a static build
 ifdef IS_COMPONENT
 	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DEPTH)/staticlib/components
--- a/configure.in
+++ b/configure.in
@@ -8241,17 +8241,19 @@ LDFLAGS="$_SUBDIR_LDFLAGS"
 HOST_CC="$_SUBDIR_HOST_CC" 
 HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
 HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
 RC=
 
 unset MAKEFILES
 unset CONFIG_FILES
 
-if test "$COMPILE_ENVIRONMENT"; then
+# No need to run subconfigures when building with LIBXUL_SDK_DIR
+if test "$COMPILE_ENVIRONMENT" -a -z "$LIBXUL_SDK_DIR"; then
+
 if test -z "$MOZ_NATIVE_NSPR"; then
     ac_configure_args="$_SUBDIR_CONFIG_ARGS --with-dist-prefix=$MOZ_BUILD_ROOT/dist --with-mozilla"
     if test -z "$MOZ_DEBUG"; then
         ac_configure_args="$ac_configure_args --disable-debug"
     fi
     if test "$MOZ_OPTIMIZE" = "1"; then
         ac_configure_args="$ac_configure_args --enable-optimize"
     fi
@@ -8291,10 +8293,9 @@ ac_configure_args="$ac_configure_args --
 ac_configure_args="$ac_configure_args --libdir=$dist/lib"
 ac_configure_args="$ac_configure_args --with-sync-build-files=$srcdir"
 if test "$MOZ_MEMORY"; then
    ac_configure_args="$ac_configure_args --enable-jemalloc"  
 fi
 AC_OUTPUT_SUBDIRS(js/src)
 ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 
-fi # COMPILE_ENVIRONMENT
-
+fi # COMPILE_ENVIRONMENT && !LIBXUL_SDK_DIR
--- a/content/base/src/mozSanitizingSerializer.h
+++ b/content/base/src/mozSanitizingSerializer.h
@@ -94,17 +94,17 @@ public:
                                 nsAString& aStr); 
   NS_IMETHOD AppendElementEnd(nsIDOMElement *aElement, nsAString& aStr);
   NS_IMETHOD Flush(nsAString& aStr);
 
   NS_IMETHOD AppendDocumentStart(nsIDOMDocument *aDocument,
                                  nsAString& aStr);
 
   // nsIContentSink
-  NS_IMETHOD WillTokenize(void) { return NS_OK; }
+  NS_IMETHOD WillParse(void) { return NS_OK; }
   NS_IMETHOD WillBuildModel(void) { return NS_OK; }
   NS_IMETHOD DidBuildModel(void) { return NS_OK; }
   NS_IMETHOD WillInterrupt(void) { return NS_OK; }
   NS_IMETHOD WillResume(void) { return NS_OK; }
   NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
@@ -118,17 +118,16 @@ public:
 
   // nsIHTMLContentSink
   NS_IMETHOD OpenHead();
   NS_IMETHOD IsEnabled(PRInt32 aTag, PRBool* aReturn);
   NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; }
   NS_IMETHOD_(PRBool) IsFormOnStack() { return PR_FALSE; }
   NS_IMETHOD BeginContext(PRInt32 aPosition) { return NS_OK; }
   NS_IMETHOD EndContext(PRInt32 aPosition) { return NS_OK; }
-  NS_IMETHOD WillProcessTokens(void) { return NS_OK; }
   NS_IMETHOD DidProcessTokens(void) { return NS_OK; }
   NS_IMETHOD WillProcessAToken(void) { return NS_OK; }
   NS_IMETHOD DidProcessAToken(void) { return NS_OK; }
 
   // nsISanitizingHTMLSerializer
   NS_IMETHOD Initialize(nsAString* aOutString,
                         PRUint32 aFlags, const nsAString& allowedTags);
 
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -1709,17 +1709,17 @@ nsContentSink::DropParserAndPerfHint(voi
   }
 
   if (mCanInterruptParser) {
     mDocument->UnblockOnload(PR_TRUE);
   }
 }
 
 nsresult
-nsContentSink::WillProcessTokensImpl(void)
+nsContentSink::WillParseImpl(void)
 {
   if (mCanInterruptParser) {
     mDelayTimerStart = PR_IntervalToMicroseconds(PR_IntervalNow());
   }
 
   return NS_OK;
 }
 
--- a/content/base/src/nsContentSink.h
+++ b/content/base/src/nsContentSink.h
@@ -126,23 +126,23 @@ class nsContentSink : public nsICSSLoade
 
   // nsICSSLoaderObserver
   NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aWasAlternate,
                               nsresult aStatus);
 
   virtual nsresult ProcessMETATag(nsIContent* aContent);
 
   // nsIContentSink implementation helpers
+  NS_HIDDEN_(nsresult) WillParseImpl(void);
   NS_HIDDEN_(nsresult) WillInterruptImpl(void);
   NS_HIDDEN_(nsresult) WillResumeImpl(void);
   NS_HIDDEN_(nsresult) DidProcessATokenImpl(void);
   NS_HIDDEN_(void) WillBuildModelImpl(void);
   NS_HIDDEN_(void) DidBuildModelImpl(void);
   NS_HIDDEN_(void) DropParserAndPerfHint(void);
-  NS_HIDDEN_(nsresult) WillProcessTokensImpl(void);
 
   void NotifyAppend(nsIContent* aContent, PRUint32 aStartIndex);
 
   // nsIDocumentObserver
   virtual void BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType);
   virtual void EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType);
 
   virtual void UpdateChildCounts() = 0;
--- a/content/base/src/nsPlainTextSerializer.h
+++ b/content/base/src/nsPlainTextSerializer.h
@@ -91,17 +91,17 @@ public:
   NS_IMETHOD AppendElementEnd(nsIDOMElement *aElement,
                               nsAString& aStr);
   NS_IMETHOD Flush(nsAString& aStr);
 
   NS_IMETHOD AppendDocumentStart(nsIDOMDocument *aDocument,
                                  nsAString& aStr);
 
   // nsIContentSink
-  NS_IMETHOD WillTokenize(void) { return NS_OK; }
+  NS_IMETHOD WillParse(void) { return NS_OK; }
   NS_IMETHOD WillBuildModel(void) { return NS_OK; }
   NS_IMETHOD DidBuildModel(void) { return NS_OK; }
   NS_IMETHOD WillInterrupt(void) { return NS_OK; }
   NS_IMETHOD WillResume(void) { return NS_OK; }
   NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -176,17 +176,17 @@ public:
 
   nsresult Init(nsIDocument* aDoc, nsIURI* aURI, nsISupports* aContainer,
                 nsIChannel* aChannel);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIContentSink
-  NS_IMETHOD WillTokenize(void);
+  NS_IMETHOD WillParse(void);
   NS_IMETHOD WillBuildModel(void);
   NS_IMETHOD DidBuildModel(void);
   NS_IMETHOD WillInterrupt(void);
   NS_IMETHOD WillResume(void);
   NS_IMETHOD SetParser(nsIParser* aParser);
   virtual void FlushPendingNotifications(mozFlushType aType);
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
   virtual nsISupports *GetTarget();
@@ -194,17 +194,16 @@ public:
   // nsIHTMLContentSink
   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
   NS_IMETHOD CloseMalformedContainer(const nsHTMLTag aTag);
   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
   NS_IMETHOD AddComment(const nsIParserNode& aNode);
   NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
   NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode);
-  NS_IMETHOD WillProcessTokens(void);
   NS_IMETHOD DidProcessTokens(void);
   NS_IMETHOD WillProcessAToken(void);
   NS_IMETHOD DidProcessAToken(void);
   NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode);
   NS_IMETHOD BeginContext(PRInt32 aID);
   NS_IMETHOD EndContext(PRInt32 aID);
   NS_IMETHOD OpenHead();
   NS_IMETHOD IsEnabled(PRInt32 aTag, PRBool* aReturn);
@@ -1740,16 +1739,22 @@ HTMLContentSink::Init(nsIDocument* aDoc,
 
   MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::Init()\n"));
   MOZ_TIMER_STOP(mWatch);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+HTMLContentSink::WillParse(void)
+{
+  return WillParseImpl();
+}
+
+NS_IMETHODIMP
 HTMLContentSink::WillBuildModel(void)
 {
   WillBuildModelImpl();
   if (mHTMLDocument) {
     NS_ASSERTION(mParser, "no parser");
     nsCompatibility mode = eCompatibility_NavQuirks;
     if (mParser) {
       nsDTDMode dtdMode = mParser->GetParseMode();
@@ -2692,28 +2697,16 @@ HTMLContentSink::AddDocTypeDecl(const ns
 
   MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::AddDocTypeDecl()\n"));
   MOZ_TIMER_STOP(mWatch);
 
   return rv;
 }
 
 NS_IMETHODIMP
-HTMLContentSink::WillTokenize(void)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-HTMLContentSink::WillProcessTokens(void)
-{
-  return WillProcessTokensImpl();
-}
-
-NS_IMETHODIMP
 HTMLContentSink::DidProcessTokens(void)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLContentSink::WillProcessAToken(void)
 {
@@ -2724,17 +2717,17 @@ NS_IMETHODIMP
 HTMLContentSink::DidProcessAToken(void)
 {
   return DidProcessATokenImpl();
 }
 
 NS_IMETHODIMP
 HTMLContentSink::WillInterrupt()
 {
-  return WillInterruptImpl();	
+  return WillInterruptImpl();
 }
 
 NS_IMETHODIMP
 HTMLContentSink::WillResume()
 {
   return WillResumeImpl();
 }
 
--- a/content/html/document/src/nsHTMLFragmentContentSink.cpp
+++ b/content/html/document/src/nsHTMLFragmentContentSink.cpp
@@ -82,17 +82,17 @@ public:
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHTMLFragmentContentSink,
                                            nsIContentSink)
 
   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
 
   // nsIContentSink
-  NS_IMETHOD WillTokenize(void) { return NS_OK; }
+  NS_IMETHOD WillParse(void) { return NS_OK; }
   NS_IMETHOD WillBuildModel(void);
   NS_IMETHOD DidBuildModel(void);
   NS_IMETHOD WillInterrupt(void);
   NS_IMETHOD WillResume(void);
   NS_IMETHOD SetParser(nsIParser* aParser);
   virtual void FlushPendingNotifications(mozFlushType aType) { }
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
   virtual nsISupports *GetTarget() { return mTargetDocument; }
@@ -101,17 +101,16 @@ public:
   NS_IMETHOD BeginContext(PRInt32 aID);
   NS_IMETHOD EndContext(PRInt32 aID);
   NS_IMETHOD OpenHead();
   NS_IMETHOD IsEnabled(PRInt32 aTag, PRBool* aReturn) {
     *aReturn = PR_TRUE;
     return NS_OK;
   }
   NS_IMETHOD_(PRBool) IsFormOnStack() { return PR_FALSE; }
-  NS_IMETHOD WillProcessTokens(void) { return NS_OK; }
   NS_IMETHOD DidProcessTokens(void) { return NS_OK; }
   NS_IMETHOD WillProcessAToken(void) { return NS_OK; }
   NS_IMETHOD DidProcessAToken(void) { return NS_OK; }
   NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; }
   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
   NS_IMETHOD AddComment(const nsIParserNode& aNode);
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -200,19 +200,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   for (PRUint32 i = 0, count = tmp->mContentStack.Length(); i < count; i++) {
     const StackNode& node = tmp->mContentStack.ElementAt(i);
     cb.NoteXPCOMChild(node.mContent);
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 // nsIContentSink
 NS_IMETHODIMP
-nsXMLContentSink::WillTokenize(void)
+nsXMLContentSink::WillParse(void)
 {
-  return WillProcessTokensImpl();
+  return WillParseImpl();
 }
 
 NS_IMETHODIMP
 nsXMLContentSink::WillBuildModel(void)
 {
   WillBuildModelImpl();
 
   // Notify document that the load is beginning
--- a/content/xml/document/src/nsXMLContentSink.h
+++ b/content/xml/document/src/nsXMLContentSink.h
@@ -85,17 +85,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXMLContentSink,
                                                      nsContentSink)
 
   NS_DECL_NSIEXPATSINK
 
   // nsIContentSink
-  NS_IMETHOD WillTokenize(void);
+  NS_IMETHOD WillParse(void);
   NS_IMETHOD WillBuildModel(void);
   NS_IMETHOD DidBuildModel(void);
   NS_IMETHOD WillInterrupt(void);
   NS_IMETHOD WillResume(void);
   NS_IMETHOD SetParser(nsIParser* aParser);  
   virtual void FlushPendingNotifications(mozFlushType aType);
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
   virtual nsISupports *GetTarget();
--- a/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
+++ b/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
@@ -103,17 +103,17 @@ public:
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIEXPATSINK
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSIREQUESTOBSERVER
     NS_DECL_NSIINTERFACEREQUESTOR
 
     // nsIContentSink
-    NS_IMETHOD WillTokenize(void) { return NS_OK; }
+    NS_IMETHOD WillParse(void) { return NS_OK; }
     NS_IMETHOD WillBuildModel(void) { return NS_OK; }
     NS_IMETHOD DidBuildModel();
     NS_IMETHOD WillInterrupt(void) { return NS_OK; }
     NS_IMETHOD WillResume(void) { return NS_OK; }
     NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
     virtual void FlushPendingNotifications(mozFlushType aType) { }
     NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
     virtual nsISupports *GetTarget() { return nsnull; }
--- a/content/xul/document/src/nsXULContentSink.h
+++ b/content/xul/document/src/nsXULContentSink.h
@@ -64,17 +64,17 @@ public:
     XULContentSinkImpl();
     virtual ~XULContentSinkImpl();
 
     // nsISupports
     NS_DECL_ISUPPORTS
     NS_DECL_NSIEXPATSINK
 
     // nsIContentSink
-    NS_IMETHOD WillTokenize(void) { return NS_OK; }
+    NS_IMETHOD WillParse(void) { return NS_OK; }
     NS_IMETHOD WillBuildModel(void);
     NS_IMETHOD DidBuildModel(void);
     NS_IMETHOD WillInterrupt(void);
     NS_IMETHOD WillResume(void);
     NS_IMETHOD SetParser(nsIParser* aParser);
     virtual void FlushPendingNotifications(mozFlushType aType) { }
     NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
     virtual nsISupports *GetTarget();
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -695,29 +695,29 @@ ifneq (,$(DIRS)$(TOOL_DIRS)$(PARALLEL_DI
 	+$(LOOP_OVER_PARALLEL_DIRS)
 	+$(LOOP_OVER_DIRS)
 	+$(LOOP_OVER_TOOL_DIRS)
 endif
 
 ifdef PARALLEL_DIRS
 export:: $(PARALLEL_SUBMAKEFILES) | $(PARALLEL_DIRS_export)
 
-$(PARALLEL_DIRS_export):: %_export:
-	+$(MAKE) -C $* export
+$(PARALLEL_DIRS_export):: %_export: %
+	+$(MAKE) -C $< export
 endif
 
 export:: $(SUBMAKEFILES) $(MAKE_DIRS) $(if $(EXPORTS)$(XPIDLSRCS)$(SDK_HEADERS)$(SDK_XPIDLSRCS),$(PUBLIC)) $(if $(SDK_HEADERS)$(SDK_XPIDLSRCS),$(SDK_PUBLIC)) $(if $(XPIDLSRCS),$(IDL_DIR)) $(if $(SDK_XPIDLSRCS),$(SDK_IDL_DIR))
 	+$(LOOP_OVER_DIRS)
 	+$(LOOP_OVER_TOOL_DIRS)
 
 ifdef PARALLEL_DIRS
 tools:: $(PARALLEL_SUBMAKEFILES) | $(PARALLEL_DIRS_tools)
 
-$(PARALLEL_DIRS_tools):: %_tools:
-	+$(MAKE) -C $* tools
+$(PARALLEL_DIRS_tools):: %_tools: %
+	+$(MAKE) -C $< tools
 endif
 
 tools:: $(SUBMAKEFILES) $(MAKE_DIRS)
 	+$(LOOP_OVER_DIRS)
 ifdef TOOL_DIRS
 	@$(EXIT_ON_ERROR) \
 	$(foreach dir,$(TOOL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) libs; ) true
 endif
@@ -745,18 +745,18 @@ endif # LIBRARY_NAME
 LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
 HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
 DSO_LDOPTS_DEPS = $(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS))
 
 ##############################################
 ifdef PARALLEL_DIRS
 libs:: $(PARALLEL_SUBMAKEFILES) | $(PARALLEL_DIRS_libs)
 
-$(PARALLEL_DIRS_libs):: %_libs:
-	+$(MAKE) -C $* libs
+$(PARALLEL_DIRS_libs):: %_libs: %
+	+$(MAKE) -C $< libs
 endif
 
 libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
 ifndef NO_DIST_INSTALL
 ifdef LIBRARY
 ifdef EXPORT_LIBRARY # Stage libs that will be linked into a static build
 ifdef IS_COMPONENT
 	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DEPTH)/staticlib/components
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -3796,21 +3796,19 @@ UnionRectForClosestScrolledView(nsIFrame
       prevFrame = f;
       f = prevFrame->GetParent();
     }
 
     if (f != aFrame &&
         f &&
         frameType == nsGkAtoms::blockFrame) {
       // find the line containing aFrame and increase the top of |offset|.
-      nsCOMPtr<nsILineIterator> lines(do_QueryInterface(f));
-
+      nsAutoLineIterator lines = f->GetLineIterator();
       if (lines) {
-        PRInt32 index = -1;
-        lines->FindLineContaining(prevFrame, &index);
+        PRInt32 index = lines->FindLineContaining(prevFrame);
         if (index >= 0) {
           nsIFrame *trash1;
           PRInt32 trash2;
           nsRect lineBounds;
           PRUint32 trash3;
 
           if (NS_SUCCEEDED(lines->GetLine(index, &trash1, &trash2,
                                           lineBounds, &trash3))) {
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -310,45 +310,41 @@ nsBlockFrame::Destroy()
     nsAutoOOFFrameList oofs(this);
     oofs.mList.DestroyFrames();
     // oofs is now empty and will remove the frame list property
   }
 
   nsBlockFrameSuper::Destroy();
 }
 
+/* virtual */ nsILineIterator*
+nsBlockFrame::GetLineIterator()
+{
+  nsLineIterator* it = new nsLineIterator;
+  if (!it)
+    return nsnull;
+
+  const nsStyleVisibility* visibility = GetStyleVisibility();
+  nsresult rv = it->Init(mLines, visibility->mDirection == NS_STYLE_DIRECTION_RTL);
+  if (NS_FAILED(rv)) {
+    delete it;
+    return nsnull;
+  }
+  return it;
+}
+
 NS_IMETHODIMP
 nsBlockFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
 {
   NS_PRECONDITION(aInstancePtr, "null out param");
 
   if (aIID.Equals(kBlockFrameCID)) {
     *aInstancePtr = static_cast<void*>(static_cast<nsBlockFrame*>(this));
     return NS_OK;
   }
-  if (aIID.Equals(NS_GET_IID(nsILineIterator)) ||
-      aIID.Equals(NS_GET_IID(nsILineIteratorNavigator))) {
-    nsLineIterator* it = new nsLineIterator;
-    if (!it) {
-      *aInstancePtr = nsnull;
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    NS_ADDREF(it); // reference passed to caller
-    const nsStyleVisibility* visibility = GetStyleVisibility();
-    nsresult rv = it->Init(mLines,
-                           visibility->mDirection == NS_STYLE_DIRECTION_RTL);
-    if (NS_FAILED(rv)) {
-      *aInstancePtr = nsnull;
-      NS_RELEASE(it);
-      return rv;
-    }
-    *aInstancePtr = static_cast<nsILineIteratorNavigator*>(it);
-    return NS_OK;
-  }
-
   return nsBlockFrameSuper::QueryInterface(aIID, aInstancePtr);
 }
 
 nsSplittableType
 nsBlockFrame::GetSplittableType() const
 {
   return NS_FRAME_SPLITTABLE_NON_RECTANGULAR;
 }
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -69,17 +69,16 @@ enum LineReflowStatus {
   LINE_REFLOW_TRUNCATED
 };
 
 class nsBlockReflowState;
 class nsBlockInFlowLineIterator;
 class nsBulletFrame;
 class nsLineBox;
 class nsFirstLineFrame;
-class nsILineIterator;
 class nsIntervalSet;
 /**
  * Child list name indices
  * @see #GetAdditionalChildListName()
  */
 #define NS_BLOCK_LIST_COUNT  (NS_CONTAINER_LIST_COUNT_INCL_OC + 4)
 
 /**
@@ -593,16 +592,18 @@ protected:
   static PRBool FrameStartsCounterScope(nsIFrame* aFrame);
 
   void ReflowBullet(nsBlockReflowState& aState,
                     nsHTMLReflowMetrics& aMetrics,
                     nscoord aLineTop);
 
   //----------------------------------------
 
+  virtual nsILineIterator* GetLineIterator();
+
 public:
   nsLineList* GetOverflowLines() const;
 protected:
   nsLineList* RemoveOverflowLines();
   nsresult SetOverflowLines(nsLineList* aOverflowLines);
 
   nsFrameList* GetOverflowPlaceholders() const;
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4539,24 +4539,21 @@ nsFrame::GetNextPrevLineFromeBlockFrame(
   //magic numbers aLineStart will be -1 for end of block 0 will be start of block
   if (!aBlockFrame || !aPos)
     return NS_ERROR_NULL_POINTER;
 
   aPos->mResultFrame = nsnull;
   aPos->mResultContent = nsnull;
   aPos->mAttachForward = (aPos->mDirection == eDirNext);
 
-   nsresult result;
-  nsCOMPtr<nsILineIteratorNavigator> it; 
-  result = aBlockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
-  if (NS_FAILED(result) || !it)
-    return result;
+  nsAutoLineIterator it = aBlockFrame->GetLineIterator();
+  if (!it)
+    return NS_ERROR_FAILURE;
   PRInt32 searchingLine = aLineStart;
-  PRInt32 countLines;
-  result = it->GetNumLines(&countLines);
+  PRInt32 countLines = it->GetNumLines();
   if (aOutSideLimit > 0) //start at end
     searchingLine = countLines;
   else if (aOutSideLimit <0)//start at beginning
     searchingLine = -1;//"next" will be 0  
   else 
     if ((aPos->mDirection == eDirPrevious && searchingLine == 0) || 
        (aPos->mDirection == eDirNext && searchingLine >= (countLines -1) )){
       //we need to jump to new block frame.
@@ -4566,16 +4563,18 @@ nsFrame::GetNextPrevLineFromeBlockFrame(
   nsIFrame *resultFrame = nsnull;
   nsIFrame *farStoppingFrame = nsnull; //we keep searching until we find a "this" frame then we go to next line
   nsIFrame *nearStoppingFrame = nsnull; //if we are backing up from edge, stop here
   nsIFrame *firstFrame;
   nsIFrame *lastFrame;
   nsRect  rect;
   PRBool isBeforeFirstFrame, isAfterLastFrame;
   PRBool found = PR_FALSE;
+
+  nsresult result = NS_OK;
   while (!found)
   {
     if (aPos->mDirection == eDirPrevious)
       searchingLine --;
     else
       searchingLine ++;
     if ((aPos->mDirection == eDirPrevious && searchingLine < 0) || 
        (aPos->mDirection == eDirNext && searchingLine >= countLines ))
@@ -4614,25 +4613,25 @@ nsFrame::GetNextPrevLineFromeBlockFrame(
       nscoord newDesiredX  = aPos->mDesiredX - offset.x;//get desired x into blockframe coordinates!
       result = it->FindFrameAt(searchingLine, newDesiredX, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
       if(NS_FAILED(result))
         continue;
     }
 
     if (NS_SUCCEEDED(result) && resultFrame)
     {
-      nsCOMPtr<nsILineIteratorNavigator> newIt; 
       //check to see if this is ANOTHER blockframe inside the other one if so then call into its lines
-      result = resultFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(newIt));
-      if (NS_SUCCEEDED(result) && newIt)
+      nsAutoLineIterator newIt = resultFrame->GetLineIterator();
+      if (newIt)
       {
         aPos->mResultFrame = resultFrame;
         return NS_OK;
       }
       //resultFrame is not a block frame
+      result = NS_ERROR_FAILURE;
 
       nsCOMPtr<nsIFrameEnumerator> frameTraversal;
       result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
                                     aPresContext, resultFrame,
                                     ePostOrder,
                                     PR_FALSE, // aVisual
                                     aPos->mScrollViewStop,
                                     PR_FALSE  // aFollowOOFs
@@ -5060,25 +5059,26 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct*
       aPos->mResultFrame = current;
       aPos->mResultContent = range.content;
       // Output offset is relative to content, not frame
       aPos->mContentOffset = offset < 0 ? range.end : range.start + offset;
       break;
     }
     case eSelectLine :
     {
-      nsCOMPtr<nsILineIteratorNavigator> iter; 
+      nsAutoLineIterator iter;
       nsIFrame *blockFrame = this;
 
       while (NS_FAILED(result)){
         PRInt32 thisLine = nsFrame::GetLineNumber(blockFrame, aPos->mScrollViewStop, &blockFrame);
         if (thisLine < 0) 
           return  NS_ERROR_FAILURE;
-        result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(iter));
-        NS_ASSERTION(NS_SUCCEEDED(result) && iter, "GetLineNumber() succeeded but no block frame?");
+        iter = blockFrame->GetLineIterator();
+        NS_ASSERTION(iter, "GetLineNumber() succeeded but no block frame?");
+        result = NS_OK;
 
         int edgeCase = 0;//no edge case. this should look at thisLine
         
         PRBool doneLooping = PR_FALSE;//tells us when no more block frames hit.
         //this part will find a frame or a block frame. if it's a block frame
         //it will "drill down" to find a viable frame or it will return an error.
         nsIFrame *lastFrame = this;
         do {
@@ -5112,30 +5112,33 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct*
             PRBool searchTableBool = PR_FALSE;
             if (aPos->mResultFrame->GetType() == nsGkAtoms::tableOuterFrame ||
                 aPos->mResultFrame->GetType() == nsGkAtoms::tableCellFrame)
             {
               nsIFrame *frame = aPos->mResultFrame->GetFirstChild(nsnull);
               //got the table frame now
               while(frame) //ok time to drill down to find iterator
               {
-                result = frame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),
-                                                          getter_AddRefs(iter));
-                if (NS_SUCCEEDED(result))
+                iter = frame->GetLineIterator();
+                if (iter)
                 {
                   aPos->mResultFrame = frame;
                   searchTableBool = PR_TRUE;
+                  result = NS_OK;
                   break; //while(frame)
                 }
+                result = NS_ERROR_FAILURE;
                 frame = frame->GetFirstChild(nsnull);
               }
             }
-            if (!searchTableBool)
-              result = aPos->mResultFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),
-                                                        getter_AddRefs(iter));
+
+            if (!searchTableBool) {
+              iter = aPos->mResultFrame->GetLineIterator();
+              result = iter ? NS_OK : NS_ERROR_FAILURE;
+            }
             if (NS_SUCCEEDED(result) && iter)//we've struck another block element!
             {
               doneLooping = PR_FALSE;
               if (aPos->mDirection == eDirPrevious)
                 edgeCase = 1;//far edge, search from end backwards
               else
                 edgeCase = -1;//near edge search from beginning onwards
               thisLine=0;//this line means nothing now.
@@ -5155,36 +5158,34 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct*
     }
 
     case eSelectParagraph:
       return PeekOffsetParagraph(aPos);
 
     case eSelectBeginLine:
     case eSelectEndLine:
     {
-      nsCOMPtr<nsILineIteratorNavigator> it;
       // Adjusted so that the caret can't get confused when content changes
       nsIFrame* blockFrame = AdjustFrameForSelectionStyles(this);
       PRInt32 thisLine = nsFrame::GetLineNumber(blockFrame, aPos->mScrollViewStop, &blockFrame);
       if (thisLine < 0)
         return NS_ERROR_FAILURE;
-      result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
-      NS_ASSERTION(NS_SUCCEEDED(result) && it, "GetLineNumber() succeeded but no block frame?");
+      nsAutoLineIterator it = blockFrame->GetLineIterator();
+      NS_ASSERTION(it, "GetLineNumber() succeeded but no block frame?");
 
       PRInt32 lineFrameCount;
       nsIFrame *firstFrame;
       nsRect usedRect;
       PRUint32 lineFlags;
       nsIFrame* baseFrame = nsnull;
       PRBool endOfLine = (eSelectEndLine == aPos->mAmount);
       
 #ifdef IBMBIDI
       if (aPos->mVisual && PresContext()->BidiEnabled()) {
-        PRBool lineIsRTL;
-        it->GetDirection(&lineIsRTL);
+        PRBool lineIsRTL = it->GetDirection();
         PRBool isReordered;
         nsIFrame *lastFrame;
         result = it->CheckLineOrder(thisLine, &isReordered, &firstFrame, &lastFrame);
         baseFrame = endOfLine ? lastFrame : firstFrame;
         if (baseFrame) {
           nsBidiLevel embeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(baseFrame);
           // If the direction of the frame on the edge is opposite to that of the line,
           // we'll need to drill down to its opposite end, so reverse endOfLine.
@@ -5330,17 +5331,17 @@ nsFrame::CheckVisibility(nsPresContext* 
 PRInt32
 nsFrame::GetLineNumber(nsIFrame *aFrame, PRBool aLockScroll, nsIFrame** aContainingBlock)
 {
   NS_ASSERTION(aFrame, "null aFrame");
   nsFrameManager* frameManager = aFrame->PresContext()->FrameManager();
   nsIFrame *blockFrame = aFrame;
   nsIFrame *thisBlock;
   PRInt32   thisLine;
-  nsCOMPtr<nsILineIteratorNavigator> it; 
+  nsAutoLineIterator it;
   nsresult result = NS_ERROR_FAILURE;
   while (NS_FAILED(result) && blockFrame)
   {
     thisBlock = blockFrame;
     if (thisBlock->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
       //if we are searching for a frame that is not in flow we will not find it. 
       //we must instead look for its placeholder
       if (thisBlock->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
@@ -5351,63 +5352,63 @@ nsFrame::GetLineNumber(nsIFrame *aFrame,
       if (!thisBlock)
         return -1;
     }  
     blockFrame = thisBlock->GetParent();
     result = NS_OK;
     if (blockFrame) {
       if (aLockScroll && blockFrame->GetType() == nsGkAtoms::scrollFrame)
         return -1;
-      result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
+      it = blockFrame->GetLineIterator();
+      if (!it)
+        result = NS_ERROR_FAILURE;
     }
   }
   if (!blockFrame || !it)
     return -1;
 
   if (aContainingBlock)
     *aContainingBlock = blockFrame;
-  result = it->FindLineContaining(thisBlock, &thisLine);
-  if (NS_FAILED(result))
-    return -1;
-  return thisLine;
+  return it->FindLineContaining(thisBlock);
 }
 
 nsresult
 nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
                                 PRBool aJumpLines, PRBool aScrollViewStop, 
                                 nsIFrame** aOutFrame, PRInt32* aOutOffset, PRBool* aOutJumpedLine)
-{  
+{
+  nsresult result;
+
   if (!aOutFrame || !aOutOffset || !aOutJumpedLine)
     return NS_ERROR_NULL_POINTER;
   
   nsPresContext* presContext = PresContext();
   *aOutFrame = nsnull;
   *aOutOffset = 0;
   *aOutJumpedLine = PR_FALSE;
 
   // Find the prev/next selectable frame
   PRBool selectable = PR_FALSE;
   nsIFrame *traversedFrame = this;
   while (!selectable) {
     nsIFrame *blockFrame;
-    nsCOMPtr<nsILineIteratorNavigator> it; 
     
     PRInt32 thisLine = nsFrame::GetLineNumber(traversedFrame, aScrollViewStop, &blockFrame);
     if (thisLine < 0)
       return NS_ERROR_FAILURE;
-    nsresult result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
-    NS_ASSERTION(NS_SUCCEEDED(result) && it, "GetLineNumber() succeeded but no block frame?");
+
+    nsAutoLineIterator it = blockFrame->GetLineIterator();
+    NS_ASSERTION(it, "GetLineNumber() succeeded but no block frame?");
 
     PRBool atLineEdge;
     nsIFrame *firstFrame;
     nsIFrame *lastFrame;
 #ifdef IBMBIDI
     if (aVisual && presContext->BidiEnabled()) {
-      PRBool lineIsRTL;                                                             
-      it->GetDirection(&lineIsRTL);
+      PRBool lineIsRTL = it->GetDirection();
       PRBool isReordered;
       result = it->CheckLineOrder(thisLine, &isReordered, &firstFrame, &lastFrame);
       nsIFrame** framePtr = aDirection == eDirPrevious ? &firstFrame : &lastFrame;
       if (*framePtr) {
         nsBidiLevel embeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(*framePtr);
         if ((((embeddingLevel & 1) && lineIsRTL) || (!(embeddingLevel & 1) && !lineIsRTL)) ==
             (aDirection == eDirPrevious)) {
           nsFrame::GetFirstLeaf(presContext, framePtr);
@@ -6185,17 +6186,17 @@ nsFrame::RefreshSizeCache(nsBoxLayoutSta
       newRect.x = 0;
       newRect.y = 0;
       Redraw(aState, &newRect);
     }
 
     metrics->mBlockMinSize.height = 0;
     // ok we need the max ascent of the items on the line. So to do this
     // ask the block for its line iterator. Get the max ascent.
-    nsCOMPtr<nsILineIterator> lines = do_QueryInterface(static_cast<nsIFrame*>(this));
+    nsAutoLineIterator lines = GetLineIterator();
     if (lines) 
     {
       metrics->mBlockMinSize.height = 0;
       int count = 0;
       nsIFrame* firstFrame = nsnull;
       PRInt32 framesOnLine;
       nsRect lineBounds;
       PRUint32 lineFlags;
@@ -6228,16 +6229,22 @@ nsFrame::RefreshSizeCache(nsBoxLayoutSta
                                                      metrics->mBlockPrefSize.height,
                                                      metrics->mBlockAscent);
 #endif
   }
 
   return rv;
 }
 
+/* virtual */ nsILineIterator*
+nsFrame::GetLineIterator()
+{
+  return nsnull;
+}
+
 nsSize
 nsFrame::GetPrefSize(nsBoxLayoutState& aState)
 {
   nsSize size(0,0);
   DISPLAY_PREF_SIZE(this, size);
   // If the size is cached, and there are no HTML constraints that we might
   // be depending on, then we just return the cached size.
   nsBoxLayoutMetrics *metrics = BoxMetrics();
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -616,16 +616,18 @@ private:
                      nscoord aX,
                      nscoord aY,
                      nscoord aWidth,
                      nscoord aHeight,
                      PRBool aMoveFrame = PR_TRUE);
 
   NS_IMETHODIMP RefreshSizeCache(nsBoxLayoutState& aState);
 
+  virtual nsILineIterator* GetLineIterator();
+
 protected:
   NS_IMETHOD_(nsrefcnt) AddRef(void);
   NS_IMETHOD_(nsrefcnt) Release(void);
 };
 
 // Start Display Reflow Debugging
 #ifdef DEBUG
 
--- a/layout/generic/nsFrameList.cpp
+++ b/layout/generic/nsFrameList.cpp
@@ -422,30 +422,28 @@ nsFrameList::List(FILE* out) const
   fputs(">\n", out);
 }
 #endif
 
 #ifdef IBMBIDI
 nsIFrame*
 nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const
 {
-  nsCOMPtr<nsILineIterator> iter;
-
   if (!mFirstChild)
     return nsnull;
   
   nsIFrame* parent = mFirstChild->GetParent();
   if (!parent)
     return aFrame ? GetPrevSiblingFor(aFrame) : LastChild();
 
   nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild);  
   nsBidiPresUtils* bidiUtils = mFirstChild->PresContext()->GetBidiUtils();
 
-  nsresult result = parent->QueryInterface(NS_GET_IID(nsILineIterator), getter_AddRefs(iter));
-  if (NS_FAILED(result) || !iter) { 
+  nsAutoLineIterator iter = parent->GetLineIterator();
+  if (!iter) { 
     // Parent is not a block Frame
     if (parent->GetType() == nsGkAtoms::lineFrame) {
       // Line frames are not bidi-splittable, so need to consider bidi reordering
       if (baseLevel == NSBIDI_LTR) {
         return bidiUtils->GetFrameToLeftOf(aFrame, mFirstChild, -1);
       } else { // RTL
         return bidiUtils->GetFrameToRightOf(aFrame, mFirstChild, -1);
       }
@@ -460,21 +458,21 @@ nsFrameList::GetPrevVisualFor(nsIFrame* 
     }
   }
 
   // Parent is a block frame, so use the LineIterator to find the previous visual 
   // sibling on this line, or the last one on the previous line.
 
   PRInt32 thisLine;
   if (aFrame) {
-    result = iter->FindLineContaining(aFrame, &thisLine);
-    if (NS_FAILED(result) || thisLine < 0)
+    thisLine = iter->FindLineContaining(aFrame);
+    if (thisLine < 0)
       return nsnull;
   } else {
-    iter->GetNumLines(&thisLine);
+    thisLine = iter->GetNumLines();
   }
 
   nsIFrame* frame = nsnull;
   nsIFrame* firstFrameOnLine;
   PRInt32 numFramesOnLine;
   nsRect lineBounds;
   PRUint32 lineFlags;
 
@@ -499,30 +497,28 @@ nsFrameList::GetPrevVisualFor(nsIFrame* 
     }
   }
   return frame;
 }
 
 nsIFrame*
 nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const
 {
-  nsCOMPtr<nsILineIterator> iter;
-
   if (!mFirstChild)
     return nsnull;
   
   nsIFrame* parent = mFirstChild->GetParent();
   if (!parent)
     return aFrame ? GetPrevSiblingFor(aFrame) : mFirstChild;
 
   nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild);
   nsBidiPresUtils* bidiUtils = mFirstChild->PresContext()->GetBidiUtils();
   
-  nsresult result = parent->QueryInterface(NS_GET_IID(nsILineIterator), getter_AddRefs(iter));
-  if (NS_FAILED(result) || !iter) { 
+  nsAutoLineIterator iter = parent->GetLineIterator();
+  if (!iter) { 
     // Parent is not a block Frame
     if (parent->GetType() == nsGkAtoms::lineFrame) {
       // Line frames are not bidi-splittable, so need to consider bidi reordering
       if (baseLevel == NSBIDI_LTR) {
         return bidiUtils->GetFrameToRightOf(aFrame, mFirstChild, -1);
       } else { // RTL
         return bidiUtils->GetFrameToLeftOf(aFrame, mFirstChild, -1);
       }
@@ -537,18 +533,18 @@ nsFrameList::GetNextVisualFor(nsIFrame* 
     }
   }
 
   // Parent is a block frame, so use the LineIterator to find the next visual 
   // sibling on this line, or the first one on the next line.
   
   PRInt32 thisLine;
   if (aFrame) {
-    result = iter->FindLineContaining(aFrame, &thisLine);
-    if (NS_FAILED(result) || thisLine < 0)
+    thisLine = iter->FindLineContaining(aFrame);
+    if (thisLine < 0)
       return nsnull;
   } else {
     thisLine = -1;
   }
 
   nsIFrame* frame = nsnull;
   nsIFrame* firstFrameOnLine;
   PRInt32 numFramesOnLine;
@@ -560,18 +556,17 @@ nsFrameList::GetNextVisualFor(nsIFrame* 
     
     if (baseLevel == NSBIDI_LTR) {
       frame = bidiUtils->GetFrameToRightOf(aFrame, firstFrameOnLine, numFramesOnLine);
     } else { // RTL
       frame = bidiUtils->GetFrameToLeftOf(aFrame, firstFrameOnLine, numFramesOnLine);
     }
   }
   
-  PRInt32 numLines;
-  iter->GetNumLines(&numLines);
+  PRInt32 numLines = iter->GetNumLines();
   if (!frame && thisLine < numLines - 1) {
     // Get the first frame of the next line
     iter->GetLine(thisLine + 1, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags);
     
     if (baseLevel == NSBIDI_LTR) {
       frame = bidiUtils->GetFrameToRightOf(nsnull, firstFrameOnLine, numFramesOnLine);
     } else { // RTL
       frame = bidiUtils->GetFrameToLeftOf(nsnull, firstFrameOnLine, numFramesOnLine);
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -80,16 +80,17 @@ class nsPresContext;
 class nsIPresShell;
 class nsIRenderingContext;
 class nsIView;
 class nsIWidget;
 class nsIDOMRange;
 class nsISelectionController;
 class nsBoxLayoutState;
 class nsIBoxLayout;
+class nsILineIterator;
 #ifdef ACCESSIBILITY
 class nsIAccessible;
 #endif
 class nsDisplayListBuilder;
 class nsDisplayListSet;
 class nsDisplayList;
 class gfxSkipChars;
 class gfxSkipCharsIterator;
@@ -2219,16 +2220,24 @@ NS_PTR_TO_INT32(frame->GetProperty(nsGkA
    * GetOverflowRect() of the frame!  Note that it's safe to assume in this
    * method that the frame origin didn't change.  If it did, whoever moved the
    * frame will invalidate as needed anyway.
    */
   void CheckInvalidateSizeChange(const nsRect& aOldRect,
                                  const nsRect& aOldOverflowRect,
                                  const nsSize& aNewDesiredSize);
 
+  /**
+   * Get a line iterator for this frame, if supported.
+   *
+   * @return nsnull if no line iterator is supported.
+   * @note dispose the line iterator using nsILineIterator::DisposeLineIterator
+   */
+  virtual nsILineIterator* GetLineIterator() = 0;
+
 protected:
   // Members
   nsRect           mRect;
   nsIContent*      mContent;
   nsStyleContext*  mStyleContext;
   nsIFrame*        mParent;
   nsIFrame*        mNextSibling;  // singly-linked list of frames
   nsFrameState     mState;
--- a/layout/generic/nsILineIterator.h
+++ b/layout/generic/nsILineIterator.h
@@ -32,57 +32,61 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef nsILineIterator_h___
 #define nsILineIterator_h___
 
-#include "nsISupports.h"
-
-/* a6cf90ff-15b3-11d2-932e-00805f8add32 */
-#define NS_ILINE_ITERATOR_IID \
- { 0xa6cf90ff, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
-
-/* {80AA3D7A-E0BF-4e18-8A82-2110397D7BC4}*/
-#define NS_ILINE_ITERATOR_NAV_IID \
- { 0x80aa3d7a, 0xe0bf, 0x4e18,{0x8a, 0x82, 0x21, 0x10, 0x39, 0x7d, 0x7b, 0xc4}}
+#include "nscore.h"
+#include "nsCoord.h"
 
-// Line iterator API.
-//
-// Lines are numbered from 0 to N, where 0 is the top line and N is
-// the bottom line.
-//
-// NOTE: while you can get this interface by doing a slezy hacky
-// QueryInterface on block frames, it isn't like a normal com
-// interface: it's not reflexive (you can't query back to the block
-// frame) and unlike other frames, it *IS* reference counted so don't
-// forget to NS_RELEASE it when you are done with it!
+class nsIFrame;
+struct nsRect;
 
 // Line Flags (see GetLine below)
 
 // This bit is set when the line is wrapping up a block frame. When
 // clear, it means that the line contains inline elements.
 #define NS_LINE_FLAG_IS_BLOCK           0x1
 
 // This bit is set when the line ends in some sort of break.
 #define NS_LINE_FLAG_ENDS_IN_BREAK      0x4
 
-class nsILineIterator : public nsISupports {
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILINE_ITERATOR_IID)
+/**
+ * Line iterator API.
+ *
+ * Lines are numbered from 0 to N, where 0 is the top line and N is
+ * the bottom line.
+ *
+ * Obtain this interface from frames via nsIFrame::GetLineIterator.
+ * When you are finished using the iterator, call DisposeLineIterator()
+ * to destroy the iterator if appropriate.
+ */
+class nsILineIterator
+{
+protected:
+  ~nsILineIterator() { }
 
-  // Return the number of lines in the block.
-  NS_IMETHOD GetNumLines(PRInt32* aResult) = 0;
+public:
+  virtual void DisposeLineIterator() = 0;
+
+  /**
+   * The number of lines in the block
+   */
+  virtual PRInt32 GetNumLines() = 0;
 
-  // Return the prevailing direction for the line. aIsRightToLeft will
-  // be set to PR_TRUE if the CSS direction property for the block is
-  // "rtl", otherwise aIsRightToLeft will be set to PR_FALSE.
-  NS_IMETHOD GetDirection(PRBool* aIsRightToLeft) = 0;
+  /**
+   * The prevailing direction of lines.
+   *
+   * @return PR_TRUE if the CSS direction property for the block is
+   *         "rtl", otherwise PR_FALSE
+   */
+  virtual PRBool GetDirection() = 0;
 
   // Return structural information about a line. aFirstFrameOnLine is
   // the first frame on the line and aNumFramesOnLine is the number of
   // frames that are on the line. If the line-number is invalid then
   // aFirstFrameOnLine will be nsnull and aNumFramesOnLine will be
   // zero.
   //
   // For valid line numbers, aLineBounds is set to the bounding box of
@@ -93,29 +97,30 @@ public:
   // In addition, aLineFlags will contain flag information about the
   // line.
   NS_IMETHOD GetLine(PRInt32 aLineNumber,
                      nsIFrame** aFirstFrameOnLine,
                      PRInt32* aNumFramesOnLine,
                      nsRect& aLineBounds,
                      PRUint32* aLineFlags) = 0;
 
-  // Given a frame that's a child of the block, find which line its on
-  // and return that line index into aIndexResult. aIndexResult will
-  // be set to -1 if the frame cannot be found.
-  NS_IMETHOD FindLineContaining(nsIFrame* aFrame,
-                                PRInt32* aLineNumberResult) = 0;
+  /**
+   * Given a frame that's a child of the block, find which line its on
+   * and return that line index. Returns -1 if the frame cannot be found.
+   */
+  virtual PRInt32 FindLineContaining(nsIFrame* aFrame) = 0;
 
-  // Given a Y coordinate relative to the block that provided this
-  // line iterator, find the line that contains the Y
-  // coordinate. Returns -1 in aLineNumberResult if the Y coordinate
-  // is above the first line. Returns N (where N is the number of
-  // lines) if the Y coordinate is below the last line.
-  NS_IMETHOD FindLineAt(nscoord aY,
-                        PRInt32* aLineNumberResult) = 0;
+  /**
+   * Given a Y coordinate relative to the block that provided this
+   * line iterator, return the line that contains the Y
+   * coordinate. Returns -1 in aLineNumberResult if the Y coordinate
+   * is above the first line. Returns N (where N is the number of
+   * lines) if the Y coordinate is below the last line.
+   */
+  virtual PRInt32 FindLineAt(nscoord aY) = 0;
 
   // Given a line number and an X coordinate, find the frame on the
   // line that is nearest to the X coordinate. The
   // aXIsBeforeFirstFrame and aXIsAfterLastFrame flags are updated
   // appropriately.
   NS_IMETHOD FindFrameAt(PRInt32 aLineNumber,
                          nscoord aX,
                          nsIFrame** aFrameFound,
@@ -131,20 +136,38 @@ public:
   //  If not, return the first and last visual frames
   NS_IMETHOD CheckLineOrder(PRInt32                  aLine,
                             PRBool                   *aIsReordered,
                             nsIFrame                 **aFirstVisual,
                             nsIFrame                 **aLastVisual) = 0;
 #endif
 };
 
-NS_DEFINE_STATIC_IID_ACCESSOR(nsILineIterator, NS_ILINE_ITERATOR_IID)
+class nsAutoLineIterator
+{
+public:
+  nsAutoLineIterator() : mRawPtr(nsnull) { }
+  nsAutoLineIterator(nsILineIterator *i) : mRawPtr(i) { }
+
+  ~nsAutoLineIterator() {
+    if (mRawPtr)
+      mRawPtr->DisposeLineIterator();
+  }
+
+  operator nsILineIterator*() { return mRawPtr; }
+  nsILineIterator* operator->() { return mRawPtr; }
 
-//special line iterator for keyboard navigation
-class nsILineIteratorNavigator : public nsILineIterator {
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILINE_ITERATOR_NAV_IID)
+  nsILineIterator* operator=(nsILineIterator* i) {
+    if (i == mRawPtr)
+      return i;
+
+    if (mRawPtr)
+      mRawPtr->DisposeLineIterator();
+
+    mRawPtr = i;
+    return i;
+  }
+
+private:
+  nsILineIterator* mRawPtr;
 };
 
-NS_DEFINE_STATIC_IID_ACCESSOR(nsILineIteratorNavigator,
-                              NS_ILINE_ITERATOR_NAV_IID)
-
 #endif /* nsILineIterator_h___ */
--- a/layout/generic/nsLineBox.cpp
+++ b/layout/generic/nsLineBox.cpp
@@ -538,17 +538,21 @@ nsLineIterator::nsLineIterator()
 
 nsLineIterator::~nsLineIterator()
 {
   if (mLines != gDummyLines) {
     delete [] mLines;
   }
 }
 
-NS_IMPL_ISUPPORTS2(nsLineIterator, nsILineIterator, nsILineIteratorNavigator)
+/* virtual */ void
+nsLineIterator::DisposeLineIterator()
+{
+  delete this;
+}
 
 nsresult
 nsLineIterator::Init(nsLineList& aLines, PRBool aRightToLeft)
 {
   mRightToLeft = aRightToLeft;
 
   // Count the lines
   PRInt32 numLines = aLines.size();
@@ -573,36 +577,26 @@ nsLineIterator::Init(nsLineList& aLines,
        ++line)
   {
     *lp++ = line;
   }
   mNumLines = numLines;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsLineIterator::GetNumLines(PRInt32* aResult)
+PRInt32
+nsLineIterator::GetNumLines()
 {
-  NS_PRECONDITION(aResult, "null OUT ptr");
-  if (!aResult) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  *aResult = mNumLines;
-  return NS_OK;
+  return mNumLines;
 }
 
-NS_IMETHODIMP
-nsLineIterator::GetDirection(PRBool* aIsRightToLeft)
+PRBool
+nsLineIterator::GetDirection()
 {
-  NS_PRECONDITION(aIsRightToLeft, "null OUT ptr");
-  if (!aIsRightToLeft) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  *aIsRightToLeft = mRightToLeft;
-  return NS_OK;
+  return mRightToLeft;
 }
 
 NS_IMETHODIMP
 nsLineIterator::GetLine(PRInt32 aLineNumber,
                         nsIFrame** aFirstFrameOnLine,
                         PRInt32* aNumFramesOnLine,
                         nsRect& aLineBounds,
                         PRUint32* aLineFlags)
@@ -630,52 +624,45 @@ nsLineIterator::GetLine(PRInt32 aLineNum
     if (line->HasBreakAfter())
       flags |= NS_LINE_FLAG_ENDS_IN_BREAK;
   }
   *aLineFlags = flags;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsLineIterator::FindLineContaining(nsIFrame* aFrame,
-                                   PRInt32* aLineNumberResult)
+PRInt32
+nsLineIterator::FindLineContaining(nsIFrame* aFrame)
 {
   nsLineBox* line = mLines[0];
   PRInt32 lineNumber = 0;
   while (lineNumber != mNumLines) {
     if (line->Contains(aFrame)) {
-      *aLineNumberResult = lineNumber;
-      return NS_OK;
+      return lineNumber;
     }
     line = mLines[++lineNumber];
   }
-  *aLineNumberResult = -1;
-  return NS_OK;
+  return -1;
 }
 
-NS_IMETHODIMP
-nsLineIterator::FindLineAt(nscoord aY,
-                           PRInt32* aLineNumberResult)
+/* virtual */ PRInt32
+nsLineIterator::FindLineAt(nscoord aY)
 {
   nsLineBox* line = mLines[0];
   if (!line || (aY < line->mBounds.y)) {
-    *aLineNumberResult = -1;
-    return NS_OK;
+    return -1;
   }
   PRInt32 lineNumber = 0;
   while (lineNumber != mNumLines) {
     if ((aY >= line->mBounds.y) && (aY < line->mBounds.YMost())) {
-      *aLineNumberResult = lineNumber;
-      return NS_OK;
+      return lineNumber;
     }
     line = mLines[++lineNumber];
   }
-  *aLineNumberResult = mNumLines;
-  return NS_OK;
+  return mNumLines;
 }
 
 #ifdef IBMBIDI
 NS_IMETHODIMP
 nsLineIterator::CheckLineOrder(PRInt32                  aLine,
                                PRBool                   *aIsReordered,
                                nsIFrame                 **aFirstVisual,
                                nsIFrame                 **aLastVisual)
--- a/layout/generic/nsLineBox.h
+++ b/layout/generic/nsLineBox.h
@@ -1503,58 +1503,49 @@ nsLineList_const_reverse_iterator&
 nsLineList_const_reverse_iterator::operator=(const nsLineList_const_reverse_iterator& aOther)
 {
   ASSIGN_FROM(aOther)
 }
 
 
 //----------------------------------------------------------------------
 
-class nsLineIterator : public nsILineIteratorNavigator {
+class NS_FINAL_CLASS nsLineIterator : public nsILineIterator
+{
 public:
   nsLineIterator();
-  virtual ~nsLineIterator();
+  ~nsLineIterator();
 
-  NS_DECL_ISUPPORTS
+  virtual void DisposeLineIterator();
 
-  NS_IMETHOD GetNumLines(PRInt32* aResult);
-  NS_IMETHOD GetDirection(PRBool* aIsRightToLeft);
+  virtual PRInt32 GetNumLines();
+  virtual PRBool GetDirection();
   NS_IMETHOD GetLine(PRInt32 aLineNumber,
                      nsIFrame** aFirstFrameOnLine,
                      PRInt32* aNumFramesOnLine,
                      nsRect& aLineBounds,
                      PRUint32* aLineFlags);
-  NS_IMETHOD FindLineContaining(nsIFrame* aFrame,
-                                PRInt32* aLineNumberResult);
-  NS_IMETHOD FindLineAt(nscoord aY,
-                        PRInt32* aLineNumberResult);
+  virtual PRInt32 FindLineContaining(nsIFrame* aFrame);
+  virtual PRInt32 FindLineAt(nscoord aY);
   NS_IMETHOD FindFrameAt(PRInt32 aLineNumber,
                          nscoord aX,
                          nsIFrame** aFrameFound,
                          PRBool* aXIsBeforeFirstFrame,
                          PRBool* aXIsAfterLastFrame);
 
   NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame, PRInt32 aLineNumber);
 #ifdef IBMBIDI
   NS_IMETHOD CheckLineOrder(PRInt32                  aLine,
                             PRBool                   *aIsReordered,
                             nsIFrame                 **aFirstVisual,
                             nsIFrame                 **aLastVisual);
 #endif
   nsresult Init(nsLineList& aLines, PRBool aRightToLeft);
 
-protected:
-  PRInt32 NumLines() const {
-    return mNumLines;
-  }
-
-  nsLineBox* CurrentLine() {
-    return mLines[mIndex];
-  }
-
+private:
   nsLineBox* PrevLine() {
     if (0 == mIndex) {
       return nsnull;
     }
     return mLines[--mIndex];
   }
 
   nsLineBox* NextLine() {
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -59,45 +59,26 @@ nsTableRowGroupFrame::nsTableRowGroupFra
 {
   SetRepeatable(PR_FALSE);
 }
 
 nsTableRowGroupFrame::~nsTableRowGroupFrame()
 {
 }
 
-/* ----------- nsTableRowGroupFrame ---------- */
-nsrefcnt nsTableRowGroupFrame::AddRef(void)
-{
-  return 1;//implementation of nsLineIterator
-}
-
-nsrefcnt nsTableRowGroupFrame::Release(void)
-{
-  return 1;//implementation of nsLineIterator
-}
-
 NS_IMETHODIMP
 nsTableRowGroupFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
 {
   NS_PRECONDITION(aInstancePtr, "null out param");
 
   static NS_DEFINE_IID(kITableRowGroupIID, NS_ITABLEROWGROUPFRAME_IID);
   if (aIID.Equals(kITableRowGroupIID)) {
     *aInstancePtr = (void*)this;
     return NS_OK;
   }
-  if (aIID.Equals(NS_GET_IID(nsILineIteratorNavigator))) {
-    *aInstancePtr = static_cast<nsILineIteratorNavigator*>(this);
-    return NS_OK;
-  }
-  if (aIID.Equals(NS_GET_IID(nsILineIterator))) {
-    *aInstancePtr = static_cast<nsILineIterator*>(this);
-    return NS_OK;
-  }
 
   return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
 }
 
 /* virtual */ PRBool
 nsTableRowGroupFrame::IsContainingBlock() const
 {
   return PR_TRUE;
@@ -1648,33 +1629,28 @@ void nsTableRowGroupFrame::SetContinuous
       mLeftContBorderWidth = aPixelValue;
       return;
     default:
       NS_ERROR("invalid NS_SIDE argument");
   }
 }
 
 //nsILineIterator methods
-NS_IMETHODIMP
-nsTableRowGroupFrame::GetNumLines(PRInt32* aResult)
+PRInt32
+nsTableRowGroupFrame::GetNumLines()
 {
-  NS_ENSURE_ARG_POINTER(aResult);
-  *aResult = GetRowCount();
-  return NS_OK;
+  return GetRowCount();
 }
 
-NS_IMETHODIMP
-nsTableRowGroupFrame::GetDirection(PRBool* aIsRightToLeft)
+PRBool
+nsTableRowGroupFrame::GetDirection()
 {
-  NS_ENSURE_ARG_POINTER(aIsRightToLeft);
-  // rtl is table wide @see nsTableIterator
   nsTableFrame* table = nsTableFrame::GetTableFrame(this);
-  *aIsRightToLeft = (NS_STYLE_DIRECTION_RTL ==
-                     table->GetStyleVisibility()->mDirection);
-  return NS_OK;
+  return (NS_STYLE_DIRECTION_RTL ==
+          table->GetStyleVisibility()->mDirection);
 }
   
 NS_IMETHODIMP
 nsTableRowGroupFrame::GetLine(PRInt32    aLineNumber, 
                               nsIFrame** aFirstFrameOnLine, 
                               PRInt32*   aNumFramesOnLine,
                               nsRect&    aLineBounds, 
                               PRUint32*  aLineFlags)
@@ -1709,38 +1685,35 @@ nsTableRowGroupFrame::GetLine(PRInt32   
       aLineBounds = parent->GetRect();
       return NS_OK;
     }
   }
   NS_ERROR("cellmap is lying");
   return NS_ERROR_FAILURE;
 }
   
-NS_IMETHODIMP
-nsTableRowGroupFrame::FindLineContaining(nsIFrame* aFrame, 
-                                         PRInt32*  aLineNumberResult)
+PRInt32
+nsTableRowGroupFrame::FindLineContaining(nsIFrame* aFrame)
 {
   NS_ENSURE_ARG_POINTER(aFrame);
-  NS_ENSURE_ARG_POINTER(aLineNumberResult);
   
   NS_ASSERTION((aFrame->GetType() == nsGkAtoms::tableRowFrame),
                "RowGroup contains a frame that is not a row");
 
   nsTableRowFrame* rowFrame = (nsTableRowFrame*)aFrame;
-  *aLineNumberResult = rowFrame->GetRowIndex() - GetStartRowIndex();
-
-  return NS_OK;
+  return rowFrame->GetRowIndex() - GetStartRowIndex();
 }
 
-NS_IMETHODIMP
-nsTableRowGroupFrame::FindLineAt(nscoord  aY, 
-                                 PRInt32* aLineNumberResult)
+PRInt32
+nsTableRowGroupFrame::FindLineAt(nscoord  aY)
 {
+  NS_NOTREACHED("Not implemented");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
+
 #ifdef IBMBIDI
 NS_IMETHODIMP
 nsTableRowGroupFrame::CheckLineOrder(PRInt32                  aLine,
                                      PRBool                   *aIsReordered,
                                      nsIFrame                 **aFirstVisual,
                                      nsIFrame                 **aLastVisual)
 {
   *aIsReordered = PR_FALSE;
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -91,21 +91,22 @@ struct nsRowGroupReflowState {
  * nsTableRowGroupFrame is the frame that maps row groups 
  * (HTML tags THEAD, TFOOT, and TBODY). This class cannot be reused
  * outside of an nsTableFrame.  It assumes that its parent is an nsTableFrame, and 
  * its children are nsTableRowFrames.
  * 
  * @see nsTableFrame
  * @see nsTableRowFrame
  */
-class nsTableRowGroupFrame : public nsHTMLContainerFrame, public nsILineIteratorNavigator
+class nsTableRowGroupFrame
+  : public nsHTMLContainerFrame
+  , public nsILineIterator
 {
 public:
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
+  NS_IMETHOD QueryInterface(const nsIID &aIID, void **aInstancePtr);
 
   /** instantiate a new instance of nsTableRowFrame.
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
   friend nsIFrame* NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
   virtual ~nsTableRowGroupFrame();
@@ -222,32 +223,34 @@ public:
     * @param aYTotalOffset the total amount that the rowgroup is shifted up
     * @param aWidth        new width of the rowgroup
     */
   nscoord CollapseRowGroupIfNecessary(nscoord aYTotalOffset,
                                       nscoord aWidth);
 
 // nsILineIterator methods
 public:
+  virtual void DisposeLineIterator() { }
+
   // The table row is the equivalent to a line in block layout. 
   // The nsILineIterator assumes that a line resides in a block, this role is
   // fullfilled by the row group. Rows in table are counted relative to the
   // table. The row index of row corresponds to the cellmap coordinates. The
   // line index with respect to a row group can be computed by substracting the
   // row index of the first row in the row group.
    
   /** Get the number of rows in a row group
-    * @param aResult - pointer that holds the number of lines in a row group
+    * @return the number of lines in a row group
     */
-  NS_IMETHOD GetNumLines(PRInt32* aResult);
+  virtual PRInt32 GetNumLines();
 
   /** @see nsILineIterator.h GetDirection
-    * @param aIsRightToLeft - true if the table is rtl
+    * @return true if the table is rtl
     */
-  NS_IMETHOD GetDirection(PRBool* aIsRightToLeft);
+  virtual PRBool GetDirection();
   
   /** Return structural information about a line. 
     * @param aLineNumber       - the index of the row relative to the row group
     *                            If the line-number is invalid then
     *                            aFirstFrameOnLine will be nsnull and 
     *                            aNumFramesOnLine will be zero.
     * @param aFirstFrameOnLine - the first cell frame that originates in row
     *                            with a rowindex that matches a line number
@@ -259,26 +262,25 @@ public:
   NS_IMETHOD GetLine(PRInt32 aLineNumber,
                      nsIFrame** aFirstFrameOnLine,
                      PRInt32* aNumFramesOnLine,
                      nsRect& aLineBounds,
                      PRUint32* aLineFlags);
   
   /** Given a frame that's a child of the rowgroup, find which line its on.
     * @param aFrame       - frame, should be a row
-    * @param aIndexResult - row index relative to the row group if this a row
-    *                       frame. aIndexResult will be set to -1 if the frame
-    *                       cannot be found.
+    * @return               row index relative to the row group if this a row
+    *                       frame. -1 if the frame cannot be found.
     */
-  NS_IMETHOD FindLineContaining(nsIFrame* aFrame, PRInt32* aLineNumberResult);
+  virtual PRInt32 FindLineContaining(nsIFrame* aFrame);
   
   /** not implemented
     * the function is also not called in our tree
     */
-  NS_IMETHOD FindLineAt(nscoord aY, PRInt32* aLineNumberResult);
+  virtual PRInt32 FindLineAt(nscoord aY);
 
   /** Find the orginating cell frame on a row that is the nearest to the
     * coordinate X.
     * @param aLineNumber          - the index of the row relative to the row group
     * @param aX                   - X coordinate in twips relative to the
     *                               origin of the row group
     * @param aFrameFound          - pointer to the cellframe
     * @param aXIsBeforeFirstFrame - the point is before the first originating
@@ -368,16 +370,18 @@ public:
   
   PRBool IsScrolled() {
     // Note that if mOverflowY is CLIP, so is mOverflowX, and we need to clip the background
     // as if the rowgroup is scrollable.
     return GetStyleContext()->GetPseudoType() == nsCSSAnonBoxes::scrolledContent ||
            GetStyleDisplay()->mOverflowY == NS_STYLE_OVERFLOW_CLIP;
   }
 
+  virtual nsILineIterator* GetLineIterator() { return this; }
+
 protected:
   nsTableRowGroupFrame(nsStyleContext* aContext);
 
   void InitChildReflowState(nsPresContext&     aPresContext, 
                             PRBool             aBorderCollapse,
                             nsHTMLReflowState& aReflowState);
   
   /** implement abstract method on nsHTMLContainerFrame */
--- a/memory/jemalloc/jemalloc.c
+++ b/memory/jemalloc/jemalloc.c
@@ -1281,16 +1281,19 @@ static void	malloc_print_stats(void);
 static
 #endif
 bool		malloc_init_hard(void);
 static void	reserve_shrink(void);
 static uint64_t	reserve_notify(reserve_cnd_t cnd, size_t size, uint64_t seq);
 static uint64_t	reserve_crit(size_t size, const char *fname, uint64_t seq);
 static void	reserve_fail(size_t size, const char *fname);
 
+void		_malloc_prefork(void);
+void		_malloc_postfork(void);
+
 /*
  * End function prototypes.
  */
 /******************************************************************************/
 
 /*
  * umax2s() provides minimal integer printing functionality, which is
  * especially useful for situations where allocation in vsnprintf() calls would
@@ -5686,16 +5689,21 @@ MALLOC_OUT:
 	/* Take care to call atexit() only once. */
 	if (opt_print_stats) {
 #ifndef MOZ_MEMORY_WINDOWS
 		/* Print statistics at exit. */
 		atexit(malloc_print_stats);
 #endif
 	}
 
+#if (!defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_DARWIN))
+	/* Prevent potential deadlock on malloc locks after fork. */
+	pthread_atfork(_malloc_prefork, _malloc_postfork, _malloc_postfork);
+#endif
+
 	/* Set variables according to the value of opt_small_max_2pow. */
 	if (opt_small_max_2pow < opt_quantum_2pow)
 		opt_small_max_2pow = opt_quantum_2pow;
 	small_max = (1U << opt_small_max_2pow);
 
 	/* Set bin-related variables. */
 	bin_maxclass = (pagesize >> 1);
 	assert(opt_quantum_2pow >= TINY_MIN_2POW);
--- a/parser/htmlparser/public/nsIContentSink.h
+++ b/parser/htmlparser/public/nsIContentSink.h
@@ -60,57 +60,54 @@ class nsIParser;
  { 0x85, 0x10, 0xe3, 0x5f, 0x4f, 0x36, 0xea, 0xaa } }
 
 class nsIContentSink : public nsISupports {
 public:
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_SINK_IID)
 
   /**
-   * This method gets called before the nsParser calls tokenize.
-   * This is needed because the XML side actually builds
-   * the content model as part of the tokenization and
-   * not on BuildModel(). The XML side can use this call
-   * to do stuff that the HTML side does in WillProcessTokens().
-   *
-   * @update 2006-10-17 hsivonen
+   * This method is called by the parser when it is entered from
+   * the event loop. The content sink wants to know how long the
+   * parser has been active since we last processed events on the
+   * main event loop and this call calibrates that measurement.
    */
-  NS_IMETHOD WillTokenize(void)=0;
+  NS_IMETHOD WillParse(void)=0;
 
   /**
    * This method gets called when the parser begins the process
    * of building the content model via the content sink.
    *
    * @update 5/7/98 gess
-   */     
+   */
   NS_IMETHOD WillBuildModel(void)=0;
 
   /**
    * This method gets called when the parser concludes the process
    * of building the content model via the content sink.
    *
    * @update 5/7/98 gess
-   */     
+   */
   NS_IMETHOD DidBuildModel()=0;
 
   /**
    * This method gets called when the parser gets i/o blocked,
    * and wants to notify the sink that it may be a while before
    * more data is available.
    *
    * @update 5/7/98 gess
-   */     
+   */
   NS_IMETHOD WillInterrupt(void)=0;
 
   /**
    * This method gets called when the parser i/o gets unblocked,
    * and we're about to start dumping content again to the sink.
    *
    * @update 5/7/98 gess
-   */     
+   */
   NS_IMETHOD WillResume(void)=0;
 
   /**
    * This method gets called by the parser so that the content
    * sink can retain a reference to the parser. The expectation
    * is that the content sink will drop the reference when it
    * gets the DidBuildModel notification i.e. when parsing is done.
    */
--- a/parser/htmlparser/public/nsIHTMLContentSink.h
+++ b/parser/htmlparser/public/nsIHTMLContentSink.h
@@ -77,19 +77,20 @@
  *
  * NOTE: I haven't figured out how sub-documents (non-frames)
  *       are going to be handled. Stay tuned.
  */
 #include "nsIParserNode.h"
 #include "nsIContentSink.h"
 #include "nsHTMLTags.h"
 
+// d19e6730-5e2f-4131-89db-8a918515097d
 #define NS_IHTML_CONTENT_SINK_IID \
-{ 0x73b5a072, 0x0f87, 0x4d07, \
-  { 0xa8, 0x16, 0xe6, 0xac, 0x73, 0xa7, 0x04, 0x3c } }
+{ 0xd19e6730, 0x5e2f, 0x4131, \
+  { 0x89, 0xdb, 0x8a, 0x91, 0x85, 0x15, 0x09, 0x7d } }
 
 
 #if defined(XP_MAC) 
 #define MAX_REFLOW_DEPTH  75    //setting to 75 to prevent layout from crashing on mac. Bug 55095.
 #else
 #define MAX_REFLOW_DEPTH  200   //windows and linux (etc) can do much deeper structures.
 #endif
 
@@ -125,22 +126,16 @@ public:
   NS_IMETHOD EndContext(PRInt32 aPosition) = 0;
   
   /**
    * @update 01/09/2003 harishd
    * @param aTag - Check if this tag is enabled or not.
    */
   NS_IMETHOD IsEnabled(PRInt32 aTag, PRBool* aReturn) = 0;
 
-   /**
-   * This method is called when parser is about to begin
-   * synchronously processing a chunk of tokens. 
-   */
-  NS_IMETHOD WillProcessTokens(void) = 0;
-
   /**
    * This method is called when parser has
    * completed processing a chunk of tokens. The processing of the
    * tokens may be interrupted by returning NS_ERROR_HTMLPARSER_INTERRUPTED from
    * DidProcessAToken.
    */
   NS_IMETHOD DidProcessTokens() = 0;
 
--- a/parser/htmlparser/src/CNavDTD.cpp
+++ b/parser/htmlparser/src/CNavDTD.cpp
@@ -318,18 +318,16 @@ CNavDTD::BuildModel(nsIParser* aParser,
                                            eHTMLTag_html,
                                            NS_LITERAL_STRING("html"));
       if (tempToken) {
         mTokenizer->PushTokenFront(tempToken);
       }
     }
   }
 
-  mSink->WillProcessTokens();
-
   while (NS_SUCCEEDED(result)) {
     if (!(mFlags & NS_DTD_FLAG_STOP_PARSING)) {
       CToken* theToken = mTokenizer->PopToken();
       if (!theToken) {
         break;
       }
       result = HandleToken(theToken, aParser);
     } else {
--- a/parser/htmlparser/src/nsLoggingSink.cpp
+++ b/parser/htmlparser/src/nsLoggingSink.cpp
@@ -89,17 +89,17 @@ nsLoggingSink::SetOutputStream(PRFileDes
 static
 void WriteTabs(PRFileDesc * out,int aTabCount) {
   int tabs;
   for(tabs=0;tabs<aTabCount;++tabs)
     PR_fprintf(out, "  ");
 }
 
 NS_IMETHODIMP
-nsLoggingSink::WillTokenize() {
+nsLoggingSink::WillParse() {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsLoggingSink::WillBuildModel() {
   
   WriteTabs(mOutput,++mLevel);
   PR_fprintf(mOutput, "<begin>\n");
--- a/parser/htmlparser/src/nsLoggingSink.h
+++ b/parser/htmlparser/src/nsLoggingSink.h
@@ -55,17 +55,17 @@ public:
     mSink=0;
   }
 
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   // nsIContentSink
-  NS_IMETHOD WillTokenize();
+  NS_IMETHOD WillParse();
   NS_IMETHOD WillBuildModel();
   NS_IMETHOD DidBuildModel();
   NS_IMETHOD WillInterrupt();
   NS_IMETHOD WillResume();
   NS_IMETHOD SetParser(nsIParser* aParser);
   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
@@ -81,17 +81,16 @@ public:
   NS_IMETHOD IsEnabled(PRInt32 aTag, PRBool* aReturn) 
   /* Take the largest possible feature set. */
   { NS_ENSURE_ARG_POINTER(aReturn); *aReturn = PR_TRUE; return NS_OK; }
   NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; }
   NS_IMETHOD_(PRBool) IsFormOnStack() { return PR_FALSE; }
 
   NS_IMETHOD BeginContext(PRInt32 aPosition);
   NS_IMETHOD EndContext(PRInt32 aPosition);
-  NS_IMETHOD WillProcessTokens(void) { return NS_OK; }
   NS_IMETHOD DidProcessTokens(void) { return NS_OK; }
   NS_IMETHOD WillProcessAToken(void) { return NS_OK; }
   NS_IMETHOD DidProcessAToken(void) { return NS_OK; }
 
   // nsILoggingSink
   NS_IMETHOD SetOutputStream(PRFileDesc *aStream,PRBool autoDelete=PR_FALSE);
 
   nsresult OpenNode(const char* aKind, const nsIParserNode& aNode);
--- a/parser/htmlparser/src/nsParser.cpp
+++ b/parser/htmlparser/src/nsParser.cpp
@@ -1719,16 +1719,19 @@ nsParser::ContinueInterruptedParsing()
 
   if (mSpeculativeScriptThread) {
     mSpeculativeScriptThread->StopParsing(PR_FALSE);
   }
 
   PRBool isFinalChunk = mParserContext &&
                         mParserContext->mStreamListenerState == eOnStop;
 
+  if (mSink) {
+    mSink->WillParse();
+  }
   result = ResumeParse(PR_TRUE, isFinalChunk); // Ref. bug 57999
 
   if (result != NS_OK) {
     result=mInternalState;
   }
 
   return result;
 }
@@ -2862,16 +2865,19 @@ nsParser::OnDataAvailable(nsIRequest *re
     rv = pIStream->ReadSegments(ParserWriteFunc, &pws, aLength, &totalRead);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     // Don't bother to start parsing until we've seen some
     // non-whitespace data
     if (theContext->mScanner->FirstNonWhitespacePosition() >= 0) {
+      if (mSink) {
+        mSink->WillParse();
+      }
       rv = ResumeParse();
     }
   } else {
     rv = NS_ERROR_UNEXPECTED;
   }
 
   return rv;
 }
@@ -2910,16 +2916,19 @@ nsParser::OnStopRequest(nsIRequest *requ
   }
 
   mStreamStatus = status;
 
   if (mParserFilter)
     mParserFilter->Finish();
 
   if (NS_SUCCEEDED(rv)) {
+    if (mSink) {
+      mSink->WillParse();
+    }
     rv = ResumeParse(PR_TRUE, PR_TRUE);
   }
 
   // If the parser isn't enabled, we don't finish parsing till
   // it is reenabled.
 
 
   // XXX Should we wait to notify our observers as well if the
@@ -2959,17 +2968,16 @@ nsParser::WillTokenize(PRBool aIsFinalCh
     return PR_TRUE;
   }
 
   nsITokenizer* theTokenizer;
   PRInt32 type = mParserContext->mDTD ? mParserContext->mDTD->GetType() :
                                         NS_IPARSER_FLAG_HTML;
   nsresult result = mParserContext->GetTokenizer(type, mSink, theTokenizer);
   NS_ENSURE_SUCCESS(result, PR_FALSE);
-  mSink->WillTokenize();
   return NS_SUCCEEDED(theTokenizer->WillTokenize(aIsFinalChunk,
                                                  &mTokenAllocator));
 }
 
 
 /**
  * This is the primary control routine to consume tokens.
  * It iteratively consumes tokens until an error occurs or
--- a/parser/htmlparser/src/nsViewSourceHTML.cpp
+++ b/parser/htmlparser/src/nsViewSourceHTML.cpp
@@ -446,18 +446,16 @@ NS_IMETHODIMP CViewSourceHTML::BuildMode
           } else {
             result = NS_ERROR_OUT_OF_MEMORY;
           }
           IF_FREE(preToken, theAllocator);
         }
       }
     }
 
-    mSink->WillProcessTokens();
-
     while(NS_SUCCEEDED(result)){
       CToken* theToken=mTokenizer->PopToken();
       if(theToken) {
         result=HandleToken(theToken,aParser);
         if(NS_SUCCEEDED(result)) {
           IF_FREE(theToken, mTokenizer->GetTokenAllocator());
           if (mParser->CanInterrupt() &&
               mSink->DidProcessAToken() == NS_ERROR_HTMLPARSER_INTERRUPTED) {
--- a/parser/xml/src/nsSAXXMLReader.h
+++ b/parser/xml/src/nsSAXXMLReader.h
@@ -67,17 +67,17 @@ public:
   NS_DECL_NSIEXTENDEDEXPATSINK
   NS_DECL_NSISAXXMLREADER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
 
   nsSAXXMLReader();
 
   //nsIContentSink
-  NS_IMETHOD WillTokenize()
+  NS_IMETHOD WillParse()
   {
     return NS_OK;
   }
 
   NS_IMETHOD WillBuildModel();
   NS_IMETHOD DidBuildModel();
   NS_IMETHOD SetParser(nsIParser* aParser);
   
--- a/rdf/base/src/nsRDFContentSink.cpp
+++ b/rdf/base/src/nsRDFContentSink.cpp
@@ -154,17 +154,17 @@ public:
     RDFContentSinkImpl();
     virtual ~RDFContentSinkImpl();
 
     // nsISupports
     NS_DECL_ISUPPORTS
     NS_DECL_NSIEXPATSINK
 
     // nsIContentSink
-    NS_IMETHOD WillTokenize(void);
+    NS_IMETHOD WillParse(void);
     NS_IMETHOD WillBuildModel(void);
     NS_IMETHOD DidBuildModel(void);
     NS_IMETHOD WillInterrupt(void);
     NS_IMETHOD WillResume(void);
     NS_IMETHOD SetParser(nsIParser* aParser);  
     virtual void FlushPendingNotifications(mozFlushType aType) { }
     NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
     virtual nsISupports *GetTarget() { return nsnull; }
@@ -602,17 +602,17 @@ RDFContentSinkImpl::ReportError(const PR
   *_retval = PR_TRUE;
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////
 // nsIContentSink interface
 
 NS_IMETHODIMP 
-RDFContentSinkImpl::WillTokenize(void)
+RDFContentSinkImpl::WillParse(void)
 {
     return NS_OK;
 }
 
 
 NS_IMETHODIMP 
 RDFContentSinkImpl::WillBuildModel(void)
 {
--- a/toolkit/components/places/src/nsPlacesDBFlush.js
+++ b/toolkit/components/places/src/nsPlacesDBFlush.js
@@ -195,17 +195,20 @@ nsPlacesDBFlush.prototype = {
     if (this._inBatchMode)
       return;
 
     let statements = [];
     for (let i = 0; i < aTableNames.length; i++)
       statements.push(this._getSyncTableStatement(aTableNames[i]));
 
     // Execute sync statements async in a transaction
-    this._db.executeAsync(statements, statements.length, this);
+    // XXX due to a bug in sqlite, we cannot wrap these in a transaction.  See
+    //     https://bugzilla.mozilla.org/show_bug.cgi?id=462379#c2 for details.
+    //this._db.executeAsync(statements, statements.length, this);
+    statements.forEach(function(stmt) stmt.executeAsync(this), this);
 
     // Finalize statements, otherwise we could get in trouble
     statements.forEach(function(stmt) stmt.finalize());
   },
 
   /**
    * Generate the statement to synchronizes the moz_{aTableName} and
    * moz_{aTableName}_temp by copying all the data from the temporary table
--- a/toolkit/themes/gnomestripe/global/textbox.css
+++ b/toolkit/themes/gnomestripe/global/textbox.css
@@ -92,16 +92,17 @@ textbox[disabled="true"] {
   background-color: -moz-Dialog;
   color: GrayText;
 }
 
 /* ::::: plain textbox ::::: */
 
 textbox.plain {
   -moz-appearance: none !important;
+  background-color: transparent;
   padding: 0px !important;
   margin: 0px !important;
   border: none !important;
 }
 
 /* ::::: search textbox ::::: */
 
 .textbox-search-icon {
--- a/toolkit/themes/pinstripe/global/textbox.css
+++ b/toolkit/themes/pinstripe/global/textbox.css
@@ -105,16 +105,17 @@ textbox[disabled="true"] {
   background-color: -moz-Dialog;
   color: GrayText;
 } 
 
 /* ::::: plain textbox ::::: */
 
 textbox.plain {
   -moz-appearance: none !important;
+  background-color: transparent;
   padding: 0px !important;
   margin: 0px !important;
   border: none !important;
 }
 
 
 /* ::::: rounded search box ::::: */
 
--- a/toolkit/themes/winstripe/global/textbox.css
+++ b/toolkit/themes/winstripe/global/textbox.css
@@ -92,16 +92,17 @@ textbox[disabled="true"] {
   background-color: -moz-Dialog;
   color: GrayText;
 }
 
 /* ::::: plain textbox ::::: */
 
 textbox.plain {
   -moz-appearance: none !important;
+  background-color: transparent;
   padding: 0px !important;
   margin: 0px !important;
   border: none !important;
 }
 
 /* ::::: search textbox ::::: */
 
 .textbox-search-icon {