Merge old head via |hg debugsetparents d0327300cfe7e64e91c166912bac763d365218db d863896fcb56221128756286f22e41f9c698d598|. CLOSED TREE DONTBUILD a=release
authorffxbld <release@mozilla.com>
Thu, 11 Jan 2018 18:52:29 +0000
changeset 453014 5d6ef3517da32b07c7df4bf5c2b9312c0d83f9ea
parent 453013 d0327300cfe7e64e91c166912bac763d365218db (diff)
parent 445640 d863896fcb56221128756286f22e41f9c698d598 (current diff)
child 453015 4ccf9c43bc15e3636173a46849b646d062005d03
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrelease
milestone59.0a1
Merge old head via |hg debugsetparents d0327300cfe7e64e91c166912bac763d365218db d863896fcb56221128756286f22e41f9c698d598|. CLOSED TREE DONTBUILD a=release
new file mode 100644
--- /dev/null
+++ b/.arcconfig
@@ -0,0 +1,4 @@
+{
+  "phabricator.uri" : "https://phabricator.services.mozilla.com/",
+  "repository.callsign": "MOZILLACENTRAL"
+}
--- a/.cargo/config.in
+++ b/.cargo/config.in
@@ -1,6 +1,18 @@
+# Note: if you add more configure substitutions here with required values
+# you will also need to fix the sed commands in:
+# taskcluster/scripts/builder/build-sm-mozjs-crate.sh
+# taskcluster/scripts/builder/build-sm-rust-bindings.sh
+
 [source.crates-io]
 registry = 'https://github.com/rust-lang/crates.io-index'
 replace-with = 'vendored-sources'
 
+[source."https://github.com/gankro/serde"]
+git = "https://github.com/gankro/serde"
+branch = "deserialize_from_enums4"
+replace-with = "vendored-sources"
+
 [source.vendored-sources]
 directory = '@top_srcdir@/third_party/rust'
+
+@WIN64_CARGO_LINKER_CONFIG@
deleted file mode 100644
--- a/.clang-tidy
+++ /dev/null
@@ -1,16 +0,0 @@
-# Checks run by clang-tidy over Mozilla code.
-
-# The following checks are currently enabled:
-# * modernize-raw-string-literal -
-#     Replace string literals containing escaped characters with raw string literals
-# * modernize-use-bool-literals
-#     Replace integer literals which are cast to bool
-# * modernize-loop-convert
-#     Converts for(...; ...; ...) loops to use the new range-based loops in C++11
-# * modernize-use-default
-#     Replace default bodies of special member functions with = default;
-# * modernize-use-override
-#     Use C++11's override and remove virtual where applicable
-
-Checks:          '-*, modernize-raw-string-literal, modernize-use-bool-literals, modernize-loop-convert, modernize-use-default, modernize-use-override'
-
--- a/.cron.yml
+++ b/.cron.yml
@@ -93,16 +93,28 @@ jobs:
           target-tasks-method: nightly_dmd
       run-on-projects:
           - mozilla-central
       when:
           by-project:
               mozilla-central: [{hour: 10, minute: 0}]
               # No default
 
+    - name: searchfox-index
+      job:
+          type: decision-task
+          treeherder-symbol: Searchfox
+          target-tasks-method: searchfox_index
+      run-on-projects:
+          - mozilla-central
+      when:
+          by-project:
+              mozilla-central: [{hour: 10, minute: 30}]
+              # No default
+
     - name: periodic-update
       job:
           type: decision-task
           treeherder-symbol: Nfile
           target-tasks-method: file_update
       run-on-projects:
           - mozilla-central
       when:
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,39 +1,55 @@
 # Always ignore node_modules.
 **/node_modules/**/*.*
 
 # Always ignore crashtests - specially crafted files that originally caused a
 # crash.
 **/crashtests/**
+# Also ignore reftest - specially crafted to produce expected output.
+**/reftest/**
 
 # Exclude expected objdirs.
 obj*/**
 
 # We ignore all these directories by default, until we get them enabled.
 # If you are enabling a directory, please add directory specific exclusions
 # below.
 docshell/**
 editor/**
 extensions/cookie/**
 extensions/spellcheck/**
 extensions/universalchardet/**
-gfx/**
+gfx/layers/**
+gfx/tests/browser/**
+gfx/tests/chrome/**
+gfx/tests/mochitest/**
+gfx/tests/unit/**
 image/**
 intl/**
 layout/**
-media/**
-memory/**
+memory/replace/dmd/test/**
 modules/**
-netwerk/**
+netwerk/base/NetUtil.jsm
+netwerk/cookie/test/browser/**
+netwerk/cookie/test/unit/**
+netwerk/protocol/**
+netwerk/dns/**
+netwerk/test/browser/**
+netwerk/test/httpserver/**
+netwerk/test/mochitests/**
+netwerk/test/unit*/**
+netwerk/wifi/**
 parser/**
 rdf/**
 tools/update-packaging/**
-uriloader/**
-widget/**
+uriloader/exthandler/**
+uriloader/exthandler/tests/mochitest/**
+widget/headless/tests/**
+widget/tests/**
 
 # We currently have no js files in these directories, so we ignore them by
 # default to aid ESLint's performance.
 build/**
 config/**
 db/**
 embedding/**
 gradle/**
@@ -69,16 +85,17 @@ browser/extensions/followonsearch/**
 browser/extensions/screenshots/**
 browser/extensions/pdfjs/content/build**
 browser/extensions/pdfjs/content/web**
 # generated or library files in pocket
 browser/extensions/pocket/content/panels/js/tmpl.js
 browser/extensions/pocket/content/panels/js/vendor/**
 # generated or library files in activity-stream
 browser/extensions/activity-stream/data/content/activity-stream.bundle.js
+browser/extensions/activity-stream/test/**
 browser/extensions/activity-stream/vendor/**
 # The only file in browser/locales/ is pre-processed.
 browser/locales/**
 # imported from chromium
 browser/extensions/mortar/**
 # Generated data files
 browser/extensions/formautofill/phonenumberutils/PhoneNumberMetaData.jsm
 
@@ -186,28 +203,30 @@ dom/animation/**
 dom/archivereader/**
 dom/asmjscache/**
 dom/audiochannel/**
 dom/base/**
 dom/battery/**
 dom/bindings/**
 dom/broadcastchannel/**
 dom/browser-element/**
-dom/cache/**
+dom/cache/test/mochitest/**
+dom/cache/test/xpcshell/**
 dom/canvas/**
 dom/commandhandler/**
 dom/console/**
 dom/crypto/**
 dom/devicestorage/**
 dom/encoding/**
 dom/events/**
 dom/fetch/**
 dom/file/**
 dom/filehandle/**
 dom/filesystem/**
+dom/flex/**
 dom/flyweb/**
 dom/gamepad/**
 dom/geolocation/**
 dom/grid/**
 dom/html/**
 dom/imptests/**
 dom/interfaces/**
 dom/ipc/**
@@ -215,35 +234,53 @@ dom/json/**
 dom/jsurl/**
 dom/locales/**
 dom/manifest/**
 dom/mathml/**
 dom/media/**
 !dom/media/*.js*
 dom/messagechannel/**
 dom/network/**
-dom/notification/**
+dom/notification/Notification*.*
+dom/notification/test/browser/**
+dom/notification/test/unit/**
+dom/notification/test/mochitest/**
 dom/offline/**
 dom/payments/**
 dom/performance/**
 dom/permission/**
-dom/plugins/**
+dom/plugins/test/mochitest/**
+dom/plugins/test/unit/**
 dom/power/**
-dom/presentation/**
+dom/presentation/Presentation*.js
+dom/presentation/provider/**
+dom/presentation/tests/mochitest/**
+dom/presentation/tests/xpcshell/**
 dom/promise/**
 dom/push/**
 dom/quota/**
 dom/res/**
 dom/secureelement/**
-dom/security/**
+dom/security/test/contentverifier/**
+dom/security/test/cors/**
+dom/security/test/csp/**
+dom/security/test/general/**
+dom/security/test/hsts/**
+dom/security/test/mixedcontentblocker/**
+dom/security/test/sri/**
+dom/security/test/unit/**
 dom/smil/**
 dom/storage/**
 dom/svg/**
 dom/system/**
-dom/tests/**
+dom/tests/browser/**
+dom/tests/html/**
+dom/tests/js/**
+dom/tests/mochitest/**
+dom/tests/unit/**
 dom/time/**
 dom/u2f/**
 dom/url/**
 dom/vr/**
 dom/webauthn/**
 dom/webbrowserpersist/**
 dom/webidl/**
 dom/websocket/**
@@ -253,34 +290,41 @@ dom/xbl/**
 dom/xhr/**
 dom/xml/**
 dom/xslt/**
 dom/xul/**
 
 # Third-party
 dom/media/webvtt/**
 
+# Third-party
+gfx/ots/**
+gfx/skia/**
+
 # Exclude everything but self-hosted JS
 js/ductwork/**
 js/examples/**
 js/ipc/**
 js/public/**
 js/xpconnect/**
 js/src/devtools/**
 js/src/octane/**
 js/src/jit-test/**
+js/src/jsapi-tests/binast/**
 js/src/tests/**
 js/src/Y.js
 
+# Third-party
+media/webrtc/trunk/**
+
 # mobile/android/ exclusions
 mobile/android/tests/browser/chrome/tp5/**
 
 # Uses `#filter substitution`
 mobile/android/app/mobile.js
-mobile/android/chrome/content/healthreport-prefs.js
 
 # Uses `#expand`
 mobile/android/chrome/content/about.js
 
 # Not much JS to lint and non-standard at that
 mobile/android/installer/
 mobile/android/locales/
 
@@ -348,16 +392,17 @@ toolkit/components/workerloader/tests/mo
 # Tests old non-star function generators
 toolkit/modules/tests/xpcshell/test_task.js
 
 # External code:
 toolkit/components/microformats/test/**
 toolkit/components/microformats/microformat-shiv.js
 toolkit/components/reader/Readability.js
 toolkit/components/reader/JSDOMParser.js
+toolkit/components/payments/res/vendor/*
 
 # Uses preprocessing
 toolkit/content/widgets/wizard.xml
 toolkit/components/osfile/osfile.jsm
 toolkit/components/urlformatter/nsURLFormatter.js
 toolkit/modules/AppConstants.jsm
 toolkit/mozapps/downloads/nsHelperAppDlg.js
 toolkit/mozapps/update/tests/data/xpcshellConstantsPP.js
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -11,9 +11,35 @@ module.exports = {
     "mozilla"
   ],
   // The html plugin is enabled via a command line option on eslint. To avoid
   // bad interactions with the xml preprocessor in eslint-plugin-mozilla, we
   // turn off processing of the html plugin for .xml files.
   "settings": {
     "html/xml-extensions": [ ".xhtml" ]
   },
+
+  "overrides": [{
+    // eslint-plugin-html handles eol-last slightly different - it applies to
+    // each set of script tags, so we turn it off here.
+    "files": "**/*.*html",
+    "rules": {
+      "eol-last": "off",
+    }
+  }, {
+    // XXX Bug 1421969. These files/directories are still being fixed,
+    // so turn off mozilla/use-services for them for now.
+    "files": [
+      // Browser: Bug 1421379
+      "browser/extensions/shield-recipe-client/test/browser/head.js",
+      "browser/modules/offlineAppCache.jsm",
+      "devtools/**",
+      "dom/indexedDB/**",
+      "extensions/pref/**",
+      "mobile/android/**",
+      "testing/**",
+      "tools/profiler/**",
+    ],
+    "rules": {
+      "mozilla/use-services": "off",
+    }
+  }]
 };
--- a/.gitignore
+++ b/.gitignore
@@ -1,19 +1,19 @@
 # .gitignore - List of filenames git should ignore
 
 # Filenames that should be ignored wherever they appear
 *~
 *.pyc
 *.pyo
 TAGS
 tags
+# Ignore ID generated by idutils and un-ignore id directory (for Indonesian locale)
 ID
-!/browser/extensions/activity-stream/prerendered/locales/id/
-!/browser/extensions/screenshots/webextension/_locales/id/
+!id/
 .DS_Store*
 *.pdb
 *.egg-info
 
 # Vim swap files.
 .*.sw[a-z]
 
 # Emacs directory variable files.
--- a/.hgignore
+++ b/.hgignore
@@ -140,16 +140,21 @@ GPATH
 ^testing/talos/talos/tests/tp5n
 ^testing/talos/talos/tests/devtools/damp.manifest.develop
 ^talos-venv
 ^py3venv
 ^testing/talos/talos/mitmproxy/mitmdump
 ^testing/talos/talos/mitmproxy/mitmproxy
 ^testing/talos/talos/mitmproxy/mitmweb
 
+# Ignore talos speedometer files; source is copied from in-tree /third_party
+# into testing/talos/talos/tests/webkit/PerformanceTests/Speedometer when
+# talos speedometer test is run locally
+^testing/talos/talos/tests/webkit/PerformanceTests/Speedometer
+
 # Ignore toolchains.json created by tooltool.
 ^toolchains\.json
 
 # Ignore files created when running a reftest.
 ^lextab.py$
 
 # tup database
 ^\.tup
@@ -160,8 +165,11 @@ tps_result\.json
 
 # Ignore Visual Studio Code workspace files.
 \.vscode/(?!extensions\.json|tasks\.json)
 
 subinclude:servo/.hgignore
 
 # Ignore Infer output
 ^infer-out/
+
+# https://bz.mercurial-scm.org/show_bug.cgi?id=5322
+^comm/
--- a/.hgtags
+++ b/.hgtags
@@ -92,611 +92,50 @@ cf8750abee06cde395c659f8ecd8ae019d7512e3
 5bb309998e7050c9ee80b0147de1e473f008e221 FIREFOX_AURORA_20_BASE
 cc37417e2c284aed960f98ffa479de4ccdd5c7c3 FIREFOX_AURORA_21_BASE
 1c070ab0f9db59f13423b9c1db60419f7a9098f9 FIREFOX_AURORA_22_BASE
 d7ce9089999719d5186595d160f25123a4e63e39 FIREFOX_AURORA_23_BASE
 8d3810543edccf4fbe458178b88dd4a6e420b010 FIREFOX_AURORA_24_BASE
 ad0ae007aa9e03cd74e9005cd6652e544139b3b5 FIREFOX_AURORA_25_BASE
 2520866d58740851d862c7c59246a4e3f8b4a176 FIREFOX_AURORA_26_BASE
 05025f4889a0bf4dc99ce0c244c750adc002f015 FIREFOX_AURORA_27_BASE
-ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_29_BASE-m
-ba2cc1eda988a1614d8986ae145d28e1268409b9 Tagging for mozilla-central version bumps CLOSED TREE DONTBUILD
-ba2cc1eda988a1614d8986ae145d28e1268409b9 Tagging for mozilla-central version bumps CLOSED TREE DONTBUILD
-0000000000000000000000000000000000000000 Tagging for mozilla-central version bumps CLOSED TREE DONTBUILD
-ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_29_BASE-m
-0000000000000000000000000000000000000000 FIREFOX_AURORA_29_BASE-m
+9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_29_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
-07f5580d8a54e8311fa7641c907065a88de19e08 FIREFOX_AURORA_29_END
-3776f72f1967a7068879501eb7c08920032785b8 B2G_1_4_20140317_MERGEDAY
-aa70a6ce178a6839cd9e55761c4ac31d43ee7bd9 FIREFOX_BETA_29_END
-ba4a8f81efdcf000414f192342ccbd14c9626c36 RELEASE_BASE_20140602
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 83c9853e136451474dfa6d1aaa60a7fca7d2d83a FIREFOX_AURORA_30_BASE
 cfde3603b0206e119abea76fdd6e134b634348f1 FIREFOX_AURORA_31_BASE
-ab25447610b532eb4c32524a7dbc56a21eeaabb8 FIREFOX_BETA_30_BASE
-ab25447610b532eb4c32524a7dbc56a21eeaabb8 FIREFOX_AURORA_30_END
-6c18811bcd1b319801fd97aeb09c41b963863968 FIREFOX_BETA_30_END
-1772e55568e420f8c7fbf7b9434157e9f419c8f1 FIREFOX_RELEASE_31_BASE
-40b1b0712d7b53219a0404e78eec4e6a2796423e FIREFOX_RELEASE_30_END
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 16f3cac5e8fe471e12f76d6a94a477b14e78df7c FIREFOX_AURORA_32_BASE
-f11b164d75442617c4f046177d2ab913ed03a318 FIREFOX_BETA_31_BASE
-f11b164d75442617c4f046177d2ab913ed03a318 FIREFOX_AURORA_31_END
-dc2fd26b301375f15c935f00fe6283d3e3bc1efc B2G_2_0_20140609_MERGEDAY
-d69cd84b6824e018e0906cab0464e11e97a9bdca FIREFOX_BETA_32_BASE
-d69cd84b6824e018e0906cab0464e11e97a9bdca FIREFOX_BETA_32_BASE
-0000000000000000000000000000000000000000 FIREFOX_BETA_32_BASE
-0000000000000000000000000000000000000000 FIREFOX_BETA_32_BASE
-ac396ad5a32d60ae5b7eebe5416fdd46e9e12be1 FIREFOX_BETA_32_BASE
-6befadcaa68524d24960d8342e00503e4edc1869 FIREFOX_BETA_31_END
-92ad4cfa9435fbe136c61071041812f90bc8d89e FIREFOX_RELEASE_32_BASE
-cd52a7f8954809fd893196dc857f81b0cb61717c FIREFOX_RELEASE_31_END
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 dc23164ba2a289a8b22902e30990c77d9677c214 FIREFOX_AURORA_33_BASE
-a104ddcd4cdbf950f1755dfaf5a278d53570655f FIREFOX_AURORA_32_END
-114b010b6bf1a0efee03f003e54ed6fa00909972 FIREFOX_BETA_33_BASE
-ebd0ee3e97dc2756d979261b29f173638fe6aeb6 FIREFOX_BETA_32_END
-e8360a0c7d7483491e064c7cd445a94004af0a83 FIREFOX_RELEASE_33_BASE
-4641475ee1f3ec3e723e932e0f4f3f3fa7c55a5c FIREFOX_RELEASE_32_END
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 c360f3d1c00d73b0c1fb0a2c0da525cb55e58b83 FIREFOX_AURORA_34_BASE
-9f1aad8e807cc283aafbc14caa3d4775e8d0535c FIREFOX_AURORA_33_END
-5b8210dcf52a795646bf0c8a32082a2ed7c4f537 B2G_2_1_20140902_MERGEDAY
-e85828ce78a80e2ccda98972d69d5f750335c4ab FIREFOX_BETA_34_BASE
-8574e35b517785acc905327f4994e96576218fa8 FIREFOX_BETA_33_END
-e247a7f7c43842941bdb4207ca1b9d8881798997 FIREFOX_RELEASE_34_BASE
-a47b1b720b67b018a9cb106178de53a363641392 FIREFOX_RELEASE_33_END
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 cec1a116c4f9a3e887d52e9a26e8bbec200fe162 FIREFOX_AURORA_35_BASE
-2608561c091ae83cc85e38740feffa5bfc6b5ed4 FIREFOX_AURORA_34_END
-390a34a40ea4e7f4d24b3ed83778e0f408411fcc FIREFOX_BETA_35_BASE
-a3cc435fd3c315e5dfe9329d03d5943bb893cced FIREFOX_BETA_34_END
-fb06fa0600ab95db48212a237c79b650cac213c5 FIREFOX_RELEASE_35_BASE
-f4217563f1568c478c1ddf1647098946e51bc7f8 FIREFOX_RELEASE_34_END
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 ca89fe55717059e4e43040d16d260765ffa9dca7 FIREFOX_AURORA_36_BASE
 6047f510fb73c7dbe9866066fb01ddda3c170c9c FIREFOX_AURORA_37_BASE
 ca89fe55717059e4e43040d16d260765ffa9dca7 FIREFOX_AURORA_36_BASE
 0000000000000000000000000000000000000000 FIREFOX_AURORA_36_BASE
 6047f510fb73c7dbe9866066fb01ddda3c170c9c FIREFOX_AURORA_37_BASE
 0000000000000000000000000000000000000000 FIREFOX_AURORA_37_BASE
 0000000000000000000000000000000000000000 FIREFOX_AURORA_36_BASE
 b297a6727acfd21e757ddd38cd61894812666265 FIREFOX_AURORA_36_BASE
-0cf828669d5a0911b6f2b83d501eeef5bdf9905e FIREFOX_AURORA_35_END
-75177371cb85baaa9d623f56d849a5c21d18040f FIREFOX_BETA_36_BASE
-137baee3dda45c6a3b38be74f5709c24f7c7701a FIREFOX_BETA_35_END
-948a2c2e31d4b7eaa282ddeb327708605e3cc7fa FIREFOX_RELEASE_36_BASE
-d57ff45ca4fd7ccf1cb924030abf6c7d108eaab0 FIREFOX_RELEASE_35_END
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 0000000000000000000000000000000000000000 FIREFOX_AURORA_37_BASE
 2c951493eef5b50b8085ef78ffe0d7902ff3d593 FIREFOX_AURORA_37_BASE
-1bc9beda018a42bdd5f63fc9fc46facf0c6f37ec FIREFOX_AURORA_36_END
-030fa1665346dfa94d1f72a1c7830644664ecf08 FIREFOX_BETA_37_BASE
-7d4016a05dd32bf2d726975ba9175bb13fc9ea97 FIREFOX_BETA_36_END
-196c6575593d6e8997402fb458bf8ed2f954fa4a FIREFOX_RELEASE_37_BASE
-58fe203296af528cc711dc314e4769a902e3852f FIREFOX_RELEASE_36_END
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 98086da94ccdc88f6de86774ce3d1fa258dc7c44 FIREFOX_AURORA_38_BASE
-d55b99e8010728b0c802e75e967d2a853122dd30 FIREFOX_AURORA_37_END
-8bc9656cad94db48cd44f3947f1b3b1d8c57768a FIREFOX_BETA_38_BASE
-b41c57eefd69242fc9664a3e5c2dcaa46840051c FIREFOX_BETA_37_END
-fc98815acf5f041c6269fd256a68af8a92ba222a FIREFOX_RELEASE_38_BASE
-b95583c8e7e7a7ce629b4d4551747e818367d0a0 FIREFOX_RELEASE_37_END
-f33925facceefe32f6347faed2d805551d82e60b FIREFOX_RELEASE_38_END
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 1b6bf6612c0f4d4fee81d18bf18016e692f874e1 FIREFOX_AURORA_39_BASE
-d92bf011e305a4a4ad6bb98192a53b86bd64b813 FIREFOX_AURORA_38_END
-5e851d50fb9b8d5a28e4fcd4731dd0f17e8fb4b9 FIREFOX_BETA_39_BASE
-85229fbaf01713caa9ad26c7d3afec271494113c FIREFOX_BETA_38_END
-5fecfbec2e3c934d4646a739bea60d3c93a35f9e FIREFOX_RELEASE_39_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 66a95a483d2c77dfc387019336d18093acd6aac2 FIREFOX_AURORA_40_BASE
-eead3ccdf2d11feefc12907467cebbe07aa91ea9 FIREFOX_AURORA_39_END
-d77cf39268848f8a7e9b38082348b6cd4d1f3b5e FIREFOX_BETA_40_BASE
-0b0822cabbb95d8509852f90c0b7df5da0a4cabc FIREFOX_BETA_39_END
-34e00eb800c52e33059d37f6e41fb255b4bae6b8 FIREFOX_RELEASE_40_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 312c68b16549de9cea1557f461d5d234bd5e0a7d FIREFOX_AURORA_41_BASE
-9d83ab013ab61c7f6e987bf0e7cbab1a1aed1ca8 FIREFOX_AURORA_40_END
-a019592053c4d93fbbafab8d0bd709529e3746de FIREFOX_BETA_41_BASE
-f147014ff61a12480d377c8bde1f90891772540f FIREFOX_BETA_40_END
-6c0329aacb73ab0510c6f1026ef066dfaed9139c FIREFOX_RELEASE_41_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 7a19194812eb767bee7cdf8fc36ba9a383c1bead FIREFOX_AURORA_42_BASE
-d561dc208e61b2f2b4e82ab61710e14f56da4ddb FIREFOX_AURORA_41_END
-61bbc30704aa104e9929c719c0fd7957f96f00ea FIREFOX_BETA_42_BASE
-a5bf9cf6777519663e8e1db553727e59d3ad5681 FIREFOX_BETA_41_END
-3f2ff85b2f16c1fd161dc5ba77a5f3f2c52fd127 FIREFOX_RELEASE_42_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 fcef8ded82219c89298b4e376cfbdfba79a1d35a FIREFOX_AURORA_43_BASE
-b0e20ff87b175424edec414215b325918ccb4792 FIREFOX_AURORA_42_END
-41fdefd640f368bccdeafe6446d42c0a5ad22797 FIREFOX_BETA_43_BASE
-0ec8472a93ac0c7ef0e98ebb91ac780bde12d5a5 FIREFOX_BETA_42_END
-38ffeba26f3e420312e04cb3afb408f4c66a6f2e FIREFOX_RELEASE_43_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 67a788db9f07822cfef52351bbbe3745dff8bd7f FIREFOX_AURORA_44_BASE
-9d3bc275a924a84ab5f34df58c566af0f87479d0 FIREFOX_AURORA_43_END
-b717b80eec62a7ba9b8842487f157b68c1419edd FIREFOX_BETA_44_BASE
-366dd290472633b06f0942d7737c34e942e0916a FIREFOX_BETA_43_END
-ef3cfadfccb97588653ae06eefdac28ec447c1f6 FIREFOX_RELEASE_44_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 99137d6d4061f408ae0869122649d8bdf489cc30 FIREFOX_AURORA_45_BASE
-4fbd53613240c431522521b953d5a62692909e65 FIREFOX_AURORA_44_END
-3bfa5bc61b626761d487b45c170b115259f69d6b FIREFOX_BETA_45_BASE
-6a7547e4a0f0e213bb8487c773e16543cbea8c73 FIREFOX_BETA_44_END
-3a9789adadcd0de9ee31b16a89a11985822c6a11 FENNEC_45_0b1_RELEASE
-6c0fd1f666e70f2b11f7083f9e7bf4c844a3716a FENNEC_45_0b1_RELEASE
-3a9789adadcd0de9ee31b16a89a11985822c6a11 FENNEC_45_0b1_BUILD1
-6c0fd1f666e70f2b11f7083f9e7bf4c844a3716a FENNEC_45_0b1_BUILD1
-5e1da6523e97d7f8b01004bbe33118ac784b40ea FIREFOX_45_0b1_RELEASE
-6c0fd1f666e70f2b11f7083f9e7bf4c844a3716a FIREFOX_45_0b1_RELEASE
-5e1da6523e97d7f8b01004bbe33118ac784b40ea FIREFOX_45_0b1_BUILD1
-6c0fd1f666e70f2b11f7083f9e7bf4c844a3716a FIREFOX_45_0b1_BUILD1
-bbe048ab30ad3321a6505697703e5fee20e91343 FIREFOX_RELEASE_45_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 67c66c2878aed17ae3096d7db483ddbb2293c503 FIREFOX_AURORA_46_BASE
-d82221ba4219e4ac04ecfe2a5301703411e176fa FIREFOX_AURORA_45_END
-89effb961712d4a5f84e90bcdd4e421ed6645eea FIREFOX_BETA_46_BASE
-78fe98c670fcc9a1548ac655ae9a488d940fd9c8 FIREFOX_BETA_45_END
-fb3494d06dfb73e26df72ca7a4bc4ef5ebf8795c FIREFOX_46_0b1_RELEASE
-5904e3eb711dd263a6d2deb63b14e0c44e577054 FIREFOX_46_0b2_BUILD3
-5904e3eb711dd263a6d2deb63b14e0c44e577054 FIREFOX_46_0b2_RELEASE
-2f6f69a19150e03ad68062f2ac92342afb1ef787 FIREFOX_46_0b4_BUILD2
-2f6f69a19150e03ad68062f2ac92342afb1ef787 FIREFOX_46_0b4_RELEASE
-53d6e6648f97402a740687a82a297c66f5396548 FIREFOX_46_0b5_BUILD2
-53d6e6648f97402a740687a82a297c66f5396548 FIREFOX_46_0b5_RELEASE
-97b81104ac035d6a8f6ed59a1aad63fcc23e73c8 FIREFOX_46_0b6_BUILD1
-97b81104ac035d6a8f6ed59a1aad63fcc23e73c8 FIREFOX_46_0b6_RELEASE
-191f5eb4cbd72590277296cdb90d355adb347d45 FIREFOX_46_0b7_BUILD2
-191f5eb4cbd72590277296cdb90d355adb347d45 FIREFOX_46_0b7_RELEASE
-0334bcac4033f4f163476677165acd406e08fed8 FIREFOX_46_0b8_BUILD1
-0334bcac4033f4f163476677165acd406e08fed8 FIREFOX_46_0b8_RELEASE
-b007110e90053e58946b59765605bfca766c30d1 FIREFOX_46_0b9_BUILD1
-b007110e90053e58946b59765605bfca766c30d1 FIREFOX_46_0b9_RELEASE
-9ea83990839bd513869018e57bcbedb3454b63bb FIREFOX_46_0b10_BUILD1
-9ea83990839bd513869018e57bcbedb3454b63bb FIREFOX_46_0b10_RELEASE
-6c4646c7a6d6506e744c92a8170310191904c98e FIREFOX_RELEASE_46_BASE
-076bf6a0ac85ec6a4f3ee7c3efe653964d92b9f2 FIREFOX_46_0b11_BUILD1
-076bf6a0ac85ec6a4f3ee7c3efe653964d92b9f2 FIREFOX_46_0b11_RELEASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 68d3781deda0d4d58ec9877862830db89669b3a5 FIREFOX_AURORA_47_BASE
-43d92f7052e7bab870c9b994d4b0a0f42d26b7a7 FIREFOX_AURORA_46_END
-8551b253f4061db31e4be7829c2f70c2610caf42 FIREFOX_BETA_47_BASE
-a2290938ee6cf794896a9347980bcb00ebb24c68 FIREFOX_BETA_46_END
-5bbf2e7c2fc6ff9010b1948e2f11477f48ee36e2 FIREFOX_47_0b1_BUILD2
-5bbf2e7c2fc6ff9010b1948e2f11477f48ee36e2 FIREFOX_47_0b1_RELEASE
-6f82d30fe05e1412e744cb76af86f0c9ffe509d4 FIREFOX_47_0b2_BUILD1
-6f82d30fe05e1412e744cb76af86f0c9ffe509d4 FIREFOX_47_0b2_RELEASE
-609000bcc11211d7c27ceea36fa2d2262fa0523f FIREFOX_47_0b3_BUILD1
-609000bcc11211d7c27ceea36fa2d2262fa0523f FIREFOX_47_0b3_RELEASE
-2991f214d4f4d8a3c5cfd95e6223f0660006767d FIREFOX_47_0b4_BUILD1
-2991f214d4f4d8a3c5cfd95e6223f0660006767d FIREFOX_47_0b4_RELEASE
-93a53170dedffdff45bf9eb8dac6e5ef7a13c4ba FIREFOX_47_0b5_BUILD1
-93a53170dedffdff45bf9eb8dac6e5ef7a13c4ba FIREFOX_47_0b5_RELEASE
-7d1f3450acc47025876964c1eca854ae027934f3 FIREFOX_47_0b6_BUILD1
-7d1f3450acc47025876964c1eca854ae027934f3 FIREFOX_47_0b6_RELEASE
-0723a0212f5e0b30d7532d4e35eba7759fb54507 FIREFOX_47_0b7_BUILD1
-0723a0212f5e0b30d7532d4e35eba7759fb54507 FIREFOX_47_0b7_RELEASE
-cb27eacbe04abc5f91a0379c23617715aab432ec FIREFOX_47_0b8_BUILD1
-cb27eacbe04abc5f91a0379c23617715aab432ec FIREFOX_47_0b8_RELEASE
-2ee4473c729acb2ba7dc723e7affe79ce14bff85 FIREFOX_47_0b9_BUILD1
-2ee4473c729acb2ba7dc723e7affe79ce14bff85 FIREFOX_47_0b9_RELEASE
-cf6ec12bd62001b93387ffb184a8841644255b5e FIREFOX_RELEASE_47_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 1c6385ae1fe7e37d8f23f958ce14582f07af729e FIREFOX_AURORA_48_BASE
-037f67a2d6c87e32f60b2753f19e4bed69cb60b3 FIREFOX_AURORA_47_END
-961e7105e527f5b44e2b3cb6e24f6da33756f6ab FIREFOX_BETA_48_BASE
-a86835580095325bf5c85483fad952f5c99d973e FIREFOX_BETA_47_END
-55124c7343021091a61fdddac9f22628ca09642a FIREFOX_48_0b1_BUILD2
-55124c7343021091a61fdddac9f22628ca09642a FIREFOX_48_0b1_RELEASE
-9798772706750302d87a689cbbf056ae04244f80 FIREFOX_48_0b2_BUILD2
-9798772706750302d87a689cbbf056ae04244f80 FIREFOX_48_0b2_RELEASE
-13b02b96281e550c3cdbdf4eaed034aa1edefd69 FIREFOX_48_0b3_BUILD1
-13b02b96281e550c3cdbdf4eaed034aa1edefd69 FIREFOX_48_0b3_RELEASE
-676a32cdd41fd372f4c6df3a4954939f73a6ef02 FIREFOX_48_0b4_BUILD1
-676a32cdd41fd372f4c6df3a4954939f73a6ef02 FIREFOX_48_0b4_RELEASE
-dd7af1fa4ece1cb3158d08c80dfcbf1c6ca830fb FIREFOX_48_0b5_BUILD1
-dd7af1fa4ece1cb3158d08c80dfcbf1c6ca830fb FIREFOX_48_0b5_RELEASE
-d142c49033c015f67272562b37dbe2912cfc7f14 FIREFOX_48_0b6_BUILD1
-d142c49033c015f67272562b37dbe2912cfc7f14 FIREFOX_48_0b6_RELEASE
-9d734024ed35d74449601cc04917b327e0973c0d FIREFOX_48_0b7_BUILD1
-9d734024ed35d74449601cc04917b327e0973c0d FIREFOX_48_0b7_RELEASE
-d2ab9c39bd1059d74acb3d9ac87dbfbba913427b FIREFOX_48_0b9_BUILD1
-d2ab9c39bd1059d74acb3d9ac87dbfbba913427b FIREFOX_48_0b9_RELEASE
-05853bb06a8739b77c2937f418cdf4e1610d0d9f FIREFOX_48_0b10_BUILD1
-05853bb06a8739b77c2937f418cdf4e1610d0d9f FIREFOX_48_0b10_RELEASE
-f3d7abb885c267a7657e3b8ea06c18f76eb69641 FIREFOX_RELEASE_48_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
-a8fe75f38163d0af067fea60e951a844fb328db9 FIREFOX_AURORA_48_END
-d2f65d99fd51e5ee2f34d892115cc5d6c39a8ea9 FIREFOX_BETA_49_BASE
-958cee08361af9ed370be06695973bcda3d3aa46 FIREFOX_BETA_48_END
-c14631e328bbbd3aabaf06b51597060b55938ba8 FIREFOX_49_0b1_BUILD3
-c14631e328bbbd3aabaf06b51597060b55938ba8 FIREFOX_49_0b1_RELEASE
-b1bdd0f3482ae07d38a2ec5fbf190a2c4f2310ee FIREFOX_49_0b2_BUILD1
-b1bdd0f3482ae07d38a2ec5fbf190a2c4f2310ee FIREFOX_49_0b2_RELEASE
-36af692196a1c92cc935cf6569e03fdf5dc5e426 FIREFOX_49_0b3_BUILD1
-36af692196a1c92cc935cf6569e03fdf5dc5e426 FIREFOX_49_0b3_RELEASE
-ab7b68014a1e20c423aa9b50ca76fd8edccb272c FIREFOX_49_0b4_BUILD1
-ab7b68014a1e20c423aa9b50ca76fd8edccb272c FIREFOX_49_0b4_RELEASE
-91505c2a68fb868bcab1e3dc03ffc2e89bf71cac FIREFOX_49_0b5_BUILD1
-91505c2a68fb868bcab1e3dc03ffc2e89bf71cac FIREFOX_49_0b5_RELEASE
-e6d6eb0ce3c42b4ebca91b1b1b64b716b2acb9fd FIREFOX_49_0b6_BUILD1
-e6d6eb0ce3c42b4ebca91b1b1b64b716b2acb9fd FIREFOX_49_0b6_RELEASE
-b44c72b85a800d9c6e719579d480bb2c3a87a753 FIREFOX_49_0b7_BUILD1
-b44c72b85a800d9c6e719579d480bb2c3a87a753 FIREFOX_49_0b7_RELEASE
-68d24e6f784c7e375cf6c84c5c92496464d4f7e0 FIREFOX_49_0b8_BUILD1
-68d24e6f784c7e375cf6c84c5c92496464d4f7e0 FIREFOX_49_0b8_RELEASE
-e3cc699ccef2abb7075c39e7b9a081718eb9c159 FIREFOX_49_0b9_BUILD1
-e3cc699ccef2abb7075c39e7b9a081718eb9c159 FIREFOX_49_0b9_RELEASE
-77a60bbacb97c2f36815b2c395958a354aa581c9 FIREFOX_49_0b10_BUILD1
-77a60bbacb97c2f36815b2c395958a354aa581c9 FIREFOX_49_0b10_RELEASE
-5d1f8216843a6374f3bd2bd74ab2532da67d74ee FIREFOX_RELEASE_49_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 d98f20c25feeac4dd7ebbd1c022957df1ef58af4 FIREFOX_AURORA_49_BASE
 465d150bc8be5bbf9f02a8607d4552b6a5e1697c FIREFOX_AURORA_50_BASE
-fa80a27f26dfc653d23392c71f562b1827d82174 FIREFOX_AURORA_49_END
-c174d0c3195371011b3bf8044512c06c26f5c741 FIREFOX_BETA_50_BASE
-ddeb7907bc1e854738b164bab5ff71c3dcf1d786 FIREFOX_BETA_49_END
-91faf7ec36cd18a8ebdc0e2edac966e5bbb15da2 FIREFOX_50_0b1_BUILD2
-91faf7ec36cd18a8ebdc0e2edac966e5bbb15da2 FIREFOX_50_0b1_RELEASE
-865939f4946d80fa532aaa168515a2fe69f9a774 FIREFOX_50_0b2_BUILD1
-865939f4946d80fa532aaa168515a2fe69f9a774 FIREFOX_50_0b2_RELEASE
-6a7c1c8db5548d077c7fa36bce41af629ba52bd8 FIREFOX_50_0b3_BUILD1
-6a7c1c8db5548d077c7fa36bce41af629ba52bd8 FIREFOX_50_0b3_RELEASE
-f4b45ea3c0c836e5a457c8009bff423447e54803 FIREFOX_50_0b4_BUILD1
-f4b45ea3c0c836e5a457c8009bff423447e54803 FIREFOX_50_0b4_RELEASE
-49776d31766dd130969f9ec4ea3354a43e8e6d9d FIREFOX_50_0b5_BUILD1
-49776d31766dd130969f9ec4ea3354a43e8e6d9d FIREFOX_50_0b5_RELEASE
-70abfe99097824fd510544b188f24c588fd6d5a0 FIREFOX_50_0b6_BUILD1
-70abfe99097824fd510544b188f24c588fd6d5a0 FIREFOX_50_0b6_RELEASE
-6efc0964ec62bc4abfdc4cb1dc7cc461c3238634 FIREFOX_50_0b7_BUILD1
-6efc0964ec62bc4abfdc4cb1dc7cc461c3238634 FIREFOX_50_0b7_RELEASE
-b7adb2f10487f6f886e047670ba720a248edcb44 FIREFOX_50_0b8_BUILD1
-b7adb2f10487f6f886e047670ba720a248edcb44 FIREFOX_50_0b8_RELEASE
-2bb6dc758711c00d84246d74b57e5aa6cae4b447 FIREFOX_50_0b9_BUILD1
-2bb6dc758711c00d84246d74b57e5aa6cae4b447 FIREFOX_50_0b9_RELEASE
-38cfded1705240c5d20baff4aef99bdd0a13bcec FIREFOX_50_0b10_BUILD1
-38cfded1705240c5d20baff4aef99bdd0a13bcec FIREFOX_50_0b10_RELEASE
-829a3f99f2606759305e3db204185242566a4ca6 FIREFOX_50_0b11_BUILD1
-829a3f99f2606759305e3db204185242566a4ca6 FIREFOX_50_0b11_RELEASE
-d7598ee90bc6085d430b2e9e75c13358ef00a5f4 FIREFOX_RELEASE_50_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 fc69febcbf6c0dcc4b3dfc7a346d8d348798a65f FIREFOX_AURORA_51_BASE
-3fdfaaed6e0fad2d81fc28e49903ff6f0a43b12e FIREFOX_AURORA_50_END
-2d9b6132e7d75327e063a15d8e5e279077adf987 FIREFOX_BETA_51_BASE
-24b8f08f77565f859898b45f62d2132ccc64c6d8 FIREFOX_BETA_50_END
-749a8d32b74eae516b9427f28aad4ec1c11e0a54 FIREFOX_51_0b1_BUILD2
-749a8d32b74eae516b9427f28aad4ec1c11e0a54 FIREFOX_51_0b1_RELEASE
-6296ed3dbefd133bba324230ec4f5a07d37041e1 FIREFOX_51_0b2_BUILD1
-6296ed3dbefd133bba324230ec4f5a07d37041e1 FIREFOX_51_0b2_RELEASE
-f37e99ebc6e0c682003b52573f415e5fd78d425a FIREFOX_51_0b3_BUILD1
-f37e99ebc6e0c682003b52573f415e5fd78d425a FIREFOX_51_0b3_RELEASE
-1b954c82dd04faf1926804d89c0d130dc6b9ab93 FIREFOX_51_0b4_BUILD1
-1b954c82dd04faf1926804d89c0d130dc6b9ab93 FIREFOX_51_0b4_RELEASE
-9afe68360fa82c16b760b448b2156230a90caf11 FIREFOX_51_0b5_BUILD1
-9afe68360fa82c16b760b448b2156230a90caf11 FIREFOX_51_0b5_RELEASE
-2dec3c6c7c90e2e27093b8a3512c1b32a8263a8f FIREFOX_51_0b6_BUILD1
-2dec3c6c7c90e2e27093b8a3512c1b32a8263a8f FIREFOX_51_0b6_RELEASE
-829fcc7f60f04dffff4d29b007ef8015a1cd2c99 FIREFOX_51_0b7_BUILD1
-829fcc7f60f04dffff4d29b007ef8015a1cd2c99 FIREFOX_51_0b7_RELEASE
-ae5275b8c53ba76cb98576e4e2a3031b0d659ba3 FIREFOX_51_0b8_BUILD1
-ae5275b8c53ba76cb98576e4e2a3031b0d659ba3 FIREFOX_51_0b8_RELEASE
-6e4843d1510be426212d31fec03ad4f2d70b1977 FIREFOX_51_0b9_BUILD1
-6e4843d1510be426212d31fec03ad4f2d70b1977 FIREFOX_51_0b9_RELEASE
-4fbf5d14ce92bd45e0c7881dad20a66896402683 FIREFOX_51_0b10_BUILD1
-4fbf5d14ce92bd45e0c7881dad20a66896402683 FIREFOX_51_0b10_RELEASE
-0a17d39220700e742bf37a960967480b2f8159f1 FIREFOX_51_0b11_BUILD1
-0a17d39220700e742bf37a960967480b2f8159f1 FIREFOX_51_0b11_RELEASE
-9ddd4fee07842e72ba49f1583ec5f596f6e60e72 FIREFOX_51_0b12_BUILD1
-9ddd4fee07842e72ba49f1583ec5f596f6e60e72 FIREFOX_51_0b12_RELEASE
-ce55e4d276031458f0730d481acff05d7c797038 FIREFOX_51_0b13_BUILD1
-ce55e4d276031458f0730d481acff05d7c797038 FIREFOX_51_0b13_RELEASE
-09142d07fd735e375fc1ae46886a52d6aef43b60 FIREFOX_51_0b14_BUILD1
-09142d07fd735e375fc1ae46886a52d6aef43b60 FIREFOX_51_0b14_RELEASE
-15467610e733e3549ea86cdf940b0fccd87eff89 FIREFOX_RELEASE_51_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 1196bf3032e1bce1fb07a01fd9082a767426c5fb FIREFOX_AURORA_52_BASE
-3223a6411d8c8b9ec8bcbc607c990bf099ade099 FIREFOX_AURORA_51_END
-24a81d93e07cc96300f8e1f5c69034dd4743bd63 FIREFOX_BETA_52_BASE
-8e692dd4176cba81ce020b29ae8b352dc1db724a FIREFOX_BETA_51_END
-78ae21055d9f303be257abe155ba9dee466c0651 FIREFOX_52_0b1_BUILD2
-78ae21055d9f303be257abe155ba9dee466c0651 FIREFOX_52_0b1_RELEASE
-0f339c1e154f75c484fe2fac507a9a225990d212 FIREFOX_52_0b2_BUILD1
-0f339c1e154f75c484fe2fac507a9a225990d212 FIREFOX_52_0b2_RELEASE
-d171c36d484800b1bb00db1612460a7120dd2fdf FIREFOX_52_0b3_BUILD1
-d171c36d484800b1bb00db1612460a7120dd2fdf FIREFOX_52_0b3_RELEASE
-501a3fa83897af9598adfd6f794b5d5ea82fe237 FIREFOX_52_0b4_BUILD1
-501a3fa83897af9598adfd6f794b5d5ea82fe237 FIREFOX_52_0b4_RELEASE
-49b3ad9f467d48194dab8121f82e4c938b70b484 FIREFOX_52_0b5_BUILD1
-49b3ad9f467d48194dab8121f82e4c938b70b484 FIREFOX_52_0b5_RELEASE
-7b8aa893944b94d35e47314e52e0abff576c5ce2 FIREFOX_52_0b6_BUILD1
-7b8aa893944b94d35e47314e52e0abff576c5ce2 FIREFOX_52_0b6_RELEASE
-820bc5bd3120853d611af1056f4a2b35528bb927 FIREFOX_52_0b7_BUILD1
-820bc5bd3120853d611af1056f4a2b35528bb927 FIREFOX_52_0b7_RELEASE
-3b31bcb88fe341172e93cc8b1143e617c0988694 FIREFOX_52_0b8_BUILD1
-3b31bcb88fe341172e93cc8b1143e617c0988694 FIREFOX_52_0b8_RELEASE
-61519976b35f2947eeaabefcad83186b7e004167 FIREFOX_52_0b9_BUILD2
-61519976b35f2947eeaabefcad83186b7e004167 FIREFOX_52_0b9_RELEASE
-4bd2e5d2ac0d0b15b4446fca5647bfa821b52d46 FIREFOX_RELEASE_52_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 f80dc9fc34680105b714a49b4704bb843f5f7004 FIREFOX_AURORA_53_BASE
-1bf0b129e71adde135eb1eb577d497935c234a50 FIREFOX_AURORA_52_END
-69efeba94b307f236a50a9e5fdd2bbd2e946657b FIREFOX_BETA_53_BASE
-69efeba94b307f236a50a9e5fdd2bbd2e946657b FIREFOX_BETA_53_BASE
-0000000000000000000000000000000000000000 FIREFOX_BETA_53_BASE
-0000000000000000000000000000000000000000 FIREFOX_BETA_53_BASE
-39accab74f27dde4531631a66e95632bd8b4ffd3 FIREFOX_BETA_53_BASE
-615b84cd4c5f5923b78ffa1d335e51a6a74001f5 FIREFOX_BETA_52_END
-2b89485cf946cdfdd69e5d11aa6af2563fa7520d FIREFOX_53_0b1_BUILD1
-2b89485cf946cdfdd69e5d11aa6af2563fa7520d FIREFOX_53_0b1_RELEASE
-a4a198383638d54b6093b1caab16740cec21ebc2 FENNEC_53_0b1_BUILD3
-a4a198383638d54b6093b1caab16740cec21ebc2 FENNEC_53_0b1_RELEASE
-a5ccc32310c9a424ccb4f5106f5155ca20dd360a FIREFOX_53_0b2_BUILD1
-a5ccc32310c9a424ccb4f5106f5155ca20dd360a FIREFOX_53_0b2_RELEASE
-a5ccc32310c9a424ccb4f5106f5155ca20dd360a FENNEC_53_0b2_BUILD1
-a5ccc32310c9a424ccb4f5106f5155ca20dd360a FENNEC_53_0b2_RELEASE
-484f49860df6c257b06dac275d66651cc6f22867 FIREFOX_53_0b4_BUILD1
-484f49860df6c257b06dac275d66651cc6f22867 FIREFOX_53_0b4_RELEASE
-eb20f71a4f431d695b88ea5796a55d52cc9cf481 FIREFOX_53_0b5_BUILD1
-eb20f71a4f431d695b88ea5796a55d52cc9cf481 FIREFOX_53_0b5_RELEASE
-484f49860df6c257b06dac275d66651cc6f22867 FENNEC_53_0b4_BUILD1
-484f49860df6c257b06dac275d66651cc6f22867 FENNEC_53_0b4_RELEASE
-484f49860df6c257b06dac275d66651cc6f22867 FENNEC_53_0b4_BUILD1
-484f49860df6c257b06dac275d66651cc6f22867 FENNEC_53_0b4_BUILD1
-484f49860df6c257b06dac275d66651cc6f22867 FENNEC_53_0b4_RELEASE
-484f49860df6c257b06dac275d66651cc6f22867 FENNEC_53_0b4_RELEASE
-eb20f71a4f431d695b88ea5796a55d52cc9cf481 FENNEC_53_0b5_BUILD1
-eb20f71a4f431d695b88ea5796a55d52cc9cf481 FENNEC_53_0b5_RELEASE
-62467dd7218ffb48be7d4406d98ded5d0909fcfc FIREFOX_53_0b6_BUILD1
-62467dd7218ffb48be7d4406d98ded5d0909fcfc FIREFOX_53_0b6_RELEASE
-46d5fe92c82d36b922703faeb7dd3a17b5df55e1 FENNEC_53_0b7_BUILD1
-46d5fe92c82d36b922703faeb7dd3a17b5df55e1 FENNEC_53_0b7_RELEASE
-46d5fe92c82d36b922703faeb7dd3a17b5df55e1 FIREFOX_53_0b7_BUILD1
-46d5fe92c82d36b922703faeb7dd3a17b5df55e1 FIREFOX_53_0b7_RELEASE
-0a36cc120d6e7b8bc19176f5efac6b00dd9ad072 FIREFOX_53_0b8_BUILD1
-0a36cc120d6e7b8bc19176f5efac6b00dd9ad072 FIREFOX_53_0b8_RELEASE
-3a2e5c6e4ed33d9cb8b04b32f85b45a9aad4c8d8 FIREFOX_53_0b9_BUILD1
-3a2e5c6e4ed33d9cb8b04b32f85b45a9aad4c8d8 FIREFOX_53_0b9_RELEASE
-3a2e5c6e4ed33d9cb8b04b32f85b45a9aad4c8d8 FENNEC_53_0b9_BUILD1
-3a2e5c6e4ed33d9cb8b04b32f85b45a9aad4c8d8 FENNEC_53_0b9_RELEASE
-ac874b7422a6747ee5e14e348ebea77ae639a7a5 FIREFOX_53_0b10_BUILD1
-ac874b7422a6747ee5e14e348ebea77ae639a7a5 FIREFOX_53_0b10_RELEASE
-557f09b2881bf2513bc34d3a0fe2a2de04163054 FIREFOX_RELEASE_53_BASE
-557f09b2881bf2513bc34d3a0fe2a2de04163054 FIREFOX_RELEASE_53_BASE
-0000000000000000000000000000000000000000 FIREFOX_RELEASE_53_BASE
-0000000000000000000000000000000000000000 FIREFOX_RELEASE_53_BASE
-db89a02ecfbbbe17831b11f3313814a67621264d FIREFOX_RELEASE_53_BASE
-35a1b06fe7863e118ce831d9056ad20501eec606 FENNEC_53_0b11_BUILD1
-35a1b06fe7863e118ce831d9056ad20501eec606 FENNEC_53_0b11_RELEASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 6583496f169cd8a13c531ed16e98e8bf313eda8e FIREFOX_AURORA_54_BASE
-4e1faf8f62eb5edfbbe05c8f0a35cbe57a5ec9b6 FIREFOX_AURORA_53_END
-09e97b55acb30be1f8e13b0f637f9cf152658799 FIREFOX_BETA_54_BASE
-1d36370d5eac6e6927dbc4810ba5cdb760f6eb93 FIREFOX_BETA_53_END
-bfa8f90200d10fb26feb01967dc8a95736b6769a FENNEC_54_0b1_BUILD1
-bfa8f90200d10fb26feb01967dc8a95736b6769a FENNEC_54_0b1_RELEASE
-cf76e00dcd6f142acf5b49f8beeb0ac95b2afa31 FIREFOX_54_0b1_BUILD1
-cf76e00dcd6f142acf5b49f8beeb0ac95b2afa31 FIREFOX_54_0b1_RELEASE
-ca3c6131b6eadf753445b3cd7a54e29b41ab11aa FIREFOX_54_0b2_BUILD1
-ca3c6131b6eadf753445b3cd7a54e29b41ab11aa FIREFOX_54_0b2_RELEASE
-ca3c6131b6eadf753445b3cd7a54e29b41ab11aa FENNEC_54_0b2_BUILD1
-ca3c6131b6eadf753445b3cd7a54e29b41ab11aa FENNEC_54_0b2_RELEASE
-0b1c079a2a4b826b217ec7d3c7446ef942e4fc0e FIREFOX_54_0b3_BUILD1
-0b1c079a2a4b826b217ec7d3c7446ef942e4fc0e FIREFOX_54_0b3_RELEASE
-8a7f650cff30f54e60e2a55f56c2e12222352f69 FIREFOX_54_0b4_BUILD1
-8a7f650cff30f54e60e2a55f56c2e12222352f69 FIREFOX_54_0b4_RELEASE
-06bf49fb579575e4813aa54127f67c22964c822b FIREFOX_54_0b5_BUILD1
-06bf49fb579575e4813aa54127f67c22964c822b FIREFOX_54_0b5_RELEASE
-8a7f650cff30f54e60e2a55f56c2e12222352f69 FENNEC_54_0b4_BUILD1
-8a7f650cff30f54e60e2a55f56c2e12222352f69 FENNEC_54_0b4_RELEASE
-798ee0e6f73eaed68e3f3968a20e9ae5c7a82718 FIREFOX_54_0b6_BUILD1
-798ee0e6f73eaed68e3f3968a20e9ae5c7a82718 FIREFOX_54_0b6_RELEASE
-798ee0e6f73eaed68e3f3968a20e9ae5c7a82718 FENNEC_54_0b6_BUILD1
-798ee0e6f73eaed68e3f3968a20e9ae5c7a82718 FENNEC_54_0b6_RELEASE
-8b7e2a303954352189cf0e9772f35aed06953fa5 FIREFOX_54_0b7_BUILD1
-8b7e2a303954352189cf0e9772f35aed06953fa5 FIREFOX_54_0b7_RELEASE
-9bef2dfbd584c0f3ae52953bfc3aed64e308960d FIREFOX_54_0b8_BUILD1
-9bef2dfbd584c0f3ae52953bfc3aed64e308960d FIREFOX_54_0b8_RELEASE
-9bef2dfbd584c0f3ae52953bfc3aed64e308960d FENNEC_54_0b8_BUILD1
-9bef2dfbd584c0f3ae52953bfc3aed64e308960d FENNEC_54_0b8_RELEASE
-54f218cec92ffcc2cc8160ed80c58ffe8b6c268d FIREFOX_54_0b9_BUILD1
-54f218cec92ffcc2cc8160ed80c58ffe8b6c268d FIREFOX_54_0b9_RELEASE
-a6edfa473c7dde50edc14a85374eb400e5ada494 FIREFOX_54_0b10_BUILD1
-a6edfa473c7dde50edc14a85374eb400e5ada494 FIREFOX_54_0b10_RELEASE
-a6edfa473c7dde50edc14a85374eb400e5ada494 FENNEC_54_0b10_BUILD2
-a6edfa473c7dde50edc14a85374eb400e5ada494 FENNEC_54_0b10_RELEASE
-51c849c595a0b5428d1d56e4ae668653437283e2 FIREFOX_54_0b11_BUILD2
-51c849c595a0b5428d1d56e4ae668653437283e2 FIREFOX_54_0b11_RELEASE
-715d88d0bd826c9e4a5403d6561a2fcc229dd208 FIREFOX_54_0b12_BUILD1
-715d88d0bd826c9e4a5403d6561a2fcc229dd208 FIREFOX_54_0b12_RELEASE
-715d88d0bd826c9e4a5403d6561a2fcc229dd208 FENNEC_54_0b12_BUILD1
-715d88d0bd826c9e4a5403d6561a2fcc229dd208 FENNEC_54_0b12_RELEASE
-cb4a4275b365b126ae56b1df5521756b693d8ff9 FIREFOX_54_0b13_BUILD1
-cb4a4275b365b126ae56b1df5521756b693d8ff9 FIREFOX_54_0b13_RELEASE
-6f0be3ad8512b63a13cb4ec87ae4efae31411ecf FIREFOX_RELEASE_54_BASE
-97767088522e789dd04cf06b24478f052946d1c9 FENNEC_54_0b14_BUILD1
-97767088522e789dd04cf06b24478f052946d1c9 FENNEC_54_0b14_RELEASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 f9605772a0c9098ed1bcaa98089b2c944ed69e9b FIREFOX_BETA_55_BASE
-d8424bcbf72f7a451e89f8f625a9ebafecded872 FIREFOX_BETA_54_END
-e8dd9736241ea1989feaf3c85a71593c8a6f3bbb FENNEC_55_0b1_BUILD2
-e8dd9736241ea1989feaf3c85a71593c8a6f3bbb FENNEC_55_0b1_RELEASE
-d956c96a1926c1755d9ce46a110ba7893f4d478a FIREFOX_55_0b1_BUILD5
-d956c96a1926c1755d9ce46a110ba7893f4d478a FIREFOX_55_0b1_RELEASE
-803f16362c14a488b1923b184859f8265f63731f FIREFOX_55_0b2_BUILD1
-803f16362c14a488b1923b184859f8265f63731f FIREFOX_55_0b2_RELEASE
-be4a0ad5d6cab12fb89495d020532040b91be1f4 FIREFOX_55_0b3_BUILD1
-be4a0ad5d6cab12fb89495d020532040b91be1f4 FIREFOX_55_0b3_RELEASE
-be4a0ad5d6cab12fb89495d020532040b91be1f4 FENNEC_55_0b3_BUILD1
-be4a0ad5d6cab12fb89495d020532040b91be1f4 FENNEC_55_0b3_RELEASE
-0a6a0148a61c5b2255f8b4272634efc1d1bd0c98 FIREFOX_55_0b4_BUILD2
-0a6a0148a61c5b2255f8b4272634efc1d1bd0c98 FIREFOX_55_0b4_RELEASE
-af94af58d1f315f475fbe831bb48aecbeb9a0c61 FIREFOX_55_0b5_BUILD1
-af94af58d1f315f475fbe831bb48aecbeb9a0c61 FIREFOX_55_0b5_RELEASE
-af94af58d1f315f475fbe831bb48aecbeb9a0c61 FENNEC_55_0b5_BUILD1
-af94af58d1f315f475fbe831bb48aecbeb9a0c61 FENNEC_55_0b5_RELEASE
-bfd96be70455cba0fdb82593d10395dd84dfa270 FIREFOX_55_0b6_BUILD1
-bfd96be70455cba0fdb82593d10395dd84dfa270 FIREFOX_55_0b6_RELEASE
-1ae7e516e5dae3c0b537251781e1adeb50783131 FIREFOX_55_0b7_BUILD1
-1ae7e516e5dae3c0b537251781e1adeb50783131 FIREFOX_55_0b7_RELEASE
-1ae7e516e5dae3c0b537251781e1adeb50783131 FENNEC_55_0b7_BUILD1
-1ae7e516e5dae3c0b537251781e1adeb50783131 FENNEC_55_0b7_RELEASE
-0a457907494285ecf2e1745b222436d775476d17 FIREFOX_55_0b8_BUILD1
-0a457907494285ecf2e1745b222436d775476d17 FIREFOX_55_0b8_RELEASE
-0a457907494285ecf2e1745b222436d775476d17 FENNEC_55_0b8_BUILD1
-0a457907494285ecf2e1745b222436d775476d17 FENNEC_55_0b8_RELEASE
-91e10e2411762dea81d5df70d9fefe96fe619353 FIREFOX_55_0b9_BUILD2
-91e10e2411762dea81d5df70d9fefe96fe619353 FIREFOX_55_0b9_RELEASE
-e26b1f5d635e2b62ba99f5ec90a0c10509a6eee9 FIREFOX_55_0b10_BUILD1
-e26b1f5d635e2b62ba99f5ec90a0c10509a6eee9 FIREFOX_55_0b10_RELEASE
-e26b1f5d635e2b62ba99f5ec90a0c10509a6eee9 FENNEC_55_0b10_BUILD1
-e26b1f5d635e2b62ba99f5ec90a0c10509a6eee9 FENNEC_55_0b10_RELEASE
-e5f14b9ae6c4c1e0ff1c430503671289120db203 FIREFOX_55_0b11_BUILD1
-e5f14b9ae6c4c1e0ff1c430503671289120db203 FIREFOX_55_0b11_RELEASE
-5ff8131b551228ca603a76e39925495d7d2a407e FIREFOX_55_0b12_BUILD1
-5ff8131b551228ca603a76e39925495d7d2a407e FIREFOX_55_0b12_RELEASE
-5ff8131b551228ca603a76e39925495d7d2a407e FENNEC_55_0b12_BUILD1
-5ff8131b551228ca603a76e39925495d7d2a407e FENNEC_55_0b12_RELEASE
-271221d4286a7641c21f8a13df2987d655f9d3dc FIREFOX_55_0b13_BUILD1
-271221d4286a7641c21f8a13df2987d655f9d3dc FIREFOX_55_0b13_RELEASE
-2cd8c7f13e6c5ace6955da85a4d95f6e65caad2e FIREFOX_RELEASE_55_BASE
-116b3910f1c72ae12ed330ed7942ac1afeea953e FENNEC_55_0b14_BUILD1
-116b3910f1c72ae12ed330ed7942ac1afeea953e FENNEC_55_0b14_RELEASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 320642944e42a889db13c6c55b404e32319d4de6 FIREFOX_BETA_56_BASE
-907a3a5c6fede43f359184c4c604390578f8cabe FIREFOX_BETA_55_END
-6c489d5df6d4d85ddb297666e8c1cbbda96a852c FENNEC_56_0b1_BUILD1
-6c489d5df6d4d85ddb297666e8c1cbbda96a852c FENNEC_56_0b1_RELEASE
-da6760885a24e03e13f3b566f319fc255dbb4027 FIREFOX_56_0b1_BUILD5
-da6760885a24e03e13f3b566f319fc255dbb4027 FIREFOX_56_0b1_RELEASE
-2638feb177dd9104a3887fae2ce05931a6b41d6c FIREFOX_56_0b2_BUILD1
-2638feb177dd9104a3887fae2ce05931a6b41d6c FIREFOX_56_0b2_RELEASE
-efabe9b3a88e0cb1bcb092b34e0291ac99759471 FIREFOX_56_0b3_BUILD1
-efabe9b3a88e0cb1bcb092b34e0291ac99759471 FIREFOX_56_0b3_RELEASE
-efabe9b3a88e0cb1bcb092b34e0291ac99759471 FENNEC_56_0b3_BUILD1
-efabe9b3a88e0cb1bcb092b34e0291ac99759471 FENNEC_56_0b3_RELEASE
-05a4dc75c125a80cbaacd44c7b7937c77dc384a8 FIREFOX_56_0b4_BUILD5
-05a4dc75c125a80cbaacd44c7b7937c77dc384a8 FIREFOX_56_0b4_RELEASE
-86e3368b6058c3a298a6fd973de1313cfe706795 FIREFOX_56_0b5_BUILD1
-86e3368b6058c3a298a6fd973de1313cfe706795 FIREFOX_56_0b5_RELEASE
-86e3368b6058c3a298a6fd973de1313cfe706795 FENNEC_56_0b5_BUILD1
-86e3368b6058c3a298a6fd973de1313cfe706795 FENNEC_56_0b5_RELEASE
-acf7e3e5c7fd7b4faff64ebdaba535026172cfba FIREFOX_56_0b6_BUILD2
-acf7e3e5c7fd7b4faff64ebdaba535026172cfba FIREFOX_56_0b6_RELEASE
-8081a895e4353e807a851485e412ed7a907c0b3f FIREFOX_56_0b7_BUILD2
-8081a895e4353e807a851485e412ed7a907c0b3f FIREFOX_56_0b7_RELEASE
-8081a895e4353e807a851485e412ed7a907c0b3f FENNEC_56_0b7_BUILD1
-8081a895e4353e807a851485e412ed7a907c0b3f FENNEC_56_0b7_RELEASE
-dcb3e24852c4b3ddc900d5e2430853cb9a51cdc4 FIREFOX_56_0b8_BUILD1
-dcb3e24852c4b3ddc900d5e2430853cb9a51cdc4 FIREFOX_56_0b8_RELEASE
-da291ce74248b2830a0010a8bf21bba5f408bd43 FENNEC_56_0b9_BUILD3
-da291ce74248b2830a0010a8bf21bba5f408bd43 FENNEC_56_0b9_RELEASE
-da291ce74248b2830a0010a8bf21bba5f408bd43 FIREFOX_56_0b9_BUILD1
-da291ce74248b2830a0010a8bf21bba5f408bd43 FIREFOX_56_0b9_RELEASE
-3484d06e80e135e84167fe95f8a42320308a2adc FIREFOX_56_0b10_BUILD1
-3484d06e80e135e84167fe95f8a42320308a2adc FIREFOX_56_0b10_RELEASE
-6bd183fc69218cdbb69a5f9407c69206dade6ae1 FIREFOX_56_0b11_BUILD1
-6bd183fc69218cdbb69a5f9407c69206dade6ae1 FIREFOX_56_0b11_RELEASE
-6bd183fc69218cdbb69a5f9407c69206dade6ae1 FENNEC_56_0b11_BUILD1
-6bd183fc69218cdbb69a5f9407c69206dade6ae1 FENNEC_56_0b11_RELEASE
-12809a8ce21a7b10c7a4e54baa9ae742c176de87 FIREFOX_RELEASE_56_BASE
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 8e818b5e9b6bef0fc1a5c527ecf30b0d56a02f14 FIREFOX_BETA_57_BASE
-d519209bdd0a4dd4c4a74f0a9097851d949eb25f FIREFOX_BETA_56_END
-fbef00b40b98333a637211cd284db9e3f5348f07 FIREFOX_56_0b12_BUILD1
-fbef00b40b98333a637211cd284db9e3f5348f07 FIREFOX_56_0b12_RELEASE
-e85c29016601de4367a96ff4bc37a440206f3304 FIREFOX_57_0b1_BUILD1
-e85c29016601de4367a96ff4bc37a440206f3304 FIREFOX_57_0b1_BUILD2
-3d2edf73fb90e8f0601bc0b16e79c1c24919db98 FIREFOX_57_0b1_BUILD3
-3d2edf73fb90e8f0601bc0b16e79c1c24919db98 FIREFOX_57_0b1_RELEASE
-3354b84cc524a26b78ce0058fef279cf523b948f FIREFOX_57_0b2_BUILD1
-3354b84cc524a26b78ce0058fef279cf523b948f FIREFOX_57_0b2_RELEASE
-c3f480fa9744b65485b77e5d67768a9dbf075752 FIREFOX_57_0b3_BUILD1
-c3f480fa9744b65485b77e5d67768a9dbf075752 FIREFOX_57_0b3_RELEASE
-c3f480fa9744b65485b77e5d67768a9dbf075752 FENNEC_57_0b3_BUILD1
-c3f480fa9744b65485b77e5d67768a9dbf075752 FENNEC_57_0b3_RELEASE
-1c3b6791f9433c7cf8d6ecb453c9277fd99a5b4a FIREFOX_57_0b4_BUILD1
-1c3b6791f9433c7cf8d6ecb453c9277fd99a5b4a FIREFOX_57_0b4_RELEASE
-1c3b6791f9433c7cf8d6ecb453c9277fd99a5b4a FENNEC_57_0b4_BUILD1
-1c3b6791f9433c7cf8d6ecb453c9277fd99a5b4a FENNEC_57_0b4_RELEASE
-37d18f6628dcecba2f3f59a3d853071b7ca799e0 FIREFOX_57_0b5_BUILD1
-37d18f6628dcecba2f3f59a3d853071b7ca799e0 FIREFOX_57_0b5_RELEASE
-2cc69216f323ea33c977f7186b0b5668707c88f1 FENNEC_57_0b5_BUILD1
-2cc69216f323ea33c977f7186b0b5668707c88f1 FENNEC_57_0b5_RELEASE
-178de8c0b3e4c48cf86d7dbf7dfe047002d2346d FIREFOX_57_0b6_BUILD1
-178de8c0b3e4c48cf86d7dbf7dfe047002d2346d FIREFOX_57_0b6_RELEASE
-b92b69f3503e71ea7a7184f3f56526aafa57d999 FIREFOX_57_0b7_BUILD1
-b92b69f3503e71ea7a7184f3f56526aafa57d999 FIREFOX_57_0b7_RELEASE
-b92b69f3503e71ea7a7184f3f56526aafa57d999 FENNEC_57_0b7_BUILD1
-b92b69f3503e71ea7a7184f3f56526aafa57d999 FENNEC_57_0b7_RELEASE
-d96198d960f3cbc4d17eb9990c801c1903d454fd FIREFOX_57_0b8_BUILD3
-d96198d960f3cbc4d17eb9990c801c1903d454fd FIREFOX_57_0b8_RELEASE
-4b93f26c85540a41eeef07e1116770e47b78e104 FIREFOX_57_0b9_BUILD1
-4b93f26c85540a41eeef07e1116770e47b78e104 FIREFOX_57_0b9_RELEASE
-4b93f26c85540a41eeef07e1116770e47b78e104 FENNEC_57_0b9_BUILD1
-4b93f26c85540a41eeef07e1116770e47b78e104 FENNEC_57_0b9_RELEASE
-f3271256298ddeea6b13dcd64a26e3943b38aacf FIREFOX_57_0b10_BUILD1
-f3271256298ddeea6b13dcd64a26e3943b38aacf FIREFOX_57_0b10_RELEASE
-86534d5daeef8066928eef910d6d5c60442b24b0 FIREFOX_57_0b11_BUILD1
-86534d5daeef8066928eef910d6d5c60442b24b0 FIREFOX_57_0b11_RELEASE
-86534d5daeef8066928eef910d6d5c60442b24b0 FENNEC_57_0b11_BUILD1
-86534d5daeef8066928eef910d6d5c60442b24b0 FENNEC_57_0b11_RELEASE
-013f57c8692e2da5d49288d77a78aa20db9dca24 FIREFOX_57_0b12_BUILD2
-013f57c8692e2da5d49288d77a78aa20db9dca24 FIREFOX_57_0b12_RELEASE
-aa8f74f0ad60ab35955e539ac8e1164fe00a7fd1 FIREFOX_57_0b13_BUILD1
-aa8f74f0ad60ab35955e539ac8e1164fe00a7fd1 FIREFOX_57_0b13_RELEASE
-aa8f74f0ad60ab35955e539ac8e1164fe00a7fd1 FENNEC_57_0b13_BUILD1
-aa8f74f0ad60ab35955e539ac8e1164fe00a7fd1 FENNEC_57_0b13_RELEASE
-14581cf06e7fb0556dffebed82fe81b21e1fc68d FIREFOX_RELEASE_57_BASE
-d4134557db7c4aee5dd836efe4dfee7716ebc47e FIREFOX_RELEASE_56_END
-9f12a9fab080f2d363d7424e25b9ffe85ebc3414 FIREFOX_AURORA_28_BASE
 f7e9777221a34f9f23c2e4933307eb38b621b679 FIREFOX_NIGHTLY_57_END
 40a14ca1cf04499f398e4cb8ba359b39eae4e216 FIREFOX_BETA_58_BASE
-b7c372f8a26c510c30a0e49b89801508cb2116dc FIREFOX_BETA_57_END
-8c3926699de4b2f03f13a93d3750deb445b64396 FIREFOX_57_0b14_BUILD1
-8c3926699de4b2f03f13a93d3750deb445b64396 FIREFOX_57_0b14_RELEASE
-1c336e874ae849a9f0b6d12bb2858c4af5120779 FIREFOX_58_0b1_BUILD1
-1c336e874ae849a9f0b6d12bb2858c4af5120779 FIREFOX_58_0b1_RELEASE
-a1bcab123f4c5690514f85c01d108d940262040d FIREFOX_58_0b2_BUILD1
-a1bcab123f4c5690514f85c01d108d940262040d FIREFOX_58_0b2_RELEASE
-fbb14e4523d13bd065521479fabfe320f8a7ba5f FENNEC_58_0b3_BUILD1
-fbb14e4523d13bd065521479fabfe320f8a7ba5f FENNEC_58_0b3_RELEASE
-fbb14e4523d13bd065521479fabfe320f8a7ba5f FENNEC_58_0b3_BUILD4
-fbb14e4523d13bd065521479fabfe320f8a7ba5f FENNEC_58_0b3_RELEASE
-fbb14e4523d13bd065521479fabfe320f8a7ba5f FENNEC_58_0b3_RELEASE
-03402f586daaea0c5dbc80c281d262db9c9de430 FIREFOX_58_0b4_RELEASE
-03402f586daaea0c5dbc80c281d262db9c9de430 FIREFOX_58_0b4_BUILD1
-b2dca24b1741e6089c7fc1080493e2e230b52cb3 FENNEC_58_0b5_BUILD2
-b2dca24b1741e6089c7fc1080493e2e230b52cb3 FENNEC_58_0b5_RELEASE
-f155e109bb419696beb422b5afbfd7299b2b2500 FIREFOX_58_0b5_BUILD1
-f155e109bb419696beb422b5afbfd7299b2b2500 FIREFOX_58_0b5_RELEASE
-a38e0adbe442be2030b6a4b23c66365a10e1afbd FIREFOX_58_0b6_BUILD1
-a38e0adbe442be2030b6a4b23c66365a10e1afbd FIREFOX_58_0b6_RELEASE
-e8f054b3ac68557779e8e483ac7e118882ee6d9f FIREFOX_58_0b7_BUILD1
-e8f054b3ac68557779e8e483ac7e118882ee6d9f FIREFOX_58_0b7_RELEASE
-e8f054b3ac68557779e8e483ac7e118882ee6d9f FENNEC_58_0b7_BUILD1
-e8f054b3ac68557779e8e483ac7e118882ee6d9f FENNEC_58_0b7_RELEASE
-27dc691eb4a0e52b7da1d69f6b6dcf8bfbaef759 FIREFOX_58_0b8_BUILD1
-27dc691eb4a0e52b7da1d69f6b6dcf8bfbaef759 FIREFOX_58_0b8_RELEASE
-671706994162518e80a4b9f8125ff8e8c1bc3b1f FENNEC_58_0b9_BUILD1
-671706994162518e80a4b9f8125ff8e8c1bc3b1f FENNEC_58_0b9_RELEASE
-671706994162518e80a4b9f8125ff8e8c1bc3b1f FIREFOX_58_0b9_BUILD1
-671706994162518e80a4b9f8125ff8e8c1bc3b1f FIREFOX_58_0b9_RELEASE
-4fba9ec9d4ba8b3a224984f68b3358a85ed60ca6 FIREFOX_58_0b10_BUILD1
-4fba9ec9d4ba8b3a224984f68b3358a85ed60ca6 FIREFOX_58_0b10_RELEASE
-d7ddb4b0dc03cb110b8936c89465ca5e08ea71be FENNEC_58_0b11_BUILD1
-d7ddb4b0dc03cb110b8936c89465ca5e08ea71be FENNEC_58_0b11_RELEASE
-d7ddb4b0dc03cb110b8936c89465ca5e08ea71be FIREFOX_58_0b11_BUILD1
-d7ddb4b0dc03cb110b8936c89465ca5e08ea71be FIREFOX_58_0b11_RELEASE
-a59d9203232dce3e42ba3aba74cf52915fb9ce61 FIREFOX_58_0b12_BUILD1
-a59d9203232dce3e42ba3aba74cf52915fb9ce61 FIREFOX_58_0b12_RELEASE
-a59d9203232dce3e42ba3aba74cf52915fb9ce61 FENNEC_58_0b12_BUILD1
-a59d9203232dce3e42ba3aba74cf52915fb9ce61 FENNEC_58_0b12_RELEASE
-cb9a0bfe28ea476c6299d7684dab4b6f2a0b4e0f FIREFOX_58_0b13_BUILD1
-cb9a0bfe28ea476c6299d7684dab4b6f2a0b4e0f FIREFOX_58_0b13_RELEASE
-26b83e9df2019cf9c62b0db6c70edba642de51ac FIREFOX_58_0b14_BUILD2
-26b83e9df2019cf9c62b0db6c70edba642de51ac FIREFOX_58_0b14_RELEASE
-26b83e9df2019cf9c62b0db6c70edba642de51ac FENNEC_58_0b14_BUILD2
-26b83e9df2019cf9c62b0db6c70edba642de51ac FENNEC_58_0b14_RELEASE
-60e4ebb5f15082a790d840a4dc51514252ce3fab FIREFOX_58_0b15_BUILD1
-60e4ebb5f15082a790d840a4dc51514252ce3fab FIREFOX_58_0b15_RELEASE
-8bb8f895a740ba60d587337e920f30ec3000c4ca FIREFOX_RELEASE_58_BASE
+1f91961bb79ad06fd4caef9e5dfd546afd5bf42c FIREFOX_NIGHTLY_58_END
+c4e4613dbe32bb218957a140e5d0bd4fe7d1e98c FIREFOX_BETA_59_BASE
--- a/.taskcluster.yml
+++ b/.taskcluster.yml
@@ -53,24 +53,22 @@ tasks:
 
       routes:
         $if: 'tasks_for == "hg-push"'
         then:
           - "index.gecko.v2.${repository.project}.latest.firefox.decision"
           - "index.gecko.v2.${repository.project}.revision.${push.revision}.firefox.decision"
           - "index.gecko.v2.${repository.project}.pushlog-id.${push.pushlog_id}.decision"
           - "tc-treeherder.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
-          - "tc-treeherder-stage.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
           - "notify.email.${ownerEmail}.on-failed"
           - "notify.email.${ownerEmail}.on-exception"
         else:
           - "tc-treeherder.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
-          - "tc-treeherder-stage.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
           - $if: 'tasks_for == "action"'
-            then: "index.gecko.v2.${repository.project}.pushlog-id.${push.pushlog_id}.actions.$ownTaskId"
+            then: "index.gecko.v2.${repository.project}.pushlog-id.${push.pushlog_id}.actions.${ownTaskId}"
             else: "index.gecko.v2.${repository.project}.latest.firefox.decision-${cron.job_name}"
 
       scopes:
         $if: 'tasks_for == "hg-push"'
         then:
           - 'assume:repo:${repoUrl[8:]}:*'
           - 'queue:route:notify.email.${ownerEmail}.*'
         else:
@@ -182,8 +180,9 @@ tasks:
               parent: '${action.taskGroupId}'
               action:
                 name: '${action.name}'
                 context:
                   taskGroupId: '${action.taskGroupId}'
                   taskId: {$eval: 'taskId'}
                   input: {$eval: 'input'}
                   parameters: {$eval: 'parameters'}
+          - tasks_for: '${tasks_for}'
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -1,152 +1,186 @@
 {
     // See https://go.microsoft.com/fwlink/?LinkId=733558
     // for the documentation about the tasks.json format
     "version": "2.0.0",
+    "command": "${workspaceRoot}/mach",
     "windows": {
       "command": "\"\\mozilla-build\\start-shell.bat mach\""
     },
-    "osx": {
-      "command": "${workspaceRoot}/mach"
-    },
-    "linux": {
-      "command": "${workspaceRoot}/mach"
-    },
-    "isShellCommand": true,
     "args": ["--log-no-times"],
-    "showOutput": "silent",
     "echoCommand": true,
-    "suppressTaskName": false,
     "tasks": [
       {
-        "taskName": "clobber"
+        "label": "clobber-python",
+        "type":"shell",
+        "command": "${workspaceRoot}/mach",
+        "windows": {
+          "command": "\"\\mozilla-build\\start-shell.bat mach\""
+        },
+        "args": ["clobber", "python"],
+        "problemMatcher": []
       },
       {
-        "taskName": "clobber-python",
-        "suppressTaskName": true,
-        "args": ["clobber", "python"]
+        "label": "configure",
+        "type":"shell",
+        "problemMatcher": []
       },
       {
-        "taskName": "configure"
-      },
-      {
-        "taskName": "build",
-        "isBuildCommand": true,
+        "label": "build",
+        "type":"shell",
         "problemMatcher": {
           "owner": "cpp",
           "fileLocation": "absolute",
           "pattern": {
-            "regexp": "^.*?tools([^\\s]*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
+            "regexp": "^.*?([^\\s]*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
             "file": 1,
             "line": 2,
             "column": 3,
             "severity": 4,
             "message": 5
           }
         }
       },
       {
-        "taskName": "build-binaries",
-        "suppressTaskName": true,
-        "args": ["build", "binaries"],
+        "label": "build-binaries",
+        "type":"shell",
+        "command": "${workspaceRoot}/mach",
+        "windows": {
+          "command": "\"\\mozilla-build\\start-shell.bat mach\""
+        },
+        "args": ["--log-no-times", "build", "binaries"],
+        "problemMatcher": {
+          "owner": "cpp",
+          "fileLocation": "absolute",
+          "pattern": {
+            "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
+            "file": 1,
+            "line": 2,
+            "column": 3,
+            "severity": 4,
+            "message": 5
+          }
+        },
+        "group": {
+            "kind": "build",
+            "isDefault": true
+        }
+      },
+      {
+        "label": "build-faster",
+        "type":"shell",
+        "command": "${workspaceRoot}/mach",
+        "windows": {
+          "command": "\"\\mozilla-build\\start-shell.bat mach\""
+        },
+        "args": ["--log-no-times", "build", "faster"],
         "problemMatcher": {
           "owner": "cpp",
           "fileLocation": "absolute",
           "pattern": {
             "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
             "file": 1,
             "line": 2,
             "column": 3,
             "severity": 4,
             "message": 5
           }
         }
       },
       {
-        "taskName": "build-faster",
-        "suppressTaskName": true,
-        "args": ["build", "faster"],
-        "problemMatcher": {
-          "owner": "cpp",
-          "fileLocation": "absolute",
-          "pattern": {
-            "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
-            "file": 1,
-            "line": 2,
-            "column": 3,
-            "severity": 4,
-            "message": 5
-          }
-        }
+        "label": "run",
+        "type":"shell",
+        "args": ["-purgecaches"],
+        "problemMatcher": []
       },
       {
-        "taskName": "run",
-        "args": ["-purgecaches"],
-        "showOutput": "always"
-      },
-      {
-        "taskName": "lint-wo",
-        "suppressTaskName": true,
+        "label": "lint-wo",
+        "type":"shell",
+        "command": "${workspaceRoot}/mach",
+        "windows": {
+          "command": "\"\\mozilla-build\\start-shell.bat mach\""
+        },
         "args": ["lint", "-wo"],
         "problemMatcher": ["$eslint-stylish"]
       },
       {
-        "taskName": "eslint",
+        "label": "eslint",
+        "type": "shell",
         "problemMatcher": ["$eslint-stylish"]
       },
       {
-        "taskName": "eslint-fix",
-        "suppressTaskName": true,
+        "label": "eslint-fix",
+        "type":"shell",
+        "command": "${workspaceRoot}/mach",
+        "windows": {
+          "command": "\"\\mozilla-build\\start-shell.bat mach\""
+        },
         "args": ["eslint", "--fix", "${file}"],
         "problemMatcher": ["$eslint-stylish"]
       },
       {
-        "taskName": "test",
+        "label": "test",
+        "type":"shell",
         "args": ["${relativeFile}"],
-        "isTestCommand": true,
-        "showOutput": "always"
+        "group":"test",
+        "presentation": {
+            "reveal": "always",
+            "panel": "new"
+        }
       },
       {
-        "taskName": "mochitest",
+        "label": "mochitest",
+        "type":"shell",
         "args": ["${relativeFile}"],
-        "showOutput": "always",
         "problemMatcher": {
           "fileLocation": ["relative", "${workspaceRoot}"],
           "pattern": {
               "regexp": "^.*\\s+(TEST-UNEXPECTED-FAIL|TEST-UNEXPECTED-PASS)\\s+\\|\\s+([^\\s]*)\\s+\\|\\s+(.*)$",
               "severity": 1,
               "file": 2,
               "message": 3
           }
+        },
+        "presentation": {
+            "reveal": "always",
+            "panel": "new"
         }
       },
       {
-        "taskName": "reftest",
+        "label": "reftest",
+        "type":"shell",
         "args": ["${relativeFile}"],
-        "showOutput": "always",
         "problemMatcher": {
           "fileLocation": ["absolute"],
           "pattern": {
               "regexp": "^.*\\s+(TEST-UNEXPECTED-FAIL|TEST-UNEXPECTED-PASS)\\s+\\|\\s+file:\/\/([^\\s]*)\\s+==\\s+[^\\s]*\\s+\\|\\s+(.*)$",
               "severity": 1,
               "file": 2,
               "message": 3
           }
+        },
+        "presentation": {
+            "reveal": "always",
+            "panel": "new"
         }
       },
       {
-        "taskName": "xpcshell-test",
+        "label": "xpcshell-test",
+        "type":"shell",
         "args": ["${relativeFile}", "--sequential"],
-        "showOutput": "always",
         "problemMatcher": {
           "fileLocation": ["relative", "${workspaceRoot}"],
           "pattern": {
               "regexp": "^.*\\s+(FAIL|ERROR)\\s+\\[([^\\s]*)\\s+:\\s+(\\d+)\\]\\s+(.*)$",
               "severity": 1,
               "file": 2,
               "location": 3,
               "message": 4
           }
+        },
+        "presentation": {
+              "reveal": "always",
+              "panel": "new"
         }
       }
     ]
 }
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-bug 1368868 - if PSM xpcshell tests have been run locally, these changes will break the tests without a clobber (see bug 1416332)
+Bug 1416465 - Old track files may cause problems if they have wildcards.
--- a/Makefile.in
+++ b/Makefile.in
@@ -298,20 +298,18 @@ symbolsarchive: prepsymbolsarchive
 ifdef MOZ_CRASHREPORTER
 buildsymbols: symbolsfullarchive symbolsarchive
 else
 buildsymbols:
 endif
 
 uploadsymbols:
 ifdef MOZ_CRASHREPORTER
-ifdef SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE
 	$(PYTHON) -u $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.py '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
 endif
-endif
 
 .PHONY: update-packaging
 update-packaging:
 	$(MAKE) -C tools/update-packaging
 
 .PHONY: package-generated-sources
 package-generated-sources:
 	$(call py_action,package_generated_sources,'$(DIST)/$(PKG_PATH)$(GENERATED_SOURCE_FILE_PACKAGE)')
--- a/accessible/.eslintrc.js
+++ b/accessible/.eslintrc.js
@@ -4,14 +4,13 @@ module.exports = {
   "rules": {
     // Warn about cyclomatic complexity in functions.
     "complexity": ["error", 42],
 
     // XXX These are rules that are enabled in the recommended configuration, but
     // disabled here due to failures when initially implemented. They should be
     // removed (and hence enabled) at some stage.
     "consistent-return": "off",
-    "object-shorthand": "off",
     "no-unexpected-multiline": "off",
     "no-unsafe-finally": "off",
     "no-useless-call": "off",
   }
 };
--- a/accessible/aom/AccessibleNode.cpp
+++ b/accessible/aom/AccessibleNode.cpp
@@ -25,18 +25,22 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(AccessibleNode)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode)
 
 AccessibleNode::AccessibleNode(nsINode* aNode) : mDOMNode(aNode)
 {
-  DocAccessible* doc =
-    GetOrCreateAccService()->GetDocAccessible(mDOMNode->OwnerDoc());
+  nsAccessibilityService* accService = GetOrCreateAccService();
+  if (!accService) {
+    return;
+  }
+
+  DocAccessible* doc = accService->GetDocAccessible(mDOMNode->OwnerDoc());
   if (doc) {
     mIntl = doc->GetAccessible(mDOMNode);
   }
 }
 
 AccessibleNode::~AccessibleNode()
 {
 }
@@ -52,35 +56,42 @@ AccessibleNode::GetParentObject() const
 {
   return mDOMNode->GetParentObject();
 }
 
 void
 AccessibleNode::GetRole(nsAString& aRole)
 {
   if (mIntl) {
-    GetOrCreateAccService()->GetStringRole(mIntl->Role(), aRole);
-    return;
+    nsAccessibilityService* accService = GetOrCreateAccService();
+    if (accService) {
+      accService->GetStringRole(mIntl->Role(), aRole);
+      return;
+    }
   }
 
   aRole.AssignLiteral("unknown");
 }
 
 void
 AccessibleNode::GetStates(nsTArray<nsString>& aStates)
 {
-  if (mIntl) {
-    if (!mStates) {
-      mStates = GetOrCreateAccService()->GetStringStates(mIntl->State());
-    }
+  nsAccessibilityService* accService = GetOrCreateAccService();
+  if (!mIntl || !accService) {
+    aStates.AppendElement(NS_LITERAL_STRING("defunct"));
+    return;
+  }
+
+  if (mStates) {
     aStates = mStates->StringArray();
     return;
   }
 
-  aStates.AppendElement(NS_LITERAL_STRING("defunct"));
+  mStates = accService->GetStringStates(mIntl->State());
+  aStates = mStates->StringArray();
 }
 
 void
 AccessibleNode::GetAttributes(nsTArray<nsString>& aAttributes)
 {
   if (!mIntl) {
     return;
   }
@@ -101,30 +112,31 @@ AccessibleNode::GetAttributes(nsTArray<n
     prop->GetKey(attr);
     aAttributes.AppendElement(NS_ConvertUTF8toUTF16(attr));
   }
 }
 
 bool
 AccessibleNode::Is(const Sequence<nsString>& aFlavors)
 {
-  if (!mIntl) {
+  nsAccessibilityService* accService = GetOrCreateAccService();
+  if (!mIntl || !accService) {
     for (const auto& flavor : aFlavors) {
       if (!flavor.EqualsLiteral("unknown") && !flavor.EqualsLiteral("defunct")) {
         return false;
       }
     }
     return true;
   }
 
   nsAutoString role;
-  GetOrCreateAccService()->GetStringRole(mIntl->Role(), role);
+  accService->GetStringRole(mIntl->Role(), role);
 
   if (!mStates) {
-    mStates = GetOrCreateAccService()->GetStringStates(mIntl->State());
+    mStates = accService->GetStringStates(mIntl->State());
   }
 
   for (const auto& flavor : aFlavors) {
     if (!flavor.Equals(role) && !mStates->Contains(flavor)) {
       return false;
     }
   }
   return true;
--- a/accessible/atk/moz.build
+++ b/accessible/atk/moz.build
@@ -49,15 +49,15 @@ if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']
     CFLAGS += CONFIG['TK_CFLAGS']
     CXXFLAGS += CONFIG['TK_CFLAGS']
 
 if CONFIG['MOZ_ENABLE_DBUS']:
     CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS']
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
-if CONFIG['CLANG_CXX'] or CONFIG['GNU_CXX']:
+if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     # Used in G_DEFINE_TYPE_EXTENDED macro, probably fixed in newer glib /
     # gobject headers. See bug 1243331 comment 3.
     CXXFLAGS += [
         '-Wno-error=shadow',
         '-Wno-unused-local-typedefs',
     ]
--- a/accessible/base/ARIAMap.cpp
+++ b/accessible/base/ARIAMap.cpp
@@ -1370,51 +1370,53 @@ aria::AttrCharacteristicsFor(nsAtom* aAt
   return 0;
 }
 
 bool
 aria::HasDefinedARIAHidden(nsIContent* aContent)
 {
   return aContent &&
     nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_hidden) &&
-    !aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_hidden,
-                           nsGkAtoms::_false, eCaseMatters);
+    !aContent->AsElement()->AttrValueIs(kNameSpaceID_None,
+                                        nsGkAtoms::aria_hidden,
+                                        nsGkAtoms::_false,
+                                        eCaseMatters);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // AttrIterator class
 
 bool
 AttrIterator::Next(nsAString& aAttrName, nsAString& aAttrValue)
 {
   while (mAttrIdx < mAttrCount) {
-    const nsAttrName* attr = mContent->GetAttrNameAt(mAttrIdx);
+    const nsAttrName* attr = mElement->GetAttrNameAt(mAttrIdx);
     mAttrIdx++;
     if (attr->NamespaceEquals(kNameSpaceID_None)) {
       nsAtom* attrAtom = attr->Atom();
       nsDependentAtomString attrStr(attrAtom);
       if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
         continue; // Not ARIA
 
       uint8_t attrFlags = aria::AttrCharacteristicsFor(attrAtom);
       if (attrFlags & ATTR_BYPASSOBJ)
         continue; // No need to handle exposing as obj attribute here
 
       if ((attrFlags & ATTR_VALTOKEN) &&
-           !nsAccUtils::HasDefinedARIAToken(mContent, attrAtom))
+           !nsAccUtils::HasDefinedARIAToken(mElement, attrAtom))
         continue; // only expose token based attributes if they are defined
 
       if ((attrFlags & ATTR_BYPASSOBJ_IF_FALSE) &&
-          mContent->AttrValueIs(kNameSpaceID_None, attrAtom,
+          mElement->AttrValueIs(kNameSpaceID_None, attrAtom,
                                 nsGkAtoms::_false, eCaseMatters)) {
         continue; // only expose token based attribute if value is not 'false'.
       }
 
       nsAutoString value;
-      if (mContent->GetAttr(kNameSpaceID_None, attrAtom, value)) {
+      if (mElement->GetAttr(kNameSpaceID_None, attrAtom, value)) {
         aAttrName.Assign(Substring(attrStr, 5));
         aAttrValue.Assign(value);
         return true;
       }
     }
   }
 
   return false;
--- a/accessible/base/ARIAMap.h
+++ b/accessible/base/ARIAMap.h
@@ -9,16 +9,17 @@
 #define mozilla_a11y_aria_ARIAMap_h_
 
 #include "ARIAStateMap.h"
 #include "mozilla/a11y/AccTypes.h"
 #include "mozilla/a11y/Role.h"
 
 #include "nsAtom.h"
 #include "nsIContent.h"
+#include "mozilla/dom/Element.h"
 
 class nsINode;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Value constants
 
 /**
  * Used to define if role requires to expose Value interface.
@@ -283,30 +284,31 @@ bool HasDefinedARIAHidden(nsIContent* aC
 
  /**
   * Represents a simple enumerator for iterating through ARIA attributes
   * exposed as object attributes on a given accessible.
   */
 class AttrIterator
 {
 public:
-  explicit AttrIterator(nsIContent* aContent) :
-    mContent(aContent), mAttrIdx(0)
+  explicit AttrIterator(nsIContent* aContent)
+    : mElement(aContent->IsElement() ? aContent->AsElement() : nullptr)
+    , mAttrIdx(0)
   {
-    mAttrCount = mContent->GetAttrCount();
+    mAttrCount = mElement ? mElement->GetAttrCount() : 0;
   }
 
   bool Next(nsAString& aAttrName, nsAString& aAttrValue);
 
 private:
   AttrIterator() = delete;
   AttrIterator(const AttrIterator&) = delete;
   AttrIterator& operator= (const AttrIterator&) = delete;
 
-  nsIContent* mContent;
+  dom::Element* mElement;
   uint32_t mAttrIdx;
   uint32_t mAttrCount;
 };
 
 } // namespace aria
 } // namespace a11y
 } // namespace mozilla
 
--- a/accessible/base/ARIAStateMap.cpp
+++ b/accessible/base/ARIAStateMap.cpp
@@ -18,17 +18,17 @@ using namespace mozilla::a11y::aria;
  * Used to store state map rule data for ARIA attribute of enum type.
  */
 struct EnumTypeData
 {
   // ARIA attribute name.
   nsStaticAtom* const mAttrName;
 
   // States if the attribute value is matched to the enum value. Used as
-  // nsIContent::AttrValuesArray, last item must be nullptr.
+  // Element::AttrValuesArray, last item must be nullptr.
   nsStaticAtom* const* const mValues[4];
 
   // States applied if corresponding enum values are matched.
   const uint64_t mStates[3];
 
   // States to clear in case of match.
   const uint64_t mClearState;
 };
--- a/accessible/base/AccIterator.cpp
+++ b/accessible/base/AccIterator.cpp
@@ -80,17 +80,18 @@ RelatedAccIterator::
   mDocument(aDocument), mRelAttr(aRelAttr), mProviders(nullptr),
   mBindingParent(nullptr), mIndex(0)
 {
   mBindingParent = aDependentContent->GetBindingParent();
   nsAtom* IDAttr = mBindingParent ?
     nsGkAtoms::anonid : nsGkAtoms::id;
 
   nsAutoString id;
-  if (aDependentContent->GetAttr(kNameSpaceID_None, IDAttr, id))
+  if (aDependentContent->IsElement() &&
+      aDependentContent->AsElement()->GetAttr(kNameSpaceID_None, IDAttr, id))
     mProviders = mDocument->mDependentIDsHash.Get(id);
 }
 
 Accessible*
 RelatedAccIterator::Next()
 {
   if (!mProviders)
     return nullptr;
@@ -160,17 +161,17 @@ HTMLLabelIterator::Next()
 
   // Go up tree to get a name of ancestor label if there is one (an ancestor
   // <label> implicitly points to us). Don't go up farther than form or
   // document.
   Accessible* walkUp = mAcc->Parent();
   while (walkUp && !walkUp->IsDoc()) {
     nsIContent* walkUpEl = walkUp->GetContent();
     if (IsLabel(walkUp) &&
-        !walkUpEl->HasAttr(kNameSpaceID_None, nsGkAtoms::_for)) {
+        !walkUpEl->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::_for)) {
       mLabelFilter = eSkipAncestorLabel; // prevent infinite loop
       return walkUp;
     }
 
     if (walkUpEl->IsHTMLElement(nsGkAtoms::form))
       break;
 
     walkUp = walkUp->Parent();
@@ -252,18 +253,18 @@ XULDescriptionIterator::Next()
 // IDRefsIterator
 ////////////////////////////////////////////////////////////////////////////////
 
 IDRefsIterator::
   IDRefsIterator(DocAccessible* aDoc, nsIContent* aContent,
                  nsAtom* aIDRefsAttr) :
   mContent(aContent), mDoc(aDoc), mCurrIdx(0)
 {
-  if (mContent->IsInUncomposedDoc())
-    mContent->GetAttr(kNameSpaceID_None, aIDRefsAttr, mIDs);
+  if (mContent->IsInUncomposedDoc() && mContent->IsElement())
+    mContent->AsElement()->GetAttr(kNameSpaceID_None, aIDRefsAttr, mIDs);
 }
 
 const nsDependentSubstring
 IDRefsIterator::NextID()
 {
   for (; mCurrIdx < mIDs.Length(); mCurrIdx++) {
     if (!NS_IsAsciiWhitespace(mIDs[mCurrIdx]))
       break;
--- a/accessible/base/Logging.cpp
+++ b/accessible/base/Logging.cpp
@@ -753,17 +753,17 @@ logging::MsgBegin(const char* aTitle, co
   va_start(argptr, aMsgText);
   vprintf(aMsgText, argptr);
   va_end(argptr);
 
   PRIntervalTime time = PR_IntervalNow();
   uint32_t mins = (PR_IntervalToSeconds(time) / 60) % 60;
   uint32_t secs = PR_IntervalToSeconds(time) % 60;
   uint32_t msecs = PR_IntervalToMilliseconds(time) % 1000;
-  printf("; %02d:%02d.%03d", mins, secs, msecs);
+  printf("; %02u:%02u.%03u", mins, secs, msecs);
 
   printf("\n  {\n");
 }
 
 void
 logging::MsgEnd()
 {
   printf("  }\n");
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -414,33 +414,33 @@ NotificationController::ScheduleChildDoc
   ScheduleProcessing();
 }
 
 void
 NotificationController::ScheduleContentInsertion(Accessible* aContainer,
                                                  nsIContent* aStartChildNode,
                                                  nsIContent* aEndChildNode)
 {
-  nsTArray<nsCOMPtr<nsIContent>>* list =
-    mContentInsertions.LookupOrAdd(aContainer);
+  nsTArray<nsCOMPtr<nsIContent>> list;
 
   bool needsProcessing = false;
   nsIContent* node = aStartChildNode;
   while (node != aEndChildNode) {
     // Notification triggers for content insertion even if no content was
     // actually inserted, check if the given content has a frame to discard
     // this case early.
     if (node->GetPrimaryFrame()) {
-      if (list->AppendElement(node))
+      if (list.AppendElement(node))
         needsProcessing = true;
     }
     node = node->GetNextSibling();
   }
 
   if (needsProcessing) {
+    mContentInsertions.LookupOrAdd(aContainer)->AppendElements(list);
     ScheduleProcessing();
   }
 }
 
 void
 NotificationController::ScheduleProcessing()
 {
   // If notification flush isn't planed yet start notification flush
@@ -454,21 +454,41 @@ NotificationController::ScheduleProcessi
 ////////////////////////////////////////////////////////////////////////////////
 // NotificationCollector: protected
 
 bool
 NotificationController::IsUpdatePending()
 {
   return mPresShell->IsLayoutFlushObserver() ||
     mObservingState == eRefreshProcessingForUpdate ||
+    WaitingForParent() ||
     mContentInsertions.Count() != 0 || mNotifications.Length() != 0 ||
     mTextHash.Count() != 0 ||
     !mDocument->HasLoadState(DocAccessible::eTreeConstructed);
 }
 
+bool
+NotificationController::WaitingForParent()
+{
+  DocAccessible* parentdoc = mDocument->ParentDocument();
+  if (!parentdoc) {
+    return false;
+  }
+
+  NotificationController* parent = parentdoc->mNotificationController;
+  if (!parent || parent == this) {
+    // Do not wait for nothing or ourselves
+    return false;
+  }
+
+  // Wait for parent's notifications processing
+  return parent->mContentInsertions.Count() != 0 ||
+         parent->mNotifications.Length() != 0;
+}
+
 void
 NotificationController::ProcessMutationEvents()
 {
   // there is no reason to fire a hide event for a child of a show event
   // target.  That can happen if something is inserted into the tree and
   // removed before the next refresh driver tick, but it should not be
   // observable outside gecko so it should be safe to coalesce away any such
   // events.  This means that it should be fine to fire all of the hide events
@@ -587,16 +607,18 @@ NotificationController::ProcessMutationE
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // NotificationCollector: private
 
 void
 NotificationController::WillRefresh(mozilla::TimeStamp aTime)
 {
+  Telemetry::AutoTimer<Telemetry::A11Y_TREE_UPDATE_TIMING_MS> timer;
+
   AUTO_PROFILER_LABEL("NotificationController::WillRefresh", OTHER);
 
   // If the document accessible that notification collector was created for is
   // now shut down, don't process notifications anymore.
   NS_ASSERTION(mDocument,
                "The document was shut down while refresh observer is attached!");
   if (!mDocument)
     return;
@@ -604,16 +626,25 @@ NotificationController::WillRefresh(mozi
   // Wait until an update, we have started, or an interruptible reflow is
   // finished.
   if (mObservingState == eRefreshProcessing ||
       mObservingState == eRefreshProcessingForUpdate ||
       mPresShell->IsReflowInterrupted()) {
     return;
   }
 
+  // Process parent's notifications before ours, to get proper ordering between
+  // e.g. tab event and content event.
+  if (WaitingForParent()) {
+    mDocument->ParentDocument()->mNotificationController->WillRefresh(aTime);
+    if (!mDocument) {
+      return;
+    }
+  }
+
   // Any generic notifications should be queued if we're processing content
   // insertions or generic notifications.
   mObservingState = eRefreshProcessingForUpdate;
 
   // Initial accessible tree construction.
   if (!mDocument->HasLoadState(DocAccessible::eTreeConstructed)) {
     // If document is not bound to parent at this point then the document is not
     // ready yet (process notifications later).
@@ -641,29 +672,30 @@ NotificationController::WillRefresh(mozi
     mDocument->AddScrollListener();
 
   // Process rendered text change notifications.
   for (auto iter = mTextHash.Iter(); !iter.Done(); iter.Next()) {
     nsCOMPtrHashKey<nsIContent>* entry = iter.Get();
     nsIContent* textNode = entry->GetKey();
     Accessible* textAcc = mDocument->GetAccessible(textNode);
 
-    // If the text node is not in tree or doesn't have frame then this case should
-    // have been handled already by content removal notifications.
-    nsINode* containerNode = textNode->GetParentNode();
-    if (!containerNode) {
-      NS_ASSERTION(!textAcc,
-                   "Text node was removed but accessible is kept alive!");
+    // If the text node is not in tree or doesn't have a frame, or placed in
+    // another document, then this case should have been handled already by
+    // content removal notifications.
+    nsINode* containerNode = textNode->GetFlattenedTreeParentNode();
+    if (!containerNode || textNode->OwnerDoc() != mDocument->DocumentNode()) {
+      MOZ_ASSERT(!textAcc,
+                 "Text node was removed but accessible is kept alive!");
       continue;
     }
 
     nsIFrame* textFrame = textNode->GetPrimaryFrame();
     if (!textFrame) {
-      NS_ASSERTION(!textAcc,
-                   "Text node isn't rendered but accessible is kept alive!");
+      MOZ_ASSERT(!textAcc,
+                 "Text node isn't rendered but accessible is kept alive!");
       continue;
     }
 
   #ifdef A11Y_LOG
     nsIContent* containerElm = containerNode->IsElement() ?
       containerNode->AsElement() : nullptr;
   #endif
 
--- a/accessible/base/NotificationController.h
+++ b/accessible/base/NotificationController.h
@@ -269,16 +269,22 @@ protected:
   nsCycleCollectingAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
 
   /**
    * Return true if the accessible tree state update is pending.
    */
   bool IsUpdatePending();
 
+  /**
+   * Return true if we should wait for processing from the parent before we can
+   * process our own queue.
+   */
+  bool WaitingForParent();
+
 private:
   NotificationController(const NotificationController&);
   NotificationController& operator = (const NotificationController&);
 
   // nsARefreshObserver
   virtual void WillRefresh(mozilla::TimeStamp aTime) override;
 
   /**
--- a/accessible/base/Platform.h
+++ b/accessible/base/Platform.h
@@ -47,18 +47,18 @@ bool ShouldA11yBeEnabled();
 /*
  * Do we have AccessibleHandler.dll registered.
  */
 bool IsHandlerRegistered();
 
 /*
  * Name of platform service that instantiated accessibility
  */
-void SetInstantiator(const nsAString& aInstantiator);
-bool GetInstantiator(nsAString& aInstantiator);
+void SetInstantiator(const uint32_t aInstantiatorPid);
+bool GetInstantiator(nsIFile** aOutInstantiator);
 #endif
 
 /**
  * Called to initialize platform specific accessibility support.
  * Note this is called after internal accessibility support is initialized.
  */
 void PlatformInit();
 
--- a/accessible/base/RoleMap.h
+++ b/accessible/base/RoleMap.h
@@ -858,17 +858,17 @@ ROLE(DOCUMENT_FRAME,
      eNoNameRule)
 
 ROLE(HEADING,
      "heading",
      ATK_ROLE_HEADING,
      @"AXHeading",
      USE_ROLE_STRING,
      IA2_ROLE_HEADING,
-     eNameFromSubtreeIfReqRule)
+     eNameFromSubtreeRule)
 
 ROLE(PAGE,
      "page",
      ATK_ROLE_PAGE,
      NSAccessibilityGroupRole,
      USE_ROLE_STRING,
      IA2_ROLE_PAGE,
      eNoNameRule)
--- a/accessible/base/TextAttrs.cpp
+++ b/accessible/base/TextAttrs.cpp
@@ -296,23 +296,23 @@ TextAttrsMgr::InvalidTextAttr::
 
 bool
 TextAttrsMgr::InvalidTextAttr::
   GetValue(nsIContent* aElm, uint32_t* aValue)
 {
   nsIContent* elm = aElm;
   do {
     if (nsAccUtils::HasDefinedARIAToken(elm, nsGkAtoms::aria_invalid)) {
-      static nsIContent::AttrValuesArray tokens[] =
+      static Element::AttrValuesArray tokens[] =
         { &nsGkAtoms::_false, &nsGkAtoms::grammar, &nsGkAtoms::spelling,
           nullptr };
 
-      int32_t idx = elm->FindAttrValueIn(kNameSpaceID_None,
-                                         nsGkAtoms::aria_invalid, tokens,
-                                         eCaseMatters);
+      int32_t idx = elm->AsElement()->FindAttrValueIn(kNameSpaceID_None,
+                                                      nsGkAtoms::aria_invalid,
+                                                      tokens, eCaseMatters);
       switch (idx) {
         case 0:
           *aValue = eFalse;
           return true;
         case 1:
           *aValue = eGrammar;
           return true;
         case 2:
--- a/accessible/base/TreeWalker.cpp
+++ b/accessible/base/TreeWalker.cpp
@@ -71,16 +71,18 @@ TreeWalker::~TreeWalker()
 
 Accessible*
 TreeWalker::Scope(nsIContent* aAnchorNode)
 {
   Reset();
 
   mAnchorNode = aAnchorNode;
 
+  mFlags |= eScoped;
+
   bool skipSubtree = false;
   Accessible* acc = AccessibleFor(aAnchorNode, 0, &skipSubtree);
   if (acc) {
     mPhase = eAtEnd;
     return acc;
   }
 
   return skipSubtree ? nullptr : Next();
@@ -107,16 +109,18 @@ TreeWalker::Seek(nsIContent* aChildNode)
 
     if (!parentNode || !parentNode->IsElement()) {
       return false;
     }
 
     // If ARIA owned child.
     Accessible* child = mDoc->GetAccessible(childNode);
     if (child && child->IsRelocated()) {
+      MOZ_ASSERT(!(mFlags & eScoped),
+        "Walker should not be scoped when seeking into relocated children");
       if (child->Parent() != mContext) {
         return false;
       }
 
       Accessible* ownedChild = nullptr;
       while ((ownedChild = mDoc->ARIAOwnedAt(mContext, mARIAOwnsIdx++)) &&
              ownedChild != child);
 
@@ -144,22 +148,26 @@ Accessible*
 TreeWalker::Next()
 {
   if (mStateStack.IsEmpty()) {
     if (mPhase == eAtEnd) {
       return nullptr;
     }
 
     if (mPhase == eAtDOM || mPhase == eAtARIAOwns) {
-      mPhase = eAtARIAOwns;
-      Accessible* child = mDoc->ARIAOwnedAt(mContext, mARIAOwnsIdx);
-      if (child) {
-        mARIAOwnsIdx++;
-        return child;
+      if (!(mFlags & eScoped)) {
+        mPhase = eAtARIAOwns;
+        Accessible* child = mDoc->ARIAOwnedAt(mContext, mARIAOwnsIdx);
+        if (child) {
+          mARIAOwnsIdx++;
+          return child;
+        }
       }
+      MOZ_ASSERT(!(mFlags & eScoped) || mPhase != eAtARIAOwns,
+        "Don't walk relocated children in scoped mode");
       mPhase = eAtEnd;
       return nullptr;
     }
 
     if (!mAnchorNode) {
       mPhase = eAtEnd;
       return nullptr;
     }
@@ -225,21 +233,27 @@ TreeWalker::Prev()
 {
   if (mStateStack.IsEmpty()) {
     if (mPhase == eAtStart || mPhase == eAtDOM) {
       mPhase = eAtStart;
       return nullptr;
     }
 
     if (mPhase == eAtEnd) {
-      mARIAOwnsIdx = mDoc->ARIAOwnedCount(mContext);
-      mPhase = eAtARIAOwns;
+      if (mFlags & eScoped) {
+        mPhase = eAtDOM;
+      } else {
+        mPhase = eAtARIAOwns;
+        mARIAOwnsIdx = mDoc->ARIAOwnedCount(mContext);
+      }
     }
 
     if (mPhase == eAtARIAOwns) {
+      MOZ_ASSERT(!(mFlags & eScoped),
+        "Should not walk relocated children in scoped mode");
       if (mARIAOwnsIdx > 0) {
         return mDoc->ARIAOwnedAt(mContext, --mARIAOwnsIdx);
       }
 
       if (!mAnchorNode) {
         mPhase = eAtStart;
         return nullptr;
       }
--- a/accessible/base/TreeWalker.h
+++ b/accessible/base/TreeWalker.h
@@ -24,17 +24,18 @@ class DocAccessible;
  */
 class TreeWalker final
 {
 public:
   enum {
     // used to walk the existing tree of the given node
     eWalkCache = 1,
     // used to walk the context tree starting from given node
-    eWalkContextTree = 2 | eWalkCache
+    eWalkContextTree = 2 | eWalkCache,
+    eScoped = 4
   };
 
   /**
    * Used to navigate and create if needed the accessible children.
    */
   explicit TreeWalker(Accessible* aContext);
 
   /**
--- a/accessible/base/XULMap.h
+++ b/accessible/base/XULMap.h
@@ -1,5 +1,7 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 XULMAP(image, New_MaybeImageOrToolbarButtonAccessible)
+XULMAP(statusbar, New_StatusBarAccessible)
+XULMAP(menuseparator, New_MenuSeparator)
--- a/accessible/base/moz.build
+++ b/accessible/base/moz.build
@@ -107,10 +107,10 @@ else:
     LOCAL_INCLUDES += [
         '/accessible/other',
     ]
 
 FINAL_LIBRARY = 'xul'
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
-if CONFIG['GNU_CXX']:
+if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += ['-Wno-error=shadow']
--- a/accessible/base/nsAccUtils.cpp
+++ b/accessible/base/nsAccUtils.cpp
@@ -136,83 +136,90 @@ nsAccUtils::SetLiveContainerAttributes(n
 {
   nsAutoString live, relevant, busy;
   nsIContent* ancestor = aStartContent;
   while (ancestor) {
 
     // container-relevant attribute
     if (relevant.IsEmpty() &&
         HasDefinedARIAToken(ancestor, nsGkAtoms::aria_relevant) &&
-        ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_relevant, relevant))
+        ancestor->AsElement()->GetAttr(kNameSpaceID_None,
+                                       nsGkAtoms::aria_relevant, relevant))
       SetAccAttr(aAttributes, nsGkAtoms::containerRelevant, relevant);
 
     // container-live, and container-live-role attributes
     if (live.IsEmpty()) {
       const nsRoleMapEntry* role = nullptr;
       if (ancestor->IsElement()) {
         role = aria::GetRoleMap(ancestor->AsElement());
       }
       if (HasDefinedARIAToken(ancestor, nsGkAtoms::aria_live)) {
-        ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_live, live);
+        ancestor->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_live, live);
       } else if (role) {
         GetLiveAttrValue(role->liveAttRule, live);
       }
       if (!live.IsEmpty()) {
         SetAccAttr(aAttributes, nsGkAtoms::containerLive, live);
         if (role) {
           SetAccAttr(aAttributes, nsGkAtoms::containerLiveRole,
                      role->ARIARoleString());
         }
       }
     }
 
     // container-atomic attribute
-    if (ancestor->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_atomic,
-                              nsGkAtoms::_true, eCaseMatters)) {
+    if (ancestor->IsElement() &&
+        ancestor->AsElement()->AttrValueIs(kNameSpaceID_None,
+                                           nsGkAtoms::aria_atomic,
+                                           nsGkAtoms::_true, eCaseMatters)) {
       SetAccAttr(aAttributes, nsGkAtoms::containerAtomic,
                  NS_LITERAL_STRING("true"));
     }
 
     // container-busy attribute
     if (busy.IsEmpty() &&
         HasDefinedARIAToken(ancestor, nsGkAtoms::aria_busy) &&
-        ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_busy, busy))
+        ancestor->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_busy, busy))
       SetAccAttr(aAttributes, nsGkAtoms::containerBusy, busy);
 
     if (ancestor == aTopEl)
       break;
 
     ancestor = ancestor->GetParent();
     if (!ancestor)
       ancestor = aTopEl; // Use <body>/<frameset>
   }
 }
 
 bool
 nsAccUtils::HasDefinedARIAToken(nsIContent *aContent, nsAtom *aAtom)
 {
   NS_ASSERTION(aContent, "aContent is null in call to HasDefinedARIAToken!");
 
-  if (!aContent->HasAttr(kNameSpaceID_None, aAtom) ||
-      aContent->AttrValueIs(kNameSpaceID_None, aAtom,
-                            nsGkAtoms::_empty, eCaseMatters) ||
-      aContent->AttrValueIs(kNameSpaceID_None, aAtom,
-                            nsGkAtoms::_undefined, eCaseMatters)) {
+  if (!aContent->IsElement())
+    return false;
+
+  Element* element = aContent->AsElement();
+  if (!element->HasAttr(kNameSpaceID_None, aAtom) ||
+      element->AttrValueIs(kNameSpaceID_None, aAtom, nsGkAtoms::_empty,
+                           eCaseMatters) ||
+      element->AttrValueIs(kNameSpaceID_None, aAtom, nsGkAtoms::_undefined,
+                           eCaseMatters)) {
         return false;
   }
   return true;
 }
 
 nsAtom*
 nsAccUtils::GetARIAToken(dom::Element* aElement, nsAtom* aAttr)
 {
   if (!HasDefinedARIAToken(aElement, aAttr))
     return nsGkAtoms::_empty;
 
-  static nsIContent::AttrValuesArray tokens[] =
+  static Element::AttrValuesArray tokens[] =
     { &nsGkAtoms::_false, &nsGkAtoms::_true,
       &nsGkAtoms::mixed, nullptr};
 
   int32_t idx = aElement->FindAttrValueIn(kNameSpaceID_None,
                                           aAttr, tokens, eCaseMatters);
   if (idx >= 0)
     return *(tokens[idx]);
 
@@ -234,17 +241,19 @@ nsAccUtils::GetSelectableContainer(Acces
       return nullptr;
   }
   return parent;
 }
 
 bool
 nsAccUtils::IsARIASelected(Accessible* aAccessible)
 {
-  return aAccessible->GetContent()->
+  if (!aAccessible->GetContent()->IsElement())
+    return false;
+  return aAccessible->GetContent()->AsElement()->
     AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_selected,
                 nsGkAtoms::_true, eCaseMatters);
 }
 
 Accessible*
 nsAccUtils::TableFor(Accessible* aRow)
 {
   if (aRow) {
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -48,20 +48,17 @@
 #include "HTMLWin32ObjectAccessible.h"
 #include "mozilla/StaticPtr.h"
 #endif
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
-#ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
-#endif
-
 #include "nsImageFrame.h"
 #include "nsINamed.h"
 #include "nsIObserverService.h"
 #include "nsLayoutUtils.h"
 #include "nsPluginFrame.h"
 #include "SVGGeometryFrame.h"
 #include "nsTreeBodyFrame.h"
 #include "nsTreeColumns.h"
@@ -112,30 +109,32 @@ using namespace mozilla::dom;
  * Return true if the element must be accessible.
  */
 static bool
 MustBeAccessible(nsIContent* aContent, DocAccessible* aDocument)
 {
   if (aContent->GetPrimaryFrame()->IsFocusable())
     return true;
 
-  uint32_t attrCount = aContent->GetAttrCount();
-  for (uint32_t attrIdx = 0; attrIdx < attrCount; attrIdx++) {
-    const nsAttrName* attr = aContent->GetAttrNameAt(attrIdx);
-    if (attr->NamespaceEquals(kNameSpaceID_None)) {
-      nsAtom* attrAtom = attr->Atom();
-      nsDependentAtomString attrStr(attrAtom);
-      if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
-        continue; // not ARIA
+  if (aContent->IsElement()) {
+    uint32_t attrCount = aContent->AsElement()->GetAttrCount();
+    for (uint32_t attrIdx = 0; attrIdx < attrCount; attrIdx++) {
+      const nsAttrName* attr = aContent->AsElement()->GetAttrNameAt(attrIdx);
+      if (attr->NamespaceEquals(kNameSpaceID_None)) {
+        nsAtom* attrAtom = attr->Atom();
+        nsDependentAtomString attrStr(attrAtom);
+        if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
+          continue; // not ARIA
 
-      // A global state or a property and in case of token defined.
-      uint8_t attrFlags = aria::AttrCharacteristicsFor(attrAtom);
-      if ((attrFlags & ATTR_GLOBAL) && (!(attrFlags & ATTR_VALTOKEN) ||
-           nsAccUtils::HasDefinedARIAToken(aContent, attrAtom))) {
-        return true;
+        // A global state or a property and in case of token defined.
+        uint8_t attrFlags = aria::AttrCharacteristicsFor(attrAtom);
+        if ((attrFlags & ATTR_GLOBAL) && (!(attrFlags & ATTR_VALTOKEN) ||
+             nsAccUtils::HasDefinedARIAToken(aContent, attrAtom))) {
+          return true;
+        }
       }
     }
   }
 
   // If the given ID is referred by relation attribute then create an accessible
   // for it.
   nsAutoString id;
   if (nsCoreUtils::GetID(aContent, id) && !id.IsEmpty())
@@ -205,24 +204,37 @@ New_HTMLDefinition(nsIContent* aContent,
   return nullptr;
 }
 
 static Accessible* New_HTMLLabel(nsIContent* aContent, Accessible* aContext)
   { return new HTMLLabelAccessible(aContent, aContext->Document()); }
 
 static Accessible* New_HTMLInput(nsIContent* aContent, Accessible* aContext)
 {
-  if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                            nsGkAtoms::checkbox, eIgnoreCase)) {
+  if (!aContent->IsElement()) {
+    return nullptr;
+  }
+
+  Element* element = aContent->AsElement();
+  if (element->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                           nsGkAtoms::checkbox, eIgnoreCase)) {
     return new HTMLCheckboxAccessible(aContent, aContext->Document());
   }
-  if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                            nsGkAtoms::radio, eIgnoreCase)) {
+  if (element->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                           nsGkAtoms::radio, eIgnoreCase)) {
     return new HTMLRadioButtonAccessible(aContent, aContext->Document());
   }
+  if (element->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                           nsGkAtoms::time, eIgnoreCase)) {
+    return new EnumRoleAccessible<roles::GROUPING>(aContent, aContext->Document());
+  }
+  if (element->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                           nsGkAtoms::date, eIgnoreCase)) {
+    return new EnumRoleAccessible<roles::DATE_EDITOR>(aContent, aContext->Document());
+  }
   return nullptr;
 }
 
 static Accessible* New_HTMLOutput(nsIContent* aContent, Accessible* aContext)
   { return new HTMLOutputAccessible(aContent, aContext->Document()); }
 
 static Accessible* New_HTMLProgress(nsIContent* aContent, Accessible* aContext)
   { return new HTMLProgressMeterAccessible(aContent, aContext->Document()); }
@@ -249,37 +261,47 @@ New_HTMLTableHeaderCell(nsIContent* aCon
     return new HTMLTableHeaderCellAccessibleWrap(aContent, aContext->Document());
   return nullptr;
 }
 
 static Accessible*
 New_HTMLTableHeaderCellIfScope(nsIContent* aContent, Accessible* aContext)
 {
   if (aContext->IsTableRow() && aContext->GetContent() == aContent->GetParent() &&
-      aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::scope))
+      aContent->IsElement() &&
+      aContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::scope))
     return new HTMLTableHeaderCellAccessibleWrap(aContent, aContext->Document());
   return nullptr;
 }
 
 #ifdef MOZ_XUL
 static Accessible*
 New_MaybeImageOrToolbarButtonAccessible(nsIContent* aContent,
                                         Accessible* aContext)
 {
-  if (aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::onclick)) {
+  if (aContent->IsElement() &&
+      aContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::onclick)) {
     return new XULToolbarButtonAccessible(aContent, aContext->Document());
   }
 
   // Don't include nameless images in accessible tree.
-  if (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext)) {
+  if (!aContent->IsElement() ||
+      !aContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext)) {
     return nullptr;
   }
 
   return new ImageAccessibleWrap(aContent, aContext->Document());
 }
+static Accessible*
+New_MenuSeparator(nsIContent* aContent, Accessible* aContext)
+  { return new XULMenuSeparatorAccessible(aContent, aContext->Document()); }
+
+static Accessible*
+New_StatusBarAccessible(nsIContent* aContent, Accessible* aContext)
+  { return new XULStatusBarAccessible(aContent, aContext->Document()); }
 #endif
 
 /**
  * Cached value of the PREF_ACCESSIBILITY_FORCE_DISABLED preference.
  */
 static int32_t sPlatformDisabledState = 0;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1364,21 +1386,19 @@ nsAccessibilityService::Init()
 #else
     gApplicationAccessible = new ApplicationAccessible();
 #endif // defined(XP_WIN)
   }
 
   NS_ADDREF(gApplicationAccessible); // will release in Shutdown()
   gApplicationAccessible->Init();
 
-#ifdef MOZ_CRASHREPORTER
   CrashReporter::
     AnnotateCrashReport(NS_LITERAL_CSTRING("Accessibility"),
                         NS_LITERAL_CSTRING("Active"));
-#endif
 
 #ifdef XP_WIN
   sPendingPlugins = new nsTArray<nsCOMPtr<nsIContent> >;
   sPluginTimers = new nsTArray<nsCOMPtr<nsITimer> >;
 #endif
 
   // Now its safe to start platform accessibility.
   if (XRE_IsParentProcess())
@@ -1530,35 +1550,31 @@ nsAccessibilityService::CreateAccessible
     // then strip out redundant accessibles in the AccessibleWrap class for each platform.
     nsIContent *parent = aContent->GetParent();
     if (parent && parent->IsXULElement(nsGkAtoms::menu))
       return nullptr;
 #endif
 
     accessible = new XULMenupopupAccessible(aContent, aDoc);
 
-  } else if(role.EqualsLiteral("xul:menuseparator")) {
-    accessible = new XULMenuSeparatorAccessible(aContent, aDoc);
-
   } else if(role.EqualsLiteral("xul:pane")) {
     accessible = new EnumRoleAccessible<roles::PANE>(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:panel")) {
-    if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::noautofocus,
-                              nsGkAtoms::_true, eCaseMatters))
+    if (aContent->IsElement() &&
+        aContent->AsElement()->AttrValueIs(kNameSpaceID_None,
+                                           nsGkAtoms::noautofocus,
+                                           nsGkAtoms::_true, eCaseMatters))
       accessible = new XULAlertAccessible(aContent, aDoc);
     else
       accessible = new EnumRoleAccessible<roles::PANE>(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:progressmeter")) {
     accessible = new XULProgressMeterAccessible(aContent, aDoc);
 
-  } else if (role.EqualsLiteral("xul:statusbar")) {
-    accessible = new XULStatusBarAccessible(aContent, aDoc);
-
   } else if (role.EqualsLiteral("xul:scale")) {
     accessible = new XULSliderAccessible(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:radiobutton")) {
     accessible = new XULRadioButtonAccessible(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:radiogroup")) {
     accessible = new XULRadioGroupAccessible(aContent, aDoc);
@@ -1754,25 +1770,32 @@ nsAccessibilityService::MarkupAttributes
 
   for (uint32_t i = 0; i < ArrayLength(markupMap->attrs); i++) {
     const MarkupAttrInfo* info = markupMap->attrs + i;
     if (!info->name)
       break;
 
     if (info->DOMAttrName) {
       if (info->DOMAttrValue) {
-        if (aContent->AttrValueIs(kNameSpaceID_None, *info->DOMAttrName,
-                                  *info->DOMAttrValue, eCaseMatters)) {
+        if (aContent->IsElement() &&
+            aContent->AsElement()->AttrValueIs(kNameSpaceID_None,
+                                               *info->DOMAttrName,
+                                               *info->DOMAttrValue,
+                                               eCaseMatters)) {
           nsAccUtils::SetAccAttr(aAttributes, *info->name, *info->DOMAttrValue);
         }
         continue;
       }
 
       nsAutoString value;
-      aContent->GetAttr(kNameSpaceID_None, *info->DOMAttrName, value);
+
+      if (aContent->IsElement()) {
+        aContent->AsElement()->GetAttr(kNameSpaceID_None, *info->DOMAttrName, value);
+      }
+
       if (!value.IsEmpty())
         nsAccUtils::SetAccAttr(aAttributes, *info->name, value);
 
       continue;
     }
 
     nsAccUtils::SetAccAttr(aAttributes, *info->name, *info->value);
   }
@@ -1872,39 +1895,52 @@ nsAccessibilityService::UnsetConsumers(u
     return;
   }
 
   gConsumers &= ~aConsumers;
   NotifyOfConsumersChange();
 }
 
 void
+nsAccessibilityService::GetConsumers(nsAString& aString)
+{
+  const char16_t* kJSONFmt =
+    u"{ \"XPCOM\": %s, \"MainProcess\": %s, \"PlatformAPI\": %s }";
+  nsString json;
+  nsTextFormatter::ssprintf(json, kJSONFmt,
+    gConsumers & eXPCOM ? "true" : "false",
+    gConsumers & eMainProcess ? "true" : "false",
+    gConsumers & ePlatformAPI ? "true" : "false");
+  aString.Assign(json);
+}
+
+void
 nsAccessibilityService::NotifyOfConsumersChange()
 {
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
 
   if (!observerService) {
     return;
   }
 
-  const char16_t* kJSONFmt =
-    u"{ \"XPCOM\": %s, \"MainProcess\": %s, \"PlatformAPI\": %s }";
-  nsString json;
-  nsTextFormatter::ssprintf(json, kJSONFmt,
-    gConsumers & eXPCOM ? "true" : "false",
-    gConsumers & eMainProcess ? "true" : "false",
-    gConsumers & ePlatformAPI ? "true" : "false");
+  nsAutoString consumers;
+  GetConsumers(consumers);
   observerService->NotifyObservers(
-    nullptr, "a11y-consumers-changed", json.get());
+    nullptr, "a11y-consumers-changed", consumers.get());
 }
 
 nsAccessibilityService*
 GetOrCreateAccService(uint32_t aNewConsumer)
 {
+  // Do not initialize accessibility if it is force disabled.
+  if (PlatformDisabledState() == ePlatformIsDisabled) {
+    return nullptr;
+  }
+
   if (!nsAccessibilityService::gAccessibilityService) {
     RefPtr<nsAccessibilityService> service = new nsAccessibilityService();
     if (!service->Init()) {
       service->Shutdown();
       return nullptr;
     }
   }
 
--- a/accessible/base/nsAccessibilityService.h
+++ b/accessible/base/nsAccessibilityService.h
@@ -305,16 +305,21 @@ private:
                                 Accessible* aContext);
 
   /**
    * Notify observers about change of the accessibility service's consumers.
    */
   void NotifyOfConsumersChange();
 
   /**
+   * Get a JSON string representing the accessibility service consumers.
+   */
+  void GetConsumers(nsAString& aString);
+
+  /**
    * Set accessibility service consumers.
    */
   void SetConsumers(uint32_t aConsumers);
 
   /**
    * Unset accessibility service consumers.
    */
   void UnsetConsumers(uint32_t aConsumers);
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -179,32 +179,33 @@ nsCoreUtils::DispatchTouchEvent(EventMes
 }
 
 uint32_t
 nsCoreUtils::GetAccessKeyFor(nsIContent* aContent)
 {
   // Accesskeys are registered by @accesskey attribute only. At first check
   // whether it is presented on the given element to avoid the slow
   // EventStateManager::GetRegisteredAccessKey() method.
-  if (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::accesskey))
+  if (!aContent->IsElement() ||
+      !aContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::accesskey))
     return 0;
 
   nsIPresShell* presShell = aContent->OwnerDoc()->GetShell();
   if (!presShell)
     return 0;
 
   nsPresContext *presContext = presShell->GetPresContext();
   if (!presContext)
     return 0;
 
   EventStateManager *esm = presContext->EventStateManager();
   if (!esm)
     return 0;
 
-  return esm->GetRegisteredAccessKey(aContent);
+  return esm->GetRegisteredAccessKey(aContent->AsElement());
 }
 
 nsIContent *
 nsCoreUtils::GetDOMElementFor(nsIContent *aContent)
 {
   if (aContent->IsElement())
     return aContent;
 
@@ -220,17 +221,17 @@ nsCoreUtils::GetDOMNodeFromDOMPoint(nsIN
   if (aNode && aNode->IsElement()) {
     uint32_t childCount = aNode->GetChildCount();
     NS_ASSERTION(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)
-      return aNode->GetChildAt(aOffset);
+      return aNode->GetChildAt_Deprecated(aOffset);
   }
 
   return aNode;
 }
 
 bool
 nsCoreUtils::IsAncestorOf(nsINode *aPossibleAncestorNode,
                           nsINode *aPossibleDescendantNode,
@@ -450,24 +451,28 @@ nsCoreUtils::IsErrorPage(nsIDocument *aD
   NS_NAMED_LITERAL_CSTRING(certerror, "certerror");
 
   return StringBeginsWith(path, neterror) || StringBeginsWith(path, certerror);
 }
 
 bool
 nsCoreUtils::GetID(nsIContent *aContent, nsAString& aID)
 {
-  return aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, aID);
+  return aContent->IsElement() &&
+    aContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::id, aID);
 }
 
 bool
 nsCoreUtils::GetUIntAttr(nsIContent *aContent, nsAtom *aAttr, int32_t *aUInt)
 {
   nsAutoString value;
-  aContent->GetAttr(kNameSpaceID_None, aAttr, value);
+  if (!aContent->IsElement()) {
+    return false;
+  }
+  aContent->AsElement()->GetAttr(kNameSpaceID_None, aAttr, value);
   if (!value.IsEmpty()) {
     nsresult error = NS_OK;
     int32_t integer = value.ToInteger(&error);
     if (NS_SUCCEEDED(error) && integer > 0) {
       *aUInt = integer;
       return true;
     }
   }
@@ -478,17 +483,18 @@ nsCoreUtils::GetUIntAttr(nsIContent *aCo
 void
 nsCoreUtils::GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
                             nsAString& aLanguage)
 {
   aLanguage.Truncate();
 
   nsIContent *walkUp = aContent;
   while (walkUp && walkUp != aRootContent &&
-         !walkUp->GetAttr(kNameSpaceID_None, nsGkAtoms::lang, aLanguage))
+         (!walkUp->IsElement() ||
+          !walkUp->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::lang, aLanguage)))
     walkUp = walkUp->GetParent();
 }
 
 already_AddRefed<nsIBoxObject>
 nsCoreUtils::GetTreeBodyBoxObject(nsITreeBoxObject *aTreeBoxObj)
 {
   nsCOMPtr<nsIDOMElement> tcElm;
   aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
@@ -612,17 +618,17 @@ nsCoreUtils::GetPreviousSensibleColumn(n
   return prevColumn.forget();
 }
 
 bool
 nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
 {
   nsCOMPtr<nsIDOMElement> element;
   aColumn->GetElement(getter_AddRefs(element));
-  nsCOMPtr<nsIContent> content = do_QueryInterface(element);
+  nsCOMPtr<Element> content = do_QueryInterface(element);
   return content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
                               nsGkAtoms::_true, eCaseMatters);
 }
 
 void
 nsCoreUtils::ScrollTo(nsIPresShell* aPresShell, nsIContent* aContent,
                       uint32_t aScrollType)
 {
@@ -672,14 +678,14 @@ nsCoreUtils::DispatchAccEvent(RefPtr<nsI
   obsService->NotifyObservers(event, NS_ACCESSIBLE_EVENT_TOPIC, nullptr);
 }
 
 void
 nsCoreUtils::XBLBindingRole(const nsIContent* aEl, nsAString& aRole)
 {
   for (const nsXBLBinding* binding = aEl->GetXBLBinding(); binding;
        binding = binding->GetBaseBinding()) {
-    nsIContent* bindingElm = binding->PrototypeBinding()->GetBindingElement();
+    Element* bindingElm = binding->PrototypeBinding()->GetBindingElement();
     bindingElm->GetAttr(kNameSpaceID_None, nsGkAtoms::role, aRole);
     if (!aRole.IsEmpty())
       break;
   }
 }
--- a/accessible/base/nsCoreUtils.h
+++ b/accessible/base/nsCoreUtils.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsCoreUtils_h_
 #define nsCoreUtils_h_
 
 #include "mozilla/EventForwards.h"
+#include "mozilla/dom/Element.h"
 #include "nsIAccessibleEvent.h"
 #include "nsIContent.h"
 #include "nsIDocument.h" // for GetShell()
 #include "nsIPresShell.h"
 
 #include "nsPoint.h"
 #include "nsTArray.h"
 
@@ -286,17 +287,18 @@ public:
                        uint32_t aScrollType);
 
   /**
    * Return true if the given node is table header element.
    */
   static bool IsHTMLTableHeader(nsIContent *aContent)
   {
     return aContent->NodeInfo()->Equals(nsGkAtoms::th) ||
-      aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::scope);
+      (aContent->IsElement() &&
+       aContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::scope));
   }
 
   /**
    * Returns true if the given string is empty or contains whitespace symbols
    * only. In contrast to nsWhitespaceTokenizer class it takes into account
    * non-breaking space (0xa0).
    */
   static bool IsWhitespaceString(const nsAString& aString);
--- a/accessible/base/nsTextEquivUtils.cpp
+++ b/accessible/base/nsTextEquivUtils.cpp
@@ -308,22 +308,22 @@ nsTextEquivUtils::AppendFromDOMNode(nsIC
     nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl =
       do_QueryInterface(aContent);
 
     if (labeledEl) {
       labeledEl->GetLabel(textEquivalent);
     } else {
       if (aContent->NodeInfo()->Equals(nsGkAtoms::label,
                                        kNameSpaceID_XUL))
-        aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value,
-                          textEquivalent);
+        aContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value,
+                                       textEquivalent);
 
       if (textEquivalent.IsEmpty())
-        aContent->GetAttr(kNameSpaceID_None,
-                          nsGkAtoms::tooltiptext, textEquivalent);
+        aContent->AsElement()->GetAttr(kNameSpaceID_None,
+                                       nsGkAtoms::tooltiptext, textEquivalent);
     }
 
     AppendString(aString, textEquivalent);
   }
 
   return AppendFromDOMChildren(aContent, aString);
 }
 
--- a/accessible/generic/ARIAGridAccessible.cpp
+++ b/accessible/generic/ARIAGridAccessible.cpp
@@ -460,26 +460,28 @@ ARIAGridAccessible::GetCellInRowAt(Acces
 
 nsresult
 ARIAGridAccessible::SetARIASelected(Accessible* aAccessible,
                                     bool aIsSelected, bool aNotify)
 {
   if (IsARIARole(nsGkAtoms::table))
     return NS_OK;
 
-  nsIContent *content = aAccessible->GetContent();
+  nsIContent* content = aAccessible->GetContent();
   NS_ENSURE_STATE(content);
 
   nsresult rv = NS_OK;
-  if (aIsSelected)
-    rv = content->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
-                          NS_LITERAL_STRING("true"), aNotify);
-  else
-    rv = content->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
-                          NS_LITERAL_STRING("false"), aNotify);
+  if (content->IsElement()) {
+    if (aIsSelected)
+      rv = content->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
+                                         NS_LITERAL_STRING("true"), aNotify);
+    else
+      rv = content->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
+                                         NS_LITERAL_STRING("false"), aNotify);
+  }
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // No "smart" select/unselect for internal call.
   if (!aNotify)
     return NS_OK;
 
   // If row or cell accessible was selected then we're able to not bother about
@@ -634,21 +636,20 @@ ARIAGridCellAccessible::ApplyARIAState(u
     return;
 
   // Check aria-selected="true" on the row.
   Accessible* row = Parent();
   if (!row || row->Role() != roles::ROW)
     return;
 
   nsIContent *rowContent = row->GetContent();
-  if (nsAccUtils::HasDefinedARIAToken(rowContent,
-                                      nsGkAtoms::aria_selected) &&
-      !rowContent->AttrValueIs(kNameSpaceID_None,
-                               nsGkAtoms::aria_selected,
-                               nsGkAtoms::_false, eCaseMatters))
+  if (nsAccUtils::HasDefinedARIAToken(rowContent, nsGkAtoms::aria_selected) &&
+      !rowContent->AsElement()->AttrValueIs(kNameSpaceID_None,
+                                            nsGkAtoms::aria_selected,
+                                            nsGkAtoms::_false, eCaseMatters))
     *aState |= states::SELECTABLE | states::SELECTED;
 }
 
 already_AddRefed<nsIPersistentProperties>
 ARIAGridCellAccessible::NativeAttributes()
 {
   nsCOMPtr<nsIPersistentProperties> attributes =
     HyperTextAccessibleWrap::NativeAttributes();
--- a/accessible/generic/Accessible-inl.h
+++ b/accessible/generic/Accessible-inl.h
@@ -71,18 +71,18 @@ Accessible::SetRoleMapEntry(const nsRole
 }
 
 inline bool
 Accessible::IsSearchbox() const
 {
   const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
   return (roleMapEntry && roleMapEntry->Is(nsGkAtoms::searchbox)) ||
     (mContent->IsHTMLElement(nsGkAtoms::input) &&
-     mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                           nsGkAtoms::search, eCaseMatters));
+     mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                                        nsGkAtoms::search, eCaseMatters));
 }
 
 inline bool
 Accessible::HasGenericType(AccGenericType aType) const
 {
   const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
   return (mGenericTypes & aType) ||
     (roleMapEntry && roleMapEntry->IsOfType(aType));
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -148,22 +148,22 @@ Accessible::Name(nsString& aName)
   }
 
   ENameValueFlag nameFlag = NativeName(aName);
   if (!aName.IsEmpty())
     return nameFlag;
 
   // In the end get the name from tooltip.
   if (mContent->IsHTMLElement()) {
-    if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName)) {
+    if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName)) {
       aName.CompressWhitespace();
       return eNameFromTooltip;
     }
   } else if (mContent->IsXULElement()) {
-    if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, aName)) {
+    if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, aName)) {
       aName.CompressWhitespace();
       return eNameFromTooltip;
     }
   } else if (mContent->IsSVGElement()) {
     // If user agents need to choose among multiple ‘desc’ or ‘title’ elements
     // for processing, the user agent shall choose the first one.
     for (nsIContent* childElm = mContent->GetFirstChild(); childElm;
          childElm = childElm->GetNextSibling()) {
@@ -197,19 +197,19 @@ Accessible::Description(nsString& aDescr
                            aDescription);
 
   if (aDescription.IsEmpty()) {
     NativeDescription(aDescription);
 
     if (aDescription.IsEmpty()) {
       // Keep the Name() method logic.
       if (mContent->IsHTMLElement()) {
-        mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aDescription);
+        mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aDescription);
       } else if (mContent->IsXULElement()) {
-        mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, aDescription);
+        mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, aDescription);
       } else if (mContent->IsSVGElement()) {
         for (nsIContent* childElm = mContent->GetFirstChild(); childElm;
              childElm = childElm->GetNextSibling()) {
           if (childElm->IsSVGElement(nsGkAtoms::desc)) {
             nsTextEquivUtils::AppendTextEquivFromContent(this, childElm,
                                                          &aDescription);
             break;
           }
@@ -446,17 +446,17 @@ Accessible::NativeState()
         else
           state |= states::HORIZONTAL;
       }
     }
   }
 
   // Check if a XUL element has the popup attribute (an attached popup menu).
   if (HasOwnContent() && mContent->IsXULElement() &&
-      mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popup))
+      mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::popup))
     state |= states::HASPOPUP;
 
   // Bypass the link states specialization for non links.
   const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
   if (!roleMapEntry || roleMapEntry->roleRule == kUseNativeRole ||
       roleMapEntry->role == roles::LINK)
     state |= NativeLinkState();
 
@@ -486,18 +486,19 @@ Accessible::NativeLinkState() const
 }
 
 bool
 Accessible::NativelyUnavailable() const
 {
   if (mContent->IsHTMLElement())
     return mContent->AsElement()->State().HasState(NS_EVENT_STATE_DISABLED);
 
-  return mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
-                               nsGkAtoms::_true, eCaseMatters);
+  return mContent->IsElement() &&
+    mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
+                                       nsGkAtoms::_true, eCaseMatters);
 }
 
 Accessible*
 Accessible::FocusedChild()
 {
   Accessible* focus = FocusMgr()->FocusedAccessible();
   if (focus && (focus == this || focus->Parent() == this))
     return focus;
@@ -699,22 +700,24 @@ void
 Accessible::SetSelected(bool aSelect)
 {
   if (!HasOwnContent())
     return;
 
   Accessible* select = nsAccUtils::GetSelectableContainer(this, State());
   if (select) {
     if (select->State() & states::MULTISELECTABLE) {
-      if (ARIARoleMap()) {
+      if (mContent->IsElement() && ARIARoleMap()) {
         if (aSelect) {
-          mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
-                            NS_LITERAL_STRING("true"), true);
+          mContent->AsElement()->SetAttr(kNameSpaceID_None,
+                                         nsGkAtoms::aria_selected,
+                                         NS_LITERAL_STRING("true"), true);
         } else {
-          mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected, true);
+          mContent->AsElement()->UnsetAttr(kNameSpaceID_None,
+                                           nsGkAtoms::aria_selected, true);
         }
       }
       return;
     }
 
     if (aSelect)
       TakeFocus();
   }
@@ -820,19 +823,20 @@ Accessible::XULElmName(DocAccessible* aD
 
   // Can get text from title of <toolbaritem> if we're a child of a <toolbaritem>
   nsIContent *bindingParent = aElm->GetBindingParent();
   nsIContent* parent =
     bindingParent? bindingParent->GetParent() : aElm->GetParent();
   nsAutoString ancestorTitle;
   while (parent) {
     if (parent->IsXULElement(nsGkAtoms::toolbaritem) &&
-        parent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, ancestorTitle)) {
+        parent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::title, ancestorTitle)) {
       // Before returning this, check if the element itself has a tooltip:
-      if (aElm->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, aName)) {
+      if (aElm->IsElement() &&
+          aElm->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, aName)) {
         aName.CompressWhitespace();
         return;
       }
 
       aName.Assign(ancestorTitle);
       aName.CompressWhitespace();
       return;
     }
@@ -937,17 +941,17 @@ Accessible::Attributes()
   // 'xml-roles' attribute for landmark.
   nsAtom* landmark = LandmarkRole();
   if (landmark) {
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles, landmark);
 
   } else {
     // 'xml-roles' attribute coming from ARIA.
     nsAutoString xmlRoles;
-    if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::role, xmlRoles))
+    if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::role, xmlRoles))
       nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles, xmlRoles);
   }
 
   // Expose object attributes from ARIA attributes.
   nsAutoString unused;
   aria::AttrIterator attribIter(mContent);
   nsAutoString name, value;
   while(attribIter.Next(name, value))
@@ -1058,17 +1062,17 @@ Accessible::NativeAttributes()
     return attributes.forget();
 
   nsAutoString id;
   if (nsCoreUtils::GetID(mContent, id))
     attributes->SetStringProperty(NS_LITERAL_CSTRING("id"), id, unused);
 
   // Expose class because it may have useful microformat information.
   nsAutoString _class;
-  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, _class))
+  if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, _class))
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::_class, _class);
 
   // Expose tag.
   nsAutoString tagName;
   mContent->NodeInfo()->GetName(tagName);
   nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tag, tagName);
 
   // Expose draggable object attribute.
@@ -1172,19 +1176,20 @@ Accessible::State()
   // Apply ARIA states to be sure accessible states will be overridden.
   ApplyARIAState(&state);
 
   // If this is an ARIA item of the selectable widget and if it's focused and
   // not marked unselected explicitly (i.e. aria-selected="false") then expose
   // it as selected to make ARIA widget authors life easier.
   const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
   if (roleMapEntry && !(state & states::SELECTED) &&
-      !mContent->AttrValueIs(kNameSpaceID_None,
-                             nsGkAtoms::aria_selected,
-                             nsGkAtoms::_false, eCaseMatters)) {
+      (!mContent->IsElement() ||
+       !mContent->AsElement()->AttrValueIs(kNameSpaceID_None,
+                                           nsGkAtoms::aria_selected,
+                                           nsGkAtoms::_false, eCaseMatters))) {
     // Special case for tabs: focused tab or focus inside related tab panel
     // implies selected state.
     if (roleMapEntry->role == roles::PAGETAB) {
       if (state & states::FOCUSED) {
         state |= states::SELECTED;
       } else {
         // If focus is in a child of the tab panel surely the tab is selected!
         Relation rel = RelationByType(RelationType::LABEL_FOR);
@@ -1332,20 +1337,24 @@ Accessible::Value(nsString& aValue)
   const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
   if (!roleMapEntry)
     return;
 
   if (roleMapEntry->valueRule != eNoValue) {
     // aria-valuenow is a number, and aria-valuetext is the optional text
     // equivalent. For the string value, we will try the optional text
     // equivalent first.
-    if (!mContent->GetAttr(kNameSpaceID_None,
-                           nsGkAtoms::aria_valuetext, aValue)) {
-      mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_valuenow,
-                        aValue);
+    if (!mContent->IsElement()) {
+      return;
+    }
+
+    if (!mContent->AsElement()->GetAttr(kNameSpaceID_None,
+                                        nsGkAtoms::aria_valuetext, aValue)) {
+      mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_valuenow,
+                                     aValue);
     }
     return;
   }
 
   // Value of textbox is a textified subtree.
   if (roleMapEntry->Is(nsGkAtoms::textbox)) {
     nsTextEquivUtils::GetTextEquivFromSubtree(this, aValue);
     return;
@@ -1411,18 +1420,22 @@ Accessible::SetCurValue(double aValue)
 
   checkValue = MaxValue();
   if (!IsNaN(checkValue) && aValue > checkValue)
     return false;
 
   nsAutoString strValue;
   strValue.AppendFloat(aValue);
 
+  if (!mContent->IsElement())
+    return true;
+
   return NS_SUCCEEDED(
-    mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_valuenow, strValue, true));
+    mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_valuenow,
+                                   strValue, true));
 }
 
 role
 Accessible::ARIATransformRole(role aRole)
 {
   // Beginning with ARIA 1.1, user agents are expected to use the native host
   // language role of the element when the region role is used without a name.
   // https://rawgit.com/w3c/aria/master/core-aam/core-aam.html#role-map-region
@@ -1443,20 +1456,21 @@ Accessible::ARIATransformRole(role aRole
   // where the accessible role depends on both the role and ARIA state.
   if (aRole == roles::PUSHBUTTON) {
     if (nsAccUtils::HasDefinedARIAToken(mContent, nsGkAtoms::aria_pressed)) {
       // For simplicity, any existing pressed attribute except "" or "undefined"
       // indicates a toggle.
       return roles::TOGGLE_BUTTON;
     }
 
-    if (mContent->AttrValueIs(kNameSpaceID_None,
-                              nsGkAtoms::aria_haspopup,
-                              nsGkAtoms::_true,
-                              eCaseMatters)) {
+    if (mContent->IsElement() &&
+        mContent->AsElement()->AttrValueIs(kNameSpaceID_None,
+                                           nsGkAtoms::aria_haspopup,
+                                           nsGkAtoms::_true,
+                                           eCaseMatters)) {
       // For button with aria-haspopup="true".
       return roles::BUTTONMENU;
     }
 
   } else if (aRole == roles::LISTBOX) {
     // A listbox inside of a combobox needs a special role because of ATK
     // mapping to menu.
     if (mParent && mParent->IsCombobox()) {
@@ -1471,18 +1485,19 @@ Accessible::ARIATransformRole(role aRole
     }
 
   } else if (aRole == roles::OPTION) {
     if (mParent && mParent->Role() == roles::COMBOBOX_LIST)
       return roles::COMBOBOX_OPTION;
 
   } else if (aRole == roles::MENUITEM) {
     // Menuitem has a submenu.
-    if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_haspopup,
-                              nsGkAtoms::_true, eCaseMatters)) {
+    if (mContent->IsElement() &&
+        mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_haspopup,
+                                           nsGkAtoms::_true, eCaseMatters)) {
       return roles::PARENT_MENUITEM;
     }
   }
 
   return aRole;
 }
 
 nsAtom*
@@ -1586,17 +1601,20 @@ Accessible::DoAction(uint8_t aIndex)
   return false;
 }
 
 nsIContent*
 Accessible::GetAtomicRegion() const
 {
   nsIContent *loopContent = mContent;
   nsAutoString atomic;
-  while (loopContent && !loopContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_atomic, atomic))
+  while (loopContent &&
+         (!loopContent->IsElement() ||
+          !loopContent->AsElement()->GetAttr(kNameSpaceID_None,
+                                             nsGkAtoms::aria_atomic, atomic)))
     loopContent = loopContent->GetParent();
 
   return atomic.EqualsLiteral("true") ? loopContent : nullptr;
 }
 
 Relation
 Accessible::RelationByType(RelationType aType)
 {
@@ -1976,17 +1994,19 @@ Accessible::ARIAName(nsString& aName)
   // aria-labelledby now takes precedence over aria-label
   nsresult rv = nsTextEquivUtils::
     GetTextEquivFromIDRefs(this, nsGkAtoms::aria_labelledby, aName);
   if (NS_SUCCEEDED(rv)) {
     aName.CompressWhitespace();
   }
 
   if (aName.IsEmpty() &&
-      mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_label, aName)) {
+      mContent->IsElement() &&
+      mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_label,
+                                     aName)) {
     aName.CompressWhitespace();
   }
 }
 
 // Accessible protected
 ENameValueFlag
 Accessible::NativeName(nsString& aName)
 {
@@ -2533,30 +2553,32 @@ Accessible::IsActiveWidget() const
 
   return false;
 }
 
 bool
 Accessible::AreItemsOperable() const
 {
   return HasOwnContent() &&
-    mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant);
+    mContent->IsElement() &&
+    mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant);
 }
 
 Accessible*
 Accessible::CurrentItem()
 {
   // Check for aria-activedescendant, which changes which element has focus.
   // For activedescendant, the ARIA spec does not require that the user agent
   // checks whether pointed node is actually a DOM descendant of the element
   // with the aria-activedescendant attribute.
   nsAutoString id;
   if (HasOwnContent() &&
-      mContent->GetAttr(kNameSpaceID_None,
-                        nsGkAtoms::aria_activedescendant, id)) {
+      mContent->IsElement() &&
+      mContent->AsElement()->GetAttr(kNameSpaceID_None,
+                                     nsGkAtoms::aria_activedescendant, id)) {
     nsIDocument* DOMDoc = mContent->OwnerDoc();
     dom::Element* activeDescendantElm = DOMDoc->GetElementById(id);
     if (activeDescendantElm) {
       DocAccessible* document = Document();
       if (document)
         return document->GetAccessible(activeDescendantElm);
     }
   }
@@ -2565,30 +2587,33 @@ Accessible::CurrentItem()
 
 void
 Accessible::SetCurrentItem(Accessible* aItem)
 {
   nsAtom* id = aItem->GetContent()->GetID();
   if (id) {
     nsAutoString idStr;
     id->ToString(idStr);
-    mContent->SetAttr(kNameSpaceID_None,
-                      nsGkAtoms::aria_activedescendant, idStr, true);
+    mContent->AsElement()->SetAttr(kNameSpaceID_None,
+                                   nsGkAtoms::aria_activedescendant,
+                                   idStr,
+                                   true);
   }
 }
 
 Accessible*
 Accessible::ContainerWidget() const
 {
   if (HasARIARole() && mContent->HasID()) {
     for (Accessible* parent = Parent(); parent; parent = parent->Parent()) {
       nsIContent* parentContent = parent->GetContent();
       if (parentContent &&
-        parentContent->HasAttr(kNameSpaceID_None,
-                               nsGkAtoms::aria_activedescendant)) {
+          parentContent->IsElement() &&
+          parentContent->AsElement()->HasAttr(kNameSpaceID_None,
+                                              nsGkAtoms::aria_activedescendant)) {
         return parent;
       }
 
       // Don't cross DOM document boundaries.
       if (parent->IsDoc())
         break;
     }
   }
@@ -2651,33 +2676,34 @@ Accessible::GetSiblingAtOffset(int32_t a
 double
 Accessible::AttrNumericValue(nsAtom* aAttr) const
 {
   const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
   if (!roleMapEntry || roleMapEntry->valueRule == eNoValue)
     return UnspecifiedNaN<double>();
 
   nsAutoString attrValue;
-  if (!mContent->GetAttr(kNameSpaceID_None, aAttr, attrValue))
+  if (!mContent->IsElement() ||
+      !mContent->AsElement()->GetAttr(kNameSpaceID_None, aAttr, attrValue))
     return UnspecifiedNaN<double>();
 
   nsresult error = NS_OK;
   double value = attrValue.ToDouble(&error);
   return NS_FAILED(error) ? UnspecifiedNaN<double>() : value;
 }
 
 uint32_t
 Accessible::GetActionRule() const
 {
   if (!HasOwnContent() || (InteractiveState() & states::UNAVAILABLE))
     return eNoAction;
 
   // Return "click" action on elements that have an attached popup menu.
   if (mContent->IsXULElement())
-    if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popup))
+    if (mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::popup))
       return eClickAction;
 
   // Has registered 'click' event handler.
   bool isOnclick = nsCoreUtils::HasClickListener(mContent);
 
   if (isOnclick)
     return eClickAction;
 
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -24,17 +24,16 @@
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIDOMAttr.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsPIDOMWindow.h"
-#include "nsIDOMXULPopupElement.h"
 #include "nsIEditingSession.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsImageFrame.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsViewManager.h"
@@ -871,17 +870,17 @@ DocAccessible::AttributeChangedImpl(Acce
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_describedby) {
     FireDelayedEvent(nsIAccessibleEvent::EVENT_DESCRIPTION_CHANGE, aAccessible);
     return;
   }
 
-  nsIContent* elm = aAccessible->GetContent();
+  dom::Element* elm = aAccessible->GetContent()->AsElement();
   if (aAttribute == nsGkAtoms::aria_labelledby &&
       !elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_label)) {
     FireDelayedEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, aAccessible);
     return;
   }
 
   if (aAttribute == nsGkAtoms::alt &&
       !elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_label) &&
@@ -992,17 +991,17 @@ DocAccessible::ARIAAttributeChanged(Acce
   // change event; at least until native API comes up with a more meaningful event.
   uint8_t attrFlags = aria::AttrCharacteristicsFor(aAttribute);
   if (!(attrFlags & ATTR_BYPASSOBJ)) {
     RefPtr<AccEvent> event =
       new AccObjectAttrChangedEvent(aAccessible, aAttribute);
     FireDelayedEvent(event);
   }
 
-  nsIContent* elm = aAccessible->GetContent();
+  dom::Element* elm = aAccessible->GetContent()->AsElement();
 
   // Update aria-hidden flag for the whole subtree iff aria-hidden is changed
   // on the root, i.e. ignore any affiliated aria-hidden changes in the subtree
   // of top aria-hidden.
   if (aAttribute == nsGkAtoms::aria_hidden) {
     bool isDefined = aria::HasDefinedARIAHidden(elm);
     if (isDefined != aAccessible->IsARIAHidden() &&
         (!aAccessible->Parent() || !aAccessible->Parent()->IsARIAHidden())) {
@@ -1068,19 +1067,21 @@ DocAccessible::ARIAAttributeChanged(Acce
     mNotificationController->ScheduleRelocation(aAccessible);
   }
 }
 
 void
 DocAccessible::ARIAActiveDescendantChanged(Accessible* aAccessible)
 {
   nsIContent* elm = aAccessible->GetContent();
-  if (elm && aAccessible->IsActiveWidget()) {
+  if (elm && elm->IsElement() && aAccessible->IsActiveWidget()) {
     nsAutoString id;
-    if (elm->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant, id)) {
+    if (elm->AsElement()->GetAttr(kNameSpaceID_None,
+                                  nsGkAtoms::aria_activedescendant,
+                                  id)) {
       dom::Element* activeDescendantElm = elm->OwnerDoc()->GetElementById(id);
       if (activeDescendantElm) {
         Accessible* activeDescendant = GetAccessible(activeDescendantElm);
         if (activeDescendant) {
           FocusMgr()->ActiveItemChanged(activeDescendant, false);
 #ifdef A11Y_LOG
           if (logging::IsEnabled(logging::eFocus))
             logging::ActiveItemChangeCausedBy("ARIA activedescedant changed",
@@ -1245,36 +1246,24 @@ DocAccessible::GetAccessibleByUniqueIDIn
 }
 
 Accessible*
 DocAccessible::GetAccessibleOrContainer(nsINode* aNode) const
 {
   if (!aNode || !aNode->GetComposedDoc())
     return nullptr;
 
-  nsINode* currNode = aNode;
-  Accessible* accessible = nullptr;
-  while (!(accessible = GetAccessible(currNode))) {
-    nsINode* parent = nullptr;
-
-    // If this is a content node, try to get a flattened parent content node.
-    // This will smartly skip from the shadow root to the host element,
-    // over parentless document fragment
-    if (currNode->IsContent())
-      parent = currNode->AsContent()->GetFlattenedTreeParent();
-
-    // Fallback to just get parent node, in case there is no parent content
-    // node. Or current node is not a content node.
-    if (!parent)
-      parent = currNode->GetParentNode();
-
-    if (!(currNode = parent)) break;
+  for (nsINode* currNode = aNode; currNode;
+       currNode = currNode->GetFlattenedTreeParentNode()) {
+    if (Accessible* accessible = GetAccessible(currNode)) {
+      return accessible;
+    }
   }
 
-  return accessible;
+  return nullptr;
 }
 
 Accessible*
 DocAccessible::GetAccessibleOrDescendant(nsINode* aNode) const
 {
   Accessible* acc = GetAccessible(aNode);
   if (acc)
     return acc;
@@ -1307,18 +1296,19 @@ DocAccessible::BindToDocument(Accessible
   // Put into unique ID cache.
   mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible);
 
   aAccessible->SetRoleMapEntry(aRoleMapEntry);
 
   if (aAccessible->HasOwnContent()) {
     AddDependentIDsFor(aAccessible);
 
-    nsIContent* el = aAccessible->GetContent();
-    if (el->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_owns)) {
+    nsIContent* content = aAccessible->GetContent();
+    if (content->IsElement() &&
+        content->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_owns)) {
       mNotificationController->ScheduleRelocation(aAccessible);
     }
   }
 }
 
 void
 DocAccessible::UnbindFromDocument(Accessible* aAccessible)
 {
@@ -1849,16 +1839,17 @@ InsertIterator::Next()
         return true;
       }
     }
     else {
       TreeWalker finder(container);
       if (finder.Seek(node)) {
         mChild = mWalker.Scope(node);
         if (mChild) {
+          MOZ_ASSERT(!mChild->IsRelocated(), "child cannot be aria owned");
           mChildBefore = finder.Prev();
           return true;
         }
       }
     }
   }
 
   return false;
@@ -2208,17 +2199,18 @@ DocAccessible::PutChildrenBack(nsTArray<
                       "old parent", owner, "child", child, nullptr);
 #endif
 
     // Unset relocated flag to find an insertion point for the child.
     child->SetRelocated(false);
 
     nsIContent* content = child->GetContent();
     int32_t idxInParent = -1;
-    Accessible* origContainer = AccessibleOrTrueContainer(content->GetParentNode());
+    Accessible* origContainer =
+      AccessibleOrTrueContainer(content->GetFlattenedTreeParentNode());
     if (origContainer) {
       TreeWalker walker(origContainer);
       if (walker.Seek(content)) {
         Accessible* prevChild = walker.Prev();
         if (prevChild) {
           idxInParent = prevChild->IndexInParent() + 1;
           MOZ_DIAGNOSTIC_ASSERT(origContainer == prevChild->Parent(), "Broken tree");
           origContainer = prevChild->Parent();
--- a/accessible/generic/FormControlAccessible.cpp
+++ b/accessible/generic/FormControlAccessible.cpp
@@ -35,17 +35,17 @@ ProgressMeterAccessible<Max>::NativeRole
 template<int Max>
 uint64_t
 ProgressMeterAccessible<Max>::NativeState()
 {
   uint64_t state = LeafAccessible::NativeState();
 
   // An undetermined progressbar (i.e. without a value) has a mixed state.
   nsAutoString attrValue;
-  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue);
+  mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue);
 
   if (attrValue.IsEmpty())
     state |= states::MIXED;
 
   return state;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -89,17 +89,17 @@ template<int Max>
 double
 ProgressMeterAccessible<Max>::MaxValue() const
 {
   double value = LeafAccessible::MaxValue();
   if (!IsNaN(value))
     return value;
 
   nsAutoString strValue;
-  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, strValue)) {
+  if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::max, strValue)) {
     nsresult result = NS_OK;
     value = strValue.ToDouble(&result);
     if (NS_SUCCEEDED(result))
       return value;
   }
 
   return Max;
 }
@@ -124,17 +124,17 @@ template<int Max>
 double
 ProgressMeterAccessible<Max>::CurValue() const
 {
   double value = LeafAccessible::CurValue();
   if (!IsNaN(value))
     return value;
 
   nsAutoString attrValue;
-  if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue))
+  if (!mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue))
     return UnspecifiedNaN<double>();
 
   nsresult error = NS_OK;
   value = attrValue.ToDouble(&error);
   return NS_FAILED(error) ? UnspecifiedNaN<double>() : value;
 }
 
 template<int Max>
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -237,17 +237,17 @@ HyperTextAccessible::DOMPointToOffset(ns
     // findNode could be null if aNodeOffset == # of child nodes, which means
     // one of two things:
     // 1) there are no children, and the passed-in node is not mContent -- use
     //    parentContent for the node to find
     // 2) there are no children and the passed-in node is mContent, which means
     //    we're an empty nsIAccessibleText
     // 3) there are children and we're at the end of the children
 
-    findNode = aNode->GetChildAt(aNodeOffset);
+    findNode = aNode->GetChildAt_Deprecated(aNodeOffset);
     if (!findNode) {
       if (aNodeOffset == 0) {
         if (aNode == GetNode()) {
           // Case #1: this accessible has no children and thus has empty text,
           // we can only be at hypertext offset 0.
           return 0;
         }
 
@@ -264,22 +264,21 @@ HyperTextAccessible::DOMPointToOffset(ns
     }
   }
 
   // Get accessible for this findNode, or if that node isn't accessible, use the
   // accessible for the next DOM node which has one (based on forward depth first search)
   Accessible* descendant = nullptr;
   if (findNode) {
     nsCOMPtr<nsIContent> findContent(do_QueryInterface(findNode));
-    if (findContent && findContent->IsHTMLElement() &&
-        findContent->NodeInfo()->Equals(nsGkAtoms::br) &&
-        findContent->AttrValueIs(kNameSpaceID_None,
-                                 nsGkAtoms::mozeditorbogusnode,
-                                 nsGkAtoms::_true,
-                                 eIgnoreCase)) {
+    if (findContent && findContent->IsHTMLElement(nsGkAtoms::br) &&
+        findContent->AsElement()->AttrValueIs(kNameSpaceID_None,
+                                              nsGkAtoms::mozeditorbogusnode,
+                                              nsGkAtoms::_true,
+                                              eIgnoreCase)) {
       // This <br> is the hacky "bogus node" used when there is no text in a control
       return 0;
     }
 
     descendant = mDoc->GetAccessible(findNode);
     if (!descendant && findNode->IsContent()) {
       Accessible* container = mDoc->GetContainerAccessible(findNode);
       if (container) {
@@ -1847,30 +1846,31 @@ HyperTextAccessible::RangeAtPoint(int32_
 
 // Accessible protected
 ENameValueFlag
 HyperTextAccessible::NativeName(nsString& aName)
 {
   // Check @alt attribute for invalid img elements.
   bool hasImgAlt = false;
   if (mContent->IsHTMLElement(nsGkAtoms::img)) {
-    hasImgAlt = mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName);
+    hasImgAlt =
+      mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName);
     if (!aName.IsEmpty())
       return eNameOK;
   }
 
   ENameValueFlag nameFlag = AccessibleWrap::NativeName(aName);
   if (!aName.IsEmpty())
     return nameFlag;
 
   // Get name from title attribute for HTML abbr and acronym elements making it
   // a valid name from markup. Otherwise their name isn't picked up by recursive
   // name computation algorithm. See NS_OK_NAME_FROM_TOOLTIP.
   if (IsAbbreviation() &&
-      mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName))
+      mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName))
     aName.CompressWhitespace();
 
   return hasImgAlt ? eNoNameOnPurpose : eNameOK;
 }
 
 void
 HyperTextAccessible::Shutdown()
 {
--- a/accessible/generic/ImageAccessible.cpp
+++ b/accessible/generic/ImageAccessible.cpp
@@ -69,17 +69,17 @@ ImageAccessible::NativeState()
 
   return state;
 }
 
 ENameValueFlag
 ImageAccessible::NativeName(nsString& aName)
 {
   bool hasAltAttrib =
-    mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName);
+    mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName);
   if (!aName.IsEmpty())
     return eNameOK;
 
   ENameValueFlag nameFlag = Accessible::NativeName(aName);
   if (!aName.IsEmpty())
     return nameFlag;
 
   // No accessible name but empty 'alt' attribute is present. If further name
@@ -162,33 +162,33 @@ ImageAccessible::Size()
 // Accessible
 already_AddRefed<nsIPersistentProperties>
 ImageAccessible::NativeAttributes()
 {
   nsCOMPtr<nsIPersistentProperties> attributes =
     LinkableAccessible::NativeAttributes();
 
   nsAutoString src;
-  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src);
+  mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src);
   if (!src.IsEmpty())
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::src, src);
 
   return attributes.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Private methods
 
 already_AddRefed<nsIURI>
 ImageAccessible::GetLongDescURI() const
 {
-  if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::longdesc)) {
+  if (mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::longdesc)) {
     // To check if longdesc contains an invalid url.
     nsAutoString longdesc;
-    mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::longdesc, longdesc);
+    mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::longdesc, longdesc);
     if (longdesc.FindChar(' ') != -1 || longdesc.FindChar('\t') != -1 ||
         longdesc.FindChar('\r') != -1 || longdesc.FindChar('\n') != -1) {
       return nullptr;
     }
     nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
     nsCOMPtr<nsIURI> uri;
     nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri), longdesc,
                                               mContent->OwnerDoc(), baseURI);
@@ -196,17 +196,17 @@ ImageAccessible::GetLongDescURI() const
   }
 
   DocAccessible* document = Document();
   if (document) {
     IDRefsIterator iter(document, mContent, nsGkAtoms::aria_describedby);
     while (nsIContent* target = iter.NextElem()) {
       if ((target->IsHTMLElement(nsGkAtoms::a) ||
            target->IsHTMLElement(nsGkAtoms::area)) &&
-          target->HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
+          target->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
         nsGenericHTMLElement* element =
           nsGenericHTMLElement::FromContent(target);
 
         nsCOMPtr<nsIURI> uri;
         element->GetURIAttr(nsGkAtoms::href, nullptr, getter_AddRefs(uri));
         return uri.forget();
       }
     }
--- a/accessible/generic/moz.build
+++ b/accessible/generic/moz.build
@@ -61,10 +61,10 @@ else:
     LOCAL_INCLUDES += [
         '/accessible/other',
     ]
 
 FINAL_LIBRARY = 'xul'
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
-if CONFIG['GNU_CXX']:
+if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += ['-Wno-error=shadow']
--- a/accessible/html/HTMLFormControlAccessible.cpp
+++ b/accessible/html/HTMLFormControlAccessible.cpp
@@ -126,19 +126,19 @@ void
 HTMLRadioButtonAccessible::GetPositionAndSizeInternal(int32_t* aPosInSet,
                                                       int32_t* aSetSize)
 {
   int32_t namespaceId = mContent->NodeInfo()->NamespaceID();
   nsAutoString tagName;
   mContent->NodeInfo()->GetName(tagName);
 
   nsAutoString type;
-  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
+  mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
   nsAutoString name;
-  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
+  mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
 
   RefPtr<nsContentList> inputElms;
 
   nsCOMPtr<nsIFormControl> formControlNode(do_QueryInterface(mContent));
   dom::Element* formElm = formControlNode->GetFormElement();
   if (formElm)
     inputElms = NS_GetContentList(formElm, namespaceId, tagName);
   else
@@ -148,20 +148,21 @@ HTMLRadioButtonAccessible::GetPositionAn
   uint32_t inputCount = inputElms->Length(false);
 
   // Compute posinset and setsize.
   int32_t indexOf = 0;
   int32_t count = 0;
 
   for (uint32_t index = 0; index < inputCount; index++) {
     nsIContent* inputElm = inputElms->Item(index, false);
-    if (inputElm->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                              type, eCaseMatters) &&
-        inputElm->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
-                              name, eCaseMatters) && mDoc->HasAccessible(inputElm)) {
+    if (inputElm->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                                           type, eCaseMatters) &&
+        inputElm->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
+                                           name, eCaseMatters) &&
+        mDoc->HasAccessible(inputElm)) {
         count++;
       if (inputElm == mContent)
         indexOf = count;
     }
   }
 
   *aPosInSet = indexOf;
   *aSetSize = count;
@@ -247,22 +248,22 @@ HTMLButtonAccessible::NativeName(nsStrin
   // element that has no valid @src (note if input@type="image" has an image
   // then neither @alt nor @value attributes are used to generate a visual label
   // and thus we need to obtain the accessible name directly from attribute
   // value). Also the same algorithm works in case of default labels for
   // type="submit"/"reset"/"image" elements.
 
   ENameValueFlag nameFlag = Accessible::NativeName(aName);
   if (!aName.IsEmpty() || !mContent->IsHTMLElement(nsGkAtoms::input) ||
-      !mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                             nsGkAtoms::image, eCaseMatters))
+      !mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                                          nsGkAtoms::image, eCaseMatters))
     return nameFlag;
 
-  if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
-    mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName);
+  if (!mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
+    mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName);
 
   aName.CompressWhitespace();
   return eNameOK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLButtonAccessible: Widgets
 
@@ -285,34 +286,34 @@ HTMLTextFieldAccessible::
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLTextFieldAccessible,
                              HyperTextAccessible)
 
 role
 HTMLTextFieldAccessible::NativeRole()
 {
-  if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                            nsGkAtoms::password, eIgnoreCase)) {
+  if (mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                                         nsGkAtoms::password, eIgnoreCase)) {
     return roles::PASSWORD_TEXT;
   }
 
   return roles::ENTRY;
 }
 
 already_AddRefed<nsIPersistentProperties>
 HTMLTextFieldAccessible::NativeAttributes()
 {
   nsCOMPtr<nsIPersistentProperties> attributes =
     HyperTextAccessibleWrap::NativeAttributes();
 
   // Expose type for text input elements as it gives some useful context,
   // especially for mobile.
   nsAutoString type;
-  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type)) {
+  if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::type, type)) {
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::textInputType, type);
     if (!ARIARoleMap() && type.EqualsLiteral("search")) {
       nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                              NS_LITERAL_STRING("searchbox"));
     }
   }
 
   return attributes.forget();
@@ -329,17 +330,17 @@ HTMLTextFieldAccessible::NativeName(nsSt
   nsIContent* widgetElm = XULWidgetElm();
   if (widgetElm)
     XULElmName(mDoc, widgetElm, aName);
 
   if (!aName.IsEmpty())
     return eNameOK;
 
   // text inputs and textareas might have useful placeholder text
-  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, aName);
+  mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, aName);
   return eNameOK;
 }
 
 void
 HTMLTextFieldAccessible::Value(nsString& aValue)
 {
   aValue.Truncate();
   if (NativeState() & states::PROTECTED)    // Don't return password text!
@@ -377,22 +378,22 @@ HTMLTextFieldAccessible::NativeState()
 {
   uint64_t state = HyperTextAccessibleWrap::NativeState();
 
   // Text fields are always editable, even if they are also read only or
   // disabled.
   state |= states::EDITABLE;
 
   // can be focusable, focused, protected. readonly, unavailable, selected
-  if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                            nsGkAtoms::password, eIgnoreCase)) {
+  if (mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                                         nsGkAtoms::password, eIgnoreCase)) {
     state |= states::PROTECTED;
   }
 
-  if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly)) {
+  if (mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly)) {
     state |= states::READONLY;
   }
 
   // Is it an <input> or a <textarea> ?
   HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
   state |= input && input->IsSingleLineTextControl() ?
     states::SINGLE_LINE : states::MULTI_LINE;
 
@@ -403,38 +404,38 @@ HTMLTextFieldAccessible::NativeState()
   // Expose autocomplete states if this input is part of autocomplete widget.
   Accessible* widget = ContainerWidget();
   if (widget && widget-IsAutoComplete()) {
     state |= states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION;
     return state;
   }
 
   // Expose autocomplete state if it has associated autocomplete list.
-  if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::list))
+  if (mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::list))
     return state | states::SUPPORTS_AUTOCOMPLETION | states::HASPOPUP;
 
   // Ordinal XUL textboxes don't support autocomplete.
   if (!XULWidgetElm() && Preferences::GetBool("browser.formfill.enable")) {
     // Check to see if autocompletion is allowed on this input. We don't expose
     // it for password fields even though the entire password can be remembered
     // for a page if the user asks it to be. However, the kind of autocomplete
     // we're talking here is based on what the user types, where a popup of
     // possible choices comes up.
     nsAutoString autocomplete;
-    mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::autocomplete,
-                      autocomplete);
+    mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::autocomplete,
+                                   autocomplete);
 
     if (!autocomplete.LowerCaseEqualsLiteral("off")) {
-      nsIContent* formContent = input->GetFormElement();
-      if (formContent) {
-        formContent->GetAttr(kNameSpaceID_None,
+      Element* formElement = input->GetFormElement();
+      if (formElement) {
+        formElement->GetAttr(kNameSpaceID_None,
                              nsGkAtoms::autocomplete, autocomplete);
       }
 
-      if (!formContent || !autocomplete.LowerCaseEqualsLiteral("off"))
+      if (!formElement || !autocomplete.LowerCaseEqualsLiteral("off"))
         state |= states::SUPPORTS_AUTOCOMPLETION;
     }
   }
 
   return state;
 }
 
 uint8_t
--- a/accessible/html/HTMLImageMapAccessible.cpp
+++ b/accessible/html/HTMLImageMapAccessible.cpp
@@ -5,17 +5,16 @@
 
 #include "HTMLImageMapAccessible.h"
 
 #include "ARIAMap.h"
 #include "nsAccUtils.h"
 #include "DocAccessible-inl.h"
 #include "Role.h"
 
-#include "nsIDOMHTMLCollection.h"
 #include "nsIServiceManager.h"
 #include "nsIDOMElement.h"
 #include "nsIFrame.h"
 #include "nsImageFrame.h"
 #include "nsImageMap.h"
 #include "nsIURI.h"
 #include "mozilla/dom/HTMLAreaElement.h"
 
@@ -151,29 +150,30 @@ HTMLAreaAccessible::
 
 ENameValueFlag
 HTMLAreaAccessible::NativeName(nsString& aName)
 {
   ENameValueFlag nameFlag = Accessible::NativeName(aName);
   if (!aName.IsEmpty())
     return nameFlag;
 
-  if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
+  if (!mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
     Value(aName);
 
   return eNameOK;
 }
 
 void
 HTMLAreaAccessible::Description(nsString& aDescription)
 {
   aDescription.Truncate();
 
   // Still to do - follow IE's standard here
-  RefPtr<HTMLAreaElement> area = HTMLAreaElement::FromContentOrNull(mContent);
+  RefPtr<dom::HTMLAreaElement> area =
+    dom::HTMLAreaElement::FromContentOrNull(mContent);
   if (area)
     area->GetShape(aDescription);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLAreaAccessible: Accessible public
 
 Accessible*
--- a/accessible/html/HTMLLinkAccessible.cpp
+++ b/accessible/html/HTMLLinkAccessible.cpp
@@ -63,17 +63,17 @@ HTMLLinkAccessible::NativeLinkState() co
 uint64_t
 HTMLLinkAccessible::NativeInteractiveState() const
 {
   uint64_t state = HyperTextAccessibleWrap::NativeInteractiveState();
 
   // This is how we indicate it is a named anchor. In other words, this anchor
   // can be selected as a location :) There is no other better state to use to
   // indicate this.
-  if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::name))
+  if (mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::name))
     state |= states::SELECTABLE;
 
   return state;
 }
 
 void
 HTMLLinkAccessible::Value(nsString& aValue)
 {
--- a/accessible/html/HTMLSelectAccessible.cpp
+++ b/accessible/html/HTMLSelectAccessible.cpp
@@ -37,17 +37,17 @@ HTMLSelectListAccessible::
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLSelectListAccessible: Accessible public
 
 uint64_t
 HTMLSelectListAccessible::NativeState()
 {
   uint64_t state = AccessibleWrap::NativeState();
-  if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple))
+  if (mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple))
     state |= states::MULTISELECTABLE | states::EXTSELECTABLE;
 
   return state;
 }
 
 role
 HTMLSelectListAccessible::NativeRole()
 {
@@ -55,24 +55,24 @@ HTMLSelectListAccessible::NativeRole()
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLSelectListAccessible: SelectAccessible
 
 bool
 HTMLSelectListAccessible::SelectAll()
 {
-  return mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple) ?
+  return mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple) ?
     AccessibleWrap::SelectAll() : false;
 }
 
 bool
 HTMLSelectListAccessible::UnselectAll()
 {
-  return mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple) ?
+  return mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple) ?
     AccessibleWrap::UnselectAll() : false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLSelectListAccessible: Widgets
 
 bool
 HTMLSelectListAccessible::IsWidget() const
@@ -105,19 +105,23 @@ HTMLSelectListAccessible::CurrentItem()
     }
   }
   return nullptr;
 }
 
 void
 HTMLSelectListAccessible::SetCurrentItem(Accessible* aItem)
 {
-  aItem->GetContent()->SetAttr(kNameSpaceID_None,
-                               nsGkAtoms::selected, NS_LITERAL_STRING("true"),
-                               true);
+  if (!aItem->GetContent()->IsElement())
+    return;
+
+  aItem->GetContent()->AsElement()->SetAttr(kNameSpaceID_None,
+                                            nsGkAtoms::selected,
+                                            NS_LITERAL_STRING("true"),
+                                            true);
 }
 
 bool
 HTMLSelectListAccessible::IsAcceptableChild(nsIContent* aEl) const
 {
   return aEl->IsAnyOfHTMLElements(nsGkAtoms::option, nsGkAtoms::optgroup);
 }
 
@@ -143,17 +147,17 @@ HTMLSelectOptionAccessible::NativeRole()
   return roles::OPTION;
 }
 
 ENameValueFlag
 HTMLSelectOptionAccessible::NativeName(nsString& aName)
 {
   // CASE #1 -- great majority of the cases
   // find the label attribute - this is what the W3C says we should use
-  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
+  mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
   if (!aName.IsEmpty())
     return eNameOK;
 
   // CASE #2 -- no label parameter, get the first child,
   // use it if it is a text node
   nsIContent* text = mContent->GetFirstChild();
   if (text && text->IsNodeOfType(nsINode::eTEXT)) {
     nsTextEquivUtils::AppendTextEquivFromTextContent(text, &aName);
--- a/accessible/html/HTMLTableAccessible.cpp
+++ b/accessible/html/HTMLTableAccessible.cpp
@@ -17,17 +17,17 @@
 #include "States.h"
 #include "TreeWalker.h"
 
 #include "mozilla/dom/HTMLTableElement.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMRange.h"
 #include "nsISelectionPrivate.h"
 #include "nsIDOMNodeList.h"
-#include "nsIDOMHTMLCollection.h"
+#include "nsIHTMLCollection.h"
 #include "nsIDocument.h"
 #include "nsIMutableArray.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPresShell.h"
 #include "nsITableCellLayout.h"
 #include "nsFrameSelection.h"
 #include "nsError.h"
 #include "nsArrayUtils.h"
@@ -117,24 +117,24 @@ HTMLTableCellAccessible::NativeAttribute
       nsIContent* firstChildNode = abbr->GetContent()->GetFirstChild();
       if (firstChildNode) {
         nsTextEquivUtils::
           AppendTextEquivFromTextContent(firstChildNode, &abbrText);
       }
     }
   }
   if (abbrText.IsEmpty())
-    mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::abbr, abbrText);
+    mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::abbr, abbrText);
 
   if (!abbrText.IsEmpty())
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::abbr, abbrText);
 
   // axis attribute
   nsAutoString axisText;
-  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::axis, axisText);
+  mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::axis, axisText);
   if (!axisText.IsEmpty())
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::axis, axisText);
 
 #ifdef DEBUG
   nsAutoString unused;
   attributes->SetStringProperty(NS_LITERAL_CSTRING("cppclass"),
                                 NS_LITERAL_STRING("HTMLTableCellAccessible"),
                                 unused);
@@ -307,22 +307,22 @@ HTMLTableHeaderCellAccessible::
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableHeaderCellAccessible: Accessible implementation
 
 role
 HTMLTableHeaderCellAccessible::NativeRole()
 {
   // Check value of @scope attribute.
-  static nsIContent::AttrValuesArray scopeValues[] =
+  static Element::AttrValuesArray scopeValues[] =
     { &nsGkAtoms::col, &nsGkAtoms::colgroup,
       &nsGkAtoms::row, &nsGkAtoms::rowgroup, nullptr };
   int32_t valueIdx =
-    mContent->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::scope,
-                              scopeValues, eCaseMatters);
+    mContent->AsElement()->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::scope,
+                                           scopeValues, eCaseMatters);
 
   switch (valueIdx) {
     case 0:
     case 1:
       return roles::COLUMNHEADER;
     case 2:
     case 3:
       return roles::ROWHEADER;
@@ -432,17 +432,17 @@ HTMLTableAccessible::NativeName(nsString
     if (captionContent) {
       nsTextEquivUtils::AppendTextEquivFromContent(this, captionContent, &aName);
       if (!aName.IsEmpty())
         return eNameOK;
     }
   }
 
   // If no caption then use summary as a name.
-  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::summary, aName);
+  mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::summary, aName);
   return eNameOK;
 }
 
 already_AddRefed<nsIPersistentProperties>
 HTMLTableAccessible::NativeAttributes()
 {
   nsCOMPtr<nsIPersistentProperties> attributes =
     AccessibleWrap::NativeAttributes();
@@ -858,18 +858,18 @@ HTMLTableAccessible::Description(nsStrin
   if (caption) {
     nsIContent* captionContent = caption->GetContent();
     if (captionContent) {
       nsAutoString captionText;
       nsTextEquivUtils::AppendTextEquivFromContent(this, captionContent,
                                                    &captionText);
 
       if (!captionText.IsEmpty()) { // summary isn't used as a name.
-        mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::summary,
-                          aDescription);
+        mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::summary,
+                                       aDescription);
       }
     }
   }
 
 #ifdef SHOW_LAYOUT_HEURISTIC
   if (aDescription.IsEmpty()) {
     bool isProbablyForLayout = IsProbablyLayoutTable();
     aDescription = mLayoutHeuristic;
@@ -941,35 +941,35 @@ HTMLTableAccessible::IsProbablyLayoutTab
     }
   }
 
   // Check to see if an ARIA role overrides the role from native markup,
   // but for which we still expose table semantics (treegrid, for example).
   if (Role() != roles::TABLE)
     RETURN_LAYOUT_ANSWER(false, "Has role attribute");
 
-  if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::role)) {
+  if (mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::role)) {
     // Role attribute is present, but overridden roles have already been dealt with.
     // Only landmarks and other roles that don't override the role from native
     // markup are left to deal with here.
     RETURN_LAYOUT_ANSWER(false, "Has role attribute, weak role, and role is table");
   }
 
   NS_ASSERTION(mContent->IsHTMLElement(nsGkAtoms::table),
     "table should not be built by CSS display:table style");
 
   // Check if datatable attribute has "0" value.
-  if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::datatable,
+  if (mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::datatable,
                             NS_LITERAL_STRING("0"), eCaseMatters)) {
     RETURN_LAYOUT_ANSWER(true, "Has datatable = 0 attribute, it's for layout");
   }
 
   // Check for legitimate data table attributes.
   nsAutoString summary;
-  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::summary, summary) &&
+  if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::summary, summary) &&
       !summary.IsEmpty())
     RETURN_LAYOUT_ANSWER(false, "Has summary -- legitimate table structures");
 
   // Check for legitimate data table elements.
   Accessible* caption = FirstChild();
   if (caption && caption->Role() == roles::CAPTION && caption->HasChildren())
     RETURN_LAYOUT_ANSWER(false, "Not empty caption -- legitimate table structures");
 
@@ -994,19 +994,19 @@ HTMLTableAccessible::IsProbablyLayoutTab
                cellElm = cellElm->GetNextSibling()) {
             if (cellElm->IsHTMLElement()) {
 
               if (cellElm->NodeInfo()->Equals(nsGkAtoms::th)) {
                 RETURN_LAYOUT_ANSWER(false,
                                      "Has th -- legitimate table structures");
               }
 
-              if (cellElm->HasAttr(kNameSpaceID_None, nsGkAtoms::headers) ||
-                  cellElm->HasAttr(kNameSpaceID_None, nsGkAtoms::scope) ||
-                  cellElm->HasAttr(kNameSpaceID_None, nsGkAtoms::abbr)) {
+              if (cellElm->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::headers) ||
+                  cellElm->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::scope) ||
+                  cellElm->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::abbr)) {
                 RETURN_LAYOUT_ANSWER(false,
                                      "Has headers, scope, or abbr attribute -- legitimate table structures");
               }
 
               Accessible* cell = mDoc->GetAccessible(cellElm);
               if (cell && cell->ChildCount() == 1 &&
                   cell->FirstChild()->IsAbbreviation()) {
                 RETURN_LAYOUT_ANSWER(false,
--- a/accessible/html/moz.build
+++ b/accessible/html/moz.build
@@ -41,10 +41,10 @@ else:
     LOCAL_INCLUDES += [
         '/accessible/other',
     ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
-if CONFIG['GNU_CXX']:
+if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += ['-Wno-error=shadow']
--- a/accessible/interfaces/gecko/moz.build
+++ b/accessible/interfaces/gecko/moz.build
@@ -20,10 +20,10 @@ GENERATED_FILES += [
 
 FINAL_LIBRARY = 'xul'
 
 # The Windows MIDL code generator creates things like:
 #
 #   #endif !_MIDL_USE_GUIDDEF_
 #
 # which clang-cl complains about.  MSVC doesn't, so turn this warning off.
-if CONFIG['CLANG_CL']:
+if CONFIG['CC_TYPE'] == 'clang-cl':
     CFLAGS += ['-Wno-extra-tokens']
--- a/accessible/interfaces/ia2/moz.build
+++ b/accessible/interfaces/ia2/moz.build
@@ -86,10 +86,10 @@ GENERATED_FILES += [
 
 RCINCLUDE = 'IA2Marshal.rc'
 
 # The Windows MIDL code generator creates things like:
 #
 #   #endif !_MIDL_USE_GUIDDEF_
 #
 # which clang-cl complains about.  MSVC doesn't, so turn this warning off.
-if CONFIG['CLANG_CL']:
+if CONFIG['CC_TYPE'] == 'clang-cl':
     CXXFLAGS += ['-Wno-extra-tokens']
--- a/accessible/interfaces/msaa/moz.build
+++ b/accessible/interfaces/msaa/moz.build
@@ -36,10 +36,10 @@ GENERATED_FILES += [
 
 RCINCLUDE = 'AccessibleMarshal.rc'
 
 # The Windows MIDL code generator creates things like:
 #
 #   #endif !_MIDL_USE_GUIDDEF_
 #
 # which clang-cl complains about.  MSVC doesn't, so turn this warning off.
-if CONFIG['CLANG_CL']:
+if CONFIG['CC_TYPE'] == 'clang-cl':
     CFLAGS += ['-Wno-extra-tokens']
--- a/accessible/interfaces/nsIAccessibilityService.idl
+++ b/accessible/interfaces/nsIAccessibilityService.idl
@@ -11,17 +11,17 @@ interface nsIWeakReference;
 interface nsIPresShell;
 interface nsIAccessiblePivot;
 
 /**
  * An interface for in-process accessibility clients wishing to get an
  * nsIAccessible for a given DOM node.  More documentation at:
  *   http://www.mozilla.org/projects/ui/accessibility
  */
-[scriptable, builtinclass, uuid(9a6f80fe-25cc-405c-9f8f-25869bc9f94e)]
+[scriptable, builtinclass, uuid(2188e3a0-c88e-11e7-8f1a-0800200c9a66)]
 interface nsIAccessibilityService : nsISupports
 {
   /**
    * Return application accessible.
    */
   nsIAccessible getApplicationAccessible();
 
   /**
@@ -92,9 +92,15 @@ interface nsIAccessibilityService : nsIS
    * @see Logging.cpp for list of possible values.
    */
   void setLogging(in ACString aModules);
 
   /**
    * Return true if the given module is logged.
    */
   boolean isLogged(in AString aModule);
+
+  /**
+   * Get the current accessibility service consumers.
+   * @returns a JSON string representing the accessibility service consumers.
+   */
+  AString getConsumers();
 };
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -24,27 +24,28 @@ class xpcAccessibleGeneric;
  * an accessible document in a content process.
  */
 class DocAccessibleParent : public ProxyAccessible,
     public PDocAccessibleParent
 {
 public:
   DocAccessibleParent() :
     ProxyAccessible(this), mParentDoc(kNoParentDoc),
+#if defined(XP_WIN)
+    mEmulatedWindowHandle(nullptr),
+#endif // defined(XP_WIN)
     mTopLevel(false), mShutdown(false)
-#if defined(XP_WIN)
-                                      , mEmulatedWindowHandle(nullptr)
-#endif // defined(XP_WIN)
   {
     MOZ_COUNT_CTOR_INHERITED(DocAccessibleParent, ProxyAccessible);
     sMaxDocID++;
     mActorID = sMaxDocID;
     MOZ_ASSERT(!LiveDocs().Get(mActorID));
     LiveDocs().Put(mActorID, this);
   }
+
   ~DocAccessibleParent()
   {
     LiveDocs().Remove(mActorID);
     MOZ_COUNT_DTOR_INHERITED(DocAccessibleParent, ProxyAccessible);
     MOZ_ASSERT(mChildDocs.Length() == 0);
     MOZ_ASSERT(!ParentDoc());
   }
 
--- a/accessible/ipc/moz.build
+++ b/accessible/ipc/moz.build
@@ -28,17 +28,17 @@ else:
         LOCAL_INCLUDES += [
             '/accessible/other',
         ]
 
 EXPORTS.mozilla.a11y += [
     'IPCTypes.h',
 ]
 
-if CONFIG['GNU_CXX']:
+if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += ['-Wno-error=shadow']
 
 if CONFIG['ACCESSIBILITY']:
     EXPORTS.mozilla.a11y += [
         'DocAccessibleChildBase.h',
         'DocAccessibleParent.h',
         'ProxyAccessibleBase.h',
         'ProxyAccessibleShared.h',
--- a/accessible/ipc/other/moz.build
+++ b/accessible/ipc/other/moz.build
@@ -35,13 +35,13 @@ if CONFIG['ACCESSIBILITY']:
         ]
     else:
         LOCAL_INCLUDES += [
             '/accessible/other',
         ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
-if CONFIG['GNU_CXX']:
+if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += ['-Wno-error=shadow']
 
 FINAL_LIBRARY = 'xul'
 
--- a/accessible/ipc/win/DocAccessibleChild.cpp
+++ b/accessible/ipc/win/DocAccessibleChild.cpp
@@ -14,18 +14,18 @@
 
 namespace mozilla {
 namespace a11y {
 
 static StaticAutoPtr<PlatformChild> sPlatformChild;
 
 DocAccessibleChild::DocAccessibleChild(DocAccessible* aDoc, IProtocol* aManager)
   : DocAccessibleChildBase(aDoc)
+  , mIsRemoteConstructed(false)
   , mEmulatedWindowHandle(nullptr)
-  , mIsRemoteConstructed(false)
 {
   MOZ_COUNT_CTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase);
   if (!sPlatformChild) {
     sPlatformChild = new PlatformChild();
     ClearOnShutdown(&sPlatformChild, ShutdownPhase::Shutdown);
   }
 
   SetManager(aManager);
@@ -313,9 +313,8 @@ ipc::IPCResult
 DocAccessibleChild::RecvRestoreFocus()
 {
   FocusMgr()->ForceFocusEvent();
   return IPC_OK();
 }
 
 } // namespace a11y
 } // namespace mozilla
-
--- a/accessible/ipc/win/HandlerProvider.cpp
+++ b/accessible/ipc/win/HandlerProvider.cpp
@@ -18,21 +18,23 @@
 #include "mozilla/Assertions.h"
 #include "mozilla/a11y/AccessibleWrap.h"
 #include "mozilla/a11y/HandlerDataCleanup.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/Move.h"
 #include "mozilla/mscom/AgileReference.h"
 #include "mozilla/mscom/FastMarshaler.h"
 #include "mozilla/mscom/Interceptor.h"
+#include "mozilla/mscom/MainThreadHandoff.h"
 #include "mozilla/mscom/MainThreadInvoker.h"
 #include "mozilla/mscom/Ptr.h"
 #include "mozilla/mscom/StructStream.h"
 #include "mozilla/mscom/Utils.h"
 #include "nsThreadUtils.h"
+#include "nsTArray.h"
 
 #include <memory.h>
 
 namespace mozilla {
 namespace a11y {
 
 HandlerProvider::HandlerProvider(REFIID aIid,
                                mscom::InterceptorTargetPtr<IUnknown> aTarget)
@@ -392,37 +394,17 @@ HandlerProvider::BuildDynamicIA2Data(Dyn
   hr = target->get_uniqueID(&aOutIA2Data->mUniqueId);
 }
 
 void
 HandlerProvider::CleanupStaticIA2Data(StaticIA2Data& aData)
 {
   // When CoMarshalInterface writes interfaces out to a stream, it AddRefs.
   // Therefore, we must release our references after this.
-  if (aData.mIA2) {
-    aData.mIA2->Release();
-  }
-  if (aData.mIEnumVARIANT) {
-    aData.mIEnumVARIANT->Release();
-  }
-  if (aData.mIAHypertext) {
-    aData.mIAHypertext->Release();
-  }
-  if (aData.mIAHyperlink) {
-    aData.mIAHyperlink->Release();
-  }
-  if (aData.mIATable) {
-    aData.mIATable->Release();
-  }
-  if (aData.mIATable2) {
-    aData.mIATable2->Release();
-  }
-  if (aData.mIATableCell) {
-    aData.mIATableCell->Release();
-  }
+  ReleaseStaticIA2DataInterfaces(aData);
   ZeroMemory(&aData, sizeof(StaticIA2Data));
 }
 
 void
 HandlerProvider::BuildInitialIA2Data(
   NotNull<mscom::IInterceptor*> aInterceptor,
   StaticIA2Data* aOutStaticData,
   DynamicIA2Data* aOutDynamicData)
@@ -557,11 +539,127 @@ HandlerProvider::Refresh(DynamicIA2Data*
                                  this, &HandlerProvider::BuildDynamicIA2Data,
                                  aOutData)) {
     return E_FAIL;
   }
 
   return S_OK;
 }
 
+template<typename Interface>
+HRESULT
+HandlerProvider::ToWrappedObject(Interface** aObj)
+{
+  mscom::STAUniquePtr<Interface> inObj(*aObj);
+  RefPtr<HandlerProvider> hprov = new HandlerProvider(__uuidof(Interface),
+    mscom::ToInterceptorTargetPtr(inObj));
+  HRESULT hr = mscom::MainThreadHandoff::WrapInterface(Move(inObj), hprov,
+                                                       aObj);
+  if (FAILED(hr)) {
+    *aObj = nullptr;
+  }
+  return hr;
+}
+
+void
+HandlerProvider::GetAllTextInfoMainThread(BSTR* aText,
+                                          IAccessibleHyperlink*** aHyperlinks,
+                                          long* aNHyperlinks,
+                                          IA2TextSegment** aAttribRuns,
+                                          long* aNAttribRuns, HRESULT* result)
+{
+  MOZ_ASSERT(aText);
+  MOZ_ASSERT(aHyperlinks);
+  MOZ_ASSERT(aNHyperlinks);
+  MOZ_ASSERT(aAttribRuns);
+  MOZ_ASSERT(aNAttribRuns);
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(mTargetUnk);
+
+  RefPtr<IAccessibleHypertext2> ht;
+  HRESULT hr = mTargetUnk->QueryInterface(IID_IAccessibleHypertext2,
+                                          getter_AddRefs(ht));
+  if (FAILED(hr)) {
+    *result = hr;
+    return;
+  }
+
+  hr = ht->get_text(0, IA2_TEXT_OFFSET_LENGTH, aText);
+  if (FAILED(hr)) {
+    *result = hr;
+    return;
+  }
+
+  if (hr == S_FALSE) {
+    // No text.
+    *aHyperlinks = nullptr;
+    *aNHyperlinks = 0;
+    *aAttribRuns = nullptr;
+    *aNAttribRuns = 0;
+    *result = S_FALSE;
+    return;
+  }
+
+  hr = ht->get_hyperlinks(aHyperlinks, aNHyperlinks);
+  if (FAILED(hr)) {
+    *aHyperlinks = nullptr;
+    // -1 signals to the handler that it should call hyperlinks itself.
+    *aNHyperlinks = -1;
+  }
+  // We must wrap these hyperlinks in an interceptor.
+  for (long index = 0; index < *aNHyperlinks; ++index) {
+    ToWrappedObject(&(*aHyperlinks)[index]);
+  }
+
+  // Fetch all attribute runs.
+  nsTArray<IA2TextSegment> attribRuns;
+  long end = 0;
+  long length = ::SysStringLen(*aText);
+  while (end < length) {
+    long offset = end;
+    long start;
+    BSTR attribs;
+    // The (exclusive) end of the last run is the start of the next run.
+    hr = ht->get_attributes(offset, &start, &end, &attribs);
+    // Bug 1421873: Gecko can return end <= offset in some rare cases, which
+    // isn't valid. This is perhaps because the text mutated during the loop
+    // for some reason, making this offset invalid.
+    if (FAILED(hr) || end <= offset) {
+      break;
+    }
+    attribRuns.AppendElement(IA2TextSegment({attribs, start, end}));
+  }
+
+  // Put the attribute runs in a COM array.
+  *aNAttribRuns = attribRuns.Length();
+  *aAttribRuns = static_cast<IA2TextSegment*>(::CoTaskMemAlloc(
+    sizeof(IA2TextSegment) * *aNAttribRuns));
+  for (long index = 0; index < *aNAttribRuns; ++index) {
+    (*aAttribRuns)[index] = attribRuns[index];
+  }
+
+  *result = S_OK;
+}
+
+HRESULT
+HandlerProvider::get_AllTextInfo(BSTR* aText,
+                                 IAccessibleHyperlink*** aHyperlinks,
+                                 long* aNHyperlinks,
+                                 IA2TextSegment** aAttribRuns,
+                                 long* aNAttribRuns)
+{
+  MOZ_ASSERT(mscom::IsCurrentThreadMTA());
+
+  HRESULT hr;
+  if (!mscom::InvokeOnMainThread("HandlerProvider::GetAllTextInfoMainThread",
+                                 this,
+                                 &HandlerProvider::GetAllTextInfoMainThread,
+                                 aText, aHyperlinks, aNHyperlinks,
+                                 aAttribRuns, aNAttribRuns, &hr)) {
+    return E_FAIL;
+  }
+
+  return hr;
+}
+
 } // namespace a11y
 } // namespace mozilla
 
--- a/accessible/ipc/win/HandlerProvider.h
+++ b/accessible/ipc/win/HandlerProvider.h
@@ -50,32 +50,49 @@ public:
                                                 ULONG aCallMethod) override;
   STDMETHODIMP NewInstance(REFIID aIid,
                            mscom::InterceptorTargetPtr<IUnknown> aTarget,
                            NotNull<mscom::IHandlerProvider**> aOutNewPayload) override;
 
   // IGeckoBackChannel
   STDMETHODIMP put_HandlerControl(long aPid, IHandlerControl* aCtrl) override;
   STDMETHODIMP Refresh(DynamicIA2Data* aOutData) override;
+  STDMETHODIMP get_AllTextInfo(BSTR* aText,
+                               IAccessibleHyperlink*** aHyperlinks,
+                               long* aNHyperlinks,
+                               IA2TextSegment** aAttribRuns,
+                               long* aNAttribRuns) override;
 
 private:
   ~HandlerProvider() = default;
 
   void SetHandlerControlOnMainThread(DWORD aPid,
                                      mscom::ProxyUniquePtr<IHandlerControl> aCtrl);
   void GetAndSerializePayload(const MutexAutoLock&,
                               NotNull<mscom::IInterceptor*> aInterceptor);
   void BuildStaticIA2Data(NotNull<mscom::IInterceptor*> aInterceptor,
                           StaticIA2Data* aOutData);
   void BuildDynamicIA2Data(DynamicIA2Data* aOutIA2Data);
   void BuildInitialIA2Data(NotNull<mscom::IInterceptor*> aInterceptor,
                            StaticIA2Data* aOutStaticData,
                            DynamicIA2Data* aOutDynamicData);
   static void CleanupStaticIA2Data(StaticIA2Data& aData);
   bool IsTargetInterfaceCacheable();
+  // Replace a raw object from the main thread with a wrapped, intercepted
+  // object suitable for calling from the MTA.
+  // The reference to the original object is adopted; i.e. you should not
+  // separately release it.
+  // This is intended for objects returned from method calls on the main thread.
+  template<typename Interface> HRESULT ToWrappedObject(Interface** aObj);
+  void GetAllTextInfoMainThread(BSTR* aText,
+                                IAccessibleHyperlink*** aHyperlinks,
+                                long* aNHyperlinks,
+                                IA2TextSegment** aAttribRuns,
+                                long* aNAttribRuns,
+                                HRESULT* result);
 
   Atomic<uint32_t>                  mRefCnt;
   Mutex                             mMutex; // Protects mSerializer
   const IID                         mTargetUnkIid;
   mscom::InterceptorTargetPtr<IUnknown> mTargetUnk; // Constant, main thread only
   UniquePtr<mscom::StructToStream>  mSerializer;
   RefPtr<IUnknown>                  mFastMarshalUnk;
 };
--- a/accessible/ipc/win/handler/AccessibleHandler.cpp
+++ b/accessible/ipc/win/handler/AccessibleHandler.cpp
@@ -7,17 +7,16 @@
 #if defined(MOZILLA_INTERNAL_API)
 #error This code is NOT for internal Gecko use!
 #endif // defined(MOZILLA_INTERNAL_API)
 
 #define INITGUID
 
 #include "AccessibleHandler.h"
 #include "AccessibleHandlerControl.h"
-#include "AccessibleTextTearoff.h"
 
 #include "Factory.h"
 #include "HandlerData.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/a11y/HandlerDataCleanup.h"
 #include "mozilla/mscom/Registration.h"
 #include "mozilla/UniquePtr.h"
 
@@ -27,19 +26,22 @@
 
 #include "AccessibleHypertext.h"
 #include "AccessibleHypertext2.h"
 #include "Accessible2_i.c"
 #include "Accessible2_2_i.c"
 #include "Accessible2_3_i.c"
 #include "AccessibleAction_i.c"
 #include "AccessibleHyperlink_i.c"
+#include "AccessibleHypertext_i.c"
+#include "AccessibleHypertext2_i.c"
 #include "AccessibleTable_i.c"
 #include "AccessibleTable2_i.c"
 #include "AccessibleTableCell_i.c"
+#include "AccessibleText_i.c"
 
 namespace mozilla {
 namespace a11y {
 
 static mscom::Factory<AccessibleHandler> sHandlerFactory;
 
 HRESULT
 AccessibleHandler::Create(IUnknown* aOuter, REFIID aIid, void** aOutInterface)
@@ -64,18 +66,23 @@ AccessibleHandler::Create(IUnknown* aOut
 
 AccessibleHandler::AccessibleHandler(IUnknown* aOuter, HRESULT* aResult)
   : mscom::Handler(aOuter, aResult)
   , mDispatch(nullptr)
   , mIA2PassThru(nullptr)
   , mServProvPassThru(nullptr)
   , mIAHyperlinkPassThru(nullptr)
   , mIATableCellPassThru(nullptr)
+  , mIAHypertextPassThru(nullptr)
   , mCachedData()
   , mCacheGen(0)
+  , mCachedHyperlinks(nullptr)
+  , mCachedNHyperlinks(-1)
+  , mCachedTextAttribRuns(nullptr)
+  , mCachedNTextAttribRuns(-1)
 {
   RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetOrCreateSingleton());
   MOZ_ASSERT(ctl);
   if (!ctl) {
     if (aResult) {
       *aResult = E_UNEXPECTED;
     }
     return;
@@ -86,16 +93,17 @@ AccessibleHandler::AccessibleHandler(IUn
 
 AccessibleHandler::~AccessibleHandler()
 {
   // No need to zero memory, since we're being destroyed anyway.
   CleanupDynamicIA2Data(mCachedData.mDynamicData, false);
   if (mCachedData.mGeckoBackChannel) {
     mCachedData.mGeckoBackChannel->Release();
   }
+  ClearTextCache();
 }
 
 HRESULT
 AccessibleHandler::ResolveIA2()
 {
   if (mIA2PassThru) {
     return S_OK;
   }
@@ -157,16 +165,39 @@ AccessibleHandler::ResolveIATableCell()
     // (see comments in AccesssibleHandler.h)
     mIATableCellPassThru->Release();
   }
 
   return hr;
 }
 
 HRESULT
+AccessibleHandler::ResolveIAHypertext()
+{
+  if (mIAHypertextPassThru) {
+    return S_OK;
+  }
+
+  RefPtr<IUnknown> proxy(GetProxy());
+  if (!proxy) {
+    return E_UNEXPECTED;
+  }
+
+  HRESULT hr = proxy->QueryInterface(IID_IAccessibleHypertext2,
+    reinterpret_cast<void**>(&mIAHypertextPassThru));
+  if (SUCCEEDED(hr)) {
+    // mIAHypertextPassThru is a weak reference
+    // (see comments in AccessibleHandler.h)
+    mIAHypertextPassThru->Release();
+  }
+
+  return hr;
+}
+
+HRESULT
 AccessibleHandler::MaybeUpdateCachedData()
 {
   RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetOrCreateSingleton());
   if (!ctl) {
     return E_OUTOFMEMORY;
   }
 
   uint32_t gen = ctl->GetCacheGen();
@@ -177,16 +208,58 @@ AccessibleHandler::MaybeUpdateCachedData
   if (!mCachedData.mGeckoBackChannel) {
     return E_POINTER;
   }
 
   return mCachedData.mGeckoBackChannel->Refresh(&mCachedData.mDynamicData);
 }
 
 HRESULT
+AccessibleHandler::GetAllTextInfo(BSTR* aText)
+{
+  MOZ_ASSERT(mCachedData.mGeckoBackChannel);
+
+  ClearTextCache();
+
+  return mCachedData.mGeckoBackChannel->get_AllTextInfo(aText,
+    &mCachedHyperlinks, &mCachedNHyperlinks,
+    &mCachedTextAttribRuns, &mCachedNTextAttribRuns);
+}
+
+void
+AccessibleHandler::ClearTextCache()
+{
+  if (mCachedNHyperlinks >= 0) {
+    // We cached hyperlinks, but the caller never retrieved them.
+    for (long index = 0; index < mCachedNHyperlinks; ++index) {
+      mCachedHyperlinks[index]->Release();
+    }
+    // mCachedHyperlinks might already be null if there are no hyperlinks.
+    if (mCachedHyperlinks) {
+      ::CoTaskMemFree(mCachedHyperlinks);
+      mCachedHyperlinks = nullptr;
+    }
+    mCachedNHyperlinks = -1;
+  }
+
+  if (mCachedTextAttribRuns) {
+    for (long index = 0; index < mCachedNTextAttribRuns; ++index) {
+      if (mCachedTextAttribRuns[index].text) {
+        // The caller never requested this attribute run.
+        ::SysFreeString(mCachedTextAttribRuns[index].text);
+      }
+    }
+    // This array is internal to us, so we must always free it.
+    ::CoTaskMemFree(mCachedTextAttribRuns);
+    mCachedTextAttribRuns = nullptr;
+    mCachedNTextAttribRuns = -1;
+  }
+}
+
+HRESULT
 AccessibleHandler::ResolveIDispatch()
 {
   if (mDispatch) {
     return S_OK;
   }
 
   HRESULT hr;
 
@@ -278,18 +351,19 @@ AccessibleHandler::QueryHandlerInterface
     RefPtr<IAccessibleTableCell> iaCell(
       static_cast<IAccessibleTableCell*>(this));
     iaCell.forget(aOutInterface);
     return S_OK;
   }
 
   if (aIid == IID_IAccessibleText || aIid == IID_IAccessibleHypertext ||
       aIid == IID_IAccessibleHypertext2) {
-    RefPtr<IAccessibleHypertext2> textTearoff(new AccessibleTextTearoff(this));
-    textTearoff.forget(aOutInterface);
+    RefPtr<IAccessibleHypertext2> iaHt(
+      static_cast<IAccessibleHypertext2*>(this));
+    iaHt.forget(aOutInterface);
     return S_OK;
   }
 
   if (aIid == IID_IProvideClassInfo) {
     RefPtr<IProvideClassInfo> clsInfo(this);
     clsInfo.forget(aOutInterface);
     return S_OK;
   }
@@ -331,37 +405,17 @@ AccessibleHandler::ReadHandlerPayload(IS
   // The proxy manager will resolve these interfaces now on QI,
   // so we can release these pointers.
   // However, we don't null them out because we use their presence
   // to determine whether the interface is available
   // so as to avoid pointless cross-proc QI calls returning E_NOINTERFACE.
   // Note that if pointers to other objects (in contrast to
   // interfaces of *this* object) are added in future, we should not release
   // those pointers.
-  if (mCachedData.mStaticData.mIA2) {
-    mCachedData.mStaticData.mIA2->Release();
-  }
-  if (mCachedData.mStaticData.mIEnumVARIANT) {
-    mCachedData.mStaticData.mIEnumVARIANT->Release();
-  }
-  if (mCachedData.mStaticData.mIAHypertext) {
-    mCachedData.mStaticData.mIAHypertext->Release();
-  }
-  if (mCachedData.mStaticData.mIAHyperlink) {
-    mCachedData.mStaticData.mIAHyperlink->Release();
-  }
-  if (mCachedData.mStaticData.mIATable) {
-    mCachedData.mStaticData.mIATable->Release();
-  }
-  if (mCachedData.mStaticData.mIATable2) {
-    mCachedData.mStaticData.mIATable2->Release();
-  }
-  if (mCachedData.mStaticData.mIATableCell) {
-    mCachedData.mStaticData.mIATableCell->Release();
-  }
+  ReleaseStaticIA2DataInterfaces(mCachedData.mStaticData);
 
   if (!mCachedData.mGeckoBackChannel) {
     return S_OK;
   }
 
   RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetOrCreateSingleton());
   if (!ctl) {
     return E_OUTOFMEMORY;
@@ -1534,16 +1588,382 @@ AccessibleHandler::get_table(IUnknown** 
   HRESULT hr = ResolveIATableCell();
   if (FAILED(hr)) {
     return hr;
   }
 
   return mIATableCellPassThru->get_table(table);
 }
 
+/*** IAccessibleText ***/
+
+HRESULT
+AccessibleHandler::addSelection(long startOffset, long endOffset)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->addSelection(startOffset, endOffset);
+}
+
+HRESULT
+AccessibleHandler::get_attributes(long offset, long *startOffset,
+                                  long *endOffset, BSTR *textAttributes)
+{
+  if (!startOffset || !endOffset || !textAttributes) {
+    return E_INVALIDARG;
+  }
+
+  if (mCachedNTextAttribRuns >= 0) {
+    // We have cached attributes.
+    for (long index = 0; index < mCachedNTextAttribRuns; ++index) {
+      auto& attribRun = mCachedTextAttribRuns[index];
+      if (attribRun.start <= offset && offset < attribRun.end) {
+        *startOffset = attribRun.start;
+        *endOffset = attribRun.end;
+        *textAttributes = attribRun.text;
+        // The caller will clean this up.
+        // (We only keep each cached attribute run for one call.)
+        attribRun.text = nullptr;
+        // The cache for this run is now invalid, so don't visit it again.
+        attribRun.end = 0;
+        return S_OK;
+      }
+    }
+  }
+
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_attributes(offset, startOffset, endOffset,
+                                              textAttributes);
+}
+
+HRESULT
+AccessibleHandler::get_caretOffset(long *offset)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_caretOffset(offset);
+}
+
+HRESULT
+AccessibleHandler::get_characterExtents(long offset,
+                                        enum IA2CoordinateType coordType,
+                                        long *x, long *y, long *width,
+                                        long *height)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_characterExtents(offset, coordType, x, y,
+                                                    width, height);
+}
+
+HRESULT
+AccessibleHandler::get_nSelections(long *nSelections)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_nSelections(nSelections);
+}
+
+HRESULT
+AccessibleHandler::get_offsetAtPoint(long x, long y,
+                                     enum IA2CoordinateType coordType,
+                                     long *offset)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_offsetAtPoint(x, y, coordType, offset);
+}
+
+HRESULT
+AccessibleHandler::get_selection(long selectionIndex, long *startOffset,
+                                 long *endOffset)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_selection(selectionIndex, startOffset,
+                                             endOffset);
+}
+
+HRESULT
+AccessibleHandler::get_text(long startOffset, long endOffset, BSTR *text)
+{
+  if (!text) {
+    return E_INVALIDARG;
+  }
+
+  HRESULT hr;
+  if (mCachedData.mGeckoBackChannel &&
+      startOffset == 0 && endOffset == IA2_TEXT_OFFSET_LENGTH) {
+    // If the caller is retrieving all text, they will probably want all
+    // hyperlinks and attributes as well.
+    hr = GetAllTextInfo(text);
+    if (SUCCEEDED(hr)) {
+      return hr;
+    }
+    // We fall back to a normal call if this fails.
+  }
+
+  hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_text(startOffset, endOffset, text);
+}
+
+HRESULT
+AccessibleHandler::get_textBeforeOffset(long offset,
+                                        enum IA2TextBoundaryType boundaryType,
+                                        long *startOffset, long *endOffset,
+                                        BSTR *text)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_textBeforeOffset(offset, boundaryType,
+                                                    startOffset, endOffset,
+                                                    text);
+}
+
+HRESULT
+AccessibleHandler::get_textAfterOffset(long offset,
+                                       enum IA2TextBoundaryType boundaryType,
+                                       long *startOffset, long *endOffset,
+                                       BSTR *text)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_textAfterOffset(offset, boundaryType,
+                                                   startOffset, endOffset,
+                                                   text);
+}
+
+HRESULT
+AccessibleHandler::get_textAtOffset(long offset,
+                                    enum IA2TextBoundaryType boundaryType,
+                                    long *startOffset, long *endOffset,
+                                    BSTR *text)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_textAtOffset(offset, boundaryType,
+                                                 startOffset, endOffset, text);
+}
+
+HRESULT
+AccessibleHandler::removeSelection(long selectionIndex)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->removeSelection(selectionIndex);
+}
+
+HRESULT
+AccessibleHandler::setCaretOffset(long offset)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->setCaretOffset(offset);
+}
+
+HRESULT
+AccessibleHandler::setSelection(long selectionIndex, long startOffset,
+                                long endOffset)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->setSelection(selectionIndex, startOffset,
+                                            endOffset);
+}
+
+HRESULT
+AccessibleHandler::get_nCharacters(long *nCharacters)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_nCharacters(nCharacters);
+}
+
+HRESULT
+AccessibleHandler::scrollSubstringTo(long startIndex, long endIndex,
+                                     enum IA2ScrollType scrollType)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->scrollSubstringTo(startIndex, endIndex,
+                                                 scrollType);
+}
+
+HRESULT
+AccessibleHandler::scrollSubstringToPoint(long startIndex, long endIndex,
+                                          enum IA2CoordinateType coordinateType,
+                                          long x, long y)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->scrollSubstringToPoint(startIndex, endIndex,
+                                                      coordinateType, x, y);
+}
+
+HRESULT
+AccessibleHandler::get_newText(IA2TextSegment *newText)
+{
+  if (!newText) {
+    return E_INVALIDARG;
+  }
+
+  RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetSingleton());
+  MOZ_ASSERT(ctl);
+  if (!ctl) {
+    return S_OK;
+  }
+
+  long id;
+  HRESULT hr = this->get_uniqueID(&id);
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return ctl->GetNewText(id, WrapNotNull(newText));
+}
+
+HRESULT
+AccessibleHandler::get_oldText(IA2TextSegment *oldText)
+{
+  if (!oldText) {
+    return E_INVALIDARG;
+  }
+
+  RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetSingleton());
+  MOZ_ASSERT(ctl);
+  if (!ctl) {
+    return S_OK;
+  }
+
+  long id;
+  HRESULT hr = this->get_uniqueID(&id);
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return ctl->GetOldText(id, WrapNotNull(oldText));
+}
+
+/*** IAccessibleHypertext ***/
+
+HRESULT
+AccessibleHandler::get_nHyperlinks(long *hyperlinkCount)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_nHyperlinks(hyperlinkCount);
+}
+
+HRESULT
+AccessibleHandler::get_hyperlink(long index,
+                                 IAccessibleHyperlink **hyperlink)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_hyperlink(index, hyperlink);
+}
+
+HRESULT
+AccessibleHandler::get_hyperlinkIndex(long charIndex, long *hyperlinkIndex)
+{
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_hyperlinkIndex(charIndex, hyperlinkIndex);
+}
+
+/*** IAccessibleHypertext2 ***/
+
+HRESULT
+AccessibleHandler::get_hyperlinks(IAccessibleHyperlink*** hyperlinks,
+                                  long* nHyperlinks)
+{
+  if (!hyperlinks || !nHyperlinks) {
+    return E_INVALIDARG;
+  }
+
+  if (mCachedNHyperlinks >= 0) {
+    // We have cached hyperlinks.
+    *hyperlinks = mCachedHyperlinks;
+    *nHyperlinks = mCachedNHyperlinks;
+    // The client will clean these up. (We only keep the cache for one call.)
+    mCachedHyperlinks = nullptr;
+    mCachedNHyperlinks = -1;
+    return mCachedNHyperlinks == 0 ? S_FALSE : S_OK;
+  }
+
+  HRESULT hr = ResolveIAHypertext();
+  if (FAILED(hr)) {
+    return hr;
+  }
+
+  return mIAHypertextPassThru->get_hyperlinks(hyperlinks, nHyperlinks);
+}
+
 } // namespace a11y
 } // namespace mozilla
 
 extern "C" HRESULT __stdcall
 ProxyDllCanUnloadNow();
 
 extern "C" HRESULT __stdcall
 DllCanUnloadNow()
--- a/accessible/ipc/win/handler/AccessibleHandler.h
+++ b/accessible/ipc/win/handler/AccessibleHandler.h
@@ -31,16 +31,17 @@ import NEWEST_IA2_IDL;
 #include "HandlerData.h"
 
 #include <windows.h>
 
 #if !defined(MOZILLA_INTERNAL_API)
 
 #include "Accessible2_3.h"
 #include "AccessibleHyperlink.h"
+#include "AccessibleHypertext2.h"
 #include "AccessibleTableCell.h"
 #include "Handler.h"
 #include "mozilla/mscom/StructStream.h"
 #include "mozilla/UniquePtr.h"
 
 #include <ocidl.h>
 #include <servprov.h>
 
@@ -48,16 +49,17 @@ namespace mozilla {
 namespace a11y {
 
 class AccessibleHandler final : public mscom::Handler
                               , public NEWEST_IA2_INTERFACE
                               , public IServiceProvider
                               , public IProvideClassInfo
                               , public IAccessibleHyperlink
                               , public IAccessibleTableCell
+                              , public IAccessibleHypertext2
 {
 public:
   static HRESULT Create(IUnknown* aOuter, REFIID aIid, void** aOutInterface);
 
   // mscom::Handler
   HRESULT QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid,
                                 void** aOutInterface) override;
   HRESULT ReadHandlerPayload(IStream* aStream, REFIID aIid) override;
@@ -185,25 +187,78 @@ public:
                                   long* nRowHeaderCells) override;
   STDMETHODIMP get_rowIndex(long* rowIndex) override;
   STDMETHODIMP get_isSelected(boolean* isSelected) override;
   STDMETHODIMP get_rowColumnExtents(long* row, long* column,
                                     long* rowExtents, long* columnExtents,
                                     boolean* isSelected) override;
   STDMETHODIMP get_table(IUnknown** table) override;
 
+  // IAccessibleText
+  STDMETHODIMP addSelection(long startOffset, long endOffset) override;
+  STDMETHODIMP get_attributes(long offset, long *startOffset, long *endOffset,
+                              BSTR *textAttributes) override;
+  STDMETHODIMP get_caretOffset(long *offset) override;
+  STDMETHODIMP get_characterExtents(long offset,
+                                    enum IA2CoordinateType coordType, long *x,
+                                    long *y, long *width, long *height) override;
+  STDMETHODIMP get_nSelections(long *nSelections) override;
+  STDMETHODIMP get_offsetAtPoint(long x, long y,
+                                 enum IA2CoordinateType coordType,
+                                 long *offset) override;
+  STDMETHODIMP get_selection(long selectionIndex, long *startOffset,
+                             long *endOffset) override;
+  STDMETHODIMP get_text(long startOffset, long endOffset, BSTR *text) override;
+  STDMETHODIMP get_textBeforeOffset(long offset,
+                                    enum IA2TextBoundaryType boundaryType,
+                                    long *startOffset, long *endOffset,
+                                    BSTR *text) override;
+  STDMETHODIMP get_textAfterOffset(long offset,
+                                   enum IA2TextBoundaryType boundaryType,
+                                   long *startOffset, long *endOffset,
+                                   BSTR *text) override;
+  STDMETHODIMP get_textAtOffset(long offset,
+                                enum IA2TextBoundaryType boundaryType,
+                                long *startOffset, long *endOffset,
+                                BSTR *text) override;
+  STDMETHODIMP removeSelection(long selectionIndex) override;
+  STDMETHODIMP setCaretOffset(long offset) override;
+  STDMETHODIMP setSelection(long selectionIndex, long startOffset,
+                            long endOffset) override;
+  STDMETHODIMP get_nCharacters(long *nCharacters) override;
+  STDMETHODIMP scrollSubstringTo(long startIndex, long endIndex,
+                                 enum IA2ScrollType scrollType) override;
+  STDMETHODIMP scrollSubstringToPoint(long startIndex, long endIndex,
+                                      enum IA2CoordinateType coordinateType,
+                                      long x, long y) override;
+  STDMETHODIMP get_newText(IA2TextSegment *newText) override;
+  STDMETHODIMP get_oldText(IA2TextSegment *oldText) override;
+
+  // IAccessibleHypertext
+  STDMETHODIMP get_nHyperlinks(long *hyperlinkCount) override;
+  STDMETHODIMP get_hyperlink(long index,
+                             IAccessibleHyperlink **hyperlink) override;
+  STDMETHODIMP get_hyperlinkIndex(long charIndex, long *hyperlinkIndex) override;
+
+  // IAccessibleHypertext2
+  STDMETHODIMP get_hyperlinks(IAccessibleHyperlink*** hyperlinks,
+                              long* nHyperlinks) override;
+
 private:
   AccessibleHandler(IUnknown* aOuter, HRESULT* aResult);
   virtual ~AccessibleHandler();
 
   HRESULT ResolveIA2();
   HRESULT ResolveIDispatch();
   HRESULT ResolveIAHyperlink();
+  HRESULT ResolveIAHypertext();
   HRESULT ResolveIATableCell();
   HRESULT MaybeUpdateCachedData();
+  HRESULT GetAllTextInfo(BSTR* aText);
+  void ClearTextCache();
 
   RefPtr<IUnknown>                  mDispatchUnk;
   /**
    * Handlers aggregate their proxies. This means that their proxies delegate
    * their IUnknown implementation to us.
    *
    * mDispatchUnk and the result of Handler::GetProxy() are both strong
    * references to the aggregated objects. OTOH, any interfaces that are QI'd
@@ -220,19 +275,24 @@ private:
    * It is safe for us to use these raw pointers because the aggregated
    * objects's lifetimes are proper subsets of our own lifetime.
    */
   IDispatch*                        mDispatch;         // weak
   NEWEST_IA2_INTERFACE*             mIA2PassThru;      // weak
   IServiceProvider*                 mServProvPassThru; // weak
   IAccessibleHyperlink*             mIAHyperlinkPassThru; // weak
   IAccessibleTableCell*             mIATableCellPassThru; // weak
+  IAccessibleHypertext2*             mIAHypertextPassThru; // weak
   IA2Payload                        mCachedData;
   UniquePtr<mscom::StructToStream>  mSerializer;
   uint32_t                          mCacheGen;
+  IAccessibleHyperlink**            mCachedHyperlinks;
+  long                              mCachedNHyperlinks;
+  IA2TextSegment*                   mCachedTextAttribRuns;
+  long                              mCachedNTextAttribRuns;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif // !defined(MOZILLA_INTERNAL_API)
 
 #endif // defined(__midl)
deleted file mode 100644
--- a/accessible/ipc/win/handler/AccessibleTextTearoff.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if defined(MOZILLA_INTERNAL_API)
-#error This code is NOT for internal Gecko use!
-#endif // defined(MOZILLA_INTERNAL_API)
-
-#include "AccessibleTextTearoff.h"
-
-#include "AccessibleHandlerControl.h"
-#include "AccessibleText_i.c"
-#include "AccessibleHypertext_i.c"
-#include "AccessibleHypertext2_i.c"
-#include "Factory.h"
-
-#include "mozilla/Assertions.h"
-
-namespace mozilla {
-namespace a11y {
-
-AccessibleTextTearoff::AccessibleTextTearoff(AccessibleHandler* aHandler)
-  : mHandler(aHandler)
-{
-  MOZ_ASSERT(aHandler);
-}
-
-HRESULT
-AccessibleTextTearoff::ResolveAccHypertext()
-{
-  if (mAccHypertextProxy) {
-    return S_OK;
-  }
-
-  RefPtr<IUnknown> proxy(mHandler->GetProxy());
-  if (!proxy) {
-    return E_UNEXPECTED;
-  }
-
-  return proxy->QueryInterface(IID_IAccessibleHypertext2,
-                               getter_AddRefs(mAccHypertextProxy));
-}
-
-IMPL_IUNKNOWN_QUERY_HEAD(AccessibleTextTearoff)
-IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleText)
-IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleHypertext)
-IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleHypertext2)
-IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mHandler)
-
-HRESULT
-AccessibleTextTearoff::addSelection(long startOffset, long endOffset)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->addSelection(startOffset, endOffset);
-}
-
-HRESULT
-AccessibleTextTearoff::get_attributes(long offset, long *startOffset,
-                                      long *endOffset, BSTR *textAttributes)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_attributes(offset, startOffset, endOffset,
-                                       textAttributes);
-}
-
-HRESULT
-AccessibleTextTearoff::get_caretOffset(long *offset)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_caretOffset(offset);
-}
-
-HRESULT
-AccessibleTextTearoff::get_characterExtents(long offset,
-                                            enum IA2CoordinateType coordType,
-                                            long *x, long *y, long *width,
-                                            long *height)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_characterExtents(offset, coordType, x, y, width,
-                                             height);
-}
-
-HRESULT
-AccessibleTextTearoff::get_nSelections(long *nSelections)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_nSelections(nSelections);
-}
-
-HRESULT
-AccessibleTextTearoff::get_offsetAtPoint(long x, long y,
-                                         enum IA2CoordinateType coordType,
-                                         long *offset)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_offsetAtPoint(x, y, coordType, offset);
-}
-
-HRESULT
-AccessibleTextTearoff::get_selection(long selectionIndex, long *startOffset,
-                                     long *endOffset)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_selection(selectionIndex, startOffset, endOffset);
-}
-
-HRESULT
-AccessibleTextTearoff::get_text(long startOffset, long endOffset, BSTR *text)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_text(startOffset, endOffset, text);
-}
-
-HRESULT
-AccessibleTextTearoff::get_textBeforeOffset(long offset,
-                                            enum IA2TextBoundaryType boundaryType,
-                                            long *startOffset, long *endOffset,
-                                            BSTR *text)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_textBeforeOffset(offset, boundaryType, startOffset,
-                                             endOffset, text);
-}
-
-HRESULT
-AccessibleTextTearoff::get_textAfterOffset(long offset,
-                                           enum IA2TextBoundaryType boundaryType,
-                                           long *startOffset, long *endOffset,
-                                           BSTR *text)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_textAfterOffset(offset, boundaryType,
-                                            startOffset, endOffset, text);
-}
-
-HRESULT
-AccessibleTextTearoff::get_textAtOffset(long offset,
-                                        enum IA2TextBoundaryType boundaryType,
-                                        long *startOffset, long *endOffset,
-                                        BSTR *text)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_textAtOffset(offset, boundaryType, startOffset,
-                                         endOffset, text);
-}
-
-HRESULT
-AccessibleTextTearoff::removeSelection(long selectionIndex)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->removeSelection(selectionIndex);
-}
-
-HRESULT
-AccessibleTextTearoff::setCaretOffset(long offset)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->setCaretOffset(offset);
-}
-
-HRESULT
-AccessibleTextTearoff::setSelection(long selectionIndex, long startOffset,
-                                    long endOffset)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->setSelection(selectionIndex, startOffset, endOffset);
-}
-
-HRESULT
-AccessibleTextTearoff::get_nCharacters(long *nCharacters)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_nCharacters(nCharacters);
-}
-
-HRESULT
-AccessibleTextTearoff::scrollSubstringTo(long startIndex, long endIndex,
-                                         enum IA2ScrollType scrollType)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->scrollSubstringTo(startIndex, endIndex, scrollType);
-}
-
-HRESULT
-AccessibleTextTearoff::scrollSubstringToPoint(long startIndex, long endIndex,
-                                              enum IA2CoordinateType coordinateType,
-                                              long x, long y)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->scrollSubstringToPoint(startIndex, endIndex,
-                                               coordinateType, x, y);
-}
-
-HRESULT
-AccessibleTextTearoff::get_newText(IA2TextSegment *newText)
-{
-  if (!newText) {
-    return E_INVALIDARG;
-  }
-
-  RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetSingleton());
-  MOZ_ASSERT(ctl);
-  if (!ctl) {
-    return S_OK;
-  }
-
-  long id;
-  HRESULT hr = mHandler->get_uniqueID(&id);
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return ctl->GetNewText(id, WrapNotNull(newText));
-}
-
-HRESULT
-AccessibleTextTearoff::get_oldText(IA2TextSegment *oldText)
-{
-  if (!oldText) {
-    return E_INVALIDARG;
-  }
-
-  RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetSingleton());
-  MOZ_ASSERT(ctl);
-  if (!ctl) {
-    return S_OK;
-  }
-
-  long id;
-  HRESULT hr = mHandler->get_uniqueID(&id);
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return ctl->GetOldText(id, WrapNotNull(oldText));
-}
-
-HRESULT
-AccessibleTextTearoff::get_nHyperlinks(long *hyperlinkCount)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_nHyperlinks(hyperlinkCount);
-}
-
-HRESULT
-AccessibleTextTearoff::get_hyperlink(long index,
-                                     IAccessibleHyperlink **hyperlink)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_hyperlink(index, hyperlink);
-}
-
-HRESULT
-AccessibleTextTearoff::get_hyperlinkIndex(long charIndex, long *hyperlinkIndex)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_hyperlinkIndex(charIndex, hyperlinkIndex);
-}
-
-HRESULT
-AccessibleTextTearoff::get_hyperlinks(IAccessibleHyperlink*** hyperlinks,
-                                      long* nHyperlinks)
-{
-  HRESULT hr = ResolveAccHypertext();
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  return mAccHypertextProxy->get_hyperlinks(hyperlinks, nHyperlinks);
-}
-
-} // namespace a11y
-} // namespace mozilla
deleted file mode 100644
--- a/accessible/ipc/win/handler/AccessibleTextTearoff.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if defined(MOZILLA_INTERNAL_API)
-#error This code is NOT for internal Gecko use!
-#endif // defined(MOZILLA_INTERNAL_API)
-
-#ifndef mozilla_a11y_AccessibleTextTearoff_h
-#define mozilla_a11y_AccessibleTextTearoff_h
-
-#include "AccessibleHandler.h"
-#include "AccessibleHypertext2.h"
-#include "IUnknownImpl.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-namespace a11y {
-
-class AccessibleTextTearoff final : public IAccessibleHypertext2
-{
-public:
-  explicit AccessibleTextTearoff(AccessibleHandler* aHandler);
-
-  DECL_IUNKNOWN
-
-  // IAccessibleText
-  STDMETHODIMP addSelection(long startOffset, long endOffset) override;
-  STDMETHODIMP get_attributes(long offset, long *startOffset, long *endOffset,
-                              BSTR *textAttributes) override;
-  STDMETHODIMP get_caretOffset(long *offset) override;
-  STDMETHODIMP get_characterExtents(long offset,
-                                    enum IA2CoordinateType coordType, long *x,
-                                    long *y, long *width, long *height) override;
-  STDMETHODIMP get_nSelections(long *nSelections) override;
-  STDMETHODIMP get_offsetAtPoint(long x, long y,
-                                 enum IA2CoordinateType coordType,
-                                 long *offset) override;
-  STDMETHODIMP get_selection(long selectionIndex, long *startOffset,
-                             long *endOffset) override;
-  STDMETHODIMP get_text(long startOffset, long endOffset, BSTR *text) override;
-  STDMETHODIMP get_textBeforeOffset(long offset,
-                                    enum IA2TextBoundaryType boundaryType,
-                                    long *startOffset, long *endOffset,
-                                    BSTR *text) override;
-  STDMETHODIMP get_textAfterOffset(long offset,
-                                   enum IA2TextBoundaryType boundaryType,
-                                   long *startOffset, long *endOffset,
-                                   BSTR *text) override;
-  STDMETHODIMP get_textAtOffset(long offset,
-                                enum IA2TextBoundaryType boundaryType,
-                                long *startOffset, long *endOffset,
-                                BSTR *text) override;
-  STDMETHODIMP removeSelection(long selectionIndex) override;
-  STDMETHODIMP setCaretOffset(long offset) override;
-  STDMETHODIMP setSelection(long selectionIndex, long startOffset,
-                            long endOffset) override;
-  STDMETHODIMP get_nCharacters(long *nCharacters) override;
-  STDMETHODIMP scrollSubstringTo(long startIndex, long endIndex,
-                                 enum IA2ScrollType scrollType) override;
-  STDMETHODIMP scrollSubstringToPoint(long startIndex, long endIndex,
-                                      enum IA2CoordinateType coordinateType,
-                                      long x, long y) override;
-  STDMETHODIMP get_newText(IA2TextSegment *newText) override;
-  STDMETHODIMP get_oldText(IA2TextSegment *oldText) override;
-
-  // IAccessibleHypertext
-  STDMETHODIMP get_nHyperlinks(long *hyperlinkCount) override;
-  STDMETHODIMP get_hyperlink(long index,
-                             IAccessibleHyperlink **hyperlink) override;
-  STDMETHODIMP get_hyperlinkIndex(long charIndex, long *hyperlinkIndex) override;
-
-  // IAccessibleHypertext2
-  STDMETHODIMP get_hyperlinks(IAccessibleHyperlink*** hyperlinks,
-                              long* nHyperlinks) override;
-
-private:
-  ~AccessibleTextTearoff() = default;
-  HRESULT ResolveAccHypertext();
-
-  RefPtr<AccessibleHandler>     mHandler;
-  RefPtr<IAccessibleHypertext2>  mAccHypertextProxy;
-};
-
-} // namespace a11y
-} // namespace mozilla
-
-#endif // mozilla_a11y_AccessibleTextTearoff_h
--- a/accessible/ipc/win/handler/HandlerData.idl
+++ b/accessible/ipc/win/handler/HandlerData.idl
@@ -147,16 +147,21 @@ interface IHandlerControl : IUnknown
 
 [object,
  uuid(IGECKOBACKCHANNEL_IID),
  pointer_default(unique)]
 interface IGeckoBackChannel : IUnknown
 {
   [propput] HRESULT HandlerControl([in] long aPid, [in] IHandlerControl* aCtrl);
   HRESULT Refresh([out] DynamicIA2Data* aOutData);
+  [propget] HRESULT AllTextInfo([out] BSTR* aText,
+    [out, size_is(,*aNHyperlinks)] IAccessibleHyperlink*** aHyperlinks,
+    [out] long* aNHyperlinks,
+    [out, size_is(,*aNAttribRuns)] IA2TextSegment** aAttribRuns,
+    [out] long* aNAttribRuns);
 }
 
 [uuid(1e545f07-f108-4912-9471-546827a80983)]
 library AccessibleHandlerTypeLib
 {
   /**
    * This definition is required in order for the handler implementation to
    * support IDispatch (aka Automation). This is used by interpreted language
--- a/accessible/ipc/win/handler/HandlerDataCleanup.h
+++ b/accessible/ipc/win/handler/HandlerDataCleanup.h
@@ -9,16 +9,46 @@
 
 #include <OleAuto.h>
 #include "HandlerData.h"
 
 namespace mozilla {
 namespace a11y {
 
 inline void
+ReleaseStaticIA2DataInterfaces(StaticIA2Data& aData)
+{
+  // Only interfaces of the proxied object wrapped by this handler should be
+  // released here, never other objects!
+  // For example, if StaticIA2Data were to include accParent in future,
+  // that must not be released here.
+  if (aData.mIA2) {
+    aData.mIA2->Release();
+  }
+  if (aData.mIEnumVARIANT) {
+    aData.mIEnumVARIANT->Release();
+  }
+  if (aData.mIAHypertext) {
+    aData.mIAHypertext->Release();
+  }
+  if (aData.mIAHyperlink) {
+    aData.mIAHyperlink->Release();
+  }
+  if (aData.mIATable) {
+    aData.mIATable->Release();
+  }
+  if (aData.mIATable2) {
+    aData.mIATable2->Release();
+  }
+  if (aData.mIATableCell) {
+    aData.mIATableCell->Release();
+  }
+}
+
+inline void
 CleanupDynamicIA2Data(DynamicIA2Data& aData, bool aZero=true)
 {
   ::VariantClear(&aData.mRole);
   if (aData.mKeyboardShortcut) {
     ::SysFreeString(aData.mKeyboardShortcut);
   }
   if (aData.mName) {
     ::SysFreeString(aData.mName);
--- a/accessible/ipc/win/handler/moz.build
+++ b/accessible/ipc/win/handler/moz.build
@@ -18,17 +18,16 @@ LOCAL_INCLUDES += [
 
 SOURCES += [
     '!dlldata.c',
     '!HandlerData_c.c',
     '!HandlerData_i.c',
     '!HandlerData_p.c',
     'AccessibleHandler.cpp',
     'AccessibleHandlerControl.cpp',
-    'AccessibleTextTearoff.cpp',
 ]
 
 GENERATED_FILES += [
     'dlldata.c',
     'HandlerData.h',
     'HandlerData.tlb',
     'HandlerData_c.c',
     'HandlerData_i.c',
--- a/accessible/jsat/AccessFu.jsm
+++ b/accessible/jsat/AccessFu.jsm
@@ -293,17 +293,17 @@ this.AccessFu = { // jshint ignore:line
 
   _handleMessageManager: function _handleMessageManager(aMessageManager) {
     if (this._enabled) {
       this._addMessageListeners(aMessageManager);
     }
     this._loadFrameScript(aMessageManager);
   },
 
-  onEvent: function(event, data, callback) {
+  onEvent(event, data, callback) {
     switch (event) {
       case "Accessibility:Settings":
         this._systemPref = data.enabled;
         this._enableOrDisable();
         break;
       case "Accessibility:NextObject":
       case "Accessibility:PreviousObject": {
         let rule = "Simple";
@@ -420,18 +420,17 @@ this.AccessFu = { // jshint ignore:line
 
   /**
    * Adjusts the given bounds relative to the given browser.
    * @param {Rect} aJsonBounds the bounds to adjust
    * @param {browser} aBrowser the browser we want the bounds relative to
    * @param {bool} aToCSSPixels whether to convert to CSS pixels (as opposed to
    *               device pixels)
    */
-  adjustContentBounds:
-    function(aJsonBounds, aBrowser, aToCSSPixels) {
+  adjustContentBounds(aJsonBounds, aBrowser, aToCSSPixels) {
       let bounds = new Rect(aJsonBounds.left, aJsonBounds.top,
                             aJsonBounds.right - aJsonBounds.left,
                             aJsonBounds.bottom - aJsonBounds.top);
       let win = Utils.win;
       let dpr = win.devicePixelRatio;
       let offset = { left: -win.mozInnerScreenX, top: -win.mozInnerScreenY };
 
       // Add the offset; the offset is in CSS pixels, so multiply the
@@ -874,17 +873,17 @@ var Input = {
   },
 
   activateCurrent: function activateCurrent(aData, aActivateIfKey = false) {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
     let offset = aData && typeof aData.keyIndex === "number" ?
                  aData.keyIndex - Output.brailleState.startOffset : -1;
 
     mm.sendAsyncMessage("AccessFu:Activate",
-                        {offset: offset, activateIfKey: aActivateIfKey});
+                        {offset, activateIfKey: aActivateIfKey});
   },
 
   sendContextMenuMessage: function sendContextMenuMessage() {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
     mm.sendAsyncMessage("AccessFu:ContextMenu", {});
   },
 
   setEditState: function setEditState(aEditState) {
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -234,17 +234,17 @@ this.EventManager.prototype = {
           Ci.nsIAccessibleObjectAttributeChangedEvent);
         if (evt.changedAttribute !== "aria-hidden") {
           // Only handle aria-hidden attribute change.
           break;
         }
         let hidden = Utils.isHidden(aEvent.accessible);
         this[hidden ? "_handleHide" : "_handleShow"](evt);
         if (this.inTest) {
-          this.sendMsgFunc("AccessFu:AriaHidden", { hidden: hidden });
+          this.sendMsgFunc("AccessFu:AriaHidden", { hidden });
         }
         break;
       }
       case Events.SHOW:
       {
         this._handleShow(aEvent);
         break;
       }
--- a/accessible/jsat/Gestures.jsm
+++ b/accessible/jsat/Gestures.jsm
@@ -300,17 +300,17 @@ function compileDetail(aType, aPoints, k
       maxDeltaY = deltaY;
     }
     // Since the gesture is resolving, reset the points' distance information
     // since they are passed to the next potential gesture.
     point.reset();
   }
   return {
     type: aType,
-    touches: touches,
+    touches,
     deltaX: maxDeltaX,
     deltaY: maxDeltaY
   };
 }
 
 /**
  * A general gesture object.
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
--- a/accessible/jsat/OutputGenerator.jsm
+++ b/accessible/jsat/OutputGenerator.jsm
@@ -172,20 +172,23 @@ var OutputGenerator = {
     }
 
     let description = aAccessible.description;
     if (description) {
       // Compare against the calculated name unconditionally, regardless of name rule,
       // so we can make sure we don't speak duplicated descriptions
       let tmpName = name || aAccessible.name;
       if (tmpName && (description !== tmpName)) {
-        name = name || "";
-        name = this.outputOrder === OUTPUT_DESC_FIRST ?
-          description + " - " + name :
-          name + " - " + description;
+        if (name) {
+          name = this.outputOrder === OUTPUT_DESC_FIRST ?
+            description + " - " + name :
+            name + " - " + description;
+        } else {
+          name = description;
+        }
       }
     }
 
     if (!name || !name.trim()) {
       return;
     }
     aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? "push" : "unshift"](name);
   },
--- a/accessible/jsat/Presentation.jsm
+++ b/accessible/jsat/Presentation.jsm
@@ -164,17 +164,17 @@ VisualPresenter.prototype.viewportChange
     if (Utils.isAliveAndVisible(currentAcc)) {
       let bounds = (start === -1 && end === -1) ? Utils.getBounds(currentAcc) :
                    Utils.getTextBounds(currentAcc, start, end);
 
       return {
         type: this.type,
         details: {
           eventType: "viewport-change",
-          bounds: bounds,
+          bounds,
           padding: this.BORDER_PADDING
         }
       };
     }
 
     return null;
   };
 
@@ -193,17 +193,17 @@ VisualPresenter.prototype.pivotChanged =
             aContext.bounds : Utils.getTextBounds(aContext.accessibleForBounds,
                                                   aContext.startOffset,
                                                   aContext.endOffset);
 
       return {
         type: this.type,
         details: {
           eventType: "vc-change",
-          bounds: bounds,
+          bounds,
           padding: this.BORDER_PADDING
         }
       };
     } catch (e) {
       Logger.logException(e, "Failed to get bounds");
       return null;
     }
   };
@@ -292,17 +292,17 @@ AndroidPresenter.prototype.pivotChanged 
       androidEvents.push({eventType: (isExploreByTouch) ?
                            this.ANDROID_VIEW_HOVER_ENTER : focusEventType,
                          text: Utils.localize(UtteranceGenerator.genForContext(
                            aContext)),
                          bounds: aContext.bounds,
                          clickable: aContext.accessible.actionCount > 0,
                          checkable: state.contains(States.CHECKABLE),
                          checked: state.contains(States.CHECKED),
-                         brailleOutput: brailleOutput});
+                         brailleOutput});
     }
 
 
     return {
       type: this.type,
       details: androidEvents
     };
   };
@@ -318,17 +318,17 @@ AndroidPresenter.prototype.actionInvoked
       text = Utils.localize(UtteranceGenerator.genForAction(aObject,
         aActionName));
     }
 
     return {
       type: this.type,
       details: [{
         eventType: this.ANDROID_VIEW_CLICKED,
-        text: text,
+        text,
         checked: state.contains(States.CHECKED)
       }]
     };
   };
 
 AndroidPresenter.prototype.tabSelected =
   function AndroidPresenter_tabSelected(aDocContext, aVCContext) {
     // Send a pivot change message with the full context utterance for this doc.
@@ -377,17 +377,17 @@ AndroidPresenter.prototype.textSelection
         aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUserInput).details;
 
       androidEvents.push({
         eventType: this.ANDROID_VIEW_TEXT_SELECTION_CHANGED,
         text: [aText],
         fromIndex: aStart,
         toIndex: aEnd,
         itemCount: aText.length,
-        brailleOutput: brailleOutput
+        brailleOutput
       });
     }
 
     if (Utils.AndroidSdkVersion >= 16 && aIsFromUserInput) {
       let [from, to] = aOldStart < aStart ?
         [aOldStart, aStart] : [aStart, aOldStart];
       androidEvents.push({
         eventType: this.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
--- a/accessible/other/moz.build
+++ b/accessible/other/moz.build
@@ -18,10 +18,10 @@ LOCAL_INCLUDES += [
     '/accessible/base',
     '/accessible/generic',
     '/accessible/html',
     '/accessible/xul',
 ]
 
 FINAL_LIBRARY = 'xul'
 
-if CONFIG['GNU_CXX']:
+if CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     CXXFLAGS += ['-Wno-error=shadow']
--- a/accessible/tests/browser/.eslintrc.js
+++ b/accessible/tests/browser/.eslintrc.js
@@ -21,17 +21,17 @@ module.exports = {
     "curly": ["error", "multi-line"],
     "default-case": "off",
     "dot-location": ["error", "property"],
 
     "eqeqeq": "off",
     "func-names": "off",
     "func-style": "off",
     "handle-callback-err": ["error", "er"],
-    "indent": ["error", 2, {"SwitchCase": 1}],
+    "indent-legacy": ["error", 2, {"SwitchCase": 1}],
     "max-nested-callbacks": ["error", 4],
     "max-params": "off",
     "max-statements": "off",
     "new-cap": ["error", {"capIsNew": false}],
     "new-parens": "error",
     "no-bitwise": "off",
     "no-catch-shadow": "error",
     "no-comma-dangle": "off",
@@ -71,17 +71,16 @@ module.exports = {
     "no-use-before-define": "off",
     "no-var": "off",
     "no-warning-comments": "off",
     "object-shorthand": "off",
     "one-var": ["error", "never"],
     "padded-blocks": ["error", "never"],
     "quote-props": "off",
     "radix": "error",
-    "semi": ["error", "always"],
     "semi-spacing": ["error", {"before": false, "after": true}],
     "sort-vars": "off",
     "space-in-brackets": "off",
     "space-in-parens": ["error", "never"],
     "space-unary-word-ops": "off",
     "strict": ["error", "global"],
     "valid-jsdoc": "off",
     "vars-on-top": "off",
--- a/accessible/tests/browser/browser_shutdown_remote_no_reference.js
+++ b/accessible/tests/browser/browser_shutdown_remote_no_reference.js
@@ -34,16 +34,20 @@ add_task(async function() {
     await Promise.all([parentA11yInit, contentA11yInit]);
     await parentConsumersChanged.then(data => Assert.deepEqual(data, {
       XPCOM: true, MainProcess: false, PlatformAPI: false
     }, "Accessibility service consumers in parent are correct."));
     await contentConsumersChanged.then(data => Assert.deepEqual(data, {
       XPCOM: false, MainProcess: true, PlatformAPI: false
     }, "Accessibility service consumers in content are correct."));
 
+    Assert.deepEqual(JSON.parse(accService.getConsumers()), {
+      XPCOM: true, MainProcess: false, PlatformAPI: false
+    }, "Accessibility service consumers in parent are correct.");
+
     info("Removing a service in parent and waiting for service to be shut " +
       "down in content");
     // Remove a11y service reference in the main process.
     let parentA11yShutdown = shutdownPromise();
     let contentA11yShutdown = shutdownPromise(browser);
     parentConsumersChanged = a11yConsumersChangedPromise();
     contentConsumersChanged =
       ContentTask.spawn(browser, {}, a11yConsumersChangedPromise);
--- a/accessible/tests/browser/browser_shutdown_remote_own_reference.js
+++ b/accessible/tests/browser/browser_shutdown_remote_own_reference.js
@@ -42,16 +42,22 @@ add_task(async function() {
     // Add a new reference to the a11y service inside the content process.
     loadFrameScripts(browser, `let accService = Components.classes[
       '@mozilla.org/accessibilityService;1'].getService(
         Components.interfaces.nsIAccessibilityService);`);
     await contentConsumersChanged.then(data => Assert.deepEqual(data, {
       XPCOM: true, MainProcess: true, PlatformAPI: false
     }, "Accessibility service consumers in content are correct."));
 
+    const contentConsumers = await ContentTask.spawn(browser, {}, () =>
+      accService.getConsumers());
+    Assert.deepEqual(JSON.parse(contentConsumers), {
+      XPCOM: true, MainProcess: true, PlatformAPI: false
+    }, "Accessibility service consumers in parent are correct.");
+
     info("Shutting down a service in parent and making sure the one in " +
       "content stays alive");
     let contentCanShutdown = false;
     let parentA11yShutdown = shutdownPromise();
     contentConsumersChanged =
       ContentTask.spawn(browser, {}, a11yConsumersChangedPromise);
     // This promise will resolve only if contentCanShutdown flag is set to true.
     // If 'a11y-init-or-shutdown' event with '0' flag (in content) comes before
--- a/accessible/tests/browser/events/browser_test_docload.js
+++ b/accessible/tests/browser/events/browser_test_docload.js
@@ -43,22 +43,22 @@ async function runTests(browser, accDoc)
   browser.loadURI(`data:text/html;charset=utf-8,
     <html><body id="body2">
       <iframe id="iframe1" src="http://example.com"></iframe>
     </body></html>`);
 
   await onLoadEvents;
 
   onLoadEvents = waitForEvents([
-      [EVENT_DOCUMENT_LOAD_COMPLETE, urlChecker("about:")],
+      [EVENT_DOCUMENT_LOAD_COMPLETE, urlChecker("about:about")],
       [EVENT_STATE_CHANGE, busyChecker(false)],
       [EVENT_REORDER, getAccessible(browser)]
   ]);
 
-  browser.loadURI("about:");
+  browser.loadURI("about:about");
 
   await onLoadEvents;
 
   onLoadEvents = waitForEvents([
     [EVENT_DOCUMENT_RELOAD, evt => evt.isFromUserInput],
     [EVENT_REORDER, getAccessible(browser)],
     [EVENT_STATE_CHANGE, busyChecker(false)]
   ]);
--- a/accessible/tests/browser/general/browser.ini
+++ b/accessible/tests/browser/general/browser.ini
@@ -1,7 +1,8 @@
 [DEFAULT]
 support-files =
   !/accessible/tests/browser/shared-head.js
   head.js
   !/accessible/tests/mochitest/*.js
 
 [browser_test_doc_creation.js]
+[browser_test_urlbar.js]
--- a/accessible/tests/browser/general/browser_test_doc_creation.js
+++ b/accessible/tests/browser/general/browser_test_doc_creation.js
@@ -1,26 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const nsIAccessibleRole = Ci.nsIAccessibleRole; // eslint-disable-line no-unused-vars
-
-/* import-globals-from ../../mochitest/role.js */
-loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
-
-async function openNewTab(url) {
-  const forceNewProcess = true;
-
-  return BrowserTestUtils.openNewForegroundTab(
-    { gBrowser, url, forceNewProcess });
-}
-
 const tab1URL = `data:text/html,
   <html xmlns="http://www.w3.org/1999/xhtml">
     <head>
       <meta charset="utf-8"/>
       <title>First tab to be loaded</title>
     </head>
     <body>
       <butotn>JUST A BUTTON</butotn>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/general/browser_test_urlbar.js
@@ -0,0 +1,34 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+// Checking that the awesomebar popup gets COMBOBOX_LIST role instead of
+// LISTBOX, since its parent is a <panel> (see Bug 1422465)
+add_task(async function testAutocompleteRichResult() {
+  let tab = await openNewTab("data:text/html;charset=utf-8,");
+  let accService = await initAccessibilityService();
+
+  info("Opening the URL bar and entering a key to show the PopupAutoCompleteRichResult panel");
+  let urlbar = document.getElementById("urlbar");
+  urlbar.focus();
+  let urlbarPopup = document.getElementById("PopupAutoCompleteRichResult");
+  let shown = BrowserTestUtils.waitForEvent(urlbarPopup, "popupshown");
+  EventUtils.synthesizeKey("a", {});
+  await shown;
+
+  info("Waiting for accessibility to be created for the richlistbox");
+  let richlistbox = document.getAnonymousElementByAttribute(urlbarPopup, "anonid", "richlistbox");
+  await BrowserTestUtils.waitForCondition(() => accService.getAccessibleFor(richlistbox));
+
+  info("Confirming that the special case is handled in XULListboxAccessible");
+  let accessible = accService.getAccessibleFor(richlistbox);
+  is(accessible.role, ROLE_COMBOBOX_LIST, "Right role");
+
+  await BrowserTestUtils.removeTab(tab);
+});
+
+registerCleanupFunction(async function() {
+  await shutdownAccessibilityService();
+});
--- a/accessible/tests/browser/general/head.js
+++ b/accessible/tests/browser/general/head.js
@@ -1,22 +1,34 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-/* exported initAccessibilityService, shutdownAccessibilityService */
+/* exported initAccessibilityService, openNewTab, shutdownAccessibilityService */
 
 // Load the shared-head file first.
 /* import-globals-from ../shared-head.js */
 Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/accessible/tests/browser/shared-head.js",
   this);
 
+const nsIAccessibleRole = Ci.nsIAccessibleRole; // eslint-disable-line no-unused-vars
+
+/* import-globals-from ../../mochitest/role.js */
+loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
+
+async function openNewTab(url) {
+  const forceNewProcess = true;
+
+  return BrowserTestUtils.openNewForegroundTab(
+    { gBrowser, url, forceNewProcess });
+}
+
 async function initAccessibilityService() {
   info("Create accessibility service.");
   let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
 
   await new Promise(resolve => {
     if (Services.appinfo.accessibilityEnabled) {
       resolve();
--- a/accessible/tests/browser/head.js
+++ b/accessible/tests/browser/head.js
@@ -125,18 +125,24 @@ function shutdownPromise(contentBrowser)
  * Simpler verions of waitForEvent defined in
  * accessible/tests/browser/events.js
  */
 function waitForEvent(eventType, expectedId) {
   return new Promise(resolve => {
     let eventObserver = {
       observe(subject) {
         let event = subject.QueryInterface(Ci.nsIAccessibleEvent);
+        let id;
+        try {
+          id = event.accessible.id;
+        } catch (e) {
+          // This can throw NS_ERROR_FAILURE.
+        }
         if (event.eventType === eventType &&
-            event.accessible.id === expectedId) {
+            id === expectedId) {
           Services.obs.removeObserver(this, "accessible-event");
           resolve(event);
         }
       }
     };
     Services.obs.addObserver(eventObserver, "accessible-event");
   });
 }
--- a/accessible/tests/browser/tree/browser_aria_owns.js
+++ b/accessible/tests/browser/tree/browser_aria_owns.js
@@ -213,8 +213,41 @@ addAccessibleTask(`<div id="a"></div><di
       document.documentElement.getBoundingClientRect();
       document.body.setAttribute("aria-owns", "b a");
       document.documentElement.remove();
     });
 
     testChildrenIds(accDoc, []);
   }
 );
+
+// Don't allow ordinal child to be placed after aria-owned child (bug 1405796)
+addAccessibleTask(`<div id="container"><div id="a">Hello</div></div>
+                   <div><div id="c">There</div><div id="d">There</div></div>`,
+  async function(browser, accDoc) {
+    let containerAcc = findAccessibleChildByID(accDoc, "container");
+
+    testChildrenIds(containerAcc, ["a"]);
+
+    await contentSpawnMutation(browser, MOVE, function() {
+      document.getElementById("container").setAttribute("aria-owns", "c");
+    });
+
+    testChildrenIds(containerAcc, ["a", "c"]);
+
+    await contentSpawnMutation(browser, MOVE, function() {
+      let span = document.createElement("span");
+      document.getElementById("container").appendChild(span);
+
+      let b = document.createElement("div");
+      b.id = "b";
+      document.getElementById("container").appendChild(b);
+    });
+
+    testChildrenIds(containerAcc, ["a", "b", "c"]);
+
+    await contentSpawnMutation(browser, MOVE, function() {
+      document.getElementById("container").setAttribute("aria-owns", "c d");
+    });
+
+    testChildrenIds(containerAcc, ["a", "b", "c", "d"]);
+  }
+);
--- a/accessible/tests/mochitest/.eslintrc.js
+++ b/accessible/tests/mochitest/.eslintrc.js
@@ -6,19 +6,12 @@ module.exports = {
   ],
   "rules": {
     "mozilla/no-cpows-in-tests": "error",
     "mozilla/reject-importGlobalProperties": "error",
 
     // XXX These are rules that are enabled in the recommended configuration, but
     // disabled here due to failures when initially implemented. They should be
     // removed (and hence enabled) at some stage.
-    "comma-spacing": "off",
-    "no-cond-assign": "off",
-    "no-lonely-if": "off",
     "no-nested-ternary": "off",
-    "no-new-object": "off",
-    "no-redeclare": "off",
-    "no-shadow": "off",
     "no-undef": "off",
-    "space-unary-ops": "off",
   }
 };
--- a/accessible/tests/mochitest/actions.js
+++ b/accessible/tests/mochitest/actions.js
@@ -59,26 +59,26 @@ function testActions(aArray) {
     var events = actionObj.events;
     var accOrElmOrIDOfTarget = actionObj.targetID ?
       actionObj.targetID : accOrElmOrID;
 
     var eventSeq = [];
     if (events) {
       var elm = getNode(accOrElmOrIDOfTarget);
       if (events & MOUSEDOWN_EVENT)
-        eventSeq.push(new checkerOfActionInvoker("mousedown", elm));
+        eventSeq.push(new checkerOfActionInvoker("mousedown", elm, actionObj));
 
       if (events & MOUSEUP_EVENT)
-        eventSeq.push(new checkerOfActionInvoker("mouseup", elm));
+        eventSeq.push(new checkerOfActionInvoker("mouseup", elm, actionObj));
 
       if (events & CLICK_EVENT)
         eventSeq.push(new checkerOfActionInvoker("click", elm, actionObj));
 
       if (events & COMMAND_EVENT)
-        eventSeq.push(new checkerOfActionInvoker("command", elm));
+        eventSeq.push(new checkerOfActionInvoker("command", elm, actionObj));
 
       if (events & FOCUS_EVENT)
         eventSeq.push(new focusChecker(elm));
     }
 
     if (actionObj.eventSeq)
       eventSeq = eventSeq.concat(actionObj.eventSeq);
 
@@ -143,24 +143,28 @@ function actionInvoker(aAccOrElmOrId, aA
   };
 }
 
 function checkerOfActionInvoker(aType, aTarget, aActionObj) {
   this.type = aType;
 
   this.target = aTarget;
 
+  if (aActionObj && "eventTarget" in aActionObj) {
+    this.eventTarget = aActionObj.eventTarget;
+  }
+
   this.phase = false;
 
   this.getID = function getID() {
     return aType + " event handling";
   };
 
   this.check = function check(aEvent) {
-    if (aActionObj && "checkOnClickEvent" in aActionObj)
+    if (aType == "click" && aActionObj && "checkOnClickEvent" in aActionObj)
       aActionObj.checkOnClickEvent(aEvent);
   };
 }
 
 var gActionDescrMap =
 {
   jump: "Jump",
   press: "Press",
--- a/accessible/tests/mochitest/actions/test_link.html
+++ b/accessible/tests/mochitest/actions/test_link.html
@@ -19,17 +19,17 @@
   <script type="application/javascript">
     function getAnchorTargetDocumentAcc() {
       var thisTabDocAcc = getTabDocAccessible();
       var thisDocTabPanelAcc = thisTabDocAcc.parent.parent;
       var tabPanelsAcc = thisDocTabPanelAcc.parent;
       var newDocTabPanelAcc = tabPanelsAcc.firstChild;
       var nextAcc = newDocTabPanelAcc;
 
-      while (nextAcc = nextAcc.nextSibling) {
+      while ((nextAcc = nextAcc.nextSibling)) {
         // Find the last accessible for a browser with about:mozilla loaded.
         if (nextAcc.firstChild.DOMNode.currentURI.spec == "about:mozilla") {
           newDocTabPanelAcc = nextAcc;
         }
       }
 
       return newDocTabPanelAcc.firstChild.firstChild;
     }
--- a/accessible/tests/mochitest/actions/test_media.html
+++ b/accessible/tests/mochitest/actions/test_media.html
@@ -59,32 +59,34 @@ https://bugzilla.mozilla.org/show_bug.cg
       var playBtn = audioElm.firstChild;
       // var scrubber = playBtn.nextSibling.nextSibling.nextSibling;
       var muteBtn = audioElm.lastChild.previousSibling;
 
       var actions = [
         {
           ID: muteBtn,
           actionName: "press",
+          eventTarget: "element",
           eventSeq: [
      //       new focusChecker(muteBtn),
             new nameChecker(muteBtn, "Unmute"),
           ]
         },
      //   {
      //     ID: scrubber,
      //     actionName: "activate",
      //     events: null,
      //     eventSeq: [
      //       new focusChecker(scrubber)
      //     ]
      //   },
         {
           ID: playBtn,
           actionName: "press",
+          eventTarget: "element",
           eventSeq: [
      //       new focusChecker(playBtn),
             new nameChecker(playBtn, "Pause"),
           ]
         }
       ];
 
       testActions(actions); // Will call SimpleTest.finish();
--- a/accessible/tests/mochitest/aom/test_general.html
+++ b/accessible/tests/mochitest/aom/test_general.html
@@ -67,17 +67,17 @@
         states = [
           "readonly", "busy", "focusable", "opaque", "stale", "enabled", "sensitive"
         ];
         break;
       default:
         ok(false, "Unexpected amount of states");
     }
     if (states) {
-      for (var i = 0; i < states.length; i++) {
+      for (let i = 0; i < states.length; i++) {
         is(anode.states[i], states[i], `${states[i]} state is expected at ${i}th index`);
       }
     }
 
     ok(anode.is("document", "focusable"),
        "correct role and state on an accessible node");
 
     is(anode.get("explicit-name"), "true",
@@ -91,17 +91,17 @@
       attrs = [
         "margin-left", "text-align", "text-indent", "margin-right",
         "tag", "margin-top", "margin-bottom", "display",
         "explicit-name"
       ];
     }
 
     is(anode.attributes.length, attrs.length, "correct number of attributes");
-    for (var i = 0; i < attrs.length; i++) {
+    for (let i = 0; i < attrs.length; i++) {
       ok(attrs.indexOf(anode.attributes[i]) >= 0,
          `${anode.attributes[i]} attribute is expected and found`);
     }
 
     finish();
   }
   </script>
 </head>
--- a/accessible/tests/mochitest/attributes.js
+++ b/accessible/tests/mochitest/attributes.js
@@ -75,28 +75,28 @@ function testGroupAttrs(aAccOrElmOrID, a
   acc.groupPosition(levelObj, setSizeObj, posInSetObj);
 
   if (aPosInSet && aSetSize) {
     is(posInSetObj.value, aPosInSet,
        "Wrong group position (posinset) for " + prettyName(aAccOrElmOrID));
     is(setSizeObj.value, aSetSize,
        "Wrong size of the group (setsize) for " + prettyName(aAccOrElmOrID));
 
-    var attrs = {
+    let attrs = {
       "posinset": String(aPosInSet),
       "setsize": String(aSetSize)
     };
     testAttrs(aAccOrElmOrID, attrs, true);
   }
 
   if (aLevel) {
     is(levelObj.value, aLevel,
        "Wrong group level for " + prettyName(aAccOrElmOrID));
 
-    var attrs = { "level": String(aLevel) };
+    let attrs = { "level": String(aLevel) };
     testAttrs(aAccOrElmOrID, attrs, true);
   }
 }
 
 // //////////////////////////////////////////////////////////////////////////////
 // Text attributes.
 
 /**
@@ -138,20 +138,20 @@ function testTextAttrs(aID, aOffset, aAt
 
   is(startOffset.value, aStartOffset, "Wrong start offset" + errorMsg);
   is(endOffset.value, aEndOffset, "Wrong end offset" + errorMsg);
 
   compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs);
 
   // include attributes exposed on hyper text accessible
   var expectedAttrs = {};
-  for (var name in aAttrs)
+  for (let name in aAttrs)
     expectedAttrs[name] = aAttrs[name];
 
-  for (var name in aDefAttrs) {
+  for (let name in aDefAttrs) {
     if (!(name in expectedAttrs))
       expectedAttrs[name] = aDefAttrs[name];
   }
 
   attrs = getTextAttributes(aID, accessible, true, aOffset,
                             startOffset, endOffset);
 
   if (!attrs)
@@ -194,17 +194,17 @@ function testDefaultTextAttrs(aID, aDefA
  * Test text attributes for wrong offset.
  */
 function testTextAttrsWrongOffset(aID, aOffset) {
   var res = false;
   try {
   var s = {}, e = {};
   var acc = getAccessible(ID, [nsIAccessibleText]);
     acc.getTextAttributes(false, 157, s, e);
-  } catch (e) {
+  } catch (ex) {
     res = true;
   }
 
   ok(res,
      "text attributes are calculated successfully at wrong offset " + aOffset + " for " + prettyName(aID));
 }
 
 const kNormalFontWeight =
@@ -316,17 +316,17 @@ function testAttrsInternal(aAccOrElmOrID
   compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs, aAbsentAttrs);
 }
 
 function compareAttrs(aErrorMsg, aAttrs, aExpectedAttrs, aSkipUnexpectedAttrs,
                       aAbsentAttrs) {
   // Check if all obtained attributes are expected and have expected value.
   var enumerate = aAttrs.enumerate();
   while (enumerate.hasMoreElements()) {
-    var prop = enumerate.getNext().QueryInterface(nsIPropertyElement);
+    let prop = enumerate.getNext().QueryInterface(nsIPropertyElement);
 
     if (!(prop.key in aExpectedAttrs)) {
       if (!aSkipUnexpectedAttrs)
         ok(false, "Unexpected attribute '" + prop.key + "' having '" +
            prop.value + "'" + aErrorMsg);
     } else {
       var msg = "Attribute '" + prop.key + "' has wrong value" + aErrorMsg;
       var expectedValue = aExpectedAttrs[prop.key];
@@ -334,35 +334,35 @@ function compareAttrs(aErrorMsg, aAttrs,
       if (typeof expectedValue == "function")
         ok(expectedValue(prop.value), msg);
       else
         is(prop.value, expectedValue, msg);
     }
   }
 
   // Check if all expected attributes are presented.
-  for (var name in aExpectedAttrs) {
+  for (let name in aExpectedAttrs) {
     var value = "";
     try {
       value = aAttrs.getStringProperty(name);
     } catch (e) { }
 
     if (!value)
       ok(false,
          "There is no expected attribute '" + name + "' " + aErrorMsg);
   }
 
   // Check if all unexpected attributes are absent.
   if (aAbsentAttrs) {
     for (var name in aAbsentAttrs) {
       var wasFound = false;
 
-      var enumerate = aAttrs.enumerate();
+      enumerate = aAttrs.enumerate();
       while (enumerate.hasMoreElements()) {
-        var prop = enumerate.getNext().QueryInterface(nsIPropertyElement);
+        let prop = enumerate.getNext().QueryInterface(nsIPropertyElement);
         if (prop.key == name)
           wasFound = true;
       }
     }
 
     ok(!wasFound,
        "There is an unexpected attribute '" + name + "' " + aErrorMsg);
   }
--- a/accessible/tests/mochitest/autocomplete.js
+++ b/accessible/tests/mochitest/autocomplete.js
@@ -71,17 +71,17 @@ function ResultsHeap(aValues, aComments)
 
 ResultsHeap.prototype =
 {
   constructor: ResultsHeap,
 
   /**
    * Return AutoCompleteResult for the given search string.
    */
-  getAutoCompleteResultFor: function(aSearchString) {
+  getAutoCompleteResultFor(aSearchString) {
     var values = [], comments = [];
     for (var idx = 0; idx < this.values.length; idx++) {
       if (this.values[idx].indexOf(aSearchString) != -1) {
         values.push(this.values[idx]);
         comments.push(this.comments[idx]);
       }
     }
     return new AutoCompleteResult(values, comments);
@@ -100,36 +100,35 @@ function AutoCompleteSearch(aName, aAllR
   this.allResults = aAllResults;
 }
 
 AutoCompleteSearch.prototype =
 {
   constructor: AutoCompleteSearch,
 
   // nsIAutoCompleteSearch implementation
-  startSearch: function(aSearchString, aSearchParam, aPreviousResult,
-                        aListener) {
+  startSearch(aSearchString, aSearchParam, aPreviousResult, aListener) {
     var result = this.allResults.getAutoCompleteResultFor(aSearchString);
     aListener.onSearchResult(this, result);
   },
 
-  stopSearch: function() {},
+  stopSearch() {},
 
   // nsISupports implementation
-  QueryInterface: function(iid) {
+  QueryInterface(iid) {
     if (iid.equals(nsISupports) ||
         iid.equals(nsIFactory) ||
         iid.equals(nsIAutoCompleteSearch))
       return this;
 
     throw Components.results.NS_ERROR_NO_INTERFACE;
   },
 
   // nsIFactory implementation
-  createInstance: function(outer, iid) {
+  createInstance(outer, iid) {
     return this.QueryInterface(iid);
   },
 
   // Search name. Used by AutoCompleteController.
   name: null,
 
   // Results heap.
   allResults: null
@@ -157,44 +156,44 @@ AutoCompleteResult.prototype =
   searchResult: null,
 
   defaultIndex: 0,
 
   get matchCount() {
     return this.values.length;
   },
 
-  getValueAt: function(aIndex) {
+  getValueAt(aIndex) {
     return this.values[aIndex];
   },
 
-  getLabelAt: function(aIndex) {
+  getLabelAt(aIndex) {
     return this.getValueAt(aIndex);
   },
 
-  getCommentAt: function(aIndex) {
+  getCommentAt(aIndex) {
     return this.comments[aIndex];
   },
 
-  getStyleAt: function(aIndex) {
+  getStyleAt(aIndex) {
     return null;
   },
 
-  getImageAt: function(aIndex) {
+  getImageAt(aIndex) {
     return "";
   },
 
-  getFinalCompleteValueAt: function(aIndex) {
+  getFinalCompleteValueAt(aIndex) {
     return this.getValueAt(aIndex);
   },
 
-  removeValueAt: function(aRowIndex, aRemoveFromDb) {},
+  removeValueAt(aRowIndex, aRemoveFromDb) {},
 
   // nsISupports implementation
-  QueryInterface: function(iid) {
+  QueryInterface(iid) {
     if (iid.equals(nsISupports) ||
         iid.equals(nsIAutoCompleteResult))
       return this;
 
     throw Components.results.NS_ERROR_NO_INTERFACE;
   },
 
   // Data
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -419,17 +419,17 @@ function testAccessibleTree(aAccOrElmOrI
 
     case "absentAttributes":
       testAbsentAttrs(acc, accTree[prop]);
       break;
 
     case "interfaces": {
       var ifaces = (accTree[prop] instanceof Array) ?
         accTree[prop] : [ accTree[prop] ];
-      for (var i = 0; i < ifaces.length; i++) {
+      for (let i = 0; i < ifaces.length; i++) {
         ok((acc instanceof ifaces[i]),
            "No " + ifaces[i] + " interface on " + prettyName(acc));
       }
       break;
     }
 
     case "relations": {
       for (var rel in accTree[prop])
@@ -452,26 +452,26 @@ function testAccessibleTree(aAccOrElmOrI
 
     case "tagName":
       is(accTree[prop], acc.DOMNode.tagName, msg);
       break;
 
     case "textAttrs": {
       var prevOffset = -1;
       for (var offset in accTree[prop]) {
-        if (prevOffset != - 1) {
-          var attrs = accTree[prop][prevOffset];
+        if (prevOffset != -1) {
+          let attrs = accTree[prop][prevOffset];
           testTextAttrs(acc, prevOffset, attrs, { }, prevOffset, +offset, true);
         }
         prevOffset = +offset;
       }
 
       if (prevOffset != -1) {
         var charCount = getAccessible(acc, [nsIAccessibleText]).characterCount;
-        var attrs = accTree[prop][prevOffset];
+        let attrs = accTree[prop][prevOffset];
         testTextAttrs(acc, prevOffset, attrs, { }, prevOffset, charCount, true);
       }
 
       break;
     }
 
     default:
       if (prop.indexOf("todo_") == 0)
@@ -482,17 +482,17 @@ function testAccessibleTree(aAccOrElmOrI
   }
 
   // Test children.
   if ("children" in accTree && accTree.children instanceof Array) {
     var children = acc.children;
     var childCount = children.length;
 
     if (accTree.children.length != childCount) {
-      for (var i = 0; i < Math.max(accTree.children.length, childCount); i++) {
+      for (let i = 0; i < Math.max(accTree.children.length, childCount); i++) {
         var accChild = null, testChild = null;
         try {
           testChild = accTree.children[i];
           accChild = children.queryElementAt(i, nsIAccessible);
 
           if (!testChild) {
             ok(false, prettyName(acc) + " has an extra child at index " + i +
               " : " + prettyName(accChild));
@@ -511,18 +511,18 @@ function testAccessibleTree(aAccOrElmOrI
         } catch (e) {
           ok(false, prettyName(accTree) + " is expected to have a child at index " + i +
              " : " + prettyName(testChild) + ", original tested: " +
              prettyName(aAccOrElmOrID) + ", " + e);
         }
       }
     } else {
       if (aFlags & kSkipTreeFullCheck) {
-        for (var i = 0; i < childCount; i++) {
-          var child = children.queryElementAt(i, nsIAccessible);
+        for (let i = 0; i < childCount; i++) {
+          let child = children.queryElementAt(i, nsIAccessible);
           testAccessibleTree(child, accTree.children[i], aFlags);
         }
         return;
       }
 
       // nsIAccessible::firstChild
       var expectedFirstChild = childCount > 0 ?
         children.queryElementAt(0, nsIAccessible) : null;
@@ -535,17 +535,17 @@ function testAccessibleTree(aAccOrElmOrI
       var expectedLastChild = childCount > 0 ?
         children.queryElementAt(childCount - 1, nsIAccessible) : null;
       var lastChild = null;
       try { lastChild = acc.lastChild; } catch (e) {}
       is(lastChild, expectedLastChild,
          "Wrong last child of " + prettyName(acc));
 
       for (var i = 0; i < childCount; i++) {
-        var child = children.queryElementAt(i, nsIAccessible);
+        let child = children.queryElementAt(i, nsIAccessible);
 
         // nsIAccessible::parent
         var parent = null;
         try { parent = child.parent; } catch (e) {}
         is(parent, acc, "Wrong parent of " + prettyName(child));
 
         // nsIAccessible::indexInParent
         var indexInParent = -1;
@@ -705,32 +705,27 @@ function getLoadContext() {
                .getInterface(Ci.nsIWebNavigation)
                .QueryInterface(Ci.nsILoadContext);
 }
 
 /**
  * Return text from clipboard.
  */
 function getTextFromClipboard() {
-  var clip = Components.classes["@mozilla.org/widget/clipboard;1"].
-    getService(Components.interfaces.nsIClipboard);
-  if (!clip)
-    return "";
-
   var trans = Components.classes["@mozilla.org/widget/transferable;1"].
     createInstance(Components.interfaces.nsITransferable);
   trans.init(getLoadContext());
   if (!trans)
     return "";
 
   trans.addDataFlavor("text/unicode");
-  clip.getData(trans, clip.kGlobalClipboard);
+  Services.clipboard.getData(trans, Services.clipboard.kGlobalClipboard);
 
-  var str = new Object();
-  var strLength = new Object();
+  var str = {};
+  var strLength = {};
   trans.getTransferData("text/unicode", str, strLength);
 
   if (str)
     str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
   if (str)
     return str.data.substring(0, strLength.value / 2);
 
   return "";
@@ -761,30 +756,30 @@ function getAccessibleDOMNodeID(accessib
   } catch (e) { /* This will fail if accessible is not a proxy. */ }
 }
 
 /**
  * Return pretty name for identifier, it may be ID, DOM node or accessible.
  */
 function prettyName(aIdentifier) {
   if (aIdentifier instanceof Array) {
-    var msg = "";
+    let msg = "";
     for (var idx = 0; idx < aIdentifier.length; idx++) {
       if (msg != "")
         msg += ", ";
 
       msg += prettyName(aIdentifier[idx]);
     }
     return msg;
   }
 
   if (aIdentifier instanceof nsIAccessible) {
     var acc = getAccessible(aIdentifier);
     var domID = getAccessibleDOMNodeID(acc);
-    var msg = "[";
+    let msg = "[";
     try {
       if (Services.appinfo.browserTabsRemoteAutostart) {
         if (domID) {
           msg += `DOM node id: ${domID}, `;
         }
       } else {
         msg += `${getNodePrettyName(acc.DOMNode)}, `;
       }
--- a/accessible/tests/mochitest/editabletext/editabletext.js
+++ b/accessible/tests/mochitest/editabletext/editabletext.js
@@ -57,74 +57,74 @@ function editableTextTest(aID) {
       dump(`\nsetTextContents '${aValue}'\n`);
       var acc = getAccessible(aID, nsIAccessibleEditableText);
       acc.setTextContents(aValue);
     }
 
     aSkipStartOffset = aSkipStartOffset || 0;
     var insertTripple = aValue ?
       [ aSkipStartOffset, aSkipStartOffset + aValue.length, aValue ] : null;
-    var oldValue = getValue(aID);
+    var oldValue = getValue();
     var removeTripple = oldValue ?
       [ aSkipStartOffset, aSkipStartOffset + oldValue.length, oldValue ] : null;
 
-    this.generateTest(aID, removeTripple, insertTripple, setTextContentsInvoke,
-                      getValueChecker(aID, aValue), testID);
+    this.generateTest(removeTripple, insertTripple, setTextContentsInvoke,
+                      getValueChecker(aValue), testID);
   };
 
   /**
    * insertText test.
    */
   this.insertText = function insertText(aStr, aPos, aResStr, aResPos) {
     var testID = "insertText '" + aStr + "' at " + aPos + " for " +
       prettyName(aID);
 
     function insertTextInvoke() {
       dump(`\ninsertText '${aStr}' at ${aPos} pos\n`);
       var acc = getAccessible(aID, nsIAccessibleEditableText);
       acc.insertText(aStr, aPos);
     }
 
     var resPos = (aResPos != undefined) ? aResPos : aPos;
-    this.generateTest(aID, null, [resPos, resPos + aStr.length, aStr],
-                      insertTextInvoke, getValueChecker(aID, aResStr), testID);
+    this.generateTest(null, [resPos, resPos + aStr.length, aStr],
+                      insertTextInvoke, getValueChecker(aResStr), testID);
   };
 
   /**
    * copyText test.
    */
   this.copyText = function copyText(aStartPos, aEndPos, aClipboardStr) {
     var testID = "copyText from " + aStartPos + " to " + aEndPos + " for " +
       prettyName(aID);
 
     function copyTextInvoke() {
       var acc = getAccessible(aID, nsIAccessibleEditableText);
       acc.copyText(aStartPos, aEndPos);
     }
 
-    this.generateTest(aID, null, null, copyTextInvoke,
-                      getClipboardChecker(aID, aClipboardStr), testID);
+    this.generateTest(null, null, copyTextInvoke,
+                      getClipboardChecker(aClipboardStr), testID);
   };
 
   /**
    * copyText and pasteText test.
    */
   this.copyNPasteText = function copyNPasteText(aStartPos, aEndPos,
                                                 aPos, aResStr) {
     var testID = "copyText from " + aStartPos + " to " + aEndPos +
       "and pasteText at " + aPos + " for " + prettyName(aID);
 
     function copyNPasteTextInvoke() {
       var acc = getAccessible(aID, nsIAccessibleEditableText);
       acc.copyText(aStartPos, aEndPos);
       acc.pasteText(aPos);
     }
 
-    this.generateTest(aID, null, [aStartPos, aEndPos, getTextFromClipboard],
-                      copyNPasteTextInvoke, getValueChecker(aID, aResStr), testID);
+    this.generateTest(null, [aStartPos, aEndPos, getTextFromClipboard],
+                      copyNPasteTextInvoke, getValueChecker(aResStr), testID);
   };
 
   /**
    * cutText test.
    */
   this.cutText = function cutText(aStartPos, aEndPos, aResStr,
                                   aResStartPos, aResEndPos) {
     var testID = "cutText from " + aStartPos + " to " + aEndPos + " for " +
@@ -132,101 +132,101 @@ function editableTextTest(aID) {
 
     function cutTextInvoke() {
       var acc = getAccessible(aID, nsIAccessibleEditableText);
       acc.cutText(aStartPos, aEndPos);
     }
 
     var resStartPos = (aResStartPos != undefined) ? aResStartPos : aStartPos;
     var resEndPos = (aResEndPos != undefined) ? aResEndPos : aEndPos;
-    this.generateTest(aID, [resStartPos, resEndPos, getTextFromClipboard], null,
-                      cutTextInvoke, getValueChecker(aID, aResStr), testID);
+    this.generateTest([resStartPos, resEndPos, getTextFromClipboard], null,
+                      cutTextInvoke, getValueChecker(aResStr), testID);
   };
 
   /**
    * cutText and pasteText test.
    */
   this.cutNPasteText = function copyNPasteText(aStartPos, aEndPos,
                                                aPos, aResStr) {
     var testID = "cutText from " + aStartPos + " to " + aEndPos +
       " and pasteText at " + aPos + " for " + prettyName(aID);
 
     function cutNPasteTextInvoke() {
       var acc = getAccessible(aID, nsIAccessibleEditableText);
       acc.cutText(aStartPos, aEndPos);
       acc.pasteText(aPos);
     }
 
-    this.generateTest(aID, [aStartPos, aEndPos, getTextFromClipboard],
+    this.generateTest([aStartPos, aEndPos, getTextFromClipboard],
                       [aPos, -1, getTextFromClipboard],
-                      cutNPasteTextInvoke, getValueChecker(aID, aResStr),
+                      cutNPasteTextInvoke, getValueChecker(aResStr),
                       testID);
   };
 
   /**
    * pasteText test.
    */
   this.pasteText = function pasteText(aPos, aResStr) {
     var testID = "pasteText at " + aPos + " for " + prettyName(aID);
 
     function pasteTextInvoke() {
       var acc = getAccessible(aID, nsIAccessibleEditableText);
       acc.pasteText(aPos);
     }
 
-    this.generateTest(aID, null, [aPos, -1, getTextFromClipboard],
-                      pasteTextInvoke, getValueChecker(aID, aResStr), testID);
+    this.generateTest(null, [aPos, -1, getTextFromClipboard],
+                      pasteTextInvoke, getValueChecker(aResStr), testID);
   };
 
   /**
    * deleteText test.
    */
   this.deleteText = function deleteText(aStartPos, aEndPos, aResStr) {
     var testID = "deleteText from " + aStartPos + " to " + aEndPos +
       " for " + prettyName(aID);
 
-    var oldValue = getValue(aID).substring(aStartPos, aEndPos);
+    var oldValue = getValue().substring(aStartPos, aEndPos);
     var removeTripple = oldValue ? [aStartPos, aEndPos, oldValue] : null;
 
     function deleteTextInvoke() {
       var acc = getAccessible(aID, [nsIAccessibleEditableText]);
       acc.deleteText(aStartPos, aEndPos);
     }
 
-    this.generateTest(aID, removeTripple, null, deleteTextInvoke,
-                      getValueChecker(aID, aResStr), testID);
+    this.generateTest(removeTripple, null, deleteTextInvoke,
+                      getValueChecker(aResStr), testID);
   };
 
   // ////////////////////////////////////////////////////////////////////////////
   // Implementation details.
 
-  function getValue(aID) {
+  function getValue() {
     var elm = getNode(aID);
     if (elm instanceof Components.interfaces.nsIDOMNSEditableElement)
       return elm.value;
 
     if (elm instanceof Components.interfaces.nsIDOMHTMLDocument)
       return elm.body.textContent;
 
     return elm.textContent;
   }
 
   /**
    * Common checkers.
    */
-  function getValueChecker(aID, aValue) {
+  function getValueChecker(aValue) {
     var checker = {
       check: function valueChecker_check() {
-        is(getValue(aID), aValue, "Wrong value " + aValue);
+        is(getValue(), aValue, "Wrong value " + aValue);
       }
     };
     return checker;
   }
 
-  function getClipboardChecker(aID, aText) {
+  function getClipboardChecker(aText) {
     var checker = {
       check: function clipboardChecker_check() {
         is(getTextFromClipboard(), aText, "Wrong text in clipboard.");
       }
     };
     return checker;
   }
 
@@ -237,41 +237,41 @@ function editableTextTest(aID) {
     var data = this.mEventQueue.mInvokers[this.mEventQueue.mIndex + 1];
     if (data)
       data.func.apply(this, data.funcArgs);
   };
 
   /**
    * Used to generate an invoker object for the sheduled test.
    */
-  this.generateTest = function generateTest(aID, aRemoveTriple, aInsertTriple,
+  this.generateTest = function generateTest(aRemoveTriple, aInsertTriple,
                                             aInvokeFunc, aChecker, aInvokerID) {
     var et = this;
     var invoker = {
       eventSeq: [],
 
       invoke: aInvokeFunc,
       finalCheck: function finalCheck() {
         // dumpTree(aID, `'${aID}' tree:`);
 
         aChecker.check();
         et.unwrapNextTest(); // replace dummy invoker on real invoker object.
       },
       getID: function getID() { return aInvokerID; }
     };
 
     if (aRemoveTriple) {
-      var checker = new textChangeChecker(aID, aRemoveTriple[0],
+      let checker = new textChangeChecker(aID, aRemoveTriple[0],
                                           aRemoveTriple[1], aRemoveTriple[2],
                                           false);
       invoker.eventSeq.push(checker);
     }
 
     if (aInsertTriple) {
-      var checker = new textChangeChecker(aID, aInsertTriple[0],
+      let checker = new textChangeChecker(aID, aInsertTriple[0],
                                           aInsertTriple[1], aInsertTriple[2],
                                           true);
       invoker.eventSeq.push(checker);
     }
 
     // Claim that we don't want to fail when no events are expected.
     if (!aRemoveTriple && !aInsertTriple)
       invoker.noEventsOnAction = true;
--- a/accessible/tests/mochitest/elm/a11y.ini
+++ b/accessible/tests/mochitest/elm/a11y.ini
@@ -10,8 +10,9 @@ skip-if = buildapp == 'mulet'
 [test_listbox.xul]
 [test_MathMLSpec.html]
 [test_nsApplicationAcc.html]
 [test_plugin.html]
 skip-if = buildapp == 'mulet'
 [test_canvas.html]
 [test_shadowroot.html]
 skip-if = stylo # bug 1293844
+support-files = test_shadowroot_subframe.html
--- a/accessible/tests/mochitest/elm/test_HTMLSpec.html
+++ b/accessible/tests/mochitest/elm/test_HTMLSpec.html
@@ -830,16 +830,48 @@
       obj = {
         role: ROLE_PUSHBUTTON,
         actions: "press",
         absentStates: STATE_DEFAULT
       };
       testElm("input_reset", obj);
 
       // ////////////////////////////////////////////////////////////////////////
+      // HTML:input@type="time"
+
+      obj = {
+        role: ROLE_GROUPING,
+        children: [
+          { role: ROLE_SPINBUTTON },
+          { role: ROLE_TEXT_LEAF },
+          { role: ROLE_SPINBUTTON },
+          { role: ROLE_TEXT_LEAF },
+          { role: ROLE_ENTRY },
+          { role: ROLE_PUSHBUTTON }
+        ]
+      };
+      testElm("input_time", obj);
+
+      // ////////////////////////////////////////////////////////////////////////
+      // HTML:input@type="date"
+
+      obj = {
+        role: ROLE_DATE_EDITOR,
+        children: [
+          { role: ROLE_SPINBUTTON },
+          { role: ROLE_TEXT_LEAF },
+          { role: ROLE_SPINBUTTON },
+          { role: ROLE_TEXT_LEAF },
+          { role: ROLE_SPINBUTTON },
+          { role: ROLE_PUSHBUTTON }
+        ]
+      };
+      testElm("input_date", obj);
+
+      // ////////////////////////////////////////////////////////////////////////
       // HTML:ins contained by paragraph
 
       obj = {
         role: ROLE_PARAGRAPH,
         textAttrs: {
           0: { },
           6: { "text-underline-style": "solid" }
         },
@@ -1585,16 +1617,18 @@
   <input id="input_password" type="password" value="44">
   <input id="input_password_readonly" type="password" value="44" readonly>
   <input id="input_radio" type="radio">
   <input id="input_radio_true" type="radio" checked>
   <input id="input_range" type="range">
   <form>
     <input id="input_reset" type="reset">
   </form>
+  <input id="input_time" type="time" value="23:23">
+  <input id="input_date" type="date" value="2017-11-10">
 
   <p id="ins_container">normal<ins>Inserted</ins></p>
   <p id="kbd_container">normal<kbd>cmd</kbd></p>
   <keygen id="keygen" name="RSA public key" challenge="123456789" keytype="RSA">
 
   <label id="label">label<input id="label_input"></label>
   <label id="label_for" for="label_for_input">label</label>
   <input id="label_for_input">
--- a/accessible/tests/mochitest/elm/test_nsApplicationAcc.html
+++ b/accessible/tests/mochitest/elm/test_nsApplicationAcc.html
@@ -1,59 +1,54 @@
 <html>
 
 <head>
   <title>application accessible name</title>
-  <link rel="stylesheet" type="text/css" 
+  <link rel="stylesheet" type="text/css"
          href="chrome://mochikit/content/tests/SimpleTest/test.css" />
-  <script type="application/javascript" 
+  <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
 
-  <script type="application/javascript" 
+  <script type="application/javascript"
           src="../common.js"></script>
-  <script type="application/javascript" 
+  <script type="application/javascript"
           src="../role.js"></script>
 
   <script type="application/javascript">
+    /* import-globals-from ../common.js */
     function doTest() {
       var accessible = getApplicationAccessible();
       if (!accessible) {
         SimpleTest.finish();
         return;
       }
 
-      var bundleServ =
-        Components.classes["@mozilla.org/intl/stringbundle;1"].
-        getService(Components.interfaces.nsIStringBundleService);
       var brandBundle =
-        bundleServ.createBundle("chrome://branding/locale/brand.properties");
-
-      var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
-        getService(Components.interfaces.nsIXULAppInfo);
+        Services.strings.createBundle("chrome://branding/locale/brand.properties");
 
       // nsIAccessible::name
       var applicationName = "";
       if (LINUX || SOLARIS) {
-        applicationName = appInfo.name;
+        applicationName = Services.appinfo.name;
       } else {
         try {
           applicationName = brandBundle.GetStringFromName("brandShortName");
         } catch (e) {
         }
 
         if (applicationName == "")
           applicationName = "Gecko based application";
       }
       is(accessible.name, applicationName, "wrong application accessible name");
 
       // nsIAccessibleApplication
-      is(accessible.appName, appInfo.name, "Wrong application name");
-      is(accessible.appVersion, appInfo.version, "Wrong application version");
+      is(accessible.appName, Services.appinfo.name, "Wrong application name");
+      is(accessible.appVersion, Services.appinfo.version, "Wrong application version");
       is(accessible.platformName, "Gecko", "Wrong platform name");
-      is(accessible.platformVersion, appInfo.platformVersion,
+      is(accessible.platformVersion, Services.appinfo.platformVersion,
          "Wrong platform version");
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
--- a/accessible/tests/mochitest/elm/test_shadowroot.html
+++ b/accessible/tests/mochitest/elm/test_shadowroot.html
@@ -3,57 +3,38 @@
 <head>
   <title>ShadowRoot tests</title>
   <link rel="stylesheet" type="text/css"
         href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
 
-  <script type="application/javascript"
-          src="../common.js"></script>
-  <script type="application/javascript"
-          src="../role.js"></script>
-
-  <script type="application/javascript">
-    function doTest() {
-      testElm("component", {
-        role: ROLE_GROUPING,
-        children: [
-        {
-          role: ROLE_PUSHBUTTON,
-        },
-        {
-          role: ROLE_LINK,
-        },
-        ]
-      });
-
-      SimpleTest.finish();
-    }
-
-    SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
-  </script>
 </head>
 <body>
 
   <a target="_blank"
     title="Ensure accessible objects are created for shadow root"
     href="https://bugzilla.mozilla.org/show_bug.cgi?id=1026125">
      Mozilla Bug 1026125
   </a><br/>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
-  <div role="group" id="component"></div>
   <script>
-    var component = document.getElementById("component");
-    var shadow = component.createShadowRoot();
-
-    shadow.innerHTML = "<button>Hello</button>" +
-      '<a href="#"> World</a>';
+    SimpleTest.waitForExplicitFinish();
+    SpecialPowers.pushPrefEnv({
+      set: [
+        ["dom.webcomponents.enabled", true]
+      ]
+    }, function() {
+      // This test loads in an iframe, to ensure that the element instance is
+      // loaded with the correct value of the preference.
+      var iframe = document.createElement("iframe");
+      iframe.src = "test_shadowroot_subframe.html";
+      document.body.appendChild(iframe);
+    });
   </script>
 
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/elm/test_shadowroot_subframe.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>ShadowRoot tests</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="application/javascript" src="../common.js"></script>
+  <script type="application/javascript" src="../role.js"></script>
+
+  <script type="application/javascript">
+    let SimpleTest = window.parent.SimpleTest;
+    let ok = window.parent.ok;
+    let is = window.parent.is;
+
+    function doTest() {
+      testElm("component", {
+        role: ROLE_GROUPING,
+        children: [
+        {
+          role: ROLE_PUSHBUTTON,
+        },
+        {
+          role: ROLE_LINK,
+        },
+        ]
+      });
+
+      SimpleTest.finish();
+    }
+
+    addA11yLoadEvent(doTest);
+  </script>
+
+</head>
+<body>
+  <div role="group" id="component"></div>
+  <script>
+    var component = document.getElementById("component");
+    var shadow = component.attachShadow({mode: "open"});
+
+    shadow.innerHTML = "<button>Hello</button>" +
+      '<a href="#"> World</a>';
+  </script>
+</body>
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -1,8 +1,11 @@
+// XXX Bug 1425371 - enable no-redeclare and fix the issues with the tests.
+/* eslint-disable no-redeclare */
+
 // //////////////////////////////////////////////////////////////////////////////
 // Constants
 
 const EVENT_ALERT = nsIAccessibleEvent.EVENT_ALERT;
 const EVENT_DESCRIPTION_CHANGE = nsIAccessibleEvent.EVENT_DESCRIPTION_CHANGE;
 const EVENT_DOCUMENT_LOAD_COMPLETE = nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE;
 const EVENT_DOCUMENT_RELOAD = nsIAccessibleEvent.EVENT_DOCUMENT_RELOAD;
 const EVENT_DOCUMENT_LOAD_STOPPED = nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_STOPPED;
@@ -331,22 +334,20 @@ function eventQueue(aEventType) {
                 var checker = eventSeq[idx];
 
                 var typeStr = eventQueue.getEventTypeAsString(checker);
                 var msg = "Test with ID = '" + this.getEventID(checker) +
                   "' succeed. ";
 
                 if (checker.unexpected) {
                   ok(true, msg + `There's no unexpected '${typeStr}' event.`);
+                } else if (checker.todo) {
+                  todo(false, `Todo event '${typeStr}' was caught`);
                 } else {
-                  if (checker.todo) {
-                    todo(false, `Todo event '${typeStr}' was caught`);
-                  } else {
-                    ok(true, `${msg} Event '${typeStr}' was handled.`);
-                  }
+                  ok(true, `${msg} Event '${typeStr}' was handled.`);
                 }
               }
             }
           }
         }
 
         // We don't have completely matched scenario. Report each failure/success
         // for every scenario.
@@ -741,23 +742,23 @@ function eventQueue(aEventType) {
 
           gLogger.logToConsole(msg);
           gLogger.logToDOM(msg, true);
         }
 
         var eventType = eventSeq[idx].type;
         if (typeof eventType == "string") {
           // DOM event
-          var target = eventSeq[idx].target;
+          var target = eventQueue.getEventTarget(eventSeq[idx]);
           if (!target) {
             ok(false, "no target for DOM event!");
             return false;
           }
           var phase = eventQueue.getEventPhase(eventSeq[idx]);
-          target.ownerDocument.addEventListener(eventType, this, phase);
+          target.addEventListener(eventType, this, phase);
 
         } else {
           // A11y event
           addA11yEventListener(eventType, this);
         }
       }
     }
 
@@ -769,19 +770,19 @@ function eventQueue(aEventType) {
       return;
 
     for (var scnIdx = 0; scnIdx < this.mScenarios.length; scnIdx++) {
       var eventSeq = this.mScenarios[scnIdx];
       for (var idx = 0; idx < eventSeq.length; idx++) {
         var eventType = eventSeq[idx].type;
         if (typeof eventType == "string") {
           // DOM event
-          var target = eventSeq[idx].target;
+          var target = eventQueue.getEventTarget(eventSeq[idx]);
           var phase = eventQueue.getEventPhase(eventSeq[idx]);
-          target.ownerDocument.removeEventListener(eventType, this, phase);
+          target.removeEventListener(eventType, this, phase);
 
         } else {
           // A11y event
           removeA11yEventListener(eventType, this);
         }
       }
     }
     this.mScenarios = null;
@@ -848,16 +849,29 @@ eventQueue.getEventTargetDescr =
   var target = ("target" in aEventOrChecker) ? aEventOrChecker.target : null;
   return prettyName(target);
 };
 
 eventQueue.getEventPhase = function eventQueue_getEventPhase(aChecker) {
   return ("phase" in aChecker) ? aChecker.phase : true;
 };
 
+eventQueue.getEventTarget = function eventQueue_getEventTarget(aChecker) {
+  if ("eventTarget" in aChecker) {
+    switch (aChecker.eventTarget) {
+      case "element":
+        return aChecker.target;
+      case "document":
+      default:
+        return aChecker.target.ownerDocument;
+    }
+  }
+  return aChecker.target.ownerDocument;
+};
+
 eventQueue.compareEventTypes =
   function eventQueue_compareEventTypes(aChecker, aEvent) {
   var eventType = (aEvent instanceof nsIDOMEvent) ?
     aEvent.type : aEvent.eventType;
   return aChecker.type == eventType;
 };
 
 eventQueue.compareEvents = function eventQueue_compareEvents(aChecker, aEvent) {
@@ -1983,16 +1997,17 @@ var gA11yEventObserver =
 function listenA11yEvents(aStartToListen) {
   if (aStartToListen) {
     // Add observer when adding the first applicant only.
     if (!(gA11yEventApplicantsCount++))
       Services.obs.addObserver(gA11yEventObserver, "accessible-event");
   } else {
     // Remove observer when there are no more applicants only.
     // '< 0' case should not happen, but just in case: removeObserver() will throw.
+    // eslint-disable-next-line no-lonely-if
     if (--gA11yEventApplicantsCount <= 0)
       Services.obs.removeObserver(gA11yEventObserver, "accessible-event");
   }
 }
 
 function addA11yEventListener(aEventType, aEventHandler) {
   if (!(aEventType in gA11yEventListeners))
     gA11yEventListeners[aEventType] = [];
@@ -2102,17 +2117,17 @@ var gLogger =
       Services.console.logStringMessage("events: " + aMsg);
   },
 
   /**
    * Return true if logging feature is enabled.
    */
   hasFeature: function logger_hasFeature(aFeature) {
     var startIdx = gA11yEventDumpFeature.indexOf(aFeature);
-    if (startIdx == - 1)
+    if (startIdx == -1)
       return false;
 
     var endIdx = startIdx + aFeature.length;
     return endIdx == gA11yEventDumpFeature.length ||
       gA11yEventDumpFeature[endIdx] == ";";
   }
 };
 
--- a/accessible/tests/mochitest/events/docload/test_docload_busy.html
+++ b/accessible/tests/mochitest/events/docload/test_docload_busy.html
@@ -74,11 +74,11 @@
     Mozilla Bug 658185
   </a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
-  <div id="testContainer"><iframe id="iframe" src="about:" style="visibility: hidden;"></iframe></div>
+  <div id="testContainer"><iframe id="iframe" src="about:mozilla" style="visibility: hidden;"></iframe></div>
 </body>
 </html>
--- a/accessible/tests/mochitest/events/docload/test_docload_embedded.html
+++ b/accessible/tests/mochitest/events/docload/test_docload_embedded.html
@@ -35,30 +35,30 @@
       this.invoke = () => (this.DOMNode.src = aURL);
 
       this.finalCheck = () =>
         testAccessibleTree(this.DOMNode, {
           role: ROLE_INTERNAL_FRAME,
           children: [
             {
               role: ROLE_DOCUMENT,
-              name: aURL == "about:" ? "About:" : aURL
+              name: aURL == "about:license" ? "Licenses" : aURL
             }
           ]
         });
 
       this.getID = () => `change iframe src on ${aURL}`;
     }
 
     // //////////////////////////////////////////////////////////////////////////
     // Do tests
 
     function doTests() {
       const gQueue = new eventQueue();
-      gQueue.push(new changeIframeSrc("iframe", "about:"));
+      gQueue.push(new changeIframeSrc("iframe", "about:license"));
       gQueue.push(new changeIframeSrc("iframe", "about:buildconfig"));
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
--- a/accessible/tests/mochitest/events/docload/test_docload_root.html
+++ b/accessible/tests/mochitest/events/docload/test_docload_root.html
@@ -74,31 +74,31 @@
               role: ROLE_CHROME_WINDOW
             },
             {
               role: ROLE_CHROME_WINDOW
             }
           ]
         };
 
-        testAccessibleTree(gRootAcc, accTree)
+        testAccessibleTree(gRootAcc, accTree);
 
         gDialogDoc = gDialog.document;
         ok(isAccessibleInCache(gDialogDoc),
           `The document accessible for '${aURL}' is not in cache!`);
       };
 
       this.getID = () => `open dialog '${aURL}'`;
     }
 
     function closeDialogWnd() {
       this.eventSeq = [ new invokerChecker(EVENT_FOCUS, getAccessible(document)) ];
 
       this.invoke = () => {
-        gDialog.close()
+        gDialog.close();
         window.focus();
       };
 
       this.finalCheck = () => {
         ok(!isAccessibleInCache(gDialogDoc),
           `The document accessible for dialog is in cache still!`);
 
         gDialog = gDialogDoc = gRootAcc = null;
@@ -107,17 +107,17 @@
       this.getID = () => "close dialog";
     }
 
     // //////////////////////////////////////////////////////////////////////////
     // Do tests
 
     function doTests() {
       const gQueue = new eventQueue();
-      gQueue.push(new openDialogWnd("about:"));
+      gQueue.push(new openDialogWnd("about:about"));
       gQueue.push(new closeDialogWnd());
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
--- a/accessible/tests/mochitest/events/docload/test_docload_shutdown.html
+++ b/accessible/tests/mochitest/events/docload/test_docload_shutdown.html
@@ -37,17 +37,17 @@
 
   <script type="application/javascript">
     // //////////////////////////////////////////////////////////////////////////
     // Invokers
 
     let gDialog;
     let gDialogDoc;
     let gRootAcc;
-    let gIframeDoc
+    let gIframeDoc;
 
     function openWndShutdownDoc(aURL) {
       // Get application root accessible.
       let docAcc = getAccessible(document);
       while (docAcc) {
         gRootAcc = docAcc;
         try {
           docAcc = docAcc.parent;
@@ -90,33 +90,33 @@
               role: ROLE_CHROME_WINDOW
             },
             {
               role: ROLE_CHROME_WINDOW
             }
           ]
         };
 
-        testAccessibleTree(gRootAcc, accTree)
+        testAccessibleTree(gRootAcc, accTree);
         // After timeout after event hide for iframe was handled the document
         // accessible for iframe's document should no longer be in cache.
         ok(!isAccessibleInCache(gIframeDoc),
           "The document accessible for iframe is in cache still after iframe hide!");
         ok(isAccessibleInCache(gDialogDoc),
           `The document accessible for '${aURL}' is not in cache!`);
       };
 
       this.getID = () => `open dialog '${aURL}'`;
     }
 
     function closeWndShutdownDoc() {
       this.eventSeq = [ new invokerChecker(EVENT_FOCUS, getAccessible(document)) ];
 
       this.invoke = () => {
-        gDialog.close()
+        gDialog.close();
         window.focus();
       };
 
       this.finalCheck = () => {
         ok(!isAccessibleInCache(gDialogDoc),
           "The document accessible for dialog is in cache still!");
         // After the window is closed all alive subdocument accessibles should
         // be shut down.
--- a/accessible/tests/mochitest/events/test_aria_objattr.html
+++ b/accessible/tests/mochitest/events/test_aria_objattr.html
@@ -38,17 +38,17 @@
         return aAttr + " for " + aID + " " + aValue;
       };
     }
 
     function updateARIAHidden(aID, aIsDefined, aChildId) {
       this.__proto__ = new updateAttribute(aID, "aria-hidden",
                                            aIsDefined ? "true" : "false");
 
-      this.finalCheck = function updateARIAHidden() {
+      this.finalCheck = function updateARIAHidden_finalCheck() {
         if (aIsDefined) {
           testAttrs(aID, {"hidden": "true"}, true);
           testAttrs(aChildId, {"hidden": "true"}, true);
         } else {
           testAbsentAttrs(aID, { "hidden": "true"});
           testAbsentAttrs(aChildId, { "hidden": "true"});
         }
       };
--- a/accessible/tests/mochitest/events/test_attrs.html
+++ b/accessible/tests/mochitest/events/test_attrs.html
@@ -44,22 +44,22 @@
 
     // gA11yEventDumpID = "eventdump"; // debug stuff
     // gA11yEventDumpToConsole = true; // debug stuff
 
     function doTests() {
       gQueue = new eventQueue();
 
       var id = "textbox", noTargetId = "textarea";
-      var checker =
+      let checker =
         new eventFromInputChecker(EVENT_FOCUS, id, "false", noTargetId);
       gQueue.push(new synthFocus(id, checker));
 
       if (!MAC) { // Mac failure is bug 541093
-        var checker =
+        checker =
           new eventFromInputChecker(EVENT_TEXT_CARET_MOVED, id, "true", noTargetId);
         gQueue.push(new synthHomeKey(id, checker));
       }
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
--- a/accessible/tests/mochitest/events/test_dragndrop.html
+++ b/accessible/tests/mochitest/events/test_dragndrop.html
@@ -61,23 +61,23 @@
         return prettyName(aNodeOrID) + " aria-dropeffect changed";
       };
     }
 
     function doTests() {
       // Test aria attribute mutation events
       gQueue = new eventQueue(nsIAccessibleEvent.EVENT_OBJECT_ATTRIBUTE_CHANGED);
 
-      var id = "grabbable";
+      let id = "grabbable";
       gQueue.push(new changeGrabbed(id, "true"));
       gQueue.push(new changeGrabbed(id, "false"));
       todo(false, "uncomment this test when 472142 is fixed.");
       // gQueue.push(new changeGrabbed(id, "undefined"));
 
-      var id = "dropregion";
+      id = "dropregion";
       gQueue.push(new changeDropeffect(id, "copy"));
       gQueue.push(new changeDropeffect(id, "execute"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
--- a/accessible/tests/mochitest/events/test_flush.html
+++ b/accessible/tests/mochitest/events/test_flush.html
@@ -15,17 +15,17 @@
           src="../common.js"></script>
   <script type="application/javascript"
           src="../events.js"></script>
 
   <script type="application/javascript">
     SimpleTest.expectAssertions(0, 1);
 
     var gFocusHandler = {
-      handleEvent: function(aEvent) {
+      handleEvent(aEvent) {
         switch (this.count) {
           case 0:
             is(aEvent.DOMNode, getNode("input1"),
                "Focus event for input1 was expected!");
             getAccessible("input2").takeFocus();
             break;
 
           case 1:
--- a/accessible/tests/mochitest/events/test_focus_general.html
+++ b/accessible/tests/mochitest/events/test_focus_general.html
@@ -101,20 +101,19 @@
         gQueue.push(new toggleTopMenu(editableDoc, new topMenuChecker()));
         gQueue.push(new toggleTopMenu(editableDoc, new focusChecker(editableDoc)));
       }
       gQueue.push(new synthContextMenu(editableDoc, new contextMenuChecker()));
       gQueue.push(new synthDownKey(editableDoc, new focusContextMenuItemChecker()));
       gQueue.push(new synthEscapeKey(editableDoc, new focusChecker(editableDoc)));
       if (SEAMONKEY) {
         todo(false, "shift tab from editable document fails on (Windows) SeaMonkey! (Bug 718235)");
+      } else if (LINUX || MAC) {
+        todo(false, "shift tab from editable document fails on linux and Mac, bug 746519!");
       } else {
-      if (LINUX || MAC)
-        todo(false, "shift tab from editable document fails on linux and Mac, bug 746519!");
-      else
         gQueue.push(new synthShiftTab("link", new focusChecker("link")));
       } // ! SEAMONKEY
 
       gQueue.push(new synthFocus("a", new imageMapChecker("a")));
       gQueue.push(new synthFocus("b", new imageMapChecker("b")));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
--- a/accessible/tests/mochitest/events/test_mutation.html
+++ b/accessible/tests/mochitest/events/test_mutation.html
@@ -66,17 +66,17 @@
        * Replace the default target currently registered for a given event type
        * with the nodes in the targets array.
        */
       this.setTargets = function mutateA11yTree_setTargets(aEventType, aTargets) {
         var targetIdx = this.setTarget(aEventType, aTargets[0]);
 
         var type = this.getA11yEventType(aEventType);
         for (var i = 1; i < aTargets.length; i++) {
-          var checker = new invokerChecker(type, aTargets[i]);
+          let checker = new invokerChecker(type, aTargets[i]);
           this.getEventSeq().splice(++targetIdx, 0, checker);
         }
       };
 
       // Implementation
       this.getA11yEventType = function mutateA11yTree_getA11yEventType(aEventType) {
         if (aEventType == kReorderEvent)
           return nsIAccessibleEvent.EVENT_REORDER;
@@ -88,29 +88,29 @@
           return nsIAccessibleEvent.EVENT_SHOW;
       };
 
       this.getEventSeq = function mutateA11yTree_getEventSeq() {
         return this.doNotExpectEvents ? this.unexpectedEventSeq : this.eventSeq;
       };
 
       if (aEventTypes & kHideEvent) {
-        var checker = new invokerChecker(this.getA11yEventType(kHideEvent),
+        let checker = new invokerChecker(this.getA11yEventType(kHideEvent),
                                          this.DOMNode);
         this.getEventSeq().push(checker);
       }
 
       if (aEventTypes & kShowEvent) {
-        var checker = new invokerChecker(this.getA11yEventType(kShowEvent),
+        let checker = new invokerChecker(this.getA11yEventType(kShowEvent),
                                          this.DOMNode);
         this.getEventSeq().push(checker);
       }
 
       if (aEventTypes & kReorderEvent) {
-        var checker = new invokerChecker(this.getA11yEventType(kReorderEvent),
+        let checker = new invokerChecker(this.getA11yEventType(kReorderEvent),
                                          this.DOMNode.parentNode);
         this.getEventSeq().push(checker);
       }
     }
 
     /**
      * Change CSS style for the given node.
      */
@@ -427,61 +427,61 @@
      */
     var gQueue = null;
 
     function doTests() {
       gQueue = new eventQueue();
 
       // Show/hide events by changing of display style of accessible DOM node
       // from 'inline' to 'none', 'none' to 'inline'.
-      var id = "link1";
+      let id = "link1";
       getAccessible(id); // ensure accessible is created
       gQueue.push(new changeStyle(id, "display", "none", kHideEvents));
       gQueue.push(new changeStyle(id, "display", "inline", kShowEvents));
 
       // Show/hide events by changing of visibility style of accessible DOM node
       // from 'visible' to 'hidden', 'hidden' to 'visible'.
-      var id = "link2";
+      id = "link2";
       getAccessible(id);
       gQueue.push(new changeStyle(id, "visibility", "hidden", kHideEvents));
       gQueue.push(new changeStyle(id, "visibility", "visible", kShowEvents));
 
       // Show/hide events by changing of display style of accessible DOM node
       // from 'inline' to 'block', 'block' to 'inline'.
-      var id = "link3";
+      id = "link3";
       getAccessible(id); // ensure accessible is created
       gQueue.push(new changeStyle(id, "display", "block", kHideAndShowEvents));
       gQueue.push(new changeStyle(id, "display", "inline", kHideAndShowEvents));
 
       // Show/hide events by changing of visibility style of accessible DOM node
       // from 'collapse' to 'visible', 'visible' to 'collapse'.
-      var id = "link4";
+      id = "link4";
       gQueue.push(new changeStyle(id, "visibility", "visible", kShowEvents));
       gQueue.push(new changeStyle(id, "visibility", "collapse", kHideEvents));
 
       // Show/hide events by adding new accessible DOM node and removing old one.
-      var id = "link5";
+      id = "link5";
       gQueue.push(new cloneAndAppendToDOM(id));
       gQueue.push(new removeFromDOM(id));
 
       // No show/hide events by adding new not accessible DOM node and removing
       // old one, no reorder event for their parent.
-      var id = "child1";
+      id = "child1";
       gQueue.push(new cloneAndAppendToDOM(id, kNoEvents));
       gQueue.push(new removeFromDOM(id, kNoEvents));
 
       // Show/hide events by adding new accessible DOM node and removing
       // old one, there is reorder event for their parent.
-      var id = "child2";
+      id = "child2";
       gQueue.push(new cloneAndAppendToDOM(id));
       gQueue.push(new removeFromDOM(id));
 
       // Show/hide events by adding new DOM node containing accessible DOM and
       // removing old one, there is reorder event for their parent.
-      var id = "child3";
+      id = "child3";
       gQueue.push(new cloneAndAppendToDOM(id, kShowEvents, getFirstChild,
                                           getParent));
 
       // Hide event for accessible child of unaccessible removed DOM node and
       // reorder event for its parent.
       gQueue.push(new removeFromDOM(id, kHideEvents,
                                     getNEnsureFirstChild, getParent));
 
--- a/accessible/tests/mochitest/events/test_statechange.html
+++ b/accessible/tests/mochitest/events/test_statechange.html
@@ -29,19 +29,19 @@
         // Note: this should fire an EVENT_STATE_CHANGE
         this.DOMNode.designMode = "on";
       };
 
       this.check = function editabledoc_check(aEvent) {
 
         testStates(aDocNode, 0, EXT_STATE_EDITABLE);
 
-        var event = null;
+        let event = null;
         try {
-          var event = aEvent.QueryInterface(nsIAccessibleStateChangeEvent);
+          event = aEvent.QueryInterface(nsIAccessibleStateChangeEvent);
         } catch (e) {
           ok(false, "State change event was expected");
         }
 
         if (!event) { return; }
 
         ok(event.isExtraState, "Extra state change was expected");
         is(event.state, EXT_STATE_EDITABLE, "Wrong state of statechange event");
--- a/accessible/tests/mochitest/events/test_text.html
+++ b/accessible/tests/mochitest/events/test_text.html
@@ -59,35 +59,35 @@
      * Insert inaccessible child node containing accessibles.
      */
     function insertChildSpan(aID, aInsertAllTogether) {
       this.__proto__ = new textInsertInvoker(aID, 0, 5, "33322");
 
       this.invoke = function insertChildSpan_invoke() {
         // <span><span>333</span><span>22</span></span>
         if (aInsertAllTogether) {
-          var topSpan = document.createElement("span");
-          var fSpan = document.createElement("span");
+          let topSpan = document.createElement("span");
+          let fSpan = document.createElement("span");
           fSpan.textContent = "333";
           topSpan.appendChild(fSpan);
-          var sSpan = document.createElement("span");
+          let sSpan = document.createElement("span");
           sSpan.textContent = "22";
           topSpan.appendChild(sSpan);
 
           this.DOMNode.insertBefore(topSpan, this.DOMNode.childNodes[0]);
 
         } else {
-          var topSpan = document.createElement("span");
+          let topSpan = document.createElement("span");
           this.DOMNode.insertBefore(topSpan, this.DOMNode.childNodes[0]);
 
-          var fSpan = document.createElement("span");
+          let fSpan = document.createElement("span");
           fSpan.textContent = "333";
           topSpan.appendChild(fSpan);
 
-          var sSpan = document.createElement("span");
+          let sSpan = document.createElement("span");
           sSpan.textContent = "22";
           topSpan.appendChild(sSpan);
         }
       };
 
       this.getID = function insertChildSpan_getID() {
        return "Insert inaccessible span containing accessibles" +
           prettyName(aID);
--- a/accessible/tests/mochitest/events/test_tree.xul
+++ b/accessible/tests/mochitest/events/test_tree.xul
@@ -52,41 +52,53 @@
     {
       this.type = "TreeInvalidated";
       this.target = gTree;
       this.check = function check(aEvent)
       {
         var propBag = aEvent.detail.QueryInterface(Components.interfaces.nsIPropertyBag2);
         try {
           var startRow = propBag.getPropertyAsInt32("startrow");
-        } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
+        } catch (e) {
+          if (e.name != 'NS_ERROR_NOT_AVAILABLE') {
+            throw e;
+          }
           startRow = null;
         }
         is(startRow, aStartRow,
            "Wrong 'startrow' of 'treeInvalidated' event on " + aMsg);
 
         try {
           var endRow = propBag.getPropertyAsInt32("endrow");
-        } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
+        } catch (e) {
+          if (e.name != 'NS_ERROR_NOT_AVAILABLE') {
+            throw e;
+          }
           endRow = null;
         }
         is(endRow, aEndRow,
            "Wrong 'endrow' of 'treeInvalidated' event on " + aMsg);
 
         try {
           var startCol = propBag.getPropertyAsInt32("startcolumn");
-        } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
+        } catch (e) {
+          if (e.name != 'NS_ERROR_NOT_AVAILABLE') {
+            throw e;
+          }
           startCol = null;
         }
         is(startCol, aStartCol,
            "Wrong 'startcolumn' of 'treeInvalidated' event on " + aMsg);
 
         try {
           var endCol = propBag.getPropertyAsInt32("endcolumn");
-        } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
+        } catch (e) {
+          if (e.name != 'NS_ERROR_NOT_AVAILABLE') {
+            throw e;
+          }
           endCol = null;
         }
         is(endCol, aEndCol,
            "Wrong 'endcolumn' of 'treeInvalidated' event on " + aMsg);
       }
       this.getID = function getID()
       {
         return "TreeInvalidated on " + aMsg;
--- a/accessible/tests/mochitest/grid.js
+++ b/accessible/tests/mochitest/grid.js
@@ -66,59 +66,60 @@ function grid(aTableIdentifier) {
   };
 
   this.handleKeyEvent = function handleKeyEvent(aEvent) {
     if (aEvent.target.localName != "td")
       return;
 
     var cell = aEvent.target;
     switch (aEvent.keyCode) {
-      case nsIDOMKeyEvent.DOM_VK_UP:
-        var colsCount = this.getColsCount();
-        var idx = this.getIndexByCell(cell);
+      case nsIDOMKeyEvent.DOM_VK_UP: {
+        let colsCount = this.getColsCount();
+        let idx = this.getIndexByCell(cell);
         var upidx = idx - colsCount;
         if (upidx >= 0) {
           cell.removeAttribute("tabindex");
           var upcell = this.getCellAtIndex(upidx);
           upcell.setAttribute("tabindex", "0");
           upcell.focus();
         }
         break;
-
-      case nsIDOMKeyEvent.DOM_VK_DOWN:
-        var colsCount = this.getColsCount();
-        var idx = this.getIndexByCell(cell);
+      }
+      case nsIDOMKeyEvent.DOM_VK_DOWN: {
+        let colsCount = this.getColsCount();
+        let idx = this.getIndexByCell(cell);
         var downidx = idx + colsCount;
         if (downidx <= this.getMaxIndex()) {
           cell.removeAttribute("tabindex");
           var downcell = this.getCellAtIndex(downidx);
           downcell.setAttribute("tabindex", "0");
           downcell.focus();
         }
         break;
-
-      case nsIDOMKeyEvent.DOM_VK_LEFT:
-        var idx = this.getIndexByCell(cell);
+      }
+      case nsIDOMKeyEvent.DOM_VK_LEFT: {
+        let idx = this.getIndexByCell(cell);
         if (idx > 0) {
           cell.removeAttribute("tabindex");
           var prevcell = this.getCellAtIndex(idx - 1);
           prevcell.setAttribute("tabindex", "0");
           prevcell.focus();
         }
         break;
-
-      case nsIDOMKeyEvent.DOM_VK_RIGHT:
-        var idx = this.getIndexByCell(cell);
+      }
+      case nsIDOMKeyEvent.DOM_VK_RIGHT: {
+        let idx = this.getIndexByCell(cell);
         if (idx < this.getMaxIndex()) {
           cell.removeAttribute("tabindex");
           var nextcell = this.getCellAtIndex(idx + 1);
           nextcell.setAttribute("tabindex", "0");
           nextcell.focus();
         }
         break;
+      }
     }
   };
 
   this.handleClickEvent = function handleClickEvent(aEvent) {
     if (aEvent.target.localName != "td")
       return;
 
     var curCell = this.getCurrentCell();
--- a/accessible/tests/mochitest/hittest/a11y.ini
+++ b/accessible/tests/mochitest/hittest/a11y.ini
@@ -4,11 +4,12 @@ support-files = zoom_tree.xul
   !/accessible/tests/mochitest/letters.gif
 
 [test_browser.html]
 [test_canvas_hitregion.html]
 skip-if = (os == "android" || appname == "b2g")
 [test_general.html]
 [test_menu.xul]
 [test_shadowroot.html]
+support-files = test_shadowroot_subframe.html
 [test_zoom.html]
 [test_zoom_text.html]
 [test_zoom_tree.xul]
--- a/accessible/tests/mochitest/hittest/test_shadowroot.html
+++ b/accessible/tests/mochitest/hittest/test_shadowroot.html
@@ -3,70 +3,38 @@
 <head>
   <title>ShadowRoot hit tests</title>
   <link rel="stylesheet" type="text/css"
         href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
 
-  <script type="application/javascript"
-          src="../common.js"></script>
-  <script type="application/javascript"
-          src="../layout.js"></script>
-
-  <script type="application/javascript">
-    function doTest() {
-      var componentAcc = getAccessible("component1");
-      testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild,
-                       componentAcc.firstChild);
-
-      componentAcc = getAccessible("component2");
-      testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild,
-                       componentAcc.firstChild);
-      SimpleTest.finish();
-    }
-
-    SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
-  </script>
 </head>
 <body>
 
   <a target="_blank"
      title="Test getChildAtPoint works for shadow DOM content"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=1027315">
     Mozilla Bug 1027315
   </a><br/>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
-  <div role="group" class="components" id="component1" style="display: inline-block;">
-  <!--
-    <div role="button" id="component-child"
-         style="width: 100px; height: 100px; background-color: pink;">
-    </div>
-  -->
-  </div>
-  <div role="group" class="components"  id="component2" style="display: inline-block;">
-  <!--
-    <button>Hello world</button>
-  -->
-  </div>
   <script>
-    // This routine adds the comment children of each 'component' to its
-    // shadow root.
-    var components = document.querySelectorAll(".components");
-    for (var i = 0; i < components.length; i++) {
-      var component = components[i];
-      var shadow = component.createShadowRoot();
-      for (var child = component.firstChild; child; child = child.nextSibling) {
-        if (child.nodeType === 8)
-          // eslint-disable-next-line no-unsanitized/property
-          shadow.innerHTML = child.data;
-      }
-    }
+    SimpleTest.waitForExplicitFinish();
+    SpecialPowers.pushPrefEnv({
+      set: [
+        ["dom.webcomponents.enabled", true]
+      ]
+    }, function() {
+      // This test loads in an iframe, to ensure that the element instance is
+      // loaded with the correct value of the preference.
+      var iframe = document.createElement("iframe");
+      iframe.src = "test_shadowroot_subframe.html";
+      document.body.appendChild(iframe);
+    });
   </script>
 
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/hittest/test_shadowroot_subframe.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>ShadowRoot hit tests</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="application/javascript" src="../common.js"></script>
+  <script type="application/javascript" src="../layout.js"></script>
+
+  <script type="application/javascript">
+    let SimpleTest = window.parent.SimpleTest;
+    let ok = window.parent.ok;
+    let is = window.parent.is;
+
+    function doTest() {
+      var componentAcc = getAccessible("component1");
+      testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild,
+                       componentAcc.firstChild);
+
+      componentAcc = getAccessible("component2");
+      testChildAtPoint(componentAcc, 1, 1, componentAcc.firstChild,
+                       componentAcc.firstChild);
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+
+</head>
+<body>
+  <div role="group" class="components" id="component1" style="display: inline-block;">
+  <!--
+    <div role="button" id="component-child"
+         style="width: 100px; height: 100px; background-color: pink;">
+    </div>
+  -->
+  </div>
+  <div role="group" class="components"  id="component2" style="display: inline-block;">
+  <!--
+    <button>Hello world</button>
+  -->
+  </div>
+  <script>
+    // This routine adds the comment children of each 'component' to its
+    // shadow root.
+    var components = document.querySelectorAll(".components");
+    for (var i = 0; i < components.length; i++) {
+      var component = components[i];
+      var shadow = component.attachShadow({mode: "open"});
+      for (var child = component.firstChild; child; child = child.nextSibling) {
+        if (child.nodeType === 8)
+          // eslint-disable-next-line no-unsanitized/property
+          shadow.innerHTML = child.data;
+      }
+    }
+  </script>
+</body>
+</html>
--- a/accessible/tests/mochitest/hittest/test_zoom_text.html
+++ b/accessible/tests/mochitest/hittest/test_zoom_text.html
@@ -14,24 +14,24 @@
           src="../role.js"></script>
   <script type="application/javascript"
           src="../layout.js"></script>
 
   <script type="application/javascript">
     function doTest() {
       var hyperText = getNode("paragraph");
       var textNode = hyperText.firstChild;
-      var [x, y, width, height] = getBounds(textNode);
+      let [x, y, width, height] = getBounds(textNode);
       testOffsetAtPoint(hyperText, x + width / 2, y + height / 2,
                         COORDTYPE_SCREEN_RELATIVE,
                         hyperText.textContent.length / 2);
 
       zoomDocument(document, 2.0);
 
-      var [x, y, width, height] = getBounds(textNode);
+      [x, y, width, height] = getBounds(textNode);
       testOffsetAtPoint(hyperText, x + width / 2, y + height / 2,
                         COORDTYPE_SCREEN_RELATIVE,
                         hyperText.textContent.length / 2);
 
       zoomDocument(document, 1.0);
 
       SimpleTest.finish();
     }
--- a/accessible/tests/mochitest/hypertext/test_update.html
+++ b/accessible/tests/mochitest/hypertext/test_update.html
@@ -164,17 +164,17 @@
 
     // gA11yEventDumpToConsole = true; // debug stuff
 
     var gQueue = null;
     function doTest() {
       gQueue = new eventQueue();
       gQueue.push(new addLinks("p1"));
       gQueue.push(new updateText("p2"));
-      gQueue.push(new removeChild("div1","div2",
+      gQueue.push(new removeChild("div1", "div2",
                                   "hello my good friend", "hello friend"));
       gQueue.push(new removeFirstChild("c4"));
       gQueue.push(new removeLastChild("c5"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
--- a/accessible/tests/mochitest/jsat/jsatcommon.js
+++ b/accessible/tests/mochitest/jsat/jsatcommon.js
@@ -183,17 +183,17 @@ function AccessFuContentTest(aFuncResult
   this.queue = aFuncResultPairs;
 }
 
 AccessFuContentTest.prototype = {
   expected: [],
   currentAction: null,
   actionNum: -1,
 
-  start: function(aFinishedCallback) {
+  start(aFinishedCallback) {
     Logger.logLevel = Logger.DEBUG;
     this.finishedCallback = aFinishedCallback;
     var self = this;
 
     // Get top content message manager, and set it up.
     this.mms = [Utils.getMessageManager(currentBrowser())];
     this.setupMessageManager(this.mms[0], function() {
       // Get child message managers and set them up
@@ -215,34 +215,34 @@ AccessFuContentTest.prototype = {
               self.pump();
             }
           });
         }
       }
     });
   },
 
-  finish: function() {
+  finish() {
     Logger.logLevel = Logger.INFO;
     for (var mm of this.mms) {
         mm.sendAsyncMessage("AccessFu:Stop");
         mm.removeMessageListener("AccessFu:Present", this);
         mm.removeMessageListener("AccessFu:Input", this);
         mm.removeMessageListener("AccessFu:CursorCleared", this);
         mm.removeMessageListener("AccessFu:Focused", this);
         mm.removeMessageListener("AccessFu:AriaHidden", this);
         mm.removeMessageListener("AccessFu:Ready", this);
         mm.removeMessageListener("AccessFu:ContentStarted", this);
       }
     if (this.finishedCallback) {
       this.finishedCallback();
     }
   },
 
-  setupMessageManager:  function(aMessageManager, aCallback) {
+  setupMessageManager(aMessageManager, aCallback) {
     function contentScript() {
       addMessageListener("AccessFuTest:Focus", function(aMessage) {
         var elem = content.document.querySelector(aMessage.json.selector);
         if (elem) {
           if (aMessage.json.blur) {
             elem.blur();
           } else {
             elem.focus();
@@ -266,17 +266,17 @@ AccessFuContentTest.prototype = {
     });
 
     aMessageManager.loadFrameScript(
       "chrome://global/content/accessibility/content-script.js", false);
     aMessageManager.loadFrameScript(
       "data:,(" + contentScript.toString() + ")();", false);
   },
 
-  pump: function() {
+  pump() {
     this.expected.shift();
     if (this.expected.length) {
       return;
     }
 
     var currentPair = this.queue.shift();
 
     if (currentPair) {
@@ -294,17 +294,17 @@ AccessFuContentTest.prototype = {
       if (!this.expected[0]) {
        this.pump();
      }
     } else {
       this.finish();
     }
   },
 
-  receiveMessage: function(aMessage) {
+  receiveMessage(aMessage) {
     var expected = this.expected[0];
 
     if (!expected) {
       return;
     }
 
     var actionsString = typeof this.currentAction === "function" ?
       this.currentAction.name + "()" : JSON.stringify(this.currentAction);
@@ -495,23 +495,21 @@ ExpectedMessage.prototype.lazyCompare = 
     var expected = aExpected[attr];
     var received = aReceived[attr];
     if (typeof expected === "object") {
       var [childMatches, childDelta] = this.lazyCompare(received, expected);
       if (!childMatches) {
         delta.push(attr + " [ " + childDelta + " ]");
         matches = false;
       }
-    } else {
-      if (received !== expected) {
-        delta.push(
-          attr + " [ expected " + JSON.stringify(expected) +
-          " got " + JSON.stringify(received) + " ]");
-        matches = false;
-      }
+    } else if (received !== expected) {
+      delta.push(
+        attr + " [ expected " + JSON.stringify(expected) +
+        " got " + JSON.stringify(received) + " ]");
+      matches = false;
     }
   }
 
   var msg = delta.length ? delta.join(" ") : "Structures lazily match";
   return [matches, msg + " -- " + aInfo];
 };
 
 ExpectedMessage.prototype.is = function(aReceived, aInfo) {
--- a/accessible/tests/mochitest/jsat/test_content_integration.html
+++ b/accessible/tests/mochitest/jsat/test_content_integration.html
@@ -206,17 +206,17 @@
 
           // aria-hidden element that the virtual cursor is positioned on
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
           [doc.defaultView.ariaHideBack,
            new ExpectedCursorChange(
-            ["such app", "wow", {"string": "headingLevel","args": [1]}])],
+            ["such app", "wow", {"string": "headingLevel", "args": [1]}])],
           // Changing aria-hidden attribute twice and making sure that the event
           // is fired only once when the actual change happens.
           [doc.defaultView.ariaHideBack],
           [doc.defaultView.ariaShowBack],
           [ContentMessages.simpleMovePrevious,
            new ExpectedCursorChange(["Back", {"string": "pushbutton"}])],
           [ContentMessages.clearCursor, "AccessFu:CursorCleared"],
 
@@ -234,17 +234,17 @@
 
           // aria-hidden element and auto Move
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(["Traversal Rule test document", "Phone status bar"])],
           [doc.defaultView.ariaHideBack],
           [ContentMessages.focusSelector("button#back", false),
             // Must not speak Back button as it is aria-hidden
            new ExpectedCursorChange(
-             ["such app", "wow", {"string": "headingLevel","args": [1]}])],
+             ["such app", "wow", {"string": "headingLevel", "args": [1]}])],
           [doc.defaultView.ariaShowBack],
           [ContentMessages.focusSelector("button#back", true), null],
           [ContentMessages.clearCursor, "AccessFu:CursorCleared"],
 
           // Open dialog in outer doc, while cursor is also in outer doc
           [ContentMessages.simpleMoveLast,
            new ExpectedCursorChange(["Traversal Rule test document", "mover",
              "medium", {"string": "slider"}])],
--- a/accessible/tests/mochitest/jsat/test_content_text.html
+++ b/accessible/tests/mochitest/jsat/test_content_text.html
@@ -142,17 +142,17 @@
            new ExpectedCursorChange(
             ["So we don't get dessert?", {string: "label"}]),
            new ExpectedAnnouncement("navigating"),
            new ExpectedEditState({
             editing: false,
             multiline: false,
             atStart: true,
             atEnd: false
-           },{ focused: "html" })
+           }, { focused: "html" })
          ],
           [ContentMessages.simpleMoveNext,
            new ExpectedCursorChange(
             [{ string: "entry" }],
             { focused: "html"})],
           [ContentMessages.activateCurrent(0),
            new ExpectedClickAction(),
            new ExpectedAnnouncement("editing"),
--- a/accessible/tests/mochitest/jsat/test_output.html
+++ b/accessible/tests/mochitest/jsat/test_output.html
@@ -25,20 +25,20 @@ https://bugzilla.mozilla.org/show_bug.cg
         var tests = [{
           accOrElmOrID: "anchor",
           expectedUtterance: [[{"string": "link"}, "title"],
             ["title", {"string": "link"}]],
           expectedBraille: [[{"string": "linkAbbr"}, "title"],
             ["title", {"string": "linkAbbr"}]]
         }, {
           accOrElmOrID: "anchor_titleandtext",
-          expectedUtterance: [[{"string": "link"}, "goes to the tests -",
-            "Tests"], ["Tests", "- goes to the tests", {"string": "link"}]],
-          expectedBraille:   [[{"string": "linkAbbr"}, "goes to the tests -",
-            "Tests"], ["Tests", "- goes to the tests", {"string": "linkAbbr"}]],
+          expectedUtterance: [[{"string": "link"}, "goes to the tests",
+            "Tests"], ["Tests", "goes to the tests", {"string": "link"}]],
+          expectedBraille:   [[{"string": "linkAbbr"}, "goes to the tests",
+            "Tests"], ["Tests", "goes to the tests", {"string": "linkAbbr"}]],
         }, {
           accOrElmOrID: "anchor_duplicatedtitleandtext",
           expectedUtterance: [[{"string": "link"}, "Tests"],
             ["Tests", {"string": "link"}]],
           expectedBraille: [[{"string": "linkAbbr"}, "Tests"],
             ["Tests", {"string": "linkAbbr"}]]
         }, {
           accOrElmOrID: "anchor_arialabelandtext",
--- a/accessible/tests/mochitest/jsat/test_output_mathml.html
+++ b/accessible/tests/mochitest/jsat/test_output_mathml.html
@@ -14,162 +14,162 @@
           src="jsatcommon.js"></script>
   <script type="application/javascript">
 
     function doTest() {
       // Test the following accOrElmOrID.
       var tests = [{
           accOrElmOrID: "math-1",
           expectedUtterance: [
-            [{"string": "open-fence"},"(","x",",","y",{"string": "close-fence"},")"],
-            ["(",{"string": "open-fence"},"x",",","y",")",{"string": "close-fence"}]
+            [{"string": "open-fence"}, "(", "x", ",", "y", {"string": "close-fence"}, ")"],
+            ["(", {"string": "open-fence"}, "x", ",", "y", ")", {"string": "close-fence"}]
           ],
           expectedBraille: [
-            [{"string": "open-fenceAbbr"},"(","x",",","y",{"string": "close-fenceAbbr"},")"],
-            ["(",{"string": "open-fenceAbbr"},"x",",","y",")",{"string": "close-fenceAbbr"}]
+            [{"string": "open-fenceAbbr"}, "(", "x", ",", "y", {"string": "close-fenceAbbr"}, ")"],
+            ["(", {"string": "open-fenceAbbr"}, "x", ",", "y", ")", {"string": "close-fenceAbbr"}]
           ]
         }, {
           accOrElmOrID: "mfrac-1",
           expectedUtterance: [
-            [{"string": "mathmlfraction"},{"string": "numerator"},"a",{"string": "denominator"},"b"],
-            ["a",{"string": "numerator"},"b",{"string": "denominator"},{"string": "mathmlfraction"}]
+            [{"string": "mathmlfraction"}, {"string": "numerator"}, "a", {"string": "denominator"}, "b"],
+            ["a", {"string": "numerator"}, "b", {"string": "denominator"}, {"string": "mathmlfraction"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlfractionAbbr"},{"string": "numeratorAbbr"},"a",{"string": "denominatorAbbr"},"b"],
-            ["a",{"string": "numeratorAbbr"},"b",{"string": "denominatorAbbr"},{"string": "mathmlfractionAbbr"}]
+            [{"string": "mathmlfractionAbbr"}, {"string": "numeratorAbbr"}, "a", {"string": "denominatorAbbr"}, "b"],
+            ["a", {"string": "numeratorAbbr"}, "b", {"string": "denominatorAbbr"}, {"string": "mathmlfractionAbbr"}]
           ]
         }, {
           accOrElmOrID: "mfrac-2",
           expectedUtterance: [
-            [{"string": "mathmlfractionwithoutbar"},{"string": "numerator"},"a",{"string": "denominator"},"b"],
-            ["a",{"string": "numerator"},"b",{"string": "denominator"},{"string": "mathmlfractionwithoutbar"}]
+            [{"string": "mathmlfractionwithoutbar"}, {"string": "numerator"}, "a", {"string": "denominator"}, "b"],
+            ["a", {"string": "numerator"}, "b", {"string": "denominator"}, {"string": "mathmlfractionwithoutbar"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlfractionwithoutbarAbbr"},{"string": "numeratorAbbr"},"a",{"string": "denominatorAbbr"},"b"],
-            ["a",{"string": "numeratorAbbr"},"b",{"string": "denominatorAbbr"},{"string": "mathmlfractionwithoutbarAbbr"}]
+            [{"string": "mathmlfractionwithoutbarAbbr"}, {"string": "numeratorAbbr"}, "a", {"string": "denominatorAbbr"}, "b"],
+            ["a", {"string": "numeratorAbbr"}, "b", {"string": "denominatorAbbr"}, {"string": "mathmlfractionwithoutbarAbbr"}]
           ]
         }, {
           accOrElmOrID: "msub-1",
           expectedUtterance: [
-            [{"string": "mathmlscripted"},{"string": "base"},"a",{"string": "subscript"},"b"],
-            ["a",{"string": "base"},"b",{"string": "subscript"},{"string": "mathmlscripted"}]
+            [{"string": "mathmlscripted"}, {"string": "base"}, "a", {"string": "subscript"}, "b"],
+            ["a", {"string": "base"}, "b", {"string": "subscript"}, {"string": "mathmlscripted"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlscriptedAbbr"},{"string": "baseAbbr"},"a",{"string": "subscriptAbbr"},"b"],
-            ["a",{"string": "baseAbbr"},"b",{"string": "subscriptAbbr"},{"string": "mathmlscriptedAbbr"}]
+            [{"string": "mathmlscriptedAbbr"}, {"string": "baseAbbr"}, "a", {"string": "subscriptAbbr"}, "b"],
+            ["a", {"string": "baseAbbr"}, "b", {"string": "subscriptAbbr"}, {"string": "mathmlscriptedAbbr"}]
           ]
         }, {
           accOrElmOrID: "msup-1",
           expectedUtterance: [
-            [{"string": "mathmlscripted"},{"string": "base"},"a",{"string": "superscript"},"b"],
-            ["a",{"string": "base"},"b",{"string": "superscript"},{"string": "mathmlscripted"}]
+            [{"string": "mathmlscripted"}, {"string": "base"}, "a", {"string": "superscript"}, "b"],
+            ["a", {"string": "base"}, "b", {"string": "superscript"}, {"string": "mathmlscripted"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlscriptedAbbr"},{"string": "baseAbbr"},"a",{"string": "superscriptAbbr"},"b"],
-            ["a",{"string": "baseAbbr"},"b",{"string": "superscriptAbbr"},{"string": "mathmlscriptedAbbr"}]
+            [{"string": "mathmlscriptedAbbr"}, {"string": "baseAbbr"}, "a", {"string": "superscriptAbbr"}, "b"],
+            ["a", {"string": "baseAbbr"}, "b", {"string": "superscriptAbbr"}, {"string": "mathmlscriptedAbbr"}]
           ]
         }, {
           accOrElmOrID: "msubsup-1",
           expectedUtterance: [
-            [{"string": "mathmlscripted"},{"string": "base"},"a",{"string": "subscript"},"b",{"string": "superscript"},"c"],
-            ["a",{"string": "base"},"b",{"string": "subscript"},"c",{"string": "superscript"},{"string": "mathmlscripted"}]
+            [{"string": "mathmlscripted"}, {"string": "base"}, "a", {"string": "subscript"}, "b", {"string": "superscript"}, "c"],
+            ["a", {"string": "base"}, "b", {"string": "subscript"}, "c", {"string": "superscript"}, {"string": "mathmlscripted"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlscriptedAbbr"},{"string": "baseAbbr"},"a",{"string": "subscriptAbbr"},"b",{"string": "superscriptAbbr"},"c"],
-            ["a",{"string": "baseAbbr"},"b",{"string": "subscriptAbbr"},"c",{"string": "superscriptAbbr"},{"string": "mathmlscriptedAbbr"}]
+            [{"string": "mathmlscriptedAbbr"}, {"string": "baseAbbr"}, "a", {"string": "subscriptAbbr"}, "b", {"string": "superscriptAbbr"}, "c"],
+            ["a", {"string": "baseAbbr"}, "b", {"string": "subscriptAbbr"}, "c", {"string": "superscriptAbbr"}, {"string": "mathmlscriptedAbbr"}]
           ]
         }, {
           accOrElmOrID: "mmultiscripts-1",
           expectedUtterance: [
-            [{"string": "mathmlscripted"},{"string": "base"},"a",{"string": "subscript"},"b",{"string": "superscript"},"c",{"string": "superscript"},"d",{"string": "presubscript"},"e",{"string": "presubscript"},"f",{"string": "presuperscript"},"g"],
-            ["a",{"string": "base"},"b",{"string": "subscript"},"c",{"string": "superscript"},"d",{"string": "superscript"},"e",{"string": "presubscript"},"f",{"string": "presubscript"},"g",{"string": "presuperscript"},{"string": "mathmlscripted"}]
+            [{"string": "mathmlscripted"}, {"string": "base"}, "a", {"string": "subscript"}, "b", {"string": "superscript"}, "c", {"string": "superscript"}, "d", {"string": "presubscript"}, "e", {"string": "presubscript"}, "f", {"string": "presuperscript"}, "g"],
+            ["a", {"string": "base"}, "b", {"string": "subscript"}, "c", {"string": "superscript"}, "d", {"string": "superscript"}, "e", {"string": "presubscript"}, "f", {"string": "presubscript"}, "g", {"string": "presuperscript"}, {"string": "mathmlscripted"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlscriptedAbbr"},{"string": "baseAbbr"},"a",{"string": "subscriptAbbr"},"b",{"string": "superscriptAbbr"},"c",{"string": "superscriptAbbr"},"d",{"string": "presubscriptAbbr"},"e",{"string": "presubscriptAbbr"},"f",{"string": "presuperscriptAbbr"},"g"],
-            ["a",{"string": "baseAbbr"},"b",{"string": "subscriptAbbr"},"c",{"string": "superscriptAbbr"},"d",{"string": "superscriptAbbr"},"e",{"string": "presubscriptAbbr"},"f",{"string": "presubscriptAbbr"},"g",{"string": "presuperscriptAbbr"},{"string": "mathmlscriptedAbbr"}]
+            [{"string": "mathmlscriptedAbbr"}, {"string": "baseAbbr"}, "a", {"string": "subscriptAbbr"}, "b", {"string": "superscriptAbbr"}, "c", {"string": "superscriptAbbr"}, "d", {"string": "presubscriptAbbr"}, "e", {"string": "presubscriptAbbr"}, "f", {"string": "presuperscriptAbbr"}, "g"],
+            ["a", {"string": "baseAbbr"}, "b", {"string": "subscriptAbbr"}, "c", {"string": "superscriptAbbr"}, "d", {"string": "superscriptAbbr"}, "e", {"string": "presubscriptAbbr"}, "f", {"string": "presubscriptAbbr"}, "g", {"string": "presuperscriptAbbr"}, {"string": "mathmlscriptedAbbr"}]
           ]
         }, {
           accOrElmOrID: "munder-1",
           expectedUtterance: [
-            [{"string": "mathmlscripted"},{"string": "base"},"a",{"string": "underscript"},"b"],
-            ["a",{"string": "base"},"b",{"string": "underscript"},{"string": "mathmlscripted"}]
+            [{"string": "mathmlscripted"}, {"string": "base"}, "a", {"string": "underscript"}, "b"],
+            ["a", {"string": "base"}, "b", {"string": "underscript"}, {"string": "mathmlscripted"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlscriptedAbbr"},{"string": "baseAbbr"},"a",{"string": "underscriptAbbr"},"b"],
-            ["a",{"string": "baseAbbr"},"b",{"string": "underscriptAbbr"},{"string": "mathmlscriptedAbbr"}]
+            [{"string": "mathmlscriptedAbbr"}, {"string": "baseAbbr"}, "a", {"string": "underscriptAbbr"}, "b"],
+            ["a", {"string": "baseAbbr"}, "b", {"string": "underscriptAbbr"}, {"string": "mathmlscriptedAbbr"}]
           ]
         }, {
           accOrElmOrID: "mover-1",
           expectedUtterance: [
-            [{"string": "mathmlscripted"},{"string": "base"},"a",{"string": "overscript"},"b"],
-            ["a",{"string": "base"},"b",{"string": "overscript"},{"string": "mathmlscripted"}]
+            [{"string": "mathmlscripted"}, {"string": "base"}, "a", {"string": "overscript"}, "b"],
+            ["a", {"string": "base"}, "b", {"string": "overscript"}, {"string": "mathmlscripted"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlscriptedAbbr"},{"string": "baseAbbr"},"a",{"string": "overscriptAbbr"},"b"],
-            ["a",{"string": "baseAbbr"},"b",{"string": "overscriptAbbr"},{"string": "mathmlscriptedAbbr"}]
+            [{"string": "mathmlscriptedAbbr"}, {"string": "baseAbbr"}, "a", {"string": "overscriptAbbr"}, "b"],
+            ["a", {"string": "baseAbbr"}, "b", {"string": "overscriptAbbr"}, {"string": "mathmlscriptedAbbr"}]
           ]
         }, {
           accOrElmOrID: "munderover-1",
           expectedUtterance: [
-            [{"string": "mathmlscripted"},{"string": "base"},"a",{"string": "underscript"},"b",{"string": "overscript"},"c"],
-            ["a",{"string": "base"},"b",{"string": "underscript"},"c",{"string": "overscript"},{"string": "mathmlscripted"}]
+            [{"string": "mathmlscripted"}, {"string": "base"}, "a", {"string": "underscript"}, "b", {"string": "overscript"}, "c"],
+            ["a", {"string": "base"}, "b", {"string": "underscript"}, "c", {"string": "overscript"}, {"string": "mathmlscripted"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlscriptedAbbr"},{"string": "baseAbbr"},"a",{"string": "underscriptAbbr"},"b",{"string": "overscriptAbbr"},"c"],
-            ["a",{"string": "baseAbbr"},"b",{"string": "underscriptAbbr"},"c",{"string": "overscriptAbbr"},{"string": "mathmlscriptedAbbr"}]
+            [{"string": "mathmlscriptedAbbr"}, {"string": "baseAbbr"}, "a", {"string": "underscriptAbbr"}, "b", {"string": "overscriptAbbr"}, "c"],
+            ["a", {"string": "baseAbbr"}, "b", {"string": "underscriptAbbr"}, "c", {"string": "overscriptAbbr"}, {"string": "mathmlscriptedAbbr"}]
           ]
         }, {
           accOrElmOrID: "mroot-1",
           expectedUtterance: [
-            [{"string": "mathmlroot"},{"string": "base"},"a",{"string": "root-index"},"b"],
-            ["a",{"string": "base"},"b",{"string": "root-index"},{"string": "mathmlroot"}]
+            [{"string": "mathmlroot"}, {"string": "base"}, "a", {"string": "root-index"}, "b"],
+            ["a", {"string": "base"}, "b", {"string": "root-index"}, {"string": "mathmlroot"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlrootAbbr"},{"string": "baseAbbr"},"a",{"string": "root-indexAbbr"},"b"],
-            ["a",{"string": "baseAbbr"},"b",{"string": "root-indexAbbr"},{"string": "mathmlrootAbbr"}]
+            [{"string": "mathmlrootAbbr"}, {"string": "baseAbbr"}, "a", {"string": "root-indexAbbr"}, "b"],
+            ["a", {"string": "baseAbbr"}, "b", {"string": "root-indexAbbr"}, {"string": "mathmlrootAbbr"}]
           ]
         }, {
           accOrElmOrID: "mtable-1",
           expectedUtterance: [
-            [{"string": "mathmltable"},{"string": "tblColumnInfo","count": 3},{"string": "tblRowInfo","count": 2},{"string": "columnInfo","args": [1]},{"string": "rowInfo","args": [1]},"a",{"string": "columnInfo","args": [2]},{"string": "rowInfo","args": [1]},"b",{"string": "columnInfo","args": [3]},{"string": "rowInfo","args": [1]},"c",{"string": "columnInfo","args": [1]},{"string": "rowInfo","args": [2]},"d",{"string": "columnInfo","args": [2]},{"string": "rowInfo","args": [2]},"e",{"string": "columnInfo","args": [3]},{"string": "rowInfo","args": [2]},"f"],
-            ["a",{"string": "columnInfo","args": [1]},{"string": "rowInfo","args": [1]},"b",{"string": "columnInfo","args": [2]},{"string": "rowInfo","args": [1]},"c",{"string": "columnInfo","args": [3]},{"string": "rowInfo","args": [1]},"d",{"string": "columnInfo","args": [1]},{"string": "rowInfo","args": [2]},"e",{"string": "columnInfo","args": [2]},{"string": "rowInfo","args": [2]},"f",{"string": "columnInfo","args": [3]},{"string": "rowInfo","args": [2]},{"string": "mathmltable"},{"string": "tblColumnInfo","count": 3},{"string": "tblRowInfo","count": 2}]
+            [{"string": "mathmltable"}, {"string": "tblColumnInfo", "count": 3}, {"string": "tblRowInfo", "count": 2}, {"string": "columnInfo", "args": [1]}, {"string": "rowInfo", "args": [1]}, "a", {"string": "columnInfo", "args": [2]}, {"string": "rowInfo", "args": [1]}, "b", {"string": "columnInfo", "args": [3]}, {"string": "rowInfo", "args": [1]}, "c", {"string": "columnInfo", "args": [1]}, {"string": "rowInfo", "args": [2]}, "d", {"string": "columnInfo", "args": [2]}, {"string": "rowInfo", "args": [2]}, "e", {"string": "columnInfo", "args": [3]}, {"string": "rowInfo", "args": [2]}, "f"],
+            ["a", {"string": "columnInfo", "args": [1]}, {"string": "rowInfo", "args": [1]}, "b", {"string": "columnInfo", "args": [2]}, {"string": "rowInfo", "args": [1]}, "c", {"string": "columnInfo", "args": [3]}, {"string": "rowInfo", "args": [1]}, "d", {"string": "columnInfo", "args": [1]}, {"string": "rowInfo", "args": [2]}, "e", {"string": "columnInfo", "args": [2]}, {"string": "rowInfo", "args": [2]}, "f", {"string": "columnInfo", "args": [3]}, {"string": "rowInfo", "args": [2]}, {"string": "mathmltable"}, {"string": "tblColumnInfo", "count": 3}, {"string": "tblRowInfo", "count": 2}]
           ],
           expectedBraille: [
-            [{"string": "mathmltableAbbr"},{"string": "tblColumnInfoAbbr","count": 3},{"string": "tblRowInfoAbbr","count": 2},{"string": "cellInfoAbbr","args": [1,1]},"a",{"string": "cellInfoAbbr","args": [2,1]},"b",{"string": "cellInfoAbbr","args": [3,1]},"c",{"string": "cellInfoAbbr","args": [1,2]},"d",{"string": "cellInfoAbbr","args": [2,2]},"e",{"string": "cellInfoAbbr","args": [3,2]},"f"],
-            ["a",{"string": "cellInfoAbbr","args": [1,1]},"b",{"string": "cellInfoAbbr","args": [2,1]},"c",{"string": "cellInfoAbbr","args": [3,1]},"d",{"string": "cellInfoAbbr","args": [1,2]},"e",{"string": "cellInfoAbbr","args": [2,2]},"f",{"string": "cellInfoAbbr","args": [3,2]},{"string": "mathmltableAbbr"},{"string": "tblColumnInfoAbbr","count": 3},{"string": "tblRowInfoAbbr","count": 2}]
+            [{"string": "mathmltableAbbr"}, {"string": "tblColumnInfoAbbr", "count": 3}, {"string": "tblRowInfoAbbr", "count": 2}, {"string": "cellInfoAbbr", "args": [1, 1]}, "a", {"string": "cellInfoAbbr", "args": [2, 1]}, "b", {"string": "cellInfoAbbr", "args": [3, 1]}, "c", {"string": "cellInfoAbbr", "args": [1, 2]}, "d", {"string": "cellInfoAbbr", "args": [2, 2]}, "e", {"string": "cellInfoAbbr", "args": [3, 2]}, "f"],
+            ["a", {"string": "cellInfoAbbr", "args": [1, 1]}, "b", {"string": "cellInfoAbbr", "args": [2, 1]}, "c", {"string": "cellInfoAbbr", "args": [3, 1]}, "d", {"string": "cellInfoAbbr", "args": [1, 2]}, "e", {"string": "cellInfoAbbr", "args": [2, 2]}, "f", {"string": "cellInfoAbbr", "args": [3, 2]}, {"string": "mathmltableAbbr"}, {"string": "tblColumnInfoAbbr", "count": 3}, {"string": "tblRowInfoAbbr", "count": 2}]
           ]
       }, {
           accOrElmOrID: "menclose-1",
           expectedUtterance: [
-            [{"string": "mathmlenclosed"},{"string": "notation-longdiv"},"a"],
-            ["a",{"string": "notation-longdiv"},{"string": "mathmlenclosed"}]
+            [{"string": "mathmlenclosed"}, {"string": "notation-longdiv"}, "a"],
+            ["a", {"string": "notation-longdiv"}, {"string": "mathmlenclosed"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlenclosedAbbr"},{"string": "notation-longdivAbbr"},"a"],
-            ["a",{"string": "notation-longdivAbbr"},{"string": "mathmlenclosedAbbr"}]
+            [{"string": "mathmlenclosedAbbr"}, {"string": "notation-longdivAbbr"}, "a"],
+            ["a", {"string": "notation-longdivAbbr"}, {"string": "mathmlenclosedAbbr"}]
           ]
         }, {
           accOrElmOrID: "menclose-2",
           expectedUtterance: [
-            [{"string": "mathmlenclosed"},{"string": "notation-circle"},"a"],
-            ["a",{"string": "notation-circle"},{"string": "mathmlenclosed"}]
+            [{"string": "mathmlenclosed"}, {"string": "notation-circle"}, "a"],
+            ["a", {"string": "notation-circle"}, {"string": "mathmlenclosed"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlenclosedAbbr"},{"string": "notation-circleAbbr"},"a"],
-            ["a",{"string": "notation-circleAbbr"},{"string": "mathmlenclosedAbbr"}]
+            [{"string": "mathmlenclosedAbbr"}, {"string": "notation-circleAbbr"}, "a"],
+            ["a", {"string": "notation-circleAbbr"}, {"string": "mathmlenclosedAbbr"}]
           ]
         }, {
           accOrElmOrID: "menclose-3",
           expectedUtterance: [
-            [{"string": "mathmlenclosed"},{"string": "notation-left"},{"string": "notation-top"},{"string": "notation-bottom"},"a"],
-            ["a",{"string": "notation-left"},{"string": "notation-top"},{"string": "notation-bottom"},{"string": "mathmlenclosed"}]
+            [{"string": "mathmlenclosed"}, {"string": "notation-left"}, {"string": "notation-top"}, {"string": "notation-bottom"}, "a"],
+            ["a", {"string": "notation-left"}, {"string": "notation-top"}, {"string": "notation-bottom"}, {"string": "mathmlenclosed"}]
           ],
           expectedBraille: [
-            [{"string": "mathmlenclosedAbbr"},{"string": "notation-leftAbbr"},{"string": "notation-topAbbr"},{"string": "notation-bottomAbbr"},"a"],
-            ["a",{"string": "notation-leftAbbr"},{"string": "notation-topAbbr"},{"string": "notation-bottomAbbr"},{"string": "mathmlenclosedAbbr"}]
+            [{"string": "mathmlenclosedAbbr"}, {"string": "notation-leftAbbr"}, {"string": "notation-topAbbr"}, {"string": "notation-bottomAbbr"}, "a"],
+            ["a", {"string": "notation-leftAbbr"}, {"string": "notation-topAbbr"}, {"string": "notation-bottomAbbr"}, {"string": "mathmlenclosedAbbr"}]
           ]
         }];
 
       // Test all possible utterance order preference values.
       function testOutputOrder(aOutputOrder) {
         return function() {
           SpecialPowers.pushPrefEnv({
             "set": [[PREF_UTTERANCE_ORDER, aOutputOrder]]
--- a/accessible/tests/mochitest/layout.js
+++ b/accessible/tests/mochitest/layout.js
@@ -210,23 +210,23 @@ function getBoundsForDOMElm(aID) {
     var img = elm.ownerDocument.querySelector(selector);
 
     var areaCoords = elm.coords.split(",");
     var areaX = parseInt(areaCoords[0]);
     var areaY = parseInt(areaCoords[1]);
     var areaWidth = parseInt(areaCoords[2]) - areaX;
     var areaHeight = parseInt(areaCoords[3]) - areaY;
 
-    var rect = img.getBoundingClientRect();
+    let rect = img.getBoundingClientRect();
     x = rect.left + areaX;
     y = rect.top + areaY;
     width = areaWidth;
     height = areaHeight;
   } else {
-    var rect = elm.getBoundingClientRect();
+    let rect = elm.getBoundingClientRect();
     x = rect.left;
     y = rect.top;
     width = rect.width;
     height = rect.height;
   }
 
   var elmWindow = elm.ownerGlobal;
   return CSSToDevicePixels(elmWindow,
--- a/accessible/tests/mochitest/name/markup.js
+++ b/accessible/tests/mochitest/name/markup.js
@@ -347,17 +347,17 @@ function evaluateXPath(aNode, aExpr, aRe
     var node = aNode.ownerDocument == null ?
       aNode.documentElement : aNode.ownerDocument.documentElement;
     resolver = xpe.createNSResolver(node);
   }
 
   var result = xpe.evaluate(aExpr, aNode, resolver, 0, null);
   var found = [];
   var res;
-  while (res = result.iterateNext())
+  while ((res = result.iterateNext()))
     found.push(res);
 
   return found;
 }
 
 function htmlDocResolver(aPrefix) {
   var ns = {
     "html": "http://www.w3.org/1999/xhtml"
--- a/accessible/tests/mochitest/name/test_browserui.xul
+++ b/accessible/tests/mochitest/name/test_browserui.xul
@@ -79,17 +79,17 @@
       {
         closeBrowserWindow();
       }
 
       gQueue.invoke();
     }
 
     SimpleTest.waitForExplicitFinish();
-    openBrowserWindow(doTests, "about:");
+    openBrowserWindow(doTests, "about:license");
   ]]>
   </script>
 
   <vbox flex="1" style="overflow: auto;">
   <body xmlns="http://www.w3.org/1999/xhtml">
     <a target="_blank"
        href="https://bugzilla.mozilla.org/show_bug.cgi?id=507382"
        title="focus is fired earlier than root accessible name is changed when switching between tabs">
--- a/accessible/tests/mochitest/name/test_general.html
+++ b/accessible/tests/mochitest/name/test_general.html
@@ -143,16 +143,19 @@
       testName("tablemenuitem", "menuitem 1");
 
       // Get the name from child acronym title attribute rather than from
       // acronym content.
       testName("label_with_acronym", "O A T F World Wide Web");
 
       testName("testArticle", "Test article");
 
+      testName("h1", "heading");
+      testName("aria_heading", "aria_heading");
+
       // ////////////////////////////////////////////////////////////////////////
       // title attribute
 
       // If nothing is left. Let's try title attribute.
       testName("btn_title", "title");
 
       // ////////////////////////////////////////////////////////////////////////
       // textarea name
@@ -418,17 +421,17 @@
          title="Input your country of origin"/ >
 
   <!-- name from subtree, surround control by spaces to not jamm the text -->
   <label id="insert_spaces_around_control">
     start<input value="value">end
   </label>
 
   <!-- no name from subtree because it holds whitespaces only -->
-  <a id="from_label_ignore_ws_subtree" href="about:" title="about">&nbsp;&nbsp;  </a>
+  <a id="from_label_ignore_ws_subtree" href="about:mozilla" title="about">&nbsp;&nbsp;  </a>
 
   <!-- label element, label contains control -->
   <label>text<button id="btn_label_inside">10</button>text</label>
   <br/>
 
   <!-- label element, label and the button are in the same form -->
   <form>
     <label for="btn_label_inform">in form</label>
@@ -483,16 +486,19 @@
     <acronym title="O A T F">OATF</acronym>
     <abbr title="World Wide Web">WWW</abbr>
   </label>
 
   <div id="testArticle" role="article" title="Test article">
     <p>This is a paragraph inside the article.</p>
   </div>
 
+  <h1 id="h1" title="oops">heading</h1>
+  <div role="heading" id="aria_heading">aria_heading</div>
+
   <!-- name from title attribute -->
   <span id="btn_title" role="group" title="title">15</span>
 
   <!-- A textarea nested in a label with a text child (bug #453371). -->
   <form>
     <label>Story
       <textarea id="textareawithchild" name="name">Foo</textarea>
       is ended.
--- a/accessible/tests/mochitest/pivot.js
+++ b/accessible/tests/mochitest/pivot.js
@@ -18,43 +18,43 @@ const NS_ERROR_INVALID_ARG = 0x80070057;
 // //////////////////////////////////////////////////////////////////////////////
 // Traversal rules
 
 /**
  * Rule object to traverse all focusable nodes and text nodes.
  */
 var HeadersTraversalRule =
 {
-  getMatchRoles: function(aRules) {
+  getMatchRoles(aRules) {
     aRules.value = [ROLE_HEADING];
     return aRules.value.length;
   },
 
   preFilter: PREFILTER_INVISIBLE,
 
-  match: function(aAccessible) {
+  match(aAccessible) {
     return FILTER_MATCH;
   },
 
   QueryInterface: XPCOMUtils.generateQI([nsIAccessibleTraversalRule])
 };
 
 /**
  * Traversal rule for all focusable nodes or leafs.
  */
 var ObjectTraversalRule =
 {
-  getMatchRoles: function(aRules) {
+  getMatchRoles(aRules) {
     aRules.value = [];
     return 0;
   },
 
   preFilter: PREFILTER_INVISIBLE | PREFILTER_ARIA_HIDDEN | PREFILTER_TRANSPARENT,
 
-  match: function(aAccessible) {
+  match(aAccessible) {
     var rv = FILTER_IGNORE;
     var role = aAccessible.role;
     if (hasState(aAccessible, STATE_FOCUSABLE) &&
         (role != ROLE_DOCUMENT && role != ROLE_INTERNAL_FRAME))
       rv = FILTER_IGNORE_SUBTREE | FILTER_MATCH;
     else if (aAccessible.childCount == 0 &&
              role != ROLE_STATICTEXT && aAccessible.name.trim())
       rv = FILTER_MATCH;
@@ -379,27 +379,27 @@ function setModalRootInvoker(aDocAcc, aM
 function queueTraversalSequence(aQueue, aDocAcc, aRule, aModalRoot, aSequence) {
   aDocAcc.virtualCursor.position = null;
 
   // Add modal root (if any)
   aQueue.push(new setModalRootInvoker(aDocAcc, aModalRoot, 0));
 
   aQueue.push(new setVCPosInvoker(aDocAcc, "moveFirst", aRule, aSequence[0]));
 
-  for (var i = 1; i < aSequence.length; i++) {
-    var invoker =
+  for (let i = 1; i < aSequence.length; i++) {
+    let invoker =
       new setVCPosInvoker(aDocAcc, "moveNext", aRule, aSequence[i]);
     aQueue.push(invoker);
   }
 
   // No further more matches for given rule, expect no virtual cursor changes.
   aQueue.push(new setVCPosInvoker(aDocAcc, "moveNext", aRule, false));
 
-  for (var i = aSequence.length - 2; i >= 0; i--) {
-    var invoker =
+  for (let i = aSequence.length - 2; i >= 0; i--) {
+    let invoker =
       new setVCPosInvoker(aDocAcc, "movePrevious", aRule, aSequence[i]);
     aQueue.push(invoker);
   }
 
   // No previous more matches for given rule, expect no virtual cursor changes.
   aQueue.push(new setVCPosInvoker(aDocAcc, "movePrevious", aRule, false));
 
   aQueue.push(new setVCPosInvoker(aDocAcc, "moveLast", aRule,
--- a/accessible/tests/mochitest/pivot/test_virtualcursor.html
+++ b/accessible/tests/mochitest/pivot/test_virtualcursor.html
@@ -55,17 +55,17 @@
          "An ", "embedded", " document.", "Hide me", "Link 1", "Link 2",
          "Link 3", "Hello", "World"]);
 
       // Just a random smoke test to see if our setTextRange works.
       gQueue.push(
         new setVCRangeInvoker(
           docAcc,
           getAccessible(doc.getElementById("paragraph-2"), nsIAccessibleText),
-          [2,6]));
+          [2, 6]));
 
       gQueue.push(new removeVCPositionInvoker(
         docAcc, doc.getElementById("hide-me")));
 
       gQueue.push(new removeVCRootInvoker(
         doc.getElementById("links")));
 
       var [x, y] = getBounds(getAccessible(doc.getElementById("heading-1-1")));
--- a/accessible/tests/mochitest/pivot/test_virtualcursor_text.html
+++ b/accessible/tests/mochitest/pivot/test_virtualcursor_text.html
@@ -32,185 +32,185 @@
       gQueue = new eventQueue();
 
       gQueue.onFinish = function onFinish() {
         closeBrowserWindow();
       };
 
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("paragraph-1"))));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,4],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 4],
                   getAccessible(doc.getElementById("paragraph-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [4,5],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [4, 5],
                   getAccessible(doc.getElementById("paragraph-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", CHAR_BOUNDARY, [3,4],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", CHAR_BOUNDARY, [3, 4],
                   getAccessible(doc.getElementById("paragraph-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [5,7],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [5, 7],
                   getAccessible(doc.getElementById("paragraph-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,3],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 3],
                   getAccessible(doc.getElementById("p1-link-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [10,14],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [10, 14],
                   getAccessible(doc.getElementById("paragraph-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,3],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 3],
                   getAccessible(doc.getElementById("p1-link-1"), nsIAccessibleText)));
       // set user input to false, and see if it works
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [5,7],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [5, 7],
                   getAccessible(doc.getElementById("paragraph-1"), nsIAccessibleText)),
                   false);
 
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("section-1"))));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,1],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 1],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,9],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 9],
                   getAccessible(doc.getElementById("s1-link-1"), nsIAccessibleText)));
       // set user input to false, and see if it works
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [10,14],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [10, 14],
                   getAccessible(doc.getElementById("s1-link-1"), nsIAccessibleText),
                   false));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [4,6],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [4, 6],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [7,12],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [7, 12],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,2],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 2],
                   getAccessible(doc.getElementById("s1-link-2"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [15,19],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [15, 19],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [20,28],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [20, 28],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,5],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 5],
                   getAccessible(doc.getElementById("section-2"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [6,10],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [6, 10],
                   getAccessible(doc.getElementById("section-2"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,5],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 5],
                   getAccessible(doc.getElementById("section-2"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [20,28],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [20, 28],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [15,19],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [15, 19],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,2],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 2],
                   getAccessible(doc.getElementById("s1-link-2"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [7,12],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [7, 12],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [4,6],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [4, 6],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [10,14],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [10, 14],
                   getAccessible(doc.getElementById("s1-link-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,9],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 9],
                   getAccessible(doc.getElementById("s1-link-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,1],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 1],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
 
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("s1-link-1"))));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", CHAR_BOUNDARY, [1,2],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", CHAR_BOUNDARY, [1, 2],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", CHAR_BOUNDARY, [0,1],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", CHAR_BOUNDARY, [0, 1],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [1,2],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [1, 2],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [0,1],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [0, 1],
                   getAccessible(doc.getElementById("s1-link-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [1,2],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [1, 2],
                   getAccessible(doc.getElementById("s1-link-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [2,9],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [2, 9],
                   getAccessible(doc.getElementById("s1-link-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [10,14],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [10, 14],
                   getAccessible(doc.getElementById("s1-link-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [3,4],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [3, 4],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", CHAR_BOUNDARY, [13,14],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", CHAR_BOUNDARY, [13, 14],
                   getAccessible(doc.getElementById("s1-link-1"), nsIAccessibleText)));
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("section-2"))));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", CHAR_BOUNDARY, [27,28],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", CHAR_BOUNDARY, [27, 28],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [0,1],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", CHAR_BOUNDARY, [0, 1],
                   getAccessible(doc.getElementById("section-2"), nsIAccessibleText)));
 
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("paragraph-2"))));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,12],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 12],
                   getAccessible(doc.getElementById("paragraph-2"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,7],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 7],
                   getAccessible(doc.getElementById("cell-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,8],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 8],
                   getAccessible(doc.getElementById("cell-2"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,3],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 3],
                   getAccessible(doc.getElementById("cell-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [4,11],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [4, 11],
                   getAccessible(doc.getElementById("cell-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,6],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 6],
                   getAccessible(doc.getElementById("cell-4"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [7,13],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [7, 13],
                   getAccessible(doc.getElementById("cell-4"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,7],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 7],
                   getAccessible(doc.getElementById("section-3"), nsIAccessibleText)));
 
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("section-3"))));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,7],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 7],
                   getAccessible(doc.getElementById("section-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [7,13],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [7, 13],
                   getAccessible(doc.getElementById("cell-4"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,6],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 6],
                   getAccessible(doc.getElementById("cell-4"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [4,11],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [4, 11],
                   getAccessible(doc.getElementById("cell-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,3],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 3],
                   getAccessible(doc.getElementById("cell-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,8],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 8],
                   getAccessible(doc.getElementById("cell-2"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,7],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 7],
                   getAccessible(doc.getElementById("cell-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,12],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 12],
                   getAccessible(doc.getElementById("paragraph-2"), nsIAccessibleText)));
 
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("paragraph-3"))));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,7],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 7],
                   getAccessible(doc.getElementById("paragraph-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,8],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 8],
                   getAccessible(doc.getElementById("p3-link-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [8,10],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [8, 10],
                   getAccessible(doc.getElementById("paragraph-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,4],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 4],
                   getAccessible(doc.getElementById("p3-link-2"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,5],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 5],
                   getAccessible(doc.getElementById("p3-link-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [14,20],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [14, 20],
                   getAccessible(doc.getElementById("paragraph-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,5],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 5],
                   getAccessible(doc.getElementById("p3-link-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,4],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 4],
                   getAccessible(doc.getElementById("p3-link-2"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [8,10],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [8, 10],
                   getAccessible(doc.getElementById("paragraph-3"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,8],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 8],
                   getAccessible(doc.getElementById("p3-link-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,7],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 7],
                   getAccessible(doc.getElementById("paragraph-3"), nsIAccessibleText)));
 
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("s1-link-2"))));
       // Start with the pivot in the middle of the paragraph
       gQueue.push(new setVCPosInvoker(docAcc, "moveNext", ObjectTraversalRule, " will traverse"));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [15,19],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [15, 19],
                   getAccessible(doc.getElementById("section-1"), nsIAccessibleText)));
-      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0,2],
+      gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, [0, 2],
                   getAccessible(doc.getElementById("s1-link-2"), nsIAccessibleText)));
 
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("end-block"))));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,4],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 4],
                   getAccessible(doc.getElementById("end-block"), nsIAccessibleText)));
       gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, null, false));
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("start-block"))));
-      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0,4],
+      gQueue.push(new setVCTextInvoker(docAcc, "moveNextByText", WORD_BOUNDARY, [0, 4],
                   getAccessible(doc.getElementById("start-block"), nsIAccessibleText)));
       gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, null, false));
       gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, null, false));
       gQueue.push(new setVCPosInvoker(docAcc, null, null,
                                       getAccessible(doc.getElementById("start-block"))));
       gQueue.push(new setVCTextInvoker(docAcc, "movePreviousByText", WORD_BOUNDARY, null, false));
 
       gQueue.invoke();
--- a/accessible/tests/mochitest/relations.js
+++ b/accessible/tests/mochitest/relations.js
@@ -60,44 +60,45 @@ function testRelation(aIdentifier, aRelT
     ok(false, "There are unexpected targets of " + relDescr);
     return;
   }
 
   var relatedIds = (aRelatedIdentifiers instanceof Array) ?
   aRelatedIdentifiers : [aRelatedIdentifiers];
 
   var targets = [];
-   for (var idx = 0; idx < relatedIds.length; idx++)
+   for (let idx = 0; idx < relatedIds.length; idx++)
      targets.push(getAccessible(relatedIds[idx]));
 
   if (targets.length != relatedIds.length)
     return;
 
   var actualTargets = relation.getTargets();
 
   // Check if all given related accessibles are targets of obtained relation.
-  for (var idx = 0; idx < targets.length; idx++) {
+  for (let idx = 0; idx < targets.length; idx++) {
     var isFound = false;
-    var enumerate = actualTargets.enumerate();
+    let enumerate = actualTargets.enumerate();
     while (enumerate.hasMoreElements()) {
-      var relatedAcc = enumerate.getNext().QueryInterface(nsIAccessible);
+      let relatedAcc = enumerate.getNext().QueryInterface(nsIAccessible);
       if (targets[idx] == relatedAcc) {
         isFound = true;
         break;
       }
     }
 
     ok(isFound, prettyName(relatedIds[idx]) + " is not a target of" + relDescr);
   }
 
   // Check if all obtained targets are given related accessibles.
-  var enumerate = actualTargets.enumerate();
+  let enumerate = actualTargets.enumerate();
   while (enumerate.hasMoreElements()) {
-    var relatedAcc = enumerate.getNext().QueryInterface(nsIAccessible);
-    for (var idx = 0; idx < targets.length && relatedAcc != targets[idx]; idx++);
+    let relatedAcc = enumerate.getNext().QueryInterface(nsIAccessible);
+    let idx;
+    for (idx = 0; idx < targets.length && relatedAcc != targets[idx]; idx++);
 
     if (idx == targets.length)
       ok(false, "There is unexpected target" + prettyName(relatedAcc) + "of" + relDescr);
   }
 }
 
 /**
  * Test that the given accessible relations don't exist.
@@ -123,26 +124,26 @@ function testAbsentRelation(aIdentifier,
     ok(true, "No relations exist.");
     return;
   }
 
   var relatedIds = (aUnrelatedIdentifiers instanceof Array) ?
     aUnrelatedIdentifiers : [aUnrelatedIdentifiers];
 
   var targets = [];
-  for (var idx = 0; idx < relatedIds.length; idx++)
+  for (let idx = 0; idx < relatedIds.length; idx++)
     targets.push(getAccessible(relatedIds[idx]));
 
   if (targets.length != relatedIds.length)
     return;
 
   var actualTargets = relation.getTargets();
 
   // Any found targets that match given accessibles should be called out.
-  for (var idx = 0; idx < targets.length; idx++) {
+  for (let idx = 0; idx < targets.length; idx++) {
     var notFound = true;
     var enumerate = actualTargets.enumerate();
     while (enumerate.hasMoreElements()) {
       var relatedAcc = enumerate.getNext().QueryInterface(nsIAccessible);
       if (targets[idx] == relatedAcc) {
         notFound = false;
         break;
       }
--- a/accessible/tests/mochitest/relations/test_embeds.xul
+++ b/accessible/tests/mochitest/relations/test_embeds.xul
@@ -90,29 +90,29 @@
     function doTests()
     {
       testRelation(browserDocument(), RELATION_EMBEDS,
                    getAccessible(currentTabDocument()));
 
       enableLogging("docload");
       gQueue = new eventQueue();
 
-      gQueue.push(new loadURI("about:about"));
+      gQueue.push(new loadURI("about:robots"));
       gQueue.push(new loadOneTab("about:mozilla"));
 
       gQueue.onFinish = function()
       {
         disableLogging();
         closeBrowserWindow();
       }
       gQueue.invoke();
     }
 
     SimpleTest.waitForExplicitFinish();
-    openBrowserWindow(doTests, "about:");
+    openBrowserWindow(doTests, "about:license");
   ]]>
   </script>
 
   <vbox flex="1" style="overflow: auto;">
   <body xmlns="http://www.w3.org/1999/xhtml">
     <a target="_blank"
        href="https://bugzilla.mozilla.org/show_bug.cgi?id=707654"
        title="Embeds relation on root accessible can return not content document">
--- a/accessible/tests/mochitest/relations/test_tabbrowser.xul
+++ b/accessible/tests/mochitest/relations/test_tabbrowser.xul
@@ -30,31 +30,31 @@
     {
       this.eventSeq = [
         new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 0),
         new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
      ];
 
       this.invoke = function testTabRelations_invoke()
       {
-        var docURIs = ["about:", "about:mozilla"];
+        var docURIs = ["about:license", "about:mozilla"];
         tabBrowser().loadTabs(docURIs, {
           inBackground: false,
           replace: true,
           triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
         });
       }
 
       this.finalCheck = function testTabRelations_finalCheck(aEvent)
       {
         ////////////////////////////////////////////////////////////////////////
         // 'labelled by'/'label for' relations for xul:tab and xul:tabpanel
 
         var tabs = tabBrowser().tabContainer.childNodes;
-        var panels = tabBrowser().mTabBox.tabpanels.childNodes;
+        var panels = tabBrowser().tabbox.tabpanels.childNodes;
 
         testRelation(panels[0], RELATION_LABELLED_BY, tabs[0]);
         testRelation(tabs[0], RELATION_LABEL_FOR, panels[0]);
         testRelation(panels[1], RELATION_LABELLED_BY, tabs[1]);
         testRelation(tabs[1], RELATION_LABEL_FOR, panels[1]);
       }
 
       this.getID = function testTabRelations_getID()
--- a/accessible/tests/mochitest/relations/test_ui_modalprompt.html
+++ b/accessible/tests/mochitest/relations/test_ui_modalprompt.html
@@ -29,17 +29,17 @@
         return false;
       }
     }
 
     function showAlert() {
       this.eventSeq = [
         {
           type: EVENT_SHOW,
-          match: function(aEvent) {
+          match(aEvent) {
             return aEvent.accessible.role == ROLE_DIALOG;
           }
         }
       ];
 
       this.invoke = function showAlert_invoke() {
         window.setTimeout(
           function() {
--- a/accessible/tests/mochitest/role.js
+++ b/accessible/tests/mochitest/role.js
@@ -13,16 +13,17 @@ const ROLE_CAPTION = nsIAccessibleRole.R
 const ROLE_CELL = nsIAccessibleRole.ROLE_CELL;
 const ROLE_CHECKBUTTON = nsIAccessibleRole.ROLE_CHECKBUTTON;
 const ROLE_CHECK_MENU_ITEM = nsIAccessibleRole.ROLE_CHECK_MENU_ITEM;
 const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW;
 const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
 const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
 const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
 const ROLE_COLUMNHEADER = nsIAccessibleRole.ROLE_COLUMNHEADER;
+const ROLE_DATE_EDITOR = nsIAccessibleRole.ROLE_DATE_EDITOR;
 const ROLE_DEFINITION = nsIAccessibleRole.ROLE_DEFINITION;
 const ROLE_DEFINITION_LIST = nsIAccessibleRole.ROLE_DEFINITION_LIST;
 const ROLE_DETAILS = nsIAccessibleRole.ROLE_DETAILS;
 const ROLE_DIAGRAM = nsIAccessibleRole.ROLE_DIAGRAM;
 const ROLE_DIALOG = nsIAccessibleRole.ROLE_DIALOG;
 const ROLE_DOCUMENT = nsIAccessibleRole.ROLE_DOCUMENT;
 const ROLE_EDITCOMBOBOX = nsIAccessibleRole.ROLE_EDITCOMBOBOX;
 const ROLE_EMBEDDED_OBJECT = nsIAccessibleRole.ROLE_EMBEDDED_OBJECT;
@@ -161,17 +162,17 @@ function getRole(aAccOrElmOrID) {
   return role;
 }
 
 /**
  * Analogy of SimpleTest.is function used to check the role.
  */
 function isRole(aIdentifier, aRole, aMsg) {
   var role = getRole(aIdentifier);
-  if (role == - 1)
+  if (role == -1)
     return;
 
   if (role == aRole) {
     ok(true, aMsg);
     return;
   }
 
   var got = roleToString(role);
--- a/accessible/tests/mochitest/role/test_aria.html
+++ b/accessible/tests/mochitest/role/test_aria.html
@@ -112,17 +112,17 @@
         var id = weak_landmarks[l] + "_table";
         testRole(id, ROLE_TABLE);
     
         var accessibleTable = getAccessible(id, [nsIAccessibleTable], null,
                                             DONOTFAIL_IF_NO_INTERFACE);
         ok(!!accessibleTable, "landmarked table should have nsIAccessibleTable");
     
         if (accessibleTable)
-          is(accessibleTable.getCellAt(0,0).firstChild.name, "hi", "no cell");
+          is(accessibleTable.getCellAt(0, 0).firstChild.name, "hi", "no cell");
       }
 
       // ////////////////////////////////////////////////////////////////////////
       // test gEmptyRoleMap
       testRole("buttontable_row", ROLE_NOTHING);
       testRole("buttontable_cell", ROLE_NOTHING);
 
       // abstract roles
--- a/accessible/tests/mochitest/role/test_general.xul
+++ b/accessible/tests/mochitest/role/test_general.xul
@@ -20,18 +20,16 @@
     {
       ok(!isAccessible("image"),
                       "image without tooltiptext shouldn't be accessible.");
       testRole("image-tooltiptext", ROLE_GRAPHIC);
       testRole("image-onclick", ROLE_PUSHBUTTON);
 
       ok(!isAccessible("statusbarpanel"),
                       "statusbarpanel shouldn't be accessible.");
-      testRole("statusbarpanel-iconic", ROLE_PUSHBUTTON);
-      testRole("statusbarpanel-iconic-text", ROLE_PUSHBUTTON);
       testRole("statusbar", ROLE_STATUSBAR);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
@@ -52,15 +50,13 @@
     </pre>
   </body>
 
   <image id="image" src="../moz.png"/>
   <image id="image-tooltiptext" src="../moz.png" tooltiptext="hello"/>
   <image id="image-onclick" src="../moz.png" onclick=""/>
 
   <statusbarpanel id="statusbarpanel"></statusbarpanel>
-  <statusbarpanel id="statusbarpanel-iconic" class="statusbarpanel-iconic"></statusbarpanel>
-  <statusbarpanel id="statusbarpanel-iconic-text" class="statusbarpanel-iconic-text"></statusbarpanel>
   <statusbar id="statusbar"></statusbar>
 
   </hbox>
 </window>
 
--- a/accessible/tests/mochitest/scroll/test_zoom.html
+++ b/accessible/tests/mochitest/scroll/test_zoom.html
@@ -16,37 +16,37 @@
           src="../role.js"></script>
   <script type="application/javascript"
           src="../layout.js"></script>
 
   <script type="application/javascript">
     function testScrollToPoint() {
       // scrollToPoint relative screen
       var anchor = getAccessible("bottom1");
-      var [x, /* y */] = getPos(anchor);
+      let [x, /* y */] = getPos(anchor);
       var [docX, docY] = getPos(document);
 
       anchor.scrollToPoint(COORDTYPE_SCREEN_RELATIVE, docX, docY);
       testPos(anchor, [x, docY]);
 
       // scrollToPoint relative window
       anchor = getAccessible("bottom2");
-      var [x, /* y */] = getPos(anchor);
+      [x, /* y */] = getPos(anchor);
       var wnd = getRootAccessible().DOMDocument.defaultView;
       var [screenX, screenY] = CSSToDevicePixels(wnd, wnd.screenX, wnd.screenY);
-      var scrollToX = docX - screenX, scrollToY = docY - screenY;
+      let scrollToX = docX - screenX, scrollToY = docY - screenY;
 
       anchor.scrollToPoint(COORDTYPE_WINDOW_RELATIVE, scrollToX, scrollToY);
       testPos(anchor, [x, docY]);
 
       // scrollToPoint relative parent
       anchor = getAccessible("bottom3");
-      var [x, /* y */] = getPos(anchor);
+      [x, /* y */] = getPos(anchor);
       var [parentX, parentY] = getPos(anchor.parent);
-      var scrollToX = parentX - docX, scrollToY = parentY - docY;
+      scrollToX = parentX - docX, scrollToY = parentY - docY;
 
       anchor.scrollToPoint(COORDTYPE_PARENT_RELATIVE, scrollToX, scrollToY);
       testPos(anchor, [x, docY]);
     }
 
     function doTest() {
       testScrollToPoint();
       zoomDocument(document, 2.0);
--- a/accessible/tests/mochitest/selectable.js
+++ b/accessible/tests/mochitest/selectable.js
@@ -13,32 +13,32 @@ function testSelectableSelection(aIdenti
   var len = aSelectedChildren.length;
 
   // getSelectedChildren
   var selectedChildren = acc.selectedItems;
   is(selectedChildren ? selectedChildren.length : 0, len,
      msg + "getSelectedChildren: wrong selected children count for " +
      prettyName(aIdentifier));
 
-  for (var idx = 0; idx < len; idx++) {
-    var expectedAcc = getAccessible(aSelectedChildren[idx]);
+  for (let idx = 0; idx < len; idx++) {
+    let expectedAcc = getAccessible(aSelectedChildren[idx]);
     var actualAcc = selectedChildren.queryElementAt(idx, nsIAccessible);
     is(actualAcc, expectedAcc,
        msg + "getSelectedChildren: wrong selected child at index " + idx +
        " for " + prettyName(aIdentifier) + " { actual : " +
        prettyName(actualAcc) + ", expected: " + prettyName(expectedAcc) + "}");
   }
 
   // selectedItemCount
   is(acc.selectedItemCount, aSelectedChildren.length,
      "selectedItemCount: wrong selected children count for " + prettyName(aIdentifier));
 
   // getSelectedItemAt
-  for (var idx = 0; idx < len; idx++) {
-    var expectedAcc = getAccessible(aSelectedChildren[idx]);
+  for (let idx = 0; idx < len; idx++) {
+    let expectedAcc = getAccessible(aSelectedChildren[idx]);
     is(acc.getSelectedItemAt(idx), expectedAcc,
        msg + "getSelectedItemAt: wrong selected child at index " + idx + " for " +
        prettyName(aIdentifier));
   }
 
   // isItemSelected
   testIsItemSelected(acc, acc, { value: 0 }, aSelectedChildren, msg);
 }
@@ -63,16 +63,16 @@ function testIsItemSelected(aSelectAcc, 
 
       // isItemSelected
       is(aSelectAcc.isItemSelected(aIndexObj.value++), isSelected,
          aMsg + "isItemSelected: wrong selected child " + prettyName(child) +
          " for " + prettyName(aSelectAcc));
 
       // selected state
       testStates(child, isSelected ? STATE_SELECTED : 0, 0,
-                 !isSelected ? STATE_SELECTED : 0 , 0);
+                 !isSelected ? STATE_SELECTED : 0, 0);
 
       continue;
     }
 
     testIsItemSelected(aSelectAcc, child, aIndexObj, aSelectedChildren);
   }
 }
--- a/accessible/tests/mochitest/selectable/test_select.html
+++ b/accessible/tests/mochitest/selectable/test_select.html
@@ -76,17 +76,17 @@
       testSelectableSelection(select, [ "cb2_item1" ]);
 
       select.unselectAll();
       testSelectableSelection(select, [ "cb2_item1" ]);
 
       // ////////////////////////////////////////////////////////////////////////
       // select@size="4" aka single selectable listbox
 
-      var id = "listbox";
+      id = "listbox";
       ok(isAccessible(id, [nsIAccessibleSelectable]),
          "No selectable accessible for " + id);
 
       select = getAccessible(id, [nsIAccessibleSelectable]);
       testSelectableSelection(select, [ ]);
 
       // select 2nd item
       select.addItemToSelection(1);
@@ -151,17 +151,17 @@
                               "selectAll: ");
 
       select.unselectAll();
       testSelectableSelection(select, [ ], "unselectAll: ");
 
       // ////////////////////////////////////////////////////////////////////////
       // select@size="4" multiselect with optgroups
 
-      var id = "listbox4";
+      id = "listbox4";
       ok(isAccessible(id, [nsIAccessibleSelectable]),
          "No selectable accessible for " + id);
 
       select = getAccessible(id, [nsIAccessibleSelectable]);
       testSelectableSelection(select, [ ]);
 
       select.addItemToSelection(0);
       testSelectableSelection(select, [ "lb4_item1" ]);
--- a/accessible/tests/mochitest/states/test_doc.html
+++ b/accessible/tests/mochitest/states/test_doc.html
@@ -18,19 +18,19 @@
   <script type="application/javascript">
     function doTest() {
       // Bug 566542: root accesible should expose active state when focused.
       testStates(getRootAccessible(), 0, EXT_STATE_ACTIVE);
 
       // Bug 509696, 607219.
       testStates(document, STATE_READONLY, 0); // role=""
 
-      document.body.setAttribute("role","banner"); // no platform mapping
+      document.body.setAttribute("role", "banner"); // no platform mapping
       testStates(document, STATE_READONLY);
-      document.body.setAttribute("role","foo"); // bogus role
+      document.body.setAttribute("role", "foo"); // bogus role
       testStates(document, STATE_READONLY);
       document.body.removeAttribute("role");
       testStates(document, STATE_READONLY);
 
       // Bugs 454997 and 467387
       testStates(document, STATE_READONLY);
       testStates("document", STATE_READONLY);
       testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
--- a/accessible/tests/mochitest/states/test_inputs.html
+++ b/accessible/tests/mochitest/states/test_inputs.html
@@ -26,18 +26,18 @@
 
     testStates("input_readonly", 0, EXT_STATE_EDITABLE);
     testStates("input_disabled", 0, EXT_STATE_EDITABLE);
     testStates("textarea_readonly", 0, EXT_STATE_EDITABLE);
     testStates("textarea_disabled", 0, EXT_STATE_EDITABLE);
 
     // //////////////////////////////////////////////////////////////////////////
     // 'required', 'readonly' and 'unavailable' states.
-    var maybe_required = ["input","search","radio","checkbox","textarea"];
-    var never_required = ["submit","button","reset","image"];
+    var maybe_required = ["input", "search", "radio", "checkbox", "textarea"];
+    var never_required = ["submit", "button", "reset", "image"];
 
     var i;
     for (i in maybe_required) {
       testStates(maybe_required[i],
                  STATE_FOCUSABLE, 0,
                  STATE_REQUIRED | STATE_READONLY | STATE_UNAVAILABLE);
 
       testStates(maybe_required[i] + "_required",
@@ -69,17 +69,17 @@
     // //////////////////////////////////////////////////////////////////////////
     // inherited from file control
     var fileBrowseButton = getAccessible("file").firstChild;
     testStates(fileBrowseButton, STATE_UNAVAILABLE | STATE_REQUIRED);
     // No states on the label.
 
     // //////////////////////////////////////////////////////////////////////////
     // 'invalid' state
-    var invalid = ["pattern","email","url"];
+    var invalid = ["pattern", "email", "url"];
     for (i in invalid) {
       testStates(invalid[i], STATE_INVALID);
       testStates(invalid[i] + "2", 0, 0, STATE_INVALID);
     }
 
     // //////////////////////////////////////////////////////////////////////////
     // not 'invalid' state
     // (per spec, min/maxlength are always valid until interactively edited)
@@ -90,17 +90,17 @@
        "input should be valid despite maxlength (no interactive edits)");
 
     var validInput2 = document.createElement("input");
     validInput2.minLength = "1";
     validInput2.value = "";
     ok(validInput2.validity.valid,
        "input should be valid despite minlength (no interactive edits)");
 
-    var valid = ["minlength","maxlength"];
+    var valid = ["minlength", "maxlength"];
     for (i in valid) {
       testStates(valid[i], 0, 0, STATE_INVALID);
       testStates(valid[i] + "2", 0, 0, STATE_INVALID);
     }
 
     // //////////////////////////////////////////////////////////////////////////
     // 'invalid' state
     // (per spec, min/maxlength validity is affected by interactive edits)
--- a/accessible/tests/mochitest/table.js
+++ b/accessible/tests/mochitest/table.js
@@ -90,17 +90,17 @@ function testTableStruct(aIdentifier, aC
 
   // special types of column headers handling
   if (aColHeaderType) {
     var headersObj = {
       role: ROLE_LIST,
       children: []
     };
 
-    for (var idx = 0; idx < colsCount; idx++) {
+    for (let idx = 0; idx < colsCount; idx++) {
       var headerCellObj = {
         role: ROLE_COLUMNHEADER
       };
       headersObj.children.push(headerCellObj);
     }
 
     if (aColHeaderType == kTreeColumnHeader) {
       var columnPickerObj = {
@@ -109,43 +109,41 @@ function testTableStruct(aIdentifier, aC
 
       headersObj.children.push(columnPickerObj);
     }
 
     tableObj.children.push(headersObj);
   }
 
   // rows and cells accessibles
-  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
-    var rowObj = {
+  for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    let rowObj = {
       role: aRowRoles ? aRowRoles[rowIdx] : ROLE_ROW,
       children: []
     };
 
-    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
-      var celltype = aCellsArray[rowIdx][colIdx];
+    for (let colIdx = 0; colIdx < colsCount; colIdx++) {
+      let celltype = aCellsArray[rowIdx][colIdx];
 
       var role = ROLE_NOTHING;
       switch (celltype) {
         case kDataCell:
           role = (aTableType == kMathTable ? ROLE_MATHML_CELL :
                   (isGrid ? ROLE_GRID_CELL : ROLE_CELL));
           break;
         case kRowHeaderCell:
           role = ROLE_ROWHEADER;
           break;
         case kColHeaderCell:
           role = ROLE_COLUMNHEADER;
           break;
       }
 
       if (role != ROLE_NOTHING) {
-        var cellObj = {
-          role: role
-        };
+        var cellObj = { role };
         rowObj.children.push(cellObj);
       }
     }
 
     tableObj.children.push(rowObj);
   }
 
   testAccessibleTree(aIdentifier, tableObj);
@@ -160,35 +158,36 @@ function testTableStruct(aIdentifier, aC
 
   // rowCount and columnCount
   is(table.rowCount, rowCount,
      "Wrong rows count of " + prettyName(aIdentifier));
   is(table.columnCount, colsCount,
      "Wrong columns count of " + prettyName(aIdentifier));
 
   // rows and columns extents
-  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
-    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
-      var celltype = aCellsArray[rowIdx][colIdx];
+  for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    for (let colIdx = 0; colIdx < colsCount; colIdx++) {
+      let celltype = aCellsArray[rowIdx][colIdx];
       if (celltype & kOrigin) {
 
         // table getRowExtentAt
         var rowExtent = table.getRowExtentAt(rowIdx, colIdx);
-        for (var idx = rowIdx + 1;
+        let idx;
+        for (idx = rowIdx + 1;
              idx < rowCount && (aCellsArray[idx][colIdx] & kRowSpanned);
              idx++);
 
         var expectedRowExtent = idx - rowIdx;
         is(rowExtent, expectedRowExtent,
            "getRowExtentAt: Wrong number of spanned rows at (" + rowIdx + ", " +
            colIdx + ") for " + prettyName(aIdentifier));
 
         // table getColumnExtentAt
         var colExtent = table.getColumnExtentAt(rowIdx, colIdx);
-        for (var idx = colIdx + 1;
+        for (idx = colIdx + 1;
              idx < colsCount && (aCellsArray[rowIdx][idx] & kColSpanned);
              idx++);
 
         var expectedColExtent = idx - colIdx;
         is(colExtent, expectedColExtent,
            "getColumnExtentAt: Wrong number of spanned columns at (" + rowIdx +
            ", " + colIdx + ") for " + prettyName(aIdentifier));
 
@@ -234,17 +233,17 @@ function testTableIndexes(aIdentifier, a
       try {
         cellAcc = null;
         cellAcc = tableAcc.getCellAt(rowIdx, colIdx);
       } catch (e) { }
 
       ok(idx != -1 && cellAcc || idx == -1 && !cellAcc,
          id + ": Can't get cell accessible at row = " + rowIdx + ", column = " + colIdx);
 
-      if (idx != - 1) {
+      if (idx != -1) {
 
         // getRowIndexAt
         var origRowIdx = rowIdx;
         while (origRowIdx > 0 &&
                aIdxes[rowIdx][colIdx] == aIdxes[origRowIdx - 1][colIdx])
           origRowIdx--;
 
         try {
@@ -369,19 +368,19 @@ function testTableSelection(aIdentifier,
 
   var rowCount = aCellsArray.length;
   var colsCount = aCellsArray[0].length;
 
   // Columns selection tests.
   var selCols = [];
 
   // isColumnSelected test
-  for (var colIdx = 0; colIdx < colsCount; colIdx++) {
+  for (let colIdx = 0; colIdx < colsCount; colIdx++) {
     var isColSelected = true;
-    for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
       if (aCellsArray[rowIdx][colIdx] == false ||
           aCellsArray[rowIdx][colIdx] == undefined) {
         isColSelected = false;
         break;
       }
     }
 
     is(acc.isColumnSelected(colIdx), isColSelected,
@@ -400,28 +399,28 @@ function testTableSelection(aIdentifier,
   var actualSelColsCountObj = { value: null };
   var actualSelCols = acc.getSelectedColumnIndices(actualSelColsCountObj);
 
   var actualSelColsCount = actualSelColsCountObj.value;
   is(actualSelColsCount, selCols.length,
       msg + "Wrong count of selected columns for " + prettyName(aIdentifier) +
       "from getSelectedColumns.");
 
-  for (var i = 0; i < actualSelColsCount; i++) {
+  for (let i = 0; i < actualSelColsCount; i++) {
     is(actualSelCols[i], selCols[i],
         msg + "Column at index " + selCols[i] + " should be selected.");
   }
 
   // Rows selection tests.
   var selRows = [];
 
   // isRowSelected test
-  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+  for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     var isRowSelected = true;
-    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
+    for (let colIdx = 0; colIdx < colsCount; colIdx++) {
       if (aCellsArray[rowIdx][colIdx] == false ||
           aCellsArray[rowIdx][colIdx] == undefined) {
         isRowSelected = false;
         break;
       }
     }
 
     is(acc.isRowSelected(rowIdx), isRowSelected,
@@ -440,27 +439,27 @@ function testTableSelection(aIdentifier,
   var actualSelrowCountObj = { value: null };
   var actualSelRows = acc.getSelectedRowIndices(actualSelrowCountObj);
 
   var actualSelrowCount = actualSelrowCountObj.value;
   is(actualSelrowCount, selRows.length,
       msg + "Wrong count of selected rows for " + prettyName(aIdentifier) +
       "from getSelectedRows.");
 
-  for (var i = 0; i < actualSelrowCount; i++) {
+  for (let i = 0; i < actualSelrowCount; i++) {
     is(actualSelRows[i], selRows[i],
         msg + "Row at index " + selRows[i] + " should be selected.");
   }
 
   // Cells selection tests.
   var selCells = [];
 
   // isCellSelected test
-  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
-    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
+  for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    for (let colIdx = 0; colIdx < colsCount; colIdx++) {
       if (aCellsArray[rowIdx][colIdx] & kSpanned)
         continue;
 
       var isSelected = aCellsArray[rowIdx][colIdx] == true;
       is(acc.isCellSelected(rowIdx, colIdx), isSelected,
          msg + "Wrong selection state of cell at " + rowIdx + " row and " +
          colIdx + " column for " + prettyName(aIdentifier));
 
@@ -477,43 +476,43 @@ function testTableSelection(aIdentifier,
   var actualSelCellsCountObj = { value: null };
   var actualSelCells = acc.getSelectedCellIndices(actualSelCellsCountObj);
 
   var actualSelCellsCount = actualSelCellsCountObj.value;
   is(actualSelCellsCount, selCells.length,
      msg + "Wrong count of selected cells for " + prettyName(aIdentifier) +
      "from getSelectedCells.");
 
-  for (var i = 0; i < actualSelCellsCount; i++) {
+  for (let i = 0; i < actualSelCellsCount; i++) {
     is(actualSelCells[i], selCells[i],
        msg + "getSelectedCellIndices: Cell at index " + selCells[i] +
        " should be selected.");
   }
 
   // selectedCells and isSelected tests
   var actualSelCellsArray = acc.selectedCells;
-  for (var i = 0; i < actualSelCellsCount; i++) {
+  for (let i = 0; i < actualSelCellsCount; i++) {
     var actualSelCellAccessible =
       actualSelCellsArray.queryElementAt(i, nsIAccessibleTableCell);
 
-    var colIdx = acc.getColumnIndexAt(selCells[i]);
-    var rowIdx = acc.getRowIndexAt(selCells[i]);
+    let colIdx = acc.getColumnIndexAt(selCells[i]);
+    let rowIdx = acc.getRowIndexAt(selCells[i]);
     var expectedSelCellAccessible = acc.getCellAt(rowIdx, colIdx);
 
     ok(actualSelCellAccessible, expectedSelCellAccessible,
        msg + "getSelectedCells: Cell at index " + selCells[i] +
        " should be selected.");
 
     ok(actualSelCellAccessible.isSelected(),
        "isSelected: Cell at index " + selCells[i] + " should be selected.");
   }
 
   // selected states tests
-  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
-    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
+  for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    for (let colIdx = 0; colIdx < colsCount; colIdx++) {
       if (aCellsArray[rowIdx][colIdx] & kSpanned)
         continue;
 
       var cell = acc.getCellAt(rowIdx, colIdx);
       var isSel = aCellsArray[rowIdx][colIdx];
       if (isSel == undefined)
         testStates(cell, 0, 0, STATE_SELECTABLE | STATE_SELECTED);
       else if (isSel == true)
@@ -695,17 +694,17 @@ function testHeaderCells(aHeaderInfoMap)
     var actualRowHeaderCells = dataCell.rowHeaderCells;
     var actualRowHeaderCellsCount = actualRowHeaderCells.length;
 
     is(actualRowHeaderCellsCount, rowHeaderCellsCount,
        "Wrong number of row header cells for the cell " +
        prettyName(dataCellIdentifier));
 
     if (actualRowHeaderCellsCount == rowHeaderCellsCount) {
-      for (var idx = 0; idx < rowHeaderCellsCount; idx++) {
+      for (let idx = 0