Merge m-c to tracemonkey.
authorRobert Sayre <sayrer@gmail.com>
Thu, 18 Dec 2008 15:17:19 -0500
changeset 23095 8003e1a7d2aa5e35f85d22cc645fa32a9c438221
parent 23094 efd7691d238a2e50c7cb17469c9e196992a00504 (current diff)
parent 22917 54d08b93e78bc06e8731bcc1e2eebe215af9e7d7 (diff)
child 23096 0ceae28c4c55a08f1bcb6d2c1fe1189526dd44aa
push id4346
push userrsayre@mozilla.com
push dateFri, 26 Dec 2008 01:26:36 +0000
treeherdermozilla-central@8eb5a5b83a93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.2a1pre
Merge m-c to tracemonkey.
content/media/video/test/r11025_s16_c1_trunc.wav
js/src/Makefile.in
js/src/jsgc.cpp
js/src/jstracer.cpp
testing/performance/talos/PerfConfigurator.py
testing/performance/talos/README.txt
testing/performance/talos/base_profile/localstore.rdf
testing/performance/talos/base_profile/prefs.js
testing/performance/talos/cmanager_linux.py
testing/performance/talos/cmanager_mac.py
testing/performance/talos/cmanager_win32.py
testing/performance/talos/ffprocess.py
testing/performance/talos/ffprocess_linux.py
testing/performance/talos/ffprocess_mac.py
testing/performance/talos/ffprocess_win32.py
testing/performance/talos/ffprofile_unix.py
testing/performance/talos/ffprofile_win32.py
testing/performance/talos/ffsetup.py
testing/performance/talos/getInfo.html
testing/performance/talos/page_load_test/dhtml/colorfade.html
testing/performance/talos/page_load_test/dhtml/dhtml.manifest
testing/performance/talos/page_load_test/dhtml/diagball.html
testing/performance/talos/page_load_test/dhtml/fadespacing.html
testing/performance/talos/page_load_test/dhtml/images/3dball.gif
testing/performance/talos/page_load_test/dhtml/images/ball.gif
testing/performance/talos/page_load_test/dhtml/images/bugs-icon.jpg
testing/performance/talos/page_load_test/dhtml/images/credits-icon.jpg
testing/performance/talos/page_load_test/dhtml/images/css-icon.jpg
testing/performance/talos/page_load_test/dhtml/images/dhtml-icon.jpg
testing/performance/talos/page_load_test/dhtml/images/element_subnavigatio.gif
testing/performance/talos/page_load_test/dhtml/images/gecko-icon.jpg
testing/performance/talos/page_load_test/dhtml/images/img1.jpg
testing/performance/talos/page_load_test/dhtml/images/img2.jpg
testing/performance/talos/page_load_test/dhtml/images/moz.gif
testing/performance/talos/page_load_test/dhtml/images/welcome-icon.jpg
testing/performance/talos/page_load_test/dhtml/imageslide.html
testing/performance/talos/page_load_test/dhtml/layers1.html
testing/performance/talos/page_load_test/dhtml/layers2.html
testing/performance/talos/page_load_test/dhtml/layers4.html
testing/performance/talos/page_load_test/dhtml/layers5.html
testing/performance/talos/page_load_test/dhtml/layers6.html
testing/performance/talos/page_load_test/dhtml/meter.html
testing/performance/talos/page_load_test/dhtml/movingtext.html
testing/performance/talos/page_load_test/dhtml/mozilla.html
testing/performance/talos/page_load_test/dhtml/replaceimages.html
testing/performance/talos/page_load_test/dhtml/scrolling.html
testing/performance/talos/page_load_test/dhtml/slidein.html
testing/performance/talos/page_load_test/dhtml/slidingballs.html
testing/performance/talos/page_load_test/dhtml/textslide.html
testing/performance/talos/page_load_test/dhtml/zoom.html
testing/performance/talos/page_load_test/framecycler.html
testing/performance/talos/page_load_test/gfx/borders-dashed.html
testing/performance/talos/page_load_test/gfx/borders-rounded.html
testing/performance/talos/page_load_test/gfx/borders-solid.html
testing/performance/talos/page_load_test/gfx/gfx.manifest
testing/performance/talos/page_load_test/gfx/images/jpeg-2x2.jpg
testing/performance/talos/page_load_test/gfx/images/marble_1024.jpg
testing/performance/talos/page_load_test/gfx/images/png-2x2.png
testing/performance/talos/page_load_test/gfx/text1.html
testing/performance/talos/page_load_test/gfx/text2.html
testing/performance/talos/page_load_test/gfx/tile-jpg.html
testing/performance/talos/page_load_test/gfx/tile-png.html
testing/performance/talos/page_load_test/jss/core-eval-1.html
testing/performance/talos/page_load_test/jss/core-eval-10.html
testing/performance/talos/page_load_test/jss/core-eval-11.html
testing/performance/talos/page_load_test/jss/core-eval-12.html
testing/performance/talos/page_load_test/jss/core-eval-13.html
testing/performance/talos/page_load_test/jss/core-eval-14.html
testing/performance/talos/page_load_test/jss/core-eval-15.html
testing/performance/talos/page_load_test/jss/core-eval-16.html
testing/performance/talos/page_load_test/jss/core-eval-2.html
testing/performance/talos/page_load_test/jss/core-eval-3.html
testing/performance/talos/page_load_test/jss/core-eval-4.html
testing/performance/talos/page_load_test/jss/core-eval-5.html
testing/performance/talos/page_load_test/jss/core-eval-6.html
testing/performance/talos/page_load_test/jss/core-eval-7.html
testing/performance/talos/page_load_test/jss/core-eval-8.html
testing/performance/talos/page_load_test/jss/core-eval-9.html
testing/performance/talos/page_load_test/jss/jss.manifest
testing/performance/talos/page_load_test/jss/object-array-1.html
testing/performance/talos/page_load_test/jss/object-array-10.html
testing/performance/talos/page_load_test/jss/object-array-11.html
testing/performance/talos/page_load_test/jss/object-array-12.html
testing/performance/talos/page_load_test/jss/object-array-13.html
testing/performance/talos/page_load_test/jss/object-array-14.html
testing/performance/talos/page_load_test/jss/object-array-15.html
testing/performance/talos/page_load_test/jss/object-array-16.html
testing/performance/talos/page_load_test/jss/object-array-17.html
testing/performance/talos/page_load_test/jss/object-array-18.html
testing/performance/talos/page_load_test/jss/object-array-19.html
testing/performance/talos/page_load_test/jss/object-array-2.html
testing/performance/talos/page_load_test/jss/object-array-20.html
testing/performance/talos/page_load_test/jss/object-array-21.html
testing/performance/talos/page_load_test/jss/object-array-22.html
testing/performance/talos/page_load_test/jss/object-array-23.html
testing/performance/talos/page_load_test/jss/object-array-24.html
testing/performance/talos/page_load_test/jss/object-array-25.html
testing/performance/talos/page_load_test/jss/object-array-26.html
testing/performance/talos/page_load_test/jss/object-array-27.html
testing/performance/talos/page_load_test/jss/object-array-28.html
testing/performance/talos/page_load_test/jss/object-array-29.html
testing/performance/talos/page_load_test/jss/object-array-3.html
testing/performance/talos/page_load_test/jss/object-array-30.html
testing/performance/talos/page_load_test/jss/object-array-31.html
testing/performance/talos/page_load_test/jss/object-array-32.html
testing/performance/talos/page_load_test/jss/object-array-4.html
testing/performance/talos/page_load_test/jss/object-array-5.html
testing/performance/talos/page_load_test/jss/object-array-6.html
testing/performance/talos/page_load_test/jss/object-array-7.html
testing/performance/talos/page_load_test/jss/object-array-8.html
testing/performance/talos/page_load_test/jss/object-array-9.html
testing/performance/talos/page_load_test/jss/object-regexp-1.html
testing/performance/talos/page_load_test/jss/object-regexp-10.html
testing/performance/talos/page_load_test/jss/object-regexp-100.html
testing/performance/talos/page_load_test/jss/object-regexp-101.html
testing/performance/talos/page_load_test/jss/object-regexp-102.html
testing/performance/talos/page_load_test/jss/object-regexp-103.html
testing/performance/talos/page_load_test/jss/object-regexp-104.html
testing/performance/talos/page_load_test/jss/object-regexp-105.html
testing/performance/talos/page_load_test/jss/object-regexp-106.html
testing/performance/talos/page_load_test/jss/object-regexp-107.html
testing/performance/talos/page_load_test/jss/object-regexp-108.html
testing/performance/talos/page_load_test/jss/object-regexp-109.html
testing/performance/talos/page_load_test/jss/object-regexp-11.html
testing/performance/talos/page_load_test/jss/object-regexp-110.html
testing/performance/talos/page_load_test/jss/object-regexp-111.html
testing/performance/talos/page_load_test/jss/object-regexp-112.html
testing/performance/talos/page_load_test/jss/object-regexp-113.html
testing/performance/talos/page_load_test/jss/object-regexp-114.html
testing/performance/talos/page_load_test/jss/object-regexp-115.html
testing/performance/talos/page_load_test/jss/object-regexp-116.html
testing/performance/talos/page_load_test/jss/object-regexp-117.html
testing/performance/talos/page_load_test/jss/object-regexp-118.html
testing/performance/talos/page_load_test/jss/object-regexp-119.html
testing/performance/talos/page_load_test/jss/object-regexp-12.html
testing/performance/talos/page_load_test/jss/object-regexp-120.html
testing/performance/talos/page_load_test/jss/object-regexp-121.html
testing/performance/talos/page_load_test/jss/object-regexp-122.html
testing/performance/talos/page_load_test/jss/object-regexp-123.html
testing/performance/talos/page_load_test/jss/object-regexp-124.html
testing/performance/talos/page_load_test/jss/object-regexp-125.html
testing/performance/talos/page_load_test/jss/object-regexp-126.html
testing/performance/talos/page_load_test/jss/object-regexp-127.html
testing/performance/talos/page_load_test/jss/object-regexp-128.html
testing/performance/talos/page_load_test/jss/object-regexp-129.html
testing/performance/talos/page_load_test/jss/object-regexp-13.html
testing/performance/talos/page_load_test/jss/object-regexp-130.html
testing/performance/talos/page_load_test/jss/object-regexp-14.html
testing/performance/talos/page_load_test/jss/object-regexp-15.html
testing/performance/talos/page_load_test/jss/object-regexp-16.html
testing/performance/talos/page_load_test/jss/object-regexp-17.html
testing/performance/talos/page_load_test/jss/object-regexp-18.html
testing/performance/talos/page_load_test/jss/object-regexp-19.html
testing/performance/talos/page_load_test/jss/object-regexp-2.html
testing/performance/talos/page_load_test/jss/object-regexp-20.html
testing/performance/talos/page_load_test/jss/object-regexp-21.html
testing/performance/talos/page_load_test/jss/object-regexp-22.html
testing/performance/talos/page_load_test/jss/object-regexp-23.html
testing/performance/talos/page_load_test/jss/object-regexp-24.html
testing/performance/talos/page_load_test/jss/object-regexp-25.html
testing/performance/talos/page_load_test/jss/object-regexp-26.html
testing/performance/talos/page_load_test/jss/object-regexp-27.html
testing/performance/talos/page_load_test/jss/object-regexp-28.html
testing/performance/talos/page_load_test/jss/object-regexp-29.html
testing/performance/talos/page_load_test/jss/object-regexp-3.html
testing/performance/talos/page_load_test/jss/object-regexp-30.html
testing/performance/talos/page_load_test/jss/object-regexp-31.html
testing/performance/talos/page_load_test/jss/object-regexp-32.html
testing/performance/talos/page_load_test/jss/object-regexp-33.html
testing/performance/talos/page_load_test/jss/object-regexp-34.html
testing/performance/talos/page_load_test/jss/object-regexp-35.html
testing/performance/talos/page_load_test/jss/object-regexp-36.html
testing/performance/talos/page_load_test/jss/object-regexp-37.html
testing/performance/talos/page_load_test/jss/object-regexp-38.html
testing/performance/talos/page_load_test/jss/object-regexp-39.html
testing/performance/talos/page_load_test/jss/object-regexp-4.html
testing/performance/talos/page_load_test/jss/object-regexp-40.html
testing/performance/talos/page_load_test/jss/object-regexp-41.html
testing/performance/talos/page_load_test/jss/object-regexp-42.html
testing/performance/talos/page_load_test/jss/object-regexp-43.html
testing/performance/talos/page_load_test/jss/object-regexp-44.html
testing/performance/talos/page_load_test/jss/object-regexp-45.html
testing/performance/talos/page_load_test/jss/object-regexp-46.html
testing/performance/talos/page_load_test/jss/object-regexp-47.html
testing/performance/talos/page_load_test/jss/object-regexp-48.html
testing/performance/talos/page_load_test/jss/object-regexp-49.html
testing/performance/talos/page_load_test/jss/object-regexp-5.html
testing/performance/talos/page_load_test/jss/object-regexp-50.html
testing/performance/talos/page_load_test/jss/object-regexp-51.html
testing/performance/talos/page_load_test/jss/object-regexp-52.html
testing/performance/talos/page_load_test/jss/object-regexp-53.html
testing/performance/talos/page_load_test/jss/object-regexp-54.html
testing/performance/talos/page_load_test/jss/object-regexp-55.html
testing/performance/talos/page_load_test/jss/object-regexp-56.html
testing/performance/talos/page_load_test/jss/object-regexp-57.html
testing/performance/talos/page_load_test/jss/object-regexp-58.html
testing/performance/talos/page_load_test/jss/object-regexp-59.html
testing/performance/talos/page_load_test/jss/object-regexp-6.html
testing/performance/talos/page_load_test/jss/object-regexp-60.html
testing/performance/talos/page_load_test/jss/object-regexp-61.html
testing/performance/talos/page_load_test/jss/object-regexp-62.html
testing/performance/talos/page_load_test/jss/object-regexp-63.html
testing/performance/talos/page_load_test/jss/object-regexp-64.html
testing/performance/talos/page_load_test/jss/object-regexp-65.html
testing/performance/talos/page_load_test/jss/object-regexp-66.html
testing/performance/talos/page_load_test/jss/object-regexp-67.html
testing/performance/talos/page_load_test/jss/object-regexp-68.html
testing/performance/talos/page_load_test/jss/object-regexp-69.html
testing/performance/talos/page_load_test/jss/object-regexp-7.html
testing/performance/talos/page_load_test/jss/object-regexp-70.html
testing/performance/talos/page_load_test/jss/object-regexp-71.html
testing/performance/talos/page_load_test/jss/object-regexp-72.html
testing/performance/talos/page_load_test/jss/object-regexp-73.html
testing/performance/talos/page_load_test/jss/object-regexp-74.html
testing/performance/talos/page_load_test/jss/object-regexp-75.html
testing/performance/talos/page_load_test/jss/object-regexp-76.html
testing/performance/talos/page_load_test/jss/object-regexp-77.html
testing/performance/talos/page_load_test/jss/object-regexp-78.html
testing/performance/talos/page_load_test/jss/object-regexp-79.html
testing/performance/talos/page_load_test/jss/object-regexp-8.html
testing/performance/talos/page_load_test/jss/object-regexp-80.html
testing/performance/talos/page_load_test/jss/object-regexp-81.html
testing/performance/talos/page_load_test/jss/object-regexp-82.html
testing/performance/talos/page_load_test/jss/object-regexp-83.html
testing/performance/talos/page_load_test/jss/object-regexp-84.html
testing/performance/talos/page_load_test/jss/object-regexp-85.html
testing/performance/talos/page_load_test/jss/object-regexp-86.html
testing/performance/talos/page_load_test/jss/object-regexp-87.html
testing/performance/talos/page_load_test/jss/object-regexp-88.html
testing/performance/talos/page_load_test/jss/object-regexp-89.html
testing/performance/talos/page_load_test/jss/object-regexp-9.html
testing/performance/talos/page_load_test/jss/object-regexp-90.html
testing/performance/talos/page_load_test/jss/object-regexp-91.html
testing/performance/talos/page_load_test/jss/object-regexp-92.html
testing/performance/talos/page_load_test/jss/object-regexp-93.html
testing/performance/talos/page_load_test/jss/object-regexp-94.html
testing/performance/talos/page_load_test/jss/object-regexp-95.html
testing/performance/talos/page_load_test/jss/object-regexp-96.html
testing/performance/talos/page_load_test/jss/object-regexp-97.html
testing/performance/talos/page_load_test/jss/object-regexp-98.html
testing/performance/talos/page_load_test/jss/object-regexp-99.html
testing/performance/talos/page_load_test/jss/object-string-1.html
testing/performance/talos/page_load_test/jss/object-string-10.html
testing/performance/talos/page_load_test/jss/object-string-11.html
testing/performance/talos/page_load_test/jss/object-string-12.html
testing/performance/talos/page_load_test/jss/object-string-13.html
testing/performance/talos/page_load_test/jss/object-string-14.html
testing/performance/talos/page_load_test/jss/object-string-15.html
testing/performance/talos/page_load_test/jss/object-string-16.html
testing/performance/talos/page_load_test/jss/object-string-17.html
testing/performance/talos/page_load_test/jss/object-string-18.html
testing/performance/talos/page_load_test/jss/object-string-19.html
testing/performance/talos/page_load_test/jss/object-string-2.html
testing/performance/talos/page_load_test/jss/object-string-20.html
testing/performance/talos/page_load_test/jss/object-string-21.html
testing/performance/talos/page_load_test/jss/object-string-22.html
testing/performance/talos/page_load_test/jss/object-string-23.html
testing/performance/talos/page_load_test/jss/object-string-24.html
testing/performance/talos/page_load_test/jss/object-string-25.html
testing/performance/talos/page_load_test/jss/object-string-26.html
testing/performance/talos/page_load_test/jss/object-string-27.html
testing/performance/talos/page_load_test/jss/object-string-28.html
testing/performance/talos/page_load_test/jss/object-string-29.html
testing/performance/talos/page_load_test/jss/object-string-3.html
testing/performance/talos/page_load_test/jss/object-string-30.html
testing/performance/talos/page_load_test/jss/object-string-31.html
testing/performance/talos/page_load_test/jss/object-string-32.html
testing/performance/talos/page_load_test/jss/object-string-33.html
testing/performance/talos/page_load_test/jss/object-string-34.html
testing/performance/talos/page_load_test/jss/object-string-35.html
testing/performance/talos/page_load_test/jss/object-string-36.html
testing/performance/talos/page_load_test/jss/object-string-37.html
testing/performance/talos/page_load_test/jss/object-string-38.html
testing/performance/talos/page_load_test/jss/object-string-39.html
testing/performance/talos/page_load_test/jss/object-string-4.html
testing/performance/talos/page_load_test/jss/object-string-40.html
testing/performance/talos/page_load_test/jss/object-string-41.html
testing/performance/talos/page_load_test/jss/object-string-42.html
testing/performance/talos/page_load_test/jss/object-string-43.html
testing/performance/talos/page_load_test/jss/object-string-44.html
testing/performance/talos/page_load_test/jss/object-string-45.html
testing/performance/talos/page_load_test/jss/object-string-46.html
testing/performance/talos/page_load_test/jss/object-string-47.html
testing/performance/talos/page_load_test/jss/object-string-48.html
testing/performance/talos/page_load_test/jss/object-string-49.html
testing/performance/talos/page_load_test/jss/object-string-5.html
testing/performance/talos/page_load_test/jss/object-string-50.html
testing/performance/talos/page_load_test/jss/object-string-51.html
testing/performance/talos/page_load_test/jss/object-string-52.html
testing/performance/talos/page_load_test/jss/object-string-53.html
testing/performance/talos/page_load_test/jss/object-string-54.html
testing/performance/talos/page_load_test/jss/object-string-55.html
testing/performance/talos/page_load_test/jss/object-string-56.html
testing/performance/talos/page_load_test/jss/object-string-57.html
testing/performance/talos/page_load_test/jss/object-string-58.html
testing/performance/talos/page_load_test/jss/object-string-59.html
testing/performance/talos/page_load_test/jss/object-string-6.html
testing/performance/talos/page_load_test/jss/object-string-60.html
testing/performance/talos/page_load_test/jss/object-string-61.html
testing/performance/talos/page_load_test/jss/object-string-62.html
testing/performance/talos/page_load_test/jss/object-string-63.html
testing/performance/talos/page_load_test/jss/object-string-64.html
testing/performance/talos/page_load_test/jss/object-string-65.html
testing/performance/talos/page_load_test/jss/object-string-66.html
testing/performance/talos/page_load_test/jss/object-string-67.html
testing/performance/talos/page_load_test/jss/object-string-68.html
testing/performance/talos/page_load_test/jss/object-string-69.html
testing/performance/talos/page_load_test/jss/object-string-7.html
testing/performance/talos/page_load_test/jss/object-string-70.html
testing/performance/talos/page_load_test/jss/object-string-71.html
testing/performance/talos/page_load_test/jss/object-string-72.html
testing/performance/talos/page_load_test/jss/object-string-73.html
testing/performance/talos/page_load_test/jss/object-string-74.html
testing/performance/talos/page_load_test/jss/object-string-75.html
testing/performance/talos/page_load_test/jss/object-string-76.html
testing/performance/talos/page_load_test/jss/object-string-77.html
testing/performance/talos/page_load_test/jss/object-string-78.html
testing/performance/talos/page_load_test/jss/object-string-79.html
testing/performance/talos/page_load_test/jss/object-string-8.html
testing/performance/talos/page_load_test/jss/object-string-80.html
testing/performance/talos/page_load_test/jss/object-string-81.html
testing/performance/talos/page_load_test/jss/object-string-82.html
testing/performance/talos/page_load_test/jss/object-string-83.html
testing/performance/talos/page_load_test/jss/object-string-84.html
testing/performance/talos/page_load_test/jss/object-string-9.html
testing/performance/talos/page_load_test/jss/real-base64-1.html
testing/performance/talos/page_load_test/jss/real-base64-2.html
testing/performance/talos/page_load_test/jss/real-base64-3.html
testing/performance/talos/page_load_test/jss/real-base64-4.html
testing/performance/talos/page_load_test/jss/real-base64-5.html
testing/performance/talos/page_load_test/jss/real-base64-6.html
testing/performance/talos/page_load_test/jss/real-base64-7.html
testing/performance/talos/page_load_test/jss/real-base64-8.html
testing/performance/talos/page_load_test/jss/real-binary-trees-1.html
testing/performance/talos/page_load_test/jss/real-binary-trees-2.html
testing/performance/talos/page_load_test/jss/real-binary-trees-3.html
testing/performance/talos/page_load_test/jss/real-cube-1.html
testing/performance/talos/page_load_test/jss/real-cube-2.html
testing/performance/talos/page_load_test/jss/real-cube-3.html
testing/performance/talos/page_load_test/jss/real-cube-4.html
testing/performance/talos/page_load_test/jss/real-fannkuch-1.html
testing/performance/talos/page_load_test/jss/real-fannkuch-2.html
testing/performance/talos/page_load_test/jss/real-fannkuch-3.html
testing/performance/talos/page_load_test/jss/real-fannkuch-4.html
testing/performance/talos/page_load_test/jss/real-fasta-1.html
testing/performance/talos/page_load_test/jss/real-fasta-10.html
testing/performance/talos/page_load_test/jss/real-fasta-11.html
testing/performance/talos/page_load_test/jss/real-fasta-12.html
testing/performance/talos/page_load_test/jss/real-fasta-2.html
testing/performance/talos/page_load_test/jss/real-fasta-3.html
testing/performance/talos/page_load_test/jss/real-fasta-4.html
testing/performance/talos/page_load_test/jss/real-fasta-5.html
testing/performance/talos/page_load_test/jss/real-fasta-6.html
testing/performance/talos/page_load_test/jss/real-fasta-7.html
testing/performance/talos/page_load_test/jss/real-fasta-8.html
testing/performance/talos/page_load_test/jss/real-fasta-9.html
testing/performance/talos/page_load_test/jss/real-morph-1.html
testing/performance/talos/page_load_test/jss/real-morph-2.html
testing/performance/talos/page_load_test/jss/real-morph-3.html
testing/performance/talos/page_load_test/jss/real-morph-4.html
testing/performance/talos/page_load_test/jss/real-nbody-1.html
testing/performance/talos/page_load_test/jss/real-nbody-2.html
testing/performance/talos/page_load_test/jss/real-nbody-3.html
testing/performance/talos/page_load_test/jss/real-nbody-4.html
testing/performance/talos/page_load_test/jss/real-nsieve-1.html
testing/performance/talos/page_load_test/jss/real-nsieve-2.html
testing/performance/talos/page_load_test/jss/real-nsieve-3.html
testing/performance/talos/page_load_test/jss/real-nsieve-4.html
testing/performance/talos/page_load_test/jss/real-nsieve-bits-1.html
testing/performance/talos/page_load_test/jss/real-nsieve-bits-2.html
testing/performance/talos/page_load_test/jss/real-nsieve-bits-3.html
testing/performance/talos/page_load_test/jss/real-nsieve-bits-4.html
testing/performance/talos/page_load_test/jss/real-packer-1.html
testing/performance/talos/page_load_test/jss/real-packer-2.html
testing/performance/talos/page_load_test/jss/real-packer-3.html
testing/performance/talos/page_load_test/jss/real-packer-4.html
testing/performance/talos/page_load_test/jss/real-packer-5.html
testing/performance/talos/page_load_test/jss/real-partial-sums-1.html
testing/performance/talos/page_load_test/jss/real-partial-sums-2.html
testing/performance/talos/page_load_test/jss/real-partial-sums-3.html
testing/performance/talos/page_load_test/jss/real-partial-sums-4.html
testing/performance/talos/page_load_test/jss/real-recursive-1.html
testing/performance/talos/page_load_test/jss/real-recursive-10.html
testing/performance/talos/page_load_test/jss/real-recursive-11.html
testing/performance/talos/page_load_test/jss/real-recursive-12.html
testing/performance/talos/page_load_test/jss/real-recursive-2.html
testing/performance/talos/page_load_test/jss/real-recursive-3.html
testing/performance/talos/page_load_test/jss/real-recursive-4.html
testing/performance/talos/page_load_test/jss/real-recursive-5.html
testing/performance/talos/page_load_test/jss/real-recursive-6.html
testing/performance/talos/page_load_test/jss/real-recursive-7.html
testing/performance/talos/page_load_test/jss/real-recursive-8.html
testing/performance/talos/page_load_test/jss/real-recursive-9.html
testing/performance/talos/page_load_test/jss/real-spectral-norm-1.html
testing/performance/talos/page_load_test/jss/real-spectral-norm-2.html
testing/performance/talos/page_load_test/jss/real-spectral-norm-3.html
testing/performance/talos/page_load_test/jss/real-spectral-norm-4.html
testing/performance/talos/page_load_test/jss/runner.js
testing/performance/talos/page_load_test/manifest.txt
testing/performance/talos/page_load_test/parray.js
testing/performance/talos/page_load_test/quit.js
testing/performance/talos/page_load_test/report.html
testing/performance/talos/page_load_test/sunspider/3d-cube.html
testing/performance/talos/page_load_test/sunspider/3d-morph.html
testing/performance/talos/page_load_test/sunspider/3d-raytrace.html
testing/performance/talos/page_load_test/sunspider/access-binary-trees.html
testing/performance/talos/page_load_test/sunspider/access-fannkuch.html
testing/performance/talos/page_load_test/sunspider/access-nbody.html
testing/performance/talos/page_load_test/sunspider/access-nsieve.html
testing/performance/talos/page_load_test/sunspider/bitops-3bit-bits-in-byte.html
testing/performance/talos/page_load_test/sunspider/bitops-bits-in-byte.html
testing/performance/talos/page_load_test/sunspider/bitops-bitwise-and.html
testing/performance/talos/page_load_test/sunspider/bitops-nsieve-bits.html
testing/performance/talos/page_load_test/sunspider/controlflow-recursive.html
testing/performance/talos/page_load_test/sunspider/crypto-aes.html
testing/performance/talos/page_load_test/sunspider/crypto-md5.html
testing/performance/talos/page_load_test/sunspider/crypto-sha1.html
testing/performance/talos/page_load_test/sunspider/date-format-tofte.html
testing/performance/talos/page_load_test/sunspider/date-format-xparb.html
testing/performance/talos/page_load_test/sunspider/math-cordic.html
testing/performance/talos/page_load_test/sunspider/math-partial-sums.html
testing/performance/talos/page_load_test/sunspider/math-spectral-norm.html
testing/performance/talos/page_load_test/sunspider/regexp-dna.html
testing/performance/talos/page_load_test/sunspider/string-base64.html
testing/performance/talos/page_load_test/sunspider/string-fasta.html
testing/performance/talos/page_load_test/sunspider/string-tagcloud.html
testing/performance/talos/page_load_test/sunspider/string-unpack-code.html
testing/performance/talos/page_load_test/sunspider/string-validate-input.html
testing/performance/talos/page_load_test/sunspider/sunspider.css
testing/performance/talos/page_load_test/sunspider/sunspider.manifest
testing/performance/talos/page_load_test/svg/composite-scale-opacity.svg
testing/performance/talos/page_load_test/svg/composite-scale-rotate-opacity.svg
testing/performance/talos/page_load_test/svg/composite-scale-rotate.svg
testing/performance/talos/page_load_test/svg/composite-scale.svg
testing/performance/talos/page_load_test/svg/gearflowers.svg
testing/performance/talos/page_load_test/svg/hixie-001.xml
testing/performance/talos/page_load_test/svg/hixie-002.xml
testing/performance/talos/page_load_test/svg/hixie-003.xml
testing/performance/talos/page_load_test/svg/hixie-004.xml
testing/performance/talos/page_load_test/svg/hixie-005.xml
testing/performance/talos/page_load_test/svg/hixie-006.xml
testing/performance/talos/page_load_test/svg/hixie-007.xml
testing/performance/talos/page_load_test/svg/images/kyoto_1.jpg
testing/performance/talos/page_load_test/svg/images/kyoto_2.jpg
testing/performance/talos/page_load_test/svg/svg.manifest
testing/performance/talos/post_file.py
testing/performance/talos/run_tests.py
testing/performance/talos/sample.config
testing/performance/talos/startup_test/startup_test.html
testing/performance/talos/startup_test/twinopen/child-window.html
testing/performance/talos/startup_test/twinopen/winopen.js
testing/performance/talos/startup_test/twinopen/winopen.xul
testing/performance/talos/ttest.py
testing/performance/talos/utils.py
testing/performance/win32/README.txt
testing/performance/win32/base_profile/Cache/A89F4DBCd01
testing/performance/win32/base_profile/Cache/_CACHE_001_
testing/performance/win32/base_profile/Cache/_CACHE_002_
testing/performance/win32/base_profile/Cache/_CACHE_003_
testing/performance/win32/base_profile/Cache/_CACHE_MAP_
testing/performance/win32/base_profile/XUL.mfl
testing/performance/win32/base_profile/bookmarkbackups/bookmarks-2006-06-27.html
testing/performance/win32/base_profile/bookmarkbackups/bookmarks-2006-07-06.html
testing/performance/win32/base_profile/bookmarks.bak
testing/performance/win32/base_profile/bookmarks.html
testing/performance/win32/base_profile/compatibility.ini
testing/performance/win32/base_profile/compreg.dat
testing/performance/win32/base_profile/cookies.txt
testing/performance/win32/base_profile/extensions.cache
testing/performance/win32/base_profile/extensions.ini
testing/performance/win32/base_profile/extensions.rdf
testing/performance/win32/base_profile/history.dat
testing/performance/win32/base_profile/hostperm.1
testing/performance/win32/base_profile/localstore.rdf
testing/performance/win32/base_profile/prefs.js
testing/performance/win32/base_profile/search.rdf
testing/performance/win32/base_profile/xpti.dat
testing/performance/win32/ffprocess.py
testing/performance/win32/ffprofile.py
testing/performance/win32/initialize.html
testing/performance/win32/page_load_test/base/bugzilla.mozilla.org/20001028.html.orig
testing/performance/win32/page_load_test/base/bugzilla.mozilla.org/index.html
testing/performance/win32/page_load_test/base/bugzilla.mozilla.org/res/mozilla-banner.gif
testing/performance/win32/page_load_test/base/lxr.mozilla.org/20001028.html.orig
testing/performance/win32/page_load_test/base/lxr.mozilla.org/index.html
testing/performance/win32/page_load_test/base/lxr.mozilla.org/res/mozilla-banner.gif
testing/performance/win32/page_load_test/base/vanilla-page/index.html
testing/performance/win32/page_load_test/cycler.html
testing/performance/win32/page_load_test/report.html
testing/performance/win32/paths.py
testing/performance/win32/report.py
testing/performance/win32/run_tests.py
testing/performance/win32/sample.config
testing/performance/win32/startup_test/startup_test.html
testing/performance/win32/tp.py
testing/performance/win32/ts.py
xpfe/components/related/Makefile.in
xpfe/components/related/public/Makefile.in
xpfe/components/related/public/nsIRelatedLinksHandler.idl
xpfe/components/related/src/Makefile.in
xpfe/components/related/src/nsRelatedLinksHandler.cpp
xpfe/components/related/src/nsRelatedLinksHandlerImpl.h
--- a/accessible/public/nsIAccessible.idl
+++ b/accessible/public/nsIAccessible.idl
@@ -98,17 +98,24 @@ interface nsIAccessible : nsISupports
 
   /**
    * The 0-based index of this accessible in its parent's list of children,
    * or -1 if this accessible does not have a parent.
    */
   readonly attribute long indexInParent;
 
   /**
-   * Accessible name -- the main text equivalent for this node
+   * Accessible name -- the main text equivalent for this node. The name is
+   * specified by ARIA or by native markup. Example of ARIA markup is
+   * aria-labelledby attribute placed on element of this accessible. Example
+   * of native markup is HTML label linked with HTML element of this accessible.
+   *
+   * Value can be string or null. A null value indicates that AT may attempt to
+   * compute the name. Any string value, including the empty string, should be
+   * considered author-intentional, and respected.
    */
   attribute AString name;
 
   /**
    * Accessible value -- a number or a secondary text equivalent for this node
    * Widgets that use role attribute can force a value using the valuenow attribute
    */
   readonly attribute AString value;
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -443,39 +443,26 @@ nsAccUtils::GetARIATreeItemParent(nsIAcc
 
 already_AddRefed<nsIAccessibleText>
 nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection,
                                            nsIDOMNode **aNode)
 {
   // Get accessible from selection's focus DOM point (the DOM point where
   // selection is ended).
 
-  nsCOMPtr<nsIDOMNode> resultNode;
-  aSelection->GetFocusNode(getter_AddRefs(resultNode));
-  if (!resultNode)
+  nsCOMPtr<nsIDOMNode> focusNode;
+  aSelection->GetFocusNode(getter_AddRefs(focusNode));
+  if (!focusNode)
     return nsnull;
 
-  // Get DOM node that focus DOM point points to.
-  nsCOMPtr<nsIContent> content(do_QueryInterface(resultNode));
-  if (content && content->IsNodeOfType(nsINode::eELEMENT)) {
-    PRInt32 offset = 0;
-    aSelection->GetFocusOffset(&offset);
+  PRInt32 focusOffset = 0;
+  aSelection->GetFocusOffset(&focusOffset);
 
-    PRInt32 childCount = static_cast<PRInt32>(content->GetChildCount());
-    NS_ASSERTION(offset >= 0 && offset <= childCount,
-                 "Wrong focus offset in selection!");
-
-    // The offset can be after last child of container node that means DOM point
-    // is placed immediately after the last child. In this case use focusNode
-    // as result node.
-    if (offset != childCount) {
-      nsCOMPtr<nsIContent> child = content->GetChildAt(offset);
-      resultNode = do_QueryInterface(child);
-    }
-  }
+  nsCOMPtr<nsIDOMNode> resultNode =
+    nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
 
   nsIAccessibilityService *accService = nsAccessNode::GetAccService();
 
   // Get text accessible containing the result node.
   while (resultNode) {
     // Make sure to get the correct starting node for selection events inside
     // XBL content trees.
     nsCOMPtr<nsIDOMNode> relevantNode;
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -303,17 +303,17 @@ nsAccessible::GetName(nsAString& aName)
   else
     return NS_OK;
 
   // XXX: if CompressWhiteSpace worked on nsAString we could avoid a copy.
   nsAutoString name;
   if (content->GetAttr(kNameSpaceID_None, tooltipAttr, name)) {
     name.CompressWhitespace();
     aName = name;
-  } else {
+  } else if (rv != NS_OK_EMPTY_NAME) {
     aName.SetIsVoid(PR_TRUE);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsAccessible::GetDescription(nsAString& aDescription)
 {
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -61,19 +61,24 @@
 struct nsRect;
 class nsIContent;
 class nsIFrame;
 class nsIPresShell;
 class nsIDOMNode;
 class nsIAtom;
 class nsIView;
 
+// see nsAccessible::GetAttrValue
 #define NS_OK_NO_ARIA_VALUE \
 NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x21)
 
+// see nsAccessible::GetNameInternal
+#define NS_OK_EMPTY_NAME \
+NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x23)
+
 // Saves a data member -- if child count equals this value we haven't
 // cached children or child count yet
 enum { eChildCountUninitialized = -1 };
 
 class nsAccessibleDOMStringList : public nsIDOMDOMStringList
 {
 public:
   nsAccessibleDOMStringList();
@@ -130,17 +135,23 @@ public:
 
   /**
    * Returns the accessible name specified by ARIA.
    */
   nsresult GetARIAName(nsAString& aName);
 
   /**
    * Returns the accessible name provided by native markup. It doesn't take
-   * into account ARIA stuffs used to specify the name.
+   * into account ARIA markup used to specify the name.
+   *
+   * @param  aName             [out] the accessible name
+   *
+   * @return NS_OK_EMPTY_NAME  points empty name was specified by native markup
+   *                           explicitly (see nsIAccessible::name attribute for
+   *                           details)
    */
   virtual nsresult GetNameInternal(nsAString& aName);
 
   /**
    * Return the state of accessible that doesn't take into account ARIA states.
    * Use nsIAccessible::state to get all states for accessible. If
    * second argument is omitted then second bit field of accessible state won't
    * be calculated.
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -187,16 +187,41 @@ nsCoreUtils::GetDOMElementFor(nsIDOMNode
 
     nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(node));
     domDoc->GetDocumentElement(&element);
   }
 
   return element;
 }
 
+already_AddRefed<nsIDOMNode>
+nsCoreUtils::GetDOMNodeFromDOMPoint(nsIDOMNode *aNode, PRUint32 aOffset)
+{
+  nsIDOMNode *resultNode = nsnull;
+
+  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
+  if (content && content->IsNodeOfType(nsINode::eELEMENT)) {
+
+    PRInt32 childCount = static_cast<PRInt32>(content->GetChildCount());
+    NS_ASSERTION(aOffset >= 0 && aOffset <= childCount,
+                 "Wrong offset of the DOM point!");
+
+    // The offset can be after last child of container node that means DOM point
+    // is placed immediately after the last child. In this case use the DOM node
+    // from the given DOM point is used as result node.
+    if (aOffset != childCount) {
+      CallQueryInterface(content->GetChildAt(aOffset), &resultNode);
+      return resultNode;
+    }
+  }
+
+  NS_IF_ADDREF(resultNode = aNode);
+  return resultNode;
+}
+
 nsIContent*
 nsCoreUtils::GetRoleContent(nsIDOMNode *aDOMNode)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(aDOMNode));
   if (!content) {
     nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(aDOMNode));
     if (domDoc) {
       nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(aDOMNode));
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -82,16 +82,21 @@ public:
    * c) body element if it is HTML document node
    * d) document element if it is document node.
    *
    * @param aNode  [in] the given DOM node
    */
   static already_AddRefed<nsIDOMElement> GetDOMElementFor(nsIDOMNode *aNode);
 
   /**
+   * Return DOM node for the given DOM point.
+   */
+  static already_AddRefed<nsIDOMNode> GetDOMNodeFromDOMPoint(nsIDOMNode *aNode,
+                                                             PRUint32 aOffset);
+  /**
    * Return the nsIContent* to check for ARIA attributes on -- this may not
    * always be the DOM node for the accessible. Specifically, for doc
    * accessibles, it is not the document node, but either the root element or
    * <body> in HTML. Similar with GetDOMElementFor() method.
    *
    * @param aDOMNode  DOM node for the accessible that may be affected by ARIA
    * @return          the nsIContent which may have ARIA markup
    */
--- a/accessible/src/html/nsHTMLImageAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageAccessible.cpp
@@ -122,33 +122,31 @@ nsHTMLImageAccessible::GetStateInternal(
   }
 
   return NS_OK;
 }
 
 nsresult
 nsHTMLImageAccessible::GetNameInternal(nsAString& aName)
 {
-  // No alt attribute means AT can repair if there is no accessible name
-  // alt="" with no title or aria-labelledby means image is presentational and 
-  // AT should leave accessible name empty
-
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   PRBool hasAltAttrib =
     content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::alt, aName);
   if (!aName.IsEmpty())
     return NS_OK;
 
   nsresult rv = nsAccessible::GetNameInternal(aName);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (aName.IsVoid() && hasAltAttrib) {
-    // No accessible name but empty alt attribute is present. This means a name
-    // was provided by author and AT repair of the name isn't allowed.
-    aName.Truncate();
+  if (aName.IsEmpty() && hasAltAttrib) {
+    // No accessible name but empty 'alt' attribute is present. If further name
+    // computation algorithm doesn't provide non empty name then it means
+    // an empty 'alt' attribute was used to indicate a decorative image (see
+    // nsIAccessible::name attribute for details).
+    return NS_OK_EMPTY_NAME;
   }
 
   return NS_OK;
 }
 
 /* wstring getRole (); */
 NS_IMETHODIMP nsHTMLImageAccessible::GetRole(PRUint32 *_retval)
 {
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -1627,33 +1627,56 @@ nsresult nsHyperTextAccessible::SetSelec
 NS_IMETHODIMP nsHyperTextAccessible::SetCaretOffset(PRInt32 aCaretOffset)
 {
   return SetSelectionRange(aCaretOffset, aCaretOffset);
 }
 
 /*
  * Gets the offset position of the caret (cursor).
  */
-NS_IMETHODIMP nsHyperTextAccessible::GetCaretOffset(PRInt32 *aCaretOffset)
+NS_IMETHODIMP
+nsHyperTextAccessible::GetCaretOffset(PRInt32 *aCaretOffset)
 {
-  *aCaretOffset = 0;
+  *aCaretOffset = -1;
+
+  // No caret if the focused node is not inside this DOM node and this DOM node
+  // is not inside of focused node.
+  PRBool isInsideOfFocusedNode =
+    nsCoreUtils::IsAncestorOf(gLastFocusedNode, mDOMNode);
 
+  if (!isInsideOfFocusedNode && mDOMNode != gLastFocusedNode &&
+      !nsCoreUtils::IsAncestorOf(mDOMNode, gLastFocusedNode))
+    return NS_OK;
+
+  // Turn the focus node and offset of the selection into caret hypretext
+  // offset.
   nsCOMPtr<nsISelection> domSel;
   nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
                               nsnull, getter_AddRefs(domSel));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIDOMNode> caretNode;
-  rv = domSel->GetFocusNode(getter_AddRefs(caretNode));
+  nsCOMPtr<nsIDOMNode> focusNode;
+  rv = domSel->GetFocusNode(getter_AddRefs(focusNode));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 focusOffset;
+  rv = domSel->GetFocusOffset(&focusOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 caretOffset;
-  domSel->GetFocusOffset(&caretOffset);
+  // No caret if this DOM node is inside of focused node but the selection's
+  // focus point is not inside of this DOM node.
+  if (isInsideOfFocusedNode) {
+    nsCOMPtr<nsIDOMNode> resultNode =
+      nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
+    if (resultNode != mDOMNode &&
+        !nsCoreUtils::IsAncestorOf(mDOMNode, resultNode))
+      return NS_OK;
+  }
 
-  return DOMPointToHypertextOffset(caretNode, caretOffset, aCaretOffset);
+  return DOMPointToHypertextOffset(focusNode, focusOffset, aCaretOffset);
 }
 
 PRInt32 nsHyperTextAccessible::GetCaretLineNumber()
 {
   // Provide the line number for the caret, relative to the
   // currently focused node. Use a 1-based index
   nsCOMPtr<nsISelection> domSel;
   GetSelections(nsISelectionController::SELECTION_NORMAL, nsnull,
--- a/accessible/src/msaa/CAccessibleText.cpp
+++ b/accessible/src/msaa/CAccessibleText.cpp
@@ -140,17 +140,17 @@ CAccessibleText::get_caretOffset(long *a
   GET_NSIACCESSIBLETEXT
 
   PRInt32 offset = 0;
   nsresult rv = textAcc->GetCaretOffset(&offset);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aOffset = offset;
-  return S_OK;
+  return offset != -1 ? S_OK : S_FALSE;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleText::get_characterExtents(long aOffset,
                                       enum IA2CoordinateType aCoordType,
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -1,16 +1,18 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Interfaces
 
 const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
 
 const nsIAccessibleEvent = Components.interfaces.nsIAccessibleEvent;
 const nsIAccessibleStateChangeEvent =
   Components.interfaces.nsIAccessibleStateChangeEvent;
+const nsIAccessibleCaretMoveEvent =
+  Components.interfaces.nsIAccessibleCaretMoveEvent;
 
 const nsIAccessibleStates = Components.interfaces.nsIAccessibleStates;
 const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;
 const nsIAccessibleTypes = Components.interfaces.nsIAccessibleTypes;
 
 const nsIAccessibleRelation = Components.interfaces.nsIAccessibleRelation;
 
 const nsIAccessNode = Components.interfaces.nsIAccessNode;
@@ -68,17 +70,71 @@ const EXT_STATE_EXPANDABLE = nsIAccessib
 // Accessible general
 
 /**
  * nsIAccessibleRetrieval, initialized when test is loaded.
  */
 var gAccRetrieval = null;
 
 /**
- * Return accessible for the given ID attribute or DOM element.
+ * Invokes the given function when document is loaded. Preferable to mochitests
+ * 'addLoadEvent' function -- additionally ensures state of the document
+ * accessible is not busy.
+ *
+ * @param aFunc  the function to invoke
+ */
+function addA11yLoadEvent(aFunc)
+{
+  function waitForDocLoad()
+  {
+    window.setTimeout(
+      function()
+      {
+        var accDoc = getAccessible(document);
+        var state = {};
+        accDoc.getState(state, {});
+        if (state.value & nsIAccessibleStates.STATE_BUSY)
+          return waitForDocLoad();
+
+        aFunc.call();
+      },
+      0
+    );
+  }
+
+  addLoadEvent(waitForDocLoad);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Get DOM node/accesible helpers
+
+/**
+ * Return the DOM node.
+ */
+function getNode(aNodeOrID)
+{
+  if (!aNodeOrID)
+    return null;
+
+  var node = aNodeOrID;
+
+  if (!(aNodeOrID instanceof nsIDOMNode)) {
+    node = document.getElementById(aNodeOrID);
+
+    if (!node) {
+      ok(false, "Can't get DOM element for " + aNodeOrID);
+      return null;
+    }
+  }
+
+  return node;
+}
+
+/**
+ * Return accessible for the given ID attribute or DOM element or accessible.
  *
  * @param aAccOrElmOrID  [in] DOM element or ID attribute to get an accessible
  *                        for or an accessible to query additional interfaces.
  * @param aInterfaces    [in, optional] the accessible interface or the array of
  *                        accessible interfaces to query it/them from obtained
  *                        accessible
  * @param aElmObj        [out, optional] object to store DOM element which
  *                        accessible is obtained for
@@ -205,16 +261,17 @@ function unregisterA11yEventListener(aEv
  * When event is caught then current invoker object is asked to check wether
  * event was handled correctly.
  *
  * Invoker interface is:
  *   var invoker = {
  *     invoke: function(){}, // generates event for the DOM node
  *     check: function(aEvent){}, // checks event for correctness
  *     DOMNode getter() {} // DOM node event is generated for
+ *     getID: function(){} // returns invoker ID
  *   };
  *
  * @param  aEventType     the given event type
  */
 function eventQueue(aEventType)
 {
   /**
    * Add invoker object into queue.
@@ -230,28 +287,31 @@ function eventQueue(aEventType)
   this.invoke = function eventQueue_invoke()
   {
     window.setTimeout(
       function(aQueue)
       {
         if (aQueue.mIndex == aQueue.mInvokers.length - 1) {
           unregisterA11yEventListener(aQueue.mEventType, aQueue.mEventHandler);
 
-          for (var idx = 0; idx < aQueue.mInvokers.length; idx++)
-            ok(aQueue.mInvokers[idx].wasCaught, "test " + idx + " failed.");
+          for (var idx = 0; idx < aQueue.mInvokers.length; idx++) {
+            var invoker = aQueue.mInvokers[idx];
+            ok(invoker.wasCaught,
+               "test with ID = '" + invoker.getID() + "' failed.");
+          }
 
           SimpleTest.finish();
           return;
         }
 
         aQueue.mInvokers[++aQueue.mIndex].invoke();
 
         aQueue.invoke();
       },
-      100, this
+      200, this
     );
   }
 
   this.getInvoker = function eventQueue_getInvoker()
   {
     return this.mInvokers[this.mIndex];
   }
 
@@ -304,16 +364,22 @@ var gA11yEventObserver =
   }
 };
 
 function eventHandlerForEventQueue(aQueue)
 {
   this.handleEvent = function eventHandlerForEventQueue_handleEvent(aEvent)
   {
     var invoker = this.mQueue.getInvoker();
+    if (!invoker) // skip events before test was started
+      return;
+
+    if ("debugCheck" in invoker)
+      invoker.debugCheck(aEvent);
+
     if (aEvent.DOMNode == invoker.DOMNode) {
       invoker.check(aEvent);
       invoker.wasCaught = true;
     }
   }
   
   this.mQueue = aQueue;
 }
--- a/accessible/tests/mochitest/test_events_caretmove.html
+++ b/accessible/tests/mochitest/test_events_caretmove.html
@@ -12,124 +12,193 @@
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="chrome://mochikit/content/a11y/accessible/common.js"></script>
 
   <script type="application/javascript">
-    function synthMouseTest(aNode)
+    /**
+     * Invoker base class.
+     */
+    function synthAction(aNodeOrID, aCaretOffset)
     {
-      this.node = aNode;
-      this.testFunc = function testFunc()
+      this.DOMNode = getNode(aNodeOrID);
+
+      this.check = function synthAction_check(aEvent)
       {
-        synthesizeMouse(this.node, 1, 1, {});
+        is(aEvent.QueryInterface(nsIAccessibleCaretMoveEvent).caretOffset,
+           this.caretOffset,
+           "Wrong caret offset for " + aNodeOrID);
       }
+
+      this.getID = function synthAction_getID() { return aNodeOrID + " action"; }
+
+      this.caretOffset = aCaretOffset;
     }
 
-    function synthKeyTest(aNode, aKey)
+    /**
+     * Click invoker.
+     */
+    function synthClick(aNodeOrID, aCaretOffset,
+                        aExtraNodeOrID, aExtraCaretOffset)
     {
-      this.node = aNode;
-      this.testFunc = function testFunc()
+      this.__proto__ = new synthAction(aNodeOrID, aCaretOffset);
+
+      this.extraNode = getNode(aExtraNodeOrID);
+      this.extraCaretOffset = aExtraCaretOffset;
+
+      this.invoke = function synthClick_invoke()
       {
-        synthesizeKey(aKey, {});
+        // Scroll the node into view, otherwise synth click may fail.
+        this.DOMNode.scrollIntoView(true);
+
+        synthesizeMouse(this.DOMNode, 1, 1, {});
       }
+
+      this.check = function synthFocus_check(aEvent)
+      {
+        this.__proto__.check(aEvent);
+
+        if (this.extraNode) {
+          var acc = getAccessible(this.extraNode, [nsIAccessibleText]);
+          is(acc.caretOffset, this.extraCaretOffset,
+             "Wrong caret offset for " + aExtraNodeOrID);
+        }
+      }
+
+      this.getID = function synthFocus_getID() { return aNodeOrID + " click"; }
     }
 
-    function synthTabTest(aNode, aBackTab)
+    /**
+     * Key press invokers.
+     */
+    function synthKey(aNodeOrID, aCaretOffset, aKey, aArgs)
     {
-      this.node = aNode;
-      this.testFunc = function testFunc()
+      this.__proto__ = new synthAction(aNodeOrID, aCaretOffset);
+  
+      this.invoke = function synthKey_invoke()
       {
-        synthesizeKey("VK_TAB", {shiftKey: aBackTab});
+        synthesizeKey(this.mKey, this.mArgs);
       }
+
+      this.mKey = aKey;
+      this.mArgs = aArgs ? aArgs : {};
     }
 
-    function synthFocusTest(aNode)
+    function synthTabTest(aNodeOrID, aCaretOffset, aBackTab)
     {
-      // bug 460417
-      this.node = aNode;
-      this.testFunc = function testFunc()
+      this.__proto__ = new synthKey(aNodeOrID, aCaretOffset,
+                                    "VK_TAB", {shiftKey: aBackTab});
+
+      this.getID = function synthTabTest_getID() { return aNodeOrID + " tab"; }
+    }
+
+    function synthDownKey(aNodeOrID, aCaretOffset)
+    {
+      this.__proto__ = new synthKey(aNodeOrID, aCaretOffset, "VK_DOWN");
+
+      this.getID = function synthDownKey_getID()
       {
-        this.node.focus();
+        return aNodeOrID + " key down";
       }
     }
 
-    function synthSelectAllTest(aNode)
+    function synthRightKey(aNodeOrID, aCaretOffset)
     {
-      // bug 460417
-      this.node = aNode;
-      this.testFunc = function testFunc()
+      this.__proto__ = new synthKey(aNodeOrID, aCaretOffset, "VK_RIGHT");
+
+      this.getID = function synthRightKey_getID()
       {
-        this.node.select();
+        return aNodeOrID + " key right";
       }
     }
 
-    var gTestsArray = [];
-    var gTestIdx = -1;
+    /**
+     * Focus invoker.
+     */
+    function synthFocus(aNodeOrID, aCaretOffset)
+    {
+      this.__proto__ = new synthAction(aNodeOrID, aCaretOffset);
 
-    var gCaretMoveHandler =
-    {
-      handleEvent: function handleEvent(aEvent)
+      this.invoke = function synthFocus_invoke()
       {
-        if (aEvent.DOMNode == gTestsArray[gTestIdx].node)
-          gTestsArray[gTestIdx].wasCaught = true;
+        this.DOMNode.focus();
       }
-    };
+
+      this.getID = function synthFocus_getID() { return aNodeOrID + " focus"; }
+    }
 
-    function doTest()
+    /**
+     * Select all invoker.
+     */
+    function synthSelectAll(aNodeOrID, aCaretOffset)
     {
-      window.setTimeout(
-        function()
-        {
-          if (gTestIdx == gTestsArray.length - 1) {
-          
-            unregisterA11yEventListener(nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED,
-                                        gCaretMoveHandler);
+      this.__proto__ = new synthAction(aNodeOrID, aCaretOffset);
+
+      this.invoke = function synthSelectAll_invoke()
+      {
+        if (this.DOMNode instanceof Components.interfaces.nsIDOMHTMLInputElement)
+          this.DOMNode.select();
+        else
+          window.getSelection().selectAllChildren(this.DOMNode);
+      }
 
-            for (var idx = 0; idx < gTestsArray.length; idx++)
-              ok(gTestsArray[idx].wasCaught, "test " + idx + " failed");
+      this.getID = function synthSelectAll_getID()
+      {
+        return aNodeOrID + " selectall";
+      }
+    }
 
-            SimpleTest.finish();
-            return;
-          }
+    /**
+     * Do tests.
+     */
+    var gQueue = null;
 
-          gTestsArray[++gTestIdx].testFunc();
-          doTest();
-        },
-        100
-      );
+    function testCaretOffset(aAccOrElmOrID, aCaretOffset)
+    {
+      var acc = getAccessible(aAccOrElmOrID, [nsIAccessibleText]);
+      is(acc.caretOffset, aCaretOffset,
+         "Wrong caret offset for " + aAccOrElmOrID);
     }
 
     function doTests()
     {
-      var textbox = document.getElementById("textbox");
-      gTestsArray.push(new synthFocusTest(textbox));
-      gTestsArray.push(new synthSelectAllTest(textbox));
-      gTestsArray.push(new synthMouseTest(textbox));
-      gTestsArray.push(new synthKeyTest(textbox, "VK_RIGHT"));
+      // test no focused accessibles
+      testCaretOffset("textbox", -1);
+      testCaretOffset("textarea", -1);
+      testCaretOffset("p", -1);
 
-      var textarea = document.getElementById("textarea");
-      gTestsArray.push(new synthMouseTest(textarea));
-      gTestsArray.push(new synthKeyTest(textarea, "VK_RIGHT"));
-      gTestsArray.push(new synthKeyTest(textarea, "VK_DOWN"));
+      // test caret move events and caret offsets
+      gQueue = new eventQueue(nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED);
+
+      var id = "textbox";
+      gQueue.push(new synthFocus(id, 5));
+      gQueue.push(new synthSelectAll(id, 5));
+      gQueue.push(new synthClick(id, 0));
+      gQueue.push(new synthRightKey(id, 1));
 
-      var p = document.getElementById("p");
-      gTestsArray.push(new synthMouseTest(p));
-      gTestsArray.push(new synthKeyTest(p, "VK_RIGHT"));
-      gTestsArray.push(new synthKeyTest(p, "VK_DOWN"));
+      id = "textarea";
+      gQueue.push(new synthClick(id, 0));
+      gQueue.push(new synthRightKey(id, 1));
+      gQueue.push(new synthDownKey(id, 12));
 
-      gTestsArray.push(new synthTabTest(textarea, true));
-      gTestsArray.push(new synthTabTest(p));
+      id = "p";
+      gQueue.push(new synthClick(id, 0));
+      gQueue.push(new synthRightKey(id, 1));
+      gQueue.push(new synthDownKey(id, 6));
 
-      registerA11yEventListener(nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED,
-                                gCaretMoveHandler);
+      gQueue.push(new synthClick("p1_in_div", 0, "p2_in_div", -1));
 
-      doTest();
+      gQueue.push(new synthTabTest("p", 0, true));
+      gQueue.push(new synthTabTest("textarea", 12, true));
+      gQueue.push(new synthTabTest("p", 0, false));
+
+      gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addLoadEvent(doTests);
   </script>
 </head>
 
 <body>
@@ -142,11 +211,12 @@
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <input id="textbox" value="hello"/>
   <textarea id="textarea">text<br>text</textarea>
   <p id="p" contentEditable="true"><span>text</span><br/>text</p>
+  <div id="div" contentEditable="true"><p id="p1_in_div">text</p><p id="p2_in_div">text</p></div>
 
 </body>
 </html>
--- a/accessible/tests/mochitest/test_nsIAccessibleImage.html
+++ b/accessible/tests/mochitest/test_nsIAccessibleImage.html
@@ -142,20 +142,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 
       // Test non-linked image with title attribute
       testThis("nonLinkedImageWithTitle", "MoFo logo", "moz.png", 89, 38);
 
       // Test linked image with title attribute
       testThis("linkedImageWithTitle", "Link to MoFo", "moz.png", 93, 42);
 
       // Test simple image with empty alt attribute
-//      testThis("nonLinkedImageEmptyAlt", "", "moz.png", 89, 38);
+      testThis("nonLinkedImageEmptyAlt", "", "moz.png", 89, 38);
 
       // Test linked image with empty alt attribute
-//      testThis("linkedImageEmptyAlt", "", "moz.png", 93, 42);
+      testThis("linkedImageEmptyAlt", "", "moz.png", 93, 42);
 
       // Test simple image with empty alt attribute and title
       testThis("nonLinkedImageEmptyAltAndTitle", "MozillaFoundation", "moz.png", 89, 38);
 
       // Test linked image with empty alt attribute and title
       testThis("linkedImageEmptyAltAndTitle", "Link to Mozilla Foundation", "moz.png", 93, 42);
 
       // Image with long desc
--- a/accessible/tests/mochitest/test_nsIAccessible_comboboxes.xul
+++ b/accessible/tests/mochitest/test_nsIAccessible_comboboxes.xul
@@ -15,44 +15,52 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/a11y/accessible/common.js" />
 
   <script type="application/javascript">
   <![CDATA[
-    function openHideCombobox(aComboboxNode, aIsOpen)
+    function openHideCombobox(aComboboxNodeOrID, aIsOpen)
     {
       this.invoke = function invoke()
       {
         synthesizeMouse(this.DOMNode, 5, 5, {});
       }
       this.check = function check(aEvent)
       {
         aEvent.QueryInterface(nsIAccessibleStateChangeEvent);
 
+        var id = this.getID();
         is(aEvent.state, nsIAccessibleStates.STATE_EXPANDED,
-            "Wrong state change event is handled.");
+            "Wrong state change event is handled in test '" + id + "'.");
         is(aEvent.isEnabled(), this.mIsOpen,
-            "Wrong value of state expanded.");
+            "Wrong value of state expanded in test '" + id + "'.");
+      }
+      this.getID = function getID()
+      {
+        if (this.mIsOpen)
+          return this.DOMNodeOrID + " open combobox";
+        return this.DOMNodeOrID + " close combobox";
       }
 
-      this.DOMNode = aComboboxNode;
+      this.DOMNodeOrID = aComboboxNodeOrID;
+      this.DOMNode = getNode(aComboboxNodeOrID);
       this.mIsOpen = aIsOpen;
     }
 
     var gQueue = null;
     function doTest()
     {
       gQueue = new eventQueue(nsIAccessibleEvent.EVENT_STATE_CHANGE);
 
-      var menulist = document.getElementById("menulist");
-      gQueue.push(new openHideCombobox(menulist, true));
-      gQueue.push(new openHideCombobox(menulist, false));
+      var ID = "menulist";
+      gQueue.push(new openHideCombobox(ID, true));
+      gQueue.push(new openHideCombobox(ID, false));
 
       // XXX: searchbar doesn't fire state change events because accessible
       // parent of combobox_list accessible is pushbutton accessible.
       //var searchbar = document.getElementById("searchbar");
       //gQueue.push(new openHideCombobox(searchbar, true));
       //gQueue.push(new openHideCombobox(searchbar, false));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
--- a/accessible/tests/mochitest/test_textattrs.html
+++ b/accessible/tests/mochitest/test_textattrs.html
@@ -16,47 +16,34 @@
 
   <script type="application/javascript">
 
     const nsIDOMNSEditableElement =
       Components.interfaces.nsIDOMNSEditableElement;
 
     var gComputedStyle = null;
 
-    var gObserverService = null;
-    var gA11yEventObserver = null;
+    var gTextAttrChangedEventHandler = {
+      handleEvent: function gTextAttrChangedEventHandler_handleEvent(aEvent)
+      {
+        this.eventNumber++;
+      },
+
+      eventNumber: 0
+    };
 
     function testSpellTextAttrs()
     {
-      gA11yEventObserver = {
-        observe: function observe(aSubject, aTopic, aData)
-        {
-          if (aTopic != "accessible-event")
-            return;
-
-          
-          var event = aSubject.QueryInterface(nsIAccessibleEvent);
-
-          if (event.eventType == nsIAccessibleEvent.EVENT_TEXT_ATTRIBUTE_CHANGED)
-            this.mTextAttrChangedEventCounter++;
-        },
-
-        mTextAttrChangedEventCounter: 0
-      };
-
-      // Add accessibility event listeners
-      var gObserverService = Components.classes["@mozilla.org/observer-service;1"].
-                             getService(nsIObserverService);
-
-      gObserverService.addObserver(gA11yEventObserver, "accessible-event",
-                                  false);
+      registerA11yEventListener(nsIAccessibleEvent.EVENT_TEXT_ATTRIBUTE_CHANGED,
+                                gTextAttrChangedEventHandler);
 
       ID = "area8";
   
       var node = document.getElementById(ID);
+      node.setAttribute("value", "valid text inalid tixt");
       node.focus();
 
       var editor = node.QueryInterface(nsIDOMNSEditableElement).editor;
       var spellchecker = editor.getInlineSpellChecker(true);
       spellchecker.enableRealTimeSpell = true;
 
       window.setTimeout(function()
         {
@@ -77,26 +64,21 @@
             "invalid": "spelling"
           };
 
           testTextAttrs(ID, 0, attrs, 0, 11);
           testTextAttrs(ID, 11, misspelledAttrs, 11, 17);
           testTextAttrs(ID, 17, attrs, 17, 18);
           testTextAttrs(ID, 18, misspelledAttrs, 18, 22);
 
-          if (navigator.platform == "Win32")
-            is(gA11yEventObserver.mTextAttrChangedEventCounter, 2,
-               "Wrong count of 'text attribute changed' events for " + ID);
-          else
-            todo(gA11yEventObserver.mTextAttrChangedEventCounter, 2,
-                 "Wrong count of 'text attribute changed' events for " + ID);
+          is(gTextAttrChangedEventHandler.eventNumber, 2,
+             "Wrong count of 'text attribute changed' events for " + ID);
 
-          // Remove a11y events listener
-          gObserverService.removeObserver(gA11yEventObserver,
-                                          "accessible-event");
+          unregisterA11yEventListener(nsIAccessibleEvent.EVENT_TEXT_ATTRIBUTE_CHANGED,
+                                      gTextAttrChangedEventHandler);
 
           SimpleTest.finish();
         }, 0);
     }
 
     function doTest()
     {
       //////////////////////////////////////////////////////////////////////////
@@ -378,17 +360,17 @@
       testTextAttrs(ID, 61, attrs, 61, 68);
 
       //////////////////////////////////////////////////////////////////////////
       // test spelling text attributes
       testSpellTextAttrs(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addLoadEvent(doTest);
+    addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759"
      title="Implement text attributes">
     Mozilla Bug 345759
@@ -434,13 +416,13 @@
     <span style="background-color: blue">Blue BG color</span>
     <span lang="de">Ich bin/Du bist</span>
     <span lang="en">
       Normal
       <span style="color: magenta">Magenta<b>Bold</b>Magenta</span>
     </span>
   </p>
 
-  <input id="area8" value="valid text inalid tixt"/>
+  <input id="area8"/>
 
   <p id="output"/>
 </body>
 </html>
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -17,16 +17,17 @@
 # Portions created by the Initial Developer are Copyright (C) 2006
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Ben Goodger <beng@google.com>
 #   Annie Sullivan <annie.sullivan@gmail.com>
 #   Joe Hughes <joe@retrovirus.com>
 #   Asaf Romano <mano@mozilla.com>
+#   Ehsan Akhgari <ehsan.akhgari@gmail.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either 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
@@ -161,16 +162,19 @@ var StarUI = {
     };
     this._overlayLoading = true;
     document.loadOverlay("chrome://browser/content/places/editBookmarkOverlay.xul",
                          loadObserver);
   },
 
   _doShowEditBookmarkPanel:
   function SU__doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition) {
+    if (this.panel.state != "closed")
+      return;
+
     this._blockCommands(); // un-done in the popuphiding handler
 
     var bundle = this._element("bundle_browser");
 
     // Set panel title:
     // if we are batching, i.e. the bookmark has been added now,
     // then show Page Bookmarked, else if the bookmark did already exist,
     // we are about editing it, then use Edit This Bookmark.
@@ -211,27 +215,20 @@ var StarUI = {
     // transaction on the undo stack may be the initial createItem transaction,
     // or worse, the batched editing of some other item.
     PlacesUIUtils.ptm.doTransaction({ doTransaction: function() { },
                                       undoTransaction: function() { },
                                       redoTransaction: function() { },
                                       isTransient: false,
                                       merge: function() { return false; } });
 
-    if (this.panel.state == "closed") {
-      // Consume dismiss clicks, see bug 400924
-      this.panel.popupBoxObject
-          .setConsumeRollupEvent(Ci.nsIPopupBoxObject.ROLLUP_CONSUME);
-      this.panel.openPopup(aAnchorElement, aPosition, -1, -1);
-    }
-    else {
-      var namePicker = this._element("editBMPanel_namePicker");
-      namePicker.focus();
-      namePicker.editor.selectAll();
-    }
+    // Consume dismiss clicks, see bug 400924
+    this.panel.popupBoxObject
+        .setConsumeRollupEvent(Ci.nsIPopupBoxObject.ROLLUP_CONSUME);
+    this.panel.openPopup(aAnchorElement, aPosition, -1, -1);
 
     gEditItemOverlay.initPanel(this._itemId,
                                { hiddenRows: ["description", "location",
                                               "loadInSidebar", "keyword"] });
   },
 
   panelShown:
   function SU_panelShown(aEvent) {
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -26,16 +26,21 @@ toolbar[printpreview="true"] {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
 }
 
 #urlbar-throbber:not([busy="true"]),
 #urlbar-throbber[busy="true"] + #page-proxy-favicon {
   display: none;
 }
 
+#feed-button > .button-box > .box-inherit > .button-text,
+#feed-button > .button-box > .button-menu-dropmarker {
+  display: none;
+}
+
 #urlbar[pageproxystate="invalid"] > #urlbar-icons > :not(#go-button) ,
 #urlbar[pageproxystate="valid"] > #urlbar-icons > #go-button ,
 #urlbar[empty="true"] > #urlbar-icons > #go-button {
   visibility: collapse;
 }
 
 #identity-box > hbox {
   max-width: 22em;
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -328,22 +328,22 @@ const gPopupBlockerObserver = {
     if (aEvent.originalTarget != gBrowser.selectedBrowser)
       return;
 
     if (!this._reportButton)
       this._reportButton = document.getElementById("page-report-button");
 
     if (!gBrowser.pageReport) {
       // Hide the popup blocker statusbar button
-      this._reportButton.removeAttribute("blocked");
+      this._reportButton.hidden = true;
 
       return;
     }
 
-    this._reportButton.setAttribute("blocked", true);
+    this._reportButton.hidden = false;
 
     // Only show the notification again if we've not already shown it. Since
     // notifications are per-browser, we don't need to worry about re-adding
     // it.
     if (!gBrowser.pageReport.reported) {
       if (gPrefService.getBoolPref("privacy.popups.showBrowserMessage")) {
         var bundle_browser = document.getElementById("bundle_browser");
         var brandBundle = document.getElementById("bundle_brand");
@@ -6098,30 +6098,25 @@ var FeedHandler = {
     if (!this._feedMenuitem)
       this._feedMenuitem = document.getElementById("subscribeToPageMenuitem");
     if (!this._feedMenupopup)
       this._feedMenupopup = document.getElementById("subscribeToPageMenupopup");
 
     var feeds = gBrowser.mCurrentBrowser.feeds;
     if (!feeds || feeds.length == 0) {
       if (feedButton) {
-        feedButton.removeAttribute("feeds");
+        feedButton.collapsed = true;
         feedButton.removeAttribute("feed");
-        feedButton.setAttribute("tooltiptext", 
-                                gNavigatorBundle.getString("feedNoFeeds"));
       }
       this._feedMenuitem.setAttribute("disabled", "true");
       this._feedMenupopup.setAttribute("hidden", "true");
       this._feedMenuitem.removeAttribute("hidden");
     } else {
-      if (feedButton) {
-        feedButton.setAttribute("feeds", "true");
-        feedButton.setAttribute("tooltiptext", 
-                                gNavigatorBundle.getString("feedHasFeedsNew"));
-      }
+      if (feedButton)
+        feedButton.collapsed = false;
       
       if (feeds.length > 1) {
         this._feedMenuitem.setAttribute("hidden", "true");
         this._feedMenupopup.removeAttribute("hidden");
         if (feedButton)
           feedButton.removeAttribute("feed");
       } else {
         if (feedButton)
@@ -6147,21 +6142,18 @@ var FeedHandler = {
       var feeds = [];
       if (browserForLink.feeds != null)
         feeds = browserForLink.feeds;
 
       feeds.push(feed);
       browserForLink.feeds = feeds;
       if (browserForLink == gBrowser || browserForLink == gBrowser.mCurrentBrowser) {
         var feedButton = document.getElementById("feed-button");
-        if (feedButton) {
-          feedButton.setAttribute("feeds", "true");
-          feedButton.setAttribute("tooltiptext", 
-                                  gNavigatorBundle.getString("feedHasFeedsNew"));
-        }
+        if (feedButton)
+          feedButton.collapsed = false;
       }
     }
   }
 };
 
 #include browser-places.js
 
 #include browser-textZoom.js
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -392,16 +392,18 @@
             </hbox>
           </box>
           <hbox id="urlbar-icons">
             <button type="menu"
                     style="-moz-user-focus: none"
                     class="plain urlbar-icon"
                     id="feed-button"
                     chromedir="&locale.dir;"
+                    collapsed="true"
+                    tooltiptext="&feedButton.tooltip;"
                     onclick="return FeedHandler.onFeedButtonClick(event);">
               <menupopup position="after_end"
                          onpopupshowing="return FeedHandler.buildFeedList(this);"
                          oncommand="return FeedHandler.subscribeToFeed(null, event);"
                          onclick="checkForMiddleClick(this, event);"/>
             </button>
             <image id="star-button"
                    class="urlbar-icon"
@@ -568,16 +570,17 @@
       <statusbarpanel id="download-monitor" class="statusbarpanel-iconic-text"
                       tooltiptext="&downloadMonitor2.tooltip;" hidden="true"
                       command="Tools:Downloads"/>
       <statusbarpanel id="security-button" class="statusbarpanel-iconic-text"
                       hidden="true"
                       ondblclick="if (event.button == 0) displaySecurityInfo();"/>
       <statusbarpanel id="page-report-button" type="menu"
                       class="statusbarpanel-menu-iconic"
+                      hidden="true"
                       tooltiptext="&pageReportIcon.tooltip;">
         <menupopup onpopupshowing="gPopupBlockerObserver.fillPopupList(event);">
           <menuitem observes="blockedPopupAllowSite"/>
           <menuitem observes="blockedPopupEditSettings"/>
           <menuitem observes="blockedPopupDontShowMessage"/>
           <menuseparator observes="blockedPopupsSeparator"/>
         </menupopup>
       </statusbarpanel>
--- a/browser/base/content/pageReportFirstTime.xul
+++ b/browser/base/content/pageReportFirstTime.xul
@@ -59,17 +59,17 @@
     &startDescription.label;
   </description>
 
   <separator class="thin"/>
 
   <hbox pack="center">
     <statusbar style="width:20em">
       <statusbarpanel flex="1" pack="left"><description>&done.label;</description></statusbarpanel>
-      <statusbarpanel class="statusbarpanel-iconic" style="min-height:18px" id="page-report-button" blocked="true"/>
+      <statusbarpanel class="statusbarpanel-iconic" style="min-height:18px" id="page-report-button"/>
     </statusbar>
   </hbox>
 
   <separator class="thin"/>
 
   <description>
     &endDescription.label;
   </description>
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -55,16 +55,17 @@ include $(topsrcdir)/config/rules.mk
 # browser_bug423833.js disabled temporarily since it's unreliable: bug 428712
 # browser_sanitize-download-history.js disabled temporarily since it's unreliable: bug 432425
 _BROWSER_FILES = browser_bug321000.js \
                  browser_sanitize-timespans.js \
                  browser_bug405137.js \
                  browser_bug409481.js \
                  browser_bug413915.js \
                  browser_bug420160.js \
+                 browser_bug432599.js \
                  browser_bug427559.js \
                  browser_bug441778.js \
                  browser_discovery.js \
                  discovery.html \
                  moz.png \
                  browser_getshortcutoruri.js \
                  browser_page_style_menu.js \
                  page_style_sample.html \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug432599.js
@@ -0,0 +1,109 @@
+function invokeUsingCtrlD(phase) {
+  switch (phase) {
+  case 1:
+    EventUtils.synthesizeKey("d", { accelKey: true });
+    break;
+  case 2:
+  case 4:
+    EventUtils.synthesizeKey("VK_ESCAPE", {});
+    break;
+  case 3:
+    EventUtils.synthesizeKey("d", { accelKey: true });
+    EventUtils.synthesizeKey("d", { accelKey: true });
+    break;
+  }
+}
+
+function invokeUsingStarButton(phase) {
+  switch (phase) {
+  case 1:
+    EventUtils.sendMouseEvent({ type: "click" }, "star-button");
+    break;
+  case 2:
+  case 4:
+    EventUtils.synthesizeKey("VK_ESCAPE", {});
+    break;
+  case 3:
+    EventUtils.synthesizeMouse(document.getElementById("star-button"),
+                               1, 1, { clickCount: 2 });
+    break;
+  }
+}
+
+// test bug 432599
+function test() {
+  waitForExplicitFinish();
+
+  let testTab = gBrowser.addTab();
+  gBrowser.selectedTab = testTab;
+  let testBrowser = gBrowser.getBrowserForTab(testTab);
+  testBrowser.addEventListener("load", initTest, true);
+
+  testBrowser.contentWindow.location = "data:text/plain,Content";
+}
+
+let invokers = [invokeUsingStarButton, invokeUsingCtrlD];
+let currentInvoker = 0;
+
+function initTest() {
+  // first, bookmark the page
+  let app = Components.classes["@mozilla.org/fuel/application;1"]
+                      .getService(Components.interfaces.fuelIApplication);
+  let ios = Components.classes["@mozilla.org/network/io-service;1"]
+                      .getService(Ci.nsIIOService);
+  app.bookmarks.toolbar.addBookmark("Bug 432599 Test",
+                                    ios.newURI("data:text/plain,Content", null, null));
+
+  checkBookmarksPanel(invokers[currentInvoker], 1);
+}
+
+let initialValue;
+let initialRemoveHidden;
+
+let popupElement = document.getElementById("editBookmarkPanel");
+let titleElement = document.getElementById("editBookmarkPanelTitle");
+let removeElement = document.getElementById("editBookmarkPanelRemoveButton");
+
+function checkBookmarksPanel(invoker, phase)
+{
+  let onPopupShown = function(aEvent) {
+    if (aEvent.originalTarget == popupElement) {
+      checkBookmarksPanel(invoker, phase + 1);
+      popupElement.removeEventListener("popupshown", onPopupShown, false);
+    }
+  };
+  let onPopupHidden = function(aEvent) {
+    if (aEvent.originalTarget == popupElement) {
+      if (phase < 4) {
+        checkBookmarksPanel(invoker, phase + 1);
+      } else {
+        ++ currentInvoker;
+        if (currentInvoker < invokers.length) {
+          checkBookmarksPanel(invokers[currentInvoker], 1);
+        } else {
+          gBrowser.removeCurrentTab();
+          finish();
+        }
+      }
+      popupElement.removeEventListener("popuphidden", onPopupHidden, false);
+    }
+  };
+
+  switch (phase) {
+  case 1:
+  case 3:
+    popupElement.addEventListener("popupshown", onPopupShown, false);
+    break;
+  case 2:
+    popupElement.addEventListener("popuphidden", onPopupHidden, false);
+    initialValue = titleElement.value;
+    initialRemoveHidden = removeElement.hidden;
+    break;
+  case 4:
+    popupElement.addEventListener("popuphidden", onPopupHidden, false);
+    is(titleElement.value, initialValue, "The bookmark panel's title should be the same");
+    is(removeElement.hidden, initialRemoveHidden, "The bookmark panel's visibility should not change");
+    break;
+  }
+  invoker(phase);
+}
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -348,17 +348,17 @@ function getShellService()
     shell = Components.classes["@mozilla.org/browser/shell-service;1"]
       .getService(Components.interfaces.nsIShellService);
   } catch (e) {dump("*** e = " + e + "\n");}
   return shell;
 }
 
 function isBidiEnabled() {
   // first check the pref.
-  if (getBoolPref("browser.bidi.ui", false))
+  if (getBoolPref("bidi.browser.ui", false))
     return true;
 
   // if the pref isn't set, check for an RTL locale and force the pref to true
   // if we find one.
   var rv = false;
 
   try {
     var localeService = Components.classes["@mozilla.org/intl/nslocaleservice;1"]
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -80,24 +80,27 @@ var gEditItemOverlay = {
                      this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK;
     var isQuery = false;
     if (this._uri)
       isQuery = this._uri.schemeIs("place");
 
     this._element("nameRow").collapsed = this._hiddenRows.indexOf("name") != -1;
     this._element("folderRow").collapsed =
       this._hiddenRows.indexOf("folderPicker") != -1 || this._readOnly;
-
     this._element("tagsRow").collapsed = !this._uri ||
       this._hiddenRows.indexOf("tags") != -1 || isQuery;
+    // Collapse the tag selector if the item does not accept tags.
+    if (!this._element("tagsSelector").collapsed &&
+        this._element("tagsRow").collapsed)
+      this.toggleTagsSelector();
     this._element("descriptionRow").collapsed =
       this._hiddenRows.indexOf("description") != -1 || this._readOnly;
     this._element("keywordRow").collapsed = !isBookmark || this._readOnly ||
       this._hiddenRows.indexOf("keyword") != -1 || isQuery;
-    this._element("locationRow").collapsed = !isBookmark || isQuery ||
+    this._element("locationRow").collapsed = !(this._uri && !isQuery) ||
       this._hiddenRows.indexOf("location") != -1;
     this._element("loadInSidebarCheckbox").collapsed = !isBookmark || isQuery ||
       this._readOnly || this._hiddenRows.indexOf("loadInSidebar") != -1;
     this._element("feedLocationRow").collapsed = !this._isLivemark ||
       this._hiddenRows.indexOf("feedLocation") != -1;
     this._element("siteLocationRow").collapsed = !this._isLivemark ||
       this._hiddenRows.indexOf("siteLocation") != -1;
     this._element("selectionCount").hidden = !this._multiEdit;
--- a/browser/components/places/content/toolbar.xml
+++ b/browser/components/places/content/toolbar.xml
@@ -72,16 +72,17 @@
       </xul:vbox>
       <xul:hbox mousethrough="always"
                 flex="1"
                 pack="end">
         <xul:toolbarbutton type="menu"
                            class="chevron"
                            mousethrough="never"
                            collapsed="true"
+                           tooltiptext="&bookmarksToolbarChevron.tooltip;"
                            onpopupshowing="chevronPopupShowing(event);">
           <xul:menupopup anonid="chevronPopup"
                          xbl:inherits="tooltip"
 #ifndef XP_MACOSX
                          context="placesContext"
 #endif
           />
         </xul:toolbarbutton>
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -289,43 +289,48 @@ PlacesTreeView.prototype = {
     // Persist selection state
     var previouslySelectedNodes = [];
     var selection = this.selection;
     var rc = selection.getRangeCount();
     for (var rangeIndex = 0; rangeIndex < rc; rangeIndex++) {
       var min = { }, max = { };
       selection.getRangeAt(rangeIndex, min, max);
       var lastIndex = Math.min(max.value, startReplacement + replaceCount -1);
-      if (min.value < startReplacement || min.value > lastIndex)
+      // if this range does not overlap the replaced chunk we don't need to
+      // persist the selection.
+      if (max.value < startReplacement || min.value > lastIndex)
         continue;
-
-      for (var nodeIndex = min.value; nodeIndex <= lastIndex; nodeIndex++)
+      // if this range starts before the replaced chunk we should persist from
+      // startReplacement to lastIndex
+      var firstIndex = Math.max(min.value, startReplacement);
+      for (var nodeIndex = firstIndex; nodeIndex <= lastIndex; nodeIndex++)
         previouslySelectedNodes.push(
           { node: this._visibleElements[nodeIndex].node, oldIndex: nodeIndex });
     }
 
     // Mark the removes as invisible
     for (var i = 0; i < replaceCount; i++)
       this._visibleElements[startReplacement + i].node.viewIndex = -1;
 
     // Building the new list will set the new elements' visible indices.
     var newElements = [];
     var toOpenElements = [];
-    this._buildVisibleSection(aContainer, newElements, toOpenElements, startReplacement);
+    this._buildVisibleSection(aContainer,
+                              newElements, toOpenElements, startReplacement);
 
     // actually update the visible list
     this._visibleElements =
       this._visibleElements.slice(0, startReplacement).concat(newElements)
           .concat(this._visibleElements.slice(startReplacement + replaceCount,
                                               this._visibleElements.length));
 
     // If the new area has a different size, we'll have to renumber the
     // elements following the area.
     if (replaceCount != newElements.length) {
-      for (i = startReplacement + newElements.length;
+      for (var i = startReplacement + newElements.length;
            i < this._visibleElements.length; i ++) {
         this._visibleElements[i].node.viewIndex = i;
       }
     }
 
     // now update the number of elements
     selection.selectEventsSuppressed = true;
     this._tree.beginUpdateBatch();
--- a/browser/components/preferences/privacy.xul
+++ b/browser/components/preferences/privacy.xul
@@ -58,16 +58,21 @@
       <!-- XXX button prefs -->
       <preference id="pref.privacy.disable_button.cookie_exceptions"
                   name="pref.privacy.disable_button.cookie_exceptions"
                   type="bool"/>
       <preference id="pref.privacy.disable_button.view_cookies"
                   name="pref.privacy.disable_button.view_cookies"
                   type="bool"/>
 
+      <!-- Location Bar -->
+      <preference id="browser.urlbar.search.sources"
+                  name="browser.urlbar.search.sources"
+                  type="int"/>
+
       <!-- History -->
       <preference id="browser.history_expire_days"
                   name="browser.history_expire_days"
                   type="int"/>
       <preference id="browser.history_expire_days.mirror"
                   name="browser.history_expire_days.mirror"
                   type="int"/>
       <preference id="browser.history_expire_days_min"
@@ -100,16 +105,32 @@
     
     <script type="application/x-javascript" src="chrome://browser/content/preferences/privacy.js"/>
 
     <!-- History -->
     <groupbox id="historyGroup">
       <caption label="&history.label;"/>
 
       <hbox align="center">
+        <label id="locationBarSuggestionLabel"
+               control="locationBarSuggestion"
+               accesskey="&locbar.pre.accessKey;">&locbar.pre.label;</label>
+        <menulist id="locationBarSuggestion"
+                  preference="browser.urlbar.search.sources">
+          <menupopup>
+            <menuitem label="&locbar.both.label;" value="3"/>
+            <menuitem label="&locbar.history.label;" value="1"/>
+            <menuitem label="&locbar.bookmarks.label;" value="2"/>
+            <menuitem label="&locbar.nothing.label;" value="0"/>
+          </menupopup>
+        </menulist>
+        <label>&locbar.post.label;</label>
+      </hbox>
+
+      <hbox align="center">
         <checkbox id="rememberHistoryDays"
                   label="&rememberDaysBefore.label;"
                   accesskey="&rememberDaysBefore.accesskey;"
                   oncommand="gPrivacyPane.onchangeHistoryDaysCheck();"
                   aria-labelledby="rememberHistoryDays historyDays rememberAfter"/>
         <textbox id="historyDays" type="number" size="3"
                  aria-labelledby="rememberHistoryDays historyDays rememberAfter"
                  onkeyup="gPrivacyPane.onkeyupHistoryDaysText();"
--- a/browser/components/privatebrowsing/test/unit/head_privatebrowsing.js
+++ b/browser/components/privatebrowsing/test/unit/head_privatebrowsing.js
@@ -93,16 +93,17 @@ if (!profileDir) {
  */
 function cleanUp()
 {
   let files = [
     "downloads.sqlite",
     "places.sqlite",
     "cookies.sqlite",
     "signons.sqlite",
+    "permissions.sqlite"
   ];
 
   for (let i = 0; i < files.length; i++) {
     let file = dirSvc.get("ProfD", Ci.nsIFile);
     file.append(files[i]);
     if (file.exists())
       file.remove(false);
   }
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -1336,18 +1336,22 @@ SessionStoreService.prototype = {
                                        Ci.nsIDOMXPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
     let node = formNodes.iterateNext();
     if (!node)
       return null;
     
     let data = {};
     do {
       let id = node.id ? "#" + node.id : XPathHelper.generate(node);
-      if (node instanceof Ci.nsIDOMHTMLInputElement)
-        data[id] = node.type == "checkbox" || node.type == "radio" ? node.checked : node.value;
+      if (node instanceof Ci.nsIDOMHTMLInputElement) {
+        if (node.type != "file")
+          data[id] = node.type == "checkbox" || node.type == "radio" ? node.checked : node.value;
+        else
+          data[id] = { type: "file", value: node.value };
+      }
       else if (node instanceof Ci.nsIDOMHTMLTextAreaElement)
         data[id] = node.value;
       else if (!node.multiple)
         data[id] = node.selectedIndex;
       else {
         let options = Array.map(node.options, function(aOpt, aIx) aOpt.selected ? aIx : -1);
         data[id] = options.filter(function(aIx) aIx >= 0);
       }
@@ -1628,18 +1632,18 @@ SessionStoreService.prototype = {
     
     if (aOverwriteTabs) {
       this.restoreWindowFeatures(aWindow, winData);
     }
     if (winData.cookies) {
       this.restoreCookies(winData.cookies);
     }
     if (winData.extData) {
-      if (!this._windows[aWindow.__SSi].extData) {
-        this._windows[aWindow.__SSi].extData = {}
+      if (aOverwriteTabs  || !this._windows[aWindow.__SSi].extData) {
+        this._windows[aWindow.__SSi].extData = {};
       }
       for (var key in winData.extData) {
         this._windows[aWindow.__SSi].extData[key] = winData.extData[key];
       }
     }
     if (winData._closedTabs && (root._firstTabs || aOverwriteTabs)) {
       this._windows[aWindow.__SSi]._closedTabs = winData._closedTabs;
     }
@@ -1964,17 +1968,17 @@ SessionStoreService.prototype = {
     // restore text data saved by Firefox 2.0/3.0
     var textArray = this.__SS_restore_text ? this.__SS_restore_text.split(" ") : [];
     function restoreTextData(aContent, aPrefix, aURL) {
       textArray.forEach(function(aEntry) {
         if (/^((?:\d+\|)*)(#?)([^\s=]+)=(.*)$/.test(aEntry) &&
             RegExp.$1 == aPrefix && hasExpectedURL(aContent.document, aURL)) {
           var document = aContent.document;
           var node = RegExp.$2 ? document.getElementById(RegExp.$3) : document.getElementsByName(RegExp.$3)[0] || null;
-          if (node && "value" in node) {
+          if (node && "value" in node && node.type != "file") {
             node.value = decodeURI(RegExp.$4);
             
             var event = document.createEvent("UIEvents");
             event.initUIEvent("input", true, true, aContent, 0);
             node.dispatchEvent(event);
           }
         }
       });
@@ -1986,29 +1990,31 @@ SessionStoreService.prototype = {
           return;
         
         let node = key.charAt(0) == "#" ? aDocument.getElementById(key.slice(1)) :
                                           XPathHelper.resolve(aDocument, key);
         if (!node)
           continue;
         
         let value = aData[key];
-        if (typeof value == "string") {
+        if (typeof value == "string" && node.type != "file") {
           node.value = value;
           
           let event = aDocument.createEvent("UIEvents");
           event.initUIEvent("input", true, true, aDocument.defaultView, 0);
           node.dispatchEvent(event);
         }
         else if (typeof value == "boolean")
           node.checked = value;
         else if (typeof value == "number")
           try {
             node.selectedIndex = value;
           } catch (ex) { /* throws for invalid indices */ }
+        else if (value && value.type && value.type == node.type)
+          node.value = value.value;
         else if (value && typeof value.indexOf == "function" && node.options) {
           Array.forEach(node.options, function(aOpt, aIx) {
             aOpt.selected = value.indexOf(aIx) > -1;
           });
         }
         // NB: dispatching "change" events might have unintended side-effects
       }
     }
@@ -2117,21 +2123,30 @@ SessionStoreService.prototype = {
     
     // only modify those aspects which aren't correct yet
     if (aWidth && aHeight && (aWidth != win_("width") || aHeight != win_("height"))) {
       aWindow.resizeTo(aWidth, aHeight);
     }
     if (!isNaN(aLeft) && !isNaN(aTop) && (aLeft != win_("screenX") || aTop != win_("screenY"))) {
       aWindow.moveTo(aLeft, aTop);
     }
-    if (aSizeMode == "maximized" && win_("sizemode") != "maximized") {
-      aWindow.maximize();
-    }
-    else if (aSizeMode && aSizeMode != "maximized" && win_("sizemode") != "normal") {
-      aWindow.restore();
+    switch (aSizeMode)
+    {
+    case "maximized":
+    	if (win_("sizemode") != "maximized")
+    	  aWindow.maximize();
+    	break
+    case "minimized":
+    	if (win_("sizemode") != "minimized")
+    	  aWindow.minimize();
+    	break
+    default:
+    	if (win_("sizemode") != "normal")
+    	  aWindow.restore();
+    	break
     }
     var sidebar = aWindow.document.getElementById("sidebar-box");
     if (sidebar.getAttribute("sidebarcommand") != aSidebar) {
       aWindow.toggleSidebar(aSidebar);
     }
     // since resizing/moving a window brings it to the foreground,
     // we might want to re-focus the last focused window
     if (this.windowToFocus) {
--- a/browser/components/sessionstore/test/browser/Makefile.in
+++ b/browser/components/sessionstore/test/browser/Makefile.in
@@ -61,12 +61,15 @@ include $(topsrcdir)/config/rules.mk
 	browser_448741.js \
 	browser_454908.js \
 	browser_454908_sample.html \
 	browser_456342.js \
 	browser_456342_sample.xhtml \
 	browser_463206.js \
 	browser_463206_sample.html \
 	browser_465215.js \
+	browser_465223.js \
+	browser_466937.js \
+	browser_466937_sample.html \
 	$(NULL)
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser/browser_465223.js
@@ -0,0 +1,79 @@
+/* ***** 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 sessionstore test code.
+ *
+ * The Initial Developer of the Original Code is
+ * Simon Bünzli <zeniko@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either 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 ***** */
+
+function test() {
+  /** Test for Bug 465223 **/
+  
+  // test setup
+  let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
+  waitForExplicitFinish();
+  
+  let uniqueKey1 = "bug 465223.1";
+  let uniqueKey2 = "bug 465223.2";
+  let uniqueValue1 = "unik" + Date.now();
+  let uniqueValue2 = "pi != " + Math.random();
+  
+  // open a window and set a value on it
+  let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
+  newWin.addEventListener("load", function(aEvent) {
+    ss.setWindowValue(newWin, uniqueKey1, uniqueValue1);
+    
+    let newState = { windows: [{ tabs:[{ entries: [] }], extData: {} }] };
+    newState.windows[0].extData[uniqueKey2] = uniqueValue2;
+    ss.setWindowState(newWin, JSON.stringify(newState), false);
+    
+    is(newWin.gBrowser.tabContainer.childNodes.length, 2,
+       "original tab wasn't overwritten");
+    is(ss.getWindowValue(newWin, uniqueKey1), uniqueValue1,
+       "window value wasn't overwritten when the tabs weren't");
+    is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue2,
+       "new window value was correctly added");
+    
+    newState.windows[0].extData[uniqueKey2] = uniqueValue1;
+    ss.setWindowState(newWin, JSON.stringify(newState), true);
+    
+    is(newWin.gBrowser.tabContainer.childNodes.length, 1,
+       "original tabs were overwritten");
+    is(ss.getWindowValue(newWin, uniqueKey1), "",
+       "window value was cleared");
+    is(ss.getWindowValue(newWin, uniqueKey2), uniqueValue1,
+       "window value was correctly overwritten");
+    
+    // clean up
+    newWin.close();
+    finish();
+  }, false);
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser/browser_466937.js
@@ -0,0 +1,69 @@
+/* ***** 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 sessionstore test code.
+ *
+ * The Initial Developer of the Original Code is
+ * Simon Bünzli <zeniko@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either 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 ***** */
+
+function test() {
+  /** Test for Bug 466937 **/
+  
+  waitForExplicitFinish();
+  
+  let testURL = "http://localhost:8888/browser/" +
+    "browser/components/sessionstore/test/browser/browser_466937_sample.html";
+  let testPath = "/home/user/regular.file";
+  
+  let tab = gBrowser.addTab(testURL);
+  tab.linkedBrowser.addEventListener("load", function(aEvent) {
+    let doc = tab.linkedBrowser.contentDocument;
+    doc.getElementById("reverse_thief").value = "/home/user/secret2";
+    doc.getElementById("bystander").value = testPath;
+    
+    let tab2 = gBrowser.duplicateTab(tab);
+    tab2.linkedBrowser.addEventListener("load", function(aEvent) {
+      doc = tab2.linkedBrowser.contentDocument;
+      is(doc.getElementById("thief").value, "",
+         "file path wasn't set to text field value");
+      is(doc.getElementById("reverse_thief").value, "",
+         "text field value wasn't set to full file path");
+      is(doc.getElementById("bystander").value, testPath,
+         "normal case: file path was correctly preserved");
+      
+      // clean up
+      gBrowser.removeTab(tab2);
+      gBrowser.removeTab(tab);
+      
+      finish();
+    }, true);
+  }, true);
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser/browser_466937_sample.html
@@ -0,0 +1,20 @@
+<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
+
+<!DOCTYPE html>
+<title>Test for bug 466937</title>
+
+<input id="thief" value="/home/user/secret">
+<input type="file" id="reverse_thief">
+<input type="file" id="bystander">
+
+<script>
+  window.addEventListener("DOMContentLoaded", function() {
+    if (!document.location.hash) {
+      document.location.hash = "#ready";
+    }
+    else {
+      document.getElementById("thief").type = "file";
+      document.getElementById("reverse_thief").type = "text";
+    }
+  }, false);
+</script>
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -66,32 +66,34 @@
 <!ENTITY bookmarksMenu.accesskey "B">
 <!ENTITY bookmarkThisPageCmd.label "Bookmark This Page">
 <!ENTITY bookmarkThisPageCmd.commandkey "d">
 <!ENTITY subscribeToPageMenupopup.label "Subscribe to This Page">
 <!ENTITY subscribeToPageMenuitem.label "Subscribe to This Page…">
 <!ENTITY addCurPagesCmd.label "Bookmark All Tabs…">
 <!ENTITY organizeBookmarks.label "Organize Bookmarks…">
 <!ENTITY bookmarkAllCmd.label "Bookmark All Tabs…">
+<!ENTITY bookmarksToolbarChevron.tooltip "Show more bookmarks">
 
 <!ENTITY backCmd.label                "Back">
 <!ENTITY backCmd.accesskey            "B">
 <!ENTITY backButton.tooltip           "Go back one page">
 <!ENTITY forwardCmd.label             "Forward">
 <!ENTITY forwardCmd.accesskey         "F">
 <!ENTITY forwardButton.tooltip        "Go forward one page">
 <!ENTITY backForwardMenu.tooltip      "Recent pages">
 <!ENTITY reloadCmd.label              "Reload">
 <!ENTITY reloadCmd.accesskey          "R">
 <!ENTITY reloadButton.tooltip         "Reload current page">
 <!ENTITY stopCmd.label                "Stop">
 <!ENTITY stopCmd.accesskey            "S">
 <!ENTITY stopCmd.macCommandKey        ".">
 <!ENTITY stopButton.tooltip           "Stop loading this page">
 <!ENTITY goEndCap.tooltip             "Go to the address in the Location Bar">
+<!ENTITY feedButton.tooltip           "Subscribe to this page…">
 <!ENTITY printButton.label            "Print">
 <!ENTITY printButton.tooltip          "Print this page">
 
 <!ENTITY locationItem.title           "Location">
 <!ENTITY searchItem.title             "Search">
 <!ENTITY throbberItem.title           "Activity Indicator">
 <!ENTITY bookmarksItem.title          "Bookmarks">
 
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -68,19 +68,17 @@ updatesItem_defaultFallback=Check for Updates…
 updatesItem_downloading=Downloading %S…
 updatesItem_downloadingFallback=Downloading Update…
 updatesItem_resume=Resume Downloading %S…
 updatesItem_resumeFallback=Resume Downloading Update…
 updatesItem_pending=Apply Downloaded Update Now…
 updatesItem_pendingFallback=Apply Downloaded Update Now…
 
 # RSS Pretty Print
-feedNoFeeds=Page has no feeds
 feedShowFeedNew=Subscribe to '%S'…
-feedHasFeedsNew=Subscribe to this page…
 
 # History menu
 menuOpenAllInTabs.label=Open All in Tabs
 menuOpenAllInTabs.accesskey=o
 
 # Unified Back-/Forward Popup
 tabHistory.current=Stay on this page
 tabHistory.goBack=Go back to this page
--- a/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
@@ -1,9 +1,17 @@
-<!ENTITY  history.label "History">
+<!ENTITY  history.label                 "History">
+
+<!ENTITY  locbar.pre.label              "When using the location bar, suggest:">
+<!ENTITY  locbar.pre.accessKey          "l">
+<!ENTITY  locbar.post.label             "">
+<!ENTITY  locbar.both.label             "History and Bookmarks">
+<!ENTITY  locbar.history.label          "History">
+<!ENTITY  locbar.bookmarks.label        "Bookmarks">
+<!ENTITY  locbar.nothing.label          "Nothing">
 
 <!-- LOCALIZATION NOTE:
   The entities rememberDaysBefore.label and rememberDaysAfter2.label appear on a single
   line in preferences as follows:
 
   &rememberDaysBefore.label  [ textbox for number of days ]  &rememberDaysAfter2.label;
 -->
 <!ENTITY  rememberDaysBefore.label      "Keep my history for at least">
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -981,29 +981,20 @@ toolbar[iconsize="small"] #paste-button[
 #feed-button > .button-box,
 #feed-button:hover:active > .button-box {
   padding: 0px;
   margin: 0px;
   border: 0px; 
   background-color: transparent;
 }
 
-#feed-button > hbox > .button-menu-dropmarker,
-#feed-button > hbox > .button-text {
-  display: none;
-}
-
 #feed-button {
-  -moz-binding: url("chrome://global/content/bindings/button.xml#menu");
   -moz-appearance: none; 
   min-width: 0px; 
   margin-right: 1px !important;
-}
-
-#feed-button[feeds] {
   list-style-image: url("chrome://browser/skin/page-livemarks.png");
 }
 
 /* Autocomplete */
 #urlbar .autocomplete-textbox-container {
   -moz-box-align: stretch;
 }
 
@@ -1125,24 +1116,18 @@ statusbarpanel#statusbar-display {
 }
 
 /* XXXsw prevent margins of a value-less label from shifting the image */
 #security-button > label:not([value]) {
   display: none;
 }
 
 #page-report-button {
-  list-style-image: none;
+  list-style-image: url("chrome://browser/skin/Info.png");
   width: 20px;
-  display: none;
-}
-
-#page-report-button[blocked] {
-  list-style-image: url("chrome://browser/skin/Info.png");
-  display: -moz-box;
 }
 
 /* Throbber */
 #navigator-throbber {
   width: 16px;
   min-height: 16px;
   margin: 0 3px;
   list-style-image: url("chrome://global/skin/icons/notloading_16.png");
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -978,16 +978,17 @@ richlistitem[selected="true"][current="t
 
 #go-button:hover:active {
   -moz-image-region: rect(0px, 48px, 16px, 32px);  
 }
 
 /* STAR BUTTON */
 #star-button {
   padding: 1px;
+  -moz-padding-start: 4px;
   list-style-image: url("chrome://browser/skin/places/star-icons.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px);  
 }
 
 #star-button:hover {
   -moz-image-region: rect(0px, 32px, 16px, 16px);  
 }
 
@@ -1428,56 +1429,35 @@ sidebarheader > .tabs-closebutton > .too
 
 #security-button[level="broken"] {
   list-style-image: url("chrome://browser/skin/Secure-statusbar-broken.png");
 }
 
 /* ----- PAGE REPORT DISPLAY ----- */
 
 #page-report-button {
-  display: none;
-}
-
-#page-report-button[blocked] {
-  display: -moz-box;
   list-style-image: url("chrome://browser/skin/Popup-blocked.png");
   padding: 0px 3px 0px 3px;
 }
 
 /* ----- FEED CONTENT DISPLAY ---- */
 
-#feed-button, #feed-button > .button-box,
-#feed-button:hover:active > .button-box {
-  padding: 0px;
-  margin: -1px;
-  border: 0px; 
-  background-color: transparent;
-}
-
-#feed-button .button-menu-dropmarker,
-#feed-button .button-text {
-  display: none;
-}
-
 #feed-button {
-  -moz-binding: url("chrome://global/content/bindings/button.xml#menu");
   -moz-appearance: none; 
   min-width: 0;
   min-height: 0;
-  margin-right: 1px !important;
-}
-
-#feed-button[feeds] {
+  -moz-padding-start: 4px !important;
   list-style-image: url("chrome://browser/skin/feed-icons.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
-#feed-button[feeds]:hover {
+#feed-button:hover {
   -moz-image-region: rect(0px, 32px, 16px, 16px);
 }
-#feed-button[feeds]:active {
+#feed-button[open="true"],
+#feed-button:hover:active {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
 
 /* ----- THROBBER ----- */
 
 #navigator-throbber {
   width: 17px;
   min-height: 16px;
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -1256,24 +1256,18 @@ statusbarpanel#statusbar-display {
 }
 
 /* XXXsw prevent margins of a value-less label from shifting the image */
 #security-button > label:not([value]) {
   display: none;
 }
 
 #page-report-button {
-  list-style-image: none;
   width: 20px;
-  display: none;
-}
-
-#page-report-button[blocked] {
   list-style-image: url("chrome://browser/skin/Info.png");
-  display: -moz-box;
 }
 
 /* ::::: throbber ::::: */
 
 #navigator-throbber {
   width: 16px;
   min-height: 16px;
   margin: 0 3px;
@@ -1649,54 +1643,42 @@ toolbar[mode="text"] > #window-controls 
 }
 
 #urlbar[chromedir="ltr"] > .autocomplete-history-dropmarker:hover ,
 #urlbar[chromedir="ltr"] > .autocomplete-history-dropmarker[open="true"] {
   -moz-border-left-colors: ButtonShadow;
 }
 
 /* Feed icon */
-#feed-button, #feed-button > .button-box,
+#feed-button,
+#feed-button > .button-box,
 #feed-button:hover:active > .button-box {
   padding: 0px;
   margin: 0px;
   border: 0px; 
   background-color: transparent;
 }
 
-#feed-button > hbox > .button-menu-dropmarker,
-#feed-button > hbox > .button-text {
-  display: none;
-}
-
 #feed-button {
-  -moz-binding: url("chrome://global/content/bindings/button.xml#menu");
   -moz-appearance: none; 
   min-width: 0px; 
   padding: 0 2px !important;
-}
-
-#feed-button[feeds] {
   list-style-image: url("chrome://browser/skin/feeds/feed-icons-16.png");
   -moz-image-region: rect(0px 16px 16px 0px);
 }
 
-#feed-button[feeds]:hover {
+#feed-button:hover {
   -moz-image-region: rect(0px 32px 16px 16px);
 }
 
-#feed-button[feeds][open="true"],
-#feed-button[feeds]:hover:active {
+#feed-button[open="true"],
+#feed-button:hover:active {
   -moz-image-region: rect(0px 48px 16px 32px);
 }
 
-#feed-button:not([feeds]) {
-  visibility: collapse;
-}
-
 /* ::::: About Popup Blocking dialog ::::: */
 #pageReportFirstTime statusbarpanel.statusbar-resizerpanel {
   visibility: collapse;
 }
 
 #checkForUpdates[loading="true"] {
   list-style-image: url("chrome://global/skin/icons/loading_16.png");
 }
--- a/build/wince/shunt/include/mozce_shunt.h
+++ b/build/wince/shunt/include/mozce_shunt.h
@@ -66,16 +66,20 @@ MOZCE_SHUNT_API char* strerror(int);
 MOZCE_SHUNT_API void abort(void);
   
 /* Environment stuff */
 MOZCE_SHUNT_API char* getenv(const char* inName);
 MOZCE_SHUNT_API int putenv(const char *a);
 MOZCE_SHUNT_API char SetEnvironmentVariableW(const unsigned short * name, const unsigned short * value );
 MOZCE_SHUNT_API char GetEnvironmentVariableW(const unsigned short * lpName, unsigned short* lpBuffer, unsigned long nSize);
   
+MOZCE_SHUNT_API unsigned int ExpandEnvironmentStringsW(const unsigned short* lpSrc,
+                                                       unsigned short* lpDst,
+                                                       unsigned int nSize);
+
 /* File system stuff */
 MOZCE_SHUNT_API unsigned short * _wgetcwd(unsigned short* dir, unsigned long size);
 MOZCE_SHUNT_API unsigned short *_wfullpath( unsigned short *absPath, const unsigned short *relPath, unsigned long maxLength );
 MOZCE_SHUNT_API int _unlink(const char *filename );
   
 /* The time stuff should be defined here, but it can't be because it
    is already defined in time.h.
   
--- a/build/wince/shunt/map.cpp
+++ b/build/wince/shunt/map.cpp
@@ -188,16 +188,131 @@ MOZCE_SHUNT_API char SetEnvironmentVaria
                            NULL,
                            NULL);
   if(rv < 0)
     return rv;
   
   return map_put(key,val);
 }
 
+
+typedef struct MOZCE_SHUNT_SPECIAL_FOLDER_INFO
+{
+  int   nFolder;
+  char *folderEnvName;
+} MozceShuntSpecialFolderInfo;
+
+// TAKEN DIRECTLY FROM MICROSOFT SHELLAPI.H HEADER FILE 
+// supported SHGetSpecialFolderPath nFolder ids
+#define CSIDL_DESKTOP            0x0000
+#define CSIDL_PROGRAMS           0x0002      // \Windows\Start Menu\Programs
+#define CSIDL_PERSONAL           0x0005
+#define CSIDL_WINDOWS            0x0024      // \Windows
+#define CSIDL_PROGRAM_FILES      0x0026      // \Program Files
+
+#define CSIDL_APPDATA            0x001A      // NOT IN SHELLAPI.H header file
+#define CSIDL_PROFILE            0x0028      // NOT IN SHELLAPI.H header file
+
+MozceShuntSpecialFolderInfo mozceSpecialFoldersToEnvVars[] = {
+  { CSIDL_APPDATA,  "APPDATA" },
+  { CSIDL_PROGRAM_FILES, "ProgramFiles" },
+  { CSIDL_WINDOWS,  "windir" },
+
+  //  { CSIDL_PROFILE,  "HOMEPATH" },     // No return on WinMobile 6 Pro
+  //  { CSIDL_PROFILE,  "USERPROFILE" },  // No return on WinMobile 6 Pro
+  //  { int, "ALLUSERSPROFILE" },         // Only one profile on WinCE
+  //  { int, "CommonProgramFiles" },
+  //  { int, "COMPUTERNAME" },
+  //  { int, "HOMEDRIVE" },
+  //  { int, "SystemDrive" },
+  //  { int, "SystemRoot" },
+  //  { int, "TEMP" },
+
+  { NULL, NULL }
+};
+
+
+static void InitializeSpecialFolderEnvVars()
+{
+  MozceShuntSpecialFolderInfo *p = mozceSpecialFoldersToEnvVars;
+  while ( p && p->nFolder && p->folderEnvName ) {
+    WCHAR wPath[MAX_PATH];
+    char  cPath[MAX_PATH];
+    if ( SHGetSpecialFolderPath(NULL, wPath, p->nFolder, FALSE) )
+      if ( 0 != WideCharToMultiByte(CP_ACP, 0, wPath, -1, cPath, MAX_PATH, 0, 0) )
+        map_put(p->folderEnvName, cPath);
+    p++;
+  }
+}
+
+
+
+MOZCE_SHUNT_API unsigned int ExpandEnvironmentStringsW(const unsigned short* lpSrc,
+                                                       unsigned short* lpDst,
+                                                       unsigned int nSize)
+{
+  if ( NULL == lpDst )
+    return 0;
+  
+  unsigned int size = 0;
+  unsigned int index = 0;
+  unsigned int origLen = wcslen(lpSrc);
+
+  const unsigned short *pIn = lpSrc;
+  unsigned short *pOut = lpDst;
+  
+  while ( index < origLen ) {
+	
+    if (*pIn != L'%') {  // Regular char, copy over
+      if ( size < nSize ) *pOut = *pIn, pOut++;
+      index++, size++, pIn++;
+      continue;
+    }
+	
+    // Have a starting '%' - look for matching '%'
+    int envlen = 0;
+    const unsigned short *pTmp = ++pIn;                    // Move past original '%'
+    while ( L'%' != *pTmp ) {
+      envlen++, pTmp++;
+      if ( origLen < index + envlen ) {    // Ran past end of original
+        SetLastError(ERROR_INVALID_PARAMETER); // buffer without matching '%'
+        return -1;
+      }
+    }
+	
+    if ( 0 == envlen ) {  // Encountered a "%%" - mapping to "%"
+      size++;
+      if ( size < nSize ) *pOut = *pIn, pOut++;
+      pIn++;
+      index += 2;
+    } else {
+      // Encountered a "%something%" - mapping "something"
+      char key[250];
+      WideCharToMultiByte( CP_ACP, 0, pIn, envlen, key, 250, NULL, NULL );
+      key[envlen] = 0;
+      char *pC = map_get(key);
+      if ( NULL != pC ) {
+        int n = MultiByteToWideChar( CP_ACP, 0, pC, -1, pOut, nSize - size );
+        if ( n > 0 ) {
+          size += n - 1;  // Account for trailing zero
+          pOut += n - 1;
+        }
+      }
+      index += envlen + 2;
+      pIn = ++pTmp;
+    }
+  }
+  
+  if ( size < nSize ) lpDst[size] = 0;
+  return size;
+}
+
+
+
+
 ////////////////////////////////////////////////////////
 //  errno
 ////////////////////////////////////////////////////////
 
 MOZCE_SHUNT_API char* strerror(int inErrno)
 {
   return "Unknown Error";
 }
@@ -218,24 +333,33 @@ MOZCE_SHUNT_API unsigned short * _wgetcw
   return dir;
 }
 
 MOZCE_SHUNT_API unsigned short *_wfullpath( unsigned short *absPath, const unsigned short *relPath, unsigned long maxLength )
 {
   if(absPath == NULL){
     absPath = (unsigned short *)malloc(maxLength*sizeof(unsigned short));
   }
-  _wgetcwd( absPath, maxLength);
-  unsigned long len = wcslen(absPath);
-  if(!(absPath[len-1] == TCHAR('/') || absPath[len-1] == TCHAR('\\'))&& len< maxLength){
-    absPath[len] = TCHAR('\\');
-    absPath[++len] = TCHAR('\0');
+  unsigned short cwd[MAX_PATH];
+  if (NULL == _wgetcwd( cwd, MAX_PATH))
+    return NULL;
+
+  unsigned long len = wcslen(cwd);
+  if(!(cwd[len-1] == TCHAR('/') || cwd[len-1] == TCHAR('\\'))&& len< maxLength){
+    cwd[len] = TCHAR('\\');
+    cwd[++len] = TCHAR('\0');
   }
   if(len+wcslen(relPath) < maxLength){
-    return wcscat(absPath,relPath);
+#if (_WIN32_WCE > 300)
+    if ( 0 < CeGetCanonicalPathName(wcscat(cwd,relPath), absPath, maxLength, 0) )
+      return absPath;
+#else
+    #error Need CeGetCanonicalPathName to build.
+    // NO ACTUAL CeGetCanonicalPathName function in earlier versions of WinCE
+#endif
   }
   return NULL;
 }
 
 MOZCE_SHUNT_API int _unlink(const char *filename)
 {
   unsigned short wname[MAX_PATH];
   
@@ -454,12 +578,41 @@ static struct lconv s_locale_conv =
     1,     /* n_sign_posn */
   };
 
 MOZCE_SHUNT_API struct lconv * localeconv(void)
 {
   return &s_locale_conv;
 }
  
+
+
+BOOL WINAPI DllMain(HANDLE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+  // Perform actions based on the reason for calling.
+  switch( fdwReason ) 
+  { 
+    case DLL_PROCESS_ATTACH:
+      // Initialize once for each new process.
+      // Return FALSE to fail DLL load.
+      InitializeSpecialFolderEnvVars();
+      break;
+
+    case DLL_THREAD_ATTACH:
+      // Do thread-specific initialization.
+      break;
+
+    case DLL_THREAD_DETACH:
+      // Do thread-specific cleanup.
+      break;
+
+    case DLL_PROCESS_DETACH:
+      // Perform any necessary cleanup.
+      break;
+  }
+  return TRUE;  // Successful DLL_PROCESS_ATTACH.
+}
+
+
  #if 0
  {
  #endif
  } /* extern "C" */
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -2170,16 +2170,19 @@ TAGS: $(SUBMAKEFILES) $(CSRCS) $(CPPSRCS
 	+$(LOOP_OVER_DIRS)
 
 echo-variable-%:
 	@echo $($*)
 
 echo-tiers:
 	@echo $(TIERS)
 
+echo-tier-dirs:
+	@$(foreach tier,$(TIERS),echo '$(tier):'; echo '  dirs: $(tier_$(tier)_dirs)'; echo '  staticdirs: $(tier_$(tier)_staticdirs)'; )
+
 echo-dirs:
 	@echo $(DIRS)
 
 echo-module:
 	@echo $(MODULE)
 
 echo-requires:
 	@echo $(REQUIRES)
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -54,16 +54,17 @@
 #include "nsIClassInfo.h"
 #include "nsIDOM3Node.h"
 #include "nsDataHashtable.h"
 #include "nsIScriptRuntime.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMEvent.h"
 #include "nsTArray.h"
 #include "nsTextFragment.h"
+#include "nsReadableUtils.h"
 
 struct nsNativeKeyEvent; // Don't include nsINativeKeyBindings.h here: it will force strange compilation error!
 
 class nsIDOMScriptObjectFactory;
 class nsIXPConnect;
 class nsINode;
 class nsIContent;
 class nsIDOMNode;
@@ -107,16 +108,17 @@ class nsIDragSession;
 class nsPIDOMWindow;
 class nsPIDOMEventTarget;
 #ifdef MOZ_XTF
 class nsIXTFService;
 #endif
 #ifdef IBMBIDI
 class nsIBidiKeyboard;
 #endif
+class nsIMIMEHeaderParam;
 
 extern const char kLoadAsData[];
 
 enum EventNameType {
   EventNameType_None = 0x0000,
   EventNameType_HTML = 0x0001,
   EventNameType_XUL = 0x0002,
   EventNameType_SVGGraphic = 0x0004, // svg graphic elements
@@ -1678,9 +1680,38 @@ inline NS_HIDDEN_(PRBool) NS_FloatIsFini
     return (rv);                                                              \
   }
 
 #define NS_ENSURE_FINITE6(f1, f2, f3, f4, f5, f6, rv)                         \
   if (!NS_FloatIsFinite((f1)+(f2)+(f3)+(f4)+(f5)+(f6))) {                     \
     return (rv);                                                              \
   }
 
+// Deletes a linked list iteratively to avoid blowing up the stack (bug 460444).
+#define NS_CONTENT_DELETE_LIST_MEMBER(type_, ptr_, member_)                   \
+  {                                                                           \
+    type_ *cur = (ptr_)->member_;                                             \
+    (ptr_)->member_ = nsnull;                                                 \
+    while (cur) {                                                             \
+      type_ *next = cur->member_;                                             \
+      cur->member_ = nsnull;                                                  \
+      delete cur;                                                             \
+      cur = next;                                                             \
+    }                                                                         \
+  }
+
+class nsContentTypeParser {
+public:
+  nsContentTypeParser(const nsAString& aString);
+  ~nsContentTypeParser();
+
+  nsresult GetParameter(const char* aParameterName, nsAString& aResult);
+  nsresult GetType(nsAString& aResult)
+  {
+    return GetParameter(nsnull, aResult);
+  }
+
+private:
+  NS_ConvertUTF16toUTF8 mString;
+  nsIMIMEHeaderParam*   mService;
+};
+
 #endif /* nsContentUtils_h___ */
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -553,28 +553,33 @@ public:
    *         If you return IME_STATUS_DISABLE, you should not set the
    *         OPEN or CLOSE flag; that way, when IME is next enabled,
    *         the previous OPEN/CLOSE state will be restored (unless the newly
    *         focused content specifies the OPEN/CLOSE state by setting the OPEN
    *         or CLOSE flag with the ENABLE flag).
    *         IME_STATUS_PASSWORD should be returned only from password editor,
    *         this value has a special meaning. It is used as alternative of
    *         IME_STATUS_DISABLED.
+   *         IME_STATUS_PLUGIN should be returned only when plug-in has focus.
+   *         When a plug-in is focused content, we should send native events
+   *         directly. Because we don't process some native events, but they may
+   *         be needed by the plug-in.
    */
   enum {
     IME_STATUS_NONE     = 0x0000,
     IME_STATUS_ENABLE   = 0x0001,
     IME_STATUS_DISABLE  = 0x0002,
     IME_STATUS_PASSWORD = 0x0004,
-    IME_STATUS_OPEN     = 0x0008,
-    IME_STATUS_CLOSE    = 0x0010
+    IME_STATUS_PLUGIN   = 0x0008,
+    IME_STATUS_OPEN     = 0x0010,
+    IME_STATUS_CLOSE    = 0x0020
   };
   enum {
     IME_STATUS_MASK_ENABLED = IME_STATUS_ENABLE | IME_STATUS_DISABLE |
-                              IME_STATUS_PASSWORD,
+                              IME_STATUS_PASSWORD | IME_STATUS_PLUGIN,
     IME_STATUS_MASK_OPENED  = IME_STATUS_OPEN | IME_STATUS_CLOSE
   };
   virtual PRUint32 GetDesiredIMEState()
   {
     if (!IsEditableInternal())
       return IME_STATUS_DISABLE;
     nsIContent *editableAncestor = nsnull;
     for (nsIContent* parent = GetParent();
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -156,16 +156,17 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsReferencedElement.h"
 #include "nsIUGenCategory.h"
 #include "nsIDragService.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIOfflineCacheUpdate.h"
 #include "nsCPrefetchService.h"
 #include "nsIChromeRegistry.h"
+#include "nsIMIMEHeaderParam.h"
 
 #ifdef IBMBIDI
 #include "nsIBidiKeyboard.h"
 #endif
 #include "nsCycleCollectionParticipant.h"
 
 // for ReportToConsole
 #include "nsIStringBundle.h"
@@ -457,28 +458,26 @@ nsContentUtils::InitializeEventTable() {
     { &nsGkAtoms::onSVGScroll,                   { NS_SVG_SCROLL, EventNameType_None }},
     { &nsGkAtoms::onSVGZoom,                     { NS_SVG_ZOOM, EventNameType_None }},
     { &nsGkAtoms::onzoom,                        { NS_SVG_ZOOM, EventNameType_SVGSVG }},
 #endif // MOZ_SVG
 #ifdef MOZ_MEDIA 
     { &nsGkAtoms::onloadstart,                   { NS_LOADSTART, EventNameType_HTML }},
     { &nsGkAtoms::onprogress,                    { NS_PROGRESS, EventNameType_HTML }},
     { &nsGkAtoms::onloadedmetadata,              { NS_LOADEDMETADATA, EventNameType_HTML }},
-    { &nsGkAtoms::onloadedfirstframe,            { NS_LOADEDFIRSTFRAME, EventNameType_HTML }},
+    { &nsGkAtoms::onloadeddata,                  { NS_LOADEDDATA, EventNameType_HTML }},
     { &nsGkAtoms::onemptied,                     { NS_EMPTIED, EventNameType_HTML }},
     { &nsGkAtoms::onstalled,                     { NS_STALLED, EventNameType_HTML }},
     { &nsGkAtoms::onplay,                        { NS_PLAY, EventNameType_HTML }},
     { &nsGkAtoms::onpause,                       { NS_PAUSE, EventNameType_HTML }},
     { &nsGkAtoms::onwaiting,                     { NS_WAITING, EventNameType_HTML }},
     { &nsGkAtoms::onseeking,                     { NS_SEEKING, EventNameType_HTML }},
     { &nsGkAtoms::onseeked,                      { NS_SEEKED, EventNameType_HTML }},
     { &nsGkAtoms::ontimeupdate,                  { NS_TIMEUPDATE, EventNameType_HTML }},
     { &nsGkAtoms::onended,                       { NS_ENDED, EventNameType_HTML }},
-    { &nsGkAtoms::ondataunavailable,             { NS_DATAUNAVAILABLE, EventNameType_HTML }},
-    { &nsGkAtoms::oncanshowcurrentframe,         { NS_CANSHOWCURRENTFRAME, EventNameType_HTML }},
     { &nsGkAtoms::oncanplay,                     { NS_CANPLAY, EventNameType_HTML }},
     { &nsGkAtoms::oncanplaythrough,              { NS_CANPLAYTHROUGH, EventNameType_HTML }},
     { &nsGkAtoms::onratechange,                  { NS_RATECHANGE, EventNameType_HTML }},
     { &nsGkAtoms::ondurationchange,              { NS_DURATIONCHANGE, EventNameType_HTML }},
     { &nsGkAtoms::onvolumechange,                { NS_VOLUMECHANGE, EventNameType_HTML }},
 #endif //MOZ_MEDIA
     { &nsGkAtoms::onMozAfterPaint,               { NS_AFTERPAINT, EventNameType_None }},
 
@@ -3857,16 +3856,18 @@ nsContentUtils::GetWidgetStatusFromIMESt
 {
   switch (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
     case nsIContent::IME_STATUS_DISABLE:
       return nsIWidget::IME_STATUS_DISABLED;
     case nsIContent::IME_STATUS_ENABLE:
       return nsIWidget::IME_STATUS_ENABLED;
     case nsIContent::IME_STATUS_PASSWORD:
       return nsIWidget::IME_STATUS_PASSWORD;
+    case nsIContent::IME_STATUS_PLUGIN:
+      return nsIWidget::IME_STATUS_PLUGIN;
     default:
       NS_ERROR("The given state doesn't have valid enable state");
       return nsIWidget::IME_STATUS_ENABLED;
   }
 }
 
 /* static */
 void
@@ -4517,8 +4518,27 @@ nsSameOriginChecker::OnChannelRedirect(n
 }
 
 NS_IMETHODIMP
 nsSameOriginChecker::GetInterface(const nsIID & aIID, void **aResult)
 {
   return QueryInterface(aIID, aResult);
 }
 
+nsContentTypeParser::nsContentTypeParser(const nsAString& aString)
+  : mString(aString), mService(nsnull)
+{
+  CallGetService("@mozilla.org/network/mime-hdrparam;1", &mService);
+}
+
+nsContentTypeParser::~nsContentTypeParser()
+{
+  NS_IF_RELEASE(mService);
+}
+
+nsresult
+nsContentTypeParser::GetParameter(const char* aParameterName, nsAString& aResult)
+{
+  NS_ENSURE_TRUE(mService, NS_ERROR_FAILURE);
+  return mService->GetParameter(mString, aParameterName,
+                                EmptyCString(), PR_FALSE, nsnull,
+                                aResult);
+}
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1561,48 +1561,44 @@ GK_ATOM(svgTextPathFrame, "SVGTextPathFr
 GK_ATOM(svgTSpanFrame, "SVGTSpanFrame")
 GK_ATOM(svgUseFrame, "SVGUseFrame")
 #endif
 #ifdef MOZ_MEDIA
 GK_ATOM(HTMLVideoFrame, "VideoFrame")
 GK_ATOM(onloadstart, "onloadstart")
 GK_ATOM(onprogress, "onprogress")
 GK_ATOM(onloadedmetadata, "onloadedmetadata")
-GK_ATOM(onloadedfirstframe, "onloadedfirstframe")
+GK_ATOM(onloadeddata, "onloadeddata")
 GK_ATOM(onemptied, "onemptied")
 GK_ATOM(onstalled, "onstalled")
 GK_ATOM(onplay, "onplay")
 GK_ATOM(onpause, "onpause")
 GK_ATOM(onwaiting, "onwaiting")
 GK_ATOM(onseeking, "onseeking")
 GK_ATOM(onseeked, "onseeked")
 GK_ATOM(ontimeupdate, "ontimeupdate")
 GK_ATOM(onended, "onended")
-GK_ATOM(ondataunavailable, "ondataunavailable")
-GK_ATOM(oncanshowcurrentframe, "oncanshowcurrentframe")
 GK_ATOM(oncanplay, "oncanplay")
 GK_ATOM(oncanplaythrough, "oncanplaythrough")
 GK_ATOM(onratechange, "onratechange")
 GK_ATOM(ondurationchange, "ondurationchange")
 GK_ATOM(onvolumechange, "onvolumechange")
 GK_ATOM(loadstart, "loadstart")
 GK_ATOM(progress, "progress")
 GK_ATOM(loadedmetadata, "loadedmetadata")
-GK_ATOM(loadedfirstframe, "loadedfirstframe")
+GK_ATOM(loadeddata, "loadeddata")
 GK_ATOM(emptied, "emptied")
 GK_ATOM(stalled, "stalled")
 GK_ATOM(play, "play")
 GK_ATOM(pause, "pause")
 GK_ATOM(waiting, "waiting")
 GK_ATOM(seeking, "seeking")
 GK_ATOM(seeked, "seeked")
 GK_ATOM(timeupdate, "timeupdate")
 GK_ATOM(ended, "ended")
-GK_ATOM(dataunavailable, "dataunavailable")
-GK_ATOM(canshowcurrentframe, "canshowcurrentframe")
 GK_ATOM(canplay, "canplay")
 GK_ATOM(canplaythrough, "canplaythrough")
 GK_ATOM(ratechange, "ratechange")
 GK_ATOM(durationchange, "durationchange")
 GK_ATOM(volumechange, "volumechange")
 #endif
 
 // Frame property names
--- a/content/base/src/nsImageLoadingContent.h
+++ b/content/base/src/nsImageLoadingContent.h
@@ -41,19 +41,21 @@
  * subclassed by various content nodes that want to provide image
  * loading functionality (eg <img>, <object>, etc).
  */
 
 #ifndef nsImageLoadingContent_h__
 #define nsImageLoadingContent_h__
 
 #include "nsIImageLoadingContent.h"
+#include "nsINode.h"
 #include "imgIRequest.h"
 #include "prtypes.h"
 #include "nsCOMPtr.h"
+#include "nsContentUtils.h"
 #include "nsString.h"
 
 class nsIURI;
 class nsIDocument;
 class imgILoader;
 class nsIIOService;
 
 class nsImageLoadingContent : public nsIImageLoadingContent
@@ -158,17 +160,17 @@ private:
       mObserver(aObserver),
       mNext(nsnull)
     {
       MOZ_COUNT_CTOR(ImageObserver);
     }
     ~ImageObserver()
     {
       MOZ_COUNT_DTOR(ImageObserver);
-      delete mNext;
+      NS_CONTENT_DELETE_LIST_MEMBER(ImageObserver, this, mNext);
     }
 
     nsCOMPtr<imgIDecoderObserver> mObserver;
     ImageObserver* mNext;
   };
 
   /**
    * Struct to report state changes
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -39,17 +39,16 @@
 
 /*
  * A class that handles loading and evaluation of <script> elements.
  */
 
 #include "nsScriptLoader.h"
 #include "nsIDOMCharacterData.h"
 #include "nsParserUtils.h"
-#include "nsIMIMEHeaderParam.h"
 #include "nsICharsetConverterManager.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsIContent.h"
 #include "nsGkAtoms.h"
 #include "nsNetUtil.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptRuntime.h"
@@ -326,26 +325,20 @@ nsScriptLoader::ProcessScriptElement(nsI
   PRUint32 version = 0;
   nsAutoString language, type, src;
   nsresult rv = NS_OK;
 
   // Check the type attribute to determine language and version.
   // If type exists, it trumps the deprecated 'language='
   aElement->GetScriptType(type);
   if (!type.IsEmpty()) {
-    nsCOMPtr<nsIMIMEHeaderParam> mimeHdrParser =
-      do_GetService("@mozilla.org/network/mime-hdrparam;1");
-    NS_ENSURE_TRUE(mimeHdrParser, NS_ERROR_FAILURE);
-
-    NS_ConvertUTF16toUTF8 typeAndParams(type);
+    nsContentTypeParser parser(type);
 
     nsAutoString mimeType;
-    rv = mimeHdrParser->GetParameter(typeAndParams, nsnull,
-                                     EmptyCString(), PR_FALSE, nsnull,
-                                     mimeType);
+    rv = parser.GetType(mimeType);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Javascript keeps the fast path, optimized for most-likely type
     // Table ordered from most to least likely JS MIME types.
     // See bug 62485, feel free to add <script type="..."> survey data to it,
     // or to a new bug once 62485 is closed.
     static const char *jsTypes[] = {
       "text/javascript",
@@ -374,19 +367,17 @@ nsScriptLoader::ProcessScriptElement(nsI
         NS_WARNING("Failed to find a scripting language");
         typeID = nsIProgrammingLanguage::UNKNOWN;
       } else
         typeID = runtime->GetScriptTypeID();
     }
     if (typeID != nsIProgrammingLanguage::UNKNOWN) {
       // Get the version string, and ensure the language supports it.
       nsAutoString versionName;
-      rv = mimeHdrParser->GetParameter(typeAndParams, "version",
-                                       EmptyCString(), PR_FALSE, nsnull,
-                                       versionName);
+      rv = parser.GetParameter("version", versionName);
       if (NS_FAILED(rv)) {
         // no version attribute - version remains 0.
         if (rv != NS_ERROR_INVALID_ARG)
           return rv;
       } else {
         nsCOMPtr<nsIScriptRuntime> runtime;
         rv = NS_GetScriptRuntimeByID(typeID, getter_AddRefs(runtime));
         if (NS_FAILED(rv)) {
@@ -399,20 +390,17 @@ nsScriptLoader::ProcessScriptElement(nsI
           typeID = nsIProgrammingLanguage::UNKNOWN;
         }
       }
     }
 
     // Some js specifics yet to be abstracted.
     if (typeID == nsIProgrammingLanguage::JAVASCRIPT) {
       nsAutoString value;
-
-      rv = mimeHdrParser->GetParameter(typeAndParams, "e4x",
-                                       EmptyCString(), PR_FALSE, nsnull,
-                                       value);
+      rv = parser.GetParameter("e4x", value);
       if (NS_FAILED(rv)) {
         if (rv != NS_ERROR_INVALID_ARG)
           return rv;
       } else {
         if (value.Length() == 1 && value[0] == '1')
           // This means that we need to set JSOPTION_XML in the JS options.
           // We re-use our knowledge of the implementation to reuse
           // JSVERSION_HAS_XML as a safe version flag.
--- a/content/base/src/nsSyncLoadService.cpp
+++ b/content/base/src/nsSyncLoadService.cpp
@@ -453,18 +453,25 @@ nsresult
 nsSyncLoadService::PushSyncStreamToListener(nsIInputStream* aIn,
                                             nsIStreamListener* aListener,
                                             nsIChannel* aChannel)
 {
     // Set up buffering stream
     nsresult rv;
     nsCOMPtr<nsIInputStream> bufferedStream;
     if (!NS_InputStreamIsBuffered(aIn)) {
+        PRInt32 chunkSize;
+        rv = aChannel->GetContentLength(&chunkSize);
+        if (NS_FAILED(rv)) {
+            chunkSize = 4096;
+        }
+        chunkSize = PR_MIN(PR_UINT16_MAX, chunkSize);
+
         rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), aIn,
-                                       4096);
+                                       chunkSize);
         NS_ENSURE_SUCCESS(rv, rv);
 
         aIn = bufferedStream;
     }
 
     // Load
     aListener->OnStartRequest(aChannel, nsnull);
     PRUint32 sourceOffset = 0;
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -1962,23 +1962,27 @@ nsCanvasRenderingContext2D::SetFont(cons
 
     NS_ASSERTION(fontStyle, "Could not obtain font style");
 
     // use CSS pixels instead of dev pixels to avoid being affected by page zoom
     const PRUint32 aupcp = nsPresContext::AppUnitsPerCSSPixel();
     // un-zoom the font size to avoid being affected by text-only zoom
     const nscoord fontSize = nsStyleFont::UnZoomText(parentContext->PresContext(), fontStyle->mFont.size);
 
+    PRBool printerFont = (presShell->GetPresContext()->Type() == nsPresContext::eContext_PrintPreview ||
+                          presShell->GetPresContext()->Type() == nsPresContext::eContext_Print);
+
     gfxFontStyle style(fontStyle->mFont.style,
                        fontStyle->mFont.weight,
                        NSAppUnitsToFloatPixels(fontSize, aupcp),
                        langGroup,
                        fontStyle->mFont.sizeAdjust,
                        fontStyle->mFont.systemFont,
-                       fontStyle->mFont.familyNameQuirks);
+                       fontStyle->mFont.familyNameQuirks,
+                       printerFont);
 
     CurrentState().fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(fontStyle->mFont.name, &style, presShell->GetPresContext()->GetUserFontSet());
     NS_ASSERTION(CurrentState().fontGroup, "Could not get font group");
     CurrentState().font = font;
     return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/content/events/public/nsIPrivateTextRange.h
+++ b/content/events/public/nsIPrivateTextRange.h
@@ -44,16 +44,19 @@
 
 #define NS_IPRIVATETEXTRANGE_IID \
 {0xb471ab41, 0x2a79, 0x11d3, \
 { 0x9e, 0xa4, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b } } 
 
 class nsIPrivateTextRange : public nsISupports {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATETEXTRANGE_IID)
+
+  // Note that the range array may not specify a caret position; in that
+  // case there will be no range of type TEXTRANGE_CARETPOSITION in the array.
   enum {
     TEXTRANGE_CARETPOSITION = 1,
     TEXTRANGE_RAWINPUT = 2,
     TEXTRANGE_SELECTEDRAWTEXT = 3,
     TEXTRANGE_CONVERTEDTEXT = 4,
     TEXTRANGE_SELECTEDCONVERTEDTEXT = 5
   };
 
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -72,21 +72,20 @@ static const char* const sEventNames[] =
   "DOMActivate", "DOMFocusIn", "DOMFocusOut",
   "pageshow", "pagehide", "DOMMouseScroll", "MozMousePixelScroll",
   "offline", "online", "copy", "cut", "paste",
 #ifdef MOZ_SVG
   "SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
   "SVGZoom",
 #endif // MOZ_SVG
 #ifdef MOZ_MEDIA
-  "loadstart", "progress", "loadedmetadata", "loadedfirstframe",
+  "loadstart", "progress", "loadedmetadata", "loadeddata",
   "emptied", "stalled", "play", "pause",
-  "waiting", "seeking", "seeked", "timeupdate", "ended", "dataunavailable",
-  "canshowcurrentframe", "canplay", "canplaythrough", "ratechange",
-  "durationchange", "volumechange",
+  "waiting", "seeking", "seeked", "timeupdate", "ended",
+  "canplay", "canplaythrough", "ratechange", "durationchange", "volumechange",
 #endif // MOZ_MEDIA
   "MozAfterPaint",
   "MozSwipeGesture",
   "MozMagnifyGestureStart",
   "MozMagnifyGestureUpdate",
   "MozMagnifyGesture",
   "MozRotateGestureStart",
   "MozRotateGestureUpdate",
@@ -611,18 +610,18 @@ nsDOMEvent::SetEventType(const nsAString
 #ifdef MOZ_MEDIA
   else if (mEvent->eventStructType == NS_MEDIA_EVENT) {
     if (atom == nsGkAtoms::onloadstart)
       mEvent->message = NS_LOADSTART;
     else if (atom == nsGkAtoms::onprogress)
       mEvent->message = NS_PROGRESS;
     else if (atom == nsGkAtoms::onloadedmetadata)
       mEvent->message = NS_LOADEDMETADATA;
-    else if (atom == nsGkAtoms::onloadedfirstframe)
-      mEvent->message = NS_LOADEDFIRSTFRAME;
+    else if (atom == nsGkAtoms::onloadeddata)
+      mEvent->message = NS_LOADEDDATA;
     else if (atom == nsGkAtoms::onemptied)
       mEvent->message = NS_EMPTIED;
     else if (atom == nsGkAtoms::onstalled)
       mEvent->message = NS_STALLED;
     else if (atom == nsGkAtoms::onplay)
       mEvent->message = NS_PLAY;
     else if (atom == nsGkAtoms::onpause)
       mEvent->message = NS_PAUSE;
@@ -631,20 +630,16 @@ nsDOMEvent::SetEventType(const nsAString
     else if (atom == nsGkAtoms::onwaiting)
       mEvent->message = NS_SEEKING;
     else if (atom == nsGkAtoms::onseeking)
       mEvent->message = NS_SEEKED;
     else if (atom == nsGkAtoms::onseeked)
       mEvent->message = NS_TIMEUPDATE;
     else if (atom == nsGkAtoms::onended)
       mEvent->message = NS_ENDED;
-    else if (atom == nsGkAtoms::ondataunavailable)
-      mEvent->message = NS_DATAUNAVAILABLE;
-    else if (atom == nsGkAtoms::oncanshowcurrentframe)
-      mEvent->message = NS_CANSHOWCURRENTFRAME;
     else if (atom == nsGkAtoms::oncanplay)
       mEvent->message = NS_CANPLAY;
     else if (atom == nsGkAtoms::oncanplaythrough)
       mEvent->message = NS_CANPLAYTHROUGH;
     else if (atom == nsGkAtoms::onratechange)
       mEvent->message = NS_RATECHANGE;
     else if (atom == nsGkAtoms::ondurationchange)
       mEvent->message = NS_DURATIONCHANGE;
@@ -1474,18 +1469,18 @@ const char* nsDOMEvent::GetEventName(PRU
 #endif // MOZ_SVG
 #ifdef MOZ_MEDIA
   case NS_LOADSTART:
     return sEventNames[eDOMEvents_loadstart];
   case NS_PROGRESS:
     return sEventNames[eDOMEvents_progress];
   case NS_LOADEDMETADATA:
     return sEventNames[eDOMEvents_loadedmetadata];
-  case NS_LOADEDFIRSTFRAME:
-    return sEventNames[eDOMEvents_loadedfirstframe];
+  case NS_LOADEDDATA:
+    return sEventNames[eDOMEvents_loadeddata];
   case NS_EMPTIED:
     return sEventNames[eDOMEvents_emptied];
   case NS_STALLED:
     return sEventNames[eDOMEvents_stalled];
   case NS_PLAY:
     return sEventNames[eDOMEvents_play];
   case NS_PAUSE:
     return sEventNames[eDOMEvents_pause];
@@ -1494,20 +1489,16 @@ const char* nsDOMEvent::GetEventName(PRU
   case NS_SEEKING:
     return sEventNames[eDOMEvents_seeking];
   case NS_SEEKED:
     return sEventNames[eDOMEvents_seeked];
   case NS_TIMEUPDATE:
     return sEventNames[eDOMEvents_timeupdate];
   case NS_ENDED:
     return sEventNames[eDOMEvents_ended];
-  case NS_DATAUNAVAILABLE:
-    return sEventNames[eDOMEvents_dataunavailable];
-  case NS_CANSHOWCURRENTFRAME:
-    return sEventNames[eDOMEvents_canshowcurrentframe];
   case NS_CANPLAY:
     return sEventNames[eDOMEvents_canplay];
   case NS_CANPLAYTHROUGH:
     return sEventNames[eDOMEvents_canplaythrough];
   case NS_RATECHANGE:
     return sEventNames[eDOMEvents_ratechange];
   case NS_DURATIONCHANGE:
     return sEventNames[eDOMEvents_durationchange];
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -138,28 +138,26 @@ public:
     eDOMEvents_SVGResize,
     eDOMEvents_SVGScroll,
     eDOMEvents_SVGZoom,
 #endif // MOZ_SVG
 #ifdef MOZ_MEDIA
     eDOMEvents_loadstart,
     eDOMEvents_progress,
     eDOMEvents_loadedmetadata,
-    eDOMEvents_loadedfirstframe,
+    eDOMEvents_loadeddata,
     eDOMEvents_emptied,
     eDOMEvents_stalled,
     eDOMEvents_play,
     eDOMEvents_pause,
     eDOMEvents_waiting,
     eDOMEvents_seeking,
     eDOMEvents_seeked,
     eDOMEvents_timeupdate,
     eDOMEvents_ended,
-    eDOMEvents_dataunavailable,
-    eDOMEvents_canshowcurrentframe,
     eDOMEvents_canplay,
     eDOMEvents_canplaythrough,
     eDOMEvents_ratechange,
     eDOMEvents_durationchange,
     eDOMEvents_volumechange,
 #endif
     eDOMEvents_afterpaint,
     eDOMEvents_MozSwipeGesture,
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -52,35 +52,42 @@
 
 // nsEventTargetChainItem represents a single item in the event target chain.
 class nsEventTargetChainItem
 {
 private:
   nsEventTargetChainItem(nsPIDOMEventTarget* aTarget,
                          nsEventTargetChainItem* aChild = nsnull);
 
-  void Destroy(nsFixedSizeAllocator* aAllocator);
-
 public:
   static nsEventTargetChainItem* Create(nsFixedSizeAllocator* aAllocator, 
                                         nsPIDOMEventTarget* aTarget,
                                         nsEventTargetChainItem* aChild = nsnull)
   {
     void* place = aAllocator->Alloc(sizeof(nsEventTargetChainItem));
     return place
       ? ::new (place) nsEventTargetChainItem(aTarget, aChild)
       : nsnull;
   }
 
   static void Destroy(nsFixedSizeAllocator* aAllocator,
                       nsEventTargetChainItem* aItem)
   {
-    aItem->Destroy(aAllocator);
-    aItem->~nsEventTargetChainItem();
-    aAllocator->Free(aItem, sizeof(nsEventTargetChainItem));
+    // ::Destroy deletes ancestor chain.
+    nsEventTargetChainItem* item = aItem;
+    if (item->mChild) {
+      item->mChild->mParent = nsnull;
+      item->mChild = nsnull;
+    }
+    while (item) {
+      nsEventTargetChainItem* parent = item->mParent;
+      item->~nsEventTargetChainItem();
+      aAllocator->Free(item, sizeof(nsEventTargetChainItem));
+      item = parent;
+    }
   }
 
   PRBool IsValid()
   {
     NS_WARN_IF_FALSE(!!(mTarget), "Event target is not valid!");
     return !!(mTarget);
   }
 
@@ -176,32 +183,16 @@ nsEventTargetChainItem::nsEventTargetCha
 : mChild(aChild), mParent(nsnull), mFlags(0), mItemFlags(0)
 {
   mTarget = aTarget->GetTargetForEventTargetChain();
   if (mChild) {
     mChild->mParent = this;
   }
 }
 
-void
-nsEventTargetChainItem::Destroy(nsFixedSizeAllocator* aAllocator)
-{
-  if (mChild) {
-    mChild->mParent = nsnull;
-    mChild = nsnull;
-  }
-
-  if (mParent) {
-    Destroy(aAllocator, mParent);
-    mParent = nsnull;
-  }
-
-  mTarget = nsnull;
-}
-
 nsresult
 nsEventTargetChainItem::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   aVisitor.Reset();
   nsresult rv = mTarget->PreHandleEvent(aVisitor);
   SetForceContentDispatch(aVisitor.mForceContentDispatch);
   SetWantsWillHandleEvent(aVisitor.mWantsWillHandleEvent);
   mItemFlags = aVisitor.mItemFlags;
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -4492,16 +4492,18 @@ nsEventStateManager::GetNextTabbableMapA
                                             nsIContent *aImageContent)
 {
   nsAutoString useMap;
   aImageContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, useMap);
 
   nsCOMPtr<nsIDocument> doc = aImageContent->GetDocument();
   if (doc) {
     nsCOMPtr<nsIDOMHTMLMapElement> imageMap = nsImageMapUtils::FindImageMap(doc, useMap);
+    if (!imageMap)
+      return nsnull;
     nsCOMPtr<nsIContent> mapContent = do_QueryInterface(imageMap);
     PRUint32 count = mapContent->GetChildCount();
     // First see if mCurrentFocus is in this map
     PRInt32 index = mapContent->IndexOf(mCurrentFocus);
     PRInt32 tabIndex;
     if (index < 0 || (mCurrentFocus->IsFocusable(&tabIndex) &&
                       tabIndex != mCurrentTabIndex)) {
       // If mCurrentFocus is in this map we must start iterating past it.
--- a/content/events/test/Makefile.in
+++ b/content/events/test/Makefile.in
@@ -57,16 +57,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug379120.html \
 		test_bug391568.xhtml \
 		test_bug402089.html \
 		test_bug405632.html \
 		test_bug409604.html \
 		test_bug412567.html \
 		test_bug443985.html \
 		test_bug447736.html \
+		test_bug450876.html \
 		test_bug456273.html \
 		test_bug457672.html \
 		test_bug428988.html \
 		bug457672.html \
 		test_draggableprop.html \
 		test_dragstart.html \
 		$(NULL)
 
--- a/content/events/test/test_bug238987.html
+++ b/content/events/test/test_bug238987.html
@@ -112,33 +112,33 @@ https://bugzilla.mozilla.org/show_bug.cg
                        getInterface(Components.interfaces.nsIDOMWindowUtils);
     // Send tab key events.
     var key = Components.interfaces.nsIDOMKeyEvent.DOM_VK_TAB;
     utils.sendKeyEvent("keydown", key, 0, modifier);
     utils.sendKeyEvent("keypress", key, 0, modifier);
     utils.sendKeyEvent("keyup", key, 0, modifier);
     if (shouldStop) {
       // Did focus handling succeed
-      ok(forwardFocusArray.length == 0,
+      is(forwardFocusArray.length, 0,
          "Not all forward tabbing focus tests were run, " +
          forwardFocusArray.toString());
-      ok(backwardFocusArray.length == 0,
+      is(backwardFocusArray.length, 0,
          "Not all backward tabbing focus tests were run, " +
          backwardFocusArray.toString());
-      ok(expectedWindowFocusCount == 0,
+      is(expectedWindowFocusCount, 0,
          "|window| didn't get the right amount of focus events");
 
        // and blur.
-      ok(forwardBlurArray.length == 0,
+      is(forwardBlurArray.length, 0,
          "Not all forward tabbing blur tests were run, " +
          forwardBlurArray.toString());
-      ok(backwardBlurArray.length == 0,
+      is(backwardBlurArray.length, 0,
          "Not all backward tabbing blur tests were run, " +
          backwardBlurArray.toString());
-      ok(expectedWindowBlurCount == 0,
+      is(expectedWindowBlurCount, 0,
          "|window| didn't get the right amount of blur events");
       setOrRestoreTabFocus(0);
       SimpleTest.finish();
     } else {
       setTimeout(tab, 50);
     }
   }
 
@@ -149,16 +149,19 @@ https://bugzilla.mozilla.org/show_bug.cg
     window.addEventListener("blur", handleWindowBlur, true);
     window.addEventListener("blur", handleWindowBlur, false);
     var elements = document.getElementsByTagName("*");
     for (var i = 0; i < elements.length; ++i) {
       if (elements[i].hasAttribute("id")) {
         elements[i].addEventListener("focus", handleFocus, false);
         elements[i].addEventListener("blur", handleBlur, false);
       }
+      if (elements[i].getAttribute("tabindex") == "1") {
+        elements[i].setAttribute("tabindex", "-1");
+      }
     }
     tab();
   }
 
   function doTest() {
     setOrRestoreTabFocus(7);
     setTimeout(start, 100);
   }
@@ -201,14 +204,81 @@ https://bugzilla.mozilla.org/show_bug.cg
         <td>select</td><td><select id="i10"><option>select</option></select></td>
       </tr>
       <tr>
         <td>a</td><td><a href="#radio" id="i11">a link</a></td>
       </tr>
       <tr>
         <td>tabindex="0"</td><td><span tabindex="0" id="i12">span</span></td>
       </tr>
+      
+      <tr>
+        <td><h3>Form elements with tabindex="-1"</h3></td>
+      </tr>
+      <tr>
+        <td>type="text"</td><td><input type="text"  tabindex="-1" value=""></td>
+      </tr>
+      <tr>
+        <td>type="button"</td><td><input type="button" tabindex="-1" value="type='button'"></td>
+      </tr>
+      <tr>
+        <td>type="checkbox"</td><td><input type="checkbox" tabindex="-1"></td>
+      </tr>
+      <tr>
+        <td>type="radio" checked</td><td><input type="radio" tabindex="-1" name="radio3" checked>
+                                         <input type="radio" tabindex="-1" name="radio3"></td>
+      </tr>
+      <tr>
+        <td>type="radio"</td><td><input type="radio" tabindex="-1" name="radio4">
+                                 <input type="radio" tabindex="-1" name="radio4"></td>
+      </tr>
+      <tr>
+        <td>type="password"</td><td><input type="password" tabindex="-1"></td>
+      </tr>
+      <tr>
+        <td>type="file"</td><td><input type="file" tabindex="-1"></td>
+      </tr>
+      <tr>
+        <td>button</td><td><button tabindex="-1">button</button></td>
+      </tr>
+      <tr>
+        <td>select</td><td><select tabindex="-1"><option>select</option></select></td>
+      </tr>
+      
+      <tr>
+        <td><h3>Form elements with .setAttribute("tabindex", "-1")</h3></td>
+      </tr>
+      <tr>
+        <td>type="text"</td><td><input type="text"  tabindex="1" value=""></td>
+      </tr>
+      <tr>
+        <td>type="button"</td><td><input type="button" tabindex="1" value="type='button'"></td>
+      </tr>
+      <tr>
+        <td>type="checkbox"</td><td><input type="checkbox" tabindex="1"></td>
+      </tr>
+      <tr>
+        <td>type="radio" checked</td><td><input type="radio" tabindex="1" name="radio5" checked>
+                                         <input type="radio" tabindex="1" name="radio5"></td>
+      </tr>
+      <tr>
+        <td>type="radio"</td><td><input type="radio" tabindex="1" name="radio6">
+                                 <input type="radio" tabindex="1" name="radio6"></td>
+      </tr>
+      <tr>
+        <td>type="password"</td><td><input type="password" tabindex="1"></td>
+      </tr>
+      <tr>
+        <td>type="file"</td><td><input type="file" tabindex="1"></td>
+      </tr>
+      <tr>
+        <td>button</td><td><button tabindex="1">button</button></td>
+      </tr>
+      <tr>
+        <td>select</td><td><select tabindex="1"><option>select</option></select></td>
+      </tr>
+      
     </tbody>
   </table>
   <h4 tabindex="0" id="end">done.</h4>
 </body>
 </html>
 
new file mode 100644
--- /dev/null
+++ b/content/events/test/test_bug450876.html
@@ -0,0 +1,43 @@
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=450876
+-->
+<head>
+  <title>Test for Bug 450876 - Crash [@ nsEventStateManager::GetNextTabbableMapArea] with img usemap and tabindex</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/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=450876">Mozilla Bug 450876</a>
+<p id="display"><a href="#" id="a">link to focus from</a><img usemap="#a" tabindex="1"></p>
+<div id="content" style="display: none">
+  
+</div>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 450876 **/
+
+function doTest() {
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  is(document.activeElement, document.body, "body element should be focused");
+  document.getElementById('a').focus();
+  is(document.activeElement, document.getElementById('a'), "link should have focus");
+  var wu =  window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                .getInterface(Components.interfaces.nsIDOMWindowUtils);
+  wu.sendKeyEvent('keypress',  9, 0, 0);
+  is(document.activeElement, document.body, "body element should be focused");
+
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+
+</script>
+</pre>
+</body>
+</html>
+
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -133,19 +133,19 @@ public:
   nsresult DispatchProgressEvent(const nsAString& aName);
   nsresult DispatchAsyncSimpleEvent(const nsAString& aName);
   nsresult DispatchAsyncProgressEvent(const nsAString& aName);
 
   // Use this method to change the mReadyState member, so required
   // events can be fired.
   void ChangeReadyState(nsMediaReadyState aState);
 
-  // Is the media element actively playing as defined by the HTML 5 specification.
-  // http://www.whatwg.org/specs/web-apps/current-work/#actively
-  PRBool IsActivelyPlaying() const;
+  // Is the media element potentially playing as defined by the HTML 5 specification.
+  // http://www.whatwg.org/specs/web-apps/current-work/#potentially-playing
+  PRBool IsPotentiallyPlaying() const;
 
   // Has playback ended as defined by the HTML 5 specification.
   // http://www.whatwg.org/specs/web-apps/current-work/#ended
   PRBool IsPlaybackEnded() const;
 
   // principal of the currently playing stream
   nsIPrincipal* GetCurrentPrincipal();
 
@@ -154,52 +154,68 @@ public:
   void UpdateMediaSize(nsIntSize size);
 
   // Handle moving into and out of the bfcache by pausing and playing
   // as needed.
   void Freeze();
   void Thaw();
 
   // Returns true if we can handle this MIME type in a <video> or <audio>
-  // element
-  static PRBool CanHandleMediaType(const char* aMIMEType);
+  // element.
+  // If it returns true, then it also returns a null-terminated list
+  // of supported codecs in *aSupportedCodecs, and a null-terminated list
+  // of codecs that *may* be supported in *aMaybeSupportedCodecs. These
+  // lists should not be freed, they area static data.
+  static PRBool CanHandleMediaType(const char* aMIMEType,
+                                   const char*** aSupportedCodecs,
+                                   const char*** aMaybeSupportedCodecs);
 
   /**
    * Initialize data for available media types
    */
   static void InitMediaTypes();
   /**
    * Shutdown data for available media types
    */
   static void ShutdownMediaTypes();
 
 protected:
+  class nsMediaLoadListener;
+
   /**
-   * Figure out which resource to load (either the 'src' attribute or
-   * a <source> child) and create the decoder for it.
+   * Figure out which resource to load (either the 'src' attribute or a
+   * <source> child) and return the associated URI.
    */
-  nsresult PickMediaElement();
+  nsresult PickMediaElement(nsIURI** aURI);
   /**
    * Create a decoder for the given aMIMEType. Returns false if we
    * were unable to create the decoder.
    */
   PRBool CreateDecoder(const nsACString& aMIMEType);
   /**
-   * Initialize a decoder to load the given URI.
-   */
-  nsresult InitializeDecoder(const nsAString& aURISpec);
-  /**
    * Initialize a decoder to load the given channel. The decoder's stream
    * listener is returned via aListener.
    */
   nsresult InitializeDecoderForChannel(nsIChannel *aChannel,
                                        nsIStreamListener **aListener);
+  /**
+   * Execute the initial steps of the load algorithm that ensure existing
+   * loads are aborted and the element is emptied.  Returns true if aborted,
+   * false if emptied.
+   */
+  PRBool AbortExistingLoads();
+  /**
+   * Create a URI for the given aURISpec string.
+   */
+  nsresult NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI);
 
   nsRefPtr<nsMediaDecoder> mDecoder;
 
+  nsCOMPtr<nsIChannel> mChannel;
+
   // Error attribute
   nsCOMPtr<nsIDOMHTMLMediaError> mError;
 
   // Media loading flags. See: 
   //   http://www.whatwg.org/specs/web-apps/current-work/#video)
   nsMediaNetworkState mNetworkState;
   nsMediaReadyState mReadyState;
 
@@ -245,9 +261,13 @@ protected:
   // or was not actively playing before the current seek. Used to decide whether
   // to raise the 'waiting' event as per 4.7.1.8 in HTML 5 specification.
   PRPackedBool mPlayingBeforeSeek;
 
   // PR_TRUE if the video was paused before Freeze was called. This is checked
   // to ensure that the playstate doesn't change when the user goes Forward/Back
   // from the bfcache.
   PRPackedBool mPausedBeforeFreeze;
+
+  // True if playback was requested before a decoder was available to begin
+  // playback with.
+  PRPackedBool mPlayRequested;
 };
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -50,29 +50,31 @@
 #include "nsNodeInfoManager.h"
 #include "plbase64.h"
 #include "nsNetUtil.h"
 #include "prmem.h"
 #include "nsNetUtil.h"
 #include "nsXPCOMStrings.h"
 #include "prlock.h"
 #include "nsThreadUtils.h"
+#include "nsContentUtils.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 
 #include "nsIRenderingContext.h"
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
 #include "nsIDOMDocumentEvent.h"
 #include "nsIDOMProgressEvent.h"
 #include "nsHTMLMediaError.h"
 #include "nsICategoryManager.h"
+#include "nsCommaSeparatedTokenizer.h"
 
 #ifdef MOZ_OGG
 #include "nsOggDecoder.h"
 #endif
 #ifdef MOZ_WAVE
 #include "nsWaveDecoder.h"
 #endif
 
@@ -91,16 +93,77 @@ public:
   
   NS_IMETHOD Run() {
     return mProgress ?
       mElement->DispatchProgressEvent(mName) :
       mElement->DispatchSimpleEvent(mName);
   }
 };
 
+class nsHTMLMediaElement::nsMediaLoadListener : public nsIStreamListener
+{
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIREQUESTOBSERVER
+  NS_DECL_NSISTREAMLISTENER
+
+public:
+  nsMediaLoadListener(nsHTMLMediaElement* aElement)
+    : mElement(aElement)
+  {
+    NS_ABORT_IF_FALSE(mElement, "Must pass an element to call back");
+  }
+
+private:
+  nsRefPtr<nsHTMLMediaElement> mElement;
+  nsCOMPtr<nsIStreamListener> mNextListener;
+};
+
+NS_IMPL_ISUPPORTS2(nsHTMLMediaElement::nsMediaLoadListener, nsIRequestObserver, nsIStreamListener)
+
+NS_IMETHODIMP nsHTMLMediaElement::nsMediaLoadListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
+{
+  nsresult rv;
+
+  nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
+  if (channel &&
+      mElement &&
+      NS_SUCCEEDED(mElement->InitializeDecoderForChannel(channel, getter_AddRefs(mNextListener))) &&
+      mNextListener) {
+    rv = mNextListener->OnStartRequest(aRequest, aContext);
+  } else {
+    // If InitializeDecoderForChannel did not return a listener, we abort
+    // the connection since we aren't interested in keeping the channel
+    // alive ourselves.
+    rv = NS_BINDING_ABORTED;
+  }
+
+  // The element is only needed until we've had a chance to call
+  // InitializeDecoderForChannel.
+  mElement = nsnull;
+
+  return rv;
+}
+
+NS_IMETHODIMP nsHTMLMediaElement::nsMediaLoadListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
+                                                                     nsresult aStatus)
+{
+  if (mNextListener) {
+    return mNextListener->OnStopRequest(aRequest, aContext, aStatus);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsHTMLMediaElement::nsMediaLoadListener::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
+                                                                       nsIInputStream* aStream, PRUint32 aOffset,
+                                                                       PRUint32 aCount)
+{
+  NS_ABORT_IF_FALSE(mNextListener, "Must have a listener");
+  return mNextListener->OnDataAvailable(aRequest, aContext, aStream, aOffset, aCount);
+}
+
 // nsIDOMHTMLMediaElement
 NS_IMPL_URI_ATTR(nsHTMLMediaElement, Src, src)
 NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Controls, controls)
 NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Autoplay, autoplay)
 
 /* readonly attribute nsIDOMHTMLMediaError error; */
 NS_IMETHODIMP nsHTMLMediaElement::GetError(nsIDOMHTMLMediaError * *aError)
 {
@@ -138,63 +201,126 @@ NS_IMETHODIMP nsHTMLMediaElement::GetCur
 /* readonly attribute unsigned short networkState; */
 NS_IMETHODIMP nsHTMLMediaElement::GetNetworkState(PRUint16 *aNetworkState)
 {
   *aNetworkState = mNetworkState;
 
   return NS_OK;
 }
 
-/* void load (); */
-NS_IMETHODIMP nsHTMLMediaElement::Load()
+PRBool nsHTMLMediaElement::AbortExistingLoads()
 {
-  return LoadWithChannel(nsnull, nsnull);
-}
-
-nsresult nsHTMLMediaElement::LoadWithChannel(nsIChannel *aChannel,
-                                             nsIStreamListener **aListener)
-{
-  NS_ASSERTION((aChannel == nsnull) == (aListener == nsnull),
-               "channel and listener should both be null or both non-null");
-
-  if (aListener) {
-    *aListener = nsnull;
+  if (mDecoder) {
+    mDecoder->ElementUnavailable();
+    mDecoder->Shutdown();
+    mDecoder = nsnull;
   }
 
   if (mBegun) {
     mBegun = PR_FALSE;
-    
     mError = new nsHTMLMediaError(nsHTMLMediaError::MEDIA_ERR_ABORTED);
     DispatchProgressEvent(NS_LITERAL_STRING("abort"));
-    return NS_OK;
+    return PR_TRUE;
   }
 
   mError = nsnull;
   mLoadedFirstFrame = PR_FALSE;
   mAutoplaying = PR_TRUE;
 
   // TODO: The playback rate must be set to the default playback rate.
 
-  if (mNetworkState != nsIDOMHTMLMediaElement::EMPTY) {
-    mNetworkState = nsIDOMHTMLMediaElement::EMPTY;
-    ChangeReadyState(nsIDOMHTMLMediaElement::DATA_UNAVAILABLE);
+  if (mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
+    mNetworkState = nsIDOMHTMLMediaElement::NETWORK_EMPTY;
+    ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING);
     mPaused = PR_TRUE;
     // TODO: The current playback position must be set to 0.
     // TODO: The currentLoop DOM attribute must be set to 0.
     DispatchSimpleEvent(NS_LITERAL_STRING("emptied"));
   }
 
-  nsresult rv;
-  if (aChannel) {
-    rv = InitializeDecoderForChannel(aChannel, aListener);
-  } else {
-    rv = PickMediaElement();
+  return PR_FALSE;
+}
+
+/* void load (); */
+NS_IMETHODIMP nsHTMLMediaElement::Load()
+{
+  if (AbortExistingLoads())
+    return NS_OK;
+
+  nsCOMPtr<nsIURI> uri;
+  nsresult rv = PickMediaElement(getter_AddRefs(uri));
+  if (NS_FAILED(rv))
+    return rv;
+
+  if (mChannel) {
+    mChannel->Cancel(NS_BINDING_ABORTED);
+    mChannel = nsnull;
   }
+
+  rv = NS_NewChannel(getter_AddRefs(mChannel),
+                     uri,
+                     nsnull,
+                     nsnull,
+                     nsnull,
+                     nsIRequest::LOAD_NORMAL);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // The listener holds a strong reference to us.  This creates a reference
+  // cycle which is manually broken in the listener's OnStartRequest method
+  // after it is finished with the element.
+  nsCOMPtr<nsIStreamListener> listener = new nsMediaLoadListener(this);
+  NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
+
+  nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(mChannel);
+  if (hc) {
+    // Use a byte range request from the start of the resource.
+    // This enables us to detect if the stream supports byte range
+    // requests, and therefore seeking, early.
+    hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"),
+                         NS_LITERAL_CSTRING("bytes=0-"),
+                         PR_FALSE);
+  }
+
+  rv = mChannel->AsyncOpen(listener, nsnull);
+  if (NS_FAILED(rv)) {
+    // OnStartRequest is guaranteed to be called if the open succeeds.  If
+    // the open failed, the listener's OnStartRequest will never be called,
+    // so we need to break the element->channel->listener->element reference
+    // cycle here.  The channel holds the only reference to the listener,
+    // and is useless now anyway, so drop our reference to it to allow it to
+    // be destroyed.
+    mChannel = nsnull;
+    return rv;
+  }
+
+  mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
+
+  mBegun = PR_TRUE;
+
+  DispatchAsyncProgressEvent(NS_LITERAL_STRING("loadstart"));
+
+  return NS_OK;
+}
+
+nsresult nsHTMLMediaElement::LoadWithChannel(nsIChannel *aChannel,
+                                             nsIStreamListener **aListener)
+{
+  NS_ENSURE_ARG_POINTER(aChannel);
+  NS_ENSURE_ARG_POINTER(aListener);
+
+  *aListener = nsnull;
+
+  if (AbortExistingLoads())
+    return NS_OK;
+
+  nsresult rv = InitializeDecoderForChannel(aChannel, aListener);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
   mBegun = PR_TRUE;
 
   DispatchAsyncProgressEvent(NS_LITERAL_STRING("loadstart"));
 
   return NS_OK;
 }
 
 /* readonly attribute unsigned short readyState; */
@@ -224,20 +350,20 @@ NS_IMETHODIMP nsHTMLMediaElement::SetCur
 {
   if (!mDecoder)
     return NS_ERROR_DOM_INVALID_STATE_ERR;
 
   // Detect for a NaN and invalid values.
   if (!(aCurrentTime >= 0.0))
     return NS_ERROR_FAILURE;
 
-  if (mNetworkState < nsIDOMHTMLMediaElement::LOADED_METADATA) 
+  if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) 
     return NS_ERROR_DOM_INVALID_STATE_ERR;
 
-  mPlayingBeforeSeek = IsActivelyPlaying();
+  mPlayingBeforeSeek = IsPotentiallyPlaying();
   // The media backend is responsible for dispatching the timeupdate
   // event if it changes the playback position as a result of the seek.
   nsresult rv = mDecoder->Seek(aCurrentTime);
   return rv;
 }
 
 /* readonly attribute float duration; */
 NS_IMETHODIMP nsHTMLMediaElement::GetDuration(float *aDuration)
@@ -257,17 +383,17 @@ NS_IMETHODIMP nsHTMLMediaElement::GetPau
 /* void pause (); */
 NS_IMETHODIMP nsHTMLMediaElement::Pause()
 {
   if (!mDecoder) 
     return NS_OK;
 
   nsresult rv;
 
-  if (mNetworkState == nsIDOMHTMLMediaElement::EMPTY) {
+  if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
     rv = Load();
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   mDecoder->Pause();
   PRBool oldPaused = mPaused;
   mPaused = PR_TRUE;
   mAutoplaying = PR_FALSE;
@@ -332,49 +458,55 @@ NS_IMETHODIMP nsHTMLMediaElement::SetMut
 
   if (oldMuted != mMuted) 
     DispatchSimpleEvent(NS_LITERAL_STRING("volumechange"));
   return NS_OK;
 }
 
 nsHTMLMediaElement::nsHTMLMediaElement(nsINodeInfo *aNodeInfo, PRBool aFromParser)
   : nsGenericHTMLElement(aNodeInfo),
-    mNetworkState(nsIDOMHTMLMediaElement::EMPTY),
-    mReadyState(nsIDOMHTMLMediaElement::DATA_UNAVAILABLE),
+    mNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY),
+    mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING),
     mMutedVolume(0.0),
     mMediaSize(-1,-1),
     mBegun(PR_FALSE),
     mLoadedFirstFrame(PR_FALSE),
     mAutoplaying(PR_TRUE),
     mPaused(PR_TRUE),
     mMuted(PR_FALSE),
     mIsDoneAddingChildren(!aFromParser),
-    mPlayingBeforeSeek(PR_FALSE)
+    mPlayingBeforeSeek(PR_FALSE),
+    mPlayRequested(PR_FALSE)
 {
 }
 
 nsHTMLMediaElement::~nsHTMLMediaElement()
 {
   if (mDecoder) {
     mDecoder->Shutdown();
     mDecoder = nsnull;
   }
+  if (mChannel) {
+    mChannel->Cancel(NS_BINDING_ABORTED);
+    mChannel = nsnull;
+  }
 }
 
-NS_IMETHODIMP
-nsHTMLMediaElement::Play(void)
+NS_IMETHODIMP nsHTMLMediaElement::Play()
 {
-  if (!mDecoder)
+  if (!mDecoder) {
+    mPlayRequested = PR_TRUE;
     return NS_OK;
+  }
 
   nsresult rv;
 
-  if (mNetworkState == nsIDOMHTMLMediaElement::EMPTY) {
-    rv = Load();
-    NS_ENSURE_SUCCESS(rv, rv);
+  if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
+    mPlayRequested = PR_TRUE;
+    return Load();
   }
 
   if (mDecoder->IsEnded()) {
     SetCurrentTime(0);
   }
 
   // TODO: If the playback has ended, then the user agent must set 
   // currentLoop to zero and seek to the effective start.
@@ -387,21 +519,20 @@ nsHTMLMediaElement::Play(void)
   mAutoplaying = PR_FALSE;
 
   if (oldPaused)
     DispatchAsyncSimpleEvent(NS_LITERAL_STRING("play"));
 
   return NS_OK;
 }
 
-PRBool
-nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
-                                   nsIAtom* aAttribute,
-                                   const nsAString& aValue,
-                                   nsAttrValue& aResult)
+PRBool nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
+                                          nsIAtom* aAttribute,
+                                          const nsAString& aValue,
+                                          nsAttrValue& aResult)
 {
   if (aNamespaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::src) {
       static const char* kWhitespace = " \n\r\t\b";
       aResult.SetTo(nsContentUtils::TrimCharsInSet(kWhitespace, aValue));
       return PR_TRUE;
     }
     else if (aAttribute == nsGkAtoms::loopstart
@@ -414,20 +545,19 @@ nsHTMLMediaElement::ParseAttribute(PRInt
       return PR_TRUE;
     }
   }
 
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
-nsresult
-nsHTMLMediaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                            nsIAtom* aPrefix, const nsAString& aValue,
-                            PRBool aNotify)
+nsresult nsHTMLMediaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                                     nsIAtom* aPrefix, const nsAString& aValue,
+                                     PRBool aNotify)
 {
   nsresult rv = 
     nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
                                     aNotify);
   if (aNotify && aNameSpaceID == kNameSpaceID_None) {
     if (aName == nsGkAtoms::src) {
       Load();
     }
@@ -442,39 +572,51 @@ nsresult nsHTMLMediaElement::BindToTree(
 {
   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, 
                                                  aParent, 
                                                  aBindingParent, 
                                                  aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (mIsDoneAddingChildren &&
-      mNetworkState == nsIDOMHTMLMediaElement::EMPTY) {
+      mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
     Load();
   }
 
   return rv;
 }
 
 void nsHTMLMediaElement::UnbindFromTree(PRBool aDeep,
                                         PRBool aNullParent)
 {
-  if (!mPaused && mNetworkState != nsIDOMHTMLMediaElement::EMPTY)
+  if (!mPaused && mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY)
     Pause();
 
   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
 }
 
 #ifdef MOZ_OGG
+// See http://www.rfc-editor.org/rfc/rfc5334.txt for the definitions
+// of Ogg media types and codec types
 static const char gOggTypes[][16] = {
   "video/ogg",
   "audio/ogg",
   "application/ogg"
 };
 
+static const char* gOggCodecs[] = {
+  "vorbis",
+  "theora",
+  nsnull
+};
+
+static const char* gOggMaybeCodecs[] = {
+  nsnull
+}; 
+
 static PRBool IsOggEnabled()
 {
   return nsContentUtils::GetBoolPref("media.ogg.enabled");
 }
 
 static PRBool IsOggType(const nsACString& aType)
 {
   if (!IsOggEnabled())
@@ -483,23 +625,36 @@ static PRBool IsOggType(const nsACString
     if (aType.EqualsASCII(gOggTypes[i]))
       return PR_TRUE;
   }
   return PR_FALSE;
 }
 #endif
 
 #ifdef MOZ_WAVE
+// See http://www.rfc-editor.org/rfc/rfc2361.txt for the definitions
+// of WAVE media types and codec types. However, the audio/vnd.wave
+// MIME type described there is not used.
 static const char gWaveTypes[][16] = {
   "audio/x-wav",
   "audio/wav",
   "audio/wave",
   "audio/x-pn-wav"
 };
 
+static const char* gWaveCodecs[] = {
+  "1", // Microsoft PCM Format
+  nsnull
+};
+
+static const char* gWaveMaybeCodecs[] = {
+  "0", // Microsoft Unknown Wave Format
+  nsnull
+};
+
 static PRBool IsWaveEnabled()
 {
   return nsContentUtils::GetBoolPref("media.wave.enabled");
 }
 
 static PRBool IsWaveType(const nsACString& aType)
 {
   if (!IsWaveEnabled())
@@ -508,29 +663,109 @@ static PRBool IsWaveType(const nsACStrin
     if (aType.EqualsASCII(gWaveTypes[i]))
       return PR_TRUE;
   }
   return PR_FALSE;
 }
 #endif
 
 /* static */
-PRBool nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType)
+PRBool nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType,
+                                              const char*** aCodecList,
+                                              const char*** aMaybeCodecList)
 {
 #ifdef MOZ_OGG
-  if (IsOggType(nsDependentCString(aMIMEType)))
+  if (IsOggType(nsDependentCString(aMIMEType))) {
+    *aCodecList = gOggCodecs;
+    *aMaybeCodecList = gOggMaybeCodecs;
     return PR_TRUE;
+  }
 #endif
 #ifdef MOZ_WAVE
-  if (IsWaveType(nsDependentCString(aMIMEType)))
+  if (IsWaveType(nsDependentCString(aMIMEType))) {
+    *aCodecList = gWaveCodecs;
+    *aMaybeCodecList = gWaveMaybeCodecs;
     return PR_TRUE;
+  }
 #endif
   return PR_FALSE;
 }
 
+static PRBool
+CodecListContains(const char** aCodecs, const nsAString& aCodec)
+{
+  for (PRInt32 i = 0; aCodecs[i]; ++i) {
+    if (aCodec.EqualsASCII(aCodecs[i]))
+      return PR_TRUE;
+  }
+  return PR_FALSE;
+}
+
+enum CanPlayStatus {
+  CANPLAY_NO,
+  CANPLAY_MAYBE,
+  CANPLAY_YES
+};
+
+static CanPlayStatus GetCanPlay(const nsAString& aType)
+{
+  nsContentTypeParser parser(aType);
+  nsAutoString mimeType;
+  nsresult rv = parser.GetType(mimeType);
+  if (NS_FAILED(rv))
+    return CANPLAY_NO;
+
+  NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType);
+  const char** supportedCodecs;
+  const char** maybeSupportedCodecs;
+  if (!nsHTMLMediaElement::CanHandleMediaType(mimeTypeUTF8.get(),
+          &supportedCodecs, &maybeSupportedCodecs))
+    return CANPLAY_NO;
+
+  nsAutoString codecs;
+  rv = parser.GetParameter("codecs", codecs);
+  if (NS_FAILED(rv))
+    // Parameter not found or whatever
+    return CANPLAY_MAYBE;
+
+  CanPlayStatus result = CANPLAY_YES;
+  // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
+  // of the 'codecs' parameter
+  nsCommaSeparatedTokenizer tokenizer(codecs);
+  PRBool expectMoreTokens = PR_FALSE;
+  while (tokenizer.hasMoreTokens()) {
+    const nsSubstring& token = tokenizer.nextToken();
+
+    if (CodecListContains(maybeSupportedCodecs, token)) {
+      result = CANPLAY_MAYBE;
+    } else if (!CodecListContains(supportedCodecs, token)) {
+      // Totally unsupported codec
+      return CANPLAY_NO;
+    }
+    expectMoreTokens = tokenizer.lastTokenEndedWithComma();
+  }
+  if (expectMoreTokens) {
+    // Last codec name was empty
+    return CANPLAY_NO;
+  }
+  return result;
+}
+
+NS_IMETHODIMP
+nsHTMLMediaElement::CanPlayType(const nsAString& aType, nsAString& aResult)
+{
+  switch (GetCanPlay(aType)) {
+  case CANPLAY_NO: aResult.AssignLiteral("no"); break;
+  case CANPLAY_YES: aResult.AssignLiteral("probably"); break;
+  default:
+  case CANPLAY_MAYBE: aResult.AssignLiteral("maybe"); break;
+  }
+  return NS_OK;
+}
+
 /* static */
 void nsHTMLMediaElement::InitMediaTypes()
 {
   nsresult rv;
   nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
   if (NS_SUCCEEDED(rv)) {
 #ifdef MOZ_OGG
     if (IsOggEnabled()) {
@@ -597,196 +832,197 @@ nsresult nsHTMLMediaElement::InitializeD
                                                          nsIStreamListener **aListener)
 {
   nsCAutoString mimeType;
   aChannel->GetContentType(mimeType);
 
   if (!CreateDecoder(mimeType))
     return NS_ERROR_FAILURE;
 
-  mNetworkState = nsIDOMHTMLMediaElement::LOADING;
+  mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
   mDecoder->ElementAvailable(this);
-  
+
   return mDecoder->Load(nsnull, aChannel, aListener);
 }
 
-nsresult nsHTMLMediaElement::PickMediaElement()
+nsresult nsHTMLMediaElement::NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI)
 {
+  NS_ENSURE_ARG_POINTER(aURI);
+
+  *aURI = nsnull;
+
+  nsCOMPtr<nsIDocument> doc = GetOwnerDoc();
+  if (!doc) {
+    return NS_ERROR_DOM_INVALID_STATE_ERR;
+  }
+
+  nsCOMPtr<nsIURI> baseURI = GetBaseURI();
+  nsresult rv = nsContentUtils::NewURIWithDocumentCharset(aURI,
+                                                          aURISpec,
+                                                          doc,
+                                                          baseURI);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRBool equal;
+  if (aURISpec.IsEmpty() &&
+      doc->GetDocumentURI() &&
+      NS_SUCCEEDED(doc->GetDocumentURI()->Equals(*aURI, &equal)) &&
+      equal) {
+    // It's not possible for a media resource to be embedded in the current
+    // document we extracted aURISpec from, so there's no point returning
+    // the current document URI just to let the caller attempt and fail to
+    // decode it.
+    NS_RELEASE(*aURI);
+    return NS_ERROR_DOM_INVALID_STATE_ERR;
+  }
+
+  return NS_OK;
+}
+
+nsresult nsHTMLMediaElement::PickMediaElement(nsIURI** aURI)
+{
+  NS_ENSURE_ARG_POINTER(aURI);
+
   // Implements:
-  // http://www.whatwg.org/specs/web-apps/current-work/#pick-a
+  // http://www.whatwg.org/specs/web-apps/current-work/#pick-a-media-resource
   nsAutoString src;
   if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
-#ifdef MOZ_OGG
-    // Currently assuming an Ogg file
-    // TODO: Instantiate decoder based on type
-    if (mDecoder) {
-      mDecoder->ElementUnavailable();
-      mDecoder->Shutdown();
-      mDecoder = nsnull;
-    }
-
-    if (IsOggEnabled()) {
-      mDecoder = new nsOggDecoder();
-      if (mDecoder && !mDecoder->Init()) {
-        mDecoder = nsnull;
-      }
-    }
-#endif
-    return InitializeDecoder(src);
+    return NewURIFromString(src, aURI);
   }
 
   // Checking of 'source' elements as per:
-  // http://www.whatwg.org/specs/web-apps/current-work/#pick-a
+  // http://www.whatwg.org/specs/web-apps/current-work/#pick-a-media-resource
   PRUint32 count = GetChildCount();
   for (PRUint32 i = 0; i < count; ++i) {
     nsIContent* child = GetChildAt(i);
     NS_ASSERTION(child, "GetChildCount lied!");
-    
+
     nsCOMPtr<nsIContent> source = do_QueryInterface(child);
-    if (source) {
+    if (source &&
+        source->Tag() == nsGkAtoms::source &&
+        source->IsNodeOfType(nsINode::eHTML)) {
       nsAutoString type;
       nsAutoString src;
-      if (source->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src) &&
-          source->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type) &&
-          CreateDecoder(NS_ConvertUTF16toUTF8(type)))
-        return InitializeDecoder(src);
+      if (source->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
+        if (source->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type)) {
+          if (GetCanPlay(type) != CANPLAY_NO)
+            return NewURIFromString(src, aURI);
+        } else if (i + 1 == count) {
+          // The last source element is permitted to omit the type
+          // attribute, in which case we need to open the URI and examine
+          // the channel's MIME type.
+          return NewURIFromString(src, aURI);
+        }
+      }
     }
   }
 
   return NS_ERROR_DOM_INVALID_STATE_ERR;
 }
 
-nsresult nsHTMLMediaElement::InitializeDecoder(const nsAString& aURISpec)
-{
-  mNetworkState = nsIDOMHTMLMediaElement::LOADING;
-
-  nsCOMPtr<nsIDocument> doc = GetOwnerDoc();
-  if (!doc) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  nsresult rv;
-  nsCOMPtr<nsIURI> uri;
-  nsCOMPtr<nsIURI> baseURL = GetBaseURI();
-  rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
-                                                 aURISpec,
-                                                 doc,
-                                                 baseURL);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (mDecoder) {
-    mDecoder->ElementAvailable(this);
-    rv = mDecoder->Load(uri, nsnull, nsnull);
-    if (NS_FAILED(rv)) {
-      mDecoder->Shutdown();
-      mDecoder = nsnull;
-    }
-  }
-  return rv;
-}
-
 void nsHTMLMediaElement::MetadataLoaded()
 {
-  mNetworkState = nsIDOMHTMLMediaElement::LOADED_METADATA;
+  ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
   DispatchAsyncSimpleEvent(NS_LITERAL_STRING("durationchange"));
   DispatchAsyncSimpleEvent(NS_LITERAL_STRING("loadedmetadata"));
+  if (mPlayRequested) {
+    mPlayRequested = PR_FALSE;
+    mPaused = PR_FALSE;
+    if (mDecoder) {
+      mDecoder->Play();
+    }
+    DispatchAsyncSimpleEvent(NS_LITERAL_STRING("play"));
+  }
 }
 
 void nsHTMLMediaElement::FirstFrameLoaded()
 {
-  mNetworkState = nsIDOMHTMLMediaElement::LOADED_FIRST_FRAME;
-  ChangeReadyState(nsIDOMHTMLMediaElement::CAN_SHOW_CURRENT_FRAME);
+  ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
   mLoadedFirstFrame = PR_TRUE;
-  DispatchAsyncSimpleEvent(NS_LITERAL_STRING("loadedfirstframe"));
-  DispatchAsyncSimpleEvent(NS_LITERAL_STRING("canshowcurrentframe"));
+  DispatchAsyncSimpleEvent(NS_LITERAL_STRING("loadeddata"));
 }
 
 void nsHTMLMediaElement::ResourceLoaded()
 {
   mBegun = PR_FALSE;
-  mNetworkState = nsIDOMHTMLMediaElement::LOADED;
-  ChangeReadyState(nsIDOMHTMLMediaElement::CAN_PLAY_THROUGH);
-
+  mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADED;
+  ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA);
   DispatchProgressEvent(NS_LITERAL_STRING("load"));
 }
 
 void nsHTMLMediaElement::NetworkError()
 {
   mError = new nsHTMLMediaError(nsHTMLMediaError::MEDIA_ERR_NETWORK);
   mBegun = PR_FALSE;
   DispatchProgressEvent(NS_LITERAL_STRING("error"));
-  mNetworkState = nsIDOMHTMLMediaElement::EMPTY;
-  DispatchSimpleEvent(NS_LITERAL_STRING("empty"));
+  mNetworkState = nsIDOMHTMLMediaElement::NETWORK_EMPTY;
+  DispatchSimpleEvent(NS_LITERAL_STRING("emptied"));
 }
 
 void nsHTMLMediaElement::PlaybackEnded()
 {
   NS_ASSERTION(mDecoder->IsEnded(), "Decoder fired ended, but not in ended state");
   mBegun = PR_FALSE;
   mPaused = PR_TRUE;
   DispatchSimpleEvent(NS_LITERAL_STRING("ended"));
 }
 
 void nsHTMLMediaElement::CanPlayThrough()
 {
-  ChangeReadyState(nsIDOMHTMLMediaElement::CAN_PLAY_THROUGH);
+  ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA);
 }
 
 void nsHTMLMediaElement::SeekStarted()
 {
   DispatchAsyncSimpleEvent(NS_LITERAL_STRING("seeking"));
 }
 
 void nsHTMLMediaElement::SeekCompleted()
 {
   mPlayingBeforeSeek = PR_FALSE;
   DispatchAsyncSimpleEvent(NS_LITERAL_STRING("seeked"));
 }
 
 void nsHTMLMediaElement::ChangeReadyState(nsMediaReadyState aState)
 {
-  // Handle raising of "waiting" event during seek (see 4.7.10.8)
-  if (mPlayingBeforeSeek && aState <= nsIDOMHTMLMediaElement::CAN_PLAY)
+  // Handle raising of "waiting" event during seek (see 4.8.10.9)
+  if (mPlayingBeforeSeek && aState < nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA)
     DispatchAsyncSimpleEvent(NS_LITERAL_STRING("waiting"));
-    
+
   mReadyState = aState;
-  if (mNetworkState != nsIDOMHTMLMediaElement::EMPTY) {
+  if (mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
     switch(mReadyState) {
-    case nsIDOMHTMLMediaElement::DATA_UNAVAILABLE:
-      DispatchAsyncSimpleEvent(NS_LITERAL_STRING("dataunavailable"));
-      LOG(PR_LOG_DEBUG, ("Ready state changed to DATA_UNAVAILABLE"));
-      break;
-      
-    case nsIDOMHTMLMediaElement::CAN_SHOW_CURRENT_FRAME:
-      if (mLoadedFirstFrame) {
-        DispatchAsyncSimpleEvent(NS_LITERAL_STRING("canshowcurrentframe"));
-        LOG(PR_LOG_DEBUG, ("Ready state changed to CAN_SHOW_CURRENT_FRAME"));
-      }
+    case nsIDOMHTMLMediaElement::HAVE_NOTHING:
+      LOG(PR_LOG_DEBUG, ("Ready state changed to HAVE_NOTHING"));
       break;
 
-    case nsIDOMHTMLMediaElement::CAN_PLAY:
-      DispatchAsyncSimpleEvent(NS_LITERAL_STRING("canplay"));
-      LOG(PR_LOG_DEBUG, ("Ready state changed to CAN_PLAY"));
+    case nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA:
+      LOG(PR_LOG_DEBUG, ("Ready state changed to HAVE_CURRENT_DATA"));
       break;
 
-    case nsIDOMHTMLMediaElement::CAN_PLAY_THROUGH:
+    case nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA:
+      DispatchAsyncSimpleEvent(NS_LITERAL_STRING("canplay"));
+      LOG(PR_LOG_DEBUG, ("Ready state changed to HAVE_FUTURE_DATA"));
+      break;
+
+    case nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA:
       DispatchAsyncSimpleEvent(NS_LITERAL_STRING("canplaythrough"));
-      if (mAutoplaying && 
-         mPaused && 
-         HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) {
+      if (mAutoplaying &&
+          mPaused &&
+          HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) {
         mPaused = PR_FALSE;
         if (mDecoder) {
           mDecoder->Play();
         }
-        LOG(PR_LOG_DEBUG, ("Ready state changed to CAN_PLAY_THROUGH"));
         DispatchAsyncSimpleEvent(NS_LITERAL_STRING("play"));
       }
+      LOG(PR_LOG_DEBUG, ("Ready state changed to HAVE_ENOUGH_DATA"));
       break;
     }
-  }  
+  }
 }
 
 void nsHTMLMediaElement::Paint(gfxContext* aContext, const gfxRect& aRect) 
 {
   if (mDecoder)
     mDecoder->Paint(aContext, aRect);
 }
 
@@ -836,53 +1072,52 @@ nsresult nsHTMLMediaElement::DispatchPro
   return target->DispatchEvent(event, &dummy);  
 }
 
 nsresult nsHTMLMediaElement::DoneAddingChildren(PRBool aHaveNotified)
 {
   if (!mIsDoneAddingChildren) {
     mIsDoneAddingChildren = PR_TRUE;
   
-    if (mNetworkState == nsIDOMHTMLMediaElement::EMPTY) {
+    if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
       Load();
     }
   }
 
   return NS_OK;
 }
 
 PRBool nsHTMLMediaElement::IsDoneAddingChildren()
 {
   return mIsDoneAddingChildren;
 }
 
-PRBool nsHTMLMediaElement::IsActivelyPlaying() const
+PRBool nsHTMLMediaElement::IsPotentiallyPlaying() const
 {
   // TODO: 
   //   playback has not stopped due to errors, 
   //   and the element has not paused for user interaction
   return 
     !mPaused && 
-    (mReadyState == nsIDOMHTMLMediaElement::CAN_PLAY || 
-     mReadyState == nsIDOMHTMLMediaElement::CAN_PLAY_THROUGH) &&
+    (mReadyState == nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA ||
+    mReadyState == nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA) &&
     !IsPlaybackEnded();
 }
 
 PRBool nsHTMLMediaElement::IsPlaybackEnded() const
 {
   // TODO:
   //   the current playback position is equal to the effective end of the media resource, 
   //   and the currentLoop attribute is equal to playCount-1. 
   //   See bug 449157.
-  return mNetworkState >= nsIDOMHTMLMediaElement::LOADED_METADATA &&
+  return mNetworkState >= nsIDOMHTMLMediaElement::HAVE_METADATA &&
     mDecoder ? mDecoder->IsEnded() : PR_FALSE;
 }
 
-nsIPrincipal*
-nsHTMLMediaElement::GetCurrentPrincipal()
+nsIPrincipal* nsHTMLMediaElement::GetCurrentPrincipal()
 {
   if (!mDecoder)
     return nsnull;
 
   return mDecoder->GetCurrentPrincipal();
 }
 
 void nsHTMLMediaElement::UpdateMediaSize(nsIntSize size)
@@ -891,16 +1126,20 @@ void nsHTMLMediaElement::UpdateMediaSize
 }
 
 void nsHTMLMediaElement::DestroyContent()
 {
   if (mDecoder) {
     mDecoder->Shutdown();
     mDecoder = nsnull;
   }
+  if (mChannel) {
+    mChannel->Cancel(NS_BINDING_ABORTED);
+    mChannel = nsnull;
+  }
   nsGenericHTMLElement::DestroyContent();
 }
 
 void nsHTMLMediaElement::Freeze()
 {
   mPausedBeforeFreeze = mPaused;
   if (!mPaused) {
     Pause();
--- a/content/html/content/src/nsHTMLObjectElement.cpp
+++ b/content/html/content/src/nsHTMLObjectElement.cpp
@@ -293,17 +293,17 @@ nsHTMLObjectElement::IsHTMLFocusable(PRB
 
   return nsGenericHTMLFormElement::IsHTMLFocusable(aIsFocusable, aTabIndex);
 }
 
 PRUint32
 nsHTMLObjectElement::GetDesiredIMEState()
 {
   if (Type() == eType_Plugin) {
-    return nsIContent::IME_STATUS_ENABLE;
+    return nsIContent::IME_STATUS_PLUGIN;
   }
    
   return nsGenericHTMLFormElement::GetDesiredIMEState();
 }
 
 NS_IMETHODIMP
 nsHTMLObjectElement::Reset()
 {
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -312,17 +312,17 @@ nsHTMLSharedObjectElement::IsHTMLFocusab
 
   return nsGenericHTMLElement::IsHTMLFocusable(aIsFocusable, aTabIndex);
 }
 
 PRUint32
 nsHTMLSharedObjectElement::GetDesiredIMEState()
 {
   if (Type() == eType_Plugin) {
-    return nsIContent::IME_STATUS_ENABLE;
+    return nsIContent::IME_STATUS_PLUGIN;
   }
    
   return nsGenericHTMLElement::GetDesiredIMEState();
 }
 
 NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Align, align)
 NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Alt, alt)
 NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Archive, archive)
--- a/content/html/document/crashtests/crashtests.list
+++ b/content/html/document/crashtests/crashtests.list
@@ -1,5 +1,5 @@
-load 353713-1.html
+#load 353713-1.html # Bug 469626
 load 388183-1.html
 load 395340-1.html
 load 407053.html
 load 448564.html
--- a/content/media/video/public/nsAudioStream.h
+++ b/content/media/video/public/nsAudioStream.h
@@ -35,16 +35,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #if !defined(nsAudioStream_h_)
 #define nsAudioStream_h_
 
 #include "nscore.h"
 #include "prlog.h"
+#include "nsTArray.h"
 
 extern PRLogModuleInfo* gAudioStreamLog;
 
 class nsAudioStream 
 {
  public:
   enum SampleFormat
   {
@@ -112,11 +113,17 @@ class nsAudioStream
   PRInt64 mPauseBytes;
 
   float mStartTime;
   float mPauseTime;
   PRInt64 mSamplesBuffered;
 
   SampleFormat mFormat;
 
+  // When a Write() request is made, and the number of samples
+  // requested to be written exceeds the buffer size of the audio
+  // backend, the remaining samples are stored in this variable. They
+  // will be written on the next Write() request.
+  nsTArray<short> mBufferOverflow;
+
   PRPackedBool mPaused;
 };
 #endif
--- a/content/media/video/src/nsAudioStream.cpp
+++ b/content/media/video/src/nsAudioStream.cpp
@@ -117,59 +117,73 @@ void nsAudioStream::Shutdown()
 }
 
 void nsAudioStream::Write(const void* aBuf, PRUint32 aCount)
 {
   NS_ABORT_IF_FALSE(aCount % mChannels == 0,
                     "Buffer size must be divisible by channel count");
 
   mSamplesBuffered += aCount;
+  PRUint32 offset = mBufferOverflow.Length();
+  PRInt32 count = aCount + offset;
 
   if (!mAudioHandle)
     return;
 
-  nsAutoArrayPtr<short> s_data(new short[aCount]);
+  nsAutoArrayPtr<short> s_data(new short[count]);
 
   if (s_data) {
-    switch (mFormat) {
-    case FORMAT_U8: {
-      const PRUint8* buf = static_cast<const PRUint8*>(aBuf);
-      PRInt32 volume = PRInt32((1 << 16) * mVolume);
-      for (PRUint32 i = 0; i < aCount; ++i) {
-        s_data[i] = short(((PRInt32(buf[i]) - 128) * volume) >> 8);
-      }
-      break;
-    }
-    case FORMAT_S16_LE: {
-      const short* buf = static_cast<const short*>(aBuf);
-      PRInt32 volume = PRInt32((1 << 16) * mVolume);
-      for (PRUint32 i = 0; i < aCount; ++i) {
-        s_data[i] = short((PRInt32(buf[i]) * volume) >> 16);
-      }
-      break;
+    for (PRUint32 i=0; i < offset; ++i) {
+      s_data[i] = mBufferOverflow.ElementAt(i);
     }
-    case FORMAT_FLOAT32_LE: {
-      const float* buf = static_cast<const float*>(aBuf);
-      for (PRUint32 i= 0; i <  aCount; ++i) {
-        float scaled_value = floorf(0.5 + 32768 * buf[i] * mVolume);
-        if (buf[i] < 0.0) {
-          s_data[i] = (scaled_value < -32768.0) ?
-            -32768 :
-            short(scaled_value);
-        } else {
-          s_data[i] = (scaled_value > 32767.0) ?
-            32767 :
-            short(scaled_value);
+    mBufferOverflow.Clear();
+
+    switch (mFormat) {
+      case FORMAT_U8: {
+        const PRUint8* buf = static_cast<const PRUint8*>(aBuf);
+        PRInt32 volume = PRInt32((1 << 16) * mVolume);
+        for (PRUint32 i = 0; i < aCount; ++i) {
+          s_data[i + offset] = short(((PRInt32(buf[i]) - 128) * volume) >> 8);
+        }
+        break;
+      }
+      case FORMAT_S16_LE: {
+        const short* buf = static_cast<const short*>(aBuf);
+        PRInt32 volume = PRInt32((1 << 16) * mVolume);
+        for (PRUint32 i = 0; i < aCount; ++i) {
+          s_data[i + offset] = short((PRInt32(buf[i]) * volume) >> 16);
         }
+        break;
       }
-      break;
-    }
+      case FORMAT_FLOAT32_LE: {
+        const float* buf = static_cast<const float*>(aBuf);
+        for (PRUint32 i = 0; i <  aCount; ++i) {
+          float scaled_value = floorf(0.5 + 32768 * buf[i] * mVolume);
+          if (buf[i] < 0.0) {
+            s_data[i + offset] = (scaled_value < -32768.0) ?
+              -32768 :
+              short(scaled_value);
+          } else {
+            s_data[i+offset] = (scaled_value > 32767.0) ?
+              32767 :
+              short(scaled_value);
+          }
+        }
+        break;
+      }
     }
 
-    if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle), s_data.get(), aCount * sizeof(short)) != SA_SUCCESS) {
+    PRInt32 available = Available();
+    if (available < count) {
+      mBufferOverflow.AppendElements(s_data.get() + available, (count - available));
+      count = available;
+    }
+
+    if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle),
+       s_data.get(), count * sizeof(short)) != SA_SUCCESS) {
       PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_write error"));
       Shutdown();
     }
   }
 }
 
 PRInt32 nsAudioStream::Available()
 {
@@ -192,21 +206,31 @@ void nsAudioStream::SetVolume(float aVol
 {
   NS_ASSERTION(aVolume >= 0.0 && aVolume <= 1.0, "Invalid volume");
   mVolume = aVolume;
 }
 
 void nsAudioStream::Drain()
 {
   if (!mAudioHandle) {
+    // mSamplesBuffered already accounts for the data in the
+    // mBufferOverflow array.
     PRUint32 drainTime = (float(mSamplesBuffered) / mRate / mChannels - GetTime()) * 1000.0;
     PR_Sleep(PR_MillisecondsToInterval(drainTime));
     return;
   }
 
+  // Write any remaining unwritten sound data in the overflow buffer
+  if (!mBufferOverflow.IsEmpty()) {
+    if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle),
+                        mBufferOverflow.Elements(),
+                        mBufferOverflow.Length() * sizeof(short)) != SA_SUCCESS)
+      return;
+  }
+
   if (sa_stream_drain(static_cast<sa_stream_t*>(mAudioHandle)) != SA_SUCCESS) {
         PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsAudioStream: sa_stream_drain error"));
         Shutdown();
   }
 }
 
 void nsAudioStream::Pause()
 {
--- a/content/media/video/src/nsOggDecoder.cpp
+++ b/content/media/video/src/nsOggDecoder.cpp
@@ -136,16 +136,25 @@ public:
       MOZ_COUNT_CTOR(FrameData);
     }
 
     ~FrameData()
     {
       MOZ_COUNT_DTOR(FrameData);
     }
 
+    // Write the audio data from the frame to the Audio stream.
+    void Write(nsAudioStream* aStream)
+    {
+      PRUint32 length = mAudioData.Length();
+      if (length == 0)
+        return;
+
+      aStream->Write(mAudioData.Elements(), length);
+    }
 
     nsAutoArrayPtr<unsigned char> mVideoData;
     nsTArray<float> mAudioData;
     int mVideoWidth;
     int mVideoHeight;
     float mDecodedFrameTime;
     float mTime;
     OggPlayStreamInfo mState;
@@ -255,19 +264,18 @@ public:
   // internally by this method for synchronisation.
   void PlayFrame();
 
   // Play the video data from the given frame. The decode monitor
   // must be locked when calling this method.
   void PlayVideo(FrameData* aFrame);
 
   // Play the audio data from the given frame. The decode monitor must
-  // be locked when calling this method. Returns PR_FALSE if unable to
-  // write to the audio device without blocking.
-  PRBool PlayAudio(FrameData* aFrame);
+  // be locked when calling this method.
+  void PlayAudio(FrameData* aFrame);
 
   // Called from the main thread to get the current frame time. The decoder
   // monitor must be obtained before calling this.
   float GetCurrentTime();
 
   // Called from the main thread to get the duration. The decoder monitor
   // must be obtained before calling this. It is in units of milliseconds.
   PRInt64 GetDuration();
@@ -624,23 +632,23 @@ void nsOggDecodeStateMachine::PlayFrame(
         // FrameData start again from a time position of 0.
         // Reset the play start time.
         mPlayStartTime = PR_IntervalNow();
         mPauseDuration = 0;
       }
 
       double time = (PR_IntervalToMilliseconds(PR_IntervalNow()-mPlayStartTime-mPauseDuration)/1000.0);
       if (time >= frame->mTime) {
-        mDecodedFrames.Pop();
         // Audio for the current frame is played, but video for the next frame
         // is displayed, to account for lag from the time the audio is written
         // to when it is played. This will go away when we move to a/v sync
         // using the audio hardware clock.
+        PlayAudio(frame);
+        mDecodedFrames.Pop();
         PlayVideo(mDecodedFrames.IsEmpty() ? frame : mDecodedFrames.Peek());
-        PlayAudio(frame);
         UpdatePlaybackPosition(frame->mDecodedFrameTime);
         delete frame;
       }
       else {
         // If the queue of decoded frame is full then we wait for the
         // approximate time until the next frame. 
         if (mDecodedFrames.IsFull()) {
           mon.Wait(PR_MillisecondsToInterval(PRInt64((frame->mTime - time)*1000)));
@@ -672,27 +680,23 @@ void nsOggDecodeStateMachine::PlayVideo(
     if (aFrame->mVideoData) {
       nsAutoLock lock(mDecoder->mVideoUpdateLock);
 
       mDecoder->SetRGBData(aFrame->mVideoWidth, aFrame->mVideoHeight, mFramerate, aFrame->mVideoData);
     }
   }
 }
 
-PRBool nsOggDecodeStateMachine::PlayAudio(FrameData* aFrame)
+void nsOggDecodeStateMachine::PlayAudio(FrameData* aFrame)
 {
   //  NS_ASSERTION(PR_InMonitor(mDecoder->GetMonitor()), "PlayAudio() called without acquiring decoder monitor");
-  if (mAudioStream && aFrame && !aFrame->mAudioData.IsEmpty()) {
-    if (PRUint32(mAudioStream->Available()) < aFrame->mAudioData.Length())
-      return PR_FALSE;
+  if (!mAudioStream)
+    return;
 
-    mAudioStream->Write(aFrame->mAudioData.Elements(), aFrame->mAudioData.Length());
-  }
-
-  return PR_TRUE;
+  aFrame->Write(mAudioStream);
 }
 
 void nsOggDecodeStateMachine::OpenAudioStream()
 {
   //  NS_ASSERTION(PR_InMonitor(mDecoder->GetMonitor()), "OpenAudioStream() called without acquiring decoder monitor");
   mAudioStream = new nsAudioStream();
   if (!mAudioStream) {
     LOG(PR_LOG_ERROR, ("Could not create audio stream"));
@@ -1049,16 +1053,24 @@ nsresult nsOggDecodeStateMachine::Run()
             // invalidate's on the main thread can occur.
             mon.Wait(PR_MillisecondsToInterval(PRInt64(mCallbackPeriod*1000)));
           }
         }
 
         if (mState != DECODER_STATE_COMPLETED)
           continue;
 
+        if (mAudioStream) {
+          mon.Exit();
+          mAudioStream->Drain();
+          mon.Enter();
+          if (mState != DECODER_STATE_COMPLETED)
+            continue;
+        }
+
         nsCOMPtr<nsIRunnable> event =
           NS_NEW_RUNNABLE_METHOD(nsOggDecoder, mDecoder, PlaybackEnded);
         NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
         do {
           mon.Wait();
         } while (mState == DECODER_STATE_COMPLETED);
       }
       break;
@@ -1541,27 +1553,27 @@ void nsOggDecoder::UpdateBytesDownloaded
 }
 
 void nsOggDecoder::BufferingStopped()
 {
   if (mShuttingDown)
     return;
 
   if (mElement) {
-    mElement->ChangeReadyState(nsIDOMHTMLMediaElement::CAN_SHOW_CURRENT_FRAME);
+    mElement->ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA);
   }
 }
 
 void nsOggDecoder::BufferingStarted()
 {
   if (mShuttingDown)
     return;
 
   if (mElement) {
-    mElement->ChangeReadyState(nsIDOMHTMLMediaElement::DATA_UNAVAILABLE);
+    mElement->ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
   }
 }
 
 void nsOggDecoder::SeekingStopped()
 {
   if (mShuttingDown)
     return;
 
--- a/content/media/video/src/nsWaveDecoder.cpp
+++ b/content/media/video/src/nsWaveDecoder.cpp
@@ -532,18 +532,19 @@ nsWaveStateMachine::Run()
         // Media stream has ended and there is less data available than a
         // single sample so end playback.
         ChangeState(STATE_ENDED);
       } else {
         // Assuming enough data is available from the network, we aim to
         // completely fill the audio backend's buffers with data.  This
         // allows us plenty of time to wake up and refill the buffers
         // without an underrun occurring.
+        PRUint32 sampleSize = mSampleFormat == nsAudioStream::FORMAT_U8 ? 1 : 2;
         PRUint32 len = RoundDownToSample(NS_MIN(mStream->Available(),
-                                                PRUint32(mAudioStream->Available() * sizeof(short))));
+                                                PRUint32(mAudioStream->Available() * sampleSize)));
         if (len) {
           nsAutoArrayPtr<char> buf(new char[len]);
           PRUint32 got = 0;
 
           monitor.Exit();
           if (NS_FAILED(mStream->Read(buf.get(), len, &got))) {
             NS_WARNING("Stream read failed");
           }
@@ -1310,29 +1311,29 @@ nsWaveDecoder::Observe(nsISupports* aSub
 void
 nsWaveDecoder::BufferingStarted()
 {
   if (mShuttingDown) {
     return;
   }
 
   if (mElement) {
-    mElement->ChangeReadyState(nsIDOMHTMLMediaElement::DATA_UNAVAILABLE);
+    mElement->ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
   }
 }
 
 void
 nsWaveDecoder::BufferingStopped()
 {
   if (mShuttingDown) {
     return;
   }
 
   if (mElement) {
-    mElement->ChangeReadyState(nsIDOMHTMLMediaElement::CAN_SHOW_CURRENT_FRAME);
+    mElement->ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA);
   }
 }
 
 void
 nsWaveDecoder::SeekingStarted()
 {
   if (mShuttingDown) {
     return;
--- a/content/media/video/test/Makefile.in
+++ b/content/media/video/test/Makefile.in
@@ -38,59 +38,92 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = content/media/video/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
-_TEST_FILES = 	test_autoplay.html \
-                test_bug461281.html \
-                test_constants.html \
-                test_controls.html \
-                test_currentTime.html \
-                test_decoder_disable.html \
-                test_duration1.html \
-                test_ended1.html \
-                test_ended2.html \
-                test_networkState.html \
-                test_onloadedmetadata.html \
-                test_paused.html \
-                test_readyState.html \
-                test_seek1.html \
-                test_seek2.html \
-                test_seek3.html \
-                test_seek4.html \
-                test_seek5.html \
-                test_seek6.html \
-                test_seek7.html \
-                test_seek8.html \
-                test_standalone.html \
-                test_timeupdate1.html \
-                test_timeupdate2.html \
-                test_timeupdate3.html \
-                test_volume.html \
-                test_wav_8bit.html \
-                test_wav_ended1.html \
-                test_wav_seek3.html \
-                test_wav_seek4.html \
-                test_wav_seek5.html \
-                test_wav_seek6.html \
-                test_wav_seek7.html \
-                test_wav_seek8.html \
-                test_wav_seek_past_end.html \
-                test_wav_seek_then_play.html \
-                test_wav_trailing.html \
-                test_wav_trunc.html \
-                test_wav_trunc_seek.html \
-                320x240.ogg \
-                bug461281.ogg \
-                seek.ogg \
-                r11025_s16_c1.wav \
-                r11025_s16_c1_trailing.wav \
-                r11025_s16_c1_trunc.wav \
-                r11025_u8_c1.wav \
-#                test_bug448534.html \
-                $(NULL)
+_TEST_FILES = \
+		can_play_type_ogg.js \
+		can_play_type_wave.js \
+		test_autoplay.html \
+		test_can_play_type.html \
+		test_constants.html \
+		test_controls.html \
+		test_currentTime.html \
+		test_networkState.html \
+		test_paused.html \
+		test_readyState.html \
+		test_seek2.html \
+		test_volume.html \
+		$(NULL)
+
+ifdef MOZ_OGG
+_TEST_FILES += \
+		test_bug448534.html \
+		test_bug461281.html \
+		test_can_play_type_ogg.html \
+		test_duration1.html \
+		test_ended1.html \
+		test_ended2.html \
+		test_onloadedmetadata.html \
+		test_seek1.html \
+		test_seek3.html \
+		test_seek4.html \
+		test_seek5.html \
+		test_seek6.html \
+		test_seek7.html \
+		test_seek8.html \
+		test_standalone.html \
+		test_timeupdate1.html \
+		test_timeupdate2.html \
+		test_timeupdate3.html \
+		320x240.ogg \
+		bug461281.ogg \
+		seek.ogg \
+		$(NULL)
+else
+_TEST_FILES += \
+		test_can_play_type_no_ogg.html \
+		$(NULL)
+endif
+
+ifdef MOZ_WAVE
+_TEST_FILES += \
+		test_bug463162.xhtml \
+		test_can_play_type_wave.html \
+		test_wav_8bit.html \
+		test_wav_ended1.html \
+		test_wav_seek3.html \
+		test_wav_seek4.html \
+		test_wav_seek5.html \
+		test_wav_seek6.html \
+		test_wav_seek7.html \
+		test_wav_seek8.html \
+		test_wav_seek_past_end.html \
+		test_wav_seek_then_play.html \
+		test_wav_trailing.html \
+		test_wav_trunc.html \
+		test_wav_trunc_seek.html \
+		r11025_s16_c1.wav \
+		r11025_s16_c1_trailing.wav \
+		r11025_u8_c1.wav \
+		r11025_u8_c1_trunc.wav \
+		$(NULL)
+else
+_TEST_FILES += \
+		test_can_play_type_no_wave.html \
+		$(NULL)
+endif
+
+ifdef MOZ_OGG
+ifdef MOZ_WAVE
+_TEST_FILES += \
+		test_decoder_disable.html \
+		test_media_selection.html \
+		$(NULL)
+endif
+endif
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/can_play_type_ogg.js
@@ -0,0 +1,22 @@
+function check_ogg(v, enabled) {
+  function check(type, expected) {
+    is(v.canPlayType(type), enabled ? expected : "no", type);
+  }
+
+  // Ogg types
+  check("video/ogg", "maybe");
+  check("audio/ogg", "maybe");
+  check("application/ogg", "maybe");
+
+  // Supported Ogg codecs
+  check("audio/ogg; codecs=vorbis", "probably");
+  check("video/ogg; codecs=vorbis", "probably");
+  check("video/ogg; codecs=vorbis,theora", "probably");
+  check("video/ogg; codecs=\"vorbis, theora\"", "probably");
+  check("video/ogg; codecs=theora", "probably");
+
+  // Unsupported Ogg codecs
+  check("video/ogg; codecs=xyz", "no");
+  check("video/ogg; codecs=xyz,vorbis", "no");
+  check("video/ogg; codecs=vorbis,xyz", "no");
+}
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/can_play_type_wave.js
@@ -0,0 +1,30 @@
+function check_wave(v, enabled) {
+  function check(type, expected) {
+    is(v.canPlayType(type), enabled ? expected : "no", type);
+  }
+
+  // Wave types
+  check("audio/wave", "maybe");
+  check("audio/wav", "maybe");
+  check("audio/x-wav", "maybe");
+  check("audio/x-pn-wav", "maybe");
+
+  // Supported Wave codecs
+  check("audio/wave; codecs=1", "probably");
+  // "no codecs" should be supported, I guess
+  check("audio/wave; codecs=", "probably");
+  check("audio/wave; codecs=\"\"", "probably");
+
+  // Maybe-supported Wave codecs
+  check("audio/wave; codecs=0", "maybe");
+  check("audio/wave; codecs=\"0, 1\"", "maybe");
+
+  // Unsupported Wave codecs
+  check("audio/wave; codecs=2", "no");
+  check("audio/wave; codecs=xyz,0", "no");
+  check("audio/wave; codecs=0,xyz", "no");
+  check("audio/wave; codecs=\"xyz, 1\"", "no");
+  // empty codec names
+  check("audio/wave; codecs=,", "no");
+  check("audio/wave; codecs=\"0, 1,\"", "no");
+}
deleted file mode 100644
index 4a8f2c0e4f9dcf51eaf3bdb8f444d3f837efb1b2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4d2db39777ffe79757fa95131e138d1cf7d191b0
GIT binary patch
literal 20000
zc%1FZF%CdL6h+amQ?diSRY;gbtDv4lM5D7Ti!`wZ-8na}d&`{C`9y5PIvv;DH4#yj
k+CIKjQOBO|JeCgt000000000000000000000094a0hbg9^8f$<
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/test_bug463162.xhtml
@@ -0,0 +1,31 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:html="http://www.w3.org/1999/xhtml"
+      xmlns:svg="http://www.w3.org/2000/svg">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=463162
+-->
+<head>
+  <title>Test for Bug 463162</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"/>
+  <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=463162">Mozilla Bug 463162</a>
+<audio id='a1'><sauce type="audio/x-wav" src="r11025_s16_c1.wav"/></audio>
+<audio id='a2'><source type="audio/x-wav" src="r11025_s16_c1.wav"/></audio>
+<audio id='a3'><html:source type="audio/x-wav" src="r11025_s16_c1.wav"/></audio>
+<audio id='a4'><svg:source type="audio/x-wav" src="r11025_s16_c1.wav"/></audio>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+<![CDATA[
+ok($("a1").networkState == HTMLMediaElement.NETWORK_EMPTY, "audio a1 with bogus child should not be loading");
+ok($("a2").networkState >= HTMLMediaElement.NETWORK_LOADING, "audio a2 with valid child should be loading");
+ok($("a3").networkState >= HTMLMediaElement.NETWORK_LOADING, "audio a3 with valid child should be loading");
+ok($("a4").networkState == HTMLMediaElement.NETWORK_EMPTY, "audio a4 with bogus child should not be loading");
+]]>
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/test_can_play_type.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=469247
+-->
+<head>
+  <title>Test for Bug 469247</title>
+  <script type="application/javascript" src="/MochiKit/MochiKit.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=469247">Mozill
+a Bug 469247</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+
+<video id="v"></video>
+
+<pre id="test">
+<script type="application/javascript">
+
+var v = document.getElementById('v');
+
+function check(type, expected) {
+  is(v.canPlayType(type), expected, type);
+}
+
+// Invalid types
+check("foo/bar", "no");
+check("", "no");
+check("!!!", "no");
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/test_can_play_type_no_ogg.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=469247
+-->
+<head>
+  <title>Test for Bug 469247: Ogg backend disabled</title>
+  <script type="application/javascript" src="/MochiKit/MochiKit.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=469247">Mozill
+a Bug 469247</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+
+<video id="v"></video>
+
+<pre id="test">
+<script src="can_play_type_ogg.js"></script>
+
+check_ogg(document.getElementById('v'), false);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/test_can_play_type_no_wave.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=469247
+-->
+<head>
+  <title>Test for Bug 469247: WAVE backend disabled</title>
+  <script type="application/javascript" src="/MochiKit/MochiKit.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=469247">Mozill
+a Bug 469247</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+
+<video id="v"></video>
+
+<pre id="test">
+<script src="can_play_type_wave.js"></script>
+
+check_wave(document.getElementById('v'), false);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/test_can_play_type_ogg.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=469247
+-->
+<head>
+  <title>Test for Bug 469247: Ogg backend</title>
+  <script type="application/javascript" src="/MochiKit/MochiKit.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=469247">Mozill
+a Bug 469247</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+
+<video id="v"></video>
+
+<pre id="test">
+<script src="can_play_type_ogg.js"></script>
+<script>
+check_ogg(document.getElementById('v'), true);
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/test_can_play_type_wave.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=469247
+-->
+<head>
+  <title>Test for Bug 469247: WAVE backend</title>
+  <script type="application/javascript" src="/MochiKit/MochiKit.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=469247">Mozill
+a Bug 469247</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+
+<video id="v"></video>
+
+<pre id="test">
+<script src="can_play_type_wave.js"></script>
+<script>
+check_wave(document.getElementById('v'), true);
+</script>
+</pre>
+</body>
+</html>
--- a/content/media/video/test/test_constants.html
+++ b/content/media/video/test/test_constants.html
@@ -1,146 +1,147 @@
 <!DOCTYPE HTML>
 <html>
 <!--
   Adapted from:
-  http://simon.html5.org/test/html/dom/interfaces/HTMLElement/HTMLMediaElement/const-unsigned-short/001.htm
+  http://simon.html5.org/test/html/dom/interfaces/htmlelement/htmlmediaelement/const-unsigned-short/001.htm
 -->
 <head>
   <title>Media test: constants</title>
   <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <video><source></video><audio><source></audio>
 <pre id="test">
 <script class="testbody" type="text/javascript">
-is(HTMLElement.EMPTY, undefined);
-is(HTMLElement.LOADING, undefined);
-is(HTMLElement.LOADED_METADATA, undefined);
-is(HTMLElement.LOADED_FIRST_FRAME, undefined);
-is(HTMLElement.LOADED, undefined);
-is(HTMLElement.DATA_UNAVAILABLE, undefined);
-is(HTMLElement.CAN_SHOW_CURRENT_FRAME, undefined);
-is(HTMLElement.CAN_PLAY, undefined);
-is(HTMLElement.CAN_PLAY_THROUGH, undefined);
-is(HTMLMediaElement.EMPTY, 0);
-is(HTMLMediaElement.LOADING, 1);
-is(HTMLMediaElement.LOADED_METADATA, 2);
-is(HTMLMediaElement.LOADED_FIRST_FRAME, 3);
-is(HTMLMediaElement.LOADED, 4);
-is(HTMLMediaElement.DATA_UNAVAILABLE, 0);
-is(HTMLMediaElement.CAN_SHOW_CURRENT_FRAME, 1);
-is(HTMLMediaElement.CAN_PLAY, 2);
-is(HTMLMediaElement.CAN_PLAY_THROUGH, 3);
-is(HTMLVideoElement.EMPTY, undefined);
-is(HTMLVideoElement.LOADING, undefined);
-is(HTMLVideoElement.LOADED_METADATA, undefined);
-is(HTMLVideoElement.LOADED_FIRST_FRAME, undefined);
-is(HTMLVideoElement.LOADED, undefined);
-is(HTMLVideoElement.DATA_UNAVAILABLE, undefined);
-is(HTMLVideoElement.CAN_SHOW_CURRENT_FRAME, undefined);
-is(HTMLVideoElement.CAN_PLAY, undefined);
-is(HTMLVideoElement.CAN_PLAY_THROUGH, undefined);
-is(HTMLAudioElement.EMPTY, undefined);
-is(HTMLAudioElement.LOADING, undefined);
-is(HTMLAudioElement.LOADED_METADATA, undefined);
-is(HTMLAudioElement.LOADED_FIRST_FRAME, undefined);
-is(HTMLAudioElement.LOADED, undefined);
-is(HTMLAudioElement.DATA_UNAVAILABLE, undefined);
-is(HTMLAudioElement.CAN_SHOW_CURRENT_FRAME, undefined);
-is(HTMLAudioElement.CAN_PLAY, undefined);
-is(HTMLAudioElement.CAN_PLAY_THROUGH, undefined);
-is(HTMLSourceElement.EMPTY, undefined);
-is(HTMLSourceElement.LOADING, undefined);
-is(HTMLSourceElement.LOADED_METADATA, undefined);
-is(HTMLSourceElement.LOADED_FIRST_FRAME, undefined);
-is(HTMLSourceElement.LOADED, undefined);
-is(HTMLSourceElement.DATA_UNAVAILABLE, undefined);
-is(HTMLSourceElement.CAN_SHOW_CURRENT_FRAME, undefined);
-is(HTMLSourceElement.CAN_PLAY, undefined);
-is(HTMLSourceElement.CAN_PLAY_THROUGH, undefined);
-is(document.body.EMPTY, undefined);
-is(document.body.LOADING, undefined);
-is(document.body.LOADED_METADATA, undefined);
-is(document.body.LOADED_FIRST_FRAME, undefined);
-is(document.body.LOADED, undefined);             
-is(document.body.DATA_UNAVAILABLE, undefined);
-is(document.body.CAN_SHOW_CURRENT_FRAME, undefined);
-is(document.body.CAN_PLAY, undefined);
-is(document.body.CAN_PLAY_THROUGH, undefined);
-is(document.getElementsByTagName("video")[0].EMPTY, 0);
-is(document.getElementsByTagName("video")[0].LOADING, 1);
-is(document.getElementsByTagName("video")[0].LOADED_METADATA, 2);
-is(document.getElementsByTagName("video")[0].LOADED_FIRST_FRAME, 3);
-is(document.getElementsByTagName("video")[0].LOADED, 4);
-is(document.getElementsByTagName("video")[0].DATA_UNAVAILABLE, 0);
-is(document.getElementsByTagName("video")[0].CAN_SHOW_CURRENT_FRAME, 1);
-is(document.getElementsByTagName("video")[0].CAN_PLAY, 2);
-is(document.getElementsByTagName("video")[0].CAN_PLAY_THROUGH, 3);
-is(document.getElementsByTagName("audio")[0].EMPTY, 0);
-is(document.getElementsByTagName("audio")[0].LOADING, 1);
-is(document.getElementsByTagName("audio")[0].LOADED_METADATA, 2);
-is(document.getElementsByTagName("audio")[0].LOADED_FIRST_FRAME, 3);
-is(document.getElementsByTagName("audio")[0].LOADED, 4);
-is(document.getElementsByTagName("audio")[0].DATA_UNAVAILABLE, 0);
-is(document.getElementsByTagName("audio")[0].CAN_SHOW_CURRENT_FRAME, 1);
-is(document.getElementsByTagName("audio")[0].CAN_PLAY, 2);
-is(document.getElementsByTagName("audio")[0].CAN_PLAY_THROUGH, 3);
-is(document.getElementsByTagName("source")[0].EMPTY, undefined);
-is(document.getElementsByTagName("source")[0].LOADING, undefined);
-is(document.getElementsByTagName("source")[0].LOADED_METADATA, undefined);
-is(document.getElementsByTagName("source")[0].LOADED_FIRST_FRAME, undefined);
-is(document.getElementsByTagName("source")[0].LOADED, undefined);
-is(document.getElementsByTagName("source")[0].DATA_UNAVAILABLE, undefined);
-is(document.getElementsByTagName("source")[0].CAN_SHOW_CURRENT_FRAME, undefined);
-is(document.getElementsByTagName("source")[0].CAN_PLAY, undefined);
-is(document.getElementsByTagName("source")[0].CAN_PLAY_THROUGH, undefined);
-is(document.getElementsByTagName("source")[1].EMPTY, undefined);
-is(document.getElementsByTagName("source")[1].LOADING, undefined);
-is(document.getElementsByTagName("source")[1].LOADED_METADATA, undefined);
-is(document.getElementsByTagName("source")[1].LOADED_FIRST_FRAME, undefined);
-is(document.getElementsByTagName("source")[1].LOADED, undefined);
-is(document.getElementsByTagName("source")[1].DATA_UNAVAILABLE, undefined);
-is(document.getElementsByTagName("source")[1].CAN_SHOW_CURRENT_FRAME, undefined);
-is(document.getElementsByTagName("source")[1].CAN_PLAY, undefined);
-is(document.getElementsByTagName("source")[1].CAN_PLAY_THROUGH, undefined);
-is(HTMLElement.prototype.EMPTY, undefined);
-is(HTMLElement.prototype.LOADING, undefined);
-is(HTMLElement.prototype.LOADED_METADATA, undefined);
-is(HTMLElement.prototype.LOADED_FIRST_FRAME, undefined);
-is(HTMLElement.prototype.LOADED, undefined);
-is(HTMLElement.prototype.DATA_UNAVAILABLE, undefined);
-is(HTMLElement.prototype.CAN_SHOW_CURRENT_FRAME, undefined);
-is(HTMLElement.prototype.CAN_PLAY, undefined);
-is(HTMLElement.prototype.CAN_PLAY_THROUGH, undefined);
-is(HTMLVideoElement.prototype.EMPTY, 0);
-is(HTMLVideoElement.prototype.LOADING, 1);
-is(HTMLVideoElement.prototype.LOADED_METADATA, 2);
-is(HTMLVideoElement.prototype.LOADED_FIRST_FRAME, 3);
-is(HTMLVideoElement.prototype.LOADED, 4);
-is(HTMLVideoElement.prototype.DATA_UNAVAILABLE, 0);
-is(HTMLVideoElement.prototype.CAN_SHOW_CURRENT_FRAME, 1);
-is(HTMLVideoElement.prototype.CAN_PLAY, 2);
-is(HTMLVideoElement.prototype.CAN_PLAY_THROUGH, 3);
-is(HTMLAudioElement.prototype.EMPTY, 0);
-is(HTMLAudioElement.prototype.LOADING, 1);
-is(HTMLAudioElement.prototype.LOADED_METADATA, 2);
-is(HTMLAudioElement.prototype.LOADED_FIRST_FRAME, 3);
-is(HTMLAudioElement.prototype.LOADED, 4);
-is(HTMLAudioElement.prototype.DATA_UNAVAILABLE, 0);
-is(HTMLAudioElement.prototype.CAN_SHOW_CURRENT_FRAME, 1);
-is(HTMLAudioElement.prototype.CAN_PLAY, 2);
-is(HTMLAudioElement.prototype.CAN_PLAY_THROUGH, 3);
-is(HTMLSourceElement.prototype.EMPTY, undefined);
-is(HTMLSourceElement.prototype.LOADING, undefined);
-is(HTMLSourceElement.prototype.LOADED_METADATA, undefined);
-is(HTMLSourceElement.prototype.LOADED_FIRST_FRAME, undefined);
-is(HTMLSourceElement.prototype.LOADED, undefined);
-is(HTMLSourceElement.prototype.DATA_UNAVAILABLE, undefined);
-is(HTMLSourceElement.prototype.CAN_SHOW_CURRENT_FRAME, undefined);
-is(HTMLSourceElement.prototype.CAN_PLAY, undefined);
-is(HTMLSourceElement.prototype.CAN_PLAY_THROUGH, undefined);
+is(HTMLElement.NETWORK_EMPTY, undefined);
+is(HTMLElement.NETWORK_IDLE, undefined);
+is(HTMLElement.NETWORK_LOADING, undefined);
+is(HTMLElement.NETWORK_LOADED, undefined);
+is(HTMLElement.HAVE_NOTHING, undefined);
+is(HTMLElement.HAVE_METADATA, undefined);
+is(HTMLElement.HAVE_CURRENT_DATA, undefined);
+is(HTMLElement.HAVE_FUTURE_DATA, undefined);
+is(HTMLElement.HAVE_ENOUGH_DATA, undefined);
+is(HTMLMediaElement.NETWORK_EMPTY, 0);
+is(HTMLMediaElement.NETWORK_IDLE, 1);
+is(HTMLMediaElement.NETWORK_LOADING, 2);
+is(HTMLMediaElement.NETWORK_LOADED, 3);
+is(HTMLMediaElement.HAVE_NOTHING, 0);
+is(HTMLMediaElement.HAVE_METADATA, 1);
+is(HTMLMediaElement.HAVE_CURRENT_DATA, 2);
+is(HTMLMediaElement.HAVE_FUTURE_DATA, 3);
+is(HTMLMediaElement.HAVE_ENOUGH_DATA, 4);
+is(HTMLVideoElement.NETWORK_EMPTY, undefined);
+is(HTMLVideoElement.NETWORK_IDLE, undefined);
+is(HTMLVideoElement.NETWORK_LOADING, undefined);
+is(HTMLVideoElement.NETWORK_LOADED, undefined);
+is(HTMLVideoElement.HAVE_NOTHING, undefined);
+is(HTMLVideoElement.HAVE_METADATA, undefined);
+is(HTMLVideoElement.HAVE_CURRENT_DATA, undefined);
+is(HTMLVideoElement.HAVE_FUTURE_DATA, undefined);
+is(HTMLVideoElement.HAVE_ENOUGH_DATA, undefined);
+is(HTMLAudioElement.NETWORK_EMPTY, undefined);
+is(HTMLAudioElement.NETWORK_IDLE, undefined);
+is(HTMLAudioElement.NETWORK_LOADING, undefined);
+is(HTMLAudioElement.NETWORK_LOADED, undefined);
+is(HTMLAudioElement.HAVE_NOTHING, undefined);
+is(HTMLAudioElement.HAVE_METADATA, undefined);
+is(HTMLAudioElement.HAVE_CURRENT_DATA, undefined);
+is(HTMLAudioElement.HAVE_FUTURE_DATA, undefined);
+is(HTMLAudioElement.HAVE_ENOUGH_DATA, undefined);
+is(HTMLSourceElement.NETWORK_EMPTY, undefined);
+is(HTMLSourceElement.NETWORK_IDLE, undefined);
+is(HTMLSourceElement.NETWORK_LOADING, undefined);
+is(HTMLSourceElement.NETWORK_LOADED, undefined);
+is(HTMLSourceElement.HAVE_NOTHING, undefined);
+is(HTMLSourceElement.HAVE_METADATA, undefined);
+is(HTMLSourceElement.HAVE_CURRENT_DATA, undefined);
+is(HTMLSourceElement.HAVE_FUTURE_DATA, undefined);
+is(HTMLSourceElement.HAVE_ENOUGH_DATA, undefined);
+is(document.body.NETWORK_EMPTY, undefined);
+is(document.body.NETWORK_IDLE, undefined);
+is(document.body.NETWORK_LOADING, undefined);
+is(document.body.NETWORK_LOADED, undefined);
+is(document.body.HAVE_NOTHING, undefined);             
+is(document.body.HAVE_METADATA, undefined);
+is(document.body.HAVE_CURRENT_DATA, undefined);
+is(document.body.HAVE_FUTURE_DATA, undefined);
+is(document.body.HAVE_ENOUGH_DATA, undefined);
+is(document.getElementsByTagName("video")[0].NETWORK_EMPTY, 0);
+is(document.getElementsByTagName("video")[0].NETWORK_IDLE, 1);
+is(document.getElementsByTagName("video")[0].NETWORK_LOADING, 2);
+is(document.getElementsByTagName("video")[0].NETWORK_LOADED, 3);
+is(document.getElementsByTagName("video")[0].HAVE_NOTHING, 0);
+is(document.getElementsByTagName("video")[0].HAVE_METADATA, 1);
+is(document.getElementsByTagName("video")[0].HAVE_CURRENT_DATA, 2);
+is(document.getElementsByTagName("video")[0].HAVE_FUTURE_DATA, 3);
+is(document.getElementsByTagName("video")[0].HAVE_ENOUGH_DATA, 4);
+is(document.getElementsByTagName("audio")[0].NETWORK_EMPTY, 0);
+is(document.getElementsByTagName("audio")[0].NETWORK_IDLE, 1);
+is(document.getElementsByTagName("audio")[0].NETWORK_LOADING, 2);
+is(document.getElementsByTagName("audio")[0].NETWORK_LOADED, 3);
+is(document.getElementsByTagName("audio")[0].HAVE_NOTHING, 0);
+is(document.getElementsByTagName("audio")[0].HAVE_METADATA, 1);
+is(document.getElementsByTagName("audio")[0].HAVE_CURRENT_DATA, 2);
+is(document.getElementsByTagName("audio")[0].HAVE_FUTURE_DATA, 3);
+is(document.getElementsByTagName("audio")[0].HAVE_ENOUGH_DATA, 4);
+is(document.getElementsByTagName("source")[0].NETWORK_EMPTY, undefined);
+is(document.getElementsByTagName("source")[0].NETWORK_IDLE, undefined);
+is(document.getElementsByTagName("source")[0].NETWORK_LOADING, undefined);
+is(document.getElementsByTagName("source")[0].NETWORK_LOADED, undefined);
+is(document.getElementsByTagName("source")[0].HAVE_NOTHING, undefined);
+is(document.getElementsByTagName("source")[0].HAVE_METADATA, undefined);
+is(document.getElementsByTagName("source")[0].HAVE_CURRENT_DATA, undefined);
+is(document.getElementsByTagName("source")[0].HAVE_FUTURE_DATA, undefined);
+is(document.getElementsByTagName("source")[0].HAVE_ENOUGH_DATA, undefined);
+is(HTMLElement.prototype.NETWORK_EMPTY, undefined);
+is(HTMLElement.prototype.NETWORK_IDLE, undefined);
+is(HTMLElement.prototype.NETWORK_LOADING, undefined);
+is(HTMLElement.prototype.NETWORK_LOADED, undefined);
+is(HTMLElement.prototype.HAVE_NOTHING, undefined);
+is(HTMLElement.prototype.HAVE_METADATA, undefined);
+is(HTMLElement.prototype.HAVE_CURRENT_DATA, undefined);
+is(HTMLElement.prototype.HAVE_FUTURE_DATA, undefined);
+is(HTMLElement.prototype.HAVE_ENOUGH_DATA, undefined);
+todo_is(HTMLMediaElement.prototype.NETWORK_EMPTY, 0, "HTMLMediaElement.prototype.NETWORK_EMPTY");
+todo_is(HTMLMediaElement.prototype.NETWORK_IDLE, 1, "HTMLMediaElement.prototype.NETWORK_IDLE");
+todo_is(HTMLMediaElement.prototype.NETWORK_LOADING, 2, "HTMLMediaElement.prototype.NETWORK_LOADING");
+todo_is(HTMLMediaElement.prototype.NETWORK_LOADED, 3, "HTMLMediaElement.prototype.NETWORK_LOADED");
+todo_is(HTMLMediaElement.prototype.HAVE_NOTHING, 0, "HTMLMediaElement.prototype.HAVE_NOTHING");
+todo_is(HTMLMediaElement.prototype.HAVE_METADATA, 1, "HTMLMediaElement.prototype.HAVE_METADATA");
+todo_is(HTMLMediaElement.prototype.HAVE_CURRENT_DATA, 2, "HTMLMediaElement.prototype.HAVE_CURRENT_DATA");
+todo_is(HTMLMediaElement.prototype.HAVE_FUTURE_DATA, 3, "HTMLMediaElement.prototype.HAVE_FUTURE_DATA");
+todo_is(HTMLMediaElement.prototype.HAVE_ENOUGH_DATA, 4, "HTMLMediaElement.prototype.HAVE_ENOUGH_DATA");
+is(HTMLVideoElement.prototype.NETWORK_EMPTY, 0);
+is(HTMLVideoElement.prototype.NETWORK_IDLE, 1);
+is(HTMLVideoElement.prototype.NETWORK_LOADING, 2);
+is(HTMLVideoElement.prototype.NETWORK_LOADED, 3);
+is(HTMLVideoElement.prototype.HAVE_NOTHING, 0);
+is(HTMLVideoElement.prototype.HAVE_METADATA, 1);
+is(HTMLVideoElement.prototype.HAVE_CURRENT_DATA, 2);
+is(HTMLVideoElement.prototype.HAVE_FUTURE_DATA, 3);
+is(HTMLVideoElement.prototype.HAVE_ENOUGH_DATA, 4);
+is(HTMLAudioElement.prototype.NETWORK_EMPTY, 0);
+is(HTMLAudioElement.prototype.NETWORK_IDLE, 1);
+is(HTMLAudioElement.prototype.NETWORK_LOADING, 2);
+is(HTMLAudioElement.prototype.NETWORK_LOADED, 3);
+is(HTMLAudioElement.prototype.HAVE_NOTHING, 0);
+is(HTMLAudioElement.prototype.HAVE_METADATA, 1);
+is(HTMLAudioElement.prototype.HAVE_CURRENT_DATA, 2);
+is(HTMLAudioElement.prototype.HAVE_FUTURE_DATA, 3);
+is(HTMLAudioElement.prototype.HAVE_ENOUGH_DATA, 4);
+is(HTMLSourceElement.prototype.NETWORK_EMPTY, undefined);
+is(HTMLSourceElement.prototype.NETWORK_IDLE, undefined);
+is(HTMLSourceElement.prototype.NETWORK_LOADING, undefined);
+is(HTMLSourceElement.prototype.NETWORK_LOADED, undefined);
+is(HTMLSourceElement.prototype.HAVE_NOTHING, undefined);
+is(HTMLSourceElement.prototype.HAVE_METADATA, undefined);
+is(HTMLSourceElement.prototype.HAVE_CURRENT_DATA, undefined);
+is(HTMLSourceElement.prototype.HAVE_FUTURE_DATA, undefined);
+is(HTMLSourceElement.prototype.HAVE_ENOUGH_DATA, undefined);
+
 </script>
 </pre>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/test_media_selection.html
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Media test: media selection</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+function maketest(expect_load, attach_media, name, type, check_metadata) {
+  return function (testNum) {
+    var e = document.createElement('video');
+
+    if (expect_load) {
+      // this could be loadedmetadata, but needs bug 466410 fixed
+      e.addEventListener('loadeddata', function () {
+          ok(e.readyState >= HTMLMediaElement.HAVE_METADATA,
+             'test ' +  testNum + ' networkState ' + e.networkState + ' expected >= ' + e.LOADED_METADATA);
+          is(e.currentSrc.substring(e.currentSrc.length - name.length), name, 'test ' + testNum);
+          check_metadata(e);
+          e.parentNode.removeChild(e);
+          runNextTest();
+        }, false);
+    }
+
+    attach_media(e, name, type);
+
+    if (expect_load) {
+      ok(e.networkState >= HTMLMediaElement.NETWORK_LOADING,
+         'test ' + testNum + ' networkState ' + e.networkState + ' expected >= ' + e.LOADING);
+    } else {
+      ok(e.networkState == HTMLMediaElement.NETWORK_EMPTY,
+         'test ' + testNum + ' networkState ' + e.networkState + ' expected ' + e.EMPTY);
+      is(e.currentSrc, '', 'test ' + testNum);
+      e.parentNode.removeChild(e);
+      runNextTest();
+    }
+  }
+}
+
+function set_src(element, name, type) {
+  element.src = name;
+  document.body.appendChild(element);
+}
+
+function add_source(element, name, type) {
+  do_add_source(element, name, type);
+  document.body.appendChild(element);
+}
+
+function do_add_source(element, name, type) {
+  var source = document.createElement('source');
+  if (type) {
+    source.type = type;
+  }
+  source.src = name;
+  element.appendChild(source);
+}
+
+function add_sources_last(element, name, type) {
+  do_add_source(element, name, 'unsupported/type');
+  do_add_source(element, name, type);
+  document.body.appendChild(element);
+}
+
+function add_sources_first(element, name, type) {
+  do_add_source(element, name, type);
+  do_add_source(element, name, 'unsupported/type');
+  document.body.appendChild(element);
+}
+
+function late_add_sources_last(element, name, type) {
+  document.body.appendChild(element);
+  do_add_source(element, name, 'unsupported/type');
+  do_add_source(element, name, type);
+}
+
+function late_add_sources_first(element, name, type) {
+  document.body.appendChild(element);
+  do_add_source(element, name, type);
+  do_add_source(element, name, 'unsupported/type');
+}
+
+function check_ogg(e) {
+  ok(e.videoWidth == 320 && e.videoHeight == 240, "video should be 320x240");
+}
+
+function check_wav(e) {
+  ok(e.duration > 0.9 && e.duration < 1.1, "duration should be around 1.0");
+}
+
+var nextTest  = 0;
+var subTests = [
+                maketest(true, set_src, '320x240.ogg', null, check_ogg),
+                maketest(true, add_source, '320x240.ogg', null, check_ogg),
+                maketest(true, add_source, '320x240.ogg', 'application/ogg', check_ogg),
+                maketest(true, add_sources_last, '320x240.ogg', null, check_ogg),
+                maketest(true, add_sources_first, '320x240.ogg', 'application/ogg', check_ogg),
+                maketest(true, set_src, 'r11025_u8_c1.wav', null, check_wav),
+                maketest(true, add_source, 'r11025_u8_c1.wav', null, check_wav),
+                maketest(true, add_source, 'r11025_u8_c1.wav', 'audio/x-wav', check_wav),
+                maketest(true, add_sources_last, 'r11025_u8_c1.wav', null, check_wav),
+                maketest(true, add_sources_first, 'r11025_u8_c1.wav', 'audio/x-wav', check_wav),
+
+                // type hint matches a decoder, actual type matches different decoder
+                maketest(true, add_source, '320x240.ogg', 'audio/x-wav', check_ogg),
+                maketest(true, add_source, 'r11025_u8_c1.wav', 'application/ogg', check_wav),
+
+                // should not start loading, type excludes it from media candiate list
+                maketest(false, add_source, '320x240.ogg', 'bogus/type', null),
+                maketest(false, add_source, 'r11025_u8_c1.wav', 'bogus/type', null),
+                maketest(false, add_source, 'unknown.raw', 'bogus/type', null),
+
+                // should start loading, then fire error, needs bug 462455 fixed
+                // maketest(true, add_source, 'unknown.raw', 'application/ogg', null),
+                // maketest(true, add_source, 'unknown.raw', 'audio/x-wav', null),
+
+                // element doesn't notice source children attached later, needs bug 462455 fixed
+                // maketest(true, late_add_sources_last, '320x240.ogg', null, 0.2, 0.4),
+                // maketest(true, late_add_sources_first, '320x240.ogg', 'application/ogg', 0.2, 0.4),
+                // maketest(true, late_add_sources_last, 'r11025_u8_c1.wav', null, 0.2, 0.4),
+                // maketest(true, late_add_sources_first, 'r11025_u8_c1.wav', 'audio/x-wav', 0.2, 0.4),
+
+                SimpleTest.finish
+                ];
+
+function runNextTest() {
+  setTimeout(function () {
+      dump('subtest ' + nextTest + '\n');
+      subTests[nextTest](nextTest);
+      nextTest += 1;
+    }, 0);
+}
+
+addLoadEvent(runNextTest);
+</script>
+</pre>
+</body>
+</html>
--- a/content/media/video/test/test_onloadedmetadata.html
+++ b/content/media/video/test/test_onloadedmetadata.html
@@ -11,17 +11,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=467972">Mozilla Bug 467972</a>
 
 <video id="v"
        src="320x240.ogg"
        onloadedmetadata="return loadedMetaData();"
        onended="playbackEnded();"
-       onloadedfirstframe="return loadedFirstFrame();"       
+       onloadeddata="return loadedData();"       
        onseeking="seekStarted();"
        onseeked="seekEnded();"       
        controls></video>
 
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
@@ -29,17 +29,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 /** Test for Bug 467972 **/
 
 
 var gEnded = false;
 var gSeekStarted = false;
 var gSeekEnded = false;
-var gLoadedFirstFrameCount = 0;
+var gLoadedDataCount = 0;
 var gLoadedMetaDataCount = 0;
 
 function get(id) {
   return document.getElementById(id);
 }
 
 function video() {
   return get('v');
@@ -49,37 +49,37 @@ function seekStarted() {
   gSeekStarted = true;
 }
 
 function seekEnded() {
   gSeekEnded = true;
   video().play();
 }
 
-function loadedFirstFrame() {
-  gLoadedFirstFrameCount++;
-  ok(gLoadedFirstFrameCount <= 1, "No more than 1 onloadedfirstframe events");
+function loadedData() {
+  gLoadedDataCount++;
+  ok(gLoadedDataCount <= 1, "No more than 1 onloaddata events");
 }
 
 function loadedMetaData() {
   gLoadedMetaDataCount++;
   ok(gLoadedMetaDataCount <= 1, "No more than 1 onloadedmetadata events");
   video().play();
   return false;
 }
 
 function playbackEnded() {
   if (!gEnded) {
     video().currentTime = 0;
     gEnded = true;
   } else {
     ok(gSeekEnded, "Should have received seekended");
     ok(gSeekStarted, "Should have received seekstarted");
-    ok(gLoadedFirstFrameCount == 1, "Should have 1 onloadedfirstframe event");
-    ok(gLoadedMetaDataCount == 1, "Should have 1 onloadedmetadata event");
+    is(gLoadedDataCount, 1, "Should have 1 onloadeddata event");
+    is(gLoadedMetaDataCount, 1, "Should have 1 onloadedmetadata event");
     SimpleTest.finish();    
   }  
   return false;
 }
 
 SimpleTest.waitForExplicitFinish();
 
 </script>
--- a/content/media/video/test/test_seek1.html
+++ b/content/media/video/test/test_seek1.html
@@ -42,28 +42,30 @@ function startTest() {
   return false;
 }
 
 function seekStarted() {
   if (completed)
     return false;
 
   var v = document.getElementById('v');
+  v.pause();
   startPassed = true;
   seekFlagStart = v.seeking;
   return false;
 }
 
 function seekEnded() {
   if (completed)
     return false;
 
   var v = document.getElementById('v');
   var t = v.currentTime;
   ok(t >= 2 && t <= 3, "Video currentTime should be around 2: " + t);
+  v.play();
   endPassed = true;
   seekFlagEnd = v.seeking;
   return false;
 }
 
 function playbackEnded() {
   if (completed)
     return false;
--- a/content/media/video/test/test_seek2.html
+++ b/content/media/video/test/test_seek2.html
@@ -5,24 +5,24 @@
   <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <video id='v'></video>
 <pre id="test">
 <script class="testbody" type="text/javascript">
-// http://www.whatwg.org/specs/web-apps/current-work/#seek
-// If the media element's networkState is less than LOADED_METADATA, 
-// then the user agent must raise an INVALID_STATE_ERR exception 
+// http://www.whatwg.org/specs/web-apps/current-work/#dom-media-seek
+// If the media element's readyState is HAVE_NOTHING, then the user agent
+// must raise an INVALID_STATE_ERR exception.
 var v = document.getElementById('v');
 var passed = false;
 
-ok(v.networkState < HTMLMediaElement.LOADED_METADATA,
-   "Invalid network state in media element");
+ok(v.readyState == HTMLMediaElement.HAVE_NOTHING,
+   "Invalid ready state in media element");
 
 try {
   v.seek(1);
 }
 catch(e) {
   passed = true;
 }
 
--- a/content/media/video/test/test_seek3.html
+++ b/content/media/video/test/test_seek3.html
@@ -38,18 +38,16 @@ function seekStarted() {
   startPassed = true;
   return false;
 }
 
 function seekEnded() {
   if (completed)
     return false;
 
-  var t = document.getElementById('v').currentTime;
-  ok(t >= 2 && t <= 3, "Video currentTime should be around 2: " + t);
   endPassed = true;
   return false;
 }
 
 function playbackEnded() {
   if (completed)
     return false
 
--- a/content/media/video/test/test_seek6.html
+++ b/content/media/video/test/test_seek6.html
@@ -12,16 +12,17 @@
        onloadedmetadata='return startTest();'
        onended='return playbackEnded();'
        onseeking='return seekStarted();'
        onseeked='return seekEnded();'></video>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 // Test for a seek, followed by a play before the seek completes, ensure we play at the end of the seek.
 var startPassed = false;
+var endPassed = false;
 var completed = false;
 var seekCount = 0;
 
 function startTest() {
   if (completed)
     return false;
 
   var v = document.getElementById('v');
@@ -36,25 +37,25 @@ function seekStarted() {
   var v = document.getElementById('v');
   v.play();
   return false;
 }
 
 function seekEnded() {
   if (completed)
     return false;
-  var v = document.getElementById('v');
-  ok(v.currentTime>=2 && v.currentTime<=2.2, "First seek");
+  endPassed = true;
   return false;
 }
 
 function playbackEnded() {
   if (completed)
     return false;
-  ok(true, "Playback ended");
+  ok(startPassed, "Got seeking event");
+  ok(endPassed, "Got seeked event");
   completed = true;
   SimpleTest.finish();
   return false;
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
--- a/content/media/video/test/test_wav_seek3.html
+++ b/content/media/video/test/test_wav_seek3.html
@@ -39,18 +39,16 @@ function seekStarted() {
   startPassed = true;
   return false;
 }
 
 function seekEnded() {
   if (completed)
     return false;
 
-  var t = document.getElementById('v').currentTime;
-  ok(t >= 0.4 && t <= 0.6, "Video currentTime should be around 0.5: " + t);
   endPassed = true;
   return false;
 }
 
 function playbackEnded() {
   if (completed)
     return false
 
--- a/content/media/video/test/test_wav_seek6.html
+++ b/content/media/video/test/test_wav_seek6.html
@@ -13,16 +13,17 @@
        onseeking='return seekStarted();'
        onseeked='return seekEnded();'>
   <source type='audio/x-wav' src='r11025_s16_c1.wav'>
 </audio>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 // Test for a seek, followed by a play before the seek completes, ensure we play at the end of the seek.
 var startPassed = false;
+var endPassed = false;
 var completed = false;
 var seekCount = 0;
 
 function startTest() {
   if (completed)
     return false;
 
   var v = document.getElementById('v');
@@ -37,25 +38,25 @@ function seekStarted() {
   var v = document.getElementById('v');
   v.play();
   return false;
 }
 
 function seekEnded() {
   if (completed)
     return false;
-  var v = document.getElementById('v');
-  ok(v.currentTime>=0.4 && v.currentTime<=0.6, "First seek");
+  endPassed = true;
   return false;
 }
 
 function playbackEnded() {
   if (completed)
     return false;
-  ok(true, "Playback ended");
+  ok(startPassed, "Got seeking event");
+  ok(endPassed, "Got seeked event");
   completed = true;
   SimpleTest.finish();
   return false;
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
--- a/content/media/video/test/test_wav_trunc.html
+++ b/content/media/video/test/test_wav_trunc.html
@@ -5,41 +5,41 @@
   <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <audio id='v'
        onloadedmetadata='return startTest();'
        onended='return playbackEnded();'>
-  <source type='audio/x-wav' src='r11025_s16_c1_trunc.wav'>
+  <source type='audio/x-wav' src='r11025_u8_c1_trunc.wav'>
 </audio>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 // Test if the ended event works correctly.
 var v = document.getElementById('v');
 var endPassed = false;
 var completed = false;
 
 function startTest() {
   if (completed)
     return false;
 
-  ok(v.duration > 0.3 && v.duration < 0.5, "Duration should be around 0.4: " + v.duration);
+  ok(v.duration > 1.7 && v.duration < 1.9, "Duration should be around 1.8: " + v.duration);
 
   v.play();
   return false;
 }
 
 function playbackEnded() {
   if (completed)
     return false
 
   completed = true;
-  ok(v.currentTime >= 0.3 && v.currentTime <= 0.5,
+  ok(v.currentTime >= 1.7 && v.currentTime <= 1.9,
      "Checking currentTime at end: " + v.currentTime);
   ok(v.ended, "Checking playback has ended");
   SimpleTest.finish();
   return false;
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
--- a/content/media/video/test/test_wav_trunc_seek.html
+++ b/content/media/video/test/test_wav_trunc_seek.html
@@ -6,47 +6,47 @@
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <audio id='v'
        onloadedmetadata='return startTest();'
        onseeked='return endSeek();'
        onended='return endTest();'>
-  <source type='audio/x-wav' src='r11025_s16_c1_trunc.wav'>
+  <source type='audio/x-wav' src='r11025_u8_c1_trunc.wav'>
 </audio>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 // Test if the ended event works correctly.
 var v = document.getElementById('v');
 var endPassed = false;
 var completed = false;
 
 function startTest() {
   if (completed)
     return false;
 
-  ok(v.duration > 0.3 && v.duration < 0.5, "Duration should be around 0.4: " + v.duration);
+  ok(v.duration > 1.7 && v.duration < 1.9, "Duration should be around 1.8: " + v.duration);
 
-  v.currentTime = 1.0;
+  v.currentTime = 3.0;
   return false;
 }
 
 function endTest() {
   ok(v.ended, "Checking ended set after seeking to EOF and playing");
   SimpleTest.finish();
   return false;
 }
 
 function endSeek() {
   if (completed)
     return false
 
   completed = true;
-  ok(v.currentTime >= 0.3 && v.currentTime <= 0.5,
+  ok(v.currentTime >= 1.7 && v.currentTime <= 1.9,
      "Checking currentTime at end: " + v.currentTime);
   v.play();
   return false;
 }
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
--- a/content/xbl/src/nsXBLProtoImplField.cpp
+++ b/content/xbl/src/nsXBLProtoImplField.cpp
@@ -66,17 +66,17 @@ nsXBLProtoImplField::nsXBLProtoImplField
 }
 
 nsXBLProtoImplField::~nsXBLProtoImplField()
 {
   MOZ_COUNT_DTOR(nsXBLProtoImplField);
   if (mFieldText)
     nsMemory::Free(mFieldText);
   NS_Free(mName);
-  delete mNext;
+  NS_CONTENT_DELETE_LIST_MEMBER(nsXBLProtoImplField, this, mNext);
 }
 
 void 
 nsXBLProtoImplField::AppendFieldText(const nsAString& aText)
 {
   if (mFieldText) {
     nsDependentString fieldTextStr(mFieldText, mFieldTextLength);
     nsAutoString newFieldText = fieldTextStr + aText;
--- a/content/xbl/src/nsXBLProtoImplMember.h
+++ b/content/xbl/src/nsXBLProtoImplMember.h
@@ -42,16 +42,17 @@
 #include "nsIAtom.h"
 #include "nsString.h"
 #include "jsapi.h"
 #include "nsIContent.h"
 #include "nsString.h"
 #include "nsIJSRuntimeService.h"
 #include "nsIServiceManager.h"
 #include "nsReadableUtils.h"
+#include "nsContentUtils.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsIScriptContext;
 struct JSRuntime;
 class nsIJSRuntimeService;
 
 struct nsXBLTextWithLineNumber
 {
@@ -94,17 +95,20 @@ struct nsXBLTextWithLineNumber
     return mLineNumber;
   }
 };
 
 class nsXBLProtoImplMember
 {
 public:
   nsXBLProtoImplMember(const PRUnichar* aName) :mNext(nsnull) { mName = ToNewUnicode(nsDependentString(aName)); }
-  virtual ~nsXBLProtoImplMember() { nsMemory::Free(mName); delete mNext; }
+  virtual ~nsXBLProtoImplMember() {
+    nsMemory::Free(mName);
+    NS_CONTENT_DELETE_LIST_MEMBER(nsXBLProtoImplMember, this, mNext);
+  }
 
   nsXBLProtoImplMember* GetNext() { return mNext; }
   void SetNext(nsXBLProtoImplMember* aNext) { mNext = aNext; }
 
   virtual nsresult InstallMember(nsIScriptContext* aContext,
                                  nsIContent* aBoundElement, 
                                  void* aScriptObject,
                                  void* aTargetClassObject,
--- a/content/xbl/src/nsXBLProtoImplMethod.h
+++ b/content/xbl/src/nsXBLProtoImplMethod.h
@@ -54,17 +54,17 @@ struct nsXBLParameter {
     MOZ_COUNT_CTOR(nsXBLParameter);
     mName = ToNewCString(aName);
     mNext = nsnull;
   }
 
   ~nsXBLParameter() {
     MOZ_COUNT_DTOR(nsXBLParameter);
     nsMemory::Free(mName);
-    delete mNext;
+    NS_CONTENT_DELETE_LIST_MEMBER(nsXBLParameter, this, mNext);
   }
 };
 
 struct nsXBLUncompiledMethod {
   nsXBLParameter* mParameters;
   nsXBLParameter* mLastParameter;
   nsXBLTextWithLineNumber mBodyText;
 
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -118,17 +118,19 @@ protected:
   nsXBLAttributeEntry(nsIAtom* aSrcAtom, nsIAtom* aDstAtom, PRInt32 aDstNameSpace,
                       nsIContent* aContent)
     : mElement(aContent),
       mSrcAttribute(aSrcAtom),
       mDstAttribute(aDstAtom),
       mDstNameSpace(aDstNameSpace),
       mNext(nsnull) { }
 
-  ~nsXBLAttributeEntry() { delete mNext; }
+  ~nsXBLAttributeEntry() {
+    NS_CONTENT_DELETE_LIST_MEMBER(nsXBLAttributeEntry, this, mNext);
+  }
 
 private:
   // Hide so that only Create() and Destroy() can be used to
   // allocate and deallocate from the heap
   static void* operator new(size_t) CPP_THROW_NEW { return 0; }
   static void operator delete(void*, size_t) {}
 };
 
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -62,17 +62,16 @@
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMEventListener.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsIDOMNSEvent.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsIDOMWindowInternal.h"
 #include "nsIServiceManager.h"
-#include "nsContentUtils.h"
 #include "nsIScriptError.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
 #include "nsGkAtoms.h"
 #include "nsGUIEvent.h"
 #include "nsIXPConnect.h"
 #include "nsIDOMScriptObjectFactory.h"
 #include "nsDOMCID.h"
@@ -151,17 +150,17 @@ nsXBLPrototypeHandler::~nsXBLPrototypeHa
   --gRefCnt;
   if (mType & NS_HANDLER_TYPE_XUL) {
     NS_IF_RELEASE(mHandlerElement);
   } else if (mHandlerText) {
     nsMemory::Free(mHandlerText);
   }
 
   // We own the next handler in the chain, so delete it now.
-  delete mNextHandler;
+  NS_CONTENT_DELETE_LIST_MEMBER(nsXBLPrototypeHandler, this, mNextHandler);
 }
 
 already_AddRefed<nsIContent>
 nsXBLPrototypeHandler::GetHandlerElement()
 {
   if (mType & NS_HANDLER_TYPE_XUL) {
     nsCOMPtr<nsIContent> element = do_QueryReferent(mHandlerElement);
     nsIContent* el = nsnull;
--- a/content/xbl/src/nsXBLResourceLoader.h
+++ b/content/xbl/src/nsXBLResourceLoader.h
@@ -34,16 +34,17 @@
  * 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 ***** */
 
 #include "nsCOMPtr.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsCOMArray.h"
+#include "nsContentUtils.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsIContent;
 class nsIAtom;
 class nsIDocument;
 class nsIScriptContext;
 class nsSupportsHashtable;
 class nsXBLPrototypeResources;
@@ -61,17 +62,17 @@ struct nsXBLResource {
     MOZ_COUNT_CTOR(nsXBLResource);
     mNext = nsnull;
     mType = aType;
     mSrc = aSrc;
   }
 
   ~nsXBLResource() { 
     MOZ_COUNT_DTOR(nsXBLResource);  
-    delete mNext; 
+    NS_CONTENT_DELETE_LIST_MEMBER(nsXBLResource, this, mNext);
   }
 };
 
 class nsXBLResourceLoader : public nsICSSLoaderObserver
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsXBLResourceLoader)
--- a/content/xul/document/src/nsXULContentSink.cpp
+++ b/content/xul/document/src/nsXULContentSink.cpp
@@ -69,17 +69,16 @@
 #include "nsIURL.h"
 #include "nsIViewManager.h"
 #include "nsIXULDocument.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsLayoutCID.h"
 #include "nsNetUtil.h"
 #include "nsRDFCID.h"
 #include "nsParserUtils.h"
-#include "nsIMIMEHeaderParam.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
 #include "nsXULElement.h"
 #include "prlog.h"
 #include "prmem.h"
 #include "jscntxt.h"  // for JSVERSION_HAS_XML
 #include "nsCRT.h"
 
@@ -978,26 +977,20 @@ XULContentSinkImpl::OpenScript(const PRU
   // Look for SRC attribute and look for a LANGUAGE attribute
   nsAutoString src;
   while (*aAttributes) {
       const nsDependentString key(aAttributes[0]);
       if (key.EqualsLiteral("src")) {
           src.Assign(aAttributes[1]);
       }
       else if (key.EqualsLiteral("type")) {
-          nsCOMPtr<nsIMIMEHeaderParam> mimeHdrParser =
-              do_GetService("@mozilla.org/network/mime-hdrparam;1");
-          NS_ENSURE_TRUE(mimeHdrParser, NS_ERROR_FAILURE);
-
-          NS_ConvertUTF16toUTF8 typeAndParams(aAttributes[1]);
-
+          nsDependentString str(aAttributes[1]);
+          nsContentTypeParser parser(str);
           nsAutoString mimeType;
-          rv = mimeHdrParser->GetParameter(typeAndParams, nsnull,
-                                           EmptyCString(), PR_FALSE, nsnull,
-                                           mimeType);
+          rv = parser.GetType(mimeType);
           if (NS_FAILED(rv)) {
               if (rv == NS_ERROR_INVALID_ARG) {
                   // Might as well bail out now instead of setting langID to
                   // nsIProgrammingLanguage::UNKNOWN and bailing out later.
                   return NS_OK;
               }
               // We do want the warning here
               NS_ENSURE_SUCCESS(rv, rv);
@@ -1038,19 +1031,17 @@ XULContentSinkImpl::OpenScript(const PRU
                   langID = nsIProgrammingLanguage::UNKNOWN;
               } else
                   langID = runtime->GetScriptTypeID();
           }
 
           if (langID != nsIProgrammingLanguage::UNKNOWN) {
             // Get the version string, and ensure the language supports it.
             nsAutoString versionName;
-            rv = mimeHdrParser->GetParameter(typeAndParams, "version",
-                                             EmptyCString(), PR_FALSE, nsnull,
-                                             versionName);
+            rv = parser.GetParameter("version", versionName);
             if (NS_FAILED(rv)) {
               if (rv != NS_ERROR_INVALID_ARG)
                 return rv;
               // no version specified - version remains the default.
             } else {
               nsCOMPtr<nsIScriptRuntime> runtime;
               rv = NS_GetScriptRuntimeByID(langID, getter_AddRefs(runtime));
               if (NS_FAILED(rv))
@@ -1066,19 +1057,17 @@ XULContentSinkImpl::OpenScript(const PRU
           if (langID == nsIProgrammingLanguage::JAVASCRIPT) {
               // By default scripts in XUL documents have E4X turned on. We use
               // our implementation knowledge to reuse JSVERSION_HAS_XML as a
               // safe version flag. This is still OK if version is
               // JSVERSION_UNKNOWN (-1),
               version |= JSVERSION_HAS_XML;
 
               nsAutoString value;
-              rv = mimeHdrParser->GetParameter(typeAndParams, "e4x",
-                                               EmptyCString(), PR_FALSE, nsnull,
-                                               value);
+              rv = parser.GetParameter("e4x", value);
               if (NS_FAILED(rv)) {
                   if (rv != NS_ERROR_INVALID_ARG)
                       return rv;
               } else {
                   if (value.Length() == 1 && value[0] == '0')
                     version &= ~JSVERSION_HAS_XML;
               }
           }
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -2001,18 +2001,16 @@ nsXULDocument::StartLayout(void)
         if (! container)
             return NS_ERROR_UNEXPECTED;
 
         nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
         NS_ASSERTION(docShell != nsnull, "container is not a docshell");
         if (! docShell)
             return NS_ERROR_UNEXPECTED;
 
-        nsRect r = cx->GetVisibleArea();
-
         // Trigger a refresh before the call to InitialReflow(),
         // because the view manager's UpdateView() function is
         // dropping dirty rects if refresh is disabled rather than
         // accumulating them until refresh is enabled and then
         // triggering a repaint...
         // XXXbz Is that still the case?
         nsresult rv = NS_OK;
         nsIViewManager* vm = shell->GetViewManager();
@@ -2024,17 +2022,21 @@ nsXULDocument::StartLayout(void)
                 contentViewer->GetEnableRendering(&enabled);
                 if (enabled) {
                     vm->EnableRefresh(NS_VMREFRESH_IMMEDIATE);
                 }
             }
         }
 
         mMayStartLayout = PR_TRUE;
-        
+
+        // Don't try to call GetVisibleArea earlier than this --- the EnableRefresh call
+        // above can flush reflows, which can cause a parent document to be flushed,
+        // calling ResizeReflow on our document which does SetVisibleArea.
+        nsRect r = cx->GetVisibleArea();
         // Make sure we're holding a strong ref to |shell| before we call
         // InitialReflow()
         nsCOMPtr<nsIPresShell> shellGrip = shell;
         rv = shell->InitialReflow(r.width, r.height);
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     return NS_OK;
--- a/dom/public/idl/html/nsIDOMHTMLMediaElement.idl
+++ b/dom/public/idl/html/nsIDOMHTMLMediaElement.idl
@@ -51,38 +51,39 @@
 
 // undef the GetCurrentTime macro defined in WinBase.h from the MS Platform SDK
 %{C++
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 %}
 
-[scriptable, uuid(e3e2a8c1-4b56-4154-8ef2-fc4b2bb42e97)]
+[scriptable, uuid(c19f04dc-f09a-4b1f-b354-af65a12aa8bc)]
 interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
 {
   // error state
   readonly attribute nsIDOMHTMLMediaError error;
 
   // network state
            attribute DOMString src;
   readonly attribute DOMString currentSrc;
-  const unsigned short EMPTY = 0;
-  const unsigned short LOADING = 1;
-  const unsigned short LOADED_METADATA = 2;
-  const unsigned short LOADED_FIRST_FRAME = 3;
-  const unsigned short LOADED = 4;
+  const unsigned short NETWORK_EMPTY = 0;
+  const unsigned short NETWORK_IDLE = 1;
+  const unsigned short NETWORK_LOADING = 2;
+  const unsigned short NETWORK_LOADED = 3;
   readonly attribute unsigned short networkState;
   void load();
+  DOMString canPlayType(in DOMString type);
 
   // ready state
-  const unsigned short DATA_UNAVAILABLE = 0;
-  const unsigned short CAN_SHOW_CURRENT_FRAME = 1;
-  const unsigned short CAN_PLAY = 2;
-  const unsigned short CAN_PLAY_THROUGH = 3;
+  const unsigned short HAVE_NOTHING = 0;
+  const unsigned short HAVE_METADATA = 1;
+  const unsigned short HAVE_CURRENT_DATA = 2;
+  const unsigned short HAVE_FUTURE_DATA = 3;
+  const unsigned short HAVE_ENOUGH_DATA = 4;
   readonly attribute unsigned short readyState;
   readonly attribute boolean seeking;
 
   // playback state
            attribute float currentTime;
   readonly attribute float duration;
   readonly attribute boolean paused;
   readonly attribute boolean ended;
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -1630,42 +1630,31 @@ nsDOMClassInfo::DefineStaticJSVals(JSCon
 #endif
 
   return NS_OK;
 }
 
 // static
 nsresult
 nsDOMClassInfo::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
-                           const nsIID& aIID, jsval *vp,
+                           const nsIID* aIID, jsval *vp,
                            nsIXPConnectJSObjectHolder **aHolder)
 {
-  *aHolder = nsnull;
-  
   if (!native) {
+    NS_ASSERTION(!aHolder || !*aHolder, "*aHolder should be null!");
+
     *vp = JSVAL_NULL;
 
     return NS_OK;
   }
 
   NS_ENSURE_TRUE(sXPConnect, NS_ERROR_UNEXPECTED);
 
-  nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-  nsresult rv = sXPConnect->WrapNative(cx, ::JS_GetGlobalForObject(cx, scope),
-                                       native, aIID, getter_AddRefs(holder));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  JSObject* obj = nsnull;
-  rv = holder->GetJSObject(&obj);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *vp = OBJECT_TO_JSVAL(obj);
-  holder.swap(*aHolder);
-
-  return rv;
+  return sXPConnect->WrapNativeToJSVal(cx, ::JS_GetGlobalForObject(cx, scope),
+                                       native, aIID, vp, aHolder);
 }
 
 // static
 nsresult
 nsDOMClassInfo::ThrowJSException(JSContext *cx, nsresult aResult)
 {
   JSAutoRequest ar(cx);
 
@@ -1686,17 +1675,17 @@ nsDOMClassInfo::ThrowJSException(JSConte
     rv = xm->GetExceptionFromProvider(aResult, 0, getter_AddRefs(exception));
     if (NS_FAILED(rv) || !exception) {
       break;
     }
 
     jsval jv;
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = WrapNative(cx, ::JS_GetGlobalObject(cx), exception,
-                    NS_GET_IID(nsIException), &jv, getter_AddRefs(holder));
+                    &NS_GET_IID(nsIException), &jv, getter_AddRefs(holder));
     if (NS_FAILED(rv) || JSVAL_IS_NULL(jv)) {
       break;
     }
     JS_SetPendingException(cx, jv);
 
     return NS_OK;
   } while (0);
 
@@ -4490,18 +4479,17 @@ nsWindowSH::GlobalScopePolluterNewResolv
 
   if (!result) {
     doc->ResolveName(str, nsnull, getter_AddRefs(result));
   }
 
   if (result) {
     jsval v;
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-    nsresult rv = WrapNative(cx, obj, result, NS_GET_IID(nsISupports), &v,
-                             getter_AddRefs(holder));
+    nsresult rv = WrapNative(cx, obj, result, &v, getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, JS_FALSE);
 
     if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(jsstr),
                                ::JS_GetStringLength(jsstr), v, nsnull, nsnull,
                                0)) {
       nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_UNEXPECTED);
 
       return JS_FALSE;
@@ -4685,17 +4673,17 @@ nsWindowSH::GetProperty(nsIXPConnectWrap
       // A numeric property accessed and the numeric property is a
       // child frame, wrap the child frame without doing a security
       // check and return.
 
       nsGlobalWindow *frameWin = (nsGlobalWindow *)frame.get();
 
       nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
       rv = WrapNative(cx, frameWin->GetGlobalJSObject(), frame,
-                      NS_GET_IID(nsIDOMWindow), vp,
+                      &NS_GET_IID(nsIDOMWindow), vp,
                       getter_AddRefs(holder));
     }
 
     return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
   }
 
   if (JSVAL_IS_STRING(id) && !JSVAL_IS_PRIMITIVE(*vp) &&
       ::JS_TypeOfValue(cx, *vp) != JSTYPE_FUNCTION) {
@@ -4802,17 +4790,17 @@ nsWindowSH::SetProperty(nsIXPConnectWrap
     nsCOMPtr<nsIDOMWindowInternal> window(do_QueryWrappedNative(wrapper));
     NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
 
     nsCOMPtr<nsIDOMLocation> location;
     nsresult rv = window->GetLocation(getter_AddRefs(location));
     NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && location, rv);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-    rv = WrapNative(cx, obj, location, NS_GET_IID(nsIDOMLocation), vp,
+    rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), vp,
                     getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = location->SetHref(nsDependentJSString(val));
 
     return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING;
   }
 
@@ -5057,18 +5045,18 @@ BaseStubConstructor(nsIWeakReference* aW
     if (NS_SUCCEEDED(rv)) {
       *rval = OBJECT_TO_JSVAL(new_obj);
     }
 
     return rv;
   }
 
   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-  rv = nsDOMGenericSH::WrapNative(cx, obj, native, NS_GET_IID(nsISupports),
-                                  rval, getter_AddRefs(holder));
+  rv = nsDOMGenericSH::WrapNative(cx, obj, native, rval,
+                                  getter_AddRefs(holder));
 
   return rv;
 }
 
 static nsresult
 DefineInterfaceConstants(JSContext *cx, JSObject *obj, const nsIID *aIID)
 {
   nsCOMPtr<nsIInterfaceInfoManager>
@@ -5524,17 +5512,17 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
     NS_ENSURE_SUCCESS(rv, rv);
 
     PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty;
     sDoSecurityCheckInAddProperty = PR_FALSE;
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     jsval v;
 
-    rv = WrapNative(cx, obj, constructor, NS_GET_IID(nsIDOMDOMConstructor), &v,
+    rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor), &v,
                     getter_AddRefs(holder));
 
     sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty;
 
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = constructor->Install(cx, obj, v);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -5586,17 +5574,17 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
     NS_ENSURE_SUCCESS(rv, rv);
 
     PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty;
     sDoSecurityCheckInAddProperty = PR_FALSE;
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     jsval v;
 
-    rv = WrapNative(cx, obj, constructor, NS_GET_IID(nsIDOMDOMConstructor), &v,
+    rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor), &v,
                     getter_AddRefs(holder));
 
     sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty;
 
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = constructor->Install(cx, obj, v);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -5801,17 +5789,17 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
     nsRefPtr<nsDOMConstructor> constructor;
     rv = nsDOMConstructor::Create(class_name, name_struct,
                                   static_cast<nsPIDOMWindow*>(aWin),
                                   getter_AddRefs(constructor));
     NS_ENSURE_SUCCESS(rv, rv);
 
     jsval val;
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-    rv = WrapNative(cx, obj, constructor, NS_GET_IID(nsIDOMDOMConstructor),
+    rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor),
                     &val, getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = constructor->Install(cx, obj, val);
     NS_ENSURE_SUCCESS(rv, rv);
 
     JSObject* class_obj;
     holder->GetJSObject(&class_obj);
@@ -5849,18 +5837,17 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
         nsGlobalWindow *inner = aWin->GetCurrentInnerWindowInternal();
         NS_ENSURE_TRUE(inner, NS_ERROR_UNEXPECTED);
 
         scope = inner->GetGlobalJSObject();
       } else {
         scope = aWin->GetGlobalJSObject();
       }
 
-      rv = WrapNative(cx, scope, native, NS_GET_IID(nsISupports), &prop_val,
-                      getter_AddRefs(holder));
+      rv = WrapNative(cx, scope, native, &prop_val, getter_AddRefs(holder));
     }
 
     NS_ENSURE_SUCCESS(rv, rv);
 
     PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty;
     sDoSecurityCheckInAddProperty = PR_FALSE;
 
     JSBool ok = ::JS_DefineUCProperty(cx, obj