Merge cedar into mozilla-central
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 25 Mar 2011 23:55:33 -0400
changeset 63955 bf68a4a3ef6a08cba6dcef05954f1c1c92f0f26f
parent 63954 32b7f464e29f8259769fd7dcc7f271ab09f9d761 (current diff)
parent 63941 9be05c62b6ce59a5269cc6f4eb965b101b5b303c (diff)
child 63956 5c9d01016ee69f741377df00a6271debfe5b9993
child 63962 503e3c6ec0998fcf5f3383d2d24af2ea73b98057
push idunknown
push userunknown
push dateunknown
milestone2.2a1pre
first release with
nightly linux32
bf68a4a3ef6a / 4.2a1pre / 20110326030433 / files
nightly linux64
bf68a4a3ef6a / 4.2a1pre / 20110326030433 / files
nightly mac
bf68a4a3ef6a / 4.2a1pre / 20110326030433 / files
nightly win32
bf68a4a3ef6a / 4.2a1pre / 20110326030433 / files
nightly win64
bf68a4a3ef6a / 4.2a1pre / 20110326030208 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge cedar into mozilla-central
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
layout/reftests/bidi/229367-1-ref.html
layout/reftests/bidi/229367-1.html
layout/reftests/bidi/229367-2-ref.html
layout/reftests/bidi/229367-2.html
layout/reftests/bidi/229367-3-ref.html
layout/reftests/bidi/229367-3.html
layout/reftests/bidi/263359-1-ref.html
layout/reftests/bidi/263359-1.html
layout/reftests/bidi/263359-1a.html
layout/reftests/bidi/263359-1b.html
layout/reftests/bidi/263359-2-ref.html
layout/reftests/bidi/263359-2.html
layout/reftests/bidi/263359-3-ref.html
layout/reftests/bidi/263359-3.html
layout/reftests/bidi/263359-4-ref.html
layout/reftests/bidi/263359-4.html
layout/reftests/bidi/613157-1-ref.html
layout/reftests/bidi/613157-1.html
layout/reftests/bidi/613157-2-ref.html
layout/reftests/bidi/613157-2.html
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1817,19 +1817,22 @@
           ]]>
         </body>
       </method>
 
       <method name="addProgressListener">
         <parameter name="aListener"/>
         <body>
           <![CDATA[
-            NS_ASSERT(arguments.length == 1,
-                      "gBrowser.addProgressListener was called with a second argument, " +
-                      "which is not supported. See bug 608628.");
+            if (arguments.length != 1) {
+              Components.utils.reportError("gBrowser.addProgressListener was " +
+                                           "called with a second argument, " +
+                                           "which is not supported. See bug " +
+                                           "608628.");
+            }
 
             if (!this.mAddProgressListenerWasCalled) {
               this.mAddProgressListenerWasCalled = true;
               this.tabContainer.updateVisibility();
             }
 
             this.mProgressListeners.push(aListener);
           ]]>
--- a/client.mk
+++ b/client.mk
@@ -166,19 +166,21 @@ endif # MOZ_BUILD_PROJECTS
 CONFIGURES := $(TOPSRCDIR)/configure
 CONFIGURES += $(TOPSRCDIR)/js/src/configure
 
 #######################################################################
 # Rules
 
 # The default rule is build
 build::
+	$(MAKE) -f $(TOPSRCDIR)/client.mk $(if $(MOZ_PGO),profiledbuild,realbuild)
+
 
 # Print out any options loaded from mozconfig.
-all build clean depend distclean export libs install realclean::
+all realbuild clean depend distclean export libs install realclean::
 	@if test -f .mozconfig.out; then \
 	  cat .mozconfig.out; \
 	  rm -f .mozconfig.out; \
 	else true; \
 	fi
 
 # Windows equivalents
 build_all: build
@@ -202,38 +204,38 @@ everything: clean build
 #  application until all the build passes and postflight scripts have run.
 ifdef MOZ_OBJDIR
   PGO_OBJDIR = $(MOZ_OBJDIR)
 else
   PGO_OBJDIR := $(TOPSRCDIR)
 endif
 
 profiledbuild::
-	$(MAKE) -f $(TOPSRCDIR)/client.mk build MOZ_PROFILE_GENERATE=1
+	$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_GENERATE=1
 	$(MAKE) -C $(PGO_OBJDIR) package
 	OBJDIR=${PGO_OBJDIR} $(PROFILE_GEN_SCRIPT)
 	$(MAKE) -f $(TOPSRCDIR)/client.mk maybe_clobber_profiledbuild
-	$(MAKE) -f $(TOPSRCDIR)/client.mk build MOZ_PROFILE_USE=1
+	$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_USE=1
 
 #####################################################
 # Build date unification
 
 ifdef MOZ_UNIFY_BDATE
 ifndef MOZ_BUILD_DATE
 ifdef MOZ_BUILD_PROJECTS
 MOZ_BUILD_DATE = $(shell $(PYTHON) $(TOPSRCDIR)/toolkit/xre/make-platformini.py --print-buildid)
 export MOZ_BUILD_DATE
 endif
 endif
 endif
 
 #####################################################
 # Preflight, before building any project
 
-build alldep preflight_all::
+realbuild alldep preflight_all::
 ifeq (,$(MOZ_CURRENT_PROJECT)$(if $(MOZ_PREFLIGHT_ALL),,1))
 # Don't run preflight_all for individual projects in multi-project builds
 # (when MOZ_CURRENT_PROJECT is set.)
 ifndef MOZ_BUILD_PROJECTS
 # Building a single project, OBJDIR is usable.
 	set -e; \
 	for mkfile in $(MOZ_PREFLIGHT_ALL); do \
 	  $(MAKE) -f $(TOPSRCDIR)/$$mkfile preflight_all TOPSRCDIR=$(TOPSRCDIR) OBJDIR=$(OBJDIR) MOZ_OBJDIR=$(MOZ_OBJDIR); \
@@ -247,17 +249,17 @@ else
 	done
 endif
 endif
 
 # If we're building multiple projects, but haven't specified which project,
 # loop through them.
 
 ifeq (,$(MOZ_CURRENT_PROJECT)$(if $(MOZ_BUILD_PROJECTS),,1))
-configure depend build install export libs clean realclean distclean alldep preflight postflight maybe_clobber_profiledbuild upload sdk::
+configure depend realbuild install export libs clean realclean distclean alldep preflight postflight maybe_clobber_profiledbuild upload sdk::
 	set -e; \
 	for app in $(MOZ_BUILD_PROJECTS); do \
 	  $(MAKE) -f $(TOPSRCDIR)/client.mk $@ MOZ_CURRENT_PROJECT=$$app; \
 	done
 
 else
 
 # MOZ_CURRENT_PROJECT: either doing a single-project build, or building an
@@ -327,54 +329,54 @@ endif
 # Depend
 
 depend:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
 	$(MOZ_MAKE) export && $(MOZ_MAKE) depend
 
 ####################################
 # Preflight
 
-build alldep preflight::
+realbuild alldep preflight::
 ifdef MOZ_PREFLIGHT
 	set -e; \
 	for mkfile in $(MOZ_PREFLIGHT); do \
 	  $(MAKE) -f $(TOPSRCDIR)/$$mkfile preflight TOPSRCDIR=$(TOPSRCDIR) OBJDIR=$(OBJDIR) MOZ_OBJDIR=$(MOZ_OBJDIR); \
 	done
 endif
 
 ####################################
 # Build it
 
-build::  $(OBJDIR)/Makefile $(OBJDIR)/config.status
+realbuild::  $(OBJDIR)/Makefile $(OBJDIR)/config.status
 	$(MOZ_MAKE)
 
 ####################################
 # Other targets
 
 # Pass these target onto the real build system
 install export libs clean realclean distclean alldep maybe_clobber_profiledbuild upload sdk:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
 	$(MOZ_MAKE) $@
 
 ####################################
 # Postflight
 
-build alldep postflight::
+realbuild alldep postflight::
 ifdef MOZ_POSTFLIGHT
 	set -e; \
 	for mkfile in $(MOZ_POSTFLIGHT); do \
 	  $(MAKE) -f $(TOPSRCDIR)/$$mkfile postflight TOPSRCDIR=$(TOPSRCDIR) OBJDIR=$(OBJDIR) MOZ_OBJDIR=$(MOZ_OBJDIR); \
 	done
 endif
 
 endif # MOZ_CURRENT_PROJECT
 
 ####################################
 # Postflight, after building all projects
 
-build alldep postflight_all::
+realbuild alldep postflight_all::
 ifeq (,$(MOZ_CURRENT_PROJECT)$(if $(MOZ_POSTFLIGHT_ALL),,1))
 # Don't run postflight_all for individual projects in multi-project builds
 # (when MOZ_CURRENT_PROJECT is set.)
 ifndef MOZ_BUILD_PROJECTS
 # Building a single project, OBJDIR is usable.
 	set -e; \
 	for mkfile in $(MOZ_POSTFLIGHT_ALL); do \
 	  $(MAKE) -f $(TOPSRCDIR)/$$mkfile postflight_all TOPSRCDIR=$(TOPSRCDIR) OBJDIR=$(OBJDIR) MOZ_OBJDIR=$(MOZ_OBJDIR); \
@@ -404,9 +406,9 @@ cleansrcdir:
 echo-variable-%:
 	@echo $($*)
 
 # This makefile doesn't support parallel execution. It does pass
 # MOZ_MAKE_FLAGS to sub-make processes, so they will correctly execute
 # in parallel.
 .NOTPARALLEL:
 
-.PHONY: checkout real_checkout depend build profiledbuild maybe_clobber_profiledbuild export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything configure preflight_all preflight postflight postflight_all upload sdk
+.PHONY: checkout real_checkout depend realbuild build profiledbuild maybe_clobber_profiledbuild export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything configure preflight_all preflight postflight postflight_all upload sdk
--- a/config/expandlibs.py
+++ b/config/expandlibs.py
@@ -58,16 +58,39 @@ given a list of files, expandlibs will r
   replace ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} with the OBJS and LIBS the
   descriptor contains. And for each of these LIBS, also apply the same
   rules.
 '''
 from __future__ import with_statement
 import sys, os
 import expandlibs_config as conf
 
+def relativize(path):
+    '''Returns a path relative to the current working directory, if it is
+    shorter than the given path'''
+    def splitpath(path):
+        dir, file = os.path.split(path)
+        if os.path.splitdrive(dir)[1] == os.sep:
+            return [file]
+        return splitpath(dir) + [file]
+
+    if not os.path.exists(path):
+        return path
+    curdir = splitpath(os.path.abspath(os.curdir))
+    abspath = splitpath(os.path.abspath(path))
+    while curdir and abspath and curdir[0] == abspath[0]:
+        del curdir[0]
+        del abspath[0]
+    if not curdir and not abspath:
+        return '.'
+    relpath = os.path.join(*[os.pardir for i in curdir] + abspath)
+    if len(path) > len(relpath):
+        return relpath
+    return path
+
 class LibDescriptor(dict):
     KEYS = ['OBJS', 'LIBS']
 
     def __init__(self, content=None):
         '''Creates an instance of a lib descriptor, initialized with contents
         from a list of strings when given. This is intended for use with
         file.readlines()'''
         if isinstance(content, list) and all([isinstance(item, str) for item in content]):
@@ -94,32 +117,32 @@ class ExpandArgs(list):
         super(ExpandArgs, self).__init__()
         for arg in args:
             self += self._expand(arg)
 
     def _expand(self, arg):
         '''Internal function doing the actual work'''
         (root, ext) = os.path.splitext(arg)
         if ext != conf.LIB_SUFFIX or not os.path.basename(root).startswith(conf.LIB_PREFIX):
-            return [arg]
+            return [relativize(arg)]
         if len(conf.IMPORT_LIB_SUFFIX):
             dll = root + conf.IMPORT_LIB_SUFFIX
         else:
             dll = root.replace(conf.LIB_PREFIX, conf.DLL_PREFIX, 1) + conf.DLL_SUFFIX
         if os.path.exists(dll):
-            return [dll]
+            return [relativize(dll)]
         if os.path.exists(arg):
-            return [arg]
+            return [relativize(arg)]
         return self._expand_desc(arg)
 
     def _expand_desc(self, arg):
         '''Internal function taking care of lib descriptor expansion only'''
         if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
             with open(arg + conf.LIBS_DESC_SUFFIX, 'r') as f:
                 desc = LibDescriptor(f.readlines())
-            objs = desc['OBJS']
+            objs = [relativize(o) for o in desc['OBJS']]
             for lib in desc['LIBS']:
                 objs += self._expand(lib)
             return objs
         return [arg]
 
 if __name__ == '__main__':
     print " ".join(ExpandArgs(sys.argv[1:]))
--- a/config/expandlibs_exec.py
+++ b/config/expandlibs_exec.py
@@ -47,17 +47,17 @@ files with a list file. This can be used
 of a command line. The kind of list file format used depends on the
 EXPAND_LIBS_LIST_STYLE variable: 'list' for MSVC style lists (@file.list)
 or 'linkerscript' for GNU ld linker scripts.
 See https://bugzilla.mozilla.org/show_bug.cgi?id=584474#c59 for more details.
 '''
 from __future__ import with_statement
 import sys
 import os
-from expandlibs import ExpandArgs
+from expandlibs import ExpandArgs, relativize
 import expandlibs_config as conf
 from optparse import OptionParser
 import subprocess
 import tempfile
 import shutil
 
 class ExpandArgsMore(ExpandArgs):
     ''' Meant to be used as 'with ExpandArgsMore(args) as ...: '''
@@ -88,17 +88,17 @@ class ExpandArgsMore(ExpandArgs):
                 if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
                     newlist += self._extract(self._expand_desc(arg))
                 elif os.path.exists(arg) and len(ar_extract):
                     tmp = tempfile.mkdtemp(dir=os.curdir)
                     self.tmp.append(tmp)
                     subprocess.call(ar_extract + [os.path.abspath(arg)], cwd=tmp)
                     objs = []
                     for root, dirs, files in os.walk(tmp):
-                        objs += [os.path.join(root, f) for f in files if os.path.splitext(f)[1] == conf.OBJ_SUFFIX]
+                        objs += [relativize(os.path.join(root, f)) for f in files if os.path.splitext(f)[1] == conf.OBJ_SUFFIX]
                     newlist += objs
                 else:
                     newlist += [arg]
             else:
                 newlist += [arg]
         return newlist
 
     def makelist(self):
--- a/config/tests/unit-expandlibs.py
+++ b/config/tests/unit-expandlibs.py
@@ -2,16 +2,17 @@ from __future__ import with_statement
 import subprocess
 import unittest
 import sys
 import os
 import imp
 from tempfile import mkdtemp
 from shutil import rmtree
 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+from mozunit import MozTestRunner
 
 from UserString import UserString
 # Create a controlled configuration for use by expandlibs
 config_win = {
     'AR_EXTRACT': '',
     'DLL_PREFIX': '',
     'LIB_PREFIX': '',
     'OBJ_SUFFIX': '.obj',
@@ -30,33 +31,48 @@ config_unix = {
     'DLL_SUFFIX': '.so',
     'IMPORT_LIB_SUFFIX': '',
     'LIBS_DESC_SUFFIX': '.desc',
     'EXPAND_LIBS_LIST_STYLE': 'linkerscript',
 }
 
 config = sys.modules['expandlibs_config'] = imp.new_module('expandlibs_config')
 
-from expandlibs import LibDescriptor, ExpandArgs
+from expandlibs import LibDescriptor, ExpandArgs, relativize
 from expandlibs_gen import generate
 from expandlibs_exec import ExpandArgsMore
 
 def Lib(name):
     return config.LIB_PREFIX + name + config.LIB_SUFFIX
 
 def Obj(name):
     return name + config.OBJ_SUFFIX
 
 def Dll(name):
     return config.DLL_PREFIX + name + config.DLL_SUFFIX
 
 def ImportLib(name):
     if not len(config.IMPORT_LIB_SUFFIX): return Dll(name)
     return config.LIB_PREFIX + name + config.IMPORT_LIB_SUFFIX
 
+class TestRelativize(unittest.TestCase):
+    def test_relativize(self):
+        '''Test relativize()'''
+        os_path_exists = os.path.exists
+        def exists(path):
+            return True
+        os.path.exists = exists
+        self.assertEqual(relativize(os.path.abspath(os.curdir)), os.curdir)
+        self.assertEqual(relativize(os.path.abspath(os.pardir)), os.pardir)
+        self.assertEqual(relativize(os.path.join(os.curdir, 'a')), 'a')
+        self.assertEqual(relativize(os.path.join(os.path.abspath(os.curdir), 'a')), 'a')
+        # relativize is expected to return the absolute path if it is shorter
+        self.assertEqual(relativize(os.sep), os.sep)
+        os.path.exists = os.path.exists
+
 class TestLibDescriptor(unittest.TestCase):
     def test_serialize(self):
         '''Test LibDescriptor's serialization'''
         desc = LibDescriptor()
         desc[LibDescriptor.KEYS[0]] = ['a', 'b']
         self.assertEqual(str(desc), "%s = a b" % LibDescriptor.KEYS[0])
         desc['unsupported-key'] = ['a']
         self.assertEqual(str(desc), "%s = a b" % LibDescriptor.KEYS[0])
@@ -78,35 +94,39 @@ class TestLibDescriptor(unittest.TestCas
         self.assertEqual(False, 'foo' in desc)
 
 def wrap_method(conf, wrapped_method):
     '''Wrapper used to call a test with a specific configuration'''
     def _method(self):
         for key in conf:
             setattr(config, key, conf[key])
         self.init()
-        wrapped_method(self)
-        self.cleanup()
+        try:
+            wrapped_method(self)
+        except:
+            raise
+        finally:
+            self.cleanup()
     return _method
 
 class ReplicateTests(type):
     '''Replicates tests for unix and windows variants'''
     def __new__(cls, clsName, bases, dict):
         for name in [key for key in dict if key.startswith('test_')]:
             dict[name + '_unix'] = wrap_method(config_unix, dict[name])
             dict[name + '_unix'].__doc__ = dict[name].__doc__ + ' (unix)'
             dict[name + '_win'] = wrap_method(config_win, dict[name])
             dict[name + '_win'].__doc__ = dict[name].__doc__ + ' (win)'
             del dict[name]
         return type.__new__(cls, clsName, bases, dict)
 
 class TestCaseWithTmpDir(unittest.TestCase):
     __metaclass__ = ReplicateTests
     def init(self):
-        self.tmpdir = mkdtemp()
+        self.tmpdir = os.path.abspath(mkdtemp(dir=os.curdir))
 
     def cleanup(self):
         rmtree(self.tmpdir)
 
     def touch(self, files):
         for f in files:
             open(f, 'w').close()
 
@@ -144,104 +164,108 @@ class TestExpandInit(TestCaseWithTmpDir)
         # Create various objects and libraries 
         self.arg_files = [self.tmpfile(f) for f in [Lib('a'), Obj('b'), Obj('c'), Lib('d'), Obj('e')]]
         # We always give library names (LIB_PREFIX/SUFFIX), even for
         # dynamic/import libraries
         self.files = self.arg_files + [self.tmpfile(ImportLib('f'))]
         self.arg_files += [self.tmpfile(Lib('f'))]
         self.touch(self.files)
 
+    def assertRelEqual(self, args1, args2):
+        self.assertEqual(args1, [relativize(a) for a in args2])
+
 class TestExpandArgs(TestExpandInit):
     def test_expand(self):
         '''Test library expansion'''
         # Expanding arguments means libraries with a descriptor are expanded
         # with the descriptor content, and import libraries are used when
         # a library doesn't exist
         args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
-        self.assertEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 
+        self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 
 
         # When a library exists at the same time as a descriptor, we just use
         # the library
         self.touch([self.tmpfile('libx', Lib('x'))])
         args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
-        self.assertEqual(args, ['foo', '-bar'] + self.files + self.liby_files + [self.tmpfile('libx', Lib('x'))]) 
+        self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + [self.tmpfile('libx', Lib('x'))]) 
 
         self.touch([self.tmpfile('liby', Lib('y'))])
         args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
-        self.assertEqual(args, ['foo', '-bar'] + self.files + [self.tmpfile('liby', Lib('y'))])
+        self.assertRelEqual(args, ['foo', '-bar'] + self.files + [self.tmpfile('liby', Lib('y'))])
 
 class TestExpandArgsMore(TestExpandInit):
     def test_makelist(self):
         '''Test grouping object files in lists'''
         # ExpandArgsMore does the same as ExpandArgs
         with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
-            self.assertEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 
+            self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 
 
             # But also has an extra method replacing object files with a list
             args.makelist()
             # self.files has objects at #1, #2, #4
-            self.assertEqual(args[:3], ['foo', '-bar'] + self.files[:1])
-            self.assertEqual(args[4:], [self.files[3]] + self.files[5:] + [self.tmpfile('liby', Lib('z'))])
+            self.assertRelEqual(args[:3], ['foo', '-bar'] + self.files[:1])
+            self.assertRelEqual(args[4:], [self.files[3]] + self.files[5:] + [self.tmpfile('liby', Lib('z'))])
 
             # Check the list file content
             objs = [f for f in self.files + self.liby_files + self.libx_files if f.endswith(config.OBJ_SUFFIX)]
             if config.EXPAND_LIBS_LIST_STYLE == "linkerscript":
                 self.assertNotEqual(args[3][0], '@')
                 filename = args[3]
-                content = ["INPUT(%s)" % f for f in objs]
+                content = ["INPUT(%s)" % relativize(f) for f in objs]
+                with open(filename, 'r') as f:
+                    self.assertEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
             elif config.EXPAND_LIBS_LIST_STYLE == "list":
                 self.assertEqual(args[3][0], '@')
                 filename = args[3][1:]
                 content = objs
-
-            with open(filename, 'r') as f:
-                self.assertEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
+                with open(filename, 'r') as f:
+                    self.assertRelEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
 
             tmp = args.tmp
         # Check that all temporary files are properly removed
         self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))
 
     def test_extract(self):
         '''Test library extraction'''
         # Divert subprocess.call
         subprocess_call = subprocess.call
         extracted = {}
         def call(args, **kargs):
             # The command called is always AR_EXTRACT
             ar_extract = config.AR_EXTRACT.split()
-            self.assertEqual(args[:len(ar_extract)], ar_extract)
+            self.assertRelEqual(args[:len(ar_extract)], ar_extract)
             # Remaining argument is always one library
-            self.assertEqual([os.path.splitext(arg)[1] for arg in args[len(ar_extract):]], [config.LIB_SUFFIX])
+            self.assertRelEqual([os.path.splitext(arg)[1] for arg in args[len(ar_extract):]], [config.LIB_SUFFIX])
             # Simulate AR_EXTRACT extracting one object file for the library
             lib = os.path.splitext(os.path.basename(args[len(ar_extract)]))[0]
             extracted[lib] = os.path.join(kargs['cwd'], "%s" % Obj(lib))
             self.touch([extracted[lib]])
         subprocess.call = call
 
         # ExpandArgsMore does the same as ExpandArgs
         self.touch([self.tmpfile('liby', Lib('y'))])
         with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
-            self.assertEqual(args, ['foo', '-bar'] + self.files + [self.tmpfile('liby', Lib('y'))])
+            self.assertRelEqual(args, ['foo', '-bar'] + self.files + [self.tmpfile('liby', Lib('y'))])
 
             # ExpandArgsMore also has an extra method extracting static libraries
             # when possible
             args.extract()
 
             files = self.files + self.liby_files + self.libx_files
             if not len(config.AR_EXTRACT):
                 # If we don't have an AR_EXTRACT, extract() expands libraries with a
                 # descriptor when the corresponding library exists (which ExpandArgs
                 # alone doesn't)
-                self.assertEqual(args, ['foo', '-bar'] + files)
+                self.assertRelEqual(args, ['foo', '-bar'] + files)
             else:
                 # With AR_EXTRACT, it uses the descriptors when there are, and actually
                 # extracts the remaining libraries
-                self.assertEqual(args, ['foo', '-bar'] + [extracted[os.path.splitext(os.path.basename(f))[0]] if f.endswith(config.LIB_SUFFIX) else f for f in files])
+                self.assertRelEqual(args, ['foo', '-bar'] + [extracted[os.path.splitext(os.path.basename(f))[0]] if f.endswith(config.LIB_SUFFIX) else f for f in files])
 
             tmp = args.tmp
         # Check that all temporary files are properly removed
         self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))
 
         # Restore subprocess.call
         subprocess.call = subprocess_call
 
 if __name__ == '__main__':
-    unittest.main()
+    unittest.main(testRunner=MozTestRunner())
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -3233,48 +3233,64 @@ nsDocument::doCreateShell(nsPresContext*
   rv = shell->Init(this, aContext, aViewManager, aStyleSet, aCompatMode);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Note: we don't hold a ref to the shell (it holds a ref to us)
   mPresShell = shell;
 
   mExternalResourceMap.ShowViewers();
 
+  if (mScriptGlobalObject) {
+    RescheduleAnimationFrameNotifications();
+  }
+
+  shell.swap(*aInstancePtrResult);
+
+  return NS_OK;
+}
+
+void
+nsDocument::RescheduleAnimationFrameNotifications()
+{
   nsRefreshDriver* rd = mPresShell->GetPresContext()->RefreshDriver();
   if (mHavePendingPaint) {
     rd->ScheduleBeforePaintEvent(this);
   }
   if (!mAnimationFrameListeners.IsEmpty()) {
     rd->ScheduleAnimationFrameListeners(this);
   }
-
-  shell.swap(*aInstancePtrResult);
-
-  return NS_OK;
 }
 
 void
 nsIDocument::TakeAnimationFrameListeners(AnimationListenerList& aListeners)
 {
   aListeners.AppendElements(mAnimationFrameListeners);
   mAnimationFrameListeners.Clear();
 }
 
 void
 nsDocument::DeleteShell()
 {
   mExternalResourceMap.HideViewers();
+  if (mScriptGlobalObject) {
+    RevokeAnimationFrameNotifications();
+  }
+  mPresShell = nsnull;
+}
+
+void
+nsDocument::RevokeAnimationFrameNotifications()
+{
   if (mHavePendingPaint) {
     mPresShell->GetPresContext()->RefreshDriver()->RevokeBeforePaintEvent(this);
   }
   if (!mAnimationFrameListeners.IsEmpty()) {
     mPresShell->GetPresContext()->RefreshDriver()->
       RevokeAnimationFrameListeners(this);
   }
-  mPresShell = nsnull;
 }
 
 static void
 SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
 {
   SubDocMapEntry *e = static_cast<SubDocMapEntry *>(entry);
 
   NS_RELEASE(e->mKey);
@@ -3786,16 +3802,20 @@ nsDocument::SetScriptGlobalObject(nsIScr
                     "Clearing window pointer while animations are unpaused");
 #endif // MOZ_SMIL
 
   if (mScriptGlobalObject && !aScriptGlobalObject) {
     // We're detaching from the window.  We need to grab a pointer to
     // our layout history state now.
     mLayoutHistoryState = GetLayoutHistoryState();
 
+    if (mPresShell) {
+      RevokeAnimationFrameNotifications();
+    }
+
     // Also make sure to remove our onload blocker now if we haven't done it yet
     if (mOnloadBlockCount != 0) {
       nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
       if (loadGroup) {
         loadGroup->RemoveRequest(mOnloadBlocker, nsnull, NS_OK);
       }
     }
   }
@@ -3842,16 +3862,20 @@ nsDocument::SetScriptGlobalObject(nsIScr
         NS_ASSERTION(SameCOMIdentity(webNav, docShell),
                      "Unexpected container or script global?");
 #endif
         PRBool allowDNSPrefetch;
         docShell->GetAllowDNSPrefetch(&allowDNSPrefetch);
         mAllowDNSPrefetch = allowDNSPrefetch;
       }
     }
+
+    if (mPresShell) {
+      RescheduleAnimationFrameNotifications();
+    }
   }
 
   // Remember the pointer to our window (or lack there of), to avoid
   // having to QI every time it's asked for.
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mScriptGlobalObject);
   mWindow = window;
 }
 
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -1202,16 +1202,21 @@ private:
     CheckAncestryAndGetFrame(nsIDocument* aDocument) const;
 
   // Just like EnableStyleSheetsForSet, but doesn't check whether
   // aSheetSet is null and allows the caller to control whether to set
   // aSheetSet as the preferred set in the CSSLoader.
   void EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
                                        PRBool aUpdateCSSLoader);
 
+  // Revoke any pending notifications due to mozRequestAnimationFrame calls
+  void RevokeAnimationFrameNotifications();
+  // Reschedule any notifications we need to handle mozRequestAnimationFrame
+  void RescheduleAnimationFrameNotifications();
+
   // These are not implemented and not supported.
   nsDocument(const nsDocument& aOther);
   nsDocument& operator=(const nsDocument& aOther);
 
   nsCOMPtr<nsISupports> mXPathEvaluatorTearoff;
 
   // The layout history state that should be used by nodes in this
   // document.  We only actually store a pointer to it when:
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -622,20 +622,19 @@ nsFrameScriptExecutor::LoadFrameScriptIn
     nsContentUtils::ThreadJSContextStack()->Push(mCx);
     {
       // Need to scope JSAutoRequest to happen after Push but before Pop,
       // at least for now. See bug 584673.
       JSAutoRequest ar(mCx);
       JSObject* global = nsnull;
       mGlobal->GetJSObject(&global);
       if (global) {
-        jsval val;
         JS_ExecuteScript(mCx, global,
                          (JSScript*)JS_GetPrivate(mCx, holder->mObject),
-                         &val);
+                         nsnull);
       }
     }
     JSContext* unused;
     nsContentUtils::ThreadJSContextStack()->Pop(&unused);
     return;
   }
 
   nsCString url = NS_ConvertUTF16toUTF8(aURL);
@@ -677,39 +676,44 @@ nsFrameScriptExecutor::LoadFrameScriptIn
       // at least for now. See bug 584673.
       JSAutoRequest ar(mCx);
       JSObject* global = nsnull;
       mGlobal->GetJSObject(&global);
       if (global) {
         JSPrincipals* jsprin = nsnull;
         mPrincipal->GetJSPrincipals(mCx, &jsprin);
         nsContentUtils::XPConnect()->FlagSystemFilenamePrefix(url.get(), PR_TRUE);
+
+        uint32 oldopts = JS_GetOptions(mCx);
+        JS_SetOptions(mCx, oldopts | JSOPTION_NO_SCRIPT_RVAL);
+
         JSScript* script =
           JS_CompileUCScriptForPrincipals(mCx, nsnull, jsprin,
                                          (jschar*)dataString.get(),
                                           dataString.Length(),
                                           url.get(), 1);
 
+        JS_SetOptions(mCx, oldopts);
+
         if (script) {
           JSObject* scriptObj = JS_NewScriptObject(mCx, script);
           JS_AddObjectRoot(mCx, &scriptObj);
           nsCAutoString scheme;
           uri->GetScheme(scheme);
           // We don't cache data: scripts!
           if (!scheme.EqualsLiteral("data")) {
             nsFrameScriptExecutorJSObjectHolder* holder =
               new nsFrameScriptExecutorJSObjectHolder(scriptObj);
             // Root the object also for caching.
             JS_AddNamedObjectRoot(mCx, &(holder->mObject),
                                   "Cached message manager script");
             sCachedScripts->Put(aURL, holder);
           }
-          jsval val;
           JS_ExecuteScript(mCx, global,
-                           (JSScript*)JS_GetPrivate(mCx, scriptObj), &val);
+                           (JSScript*)JS_GetPrivate(mCx, scriptObj), nsnull);
           JS_RemoveObjectRoot(mCx, &scriptObj);
         }
         //XXX Argh, JSPrincipals are manually refcounted!
         JSPRINCIPALS_DROP(mCx, jsprin);
       }
     } 
     JSContext* unused;
     nsContentUtils::ThreadJSContextStack()->Pop(&unused);
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1606,16 +1606,17 @@ GK_ATOM(bcTableCellFrame, "BCTableCellFr
 GK_ATOM(blockFrame, "BlockFrame")
 GK_ATOM(boxFrame, "BoxFrame")
 GK_ATOM(brFrame, "BRFrame")
 GK_ATOM(bulletFrame, "BulletFrame")
 GK_ATOM(columnSetFrame, "ColumnSetFrame")
 GK_ATOM(comboboxControlFrame, "ComboboxControlFrame")
 GK_ATOM(comboboxDisplayFrame, "ComboboxDisplayFrame")
 GK_ATOM(deckFrame, "DeckFrame")
+GK_ATOM(directionalFrame, "DirectionalFrame")
 GK_ATOM(fieldSetFrame, "FieldSetFrame")
 GK_ATOM(frameSetFrame, "FrameSetFrame")
 GK_ATOM(gfxButtonControlFrame, "gfxButtonControlFrame")
 GK_ATOM(HTMLButtonControlFrame, "HTMLButtonControlFrame")
 GK_ATOM(HTMLCanvasFrame, "HTMLCanvasFrame")
 GK_ATOM(subDocumentFrame, "subDocumentFrame")
 GK_ATOM(imageBoxFrame, "ImageBoxFrame")
 GK_ATOM(imageFrame, "ImageFrame")
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -121,29 +121,26 @@
 #define XML_HTTP_REQUEST_COMPLETED      (1 << 4)  // 4
 #define XML_HTTP_REQUEST_SENT           (1 << 5)  // Internal, LOADING in IE and external view
 #define XML_HTTP_REQUEST_STOPPED        (1 << 6)  // Internal, INTERACTIVE in IE and external view
 // The above states are mutually exclusive, change with ChangeState() only.
 // The states below can be combined.
 #define XML_HTTP_REQUEST_ABORTED        (1 << 7)  // Internal
 #define XML_HTTP_REQUEST_ASYNC          (1 << 8)  // Internal
 #define XML_HTTP_REQUEST_PARSEBODY      (1 << 9)  // Internal
-#define XML_HTTP_REQUEST_XSITEENABLED   (1 << 10) // Internal, Is any cross-site request allowed?
-                                                  //           Even if this is false the
-                                                  //           access-control spec is supported
-#define XML_HTTP_REQUEST_SYNCLOOPING    (1 << 11) // Internal
-#define XML_HTTP_REQUEST_MULTIPART      (1 << 12) // Internal
-#define XML_HTTP_REQUEST_GOT_FINAL_STOP (1 << 13) // Internal
-#define XML_HTTP_REQUEST_BACKGROUND     (1 << 14) // Internal
+#define XML_HTTP_REQUEST_SYNCLOOPING    (1 << 10) // Internal
+#define XML_HTTP_REQUEST_MULTIPART      (1 << 11) // Internal
+#define XML_HTTP_REQUEST_GOT_FINAL_STOP (1 << 12) // Internal
+#define XML_HTTP_REQUEST_BACKGROUND     (1 << 13) // Internal
 // This is set when we've got the headers for a multipart XMLHttpRequest,
 // but haven't yet started to process the first part.
-#define XML_HTTP_REQUEST_MPART_HEADERS  (1 << 15) // Internal
-#define XML_HTTP_REQUEST_USE_XSITE_AC   (1 << 16) // Internal
-#define XML_HTTP_REQUEST_NEED_AC_PREFLIGHT (1 << 17) // Internal
-#define XML_HTTP_REQUEST_AC_WITH_CREDENTIALS (1 << 18) // Internal
+#define XML_HTTP_REQUEST_MPART_HEADERS  (1 << 14) // Internal
+#define XML_HTTP_REQUEST_USE_XSITE_AC   (1 << 15) // Internal
+#define XML_HTTP_REQUEST_NEED_AC_PREFLIGHT (1 << 16) // Internal
+#define XML_HTTP_REQUEST_AC_WITH_CREDENTIALS (1 << 17) // Internal
 
 #define XML_HTTP_REQUEST_LOADSTATES         \
   (XML_HTTP_REQUEST_UNINITIALIZED |         \
    XML_HTTP_REQUEST_OPENED |                \
    XML_HTTP_REQUEST_LOADED |                \
    XML_HTTP_REQUEST_INTERACTIVE |           \
    XML_HTTP_REQUEST_COMPLETED |             \
    XML_HTTP_REQUEST_SENT |                  \
@@ -1634,24 +1631,22 @@ nsXMLHttpRequest::GetCurrentHttpChannel(
   }
 
   return httpChannel;
 }
 
 nsresult
 nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
 {
-  // First check if cross-site requests are enabled
-  if ((mState & XML_HTTP_REQUEST_XSITEENABLED)) {
+  // First check if cross-site requests are enabled...
+  if (IsSystemXHR()) {
     return NS_OK;
   }
 
-  // or if this is a same-origin request.
-  NS_ASSERTION(!nsContentUtils::IsSystemPrincipal(mPrincipal),
-               "Shouldn't get here!");
+  // ...or if this is a same-origin request.
   if (nsContentUtils::CheckMayLoad(mPrincipal, aChannel)) {
     return NS_OK;
   }
 
   // This is a cross-site request
   mState |= XML_HTTP_REQUEST_USE_XSITE_AC;
 
   // Check if we need to do a preflight request.
@@ -1792,22 +1787,16 @@ nsXMLHttpRequest::OpenRequest(const nsAC
                      uri,
                      nsnull,                    // ioService
                      loadGroup,
                      nsnull,                    // callbacks
                      nsIRequest::LOAD_BACKGROUND,
                      channelPolicy);
   if (NS_FAILED(rv)) return rv;
 
-  // Check if we're doing a cross-origin request.
-  if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
-    // Chrome callers are always allowed to read from different origins.
-    mState |= XML_HTTP_REQUEST_XSITEENABLED;
-  }
-
   mState &= ~(XML_HTTP_REQUEST_USE_XSITE_AC |
               XML_HTTP_REQUEST_NEED_AC_PREFLIGHT);
 
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
   if (httpChannel) {
     rv = httpChannel->SetRequestMethod(method);
     NS_ENSURE_SUCCESS(rv, rv);
   }
@@ -1818,27 +1807,16 @@ nsXMLHttpRequest::OpenRequest(const nsAC
 }
 
 /* void open (in AUTF8String method, in AUTF8String url); */
 NS_IMETHODIMP
 nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url,
                        PRBool async, const nsAString& user,
                        const nsAString& password, PRUint8 optional_argc)
 {
-  if (nsContentUtils::GetCurrentJSContext()) {
-    // We're (likely) called from JS
-
-    // Find out if UniversalBrowserRead privileges are enabled
-    if (nsContentUtils::IsCallerTrustedForRead()) {
-      mState |= XML_HTTP_REQUEST_XSITEENABLED;
-    } else {
-      mState &= ~XML_HTTP_REQUEST_XSITEENABLED;
-    }
-  }
-
   if (!optional_argc) {
     // No optional arguments were passed in. Default async to true.
     async = PR_TRUE;
   }
 
   return OpenRequest(method, url, async, user, password);
 }
 
@@ -1949,25 +1927,27 @@ nsXMLHttpRequest::OnStartRequest(nsIRequ
     NS_ERROR("Ugh, still getting data on an aborted XMLHttpRequest!");
 
     return NS_ERROR_UNEXPECTED;
   }
 
   nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
   NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED);
 
-  nsCOMPtr<nsIPrincipal> documentPrincipal = mPrincipal;
-  if (nsContentUtils::IsSystemPrincipal(documentPrincipal)) {
+  nsCOMPtr<nsIPrincipal> documentPrincipal;
+  if (IsSystemXHR()) {
     // Don't give this document the system principal.  We need to keep track of
     // mPrincipal being system because we use it for various security checks
     // that should be passing, but the document data shouldn't get a system
     // principal.
     nsresult rv;
     documentPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
     NS_ENSURE_SUCCESS(rv, rv);
+  } else {
+    documentPrincipal = mPrincipal;
   }
 
   channel->SetOwner(documentPrincipal);
 
   mReadRequest = request;
   mContext = ctxt;
   mState |= XML_HTTP_REQUEST_PARSEBODY;
   mState &= ~XML_HTTP_REQUEST_MPART_HEADERS;
@@ -2035,17 +2015,17 @@ nsXMLHttpRequest::OnStartRequest(nsIRequ
     nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(mOwner);
     rv = nsContentUtils::CreateDocument(emptyStr, emptyStr, nsnull, docURI,
                                         baseURI, mPrincipal, global,
                                         getter_AddRefs(mResponseXML));
     NS_ENSURE_SUCCESS(rv, rv);
     nsCOMPtr<nsIDocument> responseDoc = do_QueryInterface(mResponseXML);
     responseDoc->SetPrincipal(documentPrincipal);
 
-    if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
+    if (IsSystemXHR()) {
       responseDoc->ForceEnableXULXBL();
     }
 
     if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
       nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mResponseXML);
       if (htmlDoc) {
         htmlDoc->DisableCookieAccess();
       }
@@ -2415,17 +2395,17 @@ nsXMLHttpRequest::Send(nsIVariant *aBody
   // Ignore argument if method is GET, there is no point in trying to
   // upload anything
   nsCAutoString method;
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
 
   if (httpChannel) {
     httpChannel->GetRequestMethod(method); // If GET, method name will be uppercase
 
-    if (!nsContentUtils::IsSystemPrincipal(mPrincipal)) {
+    if (!IsSystemXHR()) {
       // Get the referrer for the request.
       //
       // If it weren't for history.push/replaceState, we could just use the
       // principal's URI here.  But since we want changes to the URI effected
       // by push/replaceState to be reflected in the XHR referrer, we have to
       // be more clever.
       //
       // If the document's original URI (before any push/replaceStates) matches
@@ -2651,17 +2631,17 @@ nsXMLHttpRequest::Send(nsIVariant *aBody
   nsCOMPtr<nsIStreamListener> listener = this;
   if (mState & XML_HTTP_REQUEST_MULTIPART) {
     listener = new nsMultipartProxyListener(listener);
     if (!listener) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
-  if (!(mState & XML_HTTP_REQUEST_XSITEENABLED)) {
+  if (!IsSystemXHR()) {
     // Always create a nsCrossSiteListenerProxy here even if it's
     // a same-origin request right now, since it could be redirected.
     listener = new nsCrossSiteListenerProxy(listener, mPrincipal, mChannel,
                                             withCredentials, &rv);
     NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
@@ -2848,26 +2828,26 @@ nsXMLHttpRequest::SetRequestHeader(const
                          nsCaseInsensitiveCStringComparator()) ||
         StringBeginsWith(header, NS_LITERAL_CSTRING("sec-"),
                          nsCaseInsensitiveCStringComparator())) {
       NS_WARNING("refusing to set request header");
       return NS_OK;
     }
 
     // Check for dangerous cross-site headers
-    PRBool safeHeader = !!(mState & XML_HTTP_REQUEST_XSITEENABLED);
+    bool safeHeader = IsSystemXHR();
     if (!safeHeader) {
       // Content-Type isn't always safe, but we'll deal with it in Send()
       const char *kCrossOriginSafeHeaders[] = {
         "accept", "accept-language", "content-language", "content-type",
         "last-event-id"
       };
       for (i = 0; i < NS_ARRAY_LENGTH(kCrossOriginSafeHeaders); ++i) {
         if (header.LowerCaseEqualsASCII(kCrossOriginSafeHeaders[i])) {
-          safeHeader = PR_TRUE;
+          safeHeader = true;
           break;
         }
       }
     }
 
     if (!safeHeader) {
       mACUnsafeHeaders.AppendElement(header);
     }
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -64,16 +64,17 @@
 #include "nsHashKeys.h"
 #include "prclist.h"
 #include "prtime.h"
 #include "nsIDOMNSEvent.h"
 #include "nsITimer.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsDOMProgressEvent.h"
 #include "nsDOMEventTargetWrapperCache.h"
+#include "nsContentUtils.h"
 
 class nsILoadGroup;
 class AsyncVerifyRedirectCallbackForwarder;
 
 class nsAccessControlLRUCache
 {
 public:
   struct TokenTime
@@ -328,16 +329,20 @@ protected:
                                   nsRefPtr<nsDOMEventListenerWrapper>& aCurrent,
                                   nsIDOMEventListener* aNew);
 
   nsresult GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
                                  nsIDOMEventListener** aListener);
 
   already_AddRefed<nsIHttpChannel> GetCurrentHttpChannel();
 
+  bool IsSystemXHR() {
+    return !!nsContentUtils::IsSystemPrincipal(mPrincipal);
+  }
+
   /**
    * Check if aChannel is ok for a cross-site request by making sure no
    * inappropriate headers are set, and no username/password is set.
    *
    * Also updates the XML_HTTP_REQUEST_USE_XSITE_AC bit.
    */
   nsresult CheckChannelForCrossSiteRequest(nsIChannel* aChannel);
 
--- a/content/base/test/test_bug426308.html
+++ b/content/base/test/test_bug426308.html
@@ -17,19 +17,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 426308 **/
 
 const SJS_URL = "http://example.org:80/tests/content/base/test/bug426308-redirect.sjs";
 
-netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
-
-var req = new XMLHttpRequest();
+var req = SpecialPowers.createSystemXHR();
 req.open("GET", SJS_URL + "?" + window.location.href, false);
 req.send(null);
 
 is(req.status, 200, "Redirect did not happen");
 
 </script>
 </pre>
 </body>
--- a/content/base/test/test_bug431701.html
+++ b/content/base/test/test_bug431701.html
@@ -47,18 +47,17 @@ function frameDoc(id) {
 
 function createDoc() {
   return document.implementation.createDocument('', 'html', null);
 }
 
 function xhrDoc(idx) {
   return function() {
     // Defy same-origin restrictions!
-    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-    var xhr = new XMLHttpRequest();
+    var xhr = SpecialPowers.createSystemXHR();
     xhr.open("GET", docSources[idx], false);
     xhr.send();
     return xhr.responseXML;
   };
 }
 
 // Each row has the document getter function, then the characterSet,
 // inputEncoding, xmlEncoding expected for that document.
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4838,16 +4838,22 @@ nsDocShell::SetIsActive(PRBool aIsActive
   mIsActive = aIsActive;
 
   // Tell the PresShell about it.
   nsCOMPtr<nsIPresShell> pshell;
   GetPresShell(getter_AddRefs(pshell));
   if (pshell)
     pshell->SetIsActive(aIsActive);
 
+  // Tell the window about it
+  nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mScriptGlobal);
+  if (win) {
+      win->SetIsBackground(!aIsActive);
+  }
+
   // Recursively tell all of our children
   PRInt32 n = mChildList.Count();
   for (PRInt32 i = 0; i < n; ++i) {
       nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(ChildAt(i));
       if (docshell)
         docshell->SetIsActive(aIsActive);
   }
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -267,19 +267,24 @@ static PRBool               gDOMWindowDu
 #endif
 
 #if defined(DEBUG_bryner) || defined(DEBUG_chb)
 #define DEBUG_PAGE_CACHE
 #endif
 
 // The default shortest interval/timeout we permit
 #define DEFAULT_MIN_TIMEOUT_VALUE 10 // 10ms
+#define DEFAULT_MIN_BACKGROUND_TIMEOUT_VALUE 1000 // 1000ms
 static PRInt32 gMinTimeoutValue;
-static inline PRInt32 DOMMinTimeoutValue() {
-  return NS_MAX(gMinTimeoutValue, 0);
+static PRInt32 gMinBackgroundTimeoutValue;
+inline PRInt32
+nsGlobalWindow::DOMMinTimeoutValue() const {
+  PRBool isBackground = !mOuterWindow || mOuterWindow->IsBackground();
+  return
+    NS_MAX(isBackground ? gMinBackgroundTimeoutValue : gMinTimeoutValue, 0);
 }
 
 // The number of nested timeouts before we start clamping. HTML5 says 1, WebKit
 // uses 5.
 #define DOM_CLAMP_TIMEOUT_NESTING_LEVEL 5
 
 // The longest interval (as PRIntervalTime) we permit, or that our
 // timer code can handle, really. See DELAY_INTERVAL_LIMIT in
@@ -741,17 +746,18 @@ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsT
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsTimeout, Release)
 
 nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
 : mFrameElement(nsnull), mDocShell(nsnull), mModalStateDepth(0),
   mRunningTimeout(nsnull), mMutationBits(0), mIsDocumentLoaded(PR_FALSE),
   mIsHandlingResizeEvent(PR_FALSE), mIsInnerWindow(aOuterWindow != nsnull),
   mMayHavePaintEventListener(PR_FALSE), mMayHaveTouchEventListener(PR_FALSE),
   mMayHaveAudioAvailableEventListener(PR_FALSE), mIsModalContentWindow(PR_FALSE),
-  mIsActive(PR_FALSE), mInnerWindow(nsnull), mOuterWindow(aOuterWindow),
+  mIsActive(PR_FALSE), mIsBackground(PR_FALSE),
+  mInnerWindow(nsnull), mOuterWindow(aOuterWindow),
   // Make sure no actual window ends up with mWindowID == 0
   mWindowID(++gNextWindowID), mHasNotifiedGlobalCreated(PR_FALSE)
  {}
 
 nsPIDOMWindow::~nsPIDOMWindow() {}
 
 //*****************************************************************************
 // nsOuterWindowProxy: Outer Window Proxy
@@ -890,16 +896,19 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalW
   if (gRefCnt == 1) {
 #if !(defined(NS_DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
     nsContentUtils::AddBoolPrefVarCache("browser.dom.window.dump.enabled",
                                         &gDOMWindowDumpEnabled);
 #endif
     nsContentUtils::AddIntPrefVarCache("dom.min_timeout_value",
                                        &gMinTimeoutValue,
                                        DEFAULT_MIN_TIMEOUT_VALUE);
+    nsContentUtils::AddIntPrefVarCache("dom.min_background_timeout_value",
+                                       &gMinBackgroundTimeoutValue,
+                                       DEFAULT_MIN_BACKGROUND_TIMEOUT_VALUE);
   }
 
   if (gDumpFile == nsnull) {
     const nsAdoptingCString& fname = 
       nsContentUtils::GetCharPref("browser.dom.window.dump.file");
     if (!fname.IsEmpty()) {
       // if this fails to open, Dump() knows to just go to stdout
       // on null.
@@ -2453,16 +2462,20 @@ nsGlobalWindow::SetDocShell(nsIDocShell*
       nsCOMPtr<nsIDOMWindow> parentWindow;
       GetParent(getter_AddRefs(parentWindow));
       if (parentWindow.get() != static_cast<nsIDOMWindow*>(this)) {
         nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(parentWindow));
         mChromeEventHandler = piWindow->GetChromeEventHandler();
       }
       else NS_NewWindowRoot(this, getter_AddRefs(mChromeEventHandler));
     }
+
+    PRBool docShellActive;
+    mDocShell->GetIsActive(&docShellActive);
+    mIsBackground = !docShellActive;
   }
 }
 
 void
 nsGlobalWindow::SetOpenerWindow(nsIDOMWindowInternal* aOpener,
                                 PRBool aOriginalOpener)
 {
   FORWARD_TO_OUTER_VOID(SetOpenerWindow, (aOpener, aOriginalOpener));
@@ -8726,28 +8739,24 @@ nsGlobalWindow::SetTimeoutOrInterval(nsI
 
   // If we don't have a document (we could have been unloaded since
   // the call to setTimeout was made), do nothing.
   if (!mDocument) {
     return NS_OK;
   }
 
   PRUint32 nestingLevel = sNestingLevel + 1;
-  if (interval < DOMMinTimeoutValue()) {
-    if (aIsInterval || nestingLevel >= DOM_CLAMP_TIMEOUT_NESTING_LEVEL) {
-      // Don't allow timeouts less than DOMMinTimeoutValue() from
-      // now...
-
-      interval = DOMMinTimeoutValue();;
-    }
-    else if (interval < 0) {
-      // Clamp negative intervals to 0.
-
-      interval = 0;
-    }
+  if (aIsInterval || nestingLevel >= DOM_CLAMP_TIMEOUT_NESTING_LEVEL) {
+    // Don't allow timeouts less than DOMMinTimeoutValue() from
+    // now...
+    interval = NS_MAX(interval, DOMMinTimeoutValue());
+  }
+  else if (interval < 0) {
+    // Clamp negative intervals to 0.
+    interval = 0;
   }
 
   NS_ASSERTION(interval >= 0, "DOMMinTimeoutValue() lies");
   PRUint32 realInterval = interval;
 
   // Make sure we don't proceed with a interval larger than our timer
   // code can handle.
   if (realInterval > PR_IntervalToMilliseconds(DOM_MAX_TIMEOUT_VALUE)) {
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -817,16 +817,18 @@ protected:
   void NotifyWindowIDDestroyed(const char* aTopic);
   
   void ClearStatus();
 
   virtual void UpdateParentTarget();
 
   PRBool GetIsTabModalPromptAllowed();
 
+  inline PRInt32 DOMMinTimeoutValue() const;
+
   // When adding new member variables, be careful not to create cycles
   // through JavaScript.  If there is any chance that a member variable
   // could own objects that are implemented in JavaScript, then those
   // objects will keep the global object (this object) alive.  To prevent
   // these cycles, ownership of such members must be released in
   // |CleanUp| and |SetDocShell|.
 
   // This member is also used on both inner and outer windows, but
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -97,16 +97,26 @@ public:
     mIsActive = aActive;
   }
 
   PRBool IsActive()
   {
     return mIsActive;
   }
 
+  void SetIsBackground(PRBool aIsBackground)
+  {
+    mIsBackground = aIsBackground;
+  }
+
+  PRBool IsBackground()
+  {
+    return mIsBackground;
+  }
+
   nsPIDOMEventTarget* GetChromeEventHandler() const
   {
     return mChromeEventHandler;
   }
 
   virtual void SetChromeEventHandler(nsPIDOMEventTarget* aChromeEventHandler) = 0;
 
   nsPIDOMEventTarget* GetParentTarget()
@@ -603,18 +613,24 @@ protected:
   PRPackedBool           mMayHaveTouchEventListener;
   PRPackedBool           mMayHaveAudioAvailableEventListener;
 
   // This variable is used on both inner and outer windows (and they
   // should match).
   PRPackedBool           mIsModalContentWindow;
 
   // Tracks activation state that's used for :-moz-window-inactive.
+  // Only used on outer windows.
   PRPackedBool           mIsActive;
 
+  // Tracks whether our docshell is active.  If it is, mIsBackground
+  // is false.  Too bad we have so many different concepts of
+  // "active".  Only used on outer windows.
+  PRPackedBool           mIsBackground;
+
   // And these are the references between inner and outer windows.
   nsPIDOMWindow         *mInnerWindow;
   nsCOMPtr<nsPIDOMWindow> mOuterWindow;
 
   // the element within the document that is currently focused when this
   // window is active
   nsCOMPtr<nsIContent> mFocusedNode;
 
--- a/dom/src/threads/nsDOMWorkerScriptLoader.cpp
+++ b/dom/src/threads/nsDOMWorkerScriptLoader.cpp
@@ -264,18 +264,17 @@ nsDOMWorkerScriptLoader::ExecuteScripts(
                        JS_GetGlobalObject(aCx);
     NS_ENSURE_STATE(global);
 
     // Because we may have nested calls to this function we don't want the
     // execution to automatically report errors. We let them propagate instead.
     uint32 oldOpts =
       JS_SetOptions(aCx, JS_GetOptions(aCx) | JSOPTION_DONT_REPORT_UNCAUGHT);
 
-    jsval val;
-    PRBool success = JS_ExecuteScript(aCx, global, script, &val);
+    PRBool success = JS_ExecuteScript(aCx, global, script, NULL);
 
     JS_SetOptions(aCx, oldOpts);
 
     if (!success) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
@@ -818,17 +817,18 @@ nsDOMWorkerScriptLoader::ScriptCompiler:
   JSAutoRequest ar(cx);
 
   JSObject* global = JS_GetGlobalObject(cx);
   NS_ENSURE_STATE(global);
 
   // Because we may have nested calls to this function we don't want the
   // execution to automatically report errors. We let them propagate instead.
   uint32 oldOpts =
-    JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT);
+    JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT |
+                      JSOPTION_NO_SCRIPT_RVAL);
 
   JSPrincipals* principal = nsDOMWorkerSecurityManager::WorkerPrincipal();
 
   JSScript* script =
     JS_CompileUCScriptForPrincipals(cx, global, principal,
                                     reinterpret_cast<const jschar*>
                                                (mScriptText.BeginReading()),
                                     mScriptText.Length(), mFilename.get(), 1);
--- a/dom/src/threads/nsDOMWorkerTimeout.cpp
+++ b/dom/src/threads/nsDOMWorkerTimeout.cpp
@@ -195,21 +195,20 @@ nsDOMWorkerTimeout::ExpressionCallback::
 
   JSString* expression = JS_ValueToString(aCx, mExpression);
   NS_ENSURE_TRUE(expression, NS_ERROR_FAILURE);
 
   size_t stringLength;
   const jschar* string = JS_GetStringCharsAndLength(aCx, expression, &stringLength);
   NS_ENSURE_TRUE(string, NS_ERROR_FAILURE);
 
-  jsval rval;
   PRBool success = JS_EvaluateUCScriptForPrincipals(aCx, global, principal,
                                                     string, stringLength,
                                                     mFileName.get(),
-                                                    mLineNumber, &rval);
+                                                    mLineNumber, nsnull);
   if (!success) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 nsDOMWorkerTimeout::nsDOMWorkerTimeout(nsDOMWorker* aWorker,
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -186,17 +186,16 @@ nsresult CentralizedAdminPrefManagerFini
     return NS_OK;
 }
 
 nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
                                    const char *filename, PRBool bGlobalContext, 
                                    PRBool bCallbacks, PRBool skipFirstLine)
 {
     JSBool ok;
-    jsval result;
 
     if (skipFirstLine) {
         /* In order to protect the privacy of the JavaScript preferences file 
          * from loading by the browser, we make the first line unparseable
          * by JavaScript. We must skip that line here before executing 
          * the JavaScript code.
          */
         unsigned int i = 0;
@@ -221,17 +220,17 @@ nsresult EvaluateAdminConfigScript(const
     rv = cxstack->Push(autoconfig_cx);
     if (NS_FAILED(rv)) {
         NS_ERROR("coudn't push the context on the stack");
         return rv;
     }
 
     JS_BeginRequest(autoconfig_cx);
     ok = JS_EvaluateScript(autoconfig_cx, autoconfig_glob,
-                           js_buffer, length, filename, 0, &result);
+                           js_buffer, length, filename, 0, nsnull);
     JS_EndRequest(autoconfig_cx);
 
     JS_MaybeGC(autoconfig_cx);
 
     JSContext *cx;
     cxstack->Pop(&cx);
     NS_ASSERTION(cx == autoconfig_cx, "AutoConfig JS contexts didn't match");
 
--- a/ipc/glue/WindowsMessageLoop.cpp
+++ b/ipc/glue/WindowsMessageLoop.cpp
@@ -97,16 +97,19 @@ using namespace mozilla::ipc::windows;
  *
  * Queued and "non-queued" messages will be processed during RPC calls if
  * modal UI related api calls block an RPC in-call in the child. To prevent
  * windows from freezing, and to allow concurrent processing of critical
  * events (such as painting), we spin a native event dispatch loop while
  * these in-calls are blocked.
  */
 
+// pulled from widget's nsAppShell
+extern const PRUnichar* kAppShellEventId;
+
 namespace {
 
 const wchar_t kOldWndProcProp[] = L"MozillaIPCOldWndProc";
 
 // This isn't defined before Windows XP.
 enum { WM_XP_THEMECHANGED = 0x031A };
 
 PRUnichar gAppMessageWindowName[256] = { 0 };
@@ -117,16 +120,17 @@ nsTArray<HWND>* gNeuteredWindows = nsnul
 typedef nsTArray<nsAutoPtr<DeferredMessage> > DeferredMessageArray;
 DeferredMessageArray* gDeferredMessages = nsnull;
 
 HHOOK gDeferredGetMsgHook = NULL;
 HHOOK gDeferredCallWndProcHook = NULL;
 
 DWORD gUIThreadId = 0;
 int gEventLoopDepth = 0;
+static UINT sAppShellGeckoMsgId;
 
 LRESULT CALLBACK
 DeferredMessageHook(int nCode,
                     WPARAM wParam,
                     LPARAM lParam)
 {
   // XXX This function is called for *both* the WH_CALLWNDPROC hook and the
   //     WH_GETMESSAGE hook, but they have different parameters. We don't
@@ -294,36 +298,41 @@ ProcessOrDeferMessage(HWND hwnd,
     }
 
     // Just return, prevents DefWindowProc from messaging the window
     // syncronously with other events, which may be deferred. Prevents 
     // random shutdown of aero composition on the window. 
     case WM_SYNCPAINT:
       return 0;
 
-    // Unknown messages only.
     default: {
+      if (uMsg && uMsg == sAppShellGeckoMsgId) {
+        // Widget's registered native event callback
+        deferred = new DeferredSendMessage(hwnd, uMsg, wParam, lParam);
+      } else {
+        // Unknown messages only
 #ifdef DEBUG
-      nsCAutoString log("Received \"nonqueued\" message ");
-      log.AppendInt(uMsg);
-      log.AppendLiteral(" during a synchronous IPC message for window ");
-      log.AppendInt((PRInt64)hwnd);
+        nsCAutoString log("Received \"nonqueued\" message ");
+        log.AppendInt(uMsg);
+        log.AppendLiteral(" during a synchronous IPC message for window ");
+        log.AppendInt((PRInt64)hwnd);
 
-      wchar_t className[256] = { 0 };
-      if (GetClassNameW(hwnd, className, sizeof(className) - 1) > 0) {
-        log.AppendLiteral(" (\"");
-        log.Append(NS_ConvertUTF16toUTF8((PRUnichar*)className));
-        log.AppendLiteral("\")");
+        wchar_t className[256] = { 0 };
+        if (GetClassNameW(hwnd, className, sizeof(className) - 1) > 0) {
+          log.AppendLiteral(" (\"");
+          log.Append(NS_ConvertUTF16toUTF8((PRUnichar*)className));
+          log.AppendLiteral("\")");
+        }
+
+        log.AppendLiteral(", sending it to DefWindowProc instead of the normal "
+                          "window procedure.");
+        NS_ERROR(log.get());
+#endif
+        return DefWindowProc(hwnd, uMsg, wParam, lParam);
       }
-
-      log.AppendLiteral(", sending it to DefWindowProc instead of the normal "
-                        "window procedure.");
-      NS_ERROR(log.get());
-#endif
-      return DefWindowProc(hwnd, uMsg, wParam, lParam);
     }
   }
 
   NS_ASSERTION(deferred, "Must have a message here!");
 
   // Create the deferred message array if it doesn't exist already.
   if (!gDeferredMessages) {
     gDeferredMessages = new nsTArray<nsAutoPtr<DeferredMessage> >(20);
@@ -526,16 +535,17 @@ Init()
   // If we aren't setup before a call to NotifyWorkerThread, we'll hang
   // on startup.
   if (!gUIThreadId) {
     gUIThreadId = GetCurrentThreadId();
   }
   NS_ASSERTION(gUIThreadId, "ThreadId should not be 0!");
   NS_ASSERTION(gUIThreadId == GetCurrentThreadId(),
                "Running on different threads!");
+  sAppShellGeckoMsgId = RegisterWindowMessageW(kAppShellEventId);
 }
 
 // This timeout stuff assumes a sane value of mTimeoutMs (less than the overflow
 // value for GetTickCount(), which is something like 50 days). It uses the
 // cheapest (and least accurate) method supported by Windows 2000.
 
 struct TimeoutData
 {
--- a/js/src/config/expandlibs.py
+++ b/js/src/config/expandlibs.py
@@ -58,16 +58,39 @@ given a list of files, expandlibs will r
   replace ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} with the OBJS and LIBS the
   descriptor contains. And for each of these LIBS, also apply the same
   rules.
 '''
 from __future__ import with_statement
 import sys, os
 import expandlibs_config as conf
 
+def relativize(path):
+    '''Returns a path relative to the current working directory, if it is
+    shorter than the given path'''
+    def splitpath(path):
+        dir, file = os.path.split(path)
+        if os.path.splitdrive(dir)[1] == os.sep:
+            return [file]
+        return splitpath(dir) + [file]
+
+    if not os.path.exists(path):
+        return path
+    curdir = splitpath(os.path.abspath(os.curdir))
+    abspath = splitpath(os.path.abspath(path))
+    while curdir and abspath and curdir[0] == abspath[0]:
+        del curdir[0]
+        del abspath[0]
+    if not curdir and not abspath:
+        return '.'
+    relpath = os.path.join(*[os.pardir for i in curdir] + abspath)
+    if len(path) > len(relpath):
+        return relpath
+    return path
+
 class LibDescriptor(dict):
     KEYS = ['OBJS', 'LIBS']
 
     def __init__(self, content=None):
         '''Creates an instance of a lib descriptor, initialized with contents
         from a list of strings when given. This is intended for use with
         file.readlines()'''
         if isinstance(content, list) and all([isinstance(item, str) for item in content]):
@@ -94,32 +117,32 @@ class ExpandArgs(list):
         super(ExpandArgs, self).__init__()
         for arg in args:
             self += self._expand(arg)
 
     def _expand(self, arg):
         '''Internal function doing the actual work'''
         (root, ext) = os.path.splitext(arg)
         if ext != conf.LIB_SUFFIX or not os.path.basename(root).startswith(conf.LIB_PREFIX):
-            return [arg]
+            return [relativize(arg)]
         if len(conf.IMPORT_LIB_SUFFIX):
             dll = root + conf.IMPORT_LIB_SUFFIX
         else:
             dll = root.replace(conf.LIB_PREFIX, conf.DLL_PREFIX, 1) + conf.DLL_SUFFIX
         if os.path.exists(dll):
-            return [dll]
+            return [relativize(dll)]
         if os.path.exists(arg):
-            return [arg]
+            return [relativize(arg)]
         return self._expand_desc(arg)
 
     def _expand_desc(self, arg):
         '''Internal function taking care of lib descriptor expansion only'''
         if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
             with open(arg + conf.LIBS_DESC_SUFFIX, 'r') as f:
                 desc = LibDescriptor(f.readlines())
-            objs = desc['OBJS']
+            objs = [relativize(o) for o in desc['OBJS']]
             for lib in desc['LIBS']:
                 objs += self._expand(lib)
             return objs
         return [arg]
 
 if __name__ == '__main__':
     print " ".join(ExpandArgs(sys.argv[1:]))
--- a/js/src/config/expandlibs_exec.py
+++ b/js/src/config/expandlibs_exec.py
@@ -47,17 +47,17 @@ files with a list file. This can be used
 of a command line. The kind of list file format used depends on the
 EXPAND_LIBS_LIST_STYLE variable: 'list' for MSVC style lists (@file.list)
 or 'linkerscript' for GNU ld linker scripts.
 See https://bugzilla.mozilla.org/show_bug.cgi?id=584474#c59 for more details.
 '''
 from __future__ import with_statement
 import sys
 import os
-from expandlibs import ExpandArgs
+from expandlibs import ExpandArgs, relativize
 import expandlibs_config as conf
 from optparse import OptionParser
 import subprocess
 import tempfile
 import shutil
 
 class ExpandArgsMore(ExpandArgs):
     ''' Meant to be used as 'with ExpandArgsMore(args) as ...: '''
@@ -88,17 +88,17 @@ class ExpandArgsMore(ExpandArgs):
                 if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
                     newlist += self._extract(self._expand_desc(arg))
                 elif os.path.exists(arg) and len(ar_extract):
                     tmp = tempfile.mkdtemp(dir=os.curdir)
                     self.tmp.append(tmp)
                     subprocess.call(ar_extract + [os.path.abspath(arg)], cwd=tmp)
                     objs = []
                     for root, dirs, files in os.walk(tmp):
-                        objs += [os.path.join(root, f) for f in files if os.path.splitext(f)[1] == conf.OBJ_SUFFIX]
+                        objs += [relativize(os.path.join(root, f)) for f in files if os.path.splitext(f)[1] == conf.OBJ_SUFFIX]
                     newlist += objs
                 else:
                     newlist += [arg]
             else:
                 newlist += [arg]
         return newlist
 
     def makelist(self):
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -291,16 +291,18 @@ InitExnPrivate(JSContext *cx, JSObject *
                   : NULL;
     older = JS_SetErrorReporter(cx, NULL);
     state = JS_SaveExceptionState(cx);
 
     callerid = ATOM_TO_JSID(cx->runtime->atomState.callerAtom);
     stackDepth = 0;
     valueCount = 0;
     for (fp = js_GetTopStackFrame(cx); fp; fp = fp->prev()) {
+        if (fp->scopeChain().compartment() != cx->compartment)
+            break;
         if (fp->isFunctionFrame() && !fp->isEvalFrame()) {
             Value v = NullValue();
             if (checkAccess &&
                 !checkAccess(cx, &fp->callee(), callerid, JSACC_READ, &v)) {
                 break;
             }
             valueCount += fp->numActualArgs();
         }
@@ -332,16 +334,18 @@ InitExnPrivate(JSContext *cx, JSObject *
     priv->message = message;
     priv->filename = filename;
     priv->lineno = lineno;
     priv->stackDepth = stackDepth;
 
     values = GetStackTraceValueBuffer(priv);
     elem = priv->stackElems;
     for (fp = js_GetTopStackFrame(cx); fp != fpstop; fp = fp->prev()) {
+        if (fp->scopeChain().compartment() != cx->compartment)
+            break;
         if (!fp->isFunctionFrame() || fp->isEvalFrame()) {
             elem->funName = NULL;
             elem->argc = 0;
         } else {
             elem->funName = fp->fun()->atom
                             ? ATOM_TO_STRING(fp->fun()->atom)
                             : cx->runtime->emptyString;
             elem->argc = fp->numActualArgs();
--- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
@@ -1066,21 +1066,19 @@ mozJSComponentLoader::GlobalForLocation(
 
     if (!script) {
         // The script wasn't in the cache , so compile it now.
         LOG(("Slow loading %s\n", nativePath.get()));
 
         // If |exception| is non-null, then our caller wants us to propagate
         // any exceptions out to our caller. Ensure that the engine doesn't
         // eagerly report the exception.
-        uint32 oldopts = 0;
-        if (exception) {
-            oldopts = JS_GetOptions(cx);
-            JS_SetOptions(cx, oldopts | JSOPTION_DONT_REPORT_UNCAUGHT);
-        }
+        uint32 oldopts = JS_GetOptions(cx);
+        JS_SetOptions(cx, oldopts | JSOPTION_NO_SCRIPT_RVAL |
+                          (exception ? JSOPTION_DONT_REPORT_UNCAUGHT : 0));
 
         if (realFile) {
 #ifdef HAVE_PR_MEMMAP
             PRInt64 fileSize;
             rv = aComponentFile->GetFileSize(&fileSize);
             if (NS_FAILED(rv)) {
                 JS_SetOptions(cx, oldopts);
                 return rv;
@@ -1184,22 +1182,20 @@ mozJSComponentLoader::GlobalForLocation(
             script = JS_CompileScriptForPrincipalsVersion(
               cx, global, jsPrincipals, buf, bytesRead, nativePath.get(), 1,
               JSVERSION_LATEST);
         }
         // Propagate the exception, if one exists. Also, don't leave the stale
         // exception on this context.
         // NB: The caller must stick exception into a rooted slot (probably on
         // its context) as soon as possible to avoid GC hazards.
-        if (exception) {
-            JS_SetOptions(cx, oldopts);
-            if (!script) {
-                JS_GetPendingException(cx, exception);
-                JS_ClearPendingException(cx);
-            }
+        JS_SetOptions(cx, oldopts);
+        if (!script && exception) {
+            JS_GetPendingException(cx, exception);
+            JS_ClearPendingException(cx);
         }
     }
 
     if (!script) {
 #ifdef DEBUG_shaver_off
         fprintf(stderr, "mJCL: script compilation of %s FAILED\n",
                 nativePath.get());
 #endif
@@ -1236,18 +1232,17 @@ mozJSComponentLoader::GlobalForLocation(
         }
     }
 #endif
 
     // Assign aGlobal here so that it's available to recursive imports.
     // See bug 384168.
     *aGlobal = global;
 
-    jsval retval;
-    if (!JS_ExecuteScriptVersion(cx, global, script, &retval, JSVERSION_LATEST)) {
+    if (!JS_ExecuteScriptVersion(cx, global, script, NULL, JSVERSION_LATEST)) {
 #ifdef DEBUG_shaver_off
         fprintf(stderr, "mJCL: failed to execute %s\n", nativePath.get());
 #endif
         *aGlobal = nsnull;
         return NS_ERROR_FAILURE;
     }
 
     /* Freed when we remove from the table. */
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -42,42 +42,44 @@
 
 #include "nsBidiPresUtils.h"
 #include "nsTextFragment.h"
 #include "nsGkAtoms.h"
 #include "nsPresContext.h"
 #include "nsIRenderingContext.h"
 #include "nsIServiceManager.h"
 #include "nsFrameManager.h"
+#include "nsBidiFrames.h"
 #include "nsBidiUtils.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsHTMLContainerFrame.h"
 #include "nsInlineFrame.h"
 #include "nsPlaceholderFrame.h"
 #include "nsContainerFrame.h"
 #include "nsFirstLetterFrame.h"
 #include "gfxUnicodeProperties.h"
 #include "nsIThebesFontMetrics.h"
-#include "nsTextFrame.h"
-
-#undef NOISY_BIDI
-#undef REALLY_NOISY_BIDI
 
 using namespace mozilla;
 
 static const PRUnichar kSpace            = 0x0020;
 static const PRUnichar kLineSeparator    = 0x2028;
 static const PRUnichar kObjectSubstitute = 0xFFFC;
 static const PRUnichar kLRE              = 0x202A;
 static const PRUnichar kRLE              = 0x202B;
 static const PRUnichar kLRO              = 0x202D;
 static const PRUnichar kRLO              = 0x202E;
 static const PRUnichar kPDF              = 0x202C;
+static const PRUnichar ALEF              = 0x05D0;
 
-#define NS_BIDI_CONTROL_FRAME ((nsIFrame*)0xfffb1d1)
+#define CHAR_IS_HEBREW(c) ((0x0590 <= (c)) && ((c)<= 0x05FF))
+// Note: The above code are moved from gfx/src/windows/nsRenderingContextWin.cpp
+
+nsIFrame*
+NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUnichar aChar);
 
 nsBidiPresUtils::nsBidiPresUtils() : mArraySize(8),
                                      mIndexMap(nsnull),
                                      mLevels(nsnull),
                                      mSuccess(NS_ERROR_FAILURE),
                                      mBidiEngine(nsnull)
 {
   mBidiEngine = new nsBidi();
@@ -157,99 +159,87 @@ SplitInlineAncestors(nsIFrame*     aFram
     
     frame = parent;
     parent = grandparent;
   }
   
   return NS_OK;
 }
 
-static void
-MakeContinuationFluid(nsIFrame* aFrame, nsIFrame* aNext)
-{
-  NS_ASSERTION (!aFrame->GetNextInFlow() || aFrame->GetNextInFlow() == aNext, 
-                "next-in-flow is not next continuation!");
-  aFrame->SetNextInFlow(aNext);
-
-  NS_ASSERTION (!aNext->GetPrevInFlow() || aNext->GetPrevInFlow() == aFrame,
-                "prev-in-flow is not prev continuation!");
-  aNext->SetPrevInFlow(aFrame);
-}
-
-// If aFrame is the last child of its parent, convert bidi continuations to
-// fluid continuations for all of its inline ancestors.
+// Convert bidi continuations to fluid continuations for a frame and all of its
+// inline ancestors.
 static void
 JoinInlineAncestors(nsIFrame* aFrame)
 {
-  if (aFrame->GetNextSibling()) {
-    return;
-  }
-  nsIFrame* frame = aFrame->GetParent();
+  nsIFrame* frame = aFrame;
   while (frame && IsBidiSplittable(frame)) {
     nsIFrame* next = frame->GetNextContinuation();
     if (next) {
-      MakeContinuationFluid(frame, next);
+      NS_ASSERTION (!frame->GetNextInFlow() || frame->GetNextInFlow() == next, 
+                    "next-in-flow is not next continuation!");
+      frame->SetNextInFlow(next);
+
+      NS_ASSERTION (!next->GetPrevInFlow() || next->GetPrevInFlow() == frame,
+                    "prev-in-flow is not prev continuation!");
+      next->SetPrevInFlow(frame);
     }
     // Join the parent only as long as we're its last child.
     if (frame->GetNextSibling())
       break;
     frame = frame->GetParent();
   }
 }
 
 static nsresult
-CreateContinuation(nsIFrame*       aFrame,
-                   nsIFrame**      aNewFrame,
-                   PRBool          aIsFluid)
+CreateBidiContinuation(nsIFrame*       aFrame,
+                       nsIFrame**      aNewFrame)
 {
   NS_PRECONDITION(aNewFrame, "null OUT ptr");
   NS_PRECONDITION(aFrame, "null ptr");
 
   *aNewFrame = nsnull;
 
   nsPresContext *presContext = aFrame->PresContext();
   nsIPresShell *presShell = presContext->PresShell();
-  NS_ASSERTION(presShell, "PresShell must be set on PresContext before calling nsBidiPresUtils::CreateContinuation");
+  NS_ASSERTION(presShell, "PresShell must be set on PresContext before calling nsBidiPresUtils::CreateBidiContinuation");
 
   nsIFrame* parent = aFrame->GetParent();
-  NS_ASSERTION(parent, "Couldn't get frame parent in nsBidiPresUtils::CreateContinuation");
+  NS_ASSERTION(parent, "Couldn't get frame parent in nsBidiPresUtils::CreateBidiContinuation");
 
   nsresult rv = NS_OK;
   
   // Have to special case floating first letter frames because the continuation
   // doesn't go in the first letter frame. The continuation goes with the rest
   // of the text that the first letter frame was made out of.
   if (parent->GetType() == nsGkAtoms::letterFrame &&
       parent->GetStyleDisplay()->IsFloating()) {
     nsFirstLetterFrame* letterFrame = do_QueryFrame(parent);
     rv = letterFrame->CreateContinuationForFloatingParent(presContext, aFrame,
-                                                          aNewFrame, aIsFluid);
+                                                          aNewFrame, PR_FALSE);
     return rv;
   }
 
   rv = presShell->FrameConstructor()->
-    CreateContinuingFrame(presContext, aFrame, parent, aNewFrame, aIsFluid);
+    CreateContinuingFrame(presContext, aFrame, parent, aNewFrame, PR_FALSE);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // The list name nsGkAtoms::nextBidi would indicate we don't want reflow
   // XXXbz this needs higher-level framelist love
   nsFrameList temp(*aNewFrame, *aNewFrame);
   rv = parent->InsertFrames(nsGkAtoms::nextBidi, aFrame, temp);
   if (NS_FAILED(rv)) {
     return rv;
   }
   
-  if (!aIsFluid) {
-    // Split inline ancestor frames
-    rv = SplitInlineAncestors(aFrame);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
+  // Split inline ancestor frames
+  rv = SplitInlineAncestors(aFrame);
+  if (NS_FAILED(rv)) {
+    return rv;
   }
 
   return NS_OK;
 }
 
 static PRBool
 IsFrameInCurrentLine(nsBlockInFlowLineIterator* aLineIter,
                      nsIFrame* aPrevFrame, nsIFrame* aFrame)
@@ -290,17 +280,17 @@ AdvanceLineIteratorToFrame(nsIFrame* aFr
   aPrevFrame = child;
 }
 
 /*
  * Overview of the implementation of Resolve():
  *
  *  Walk through the descendants of aBlockFrame and build:
  *   * mLogicalFrames: an nsTArray of nsIFrame* pointers in logical order
- *   * mBuffer: an nsString containing a representation of
+ *   * mBuffer: an nsAutoString containing a representation of
  *     the content of the frames.
  *     In the case of text frames, this is the actual text context of the
  *     frames, but some other elements are represented in a symbolic form which
  *     will make the Unicode Bidi Algorithm give the correct results.
  *     Bidi embeddings and overrides set by CSS or <bdo> elements are
  *     represented by the corresponding Unicode control characters.
  *     <br> elements are represented by U+2028 LINE SEPARATOR
  *     Other inline elements are represented by U+FFFC OBJECT REPLACEMENT
@@ -320,258 +310,206 @@ AdvanceLineIteratorToFrame(nsIFrame* aFr
  *  We may also need to call RemoveBidiContinuation() to convert frames created
  *  by EnsureBidiContinuation() in previous reflows into fluid continuations.
  */
 nsresult
 nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
 {
   mLogicalFrames.Clear();
   mContentToFrameIndex.Clear();
-  mBuffer.SetLength(0);
-  mEmbeddingStack.Clear();
   
   nsPresContext *presContext = aBlockFrame->PresContext();
-
-  const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility();
+  nsIPresShell* shell = presContext->PresShell();
+  nsStyleContext* styleContext = aBlockFrame->GetStyleContext();
 
-  mParaLevel = (NS_STYLE_DIRECTION_RTL == vis->mDirection) ?
-                NSBIDI_RTL : NSBIDI_LTR;
+  // handle bidi-override being set on the block itself before calling
+  // InitLogicalArray.
+  const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility();
+  const nsStyleTextReset* text = aBlockFrame->GetStyleTextReset();
+
+  if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
+    nsIFrame *directionalFrame = nsnull;
 
-  mLineIter = new nsBlockInFlowLineIterator(aBlockFrame,
-                                            aBlockFrame->begin_lines(),
-                                            PR_FALSE);
-  if (mLineIter->GetLine() == aBlockFrame->end_lines()) {
-    // Advance to first valid line (might be in a next-continuation)
-    mLineIter->Next();
+    if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
+      directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kRLO);
+    }
+    else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) {
+      directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kLRO);
+    }
+
+    if (directionalFrame) {
+      mLogicalFrames.AppendElement(directionalFrame);
+    }
+  }
+  for (nsBlockFrame* block = aBlockFrame; block;
+       block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) {
+    block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
+    InitLogicalArray(block->GetFirstChild(nsnull));
+  }
+
+  if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
+    nsIFrame* directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kPDF);
+    if (directionalFrame) {
+      mLogicalFrames.AppendElement(directionalFrame);
+    }
   }
 
-  mIsVisual = presContext->IsVisualMode();
-  if (mIsVisual) {
+  CreateBlockBuffer();
+
+  PRInt32 bufferLength = mBuffer.Length();
+
+  if (bufferLength < 1) {
+    mSuccess = NS_OK;
+    return mSuccess;
+  }
+  PRInt32 runCount;
+  PRUint8 embeddingLevel;
+
+  nsBidiLevel paraLevel = embeddingLevel =
+    (NS_STYLE_DIRECTION_RTL == vis->mDirection)
+    ? NSBIDI_RTL : NSBIDI_LTR;
+
+  mSuccess = mBidiEngine->SetPara(mBuffer.get(), bufferLength, paraLevel, nsnull);
+  if (NS_FAILED(mSuccess) ) {
+      return mSuccess;
+  }
+
+  mSuccess = mBidiEngine->CountRuns(&runCount);
+  if (NS_FAILED(mSuccess) ) {
+    return mSuccess;
+  }
+  PRInt32     runLength      = 0;   // the length of the current run of text
+  PRInt32     lineOffset     = 0;   // the start of the current run
+  PRInt32     logicalLimit   = 0;   // the end of the current run + 1
+  PRInt32     numRun         = -1;
+  PRInt32     fragmentLength = 0;   // the length of the current text frame
+  PRInt32     frameIndex     = -1;  // index to the frames in mLogicalFrames
+  PRInt32     frameCount     = mLogicalFrames.Length();
+  PRInt32     contentOffset  = 0;   // offset of current frame in its content node
+  PRBool      isTextFrame    = PR_FALSE;
+  nsIFrame*   frame = nsnull;
+  nsIContent* content = nsnull;
+  PRInt32     contentTextLength;
+  nsIAtom*    frameType = nsnull;
+
+  FramePropertyTable *propTable = presContext->PropertyTable();
+
+  nsBlockInFlowLineIterator lineIter(aBlockFrame, aBlockFrame->begin_lines(), PR_FALSE);
+  if (lineIter.GetLine() == aBlockFrame->end_lines()) {
+    // Advance to first valid line (might be in a next-continuation)
+    lineIter.Next();
+  }
+  nsIFrame* prevFrame = nsnull;
+  PRBool lineNeedsUpdate = PR_FALSE;
+
+  PRBool isVisual = presContext->IsVisualMode();
+  if (isVisual) {
     /**
      * Drill up in content to detect whether this is an element that needs to be
      * rendered with logical order even on visual pages.
      *
      * We always use logical order on form controls, firstly so that text entry
      * will be in logical order, but also because visual pages were written with
      * the assumption that even if the browser had no support for right-to-left
      * text rendering, it would use native widgets with bidi support to display
      * form controls.
      *
      * We also use logical order in XUL elements, since we expect that if a XUL
      * element appears in a visual page, it will be generated by an XBL binding
      * and contain localized text which will be in logical order.
      */
-    for (nsIContent* content = aBlockFrame->GetContent() ; content; 
-         content = content->GetParent()) {
-      if (content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) ||
-          content->IsXUL()) {
-        mIsVisual = PR_FALSE;
+    for (content = aBlockFrame->GetContent() ; content; content = content->GetParent()) {
+      if (content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) || content->IsXUL()) {
+        isVisual = PR_FALSE;
         break;
       }
     }
   }
-  mPrevFrame = nsnull;
-
-  // handle bidi-override being set on the block itself before calling
-  // TraverseFrames.
-  const nsStyleTextReset* text = aBlockFrame->GetStyleTextReset();
-  PRUnichar ch = 0;
-  if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
-    if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
-      ch = kRLO;
-    }
-    else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) {
-      ch = kLRO;
-    }
-    if (ch != 0) {
-      mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
-      mBuffer.Append(ch);
-      mEmbeddingStack.AppendElement(ch);
-    }
-  }
-  mPrevContent = nsnull;
-  for (nsBlockFrame* block = aBlockFrame; block;
-       block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) {
-    block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
-    TraverseFrames(aBlockFrame, block->GetFirstChild(nsnull));
-  }
-
-  if (ch != 0) {
-    mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
-    mBuffer.Append(kPDF);
-    NS_ASSERTION(mEmbeddingStack.Length(), "embedding/override underflow");
-    mEmbeddingStack.TruncateLength(mEmbeddingStack.Length() - 1);
-  }
-
-  // Resolve final paragraph
-  ResolveParagraph(aBlockFrame);
-  return mSuccess;
-}
-
-void
-nsBidiPresUtils::ResolveParagraph(nsBlockFrame* aBlockFrame)
-{
-  nsPresContext *presContext = aBlockFrame->PresContext();
-  PRInt32 bufferLength = mBuffer.Length();
-
-  if (bufferLength < 1) {
-    mSuccess = NS_OK;
-    return;
-  }
-  mBuffer.ReplaceChar("\t\r\n", kSpace);
-
-  PRInt32 runCount;
-  PRUint8 embeddingLevel = mParaLevel;
-
-  mSuccess = mBidiEngine->SetPara(mBuffer.get(), bufferLength, mParaLevel, nsnull);
-  if (NS_FAILED(mSuccess) ) {
-      return;
-  }
-
-  mSuccess = mBidiEngine->CountRuns(&runCount);
-  if (NS_FAILED(mSuccess) ) {
-    return;
-  }
-  PRInt32     runLength      = 0;   // the length of the current run of text
-  PRInt32     lineOffset     = 0;   // the start of the current run
-  PRInt32     logicalLimit   = 0;   // the end of the current run + 1
-  PRInt32     numRun         = -1;
-  PRInt32     fragmentLength = 0;   // the length of the current text frame
-  PRInt32     frameIndex     = -1;  // index to the frames in mLogicalFrames
-  PRInt32     frameCount     = mLogicalFrames.Length();
-  PRInt32     contentOffset  = 0;   // offset of current frame in its content node
-  PRBool      isTextFrame    = PR_FALSE;
-  nsIFrame*   frame = nsnull;
-  nsIContent* content = nsnull;
-  PRInt32     contentTextLength;
-
-  FramePropertyTable *propTable = presContext->PropertyTable();
-
-  if (frameCount == 1 && runCount == 1) {
-    // Nothing more to do, just make sure that the frame has the right
-    // embedding level.
-    if (mIsVisual ||
-        NS_FAILED(mBidiEngine->GetLogicalRun(lineOffset, &logicalLimit,
-                                             &embeddingLevel))) {
-      embeddingLevel = mParaLevel;
-    }
-
-    frame = mLogicalFrames[0];
-    nsBidiLevel oldEmbeddingLevel = NS_GET_EMBEDDING_LEVEL(frame);
-    nsBidiLevel oldBaseLevel = NS_GET_BASE_LEVEL(frame);
-
-    if (oldEmbeddingLevel != embeddingLevel ||
-        oldBaseLevel != mParaLevel) {
-      frame->Properties().Set(nsIFrame::EmbeddingLevelProperty(),
-                              NS_INT32_TO_PTR(embeddingLevel));
-      frame->Properties().Set(nsIFrame::BaseLevelProperty(),
-                              NS_INT32_TO_PTR(mParaLevel));
-      AdvanceLineIteratorToFrame(frame, mLineIter, mPrevFrame);
-      mLineIter->GetLine()->MarkDirty();
-      if (frame->GetType() == nsGkAtoms::textFrame) {
-        frame->AddStateBits(NS_FRAME_IS_BIDI);
-      }
-    }
-
-    mSuccess = NS_OK;
-    return;
-  }
-
-  PRBool lineNeedsUpdate = PR_FALSE;
   
-#ifdef NOISY_BIDI
-  if (mBuffer[0] != kObjectSubstitute) {
-    printf("Before Resolve(), aBlockFrame=0x%p, mBuffer='%s', frameCount=%d\n",
-           (void*)aBlockFrame, NS_ConvertUTF16toUTF8(mBuffer).get(), frameCount);
-#ifdef REALLY_NOISY_BIDI
-    printf(" frameTree=:\n");
-    nsFrame::DumpFrameTree(aBlockFrame);
-#endif
-  }
-#endif
   for (; ;) {
     if (fragmentLength <= 0) {
       // Get the next frame from mLogicalFrames
       if (++frameIndex >= frameCount) {
         break;
       }
       frame = mLogicalFrames[frameIndex];
+      frameType = frame->GetType();
       lineNeedsUpdate = PR_TRUE;
-      if (frame == NS_BIDI_CONTROL_FRAME ||
-          nsGkAtoms::textFrame != frame->GetType()) {
-        /*
-         * Any non-text frame corresponds to a single character in the text buffer
-         * (a bidi control character, LINE SEPARATOR, or OBJECT SUBSTITUTE)
-         */
-        isTextFrame = PR_FALSE;
-        fragmentLength = 1;
-      }
-      else {
+      if (nsGkAtoms::textFrame == frameType) {
         content = frame->GetContent();
         if (!content) {
           mSuccess = NS_OK;
           break;
         }
         contentTextLength = content->TextLength();
         if (contentTextLength == 0) {
           frame->AdjustOffsetsForBidi(0, 0);
           // Set the base level and embedding level of the current run even
           // on an empty frame. Otherwise frame reordering will not be correct.
           propTable->Set(frame, nsIFrame::EmbeddingLevelProperty(),
                          NS_INT32_TO_PTR(embeddingLevel));
           propTable->Set(frame, nsIFrame::BaseLevelProperty(),
-                         NS_INT32_TO_PTR(mParaLevel));
+                         NS_INT32_TO_PTR(paraLevel));
           continue;
         }
         PRInt32 start, end;
         frame->GetOffsets(start, end);
         NS_ASSERTION(!(contentTextLength < end - start),
                      "Frame offsets don't fit in content");
         fragmentLength = NS_MIN(contentTextLength, end - start);
         contentOffset = start;
         isTextFrame = PR_TRUE;
       }
+      else {
+        /*
+         * Any non-text frame corresponds to a single character in the text buffer
+         * (a bidi control character, LINE SEPARATOR, or OBJECT SUBSTITUTE)
+         */
+        isTextFrame = PR_FALSE;
+        fragmentLength = 1;
+      }
     } // if (fragmentLength <= 0)
 
     if (runLength <= 0) {
       // Get the next run of text from the Bidi engine
       if (++numRun >= runCount) {
         break;
       }
       lineOffset = logicalLimit;
       if (NS_FAILED(mBidiEngine->GetLogicalRun(
               lineOffset, &logicalLimit, &embeddingLevel) ) ) {
         break;
       }
       runLength = logicalLimit - lineOffset;
-      if (mIsVisual) {
-        embeddingLevel = mParaLevel;
+      if (isVisual) {
+        embeddingLevel = paraLevel;
       }
     } // if (runLength <= 0)
 
-    if (frame == NS_BIDI_CONTROL_FRAME) {
+    if (nsGkAtoms::directionalFrame == frameType) {
+      frame->Destroy();
       frame = nsnull;
       ++lineOffset;
     }
     else {
       propTable->Set(frame, nsIFrame::EmbeddingLevelProperty(),
                      NS_INT32_TO_PTR(embeddingLevel));
       propTable->Set(frame, nsIFrame::BaseLevelProperty(),
-                     NS_INT32_TO_PTR(mParaLevel));
+                     NS_INT32_TO_PTR(paraLevel));
       if (isTextFrame) {
         if ( (runLength > 0) && (runLength < fragmentLength) ) {
           /*
            * The text in this frame continues beyond the end of this directional run.
            * Create a non-fluid continuation frame for the next directional run.
            */
           if (lineNeedsUpdate) {
-            AdvanceLineIteratorToFrame(frame, mLineIter, mPrevFrame);
+            AdvanceLineIteratorToFrame(frame, &lineIter, prevFrame);
             lineNeedsUpdate = PR_FALSE;
           }
-          mLineIter->GetLine()->MarkDirty();
+          lineIter.GetLine()->MarkDirty();
           nsIFrame* nextBidi;
           PRInt32 runEnd = contentOffset + runLength;
           EnsureBidiContinuation(frame, &nextBidi, frameIndex,
                                  contentOffset,
                                  runEnd);
           if (NS_FAILED(mSuccess)) {
             break;
           }
@@ -597,58 +535,53 @@ nsBidiPresUtils::ResolveParagraph(nsBloc
             /*
              * There is more text that belongs to this directional run in the next
              * text frame: make sure it is a fluid continuation of the current frame.
              * Do not advance frameIndex, because the next frame may contain
              * multi-directional text and need to be split
              */
             PRInt32 newIndex = frameIndex;
             do {
-            } while (++newIndex < frameCount &&
-                     mLogicalFrames[newIndex] == NS_BIDI_CONTROL_FRAME);
-            if (newIndex < frameCount) {
-              RemoveBidiContinuation(frame, frameIndex, newIndex, lineOffset);
-            }
-          } else if (runLength == fragmentLength &&
-                     numRun + 1 < runCount) {
+            } while (mLogicalFrames[++newIndex]->GetType() == nsGkAtoms::directionalFrame);
+            RemoveBidiContinuation(frame, frameIndex, newIndex, lineOffset);
+          } else if (runLength == fragmentLength) {
             /*
-             * If the directional run ends at the end of the frame, and this is
-             * not the end of our paragraph, make sure that the next frame is a
-             * non-fluid continuation
+             * The directional run ends at the end of the frame. Make sure that
+             * the next frame is a non-fluid continuation
              */
             nsIFrame* next = frame->GetNextInFlow();
             if (next) {
               frame->SetNextContinuation(next);
               next->SetPrevContinuation(frame);
             }
           }
           frame->AdjustOffsetsForBidi(contentOffset, contentOffset + fragmentLength);
           if (lineNeedsUpdate) {
-            AdvanceLineIteratorToFrame(frame, mLineIter, mPrevFrame);
+            AdvanceLineIteratorToFrame(frame, &lineIter, prevFrame);
             lineNeedsUpdate = PR_FALSE;
           }
-          mLineIter->GetLine()->MarkDirty();
+          lineIter.GetLine()->MarkDirty();
         }
       } // isTextFrame
       else {
         ++lineOffset;
       }
-    } // not bidi control frame
+    } // not directionalFrame
     PRInt32 temp = runLength;
     runLength -= fragmentLength;
     fragmentLength -= temp;
 
     if (frame && fragmentLength <= 0) {
-      // If the frame is at the end of a run, and this is not the end of our
-      // paragrah, split all ancestor inlines that need splitting.
+      // If the frame is at the end of a run, split all ancestor inlines that
+      // need splitting.
       // To determine whether we're at the end of the run, we check that we've
       // finished processing the current run, and that the current frame
       // doesn't have a fluid continuation (it could have a fluid continuation
       // of zero length, so testing runLength alone is not sufficient).
-      if (numRun + 1 < runCount && runLength <= 0 && !frame->GetNextInFlow()) {
+      if (runLength <= 0 && !frame->GetNextInFlow()) {
         nsIFrame* child = frame;
         nsIFrame* parent = frame->GetParent();
         // As long as we're on the last sibling, the parent doesn't have to be split.
         // However, if the parent has a fluid continuation, we do have to make
         // it non-fluid. This can happen e.g. when we have a first-letter frame
         // and the end of the first-letter coincides with the end of a
         // directional run.
         while (parent &&
@@ -660,59 +593,46 @@ nsBidiPresUtils::ResolveParagraph(nsBloc
             next->SetPrevContinuation(parent);
           }
           child = parent;
           parent = child->GetParent();
         }
         if (parent && IsBidiSplittable(parent))
           SplitInlineAncestors(child);
       }
-      else {
-        // We're not at an end of a run. If |frame| is the last child of its
-        // parent, and its ancestors happen to have bidi continuations, convert
-        // them into fluid continuations.
-        JoinInlineAncestors(frame);
+      else if (!frame->GetNextSibling()) {
+        // We're not at an end of a run, and |frame| is the last child of its parent.
+        // If its ancestors happen to have bidi continuations, convert them into
+        // fluid continuations.
+        nsIFrame* parent = frame->GetParent();
+        JoinInlineAncestors(parent);
       }
     }
   } // for
-#ifdef REALLY_NOISY_BIDI
-  if (mBuffer[0] != kObjectSubstitute) {
-    printf("---\nAfter Resolve(), frameTree =:\n");
-    nsFrame::DumpFrameTree(aBlockFrame);
-    printf("===\n");
-  }
-#endif
+  return mSuccess;
 }
 
 // Should this frame be treated as a leaf (e.g. when building mLogicalFrames)?
 PRBool IsBidiLeaf(nsIFrame* aFrame) {
   nsIFrame* kid = aFrame->GetFirstChild(nsnull);
   return !kid
     || !aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer);
 }
 
 void
-nsBidiPresUtils::TraverseFrames(nsBlockFrame* aBlockFrame,
-                                nsIFrame*     aCurrentFrame)
+nsBidiPresUtils::InitLogicalArray(nsIFrame*       aCurrentFrame)
 {
   if (!aCurrentFrame)
     return;
 
-  nsIFrame* childFrame = aCurrentFrame;
-  do {
-    /*
-     * It's important to get the next sibling and next continuation *before*
-     * handling the frame: If we encounter a forced paragraph break and call
-     * ResolveParagraph within this loop, doing GetNextSibling and
-     * GetNextContinuation after that could return a bidi continuation that had
-     * just been split from the original childFrame and we would process it
-     * twice.
-     */
-    nsIFrame* nextSibling = childFrame->GetNextSibling();
-    PRBool isLastFrame = !childFrame->GetNextContinuation();
+  nsIPresShell* shell = aCurrentFrame->PresContext()->PresShell();
+  nsStyleContext* styleContext;
+
+  for (nsIFrame* childFrame = aCurrentFrame; childFrame;
+       childFrame = childFrame->GetNextSibling()) {
 
     // If the real frame for a placeholder is a first letter frame, we need to
     // drill down into it and include its contents in Bidi resolution.
     // If not, we just use the placeholder.
     nsIFrame* frame = childFrame;
     if (nsGkAtoms::placeholderFrame == childFrame->GetType()) {
       nsIFrame* realFrame =
         nsPlaceholderFrame::GetRealFrameForPlaceholder(childFrame);
@@ -724,212 +644,118 @@ nsBidiPresUtils::TraverseFrames(nsBlockF
     PRUnichar ch = 0;
     if (frame->IsFrameOfType(nsIFrame::eBidiInlineContainer)) {
       const nsStyleVisibility* vis = frame->GetStyleVisibility();
       const nsStyleTextReset* text = frame->GetStyleTextReset();
       switch (text->mUnicodeBidi) {
         case NS_STYLE_UNICODE_BIDI_NORMAL:
           break;
         case NS_STYLE_UNICODE_BIDI_EMBED:
+          styleContext = frame->GetStyleContext();
+
           if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
             ch = kRLE;
           }
           else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) {
             ch = kLRE;
           }
           break;
         case NS_STYLE_UNICODE_BIDI_OVERRIDE:
+          styleContext = frame->GetStyleContext();
+
           if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
             ch = kRLO;
           }
           else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) {
             ch = kLRO;
           }
           break;
       }
 
-      // Add a dummy frame pointer representing a bidi control code before the
-      // first frame of an element specifying embedding or override
+      // Create a directional frame before the first frame of an
+      // element specifying embedding or override
       if (ch != 0 && !frame->GetPrevContinuation()) {
-        mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
-        mBuffer.Append(ch);
-        mEmbeddingStack.AppendElement(ch);
+        nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext, ch);
+        if (dirFrame) {
+          mLogicalFrames.AppendElement(dirFrame);
+        }
       }
     }
 
     if (IsBidiLeaf(frame)) {
       /* Bidi leaf frame: add the frame to the mLogicalFrames array,
        * and add its index to the mContentToFrameIndex hashtable. This
        * will be used in RemoveBidiContinuation() to identify the last
        * frame in the array with a given content.
        */
       nsIContent* content = frame->GetContent();
       if (content) {
         mContentToFrameIndex.Put(content, mLogicalFrames.Length());
       }
       mLogicalFrames.AppendElement(frame);
-
-      // Append the content of the frame to the paragraph buffer
-      nsIAtom* frameType = frame->GetType();
-      if (nsGkAtoms::textFrame == frameType) {
-        if (content != mPrevContent) {
-          mPrevContent = content;
-          if (!frame->GetStyleContext()->GetStyleText()->NewlineIsSignificant()) {
-            content->AppendTextTo(mBuffer);
-          } else {
-            /*
-             * For preformatted text we have to do bidi resolution on each line
-             * separately. 
-             */
-            nsAutoString text;
-            content->AppendTextTo(text);
-            nsIFrame* next;
-            do {
-              next = nsnull;
-
-              PRInt32 start, end;
-              frame->GetOffsets(start, end);
-              PRInt32 endLine = text.FindCharInSet(NS_LITERAL_STRING("\n\r"),
-                                                   start);
-              if (endLine == -1) {
-                /*
-                 * If there is no newline in the frame, just save the text and
-                 * do bidi resolution later
-                 */
-                mBuffer.Append(Substring(text, start));
-                break;
-              }
-
-              /*
-               * If there is a newline in the frame, break the frame after the
-               * newline, do bidi resolution and repeat until the end of the
-               * element.
-               */
-              ++endLine;
-
-              /*
-               * If the frame ends before the new line, save the text and move
-               * into the next continuation
-               */
-              while (end < endLine) {
-                mBuffer.Append(Substring(text, start, end - start));
-                frame = frame->GetNextContinuation();
-                NS_ASSERTION(frame, "Premature end of continuation chain");
-                frame->GetOffsets(start, end);
-                mLogicalFrames.AppendElement(frame);
-
-                /*
-                 * If we have already overshot the saved next-sibling while
-                 * scanning the frame's continuations, advance it.
-                 */
-                if (frame == nextSibling) {
-                  nextSibling = frame->GetNextSibling();
-                }
-              }
-
-              mBuffer.Append(Substring(text, start, endLine - start));
-
-              if (PRUint32(endLine) < text.Length()) {
-                nsTextFrame* textFrame = static_cast<nsTextFrame*>(frame);
-                textFrame->SetLength(endLine - start, nsnull);
-                next = frame->GetNextInFlow();
-                if (!next) {
-                  // If the frame already has a bidi continuation, make it fluid
-                  next = frame->GetNextContinuation();
-                  if (next) {
-                    MakeContinuationFluid(frame, next);
-                    JoinInlineAncestors(frame);
-                  } else {
-                    // If the frame has no next in flow, create one
-                    CreateContinuation(frame, &next, PR_TRUE);
-                  }
-                }
-              }
-              ResolveParagraphWithinBlock(aBlockFrame);
-
-              if (next) {
-                frame = next;
-                mLogicalFrames.AppendElement(frame);
-              }
-
-              /*
-               * If we have already overshot the saved next-sibling while
-               * scanning the frame's continuations, advance it.
-               */
-              if (frame && frame == nextSibling) {
-                nextSibling = frame->GetNextSibling();
-              }
-
-            } while (next);
-          }
-        }
-      } else if (nsGkAtoms::brFrame == frameType) {
-        // break frame -- append line separator
-        mBuffer.Append(kLineSeparator);
-        ResolveParagraphWithinBlock(aBlockFrame);
-      } else { 
-        // other frame type -- see the Unicode Bidi Algorithm:
-        // "...inline objects (such as graphics) are treated as if they are ...
-        // U+FFFC"
-        mBuffer.Append(kObjectSubstitute);
-        if (!frame->GetStyleContext()->GetStyleDisplay()->IsInlineOutside()) {
-          // if it is not inline, end the paragraph
-          ResolveParagraphWithinBlock(aBlockFrame);
-        }
-      }
     }
     else {
-      // For a non-leaf frame, recurse into TraverseFrames
       nsIFrame* kid = frame->GetFirstChild(nsnull);
-      TraverseFrames(aBlockFrame, kid);
+      InitLogicalArray(kid);
     }
 
     // If the element is attributed by dir, indicate direction pop (add PDF frame)
-    if (ch != 0 && isLastFrame) {
-      // Add a dummy frame pointer representing a bidi control code after the
-      // last frame of an element specifying embedding or override
-      mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
-      mBuffer.Append(kPDF);
-      NS_ASSERTION(mEmbeddingStack.Length(), "embedding/override underflow");
-      mEmbeddingStack.TruncateLength(mEmbeddingStack.Length() - 1);
+    if (ch != 0 && !frame->GetNextContinuation()) {
+      // Create a directional frame after the last frame of an
+      // element specifying embedding or override
+      nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext, kPDF);
+      if (dirFrame) {
+        mLogicalFrames.AppendElement(dirFrame);
+      }
     }
-    childFrame = nextSibling;
-  } while (childFrame);
+  } // for
 }
 
 void
-nsBidiPresUtils::ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame)
+nsBidiPresUtils::CreateBlockBuffer()
 {
-  nsIPresShell* shell;
-  nsStyleContext* styleContext;
+  mBuffer.SetLength(0);
+
+  nsIFrame*                 frame;
+  nsIContent*               prevContent = nsnull;
+  PRUint32                  i;
+  PRUint32                  count = mLogicalFrames.Length();
+
+  for (i = 0; i < count; i++) {
+    frame = mLogicalFrames[i];
+    nsIAtom* frameType = frame->GetType();
 
-  if (mEmbeddingStack.Length() > 0) {
-    shell = aBlockFrame->PresContext()->PresShell();
-    styleContext = aBlockFrame->GetStyleContext();
-
-    // pop all embeddings and overrides
-    for (PRUint32 i = 0; i < mEmbeddingStack.Length(); ++i) {
-      mBuffer.Append(kPDF);
-      mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
+    if (nsGkAtoms::textFrame == frameType) {
+      nsIContent* content = frame->GetContent();
+      if (!content) {
+        mSuccess = NS_OK;
+        break;
+      }
+      if (content == prevContent) {
+        continue;
+      }
+      prevContent = content;
+      content->AppendTextTo(mBuffer);
+    }
+    else if (nsGkAtoms::brFrame == frameType) { // break frame
+      // Append line separator
+      mBuffer.Append(kLineSeparator);
+    }
+    else if (nsGkAtoms::directionalFrame == frameType) {
+      nsDirectionalFrame* dirFrame = static_cast<nsDirectionalFrame*>(frame);
+      mBuffer.Append(dirFrame->GetChar());
+    }
+    else { // not text frame
+      // See the Unicode Bidi Algorithm:
+      // "...inline objects (such as graphics) are treated as if they are ... U+FFFC"
+      mBuffer.Append(kObjectSubstitute);
     }
   }
-
-  ResolveParagraph(aBlockFrame);
-
-  // Clear the frame array and paragraph buffer, and restore the stored 
-  // embeddings and overrides
-  mLogicalFrames.Clear();
-  mContentToFrameIndex.Clear();
-  mBuffer.SetLength(0);
-  if (mEmbeddingStack.Length() > 0) {
-    for (PRUint32 i = 0; i < mEmbeddingStack.Length(); ++i) {
-      mBuffer.Append(mEmbeddingStack[i]);
-      mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME);
-    }
-  } 
+  // XXX: TODO: Handle preformatted text ('\n')
+  mBuffer.ReplaceChar("\t\r\n", kSpace);
 }
 
 void
 nsBidiPresUtils::ReorderFrames(nsIFrame*            aFirstFrameOnLine,
                                PRInt32              aNumFramesOnLine)
 {
   // If this line consists of a line frame, reorder the line frame's children.
   if (aFirstFrameOnLine->GetType() == nsGkAtoms::lineFrame) {
@@ -1366,49 +1192,57 @@ nsBidiPresUtils::EnsureBidiContinuation(
                                         PRInt32&        aFrameIndex,
                                         PRInt32         aStart,
                                         PRInt32         aEnd)
 {
   NS_PRECONDITION(aNewFrame, "null OUT ptr");
   NS_PRECONDITION(aFrame, "aFrame is null");
 
   aFrame->AdjustOffsetsForBidi(aStart, aEnd);
-  mSuccess = CreateContinuation(aFrame, aNewFrame, PR_FALSE);
+  mSuccess = CreateBidiContinuation(aFrame, aNewFrame);
 }
 
 void
 nsBidiPresUtils::RemoveBidiContinuation(nsIFrame*       aFrame,
                                         PRInt32         aFirstIndex,
                                         PRInt32         aLastIndex,
                                         PRInt32&        aOffset) const
 {
   FrameProperties props = aFrame->Properties();
   nsBidiLevel embeddingLevel =
     (nsBidiLevel)NS_PTR_TO_INT32(props.Get(nsIFrame::EmbeddingLevelProperty()));
   nsBidiLevel baseLevel =
     (nsBidiLevel)NS_PTR_TO_INT32(props.Get(nsIFrame::BaseLevelProperty()));
 
   for (PRInt32 index = aFirstIndex + 1; index <= aLastIndex; index++) {
     nsIFrame* frame = mLogicalFrames[index];
-    if (frame == NS_BIDI_CONTROL_FRAME) {
+    if (nsGkAtoms::directionalFrame == frame->GetType()) {
+      frame->Destroy();
       ++aOffset;
     }
     else {
       // Make the frame and its continuation ancestors fluid,
       // so they can be reused or deleted by normal reflow code
       FrameProperties frameProps = frame->Properties();
       frameProps.Set(nsIFrame::EmbeddingLevelProperty(),
                      NS_INT32_TO_PTR(embeddingLevel));
       frameProps.Set(nsIFrame::BaseLevelProperty(),
                      NS_INT32_TO_PTR(baseLevel));
       frame->AddStateBits(NS_FRAME_IS_BIDI);
       while (frame) {
         nsIFrame* prev = frame->GetPrevContinuation();
         if (prev) {
-          MakeContinuationFluid(prev, frame);
+          NS_ASSERTION (!frame->GetPrevInFlow() || frame->GetPrevInFlow() == prev, 
+                        "prev-in-flow is not prev continuation!");
+          frame->SetPrevInFlow(prev);
+
+          NS_ASSERTION (!prev->GetNextInFlow() || prev->GetNextInFlow() == frame,
+                        "next-in-flow is not next continuation!");
+          prev->SetNextInFlow(frame);
+
           frame = frame->GetParent();
         } else {
           break;
         }
       }
     }
   }
 }
--- a/layout/base/nsBidiPresUtils.h
+++ b/layout/base/nsBidiPresUtils.h
@@ -170,18 +170,16 @@ public:
    * Make Bidi engine calculate the embedding levels of the frames that are
    * descendants of a given block frame.
    *
    * @param aBlockFrame          The block frame
    *
    *  @lina 06/18/2000
    */
   nsresult Resolve(nsBlockFrame* aBlockFrame);
-  void ResolveParagraph(nsBlockFrame* aBlockFrame);
-  void ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame);
 
   /**
    * Reorder this line using Bidi engine.
    * Update frame array, following the new visual sequence.
    * 
    * @lina 05/02/2000
    */
   void ReorderFrames(nsIFrame*            aFirstFrameOnLine,
@@ -359,24 +357,28 @@ private:
                                           Mode                   aMode,
                                           nscoord                aX, // DRAW only
                                           nscoord                aY, // DRAW only
                                           nsBidiPositionResolve* aPosResolve,  /* may be null */
                                           PRInt32                aPosResolveCount,
                                           nscoord*               aWidth /* may be null */);
 
   /**
-   * Traverse the child frames of the block element and:
-   *  Set up an array of the frames in logical order
-   *  Create a string containing the text content of all the frames
-   *  If we encounter content that requires us to split the element into more
-   *  than one paragraph for bidi resolution, resolve the paragraph up to that
-   *  point.
+   *  Create a string containing entire text content of this block.
+   *
+   *  @lina 05/02/2000
    */
-  void TraverseFrames(nsBlockFrame* aBlockFrame, nsIFrame* aCurrentFrame);
+  void CreateBlockBuffer();
+
+  /**
+   * Set up an array of the frames after splitting frames so that each frame has
+   * consistent directionality. At this point the frames are still in logical
+   * order
+   */
+  void InitLogicalArray(nsIFrame* aCurrentFrame);
 
   /**
    * Initialize the logically-ordered array of frames
    * using the top-level frames of a single line
    */
   void InitLogicalArrayFromLine(nsIFrame* aFirstFrameOnLine,
                                 PRInt32   aNumFramesOnLine);
 
@@ -506,29 +508,23 @@ private:
                                      PRUnichar* aDest,
                                      nsBidiLevel aBaseDirection,
                                      nsBidi* aBidiEngine);
 
  static void WriteReverse(const PRUnichar* aSrc,
                           PRUint32 aSrcLength,
                           PRUnichar* aDest);
 
-  nsString        mBuffer;
-  nsTArray<PRUnichar> mEmbeddingStack;
+  nsAutoString    mBuffer;
   nsTArray<nsIFrame*> mLogicalFrames;
   nsTArray<nsIFrame*> mVisualFrames;
   nsDataHashtable<nsISupportsHashKey, PRInt32> mContentToFrameIndex;
   PRInt32         mArraySize;
   PRInt32*        mIndexMap;
   PRUint8*        mLevels;
   nsresult        mSuccess;
-  PRPackedBool    mIsVisual;
-  nsBidiLevel     mParaLevel;
-  nsIFrame*       mPrevFrame;
-  nsIContent*     mPrevContent;
 
-  nsAutoPtr<nsBlockInFlowLineIterator> mLineIter;
   nsBidi*         mBidiEngine;
 };
 
 #endif /* nsBidiPresUtils_h___ */
 
 #endif // IBMBIDI
--- a/layout/base/tests/Makefile.in
+++ b/layout/base/tests/Makefile.in
@@ -318,16 +318,18 @@ ifeq (,$(filter windows,$(MOZ_WIDGET_TOO
 		test_bug570378-persian-5c.html \
 		test_bug570378-persian-5d.html \
 		test_bug570378-persian-5e.html \
 		test_bug570378-persian-5f.html \
 		test_bug570378-persian-5g.html \
 		bug570378-persian-5.html \
 		bug570378-persian-5-ref.html \
 		test_bug588174.html \
+		test_bug607529.html \
+		file_bug607529.html \
 		$(NULL)
 endif
 
 _BROWSER_FILES = \
 	browser_bug617076.js \
 	$(NULL)
 
 libs:: $(_TEST_FILES)
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/file_bug607529.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<script>
+  window.onerror = function(msg, url, line) {
+    var myMsg = JSON.stringify({msg: msg, url: url, line: line, error: true});
+    opener.postMessage(myMsg, "*");
+  }
+  
+  var report = false;
+  
+  function f() {
+    if (report) {
+      opener.postMessage("eventHappened", "*");
+    }
+    window.mozRequestAnimationFrame();
+  }
+  document.addEventListener("MozBeforePaint", f, false);
+  f();
+
+  function g() {
+    if (report) {
+      opener.postMessage("callbackHappened", "*");
+    }
+    window.mozRequestAnimationFrame(g);
+  }
+  g();
+
+  window.onload = function() {
+    opener.postMessage("loaded", "*");
+  }
+
+  addEventListener("pagehide", function f(e) {
+    if (!e.persisted && !report) {
+      opener.postMessage("notcached", "*");
+    }
+  }, false);
+
+  addEventListener("pageshow", function f(e) {
+    if (e.persisted) {
+      opener.postMessage("revived", "*");
+    }
+  }, false);
+
+  window.onmessage = function (e) {
+    if (e.data == "report") {
+      report = true;
+    }
+  };
+
+</script>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/test_bug607529.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=607529
+-->
+<head>
+  <title>Test for Bug 607529</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=607529">Mozilla Bug 607529</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+  SimpleTest.waitForExplicitFinish();
+
+  /* General idea: Open a new window (needed because we don't bfcache
+     subframes) that uses mozRequestAnimationFrame, navigate it, navigate it
+     back, and verify that the animations are still running.  */
+
+  var doneOneLoad = false;
+
+  var eventsHappening = false;
+  var callbacksHappening = false;
+
+  function tryFinishTest() {
+    if (eventsHappening && callbacksHappening) {
+      w.close();
+      SimpleTest.finish();
+    }
+  }
+
+  /** Test for Bug 607529 **/
+  window.onmessage = function(e) {
+    isnot(e.data, "notcached", "Should never end up not being cached");
+  
+    if (e.data == "loaded" && !doneOneLoad) {
+      doneOneLoad = true;
+      w.location = "data:text/html,<script>window.onload = function() { opener.postMessage('goback', '*'); }</" + "script>";
+    }
+    else if (e.data == "goback") {
+      w.history.back();
+    }
+    else if (e.data == "revived") {
+      w.postMessage("report", "*");
+    }
+    else if (e.data == "eventHappened") {
+      eventsHappening = true;
+      tryFinishTest();
+    }
+    else if (e.data == "callbackHappened") {
+      callbacksHappening = true;
+      tryFinishTest();
+    } else {
+      var msg = JSON.parse(e.data);
+      if (msg.error) {
+        window.onerror(msg.msg, msg.url, msg.line);
+      }
+    }
+  };
+
+  var w = window.open("file_bug607529.html");
+</script>
+</pre>
+</body>
+</html>
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1024,17 +1024,17 @@ nsComboboxControlFrame::CreateAnonymousC
     mListControlFrame->GetOptionText(mDisplayedIndex, mDisplayedOptionText);
   }
   ActuallyDisplayText(PR_FALSE);
 
   if (!aElements.AppendElement(mDisplayContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
-  nodeInfo = nimgr->GetNodeInfo(nsGkAtoms::input, nsnull, kNameSpaceID_XHTML);
+  nodeInfo = nimgr->GetNodeInfo(nsGkAtoms::button, nsnull, kNameSpaceID_XHTML);
 
   // create button which drops the list down
   NS_NewHTMLElement(getter_AddRefs(mButtonContent), nodeInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mButtonContent)
     return NS_ERROR_OUT_OF_MEMORY;
 
   // make someone to listen to the button. If its pressed by someone like Accessibility
@@ -1260,17 +1260,17 @@ nsComboboxControlFrame::SetInitialChildL
 {
   nsresult rv = NS_OK;
   if (nsGkAtoms::selectPopupList == aListName) {
     mPopupFrames.SetFrames(aChildList);
   } else {
     for (nsFrameList::Enumerator e(aChildList); !e.AtEnd(); e.Next()) {
       nsCOMPtr<nsIFormControl> formControl =
         do_QueryInterface(e.get()->GetContent());
-      if (formControl && formControl->GetType() == NS_FORM_INPUT_BUTTON) {
+      if (formControl && formControl->GetType() == NS_FORM_BUTTON_BUTTON) {
         mButtonFrame = e.get();
         break;
       }
     }
     NS_ASSERTION(mButtonFrame, "missing button frame in initial child list");
     rv = nsBlockFrame::SetInitialChildList(aListName, aChildList);
   }
   return rv;
--- a/layout/generic/Makefile.in
+++ b/layout/generic/Makefile.in
@@ -66,16 +66,23 @@ EXPORTS		= \
 		nsIObjectFrame.h \
 		nsIPageSequenceFrame.h \
 		nsIScrollableFrame.h \
 		nsIStatefulFrame.h \
 		nsFrameSelection.h \
 		nsSubDocumentFrame.h \
 		$(NULL)
 
+ifdef IBMBIDI
+EXPORTS		+= \
+		nsBidiFrames.h      \
+		$(NULL)
+endif
+
+
 CPPSRCS		= \
 		nsAbsoluteContainingBlock.cpp \
 		nsBRFrame.cpp \
 		nsBlockFrame.cpp \
 		nsBlockReflowContext.cpp \
 		nsBlockReflowState.cpp \
 		nsBulletFrame.cpp \
 		nsColumnSetFrame.cpp \
@@ -114,16 +121,22 @@ CPPSRCS		= \
 		$(NULL)
 
 ifdef MOZ_MEDIA
 CPPSRCS		+= \
 		nsVideoFrame.cpp \
 		$(NULL)
 endif
 
+ifdef IBMBIDI
+CPPSRCS		+= \
+		nsBidiFrames.cpp \
+		$(NULL)
+endif
+
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CMMSRCS		+= \
 		nsPluginUtilsOSX.mm \
 		$(NULL)
 endif
 
 RESOURCES_HTML = \
 		$(srcdir)/folder.png \
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/645072-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html lang=ru>
+<head>
+<meta charset=windows-1251>
+<title>Testcase, bug 645072</title>
+</head>
+<body>
+<table cellspacing=0 cellpadding=0 border=0>
+	<tr valign=top><td>ะเ็์๛๒๛ๅ,็ๅ๋ๅํ๛ๅ,ํ๎&shy;<wbr> ๊๋เ๑๑ํ๛ๅ)<br>&shy;<wbr><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAABpJREFUWMPtwQEBAAAAgiD/r25IQAEAAADvBhAgAAGX91fXAAAAAElFTkSuQmCC" alt="">&shy;<wbr>
+</table>
+<script>
+// simulate image loading
+document.body.offsetWidth;
+document.getElementsByTagName("img")[0].style.width = "604px";
+document.getElementsByTagName("img")[0].style.height = "405px";
+</script>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -348,8 +348,9 @@ load 594808-1.html
 asserts(4) load 595435-1.xhtml # bug 610331
 load 595740-1.html
 load 603490-1.html
 load 603510-1.html
 load 604314-1.html
 load 604843.html
 load 605340.html
 load 621841-1.html
+load 645072-1.html
new file mode 100644
--- /dev/null
+++ b/layout/generic/nsBidiFrames.cpp
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * 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 ***** */
+
+#ifdef IBMBIDI
+
+#include "nsBidiFrames.h"
+#include "nsGkAtoms.h"
+
+
+nsDirectionalFrame::nsDirectionalFrame(nsStyleContext* aContext, PRUnichar aChar)
+  : nsFrame(aContext), mChar(aChar)
+{
+}
+
+nsDirectionalFrame::~nsDirectionalFrame()
+{
+}
+
+nsIAtom*
+nsDirectionalFrame::GetType() const
+{ 
+  return nsGkAtoms::directionalFrame;
+}
+  
+#ifdef NS_DEBUG
+NS_IMETHODIMP
+nsDirectionalFrame::GetFrameName(nsAString& aResult) const
+{
+  return MakeFrameName(NS_LITERAL_STRING("Directional"), aResult);
+}
+#endif
+
+nsIFrame*
+NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUnichar aChar)
+{
+  return new (aPresShell) nsDirectionalFrame(aContext, aChar);
+}
+
+NS_IMPL_FRAMEARENA_HELPERS(nsDirectionalFrame)
+
+#endif /* IBMBIDI */
new file mode 100644
--- /dev/null
+++ b/layout/generic/nsBidiFrames.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * 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 ***** */
+
+#ifdef IBMBIDI
+
+#ifndef nsBidiFrames_h___
+#define nsBidiFrames_h___
+
+#include "nsFrame.h"
+
+
+class nsDirectionalFrame : public nsFrame
+{
+protected:
+  virtual ~nsDirectionalFrame();
+
+public:
+  NS_DECL_FRAMEARENA_HELPERS
+
+  nsDirectionalFrame(nsStyleContext* aContext, PRUnichar aChar);
+
+  /**
+   * Get the "type" of the frame
+   *
+   * @see nsGkAtoms::directionalFrame
+   */
+  virtual nsIAtom* GetType() const;
+
+  PRUnichar GetChar() const { return mChar; }
+
+#ifdef NS_DEBUG
+  NS_IMETHOD GetFrameName(nsAString& aResult) const;
+#endif
+
+private:
+  PRUnichar mChar;
+};
+
+
+#endif /* nsBidiFrames_h___ */
+#endif /* IBMBIDI */
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3179,29 +3179,27 @@ nsIFrame::InlineMinWidthData::ForceBreak
       prevLines = float_min;
   }
   floats.Clear();
   trailingTextFrame = nsnull;
   skipWhitespace = PR_TRUE;
 }
 
 void
-nsIFrame::InlineMinWidthData::OptionallyBreak(nsIRenderingContext *aRenderingContext,
-                                              nscoord aHyphenWidth)
+nsIFrame::InlineMinWidthData::OptionallyBreak(nsIRenderingContext *aRenderingContext)
 {
   trailingTextFrame = nsnull;
 
   // If we can fit more content into a smaller width by staying on this
   // line (because we're still at a negative offset due to negative
   // text-indent or negative margin), don't break.  Otherwise, do the
   // same as ForceBreak.  it doesn't really matter when we accumulate
   // floats.
-  if (currentLine + aHyphenWidth < 0 || atStartOfLine)
+  if (currentLine < 0 || atStartOfLine)
     return;
-  currentLine += aHyphenWidth;
   ForceBreak(aRenderingContext);
 }
 
 void
 nsIFrame::InlinePrefWidthData::ForceBreak(nsIRenderingContext *aRenderingContext)
 {
   if (floats.Length() != 0) {
             // preferred widths accumulated for floats that have already
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1460,21 +1460,17 @@ public:
       , atStartOfLine(PR_TRUE)
     {}
 
     // We need to distinguish forced and optional breaks for cases where the
     // current line total is negative.  When it is, we need to ignore
     // optional breaks to prevent min-width from ending up bigger than
     // pref-width.
     void ForceBreak(nsIRenderingContext *aRenderingContext);
-
-    // If the break here is actually taken, aHyphenWidth must be added to the
-    // width of the current line.
-    void OptionallyBreak(nsIRenderingContext *aRenderingContext,
-                         nscoord aHyphenWidth = 0);
+    void OptionallyBreak(nsIRenderingContext *aRenderingContext);
 
     // The last text frame processed so far in the current line, when
     // the last characters in that text frame are relevant for line
     // break opportunities.
     nsIFrame *trailingTextFrame;
 
     // Whether we're currently at the start of the line.  If we are, we
     // can't break (for example, between the text-indent and the first
--- a/layout/generic/nsQueryFrame.h
+++ b/layout/generic/nsQueryFrame.h
@@ -83,16 +83,17 @@ public:
     nsButtonBoxFrame_id,
     nsCanvasFrame_id,
     nsColumnSetFrame_id,
     nsComboboxControlFrame_id,
     nsComboboxDisplayFrame_id,
     nsContainerFrame_id,
     nsContinuingTextFrame_id,
     nsDeckFrame_id,
+    nsDirectionalFrame_id,
     nsDocElementBoxFrame_id,
     nsFieldSetFrame_id,
     nsFileControlFrame_id,
     nsFirstLetterFrame_id,
     nsFirstLineFrame_id,
     nsFormControlFrame_id,
     nsFrame_id,
     nsGfxButtonControlFrame_id,
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -103,16 +103,17 @@
 #include "nsILineIterator.h"
 
 #include "nsIServiceManager.h"
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 #include "nsAutoPtr.h"
 
+#include "nsBidiFrames.h"
 #include "nsBidiPresUtils.h"
 #include "nsBidiUtils.h"
 
 #include "nsIThebesFontMetrics.h"
 #include "gfxFont.h"
 #include "gfxContext.h"
 #include "gfxTextRunWordCache.h"
 #include "gfxImageSurface.h"
@@ -555,19 +556,16 @@ MakeTextRun(const PRUnichar *aText, PRUi
     }
     if (!textRun)
         return nsnull;
     nsresult rv = gTextRuns->AddObject(textRun);
     if (NS_FAILED(rv)) {
         gTextRuns->RemoveFromCache(textRun);
         return nsnull;
     }
-#ifdef NOISY_BIDI
-    printf("Created textrun\n");
-#endif
     return textRun.forget();
 }
 
 static gfxTextRun *
 MakeTextRun(const PRUint8 *aText, PRUint32 aLength,
             gfxFontGroup *aFontGroup, const gfxFontGroup::Parameters* aParams,
             PRUint32 aFlags)
 {
@@ -582,19 +580,16 @@ MakeTextRun(const PRUint8 *aText, PRUint
     }
     if (!textRun)
         return nsnull;
     nsresult rv = gTextRuns->AddObject(textRun);
     if (NS_FAILED(rv)) {
         gTextRuns->RemoveFromCache(textRun);
         return nsnull;
     }
-#ifdef NOISY_BIDI
-    printf("Created textrun\n");
-#endif
     return textRun.forget();
 }
 
 nsresult
 nsTextFrameTextRunCache::Init() {
     gTextRuns = new FrameTextRunCache();
     return gTextRuns ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
@@ -6067,61 +6062,38 @@ nsTextFrame::AddInlineMinWidthForFlow(ns
     EnsureTextRun(ctx, aData->lineContainer, aData->line, &flowEndInTextRun);
   if (!mTextRun)
     return;
 
   // Pass null for the line container. This will disable tab spacing, but that's
   // OK since we can't really handle tabs for intrinsic sizing anyway.
   const nsStyleText* textStyle = GetStyleText();
   const nsTextFragment* frag = mContent->GetText();
-
-  // If we're hyphenating, the PropertyProvider needs the actual length;
-  // otherwise we can just pass PR_INT32_MAX to mean "all the text"
-  PRInt32 len = PR_INT32_MAX;
-  PRBool hyphenating =
-    (mTextRun->GetFlags() & gfxTextRunFactory::TEXT_ENABLE_HYPHEN_BREAKS) != 0;
-  if (hyphenating) {
-    gfxSkipCharsIterator tmp(iter);
-    len =
-      tmp.ConvertSkippedToOriginal(flowEndInTextRun) - iter.GetOriginalOffset();
-  }
   PropertyProvider provider(mTextRun, textStyle, frag, this,
-                            iter, len, nsnull, 0);
+                            iter, PR_INT32_MAX, nsnull, 0);
 
   PRBool collapseWhitespace = !textStyle->WhiteSpaceIsSignificant();
   PRBool preformatNewlines = textStyle->NewlineIsSignificant();
   PRBool preformatTabs = textStyle->WhiteSpaceIsSignificant();
   gfxFloat tabWidth = -1;
   PRUint32 start =
     FindStartAfterSkippingWhitespace(&provider, aData, textStyle, &iter, flowEndInTextRun);
 
-  nsAutoTArray<PRPackedBool,BIG_TEXT_NODE_SIZE> hyphBuffer;
-  PRPackedBool *hyphBreakBefore = nsnull;
-  if (hyphenating) {
-    hyphBreakBefore = hyphBuffer.AppendElements(flowEndInTextRun - start);
-    if (hyphBreakBefore) {
-      provider.GetHyphenationBreaks(start, flowEndInTextRun - start,
-                                    hyphBreakBefore);
-    }
-  }
-
+  // XXX Should we consider hyphenation here?
   for (PRUint32 i = start, wordStart = start; i <= flowEndInTextRun; ++i) {
     PRBool preformattedNewline = PR_FALSE;
     PRBool preformattedTab = PR_FALSE;
     if (i < flowEndInTextRun) {
       // XXXldb Shouldn't we be including the newline as part of the
       // segment that it ends rather than part of the segment that it
       // starts?
       preformattedNewline = preformatNewlines && mTextRun->GetChar(i) == '\n';
       preformattedTab = preformatTabs && mTextRun->GetChar(i) == '\t';
-      if (!mTextRun->CanBreakLineBefore(i) &&
-          !preformattedNewline &&
-          !preformattedTab &&
-          (!hyphBreakBefore || !hyphBreakBefore[i - start]))
-      {
+      if (!mTextRun->CanBreakLineBefore(i) && !preformattedNewline &&
+          !preformattedTab) {
         // we can't break here (and it's not the end of the flow)
         continue;
       }
     }
 
     if (i > wordStart) {
       nscoord width =
         NSToCoordCeilClamped(mTextRun->GetAdvanceWidth(wordStart, i - wordStart, &provider));
@@ -6153,18 +6125,16 @@ nsTextFrame::AddInlineMinWidthForFlow(ns
                          mTextRun, &tabWidth);
       aData->currentLine = nscoord(afterTab + spacing.mAfter);
       wordStart = i + 1;
     } else if (i < flowEndInTextRun ||
         (i == mTextRun->GetLength() &&
          (mTextRun->GetFlags() & nsTextFrameUtils::TEXT_HAS_TRAILING_BREAK))) {
       if (preformattedNewline) {
         aData->ForceBreak(aRenderingContext);
-      } else if (hyphBreakBefore && hyphBreakBefore[i - start]) {
-        aData->OptionallyBreak(aRenderingContext, provider.GetHyphenWidth());
       } else {
         aData->OptionallyBreak(aRenderingContext);
       }
       wordStart = i;
     }
   }
 
   if (start < flowEndInTextRun) {
@@ -6601,20 +6571,16 @@ nsTextFrame::ReflowText(nsLineLayout& aL
   }
   else {
     if (0 != (mState & TEXT_BLINK_ON)) {
       mState &= ~TEXT_BLINK_ON;
       nsBlinkTimer::RemoveBlinkFrame(this);
     }
   }
 
-#ifdef NOISY_BIDI
-    printf("Reflowed textframe\n");
-#endif
-
   const nsStyleText* textStyle = GetStyleText();
 
   PRBool atStartOfLine = aLineLayout.LineAtStart();
   if (atStartOfLine) {
     AddStateBits(TEXT_START_OF_LINE);
   }
 
   PRUint32 flowEndInTextRun;
deleted file mode 100644
--- a/layout/reftests/bidi/229367-1-ref.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
-  <title>br-as-bidi-paragraph-break</title>
-  <meta charset="UTF-8">
- </head>
- <body>
-  <p>&#x05D0; --&gt;&lrm;<br>--&gt; &#x05D1;</p>
- </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/229367-1.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
-  <title>br-as-bidi-paragraph-break</title>
-  <meta charset="UTF-8">
- </head>
- <body>
-  <p>&#x05D0; --&gt;<br>--&gt; &#x05D1;</p>
- </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/229367-2-ref.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<DOCTYPE html>
-<html DIR=RTL>
- <head>
-  <meta charset=UTF-8>
-  <title>BIDI Layout Testing</title>
- </head>
- <body>
-  <h2>This is a testing for BiDi layout issues.</h2> 
-<br> 
- 
-1 - No tag<br> 
-2 - SPAN<br> 
-3 - P<br> 
-4 - DIV<br> 
-
-<br> 
-<b>Test1: No space</b><br> 
-This is a testing for BiDi layout issues.&rlm;<br> 
-<span>This is a testing for BiDi layout issues.&rlm;<br></span> 
-<p>This is a testing for BiDi layout issues.&rlm;<br></p> 
-<div>This is a testing for BiDi layout issues.&rlm;<br></div> 
-<br><br> 
-<b>Test2: 3 spaces at the end</b><br> 
-This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;<br> 
-<span>This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;<br></span> 
-
-<p>This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;<br></p> 
-<div>This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;<br></div> 
-<br><br> 
-<b>Test3: 3 spaces at the beginning</b><br> 
-&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;<br> 
-<span>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;<br></span> 
-<p>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;<br></p> 
-<div>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;<br></div> 
-<br><br> 
-
-<b>Test4: 3 spaces at the end and the beginning</b><br> 
-&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;<br> 
-<span>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;<br></span> 
-<p>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;<br></p> 
-<div>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;<br></div> 
- </body> 
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/229367-2.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<DOCTYPE html>
-<html DIR=RTL>
- <head>
-  <meta charset=UTF-8>
-  <title>BIDI Layout Testing</title>
- </head>
- <body>
-  <h2>This is a testing for BiDi layout issues.</h2> 
-<br> 
- 
-1 - No tag<br> 
-2 - SPAN<br> 
-3 - P<br> 
-4 - DIV<br> 
-
-<br> 
-<b>Test1: No space</b><br> 
-This is a testing for BiDi layout issues.<br> 
-<span>This is a testing for BiDi layout issues.<br></span> 
-<p>This is a testing for BiDi layout issues.<br></p> 
-<div>This is a testing for BiDi layout issues.<br></div> 
-<br><br> 
-<b>Test2: 3 spaces at the end</b><br> 
-This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;<br> 
-<span>This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;<br></span> 
-
-<p>This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;<br></p> 
-<div>This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;<br></div> 
-<br><br> 
-<b>Test3: 3 spaces at the beginning</b><br> 
-&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.<br> 
-<span>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.<br></span> 
-<p>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.<br></p> 
-<div>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.<br></div> 
-<br><br> 
-
-<b>Test4: 3 spaces at the end and the beginning</b><br> 
-&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;<br> 
-<span>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;<br></span> 
-<p>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;<br></p> 
-<div>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;<br></div> 
- </body> 
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/229367-3-ref.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<DOCTYPE html>
-<!-- This tests that embeddings and overrides are preserved after <br> -->
-<html>
- <head>
-  <meta charset=UTF-8>
-  <title>Bug 229367</title>
-  <style type="text/css">
-   p { margin: 0; text-align: left; }
-   p.er { unicode-bidi: embed; direction: rtl; }
-   p.ol { unicode-bidi: bidi-override; direction: ltr; }
-   p.or { unicode-bidi: bidi-override; direction: rtl; }
-  </style>
- </head>
- <body>
-  <p>ื‘ืžื” ืžื“ืœื™ืงื™ืŸ,</p>
-  <p>ื•ื‘ืžื” ืื™ืŸ ืžื“ืœื™ืงื™ืŸ?</p>
-  <p class="er">ืื™ืŸ ืžื“ืœื™ืงื™ืŸ ืœื ื‘ืœื›ืฉ, </p>
-  <p class="er">ื•ืœื ื‘ื—ื•ืกืŸ, </p>
-  <p class="er">ื•ืœื ื‘ื›ืœืš, </p>
-  <p class="er">ื•ืœื ื‘ืคืชื™ืœืช ื”ืื™ื“ืŸ, </p>
-  <p class="ol">ื•ืœื ื‘ืคืชื™ืœืช ื”ืžื“ื‘ืจ, </p>
-  <p class="ol">ื•ืœื ื‘ื™ืจื•ืงื” ืฉืขืœ ืคื ื™ ื”ืžื™ื.  </p>
-  <p class="ol">ืœื ื‘ื–ืคืช, </p>
-  <p class="or">ื•ืœื ื‘ืฉืขื•ื•ื”, </p>
-  <p class="or">ื•ืœื ื‘ืฉืžืŸ ืงื™ืง, </p>
-  <p class="or">ื•ืœื ื‘ืฉืžืŸ ืฉืจื™ืคื”, </p>
-  <p class="or">ื•ืœื ื‘ืืœื™ื”, </p>
-  <p class="ol">ื•ืœื ื‘ื—ืœื‘.  </p>
-  <p class="ol">ื ื—ื•ื ื”ืžื“ื™ ืื•ืžืจ, </p>
-  <p class="er">ืžื“ืœื™ืงื™ืŸ ื‘ื—ืœื‘ ืžื‘ื•ืฉืœ;</p>
-  <p class="er">ื•ื—ื›ืžื™ื ืื•ืžืจื™ื, </p>
-  <p>ืื—ื“ ืžื‘ื•ืฉืœ ื•ืื—ื“ ืฉืื™ื ื• ืžื‘ื•ืฉืœ,</p>
-  <p>ืื™ืŸ ืžื“ืœื™ืงื™ืŸ ื‘ื•.</p>
- </body> 
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/229367-3.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<DOCTYPE html>
-<!-- This tests that embeddings and overrides are preserved after <br> -->
-<html>
- <head>
-  <meta charset=UTF-8>
-  <title>Bug 229367</title>
- </head>
- <body>
-  <div>ื‘ืžื” ืžื“ืœื™ืงื™ืŸ,<br>
-ื•ื‘ืžื” ืื™ืŸ ืžื“ืœื™ืงื™ืŸ?<br>
-<span style="unicode-bidi: embed; direction: rtl">ืื™ืŸ ืžื“ืœื™ืงื™ืŸ ืœื ื‘ืœื›ืฉ, <br>
-ื•ืœื ื‘ื—ื•ืกืŸ, <br>
-ื•ืœื ื‘ื›ืœืš, <br>
-ื•ืœื ื‘ืคืชื™ืœืช ื”ืื™ื“ืŸ, <br>
-<span style="unicode-bidi: bidi-override; direction: ltr">ื•ืœื ื‘ืคืชื™ืœืช ื”ืžื“ื‘ืจ, <br>
-ื•ืœื ื‘ื™ืจื•ืงื” ืฉืขืœ ืคื ื™ ื”ืžื™ื.  <br>
-ืœื ื‘ื–ืคืช, <br>
-<span style="unicode-bidi: bidi-override; direction: rtl">ื•ืœื ื‘ืฉืขื•ื•ื”, <br>
-ื•ืœื ื‘ืฉืžืŸ ืงื™ืง, <br>
-ื•ืœื ื‘ืฉืžืŸ ืฉืจื™ืคื”, <br>
-ื•ืœื ื‘ืืœื™ื”, <br></span>
-ื•ืœื ื‘ื—ืœื‘.  <br>
-ื ื—ื•ื ื”ืžื“ื™ ืื•ืžืจ, <br></span>
-ืžื“ืœื™ืงื™ืŸ ื‘ื—ืœื‘ ืžื‘ื•ืฉืœ; <br>
-ื•ื—ื›ืžื™ื ืื•ืžืจื™ื, <br></span>
-ืื—ื“ ืžื‘ื•ืฉืœ ื•ืื—ื“ ืฉืื™ื ื• ืžื‘ื•ืฉืœ,<br>
-ืื™ืŸ ืžื“ืœื™ืงื™ืŸ ื‘ื•.
-  </div> 
- </body> 
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/263359-1-ref.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
-  <title>preformatted-paragraph-break-as-bidi-paragraph-break</title>
-  <meta charset="UTF-8">
- </head>
- <body>
-  <pre>&#x05D0; --&gt;&lrm;
---&gt; &#x05D1;</pre>
- </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/263359-1.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
-  <title>preformatted-paragraph-break-as-bidi-paragraph-break</title>
-  <meta charset="UTF-8">
- </head>
- <body>
-  <pre>&#x05D0; --&gt;
---&gt; &#x05D1;</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/bidi/263359-1a.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
-  <title>preformatted-paragraph-break-as-bidi-paragraph-break</title>
-  <meta charset="UTF-8">
-<script type="text/javascript">
-
-function boom()
-{
-  document.getElementById("w").style.whiteSpace="pre";
-}
-
-</script>
- </head>
- <body onload="boom();">
-  <pre id="w" style="white-space: normal">&#x05D0; --&gt;
---&gt; &#x05D1;</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/bidi/263359-1b.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
-  <title>preformatted-paragraph-break-as-bidi-paragraph-break</title>
-  <meta charset="UTF-8">
-<script type="text/javascript">
-
-function boom()
-{
-  document.getElementById("w").style.whiteSpace="normal";
-}
-
-</script>
- </head>
- <body onload="boom();">
-  <pre id="w">&#x05D0; --&gt;
---&gt; &#x05D1;</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/bidi/263359-2-ref.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<DOCTYPE html>
-<html DIR=RTL>
- <head>
-  <meta charset=UTF-8>
-  <title>BIDI Layout Testing</title>
- </head>
- <body>
-  <div style="white-space: pre">
-<b>Test1: No space</b> 
-This is a testing for BiDi layout issues. &rlm;
-<span>This is a testing for BiDi layout issues.&rlm;
-</span> 
-<p>This is a testing for BiDi layout issues.&rlm;
-</p>
-<div>This is a testing for BiDi layout issues.&rlm;
-</div>
-
-<b>Test2: 3 spaces at the end</b>
-This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;
-<span>This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;
-</span>
-
-<p>This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;
-</p>
-<div>This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;
-</div>
-
-<b>Test3: 3 spaces at the beginning</b>
-&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;
-<span>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;
-</span>
-<p>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;
-</p>
-<div>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;
-</div>
-
-<b>Test4: 3 spaces at the end and the beginning</b>
-&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;
-<span>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;
-</span>
-<p>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;
-</p>
-<div>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&rlm;&nbsp;&nbsp;&nbsp;
-</div>
-</div>
- </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/263359-2.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<DOCTYPE html>
-<html DIR=RTL>
- <head>
-  <meta charset=UTF-8>
-  <title>BIDI Layout Testing</title>
- </head>
- <body>
-  <div style="white-space: pre">
-<b>Test1: No space</b> 
-This is a testing for BiDi layout issues. 
-<span>This is a testing for BiDi layout issues.
-</span> 
-<p>This is a testing for BiDi layout issues.
-</p>
-<div>This is a testing for BiDi layout issues.</div>
-
-<b>Test2: 3 spaces at the end</b>
-This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;
-<span>This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;
-</span>
-
-<p>This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;
-</p>
-<div>This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;
-</div>
-
-<b>Test3: 3 spaces at the beginning</b>
-&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.
-<span>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.
-</span>
-<p>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.
-</p>
-<div>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.
-</div>
-
-<b>Test4: 3 spaces at the end and the beginning</b>
-&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;
-<span>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;
-</span>
-<p>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;
-</p>
-<div>&nbsp;&nbsp;&nbsp;This is a testing for BiDi layout issues.&nbsp;&nbsp;&nbsp;
-</div>
-</div>
- </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/263359-3-ref.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<DOCTYPE html>
-<!-- This tests that embeddings and overrides are preserved after <br> -->
-<html>
- <head>
-  <meta charset=UTF-8>
-  <title>Bug 263359</title>
-  <style type="text/css">
-   p { margin: 0; text-align: left; white-space: pre }
-   p.er { direction: rtl; }
-   p.ol { unicode-bidi: bidi-override; direction: ltr; }
-   p.or { unicode-bidi: bidi-override; direction: rtl; }
-  </style>
- </head>
- <body>
-<p>ื‘ืžื” ืžื“ืœื™ืงื™ืŸ,</p>
-<p>ื•ื‘ืžื” ืื™ืŸ ืžื“ืœื™ืงื™ืŸ?</p>
-<p class="er">ืื™ืŸ ืžื“ืœื™ืงื™ืŸ ืœื ื‘ืœื›ืฉ,</p>
-<p class="er">ื•ืœื ื‘ื—ื•ืกืŸ,</p>
-<p class="er">ื•ืœื ื‘ื›ืœืš,</p>
-<p class="er">ื•ืœื ื‘ืคืชื™ืœืช ื”ืื™ื“ืŸ,</p>
-<p class="ol">ื•ืœื ื‘ืคืชื™ืœืช ื”ืžื“ื‘ืจ,</p>
-<p class="ol">ื•ืœื ื‘ื™ืจื•ืงื” ืฉืขืœ ืคื ื™ ื”ืžื™ื.</p>
-<p class="ol">ืœื ื‘ื–ืคืช,</p>
-<p class="or">ื•ืœื ื‘ืฉืขื•ื•ื”,</p>
-<p class="or">ื•ืœื ื‘ืฉืžืŸ ืงื™ืง,</p>
-<p class="or">ื•ืœื ื‘ืฉืžืŸ ืฉืจื™ืคื”,</p>
-<p class="or">ื•ืœื ื‘ืืœื™ื”,</p>
-<p class="ol">ื•ืœื ื‘ื—ืœื‘.</p>
-<p class="ol">ื ื—ื•ื ื”ืžื“ื™ ืื•ืžืจ,</p>
-<p class="er">ืžื“ืœื™ืงื™ืŸ ื‘ื—ืœื‘ ืžื‘ื•ืฉืœ;</p>
-<p class="er">ื•ื—ื›ืžื™ื ืื•ืžืจื™ื,</p>
-<p>ืื—ื“ ืžื‘ื•ืฉืœ ื•ืื—ื“ ืฉืื™ื ื• ืžื‘ื•ืฉืœ,</p>
-<p>ืื™ืŸ ืžื“ืœื™ืงื™ืŸ ื‘ื•.</p>
- </body> 
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/263359-3.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<DOCTYPE html>
-<!-- This tests that embeddings and overrides are preserved in <pre> -->
-<html>
- <head>
-  <meta charset=UTF-8>
-  <title>Bug 263359</title>
-  <style type="text/css">
-   p {
- white-space: pre;
- margin: 0;
-     }
-  </style>
- </head>
- <body>
-  <p style="">ื‘ืžื” ืžื“ืœื™ืงื™ืŸ,
-ื•ื‘ืžื” ืื™ืŸ ืžื“ืœื™ืงื™ืŸ?
-<span dir="rtl">ืื™ืŸ ืžื“ืœื™ืงื™ืŸ ืœื ื‘ืœื›ืฉ,
-ื•ืœื ื‘ื—ื•ืกืŸ,
-ื•ืœื ื‘ื›ืœืš,
-ื•ืœื ื‘ืคืชื™ืœืช ื”ืื™ื“ืŸ,
-<span style="unicode-bidi: bidi-override; direction: ltr">ื•ืœื ื‘ืคืชื™ืœืช ื”ืžื“ื‘ืจ,
-ื•ืœื ื‘ื™ืจื•ืงื” ืฉืขืœ ืคื ื™ ื”ืžื™ื.
-ืœื ื‘ื–ืคืช,
-<span style="unicode-bidi: bidi-override; direction: rtl">ื•ืœื ื‘ืฉืขื•ื•ื”,
-ื•ืœื ื‘ืฉืžืŸ ืงื™ืง,
-ื•ืœื ื‘ืฉืžืŸ ืฉืจื™ืคื”,
-ื•ืœื ื‘ืืœื™ื”, </span>
-ื•ืœื ื‘ื—ืœื‘.
-ื ื—ื•ื ื”ืžื“ื™ ืื•ืžืจ, </span>
-ืžื“ืœื™ืงื™ืŸ ื‘ื—ืœื‘ ืžื‘ื•ืฉืœ;
-ื•ื—ื›ืžื™ื ืื•ืžืจื™ื, </span>
-ืื—ื“ ืžื‘ื•ืฉืœ ื•ืื—ื“ ืฉืื™ื ื• ืžื‘ื•ืฉืœ,
-ืื™ืŸ ืžื“ืœื™ืงื™ืŸ ื‘ื•.
-  </pre>
- </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/263359-4-ref.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
-  <title>change direction of pre with bidi text</title>
-  <meta charset="UTF-8">
- </head>
- <body>
-  <pre dir="rtl">	can_be_executable=TRUE
-	[he]description=ืกื•ื’ ืœื ื™ื“ื•ืข
-	description=Unknown type
-	[ar]description=ู†ูˆุน ุบูŠุฑ ู…ุนุฑูˆู
-	[az]description=Namษ™'lum nรถv
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/bidi/263359-4.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
-  <title>change direction of pre with bidi text</title>
-  <meta charset="UTF-8">
-<script type="text/javascript">
-
-function boom()
-{
-  document.getElementById("w").style.direction="rtl";
-}
-
-</script>
- </head>
- <body onload="boom();">
-  <pre id="w">	can_be_executable=TRUE
-	[he]description=ืกื•ื’ ืœื ื™ื“ื•ืข
-	description=Unknown type
-	[ar]description=ู†ูˆุน ุบูŠุฑ ู…ุนุฑูˆู
-	[az]description=Namษ™'lum nรถv
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/layout/reftests/bidi/613157-1-ref.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
-  <title>block-element-as-bidi-paragraph-break</title>
-  <meta charset="UTF-8">
- </head>
- <body>
-  <div>&#x05D0; --&gt;&lrm;<hr>--&gt; &#x05D1;</div>
- </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/613157-1.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
-  <title>block-element-as-bidi-paragraph-break</title>
-  <meta charset="UTF-8">
- </head>
- <body>
-  <div>&#x05D0; --&gt;<hr>--&gt; &#x05D1;</div>
- </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/613157-2-ref.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
-  <meta charset="utf-8">
-  <title>Inline blocks shouldn't end the paragraph</title>
- </head>
- <body>
-  <p>&#x202e;ืื ื™ ืื•ื”ื‘--&gt; 4 xoferiF--&gt;8 ื™ืžื™ื ื‘ืฉื‘ื•ืข</p>
- </body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bidi/613157-2.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
-  <meta charset="utf-8">
-  <title>Inline blocks shouldn't end the paragraph</title>
- </head>
- <body>
-  <p><span dir="rtl">ืื ื™ ืื•ื”ื‘</span>--&gt;<span style="display: inline-block">Firefox 4&nbsp;</span>--&gt;8 ื™ืžื™ื ื‘ืฉื‘ื•ืข
-  </p>
- </body>
-</html>
--- a/layout/reftests/bidi/reftest.list
+++ b/layout/reftests/bidi/reftest.list
@@ -30,26 +30,17 @@ random-if(cocoaWidget) == mirroring-02.h
 == mixedChartype-03.html mixedChartype-03-ref.html
 == mixedChartype-03-j.html mixedChartype-03-ref.html
 == with-first-letter-1a.html with-first-letter-1-ref.html
 == with-first-letter-1b.html with-first-letter-1-ref.html
 == with-first-letter-2a.html with-first-letter-2-ref.html
 == with-first-letter-2b.html with-first-letter-2-ref.html
 == 115921-1.html 115921-1-ref.html
 == 115921-2.html 115921-2-ref.html
-== 229367-1.html 229367-1-ref.html
-== 229367-2.html 229367-2-ref.html
-== 229367-3.html 229367-3-ref.html
 == 258928-1.html 258928-1-ref.html
-== 263359-1.html 263359-1-ref.html
-== 263359-1a.html 263359-1-ref.html
-!= 263359-1b.html 263359-1-ref.html
-== 263359-2.html 263359-2-ref.html
-== 263359-3.html 263359-3-ref.html
-== 263359-4.html 263359-4-ref.html
 random-if(winWidget) == 267459-1.html 267459-1-ref.html # depends on windows version, see bug 590101
 == 267459-2.html 267459-2-ref.html
 == 299065-1.html 299065-1-ref.html
 random-if(winWidget) == 305643-1.html 305643-1-ref.html # depends on windows version, see bug 590101
 == 332655-1.html 332655-1-ref.html
 == 332655-2.html 332655-2-ref.html
 == 381279-1.html 381279-1-ref.html
 fails-if(Android) == 386339.html 386339-ref.html
@@ -67,10 +58,8 @@ fails-if(/^Windows\x20NT\x206\.1/.test(h
 == 503269-1.html 503269-1-ref.html
 == 503957-1.html 503957-1-ref.html
 == 525740-1.html 525740-1-ref.html
 == 536963-1.html 536963-1-ref.html
 == 588739-1.html 588739-ref.html
 == 588739-2.html 588739-ref.html
 == 588739-3.html 588739-ref.html
 == 612843-1.html 612843-1-ref.html
-== 613157-1.html 613157-1-ref.html
-== 613157-2.html 613157-2-ref.html
--- a/layout/reftests/text/reftest.list
+++ b/layout/reftests/text/reftest.list
@@ -25,19 +25,19 @@ load ligature-with-space-1.html
 == pre-line-1.html pre-line-1-ref.html
 == pre-line-2.html pre-line-2-ref.html
 == pre-line-3.html pre-line-3-ref.html
 == pre-line-4.html pre-line-4-ref.html
 == soft-hyphens-1a.html soft-hyphens-1-ref.html
 == soft-hyphens-1b.html soft-hyphens-1-ref.html
 == soft-hyphens-1c.html soft-hyphens-1-ref.html
 # Tests for soft hyphens in table cells, bug 418975
-!= soft-hyphen-in-table-1.html soft-hyphen-in-table-1-notref.html
-== soft-hyphen-in-table-1.html soft-hyphen-in-table-1-ref.html
-== soft-hyphen-in-table-2.html soft-hyphen-in-table-2-ref.html
+fails != soft-hyphen-in-table-1.html soft-hyphen-in-table-1-notref.html # bug 418975
+fails == soft-hyphen-in-table-1.html soft-hyphen-in-table-1-ref.html # bug 418975
+fails == soft-hyphen-in-table-2.html soft-hyphen-in-table-2-ref.html # bug 418975
 # Cairo's FreeType and GDI backends snap glyphs to pixels, while Mac (usually)
 # and D2D have subpixel positioning.  The tests for pixel-snapping assume that
 # 1 CSS pixel == 1 device pixel
 fails-if(Android) skip-if(d2d||cocoaWidget) == subpixel-glyphs-x-1a.html subpixel-glyphs-x-1b.html
 # Platforms with subpixel positioning already have inconsistent glyphs by
 # design, but that is considered more tolerable because they are subpixel
 # inconsistencies.  On those platforms we just test that glyph positions are
 # subpixel.
--- a/layout/style/forms.css
+++ b/layout/style/forms.css
@@ -244,17 +244,17 @@ select[size="1"] {
   /* Except this is not a listbox */
   background-color: -moz-Combobox;
   color: -moz-ComboboxText;
   vertical-align: baseline;
   padding: 0;
   -moz-appearance: menulist;
 }
 
-select > input[type="button"] {
+select > button {
   width: 12px;
   height: 12px;
   white-space: nowrap;
   position: static !important;
   background-image: url("arrow.gif") !important;
   background-repeat: no-repeat !important;
   background-position: center !important;
   -moz-appearance: menulist-button;
@@ -266,17 +266,17 @@ select > input[type="button"] {
   /*
     Make sure to align properly with the display frame.  Note that we
     want the baseline of the combobox to match the baseline of the
     display frame, so the dropmarker is what gets the vertical-align.
   */
   vertical-align: top !important;
 }
 
-select > input[type="button"]:active {
+select > button:active {
   background-image: url("arrowd.gif") !important;
 }
 
 select:empty {
   width: 2.5em;
 }
 
 *|*::-moz-display-comboboxcontrol-frame {
@@ -583,18 +583,18 @@ input[type="file"] > input[type="button"
   border-color: ButtonText;
 }
 
 button:disabled:active, button:disabled,
 input[type="reset"]:disabled:active,
 input[type="reset"]:disabled,
 input[type="button"]:disabled:active,
 input[type="button"]:disabled,
-select:disabled > input[type="button"],
-select:disabled > input[type="button"]:active,
+select:disabled > button,
+select:disabled > button,
 input[type="submit"]:disabled:active,
 input[type="submit"]:disabled {
   /* The sum of border-top, border-bottom, padding-top, padding-bottom
      must be the same here and for text inputs */
   padding: 0px 6px 0px 6px;
   border: 2px outset ButtonFace;
   color: GrayText;
   cursor: inherit; 
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -570,16 +570,18 @@ pref("dom.disable_open_click_delay", 100
 
 pref("dom.storage.enabled", true);
 pref("dom.storage.default_quota",      5120);
 
 pref("dom.send_after_paint_to_content", false);
 
 // Timeout clamp in ms for timeouts we clamp
 pref("dom.min_timeout_value", 10);
+// And for background windows
+pref("dom.min_background_timeout_value", 1000);
 
 // Parsing perf prefs. For now just mimic what the old code did.
 #ifndef XP_WIN
 pref("content.sink.pending_event_mode", 0);
 #endif
 
 // Disable popups from plugins by default
 //   0 = openAllowed
--- a/testing/mochitest/specialpowers/content/specialpowers.js
+++ b/testing/mochitest/specialpowers/content/specialpowers.js
@@ -32,23 +32,28 @@
  * 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 *****/
 /* This code is loaded in every child process that is started by mochitest in
  * order to be used as a replacement for UniversalXPConnect
  */
+
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+
 function SpecialPowers(window) {
   this.window = window;
   bindDOMWindowUtils(this, window);
 }
 
 function bindDOMWindowUtils(sp, window) {
-  var util = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils);
+  var util = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                   .getInterface(Ci.nsIDOMWindowUtils);
   // This bit of magic brought to you by the letters
   // B Z, and E, S and the number 5.
   //
   // Take all of the properties on the nsIDOMWindowUtils-implementing
   // object, and rebind them onto a new object with a stub that uses
   // apply to call them from this privileged scope. This way we don't
   // have to explicitly stub out new methods that appear on
   // nsIDOMWindowUtils.
@@ -130,17 +135,16 @@ SpecialPowers.prototype = {
       msg = {'op':'set', 'prefName': aPrefName, 'prefType': aPrefType, 'prefValue': aValue};
     }
     return(sendSyncMessage('SPPrefService', msg)[0]);
   },
 
   //XXX: these APIs really ought to be removed, they're not e10s-safe.
   // (also they're pretty Firefox-specific)
   _getTopChromeWindow: function(window) {
-    var Ci = Components.interfaces;
     return window.QueryInterface(Ci.nsIInterfaceRequestor)
                  .getInterface(Ci.nsIWebNavigation)
                  .QueryInterface(Ci.nsIDocShellTreeItem)
                  .rootTreeItem
                  .QueryInterface(Ci.nsIInterfaceRequestor)
                  .getInterface(Ci.nsIDOMWindow)
                  .QueryInterface(Ci.nsIDOMChromeWindow);
   },
@@ -164,16 +168,21 @@ SpecialPowers.prototype = {
                                       .hasAttribute("disabled");
   },
 
   addChromeEventListener: function(type, listener, capture, allowUntrusted) {
     addEventListener(type, listener, capture, allowUntrusted);
   },
   removeChromeEventListener: function(type, listener, capture) {
     removeEventListener(type, listener, capture);
+  },
+
+  createSystemXHR: function() {
+    return Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
+             .createInstance(Ci.nsIXMLHttpRequest);
   }
 };
 
 // Expose everything but internal APIs (starting with underscores) to
 // web content.
 SpecialPowers.prototype.__exposedProps__ = {};
 for each (i in Object.keys(SpecialPowers.prototype).filter(function(v) {return v.charAt(0) != "_";})) {
   SpecialPowers.prototype.__exposedProps__[i] = "r";
--- a/toolkit/crashreporter/client/Makefile.in
+++ b/toolkit/crashreporter/client/Makefile.in
@@ -72,21 +72,19 @@ DEFINES += -DUNICODE -D_UNICODE
 OS_LIBS += $(call EXPAND_LIBNAME,comctl32 shell32 wininet shlwapi)
 MOZ_WINCONSOLE = 0
 endif
 
 ifeq ($(OS_ARCH),Darwin)
 CPPSRCS += crashreporter_unix_common.cpp
 CMMSRCS += crashreporter_osx.mm
 OS_LIBS += -framework Cocoa
-ifdef MOZ_DEBUG
 OS_LIBS += -lcrypto
-LIBS += $(DEPTH)/toolkit/crashreporter/google-breakpad/src/common/$(LIB_PREFIX)breakpad_common_s.$(LIB_SUFFIX)
-endif
 LIBS += \
+  $(DEPTH)/toolkit/crashreporter/google-breakpad/src/common/$(LIB_PREFIX)breakpad_common_s.$(LIB_SUFFIX) \
   $(DEPTH)/toolkit/crashreporter/google-breakpad/src/common/mac/$(LIB_PREFIX)breakpad_mac_common_s.$(LIB_SUFFIX) \
   $(NULL)
 
 LOCAL_INCLUDES += -I$(srcdir) -I$(srcdir)/../google-breakpad/src/common/mac/
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 CPPSRCS += crashreporter_gtk_common.cpp crashreporter_unix_common.cpp
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -202,17 +202,20 @@ ifdef MOZ_PLATFORM_MAEMO
 EXTRA_DSO_LDOPTS += $(MOZ_PLATFORM_MAEMO_LIBS)
 endif 
 
 ifdef MOZ_ENABLE_LIBCONIC
 EXTRA_DSO_LDOPTS += $(LIBCONIC_LIBS)
 endif
 
 ifdef MOZ_ENABLE_DBUS
-EXTRA_DSO_LDOPTS += $(MOZ_DBUS_LIBS) $(MOZ_DBUS_GLIB_LIBS)
+EXTRA_DSO_LDOPTS += $(MOZ_DBUS_LIBS)
+ifdef MOZ_PLATFORM_MAEMO
+EXTRA_DSO_LDOPTS += $(MOZ_DBUS_GLIB_LIBS)
+endif
 endif
 
 ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
 EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS) $(XEXT_LIBS) $(XCOMPOSITE_LIBS) $(MOZ_PANGO_LIBS) $(MOZ_GTK2_LIBS) $(XT_LIBS) -lgthread-2.0
 EXTRA_DSO_LDOPTS += $(FT2_LIBS)
 endif
 
 ifeq (qt,$(MOZ_WIDGET_TOOLKIT))
--- a/view/src/Makefile.in
+++ b/view/src/Makefile.in
@@ -54,9 +54,13 @@ EXTRA_DSO_LIBS = gkgfx
 
 CPPSRCS		= \
 		nsView.cpp \
 		nsViewManager.cpp \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
+LOCAL_INCLUDES  = \
+                -I$(srcdir)/../../content/events/src/ \
+                $(NULL)
+
 CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -57,16 +57,17 @@
 #include "nsHashtable.h"
 #include "nsCOMArray.h"
 #include "nsThreadUtils.h"
 #include "nsContentUtils.h"
 #include "nsIPluginWidget.h"
 #include "nsXULPopupManager.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
+#include "nsEventStateManager.h"
 
 static NS_DEFINE_IID(kRegionCID, NS_REGION_CID);
 
 PRTime gFirstPaintTimestamp = 0; // Timestamp of the first paint event
 /**
    XXX TODO XXX
 
    DeCOMify newly private methods
@@ -808,16 +809,30 @@ NS_IMETHODIMP nsViewManager::DispatchEve
               {
                 pm->PopupMoved(aView, aEvent->refPoint);
                 *aStatus = nsEventStatus_eConsumeNoDefault;
               }
           }
         break;
       }
 
+    case NS_DONESIZEMOVE:
+      {
+        nsCOMPtr<nsIPresShell> shell = do_QueryInterface(mObserver);
+        if (shell) {
+          nsPresContext* presContext = shell->GetPresContext();
+          if (presContext) {
+            nsEventStateManager::ClearGlobalActiveContent(nsnull);
+          }
+    
+          mObserver->ClearMouseCapture(aView);
+        }
+      }
+      break;
+  
     case NS_XUL_CLOSE:
       {
         // if this is a popup, make a request to hide it. Note that a popuphidden
         // event listener may cancel the event and the popup will not be hidden.
         nsIWidget* widget = aView->GetWidget();
         if (widget) {
           nsWindowType type;
           widget->GetWindowType(type);
--- a/widget/public/nsGUIEvent.h
+++ b/widget/public/nsGUIEvent.h
@@ -222,16 +222,19 @@ class nsHashKey;
 // toolkits responsibility to invalidate the window to 
 // ensure that it is drawn using the current system colors.
 #define NS_SYSCOLORCHANGED              (NS_WINDOW_START + 42)
 
 // Indicates that the ui state such as whether to show focus or
 // keyboard accelerator indicators has changed.
 #define NS_UISTATECHANGED               (NS_WINDOW_START + 43)
 
+// Done sizing or moving a window, so ensure that the mousedown state was cleared.
+#define NS_DONESIZEMOVE                 (NS_WINDOW_START + 44)
+
 #define NS_RESIZE_EVENT                 (NS_WINDOW_START + 60)
 #define NS_SCROLL_EVENT                 (NS_WINDOW_START + 61)
 
 // A plugin was clicked or otherwise focused. NS_PLUGIN_ACTIVATE should be
 // used when the window is not active. NS_PLUGIN_FOCUS should be used when
 // the window is active. In the latter case, the dispatcher of the event
 // is expected to ensure that the plugin's widget is focused beforehand.
 #define NS_PLUGIN_ACTIVATE               (NS_WINDOW_START + 62)
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -2635,17 +2635,17 @@ void nsWindow::UpdateTransparentRegion(c
   nsIntRegion opaqueRegion;
   opaqueRegion.Sub(clientBounds, aTransparentRegion);
 
   // If there is no opaque region or hidechrome=true, set margins
   // to support a full sheet of glass. Comments in MSDN indicate
   // all values must be set to -1 to get a full sheet of glass.
   MARGINS margins = { -1, -1, -1, -1 };
   bool visiblePlugin = false;
-  if (!opaqueRegion.IsEmpty() && !mHideChrome) {
+  if (!opaqueRegion.IsEmpty()) {
     nsIntRect pluginBounds;
     for (nsIWidget* child = GetFirstChild(); child; child = child->GetNextSibling()) {
       nsWindowType type;
       child->GetWindowType(type);
       if (type == eWindowType_plugin) {
         // Collect the bounds of all plugins for GetLargestRectangle.
         nsIntRect childBounds;
         child->GetBounds(childBounds);
@@ -4460,18 +4460,32 @@ nsWindow::IPCWindowProcHandler(UINT& msg
   DWORD dwResult = 0;
   PRBool handled = PR_FALSE;
 
   switch(msg) {
     // Windowless flash sending WM_ACTIVATE events to the main window
     // via calls to ShowWindow.
     case WM_ACTIVATE:
       if (lParam != 0 && LOWORD(wParam) == WA_ACTIVE &&
-          IsWindow((HWND)lParam))
+          IsWindow((HWND)lParam)) {
+        // Check for Adobe Reader X sync activate message from their
+        // helper window and ignore. Fixes an annoying focus problem.
+        if ((InSendMessageEx(NULL)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) {
+          PRUnichar szClass[10];
+          HWND focusWnd = (HWND)lParam;
+          if (IsWindowVisible(focusWnd) &&
+              GetClassNameW(focusWnd, szClass,
+                            sizeof(szClass)/sizeof(PRUnichar)) &&
+              !wcscmp(szClass, L"Edit") &&
+              !IsOurProcessWindow(focusWnd)) {
+            break;
+          }
+        }
         handled = PR_TRUE;
+      }
     break;
     // Wheel events forwarded from the child.
     case WM_MOUSEWHEEL:
     case WM_MOUSEHWHEEL:
     case WM_HSCROLL:
     case WM_VSCROLL:
     // Plugins taking or losing focus triggering focus app messages.
     case WM_SETFOCUS:
@@ -4514,20 +4528,24 @@ nsWindow::IPCWindowProcHandler(UINT& msg
  * The main Windows event procedures and associated
  * message processing methods.
  *
  **************************************************************/
 
 static PRBool
 DisplaySystemMenu(HWND hWnd, nsSizeMode sizeMode, PRBool isRtl, PRInt32 x, PRInt32 y)
 {
-  GetSystemMenu(hWnd, TRUE); // reset the system menu
   HMENU hMenu = GetSystemMenu(hWnd, FALSE);
   if (hMenu) {
     // update the options
+    EnableMenuItem(hMenu, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED);
+    EnableMenuItem(hMenu, SC_SIZE, MF_BYCOMMAND | MF_ENABLED);
+    EnableMenuItem(hMenu, SC_MOVE, MF_BYCOMMAND | MF_ENABLED);
+    EnableMenuItem(hMenu, SC_MAXIMIZE, MF_BYCOMMAND | MF_ENABLED);
+    EnableMenuItem(hMenu, SC_MINIMIZE, MF_BYCOMMAND | MF_ENABLED);
     switch(sizeMode) {
       case nsSizeMode_Fullscreen:
         EnableMenuItem(hMenu, SC_RESTORE, MF_BYCOMMAND | MF_GRAYED);
         // intentional fall through
       case nsSizeMode_Maximized:
         EnableMenuItem(hMenu, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
         EnableMenuItem(hMenu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);
         EnableMenuItem(hMenu, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
@@ -5287,16 +5305,22 @@ PRBool nsWindow::ProcessMessage(UINT msg
 
     case WM_NCRBUTTONDBLCLK:
       result = DispatchMouseEvent(NS_MOUSE_DOUBLECLICK, 0, lParamToClient(lParam),
                                   PR_FALSE, nsMouseEvent::eRightButton,
                                   MOUSE_INPUT_SOURCE());
       DispatchPendingEvents();
       break;
 
+    case WM_EXITSIZEMOVE:
+      if (!sIsInMouseCapture) {
+        DispatchStandardEvent(NS_DONESIZEMOVE);
+      }
+      break;
+
     case WM_APPCOMMAND:
     {
       PRUint32 appCommand = GET_APPCOMMAND_LPARAM(lParam);
 
       switch (appCommand)
       {
         case APPCOMMAND_BROWSER_BACKWARD:
         case APPCOMMAND_BROWSER_FORWARD: