Merge draft head draft
authorGregory Szorc <gps@mozilla.com>
Fri, 04 Aug 2017 15:25:56 -0700
changeset 636119 876386e591500e75dc42b297451cc13d7daf93bc
parent 636118 9cd192edd60886daac877193ac1000acae95038e (diff)
parent 604191 7c8a6b4610ce15a2556e6cd39c73857cf06aa679 (current diff)
child 636120 38bdd57c8552e8a72eaa0db62b0f45ec41e04638
push id72398
push usergszorc@mozilla.com
push dateFri, 04 Aug 2017 23:14:39 +0000
milestone57.0a1
Merge draft head
--- a/.clang-format-ignore
+++ b/.clang-format-ignore
@@ -19,17 +19,17 @@
 ^gfx/cairo/.*
 ^gfx/graphite2/.*
 ^gfx/harfbuzz/.*
 ^gfx/ots/.*
 ^gfx/qcms/.*
 ^gfx/skia/.*
 ^gfx/vr/openvr/.*
 ^gfx/webrender.*
-^gfx/webrender_traits.*
+^gfx/webrender_api.*
 ^gfx/ycbcr/.*
 ^intl/hyphenation/hyphen/.*
 ^intl/icu/.*
 ^ipc/chromium/.*
 ^js/src/ctypes/libffi/.*
 ^js/src/dtoa.c.*
 ^js/src/jit/arm64/vixl/.*
 ^media/ffvpx/.*
--- a/.cron.yml
+++ b/.cron.yml
@@ -2,72 +2,86 @@
 # `taskcluster/taskgraph/cron/schema.py`.  For documentation, see
 # `taskcluster/docs/cron.rst`.
 
 jobs:
     - name: nightly-desktop
       job:
           type: decision-task
           treeherder-symbol: Nd
-          target-tasks-method: nightly_linux
-      run-on-projects:
-          - mozilla-central
-          - mozilla-aurora
-          - date
-      when:
-          by-project:
-            # Match buildbot starts for now
-            date: [{hour: 15, minute: 0}]
-            mozilla-central: [{hour: 10, minute: 0}]
-            mozilla-aurora: [] # bug 1358976
-            # No default
-
-    - name: nightly-desktop-osx
-      job:
-          type: decision-task
-          treeherder-symbol: Nd-OSX
-          target-tasks-method: nightly_macosx
+          target-tasks-method: nightly_desktop
       run-on-projects:
           - mozilla-central
           - date
       when:
           by-project:
             # Match buildbot starts for now
             date: [{hour: 15, minute: 0}]
             mozilla-central: [{hour: 10, minute: 0}]
             # No default
 
-    - name: nightly-desktop-win64
+    - name: nightly-desktop-linux
+      job:
+          type: decision-task
+          treeherder-symbol: Nd-Ln
+          target-tasks-method: nightly_linux
+      run-on-projects:
+          - mozilla-central
+          - date
+      when: [] # never (hook only)
+
+    - name: nightly-desktop-osx
       job:
           type: decision-task
-          treeherder-symbol: Nd-Win64
-          target-tasks-method: nightly_win64
+          treeherder-symbol: Nd-OSX
+          target-tasks-method: nightly_macosx
       run-on-projects:
+          - mozilla-central
+          - date
+      when: [] # never (hook only)
+
+    - name: nightly-desktop-win
+      job:
+          type: decision-task
+          treeherder-symbol: Nd-Win
+          target-tasks-method: nightly_win
+      run-on-projects:
+          - mozilla-central
           - date
       when: [] # never (hook only)
 
     - name: nightly-android
       job:
           type: decision-task
           treeherder-symbol: Na
           target-tasks-method: nightly_fennec
       run-on-projects:
           - mozilla-central
-          - mozilla-aurora
           - date
       when:
         by-project:
             # Match buildbot starts for now
             date: [{hour: 15, minute: 0}]
             mozilla-central: [{hour: 10, minute: 0}]
-            mozilla-aurora: [] # bug 1358976
             # No default
 
     - name: nightly-mochitest-valgrind
       job:
           type: decision-task
           treeherder-symbol: Vg
           target-tasks-method: mochitest_valgrind
       run-on-projects:
           - mozilla-central
       when:
           - {hour: 16, minute: 0}
           - {hour: 4, minute: 0}
+
+    - name: nightly-dmd
+      job:
+          type: decision-task
+          treeherder-symbol: Ndmd
+          target-tasks-method: nightly_dmd
+      run-on-projects:
+          - mozilla-central
+      when:
+          by-project:
+            mozilla-central: [{hour: 10, minute: 0}]
+            # No default
--- a/.eslintignore
+++ b/.eslintignore
@@ -3,87 +3,88 @@
 
 # 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.
 addon-sdk/**
-build/**
 chrome/**
 config/**
-db/**
 docshell/**
 editor/**
 embedding/**
-extensions/**
+extensions/cookie/**
+extensions/spellcheck/**
+extensions/universalchardet/**
 gfx/**
-gradle/**
-hal/**
 image/**
 intl/**
 ipc/**
 layout/**
 media/**
 memory/**
-mfbt/**
 modules/**
-mozglue/**
 netwerk/**
-nsprpub/**
-other-licenses/**
 parser/**
-probes/**
 python/**
 rdf/**
 servo/**
-startupcache/**
 tools/update-packaging/**
 uriloader/**
 view/**
 widget/**
 xpcom/**
+
+# We currently have no js files in these directories, so we ignore them by
+# default to aid ESLint's performance.
+build/**
+db/**
+gradle/**
+hal/**
+mfbt/**
+mozglue/**
+nsprpub/**
+other-licenses/**
+probes/**
+startupcache/**
 xpfe/**
-xulrunner/**
-
-# b2g exclusions (pref files).
-b2g/app/b2g.js
-b2g/graphene/graphene.js
-b2g/locales/en-US/b2g-l10n.js
 
 # browser/ exclusions
 browser/app/**
 browser/branding/**/firefox-branding.js
-browser/base/content/test/general/file_csp_block_all_mixedcontent.html
 # Gzipped test file.
 browser/base/content/test/general/gZipOfflineChild.html
 browser/base/content/test/urlbar/file_blank_but_not_blank.html
+# New tab is likely to be replaced soon.
 browser/base/content/newtab/**
 # Test files that are really json not js, and don't need to be linted.
 browser/components/sessionstore/test/unit/data/sessionstore_valid.js
 browser/components/sessionstore/test/unit/data/sessionstore_invalid.js
-browser/components/tabview/**
 # generated & special files in cld2
 browser/components/translation/cld2/**
 # Screenshots and Follow-on search are imported as a system add-on and have
 # their own lint rules currently.
 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/**
-browser/locales/**
 # generated or library files in activity-stream
 browser/extensions/activity-stream/data/content/activity-stream.bundle.js
 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
 
 # devtools/ exclusions
 devtools/client/canvasdebugger/**
 devtools/client/commandline/**
 devtools/client/debugger/**
 devtools/client/framework/**
 !devtools/client/framework/devtools.js
 !devtools/client/framework/devtools-browser.js
@@ -132,21 +133,19 @@ devtools/server/tests/browser/storage-*.
 !devtools/server/tests/browser/storage-unsecured-iframe.html
 devtools/server/tests/browser/stylesheets-nested-iframes.html
 devtools/server/tests/unit/xpcshell_debugging_script.js
 devtools/shared/platform/content/test/test_clipboard.html
 devtools/shared/qrcode/tests/mochitest/test_decode.html
 devtools/shared/tests/mochitest/*.html
 devtools/shared/webconsole/test/test_*.html
 
-# Ignore devtools pre-processed files
-devtools/client/framework/toolbox-process-window.js
-devtools/client/performance/system.js
-devtools/client/webide/webide-prefs.js
+# Ignore devtools preferences files
 devtools/client/preferences/**
+devtools/shim/devtools-startup-prefs.js
 
 # Ignore devtools third-party libs
 devtools/shared/jsbeautify/*
 devtools/shared/acorn/*
 devtools/shared/gcli/source/*
 devtools/shared/node-properties/*
 devtools/shared/pretty-fast/*
 devtools/shared/sourcemap/*
@@ -266,62 +265,60 @@ js/src/octane/**
 js/src/jit-test/**
 js/src/tests/**
 js/src/Y.js
 
 # mobile/android/ exclusions
 mobile/android/tests/browser/chrome/tp5/**
 
 # Uses `#filter substitution`
-mobile/android/b2gdroid/app/b2gdroid.js
 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/
 
 # Non-standard `(catch ex if ...)`
 mobile/android/chrome/content/browser.js
 mobile/android/components/Snippets.js
 
-# Bug 1178739: Ignore this file as a quick fix for "Illegal yield expression"
-mobile/android/modules/HomeProvider.jsm
-
 # security/ exclusions (pref files).
 security/manager/ssl/security-prefs.js
 
-#NSS
+# NSS / taskcluster only.
 security/nss/**
 
 # services/ exclusions
 
 # Uses `#filter substitution`
 services/sync/modules/constants.js
 services/sync/services-sync.js
 
 # Remote protocol exclusions
 testing/marionette/test_*.js
 testing/marionette/atom.js
 testing/marionette/legacyaction.js
-testing/marionette/client/**
-testing/marionette/harness/**
+testing/marionette/client
+testing/marionette/doc
+testing/marionette/harness
 
 # other testing/ exclusions
 testing/mochitest/**
 # third party modules
 testing/modules/ajv-4.1.1.js
 testing/modules/sinon-2.3.2.js
 # octothorpe used for pref file comment causes parsing error
 testing/mozbase/mozprofile/tests/files/prefs_with_comments.js
 testing/talos/talos/scripts/jszip.min.js
 testing/talos/talos/startup_test/sessionrestore/profile/sessionstore.js
+testing/talos/talos/startup_test/sessionrestore/profile-manywindows/sessionstore.js
 testing/talos/talos/tests/canvasmark/**
 testing/talos/talos/tests/dromaeo/**
 testing/talos/talos/tests/v8_7/**
 testing/talos/talos/tests/kraken/**
 
 testing/web-platform/**
 testing/xpcshell/moz-http2/**
 testing/xpcshell/node-http2/**
@@ -338,30 +335,28 @@ toolkit/components/help/**
 
 # Intentionally invalid JS
 toolkit/components/workerloader/tests/moduleF-syntax-error.js
 
 # Tests old non-star function generators
 toolkit/modules/tests/xpcshell/test_task.js
 
 # Not yet updated
-toolkit/components/osfile/**
+toolkit/components/url-classifier/**
 
 # External code:
 toolkit/components/microformats/test/**
 toolkit/components/microformats/microformat-shiv.js
 toolkit/components/reader/Readability.js
 toolkit/components/reader/JSDOMParser.js
 
 # Uses preprocessing
 toolkit/content/widgets/wizard.xml
 toolkit/components/jsdownloads/src/DownloadIntegration.jsm
-toolkit/components/url-classifier/**
+toolkit/components/osfile/osfile.jsm
 toolkit/components/urlformatter/nsURLFormatter.js
 toolkit/modules/AppConstants.jsm
 toolkit/mozapps/downloads/nsHelperAppDlg.js
-toolkit/mozapps/extensions/internal/AddonConstants.jsm
 toolkit/mozapps/update/tests/data/xpcshellConstantsPP.js
-toolkit/webapps/**
 
 # Third party
 toolkit/modules/third_party/**
 third_party/**
--- a/.gitignore
+++ b/.gitignore
@@ -57,16 +57,18 @@ parser/html/java/javaparser/
 # Ignore the files and directory that Eclipse IDE creates
 .project
 .cproject
 .settings/
 
 # Ignore the files and directory that JetBrains IDEs create.
 /.idea/
 *.iml
+# Android Monitor in Android Studio creates a captures/ directory.
+/captures/
 
 # Gradle cache.
 /.gradle/
 
 # Local Gradle configuration properties.
 /local.properties
 
 # Python virtualenv artifacts.
--- a/.hgignore
+++ b/.hgignore
@@ -59,16 +59,18 @@
 # Ignore the files and directory that Eclipse IDE creates
 \.project$
 \.cproject$
 \.settings/
 
 # Ignore the files and directory that JetBrains IDEs create.
 \.idea/
 \.iml$
+# Android Monitor in Android Studio creates a captures/ directory.
+^captures/
 
 # Gradle cache.
 ^.gradle/
 
 # Local Gradle configuration properties.
 ^local.properties$
 
 # Python stuff installed at build time.
@@ -115,16 +117,17 @@ GPATH
 ^testing/mozharness/.coverage
 ^testing/mozharness/nosetests.xml
 
 # Ignore tox generated dir
 .tox/
 
 # Ignore ESLint node_modules
 ^node_modules/
+^tools/lint/eslint/eslint-plugin-mozilla/node_modules/
 
 # Ignore talos virtualenv and tp5n files.
 # The tp5n set is supposed to be decompressed at
 # testing/talos/talos/tests/tp5n in order to run tests like tps
 # locally. Similarly, running talos requires a Python package virtual
 # environment. Both the virtual environment and tp5n files end up littering
 # the status command, so we ignore them.
 ^testing/talos/.Python
--- a/.hgtags
+++ b/.hgtags
@@ -128,8 +128,9 @@ 68d3781deda0d4d58ec9877862830db89669b3a5
 1c6385ae1fe7e37d8f23f958ce14582f07af729e FIREFOX_AURORA_48_BASE
 d98f20c25feeac4dd7ebbd1c022957df1ef58af4 FIREFOX_AURORA_49_BASE
 465d150bc8be5bbf9f02a8607d4552b6a5e1697c FIREFOX_AURORA_50_BASE
 fc69febcbf6c0dcc4b3dfc7a346d8d348798a65f FIREFOX_AURORA_51_BASE
 1196bf3032e1bce1fb07a01fd9082a767426c5fb FIREFOX_AURORA_52_BASE
 f80dc9fc34680105b714a49b4704bb843f5f7004 FIREFOX_AURORA_53_BASE
 6583496f169cd8a13c531ed16e98e8bf313eda8e FIREFOX_AURORA_54_BASE
 f9605772a0c9098ed1bcaa98089b2c944ed69e9b FIREFOX_BETA_55_BASE
+320642944e42a889db13c6c55b404e32319d4de6 FIREFOX_BETA_56_BASE
--- a/.taskcluster.yml
+++ b/.taskcluster.yml
@@ -1,127 +1,134 @@
----
-version: 0
-metadata:
-  name: 'Taskcluster tasks for Gecko'
-  description: "The taskcluster task graph for Gecko trees"
-  owner: mozilla-taskcluster-maintenance@mozilla.com
-  source: {{{source}}}
+# This file is rendered via JSON-e by
+# - mozilla-taskcluster - https://docs.taskcluster.net/reference/integrations/mozilla-taskcluster/docs/taskcluster-yml
+# - cron tasks - taskcluster/taskgraph/cron/decision.py
+version: 1
+tasks:
+  $let:
+    # sometimes the push user is just `ffxbld` or the like, but we want an email-like field..
+    ownerEmail: {$if: '"@" in push.owner', then: '${push.owner}', else: '${push.owner}@noreply.mozilla.org'}
+    # ensure there's no trailing `/` on the repo URL
+    repoUrl: {$if: 'repository.url[-1] == "/"', then: {$eval: 'repository.url[:-1]'}, else: {$eval: 'repository.url'}}
+  in:
+  - taskId: '${as_slugid("decision")}'
+    taskGroupId: '${as_slugid("decision")}' # same as tsakId; this is how automation identifies a decision tsak
+    schedulerId: 'gecko-level-${repository.level}'
 
-scopes:
-  # Note the below scopes are insecure however these get overriden on the server
-  # side to whatever scopes are set by mozilla-taskcluster.
-  - queue:*
-  - docker-worker:*
-  - scheduler:*
+    created: {$fromNow: ''}
+    deadline: {$fromNow: '1 day'}
+    expires: {$fromNow: '1 year 1 second'} # 1 second so artifacts expire first, despite rounding errors
+    metadata:
+      $merge:
+        - owner: "${ownerEmail}"
+          source: "${repoUrl}/raw-file/${push.revision}/.taskcluster.yml"
+        - $if: 'tasks_for == "hg-push"'
+          then:
+            name: "Gecko Decision Task"
+            description: 'The task that creates all of the other tasks in the task graph'
+          else:
+            name: "Decision Task for cron job ${cron.job_name}"
+            description: 'Created by a [cron task](https://tools.taskcluster.net/tasks/${cron.task_id})'
 
-# This file undergoes substitution to create tasks.  For on-push tasks, that
-# substitution is done by mozilla-taskcluster.  For cron tasks, that substitution
-# is done by `taskcluster/taskgraph/cron/decision.py`.  If you change any of the
-# template parameters, please do so in all three places!
-#
-# Available template parameters:
-#
-# - now:            current time
-# - owner:          push user (email address)
-# - source:         URL of this YAML file
-# - url:            repository URL
-# - project:        alias for the destination repository (basename of
-#                   the repo url)
-# - level:          SCM level of the destination repository
-#                   (1 = try, 3 = core)
-# - revision:       hg revision of the head of the push
-# - comment:        comment of the push
-# - pushlog_id:     id in the pushlog table of the repository
-#
-# and functions:
-# - as_slugid:      convert a label into a slugId
-# - from_now:       generate a timestamp at a fixed offset from now
-# - shellquote:     quote the contents for injection into shell
+    provisionerId: "aws-provisioner-v1"
+    workerType: "gecko-decision"
+
+    tags:
+      $if: 'tasks_for == "hg-push"'
+      then: {createdForUser: "${ownerEmail}"}
 
-# The resulting tasks' taskGroupId will be equal to the taskId of the first
-# task listed here, which should be the decision task.  This gives other tools
-# an easy way to determine the ID of the decision task that created a
-# particular group.
+    routes:
+      $if: 'tasks_for == "hg-push"'
+      then:
+        - "index.gecko.v2.${repository.project}.latest.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:
+        - "index.gecko.v2.${repository.project}.latest.firefox.decision-${cron.job_name}"
+        - "tc-treeherder.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
+        - "tc-treeherder-stage.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
 
-tasks:
-  - taskId: '{{#as_slugid}}decision task{{/as_slugid}}'
-    task:
-      created: '{{now}}'
-      deadline: '{{#from_now}}1 day{{/from_now}}'
-      expires: '{{#from_now}}365 day{{/from_now}}'
-      metadata:
-        owner: mozilla-taskcluster-maintenance@mozilla.com
-        source: {{{source}}}
-        name: "Gecko Decision Task"
-        description: |
-            The task that creates all of the other tasks in the task graph
+    scopes:
+      $if: 'tasks_for == "hg-push"'
+      then:
+        - 'assume:repo:${repoUrl[8:]}:*'
+        - 'queue:route:notify.email.${ownerEmail}.*'
+      else:
+        - 'assume:repo:${repoUrl[8:]}:cron:${cron.job_name}'
 
-      workerType: "gecko-decision"
-      provisionerId: "aws-provisioner-v1"
+    dependencies: []
+    requires: all-completed
 
-      tags:
-        createdForUser: {{owner}}
+    priority: lowest
+    retries: 5
 
-      routes:
-        - "index.gecko.v2.{{project}}.latest.firefox.decision"
-        - "tc-treeherder.v2.{{project}}.{{revision}}.{{pushlog_id}}"
-        - "tc-treeherder-stage.v2.{{project}}.{{revision}}.{{pushlog_id}}"
-        - "notify.email.{{owner}}.on-failed"
-        - "notify.email.{{owner}}.on-exception"
+    payload:
+      env:
+        # checkout-gecko uses these to check out the source; the inputs
+        # to `mach taskgraph decision` are all on the command line.
+        GECKO_BASE_REPOSITORY: 'https://hg.mozilla.org/mozilla-unified'
+        GECKO_HEAD_REPOSITORY: '${repoUrl}'
+        GECKO_HEAD_REF: '${push.revision}'
+        GECKO_HEAD_REV: '${push.revision}'
+        GECKO_COMMIT_MSG: '${push.comment}'
+        HG_STORE_PATH: /home/worker/checkouts/hg-store
 
-      payload:
-        env:
-          # checkout-gecko uses these to check out the source; the inputs
-          # to `mach taskgraph decision` are all on the command line.
-          GECKO_BASE_REPOSITORY: 'https://hg.mozilla.org/mozilla-unified'
-          GECKO_HEAD_REPOSITORY: '{{{url}}}'
-          GECKO_HEAD_REF: '{{revision}}'
-          GECKO_HEAD_REV: '{{revision}}'
-          HG_STORE_PATH: /home/worker/checkouts/hg-store
+      cache:
+        level-${repository.level}-checkouts: /home/worker/checkouts
+
+      features:
+        taskclusterProxy: true
+        chainOfTrust: true
 
-        cache:
-          level-{{level}}-checkouts: /home/worker/checkouts
-
-        features:
-          taskclusterProxy: true
-          chainOfTrust: true
+      # Note: This task is built server side without the context or tooling that
+      # exist in tree so we must hard code the hash
+      # XXX Changing this will break Chain of Trust without an associated puppet and
+      # scriptworker patch!
+      image: 'taskcluster/decision:0.1.8@sha256:195d8439c8e90d59311d877bd2a8964849b2e43bfc6c234092618518d8b2891b'
 
-        # Note: This task is built server side without the context or tooling that
-        # exist in tree so we must hard code the hash
-        # XXX Changing this will break Chain of Trust without an associated puppet and
-        # scriptworker patch!
-        image: 'taskcluster/decision:0.1.8@sha256:195d8439c8e90d59311d877bd2a8964849b2e43bfc6c234092618518d8b2891b'
-
-        maxRunTime: 1800
+      maxRunTime: 1800
 
-        # TODO use mozilla-unified for the base repository once the tc-vcs
-        # tar.gz archives are created or tc-vcs isn't being used.
-        command:
-          - /home/worker/bin/run-task
-          - '--vcs-checkout=/home/worker/checkouts/gecko'
-          - '--'
-          - bash
-          - -cx
-          - >
-              cd /home/worker/checkouts/gecko &&
-              ln -s /home/worker/artifacts artifacts &&
-              ./mach --log-no-times taskgraph decision
-              --pushlog-id='{{pushlog_id}}'
-              --pushdate='{{pushdate}}'
-              --project='{{project}}'
-              --message={{#shellquote}}{{{comment}}}{{/shellquote}}
-              --owner='{{owner}}'
-              --level='{{level}}'
-              --base-repository='https://hg.mozilla.org/mozilla-central'
-              --head-repository='{{{url}}}'
-              --head-ref='{{revision}}'
-              --head-rev='{{revision}}'
+      # TODO use mozilla-unified for the base repository once the tc-vcs
+      # tar.gz archives are created or tc-vcs isn't being used.
+      command:
+        - /home/worker/bin/run-task
+        - '--vcs-checkout=/home/worker/checkouts/gecko'
+        - '--'
+        - bash
+        - -cx
+        - $let:
+            extraArgs: {$if: 'tasks_for == "hg-push"', then: '', else: '${cron.quoted_args}'}
+          # NOTE: the explicit reference to mozilla-central below is required because android-stuff
+          # still uses tc-vcs, which does not support mozilla-unified
+          # https://bugzilla.mozilla.org/show_bug.cgi?id=1383973
+          in: >
+            cd /home/worker/checkouts/gecko &&
+            ln -s /home/worker/artifacts artifacts &&
+            ./mach --log-no-times taskgraph decision
+            --pushlog-id='${push.pushlog_id}'
+            --pushdate='${push.pushdate}'
+            --project='${repository.project}'
+            --message="$GECKO_COMMIT_MSG"
+            --owner='${ownerEmail}'
+            --level='${repository.level}'
+            --base-repository='https://hg.mozilla.org/mozilla-central'
+            --head-repository="$GECKO_HEAD_REPOSITORY"
+            --head-ref="$GECKO_HEAD_REF"
+            --head-rev="$GECKO_HEAD_REV"
+            ${extraArgs}
 
-        artifacts:
-          'public':
-            type: 'directory'
-            path: '/home/worker/artifacts'
-            expires: '{{#from_now}}364 days{{/from_now}}'
+      artifacts:
+        'public':
+          type: 'directory'
+          path: '/home/worker/artifacts'
+          expires: {$fromNow: '1 year'}
 
-      extra:
-        treeherder:
+    extra:
+      treeherder:
+        $if: 'tasks_for == "hg-push"'
+        then:
           symbol: D
+        else:
+          groupSymbol: cron
+          symbol: "${cron.job_symbol}"
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -1,23 +1,36 @@
 {
     // 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"
       },
       {
+        "taskName": "clobber-python",
+        "suppressTaskName": true,
+        "args": ["clobber", "python"]
+      },
+      {
         "taskName": "configure"
       },
       {
         "taskName": "build",
         "isBuildCommand": true,
         "problemMatcher": {
           "owner": "cpp",
           "fileLocation": "absolute",
@@ -27,32 +40,36 @@
             "line": 2,
             "column": 3,
             "severity": 4,
             "message": 5
           }
         }
       },
       {
-        "taskName": "build binaries",
+        "taskName": "build-binaries",
+        "suppressTaskName": true,
+        "args": ["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
           }
         }
       },
       {
-        "taskName": "build faster",
+        "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,
@@ -62,21 +79,27 @@
         }
       },
       {
         "taskName": "run",
         "args": ["-purgecaches"],
         "showOutput": "always"
       },
       {
+        "taskName": "lint-wo",
+        "suppressTaskName": true,
+        "args": ["lint", "-wo"],
+        "problemMatcher": ["$eslint-stylish"]
+      },
+      {
         "taskName": "eslint",
         "problemMatcher": ["$eslint-stylish"]
       },
       {
-        "taskName": "eslint fix",
+        "taskName": "eslint-fix",
         "suppressTaskName": true,
         "args": ["eslint", "--fix", "${file}"],
         "problemMatcher": ["$eslint-stylish"]
       },
       {
         "taskName": "test",
         "args": ["${relativeFile}"],
         "isTestCommand": true,
--- 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 1353650 - Update to ICU 59 requires clobber
+Merge day clobber
\ No newline at end of file
--- a/Makefile.in
+++ b/Makefile.in
@@ -243,16 +243,21 @@ default all::
 include $(topsrcdir)/config/rules.mk
 
 ifdef SCCACHE_VERBOSE_STATS
 default::
 	-$(CCACHE) --show-stats --stats-format=json > sccache-stats.json
 	@echo "===SCCACHE STATS==="
 	-$(CCACHE) --show-stats
 	@echo "==================="
+ifndef MOZ_PROFILE_GENERATE
+# Ideally we'd do that in the same file as we set the sccache.log location for
+# sccache, but it's too late in the build.
+	-gzip -9 $(DIST)/sccache.log
+endif
 endif
 
 distclean::
 	$(RM) $(DIST_GARBAGE)
 
 ifdef MOZ_CRASHREPORTER
 include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
 
@@ -265,26 +270,26 @@ prepsymbolsarchive:
 
 ifndef MOZ_AUTOMATION
 prepsymbolsarchive: recurse_syms
 endif
 
 .PHONY: symbolsfullarchive
 symbolsfullarchive: prepsymbolsarchive
 	$(RM) '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
-	$(call py_action,symbols_archive,$(abspath '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip') \
+	$(call py_action,symbols_archive,'$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip' \
                                      $(abspath $(DIST)/crashreporter-symbols) \
                                      --exclude '*test*' \
                                      --exclude '*Test*' \
                                      --compress '**/*.sym')
 
 .PHONY: symbolsarchive
 symbolsarchive: prepsymbolsarchive
 	$(RM) '$(DIST)/$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip'
-	$(call py_action,symbols_archive,$(abspath '$(DIST)/$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip') \
+	$(call py_action,symbols_archive,'$(DIST)/$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip' \
                                      $(abspath $(DIST)/crashreporter-symbols) \
                                      --include '**/*.sym')
 
 ifdef MOZ_CRASHREPORTER
 buildsymbols: symbolsfullarchive symbolsarchive
 else
 buildsymbols:
 endif
--- a/accessible/.eslintrc.js
+++ b/accessible/.eslintrc.js
@@ -3,26 +3,15 @@
 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.
-    "brace-style": "off",
     "consistent-return": "off",
-    "func-call-spacing": "off",
-    "quotes": "off",
     "object-shorthand": "off",
-    "space-before-function-paren": "off",
-    "space-infix-ops": "off",
-    "key-spacing": "off",
-    "keyword-spacing": "off",
-    "no-else-return": "off",
-    "no-multi-spaces": "off",
-    "no-trailing-spaces": "off",
     "no-unexpected-multiline": "off",
     "no-unsafe-finally": "off",
     "no-useless-call": "off",
-    "spaced-comment": "off",
   }
 };
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -60,17 +60,17 @@ enum MaiInterfaceType {
     MAI_INTERFACE_ACTION,
     MAI_INTERFACE_VALUE,
     MAI_INTERFACE_EDITABLE_TEXT,
     MAI_INTERFACE_HYPERTEXT,
     MAI_INTERFACE_HYPERLINK_IMPL,
     MAI_INTERFACE_SELECTION,
     MAI_INTERFACE_TABLE,
     MAI_INTERFACE_TEXT,
-    MAI_INTERFACE_DOCUMENT, 
+    MAI_INTERFACE_DOCUMENT,
     MAI_INTERFACE_IMAGE, /* 10 */
     MAI_INTERFACE_TABLE_CELL
 };
 
 static GType GetAtkTypeForMai(MaiInterfaceType type)
 {
   switch (type) {
     case MAI_INTERFACE_COMPONENT:
@@ -97,23 +97,23 @@ static GType GetAtkTypeForMai(MaiInterfa
       return ATK_TYPE_IMAGE;
     case MAI_INTERFACE_TABLE_CELL:
       MOZ_ASSERT(false);
   }
   return G_TYPE_INVALID;
 }
 
 #define NON_USER_EVENT ":system"
-    
+
 // The atk interfaces we can expose without checking what version of ATK we are
 // dealing with.  At the moment AtkTableCell is the only interface we can't
 // always expose.
 static const GInterfaceInfo atk_if_infos[] = {
     {(GInterfaceInitFunc)componentInterfaceInitCB,
-     (GInterfaceFinalizeFunc) nullptr, nullptr}, 
+     (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)actionInterfaceInitCB,
      (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)valueInterfaceInitCB,
      (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)editableTextInterfaceInitCB,
      (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)hypertextInterfaceInitCB,
      (GInterfaceFinalizeFunc) nullptr, nullptr},
@@ -323,17 +323,17 @@ AccessibleWrap::GetAtkObject(void)
 
 // Get AtkObject from Accessible interface
 /* static */
 AtkObject *
 AccessibleWrap::GetAtkObject(Accessible* acc)
 {
     void *atkObjPtr = nullptr;
     acc->GetNativeInterface(&atkObjPtr);
-    return atkObjPtr ? ATK_OBJECT(atkObjPtr) : nullptr;    
+    return atkObjPtr ? ATK_OBJECT(atkObjPtr) : nullptr;
 }
 
 /* private */
 uint16_t
 AccessibleWrap::CreateMaiInterfaces(void)
 {
   uint16_t interfacesBits = 0;
 
@@ -367,17 +367,17 @@ AccessibleWrap::CreateMaiInterfaces(void
   // HyperLink interface.
   if (IsLink())
     interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL;
 
   if (!nsAccUtils::MustPrune(this)) {  // These interfaces require children
     // Table interface.
     if (AsTable())
       interfacesBits |= 1 << MAI_INTERFACE_TABLE;
- 
+
     if (AsTableCell())
       interfacesBits |= 1 << MAI_INTERFACE_TABLE_CELL;
 
     // Selection interface.
     if (IsSelect()) {
       interfacesBits |= 1 << MAI_INTERFACE_SELECTION;
     }
   }
--- a/accessible/atk/DocAccessibleWrap.h
+++ b/accessible/atk/DocAccessibleWrap.h
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=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/. */
 
-/* For documentation of the accessibility architecture, 
+/* For documentation of the accessibility architecture,
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 #ifndef mozilla_a11y_DocAccessibleWrap_h__
 #define mozilla_a11y_DocAccessibleWrap_h__
 
 #include "DocAccessible.h"
 
--- a/accessible/atk/TextLeafAccessibleWrap.h
+++ b/accessible/atk/TextLeafAccessibleWrap.h
@@ -6,15 +6,15 @@
 
 #ifndef mozilla_a11y_TextLeafAccessibleWrap_h__
 #define mozilla_a11y_TextLeafAccessibleWrap_h__
 
 #include "TextLeafAccessible.h"
 
 namespace mozilla {
 namespace a11y {
- 
+
 typedef class TextLeafAccessible TextLeafAccessibleWrap;
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/atk/nsMaiInterfaceText.cpp
+++ b/accessible/atk/nsMaiInterfaceText.cpp
@@ -121,17 +121,17 @@ ConvertToAtkTextAttributeSet(nsIPersiste
 
   // libatk-adaptor will free it
   return objAttributeSet;
 }
 
 static void
 ConvertTexttoAsterisks(AccessibleWrap* accWrap, nsAString& aString)
 {
-  // convert each char to "*" when it's "password text" 
+  // convert each char to "*" when it's "password text"
   if (accWrap->NativeRole() == roles::PASSWORD_TEXT) {
     for (uint32_t i = 0; i < aString.Length(); i++)
       aString.Replace(i, 1, NS_LITERAL_STRING("*"));
   }
 }
 
 extern "C" {
 
--- a/accessible/atk/nsStateMap.h
+++ b/accessible/atk/nsStateMap.h
@@ -26,17 +26,17 @@ The following accessible states aren't t
   STATE_PINNED:          The object is pinned, usually indicating it is fixed in
                          place and has permanence. No ATK equivalent. The
                          accessible state is not currently supported.
 
 The following ATK states are not supported:
   ATK_STATE_ARMED:       No clear use case, used briefly when button is activated
   ATK_STATE_HAS_TOOLTIP: No clear use case, no IA2 equivalent
   ATK_STATE_ICONIFIED:   Mozilla does not have elements which are collapsable into icons
-  ATK_STATE_TRUNCATED:   No clear use case. Indicates that an object's onscreen content is truncated, 
+  ATK_STATE_TRUNCATED:   No clear use case. Indicates that an object's onscreen content is truncated,
                          e.g. a text value in a spreadsheet cell. No IA2 state.
 ******************************************************************************/
 
 enum EStateMapEntryType {
   kMapDirectly,
   kMapOpposite,   // For example, UNAVAILABLE is the opposite of ENABLED
   kNoStateChange, // Don't fire state change event
   kNoSuchState
@@ -105,10 +105,11 @@ static const AtkStateMap gAtkStateMap[] 
   { ATK_STATE_SINGLE_LINE,                    kMapDirectly },   // states::SINGLE_LINE             = 1 << 40
   { ATK_STATE_TRANSIENT,                      kMapDirectly },   // states::TRANSIENT               = 1 << 41
   { ATK_STATE_VERTICAL,                       kMapDirectly },   // states::VERTICAL                = 1 << 42
   { ATK_STATE_STALE,                          kMapDirectly },   // states::STALE                   = 1 << 43
   { ATK_STATE_ENABLED,                        kMapDirectly },   // states::ENABLED                 = 1 << 44
   { ATK_STATE_SENSITIVE,                      kMapDirectly },   // states::SENSITIVE               = 1 << 45
   { ATK_STATE_EXPANDABLE,                     kMapDirectly },   // states::EXPANDABLE              = 1 << 46
   { kNone,                                    kMapDirectly },   // states::PINNED                  = 1 << 47
-  { kNone,                                    kNoSuchState },   //                                 = 1 << 48
+  { ATK_STATE_ACTIVE,                         kMapDirectly },   // states::CURRENT                 = 1 << 48
+  { kNone,                                    kNoSuchState },   //                                 = 1 << 49
 };
--- a/accessible/base/ARIAMap.cpp
+++ b/accessible/base/ARIAMap.cpp
@@ -128,24 +128,24 @@ static const nsRoleMapEntry sWAIRoleMaps
     eNoValue,
     eSortAction,
     eNoLiveAttr,
     eTableCell,
     kNoReqStates,
     eARIASelectableIfDefined,
     eARIAReadonlyOrEditableIfDefined
   },
-  { // combobox
+  { // combobox, which consists of text input and popup
     &nsGkAtoms::combobox,
-    roles::COMBOBOX,
+    roles::EDITCOMBOBOX,
     kUseMapRole,
     eNoValue,
     eOpenCloseAction,
     eNoLiveAttr,
-    kGenericAccType,
+    eCombobox,
     states::COLLAPSED | states::HASPOPUP,
     eARIAAutoComplete,
     eARIAReadonly,
     eARIAOrientation
   },
   { // complementary
     &nsGkAtoms::complementary,
     roles::NOTHING,
@@ -592,16 +592,26 @@ static const nsRoleMapEntry sWAIRoleMaps
     roles::GROUPING,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     kGenericAccType,
     kNoReqStates
   },
+  { // figure
+    &nsGkAtoms::figure,
+    roles::FIGURE,
+    kUseMapRole,
+    eNoValue,
+    eNoAction,
+    eNoLiveAttr,
+    kGenericAccType,
+    kNoReqStates
+  },
   { // form
     &nsGkAtoms::form,
     roles::FORM,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eLandmark,
@@ -897,22 +907,22 @@ static const nsRoleMapEntry sWAIRoleMaps
     eNoLiveAttr,
     kGenericAccType,
     kNoReqStates,
     eARIAOrientation,
     eARIAReadonly
   },
   { // region
     &nsGkAtoms::region,
-    roles::PANE,
+    roles::REGION,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
-    kGenericAccType,
+    eLandmark,
     kNoReqStates
   },
   { // row
     &nsGkAtoms::row,
     roles::ROW,
     kUseMapRole,
     eNoValue,
     eNoAction,
@@ -977,17 +987,17 @@ static const nsRoleMapEntry sWAIRoleMaps
     eARIAAutoComplete,
     eARIAMultiline,
     eARIAReadonlyOrEditable
   },
   { // separator
     &nsGkAtoms::separator_,
     roles::SEPARATOR,
     kUseMapRole,
-    eNoValue,
+    eHasValueMinMaxIfFocusable,
     eNoAction,
     eNoLiveAttr,
     kGenericAccType,
     states::HORIZONTAL,
     eARIAOrientation
   },
   { // slider
     &nsGkAtoms::slider,
@@ -1197,16 +1207,17 @@ nsRoleMapEntry aria::gEmptyRoleMap = {
 
 /**
  * Universal (Global) states:
  * The following state rules are applied to any accessible element,
  * whether there is an ARIA role or not:
  */
 static const EStateRule sWAIUnivStateMap[] = {
   eARIABusy,
+  eARIACurrent,
   eARIADisabled,
   eARIAExpanded,  // Currently under spec review but precedent exists
   eARIAHasPopup,  // Note this is technically a "property"
   eARIAInvalid,
   eARIAModal,
   eARIARequired,  // XXX not global, Bug 553117
   eARIANone
 };
--- a/accessible/base/ARIAMap.h
+++ b/accessible/base/ARIAMap.h
@@ -29,17 +29,25 @@ enum EValueRule
    * Value interface isn't exposed.
    */
   eNoValue,
 
   /**
    * Value interface is implemented, supports value, min and max from
    * aria-valuenow, aria-valuemin and aria-valuemax.
    */
-  eHasValueMinMax
+  eHasValueMinMax,
+
+  /**
+   * Value interface is implemented, but only if the element is focusable.
+   * For instance, in ARIA 1.1 the ability for authors to create adjustable
+   * splitters was provided by supporting the value interface on separators
+   * that are focusable. Non-focusable separators expose no value information.
+   */
+  eHasValueMinMaxIfFocusable
 };
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Action constants
 
 /**
  * Used to define if the role requires to expose action.
--- a/accessible/base/ARIAStateMap.cpp
+++ b/accessible/base/ARIAStateMap.cpp
@@ -140,16 +140,26 @@ aria::MapToState(EStateRule aRule, dom::
       static const TokenTypeData data(
         nsGkAtoms::aria_checked, eMixedType,
         states::CHECKABLE, states::CHECKED);
 
       MapTokenType(aElement, aState, data);
       return true;
     }
 
+    case eARIACurrent:
+    {
+      static const TokenTypeData data(
+        nsGkAtoms::aria_current, eBoolType,
+        0, states::CURRENT);
+
+      MapTokenType(aElement, aState, data);
+      return true;
+    }
+
     case eARIADisabled:
     {
       static const TokenTypeData data(
         nsGkAtoms::aria_disabled, eBoolType,
         0, states::UNAVAILABLE);
 
       MapTokenType(aElement, aState, data);
       return true;
@@ -349,20 +359,22 @@ MapEnumType(dom::Element* aElement, uint
   }
 }
 
 static void
 MapTokenType(dom::Element* aElement, uint64_t* aState,
              const TokenTypeData& aData)
 {
   if (nsAccUtils::HasDefinedARIAToken(aElement, aData.mAttrName)) {
-    if ((aData.mType & eMixedType) &&
-        aElement->AttrValueIs(kNameSpaceID_None, aData.mAttrName,
+    if (aElement->AttrValueIs(kNameSpaceID_None, aData.mAttrName,
                               nsGkAtoms::mixed, eCaseMatters)) {
-      *aState |= aData.mPermanentState | states::MIXED;
+      if (aData.mType & eMixedType)
+        *aState |= aData.mPermanentState | states::MIXED;
+      else // unsupported use of 'mixed' is an authoring error
+        *aState |= aData.mPermanentState | aData.mFalseState;
       return;
     }
 
     if (aElement->AttrValueIs(kNameSpaceID_None, aData.mAttrName,
                               nsGkAtoms::_false, eCaseMatters)) {
       *aState |= aData.mPermanentState | aData.mFalseState;
       return;
     }
--- a/accessible/base/ARIAStateMap.h
+++ b/accessible/base/ARIAStateMap.h
@@ -24,16 +24,17 @@ namespace aria {
 enum EStateRule
 {
   eARIANone,
   eARIAAutoComplete,
   eARIABusy,
   eARIACheckableBool,
   eARIACheckableMixed,
   eARIACheckedMixed,
+  eARIACurrent,
   eARIADisabled,
   eARIAExpanded,
   eARIAHasPopup,
   eARIAInvalid,
   eARIAModal,
   eARIAMultiline,
   eARIAMultiSelectable,
   eARIAOrientation,
--- a/accessible/base/FocusManager.cpp
+++ b/accessible/base/FocusManager.cpp
@@ -31,17 +31,17 @@ FocusManager::~FocusManager()
 Accessible*
 FocusManager::FocusedAccessible() const
 {
   if (mActiveItem)
     return mActiveItem;
 
   nsINode* focusedNode = FocusedDOMNode();
   if (focusedNode) {
-    DocAccessible* doc = 
+    DocAccessible* doc =
       GetAccService()->GetDocAccessible(focusedNode->OwnerDoc());
     return doc ? doc->GetAccessibleEvenIfNotInMapOrContainer(focusedNode) : nullptr;
   }
 
   return nullptr;
 }
 
 bool
@@ -54,17 +54,17 @@ FocusManager::IsFocused(const Accessible
   if (focusedNode) {
     // XXX: Before getting an accessible for node having a DOM focus make sure
     // they belong to the same document because it can trigger unwanted document
     // accessible creation for temporary about:blank document. Without this
     // peculiarity we would end up with plain implementation based on
     // FocusedAccessible() method call. Make sure this issue is fixed in
     // bug 638465.
     if (focusedNode->OwnerDoc() == aAccessible->GetNode()->OwnerDoc()) {
-      DocAccessible* doc = 
+      DocAccessible* doc =
         GetAccService()->GetDocAccessible(focusedNode->OwnerDoc());
       return aAccessible ==
         (doc ? doc->GetAccessibleEvenIfNotInMapOrContainer(focusedNode) : nullptr);
     }
   }
   return false;
 }
 
--- a/accessible/base/Role.h
+++ b/accessible/base/Role.h
@@ -125,17 +125,17 @@ enum Role {
   PANE = 16,
 
   /**
    * Represents a graphical image used to represent data.
    */
   CHART = 17,
 
   /**
-   * Represents a dialog box or message box. It is used for xul:dialog, 
+   * Represents a dialog box or message box. It is used for xul:dialog,
    * role="dialog".
    */
   DIALOG = 18,
 
   /**
    * Represents a window border.
    */
   BORDER = 19,
@@ -290,30 +290,30 @@ enum Role {
    */
   PUSHBUTTON = 43,
 
   /**
    * Represents a check box control. It is used for xul:checkbox,
    * html:input@type="checkbox", role="checkbox".
    */
   CHECKBUTTON = 44,
-  
+
   /**
    * Represents an option button, also called a radio button. It is one of a
    * group of mutually exclusive options. All objects sharing a single parent
    * that have this attribute are assumed to be part of single mutually
    * exclusive group. It is used for xul:radio, html:input@type="radio",
    * role="radio".
    */
   RADIOBUTTON = 45,
-  
+
   /**
-   * Represents a combo box; an edit control with an associated list box that
-   * provides a set of predefined choices. It is used for html:select,
-   * xul:menulist, role="combobox".
+   * Represents a combo box; a popup button with an associated list box that
+   * provides a set of predefined choices. It is used for html:select with a
+   * size of 1 and xul:menulist. See also ROLE_EDITCOMBOBOX.
    */
   COMBOBOX = 46,
 
   /**
    * Represents the calendar control.
    */
   DROPLIST = 47,
 
@@ -348,17 +348,17 @@ enum Role {
    * with the spin box. It is used for xul:spinbuttons.
    */
   SPINBUTTON = 52,
 
   /**
    * Represents a graphical image used to diagram data. It is used for svg:svg.
    */
   DIAGRAM = 53,
-  
+
   /**
    * Represents an animation control, which contains content that changes over
    * time, such as a control that displays a series of bitmap frames.
    */
   ANIMATION = 54,
 
   /**
    * Represents a mathematical equation. It is used by MATHML, where there is a
@@ -1002,17 +1002,31 @@ enum Role {
 
   /**
    * A complete or self-contained composition in a document, page, application,
    * or site and that is, in principle, independently distributable or reusable,
    * e.g. in syndication.
    */
   ARTICLE = 172,
 
-  LAST_ROLE = ARTICLE
+  /**
+   * A perceivable section containing content that is relevant to a specific,
+   * author-specified purpose and sufficiently important that users will likely
+   * want to be able to navigate to the section easily and to have it listed in
+   * a summary of the page.
+   */
+  REGION = 173,
+
+  /**
+   * Represents a control with a text input and a popup with a set of predefined
+   * choices. It is used for ARIA's combobox role. See also COMBOBOX.
+   */
+  EDITCOMBOBOX = 174,
+
+  LAST_ROLE = EDITCOMBOBOX
 };
 
 } // namespace role
 
 typedef enum mozilla::a11y::roles::Role role;
 
 } // namespace a11y
 } // namespace mozilla
--- a/accessible/base/RoleMap.h
+++ b/accessible/base/RoleMap.h
@@ -379,16 +379,17 @@ ROLE(CHECKBUTTON,
 ROLE(RADIOBUTTON,
      "radiobutton",
      ATK_ROLE_RADIO_BUTTON,
      NSAccessibilityRadioButtonRole,
      ROLE_SYSTEM_RADIOBUTTON,
      ROLE_SYSTEM_RADIOBUTTON,
      eNameFromSubtreeRule)
 
+// Equivalent of HTML select element with size="1". See also EDITCOMBOBOX.
 ROLE(COMBOBOX,
      "combobox",
      ATK_ROLE_COMBO_BOX,
      NSAccessibilityPopUpButtonRole,
      ROLE_SYSTEM_COMBOBOX,
      ROLE_SYSTEM_COMBOBOX,
      eNameFromValueRule)
 
@@ -1394,8 +1395,26 @@ ROLE(FOOTNOTE,
 
 ROLE(ARTICLE,
      "article",
      ATK_ROLE_ARTICLE,
      NSAccessibilityGroupRole,
      ROLE_SYSTEM_DOCUMENT,
      ROLE_SYSTEM_DOCUMENT,
      eNoNameRule)
+
+ROLE(REGION,
+     "region",
+     ATK_ROLE_LANDMARK,
+     NSAccessibilityGroupRole,
+     USE_ROLE_STRING,
+     IA2_ROLE_LANDMARK,
+     eNoNameRule)
+
+// A composite widget with a text input and popup. Used for ARIA role combobox.
+// See also COMBOBOX.
+ROLE(EDITCOMBOBOX,
+     "editcombobox",
+     ATK_ROLE_COMBO_BOX,
+     NSAccessibilityComboBoxRole,
+     ROLE_SYSTEM_COMBOBOX,
+     ROLE_SYSTEM_COMBOBOX,
+     eNameFromValueRule)
--- a/accessible/base/SelectionManager.cpp
+++ b/accessible/base/SelectionManager.cpp
@@ -43,60 +43,59 @@ SelectionManager::SelectionManager() :
   mCaretOffset(-1), mAccWithCaret(nullptr)
 {
 
 }
 
 void
 SelectionManager::ClearControlSelectionListener()
 {
-  if (!mCurrCtrlFrame)
-    return;
-
-  const nsFrameSelection* frameSel = mCurrCtrlFrame->GetConstFrameSelection();
-  NS_ASSERTION(frameSel, "No frame selection for the element!");
-
-  mCurrCtrlFrame = nullptr;
-  if (!frameSel)
-    return;
 
   // Remove 'this' registered as selection listener for the normal selection.
-  Selection* normalSel = frameSel->GetSelection(SelectionType::eNormal);
-  normalSel->RemoveSelectionListener(this);
+  nsCOMPtr<nsISelection> normalSel = do_QueryReferent(mCurrCtrlNormalSel);
+  if (normalSel) {
+    normalSel->AsSelection()->RemoveSelectionListener(this);
+    mCurrCtrlNormalSel = nullptr;
+  }
 
   // Remove 'this' registered as selection listener for the spellcheck
   // selection.
-  Selection* spellSel = frameSel->GetSelection(SelectionType::eSpellCheck);
-  spellSel->RemoveSelectionListener(this);
+  nsCOMPtr<nsISelection> spellSel = do_QueryReferent(mCurrCtrlSpellSel);
+  if (spellSel) {
+    spellSel->AsSelection()->RemoveSelectionListener(this);
+    mCurrCtrlSpellSel = nullptr;
+  }
 }
 
 void
 SelectionManager::SetControlSelectionListener(dom::Element* aFocusedElm)
 {
   // When focus moves such that the caret is part of a new frame selection
   // this removes the old selection listener and attaches a new one for
   // the current focus.
   ClearControlSelectionListener();
 
-  mCurrCtrlFrame = aFocusedElm->GetPrimaryFrame();
-  if (!mCurrCtrlFrame)
+  nsIFrame* controlFrame = aFocusedElm->GetPrimaryFrame();
+  if (!controlFrame)
     return;
 
-  const nsFrameSelection* frameSel = mCurrCtrlFrame->GetConstFrameSelection();
+  const nsFrameSelection* frameSel = controlFrame->GetConstFrameSelection();
   NS_ASSERTION(frameSel, "No frame selection for focused element!");
   if (!frameSel)
     return;
 
   // Register 'this' as selection listener for the normal selection.
-  Selection* normalSel = frameSel->GetSelection(SelectionType::eNormal);
-  normalSel->AddSelectionListener(this);
+  nsCOMPtr<nsISelection> normalSel = frameSel->GetSelection(SelectionType::eNormal);
+  normalSel->AsSelection()->AddSelectionListener(this);
+  mCurrCtrlNormalSel = do_GetWeakReference(normalSel);
 
   // Register 'this' as selection listener for the spell check selection.
-  Selection* spellSel = frameSel->GetSelection(SelectionType::eSpellCheck);
-  spellSel->AddSelectionListener(this);
+  nsCOMPtr<nsISelection> spellSel = frameSel->GetSelection(SelectionType::eSpellCheck);
+  spellSel->AsSelection()->AddSelectionListener(this);
+  mCurrCtrlSpellSel = do_GetWeakReference(spellSel);
 }
 
 void
 SelectionManager::AddDocSelectionListener(nsIPresShell* aPresShell)
 {
   const nsFrameSelection* frameSel = aPresShell->ConstFrameSelection();
 
   // Register 'this' as selection listener for the normal selection.
--- a/accessible/base/SelectionManager.h
+++ b/accessible/base/SelectionManager.h
@@ -116,17 +116,18 @@ protected:
 
   /**
    * Process DOM selection change. Fire selection and caret move events.
    */
   void ProcessSelectionChanged(SelData* aSelData);
 
 private:
   // Currently focused control.
-  WeakFrame mCurrCtrlFrame;
   int32_t mCaretOffset;
   HyperTextAccessible* mAccWithCaret;
+  nsWeakPtr mCurrCtrlNormalSel;
+  nsWeakPtr mCurrCtrlSpellSel;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/base/States.h
+++ b/accessible/base/States.h
@@ -68,17 +68,17 @@ namespace states {
    * The expandable object's children are displayed, the opposite of collapsed,
    * applied to trees, list and other controls.
    * @see COLLAPSED state
    */
   const uint64_t EXPANDED = ((uint64_t) 0x1) << 9;
 
   /**
    * The expandable object's children are not displayed, the opposite of
-   * expanded, applied to tree lists and other controls, 
+   * expanded, applied to tree lists and other controls,
    * @see EXPANDED state.
    */
   const uint64_t COLLAPSED = ((uint64_t) 0x1) << 10;
 
   /**
    * The control or document can not accept input at this time.
    */
   const uint64_t BUSY = ((uint64_t) 0x1) << 11;
@@ -272,14 +272,20 @@ namespace states {
    * @see EXPANDED and COLLAPSED states.
    */
   const uint64_t EXPANDABLE = ((uint64_t) 0x1) << 46;
 
   /**
    * The object is pinned, usually indicating it is fixed in place and has permanence.
    */
   const uint64_t PINNED = ((uint64_t) 0x1) << 47;
+
+  /**
+   * The object is the current item within a container or set of related elements.
+   */
+  const uint64_t CURRENT = ((uint64_t) 0x1) << 48;
+
 } // namespace states
 } // namespace a11y
 } // namespace mozilla
 
 #endif
-	
+
--- a/accessible/base/nsAccUtils.cpp
+++ b/accessible/base/nsAccUtils.cpp
@@ -79,17 +79,17 @@ nsAccUtils::GetDefaultLevel(Accessible* 
 
   if (role == roles::OUTLINEITEM)
     return 1;
 
   if (role == roles::ROW) {
     Accessible* parent = aAccessible->Parent();
     // It is a row inside flatten treegrid. Group level is always 1 until it
     // is overriden by aria-level attribute.
-    if (parent && parent->Role() == roles::TREE_TABLE) 
+    if (parent && parent->Role() == roles::TREE_TABLE)
       return 1;
   }
 
   return 0;
 }
 
 int32_t
 nsAccUtils::GetARIAOrDefaultLevel(Accessible* aAccessible)
@@ -410,17 +410,17 @@ nsAccUtils::TextLength(Accessible* aAcce
   }
 
   TextLeafAccessible* textLeaf = aAccessible->AsTextLeaf();
   if (textLeaf)
     return textLeaf->Text().Length();
 
   // For list bullets (or anything other accessible which would compute its own
   // text. They don't have their own frame.
-  // XXX In the future, list bullets may have frame and anon content, so 
+  // XXX In the future, list bullets may have frame and anon content, so
   // we should be able to remove this at that point
   nsAutoString text;
   aAccessible->AppendTextTo(text); // Get all the text
   return text.Length();
 }
 
 bool
 nsAccUtils::MustPrune(Accessible* aAccessible)
--- a/accessible/base/nsAccUtils.h
+++ b/accessible/base/nsAccUtils.h
@@ -85,19 +85,19 @@ public:
    * @param aTopContent    node to end at
    */
   static void SetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
                                          nsIContent* aStartContent,
                                          mozilla::dom::Element* aTopEl);
 
   /**
    * Any ARIA property of type boolean or NMTOKEN is undefined if the ARIA
-   * property is not present, or is "" or "undefined". Do not call 
+   * property is not present, or is "" or "undefined". Do not call
    * this method for properties of type string, decimal, IDREF or IDREFS.
-   * 
+   *
    * Return true if the ARIA property is defined, otherwise false
    */
   static bool HasDefinedARIAToken(nsIContent *aContent, nsIAtom *aAtom);
 
   /**
    * Return atomic value of ARIA attribute of boolean or NMTOKEN type.
    */
   static nsIAtom* GetARIAToken(mozilla::dom::Element* aElement, nsIAtom* aAttr);
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -53,16 +53,17 @@
 #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"
 #include "nsTreeUtils.h"
 #include "nsXBLPrototypeBinding.h"
@@ -407,16 +408,17 @@ nsAccessibilityService::GetRootDocumentA
   return nullptr;
 }
 
 #ifdef XP_WIN
 static StaticAutoPtr<nsTArray<nsCOMPtr<nsIContent> > > sPendingPlugins;
 static StaticAutoPtr<nsTArray<nsCOMPtr<nsITimer> > > sPluginTimers;
 
 class PluginTimerCallBack final : public nsITimerCallback
+                                , public nsINamed
 {
   ~PluginTimerCallBack() {}
 
 public:
   explicit PluginTimerCallBack(nsIContent* aContent) : mContent(aContent) {}
 
   NS_DECL_ISUPPORTS
 
@@ -439,21 +441,27 @@ public:
 
     // We couldn't get a doc accessible so presumably the document went away.
     // In this case don't leak our ref to the content or timer.
     sPendingPlugins->RemoveElement(mContent);
     sPluginTimers->RemoveElement(aTimer);
     return NS_OK;
   }
 
+  NS_IMETHOD GetName(nsACString& aName) final
+  {
+    aName.AssignLiteral("PluginTimerCallBack");
+    return NS_OK;
+  }
+
 private:
   nsCOMPtr<nsIContent> mContent;
 };
 
-NS_IMPL_ISUPPORTS(PluginTimerCallBack, nsITimerCallback)
+NS_IMPL_ISUPPORTS(PluginTimerCallBack, nsITimerCallback, nsINamed)
 #endif
 
 already_AddRefed<Accessible>
 nsAccessibilityService::CreatePluginAccessible(nsPluginFrame* aFrame,
                                                nsIContent* aContent,
                                                Accessible* aContext)
 {
   // nsPluginFrame means a plugin, so we need to use the accessibility support
@@ -740,17 +748,17 @@ nsAccessibilityService::GetStringRole(ui
 
 #undef ROLE
 }
 
 void
 nsAccessibilityService::GetStringStates(uint32_t aState, uint32_t aExtraState,
                                         nsISupports** aStringStates)
 {
-  RefPtr<DOMStringList> stringStates = 
+  RefPtr<DOMStringList> stringStates =
     GetStringStates(nsAccUtils::To64State(aState, aExtraState));
 
   // unknown state
   if (!stringStates->Length()) {
     stringStates->Add(NS_LITERAL_STRING("unknown"));
   }
 
   stringStates.forget(aStringStates);
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -439,17 +439,17 @@ nsCoreUtils::IsErrorPage(nsIDocument *aD
 {
   nsIURI *uri = aDocument->GetDocumentURI();
   bool isAboutScheme = false;
   uri->SchemeIs("about", &isAboutScheme);
   if (!isAboutScheme)
     return false;
 
   nsAutoCString path;
-  uri->GetPath(path);
+  uri->GetPathQueryRef(path);
 
   NS_NAMED_LITERAL_CSTRING(neterror, "neterror");
   NS_NAMED_LITERAL_CSTRING(certerror, "certerror");
 
   return StringBeginsWith(path, neterror) || StringBeginsWith(path, certerror);
 }
 
 bool
--- a/accessible/base/nsEventShell.cpp
+++ b/accessible/base/nsEventShell.cpp
@@ -55,17 +55,17 @@ nsEventShell::FireEvent(uint32_t aEventT
   NS_ENSURE_TRUE_VOID(aAccessible);
 
   RefPtr<AccEvent> event = new AccEvent(aEventType, aAccessible,
                                           aIsFromUserInput);
 
   FireEvent(event);
 }
 
-void 
+void
 nsEventShell::GetEventAttributes(nsINode *aNode,
                                  nsIPersistentProperties *aAttributes)
 {
   if (aNode != sEventTargetNode)
     return;
 
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::eventFromInput,
                          sEventFromUserInput ? NS_LITERAL_STRING("true") :
--- a/accessible/base/nsTextEquivUtils.cpp
+++ b/accessible/base/nsTextEquivUtils.cpp
@@ -130,42 +130,42 @@ nsTextEquivUtils::AppendTextEquivFromTex
             display->mDisplay == StyleDisplay::TableCell) {
           isHTMLBlock = true;
           if (!aString->IsEmpty()) {
             aString->Append(char16_t(' '));
           }
         }
       }
     }
-    
+
     if (aContent->TextLength() > 0) {
       nsIFrame *frame = aContent->GetPrimaryFrame();
       if (frame) {
         nsIFrame::RenderedText text = frame->GetRenderedText(0,
             UINT32_MAX, nsIFrame::TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
             nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
         aString->Append(text.mString);
       } else {
         // If aContent is an object that is display: none, we have no a frame.
         aContent->AppendTextTo(*aString);
       }
       if (isHTMLBlock && !aString->IsEmpty()) {
         aString->Append(char16_t(' '));
       }
     }
-    
+
     return NS_OK;
   }
-  
+
   if (aContent->IsHTMLElement() &&
       aContent->NodeInfo()->Equals(nsGkAtoms::br)) {
     aString->AppendLiteral("\r\n");
     return NS_OK;
   }
-  
+
   return NS_OK_NO_NAME_CLAUSE_HANDLED;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsTextEquivUtils. Private.
 
 nsresult
 nsTextEquivUtils::AppendFromAccessibleChildren(Accessible* aAccessible,
--- a/accessible/base/nsTextEquivUtils.h
+++ b/accessible/base/nsTextEquivUtils.h
@@ -116,17 +116,17 @@ public:
 
 private:
   /**
    * Iterates accessible children and calculates text equivalent from each
    * child.
    */
   static nsresult AppendFromAccessibleChildren(Accessible* aAccessible,
                                                nsAString *aString);
-  
+
   /**
    * Calculates text equivalent from the given accessible and its subtree if
    * allowed.
    */
   static nsresult AppendFromAccessible(Accessible* aAccessible,
                                        nsAString *aString);
 
   /**
--- a/accessible/generic/Accessible-inl.h
+++ b/accessible/generic/Accessible-inl.h
@@ -90,17 +90,23 @@ Accessible::HasGenericType(AccGenericTyp
 
 inline bool
 Accessible::HasNumericValue() const
 {
   if (mStateFlags & eHasNumericValue)
     return true;
 
   const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
-  return roleMapEntry && roleMapEntry->valueRule != eNoValue;
+  if (!roleMapEntry || roleMapEntry->valueRule == eNoValue)
+    return false;
+
+  if (roleMapEntry->valueRule == eHasValueMinMaxIfFocusable)
+    return InteractiveState() & states::FOCUSABLE;
+
+  return true;
 }
 
 inline void
 Accessible::ScrollTo(uint32_t aHow) const
 {
   if (mContent)
     nsCoreUtils::ScrollTo(mDoc->PresShell(), mContent, aHow);
 }
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -313,17 +313,19 @@ Accessible::TranslateString(const nsStri
   nsCOMPtr<nsIStringBundle> stringBundle;
   stringBundleService->CreateBundle(
     "chrome://global-platform/locale/accessible.properties",
     getter_AddRefs(stringBundle));
   if (!stringBundle)
     return;
 
   nsXPIDLString xsValue;
-  nsresult rv = stringBundle->GetStringFromName(aKey.get(), getter_Copies(xsValue));
+  nsresult rv =
+    stringBundle->GetStringFromName(NS_ConvertUTF16toUTF8(aKey).get(),
+                                    getter_Copies(xsValue));
   if (NS_SUCCEEDED(rv))
     aStringOut.Assign(xsValue);
 }
 
 uint64_t
 Accessible::VisibilityState()
 {
   nsIFrame* frame = GetFrame();
@@ -1409,16 +1411,32 @@ Accessible::SetCurValue(double aValue)
 
   return NS_SUCCEEDED(
     mContent->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
+  //
+  // XXX: While the name computation algorithm can be non-trivial in the general
+  // case, it should not be especially bad here: If the author hasn't used the
+  // region role, this calculation won't occur. And the region role's name
+  // calculation rule excludes name from content. That said, this use case is
+  // another example of why we should consider caching the accessible name. See:
+  // https://bugzilla.mozilla.org/show_bug.cgi?id=1378235.
+  if (aRole == roles::REGION) {
+    nsAutoString name;
+    Name(name);
+    return name.IsEmpty() ? NativeRole() : aRole;
+  }
+
   // XXX: these unfortunate exceptions don't fit into the ARIA table. This is
   // 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;
     }
@@ -1429,24 +1447,24 @@ Accessible::ARIATransformRole(role aRole
                               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->Role() == roles::COMBOBOX) {
+    if (mParent && mParent->IsCombobox()) {
       return roles::COMBOBOX_LIST;
     } else {
       // Listbox is owned by a combobox
       Relation rel = RelationByType(RelationType::NODE_CHILD_OF);
       Accessible* targetAcc = nullptr;
       while ((targetAcc = rel.Next()))
-        if (targetAcc->Role() == roles::COMBOBOX)
+        if (targetAcc->IsCombobox())
           return roles::COMBOBOX_LIST;
     }
 
   } else if (aRole == roles::OPTION) {
     if (mParent && mParent->Role() == roles::COMBOBOX_LIST)
       return roles::COMBOBOX_OPTION;
 
   } else if (aRole == roles::MENUITEM) {
@@ -2812,46 +2830,46 @@ KeyBinding::ToPlatformFormat(nsAString& 
     stringBundleService->CreateBundle(
       "chrome://global-platform/locale/platformKeys.properties",
       getter_AddRefs(keyStringBundle));
 
   if (!keyStringBundle)
     return;
 
   nsAutoString separator;
-  keyStringBundle->GetStringFromName(u"MODIFIER_SEPARATOR",
+  keyStringBundle->GetStringFromName("MODIFIER_SEPARATOR",
                                      getter_Copies(separator));
 
   nsAutoString modifierName;
   if (mModifierMask & kControl) {
-    keyStringBundle->GetStringFromName(u"VK_CONTROL",
+    keyStringBundle->GetStringFromName("VK_CONTROL",
                                        getter_Copies(modifierName));
 
     aValue.Append(modifierName);
     aValue.Append(separator);
   }
 
   if (mModifierMask & kAlt) {
-    keyStringBundle->GetStringFromName(u"VK_ALT",
+    keyStringBundle->GetStringFromName("VK_ALT",
                                        getter_Copies(modifierName));
 
     aValue.Append(modifierName);
     aValue.Append(separator);
   }
 
   if (mModifierMask & kShift) {
-    keyStringBundle->GetStringFromName(u"VK_SHIFT",
+    keyStringBundle->GetStringFromName("VK_SHIFT",
                                        getter_Copies(modifierName));
 
     aValue.Append(modifierName);
     aValue.Append(separator);
   }
 
   if (mModifierMask & kMeta) {
-    keyStringBundle->GetStringFromName(u"VK_META",
+    keyStringBundle->GetStringFromName("VK_META",
                                        getter_Copies(modifierName));
 
     aValue.Append(modifierName);
     aValue.Append(separator);
   }
 
   aValue.Append(mKey);
 }
--- a/accessible/generic/ApplicationAccessible.cpp
+++ b/accessible/generic/ApplicationAccessible.cpp
@@ -49,18 +49,17 @@ ApplicationAccessible::Name(nsString& aN
 
   nsCOMPtr<nsIStringBundle> bundle;
   nsresult rv = bundleService->CreateBundle("chrome://branding/locale/brand.properties",
                                             getter_AddRefs(bundle));
   if (NS_FAILED(rv))
     return eNameOK;
 
   nsXPIDLString appName;
-  rv = bundle->GetStringFromName(u"brandShortName",
-                                 getter_Copies(appName));
+  rv = bundle->GetStringFromName("brandShortName", getter_Copies(appName));
   if (NS_FAILED(rv) || appName.IsEmpty()) {
     NS_WARNING("brandShortName not found, using default app name");
     appName.AssignLiteral("Gecko based application");
   }
 
   aName.Assign(appName);
   return eNameOK;
 }
--- a/accessible/generic/DocAccessible-inl.h
+++ b/accessible/generic/DocAccessible-inl.h
@@ -130,18 +130,17 @@ DocAccessible::NotifyOfLoad(uint32_t aLo
       new AccStateChangeEvent(this, states::BUSY, false);
     FireDelayedEvent(stateEvent);
   }
 }
 
 inline void
 DocAccessible::MaybeNotifyOfValueChange(Accessible* aAccessible)
 {
-  a11y::role role = aAccessible->Role();
-  if (role == roles::ENTRY || role == roles::COMBOBOX)
+  if (aAccessible->IsCombobox() || aAccessible->Role() == roles::ENTRY)
     FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE, aAccessible);
 }
 
 inline Accessible*
 DocAccessible::GetAccessibleEvenIfNotInMapOrContainer(nsINode* aNode) const
 {
   Accessible* acc = GetAccessibleEvenIfNotInMap(aNode);
   return acc ? acc : GetContainerAccessible(aNode);
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -662,17 +662,17 @@ DocAccessible::ScrollPositionDidChange(n
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIObserver
 
 NS_IMETHODIMP
 DocAccessible::Observe(nsISupports* aSubject, const char* aTopic,
                        const char16_t* aData)
 {
-  if (!nsCRT::strcmp(aTopic,"obs_documentCreated")) {    
+  if (!nsCRT::strcmp(aTopic,"obs_documentCreated")) {
     // State editable will now be set, readonly is now clear
     // Normally we only fire delayed events created from the node, not an
     // accessible object. See the AccStateChangeEvent constructor for details
     // about this exceptional case.
     RefPtr<AccEvent> event =
       new AccStateChangeEvent(this, states::EDITABLE, true);
     FireDelayedEvent(event);
   }
@@ -815,17 +815,17 @@ DocAccessible::AttributeChangedImpl(Acce
   // DOM attribute & resulting layout to actually change. Otherwise,
   // assistive technology will retrieve the wrong state/value/selection info.
 
   // XXX todo
   // We still need to handle special HTML cases here
   // For example, if an <img>'s usemap attribute is modified
   // Otherwise it may just be a state change, for example an object changing
   // its visibility
-  // 
+  //
   // XXX todo: report aria state changes for "undefined" literal value changes
   // filed as bug 472142
   //
   // XXX todo:  invalidate accessible when aria state changes affect exposed role
   // filed as bug 472143
 
   // Universal boolean properties that don't require a role. Fire the state
   // change when disabled or aria-disabled attribute is set.
@@ -1049,16 +1049,23 @@ DocAccessible::ARIAAttributeChanged(Acce
   if (aAttribute == nsGkAtoms::aria_valuenow &&
       (!elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_valuetext) ||
        elm->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_valuetext,
                         nsGkAtoms::_empty, eCaseMatters))) {
     FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible);
     return;
   }
 
+  if (aAttribute == nsGkAtoms::aria_current) {
+    RefPtr<AccEvent> event =
+      new AccStateChangeEvent(aAccessible, states::CURRENT);
+    FireDelayedEvent(event);
+    return;
+  }
+
   if (aAttribute == nsGkAtoms::aria_owns) {
     mNotificationController->ScheduleRelocation(aAccessible);
   }
 }
 
 void
 DocAccessible::ARIAActiveDescendantChanged(Accessible* aAccessible)
 {
@@ -1326,16 +1333,18 @@ DocAccessible::UnbindFromDocument(Access
 #endif
   }
 
   // Remove an accessible from node-to-accessible map if it exists there.
   if (aAccessible->IsNodeMapEntry() &&
       mNodeToAccessibleMap.Get(aAccessible->GetNode()) == aAccessible)
     mNodeToAccessibleMap.Remove(aAccessible->GetNode());
 
+  aAccessible->mStateFlags |= eIsNotInDocument;
+
   // Update XPCOM part.
   xpcAccessibleDocument* xpcDoc = GetAccService()->GetCachedXPCDocument(this);
   if (xpcDoc)
     xpcDoc->NotifyOfShutdown(aAccessible);
 
   void* uniqueID = aAccessible->UniqueID();
 
   NS_ASSERTION(!aAccessible->IsDefunct(), "Shutdown the shutdown accessible!");
@@ -2051,72 +2060,90 @@ DocAccessible::RelocateARIAOwnedIfNeeded
   }
 
   return false;
 }
 
 void
 DocAccessible::DoARIAOwnsRelocation(Accessible* aOwner)
 {
-  nsTArray<RefPtr<Accessible> >* children = mARIAOwnsHash.LookupOrAdd(aOwner);
-
   MOZ_ASSERT(aOwner, "aOwner must be a valid pointer");
   MOZ_ASSERT(aOwner->Elm(), "aOwner->Elm() must be a valid pointer");
 
 #ifdef A11Y_LOG
   logging::TreeInfo("aria owns relocation", logging::eVerbose, aOwner);
 #endif
 
+  nsTArray<RefPtr<Accessible> >* owned = mARIAOwnsHash.LookupOrAdd(aOwner);
+
   IDRefsIterator iter(this, aOwner->Elm(), nsGkAtoms::aria_owns);
-  uint32_t arrayIdx = 0, insertIdx = aOwner->ChildCount() - children->Length();
+  uint32_t idx = 0;
   while (nsIContent* childEl = iter.NextElem()) {
     Accessible* child = GetAccessible(childEl);
+    auto insertIdx = aOwner->ChildCount() - owned->Length() + idx;
 
     // Make an attempt to create an accessible if it wasn't created yet.
     if (!child) {
       if (aOwner->IsAcceptableChild(childEl)) {
         child = GetAccService()->CreateAccessible(childEl, aOwner);
         if (child) {
           TreeMutation imut(aOwner);
           aOwner->InsertChildAt(insertIdx, child);
           imut.AfterInsertion(child);
           imut.Done();
 
           child->SetRelocated(true);
-          children->InsertElementAt(arrayIdx, child);
+          owned->InsertElementAt(idx, child);
+          idx++;
 
           // Create subtree before adjusting the insertion index, since subtree
           // creation may alter children in the container.
           CreateSubtree(child);
           FireEventsOnInsertion(aOwner);
-
-          insertIdx = child->IndexInParent() + 1;
-          arrayIdx++;
         }
       }
       continue;
     }
 
 #ifdef A11Y_LOG
   logging::TreeInfo("aria owns traversal", logging::eVerbose,
                     "candidate", child, nullptr);
 #endif
 
     // Same child on same position, no change.
-    if (child->Parent() == aOwner &&
-        child->IndexInParent() == static_cast<int32_t>(insertIdx)) {
-      MOZ_ASSERT(child == children->ElementAt(arrayIdx), "Not in sync!");
-      insertIdx++; arrayIdx++;
-      continue;
+    if (child->Parent() == aOwner) {
+      int32_t indexInParent = child->IndexInParent();
+
+      // The child is being placed in its current index,
+      // eg. aria-owns='id1 id2 id3' is changed to aria-owns='id3 id2 id1'.
+      if (indexInParent == static_cast<int32_t>(insertIdx)) {
+        MOZ_ASSERT(child->IsRelocated(),
+                   "A child, having an index in parent from aria ownded indices range, has to be aria owned");
+        MOZ_ASSERT(owned->ElementAt(idx) == child,
+                   "Unexpected child in ARIA owned array");
+        idx++;
+        continue;
+      }
+
+      // The child is being inserted directly after its current index,
+      // resulting in a no-move case. This will happen when a parent aria-owns
+      // its last ordinal child:
+      // <ul aria-owns='id2'><li id='id1'></li><li id='id2'></li></ul>
+      if (indexInParent == static_cast<int32_t>(insertIdx) - 1) {
+        MOZ_ASSERT(!child->IsRelocated(), "Child should be in its ordinal position");
+        child->SetRelocated(true);
+        owned->InsertElementAt(idx, child);
+        idx++;
+        continue;
+      }
     }
 
-    MOZ_ASSERT(children->SafeElementAt(arrayIdx) != child, "Already in place!");
+    MOZ_ASSERT(owned->SafeElementAt(idx) != child, "Already in place!");
 
-    nsTArray<RefPtr<Accessible> >::index_type idx = children->IndexOf(child);
-    if (idx < arrayIdx) {
+    if (owned->IndexOf(child) < idx) {
       continue; // ignore second entry of same ID
     }
 
     // A new child is found, check for loops.
     if (child->Parent() != aOwner) {
       Accessible* parent = aOwner;
       while (parent && parent != child && !parent->IsDoc()) {
         parent = parent->Parent();
@@ -2124,34 +2151,34 @@ DocAccessible::DoARIAOwnsRelocation(Acce
       // A referred child cannot be a parent of the owner.
       if (parent == child) {
         continue;
       }
     }
 
     if (MoveChild(child, aOwner, insertIdx)) {
       child->SetRelocated(true);
-      children->InsertElementAt(arrayIdx, child);
-      arrayIdx++;
-      insertIdx = child->IndexInParent() + 1;
+      owned->InsertElementAt(idx, child);
+      idx++;
     }
   }
 
   // Put back children that are not seized anymore.
-  PutChildrenBack(children, arrayIdx);
-  if (children->Length() == 0) {
+  PutChildrenBack(owned, idx);
+  if (owned->Length() == 0) {
     mARIAOwnsHash.Remove(aOwner);
   }
 }
 
 void
 DocAccessible::PutChildrenBack(nsTArray<RefPtr<Accessible> >* aChildren,
                                uint32_t aStartIdx)
 {
-  nsTArray<RefPtr<Accessible> > containers;
+  MOZ_ASSERT(aStartIdx <= aChildren->Length(), "Wrong removal index");
+
   for (auto idx = aStartIdx; idx < aChildren->Length(); idx++) {
     Accessible* child = aChildren->ElementAt(idx);
     if (!child->IsInDocument()) {
       continue;
     }
 
     // Remove the child from the owner
     Accessible* owner = child->Parent();
@@ -2163,44 +2190,63 @@ DocAccessible::PutChildrenBack(nsTArray<
 #ifdef A11Y_LOG
     logging::TreeInfo("aria owns put child back", 0,
                       "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 = GetContainerAccessible(child->GetContent());
+    Accessible* origContainer = AccessibleOrTrueContainer(content->GetParentNode());
     if (origContainer) {
       TreeWalker walker(origContainer);
-      if (walker.Seek(child->GetContent())) {
+      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();
         }
         else {
           idxInParent = 0;
         }
       }
     }
-    MoveChild(child, origContainer, idxInParent);
+
+    // The child may have already be in its ordinal place for 2 reasons:
+    // 1. It was the last ordinal child, and the first aria-owned child.
+    //    given:      <ul id="list" aria-owns="b"><li id="a"></li><li id="b"></li></ul>
+    //    after load: $("list").setAttribute("aria-owns", "");
+    // 2. The preceding adopted children were just reclaimed, eg:
+    //    given:      <ul id="list"><li id="b"></li></ul>
+    //    after load: $("list").setAttribute("aria-owns", "a b");
+    //    later:      $("list").setAttribute("aria-owns", "");
+    if (origContainer != owner || child->IndexInParent() != idxInParent) {
+      MoveChild(child, origContainer, idxInParent);
+    } else {
+      MOZ_ASSERT(!child->PrevSibling() || !child->PrevSibling()->IsRelocated(),
+                 "No relocated child should appear before this one");
+      MOZ_ASSERT(!child->NextSibling() || child->NextSibling()->IsRelocated(),
+                 "No ordinal child should appear after this one");
+    }
   }
 
   aChildren->RemoveElementsAt(aStartIdx, aChildren->Length() - aStartIdx);
 }
 
 bool
 DocAccessible::MoveChild(Accessible* aChild, Accessible* aNewParent,
                          int32_t aIdxInParent)
 {
   MOZ_ASSERT(aChild, "No child");
   MOZ_ASSERT(aChild->Parent(), "No parent");
+  MOZ_ASSERT(aIdxInParent <= static_cast<int32_t>(aNewParent->ChildCount()),
+             "Wrong insertion point for a moving child");
 
   Accessible* curParent = aChild->Parent();
 
 #ifdef A11Y_LOG
   logging::TreeInfo("move child", 0,
                     "old parent", curParent, "new parent", aNewParent,
                     "child", aChild, nullptr);
 #endif
--- a/accessible/generic/DocAccessible.h
+++ b/accessible/generic/DocAccessible.h
@@ -157,17 +157,17 @@ public:
     // document and all its subdocuments are ready
     eCompletelyLoaded = eReady | 1 << 2
   };
 
   /**
    * Return true if the document has given document state.
    */
   bool HasLoadState(LoadState aState) const
-    { return (mLoadState & static_cast<uint32_t>(aState)) == 
+    { return (mLoadState & static_cast<uint32_t>(aState)) ==
         static_cast<uint32_t>(aState); }
 
   /**
    * Return a native window handler or pointer depending on platform.
    */
   virtual void* GetNativeWindow() const;
 
   /**
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -1606,18 +1606,18 @@ HyperTextAccessible::SelectionBoundsAt(i
 
   uint32_t rangeCount = ranges.Length();
   if (aSelectionNum < 0 || aSelectionNum >= static_cast<int32_t>(rangeCount))
     return false;
 
   nsRange* range = ranges[aSelectionNum];
 
   // Get start and end points.
-  nsINode* startNode = range->GetStartParent();
-  nsINode* endNode = range->GetEndParent();
+  nsINode* startNode = range->GetStartContainer();
+  nsINode* endNode = range->GetEndContainer();
   int32_t startOffset = range->StartOffset(), endOffset = range->EndOffset();
 
   // Make sure start is before end, by swapping DOM points.  This occurs when
   // the user selects backwards in the text.
   int32_t rangeCompare = nsContentUtils::ComparePoints(endNode, endOffset,
                                                        startNode, startOffset);
   if (rangeCompare < 0) {
     nsINode* tempNode = startNode;
@@ -1782,32 +1782,33 @@ HyperTextAccessible::SelectionRanges(nsT
   dom::Selection* sel = DOMSelection();
   if (!sel)
     return;
 
   aRanges->SetCapacity(sel->RangeCount());
 
   for (uint32_t idx = 0; idx < sel->RangeCount(); idx++) {
     nsRange* DOMRange = sel->GetRangeAt(idx);
-    HyperTextAccessible* startParent =
-      nsAccUtils::GetTextContainer(DOMRange->GetStartParent());
-    HyperTextAccessible* endParent =
-      nsAccUtils::GetTextContainer(DOMRange->GetEndParent());
-    if (!startParent || !endParent)
+    HyperTextAccessible* startContainer =
+      nsAccUtils::GetTextContainer(DOMRange->GetStartContainer());
+    HyperTextAccessible* endContainer =
+      nsAccUtils::GetTextContainer(DOMRange->GetEndContainer());
+    if (!startContainer || !endContainer) {
       continue;
+    }
 
     int32_t startOffset =
-      startParent->DOMPointToOffset(DOMRange->GetStartParent(),
-                                    DOMRange->StartOffset(), false);
+      startContainer->DOMPointToOffset(DOMRange->GetStartContainer(),
+                                       DOMRange->StartOffset(), false);
     int32_t endOffset =
-      endParent->DOMPointToOffset(DOMRange->GetEndParent(),
-                                  DOMRange->EndOffset(), true);
+      endContainer->DOMPointToOffset(DOMRange->GetEndContainer(),
+                                     DOMRange->EndOffset(), true);
 
     TextRange tr(IsTextField() ? const_cast<HyperTextAccessible*>(this) : mDoc,
-                    startParent, startOffset, endParent, endOffset);
+                    startContainer, startOffset, endContainer, endOffset);
     *(aRanges->AppendElement()) = Move(tr);
   }
 }
 
 void
 HyperTextAccessible::VisibleRanges(nsTArray<a11y::TextRange>* aRanges) const
 {
 }
@@ -2145,27 +2146,27 @@ HyperTextAccessible::GetSpellTextAttr(ns
   uint32_t startOffset = 0, endOffset = 0;
   for (int32_t idx = 0; idx < rangeCount; idx++) {
     nsRange* range = domSel->GetRangeAt(idx);
     if (range->Collapsed())
       continue;
 
     // See if the point comes after the range in which case we must continue in
     // case there is another range after this one.
-    nsINode* endNode = range->GetEndParent();
+    nsINode* endNode = range->GetEndContainer();
     int32_t endNodeOffset = range->EndOffset();
     if (nsContentUtils::ComparePoints(aNode, aNodeOffset,
                                       endNode, endNodeOffset) >= 0)
       continue;
 
     // At this point our point is either in this range or before it but after
     // the previous range.  So we check to see if the range starts before the
     // point in which case the point is in the missspelled range, otherwise it
     // must be before the range and after the previous one if any.
-    nsINode* startNode = range->GetStartParent();
+    nsINode* startNode = range->GetStartContainer();
     int32_t startNodeOffset = range->StartOffset();
     if (nsContentUtils::ComparePoints(startNode, startNodeOffset, aNode,
                                       aNodeOffset) <= 0) {
       startOffset = DOMPointToOffset(startNode, startNodeOffset);
 
       endOffset = DOMPointToOffset(endNode, endNodeOffset);
 
       if (startOffset > *aStartOffset)
@@ -2182,17 +2183,17 @@ HyperTextAccessible::GetSpellTextAttr(ns
       return;
     }
 
     // This range came after the point.
     endOffset = DOMPointToOffset(startNode, startNodeOffset);
 
     if (idx > 0) {
       nsRange* prevRange = domSel->GetRangeAt(idx - 1);
-      startOffset = DOMPointToOffset(prevRange->GetEndParent(),
+      startOffset = DOMPointToOffset(prevRange->GetEndContainer(),
                                      prevRange->EndOffset());
     }
 
     if (startOffset > *aStartOffset)
       *aStartOffset = startOffset;
 
     if (endOffset < *aEndOffset)
       *aEndOffset = endOffset;
@@ -2200,17 +2201,17 @@ HyperTextAccessible::GetSpellTextAttr(ns
     return;
   }
 
   // We never found a range that ended after the point, therefore we know that
   // the point is not in a range, that we do not need to compute an end offset,
   // and that we should use the end offset of the last range to compute the
   // start offset of the text attribute range.
   nsRange* prevRange = domSel->GetRangeAt(rangeCount - 1);
-  startOffset = DOMPointToOffset(prevRange->GetEndParent(),
+  startOffset = DOMPointToOffset(prevRange->GetEndContainer(),
                                  prevRange->EndOffset());
 
   if (startOffset > *aStartOffset)
     *aStartOffset = startOffset;
 }
 
 bool
 HyperTextAccessible::IsTextRole()
--- a/accessible/generic/ImageAccessible.cpp
+++ b/accessible/generic/ImageAccessible.cpp
@@ -106,17 +106,17 @@ ImageAccessible::ActionCount()
   return HasLongDesc() ? actionCount + 1 : actionCount;
 }
 
 void
 ImageAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
 {
   aName.Truncate();
   if (IsLongDescIndex(aIndex) && HasLongDesc())
-    aName.AssignLiteral("showlongdesc"); 
+    aName.AssignLiteral("showlongdesc");
   else
     LinkableAccessible::ActionNameAt(aIndex, aName);
 }
 
 bool
 ImageAccessible::DoAction(uint8_t aIndex)
 {
   // Get the long description uri and open in a new window.
--- a/accessible/generic/OuterDocAccessible.h
+++ b/accessible/generic/OuterDocAccessible.h
@@ -9,17 +9,17 @@
 #include "AccessibleWrap.h"
 
 namespace mozilla {
 namespace a11y {
 class DocAccessibleParent;
 
 /**
  * Used for <browser>, <frame>, <iframe>, <page> or editor> elements.
- * 
+ *
  * In these variable names, "outer" relates to the OuterDocAccessible as
  * opposed to the DocAccessibleWrap which is "inner". The outer node is
  * a something like tags listed above, whereas the inner node corresponds to
  * the inner document root.
  */
 
 class OuterDocAccessible final : public AccessibleWrap
 {
--- a/accessible/generic/RootAccessible.cpp
+++ b/accessible/generic/RootAccessible.cpp
@@ -99,17 +99,17 @@ RootAccessible::NativeRole()
   return DocAccessibleWrap::NativeRole();
 }
 
 // RootAccessible protected member
 #ifdef MOZ_XUL
 uint32_t
 RootAccessible::GetChromeFlags()
 {
-  // Return the flag set for the top level window as defined 
+  // Return the flag set for the top level window as defined
   // by nsIWebBrowserChrome::CHROME_WINDOW_[FLAGNAME]
   // Not simple: nsIXULWindow is not just a QI from nsIDOMWindow
   nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mDocumentNode);
   NS_ENSURE_TRUE(docShell, 0);
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
   docShell->GetTreeOwner(getter_AddRefs(treeOwner));
   NS_ENSURE_TRUE(treeOwner, 0);
   nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(treeOwner));
@@ -198,17 +198,17 @@ RootAccessible::AddEventListeners()
 
   return DocAccessible::AddEventListeners();
 }
 
 nsresult
 RootAccessible::RemoveEventListeners()
 {
   nsCOMPtr<EventTarget> target = mDocumentNode;
-  if (target) { 
+  if (target) {
     for (const char* const* e = kEventTypes,
                    * const* e_end = ArrayEnd(kEventTypes);
          e < e_end; ++e) {
       nsresult rv = target->RemoveEventListener(NS_ConvertASCIItoUTF16(*e), this, true);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
@@ -280,17 +280,17 @@ RootAccessible::ProcessDOMEvent(nsIDOMEv
     HandlePopupHidingEvent(origTargetNode);
     return;
   }
 
   DocAccessible* targetDocument = GetAccService()->
     GetDocAccessible(origTargetNode->OwnerDoc());
   NS_ASSERTION(targetDocument, "No document while accessible is in document?!");
 
-  Accessible* accessible = 
+  Accessible* accessible =
     targetDocument->GetAccessibleOrContainer(origTargetNode);
   if (!accessible)
     return;
 
 #ifdef MOZ_XUL
   XULTreeAccessible* treeAcc = accessible->AsXULTree();
   if (treeAcc) {
     if (eventType.EqualsLiteral("TreeRowCountChanged")) {
@@ -512,32 +512,30 @@ RootAccessible::HandlePopupShownEvent(Ac
     // Don't fire menupopup events for combobox and autocomplete lists.
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START,
                             aAccessible);
     return;
   }
 
   if (role == roles::TOOLTIP) {
     // There is a single <xul:tooltip> node which Mozilla moves around.
-    // The accessible for it stays the same no matter where it moves. 
-    // AT's expect to get an EVENT_SHOW for the tooltip. 
+    // The accessible for it stays the same no matter where it moves.
+    // AT's expect to get an EVENT_SHOW for the tooltip.
     // In event callback the tooltip's accessible will be ready.
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SHOW, aAccessible);
     return;
   }
 
   if (role == roles::COMBOBOX_LIST) {
     // Fire expanded state change event for comboboxes and autocompeletes.
     Accessible* combobox = aAccessible->Parent();
     if (!combobox)
       return;
 
-    roles::Role comboboxRole = combobox->Role();
-    if (comboboxRole == roles::COMBOBOX || 
-	comboboxRole == roles::AUTOCOMPLETE) {
+    if (combobox->IsCombobox() || combobox->IsAutoComplete()) {
       RefPtr<AccEvent> event =
         new AccStateChangeEvent(combobox, states::EXPANDED, true);
       if (event)
         nsEventShell::FireEvent(event);
     }
   }
 }
 
--- a/accessible/generic/TableAccessible.h
+++ b/accessible/generic/TableAccessible.h
@@ -51,31 +51,31 @@ public:
    * Return the index of the cell at the given row and column.
    */
   virtual int32_t CellIndexAt(uint32_t aRowIdx, uint32_t aColIdx)
     { return ColCount() * aRowIdx + aColIdx; }
 
   /**
    * Return the column index of the cell with the given index.
    */
-  virtual int32_t ColIndexAt(uint32_t aCellIdx) 
+  virtual int32_t ColIndexAt(uint32_t aCellIdx)
     { return aCellIdx % ColCount(); }
 
   /**
    * Return the row index of the cell with the given index.
    */
-  virtual int32_t RowIndexAt(uint32_t aCellIdx) 
+  virtual int32_t RowIndexAt(uint32_t aCellIdx)
     { return aCellIdx / ColCount(); }
 
   /**
    * Get the row and column indices for the cell at the given index.
    */
   virtual void RowAndColIndicesAt(uint32_t aCellIdx, int32_t* aRowIdx,
-                                  int32_t* aColIdx) 
-    { 
+                                  int32_t* aColIdx)
+    {
       uint32_t colCount = ColCount();
       *aRowIdx = aCellIdx / colCount;
       *aColIdx = aCellIdx % colCount;
     }
 
   /**
    * Return the number of columns occupied by the cell at the given row and
    * column indices.
--- a/accessible/generic/TextLeafAccessible.h
+++ b/accessible/generic/TextLeafAccessible.h
@@ -5,17 +5,17 @@
 
 #ifndef mozilla_a11y_TextLeafAccessible_h__
 #define mozilla_a11y_TextLeafAccessible_h__
 
 #include "BaseAccessibles.h"
 
 namespace mozilla {
 namespace a11y {
- 
+
 /**
  * Generic class used for text nodes.
  */
 class TextLeafAccessible : public LinkableAccessible
 {
 public:
   TextLeafAccessible(nsIContent* aContent, DocAccessible* aDoc);
   virtual ~TextLeafAccessible();
--- a/accessible/html/HTMLFormControlAccessible.cpp
+++ b/accessible/html/HTMLFormControlAccessible.cpp
@@ -84,17 +84,17 @@ HTMLCheckboxAccessible::NativeState()
   if (!input)
     return state;
 
   if (input->Indeterminate())
     return state | states::MIXED;
 
   if (input->Checked())
     return state | states::CHECKED;
- 
+
   return state;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLCheckboxAccessible: Widgets
 
 bool
 HTMLCheckboxAccessible::IsWidget() const
--- a/accessible/html/HTMLSelectAccessible.cpp
+++ b/accessible/html/HTMLSelectAccessible.cpp
@@ -147,17 +147,17 @@ 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);
   if (!aName.IsEmpty())
     return eNameOK;
 
-  // CASE #2 -- no label parameter, get the first child, 
+  // 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);
     aName.CompressWhitespace();
     return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
   }
 
--- a/accessible/html/HTMLTableAccessible.cpp
+++ b/accessible/html/HTMLTableAccessible.cpp
@@ -971,17 +971,17 @@ HTMLTableAccessible::IsProbablyLayoutTab
   // Check for legitimate data table attributes.
   nsAutoString summary;
   if (mContent->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()) 
+  if (caption && caption->Role() == roles::CAPTION && caption->HasChildren())
     RETURN_LAYOUT_ANSWER(false, "Not empty caption -- legitimate table structures");
 
   for (nsIContent* childElm = mContent->GetFirstChild(); childElm;
        childElm = childElm->GetNextSibling()) {
     if (!childElm->IsHTMLElement())
       continue;
 
     if (childElm->IsAnyOfHTMLElements(nsGkAtoms::col,
@@ -1104,19 +1104,18 @@ HTMLTableAccessible::IsProbablyLayoutTab
 
   // Two column rules
   if (rowCount * colCount <= 10) {
     RETURN_LAYOUT_ANSWER(true, "2-4 columns, 10 cells or less, non-bordered");
   }
 
   if (HasDescendant(NS_LITERAL_STRING("embed")) ||
       HasDescendant(NS_LITERAL_STRING("object")) ||
-      HasDescendant(NS_LITERAL_STRING("applet")) ||
       HasDescendant(NS_LITERAL_STRING("iframe"))) {
-    RETURN_LAYOUT_ANSWER(true, "Has no borders, and has iframe, object, applet or iframe, typical of advertisements");
+    RETURN_LAYOUT_ANSWER(true, "Has no borders, and has iframe, object, or iframe, typical of advertisements");
   }
 
   RETURN_LAYOUT_ANSWER(false, "no layout factor strong enough, so will guess data");
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLCaptionAccessible
--- a/accessible/interfaces/nsIAccessibleRole.idl
+++ b/accessible/interfaces/nsIAccessibleRole.idl
@@ -294,19 +294,19 @@ interface nsIAccessibleRole : nsISupport
    * group of mutually exclusive options. All objects sharing a single parent
    * that have this attribute are assumed to be part of single mutually
    * exclusive group. It is used for xul:radio, html:input@type="radio",
    * role="radio".
    */
   const unsigned long ROLE_RADIOBUTTON = 45;
 
   /**
-   * Represents a combo box; an edit control with an associated list box that
-   * provides a set of predefined choices. It is used for html:select,
-   * xul:menulist, role="combobox".
+   * Represents a combo box; a popup button with an associated list box that
+   * provides a set of predefined choices. It is used for html:select with a
+   * size of 1 and xul:menulist. See also ROLE_EDITCOMBOBOX.
    */
   const unsigned long ROLE_COMBOBOX = 46;
 
   /**
    * Represents the calendar control.
    */
   const unsigned long ROLE_DROPLIST = 47;
 
@@ -996,9 +996,23 @@ interface nsIAccessibleRole : nsISupport
   const unsigned long ROLE_FOOTNOTE = 171;
 
   /**
    * A complete or self-contained composition in a document, page, application,
    * or site and that is, in principle, independently distributable or reusable,
    * e.g. in syndication.
    */
   const unsigned long ROLE_ARTICLE = 172;
+
+  /**
+   * A perceivable section containing content that is relevant to a specific,
+   * author-specified purpose and sufficiently important that users will likely
+   * want to be able to navigate to the section easily and to have it listed in
+   * a summary of the page.
+   */
+  const unsigned long ROLE_REGION = 173;
+
+  /**
+   * Represents a control with a text input and a popup with a set of predefined
+   * choices. It is used for ARIA's combobox role. See also ROLE_COMBOBOX.
+   */
+  const unsigned long ROLE_EDITCOMBOBOX = 174;
 };
--- a/accessible/interfaces/nsIAccessibleStates.idl
+++ b/accessible/interfaces/nsIAccessibleStates.idl
@@ -67,10 +67,11 @@ interface nsIAccessibleStates : nsISuppo
   const unsigned long  EXT_STATE_SINGLE_LINE             = 0x00000200;  // This text object can only contain 1 line of text    
   const unsigned long  EXT_STATE_TRANSIENT               = 0x00000400;  // 
   const unsigned long  EXT_STATE_VERTICAL                = 0x00000800;  // Especially used for sliders and scrollbars  
   const unsigned long  EXT_STATE_STALE                   = 0x00001000;  // Object not dead, but not up-to-date either
   const unsigned long  EXT_STATE_ENABLED                 = 0x00002000;  // A widget that is not unavailable
   const unsigned long  EXT_STATE_SENSITIVE               = 0x00004000;  // Same as ENABLED for now
   const unsigned long  EXT_STATE_EXPANDABLE              = 0x00008000;  // If COLLAPSED or EXPANDED
   const unsigned long  EXT_STATE_PINNED                  = 0x00010000;  // Indicates object is pinned.
+  const unsigned long  EXT_STATE_CURRENT                 = 0x00020000;  // Indicates object is the current item in its container
 };
 
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -618,36 +618,41 @@ DocAccessibleParent::MaybeInitWindowEmul
     nsIntRect rootRect = rootDocument->Bounds();
     rect.x = rootRect.x - rect.x;
     rect.y -= rootRect.y;
 
     auto tab = static_cast<dom::TabParent*>(Manager());
     tab->GetDocShellIsActive(&isActive);
   }
 
-  IAccessibleHolder hWndAccHolder;
-  HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
-  HWND hWnd = nsWinUtils::CreateNativeWindow(kClassNameTabContent,
-                                             parentWnd, rect.x, rect.y,
-                                             rect.width, rect.height,
-                                             isActive);
-  if (hWnd) {
-    // Attach accessible document to the emulated native window
-    ::SetPropW(hWnd, kPropNameDocAccParent, (HANDLE)this);
-    SetEmulatedWindowHandle(hWnd);
+  nsWinUtils::NativeWindowCreateProc onCreate([this](HWND aHwnd) -> void {
+    IAccessibleHolder hWndAccHolder;
+
+    ::SetPropW(aHwnd, kPropNameDocAccParent, reinterpret_cast<HANDLE>(this));
+
+    SetEmulatedWindowHandle(aHwnd);
+
     IAccessible* rawHWNDAcc = nullptr;
-    if (SUCCEEDED(::AccessibleObjectFromWindow(hWnd, OBJID_WINDOW,
+    if (SUCCEEDED(::AccessibleObjectFromWindow(aHwnd, OBJID_WINDOW,
                                                IID_IAccessible,
                                                (void**)&rawHWNDAcc))) {
       hWndAccHolder.Set(IAccessibleHolder::COMPtrType(rawHWNDAcc));
     }
-  }
+
+    Unused << SendEmulatedWindow(reinterpret_cast<uintptr_t>(mEmulatedWindowHandle),
+                                 hWndAccHolder);
+  });
 
-  Unused << SendEmulatedWindow(reinterpret_cast<uintptr_t>(mEmulatedWindowHandle),
-                               hWndAccHolder);
+  HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
+  DebugOnly<HWND> hWnd = nsWinUtils::CreateNativeWindow(kClassNameTabContent,
+                                                        parentWnd,
+                                                        rect.x, rect.y,
+                                                        rect.width, rect.height,
+                                                        isActive, &onCreate);
+  MOZ_ASSERT(hWnd);
 }
 
 /**
  * @param aCOMProxy COM Proxy to the document in the content process.
  */
 void
 DocAccessibleParent::SendParentCOMProxy()
 {
@@ -664,17 +669,23 @@ DocAccessibleParent::SendParentCOMProxy(
   }
 
   IAccessible* rawNative = nullptr;
   outerDoc->GetNativeInterface((void**) &rawNative);
   MOZ_ASSERT(rawNative);
 
   IAccessibleHolder::COMPtrType ptr(rawNative);
   IAccessibleHolder holder(Move(ptr));
-  Unused << PDocAccessibleParent::SendParentCOMProxy(holder);
+  if (!PDocAccessibleParent::SendParentCOMProxy(holder)) {
+    return;
+  }
+
+#if defined(MOZ_CONTENT_SANDBOX)
+  mParentProxyStream = Move(holder.GetPreservedStream());
+#endif // defined(MOZ_CONTENT_SANDBOX)
 }
 
 void
 DocAccessibleParent::SetEmulatedWindowHandle(HWND aWindowHandle)
 {
   if (!aWindowHandle && mEmulatedWindowHandle && IsTopLevel()) {
     ::DestroyWindow(mEmulatedWindowHandle);
   }
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -231,17 +231,21 @@ private:
   xpcAccessibleGeneric* GetXPCAccessible(ProxyAccessible* aProxy);
 
   nsTArray<uint64_t> mChildDocs;
   uint64_t mParentDoc;
 
 #if defined(XP_WIN)
   // The handle associated with the emulated window that contains this document
   HWND mEmulatedWindowHandle;
-#endif
+
+#if defined(MOZ_CONTENT_SANDBOX)
+  mscom::PreservedStreamPtr mParentProxyStream;
+#endif // defined(MOZ_CONTENT_SANDBOX)
+#endif // defined(XP_WIN)
 
   /*
    * Conceptually this is a map from IDs to proxies, but we store the ID in the
    * proxy object so we can't use a real map.
    */
   nsTHashtable<ProxyEntry> mAccessibles;
   uint64_t mActorID;
   bool mTopLevel;
--- a/accessible/ipc/other/ProxyAccessible.cpp
+++ b/accessible/ipc/other/ProxyAccessible.cpp
@@ -834,17 +834,17 @@ ProxyAccessible::GetSelectedItem(uint32_
 
 bool
 ProxyAccessible::IsItemSelected(uint32_t aIndex)
 {
   bool selected = false;
   Unused << mDoc->SendIsItemSelected(mID, aIndex, &selected);
   return selected;
 }
- 
+
 bool
 ProxyAccessible::AddItemToSelection(uint32_t aIndex)
 {
   bool success = false;
   Unused << mDoc->SendAddItemToSelection(mID, aIndex, &success);
   return success;
 }
 
--- a/accessible/ipc/win/HandlerProvider.cpp
+++ b/accessible/ipc/win/HandlerProvider.cpp
@@ -126,18 +126,20 @@ HandlerProvider::GetHandlerPayloadSize(N
     *aOutPayloadSize = mscom::StructToStream::GetEmptySize();
     return S_OK;
   }
 
   MutexAutoLock lock(mMutex);
 
   GetAndSerializePayload(lock);
 
-  if (!mSerializer) {
-    return E_FAIL;
+  if (!mSerializer || !(*mSerializer)) {
+    // Failed payload serialization is non-fatal
+    *aOutPayloadSize = mscom::StructToStream::GetEmptySize();
+    return S_OK;
   }
 
   *aOutPayloadSize = mSerializer->GetSize();
   return S_OK;
 }
 
 void
 HandlerProvider::BuildIA2Data(IA2Data* aOutIA2Data)
@@ -171,17 +173,18 @@ HandlerProvider::IsTargetInterfaceCachea
   return MarshalAs(mTargetUnkIid) == NEWEST_IA2_IID;
 }
 
 HRESULT
 HandlerProvider::WriteHandlerPayload(NotNull<IStream*> aStream)
 {
   MutexAutoLock lock(mMutex);
 
-  if (!mSerializer) {
+  if (!mSerializer || !(*mSerializer)) {
+    // Failed payload serialization is non-fatal
     mscom::StructToStream emptyStruct;
     return emptyStruct.Write(aStream);
   }
 
   HRESULT hr = mSerializer->Write(aStream);
 
   mSerializer.reset();
 
new file mode 100644
--- /dev/null
+++ b/accessible/ipc/win/IAccessible32.manifest
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <assemblyIdentity type="win32" name="Mozilla.Firefox.xul" version="1.0.0.0" />
+  <file name="xul.dll" />
+  <comInterfaceExternalProxyStub
+      iid="{618736E0-3C3D-11CF-810C-00AA00389B71}"
+      proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
+      name="IAccessible"
+      tlbid="{1EA4DBF0-3C3B-11CF-810C-00AA00389B71}"
+  />
+</assembly>
new file mode 100644
--- /dev/null
+++ b/accessible/ipc/win/IAccessible64.manifest
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <assemblyIdentity type="win32" name="Mozilla.Firefox.xul" version="1.0.0.0" />
+  <file name="xul.dll" />
+  <comInterfaceExternalProxyStub
+      iid="{618736E0-3C3D-11CF-810C-00AA00389B71}"
+      proxyStubClsid32="{03022430-ABC4-11D0-BDE2-00AA001A1953}"
+      name="IAccessible"
+  />
+</assembly>
--- a/accessible/ipc/win/PlatformChild.cpp
+++ b/accessible/ipc/win/PlatformChild.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=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/. */
 
+#include "mozilla/a11y/Compatibility.h"
 #include "mozilla/a11y/PlatformChild.h"
 #include "mozilla/mscom/EnsureMTA.h"
 #include "mozilla/mscom/InterceptorLog.h"
 
 #include "Accessible2.h"
 #include "Accessible2_2.h"
 #include "AccessibleHypertext2.h"
 #include "AccessibleTableCell.h"
@@ -43,16 +44,24 @@ static const mozilla::mscom::ArrayData s
 // we intend to instantiate them. Therefore RegisterProxy() must be called
 // via EnsureMTA.
 PlatformChild::PlatformChild()
   : mAccTypelib(mozilla::mscom::RegisterTypelib(L"oleacc.dll",
         mozilla::mscom::RegistrationFlags::eUseSystemDirectory))
   , mMiscTypelib(mozilla::mscom::RegisterTypelib(L"Accessible.tlb"))
   , mSdnTypelib(mozilla::mscom::RegisterTypelib(L"AccessibleMarshal.dll"))
 {
+  WORD actCtxResourceId = Compatibility::GetActCtxResourceId();
+
+  mozilla::mscom::MTADeletePtr<mozilla::mscom::ActivationContextRegion> tmpActCtxMTA;
+  mozilla::mscom::EnsureMTA([actCtxResourceId, &tmpActCtxMTA]() -> void {
+    tmpActCtxMTA.reset(new mozilla::mscom::ActivationContextRegion(actCtxResourceId));
+  });
+  mActCtxMTA = Move(tmpActCtxMTA);
+
   mozilla::mscom::InterceptorLog::Init();
   mozilla::mscom::RegisterArrayData(sPlatformChildArrayData);
 
 
   UniquePtr<mozilla::mscom::RegisteredProxy> customProxy;
   mozilla::mscom::EnsureMTA([&customProxy]() -> void {
     customProxy = Move(mozilla::mscom::RegisterProxy());
   });
--- a/accessible/ipc/win/PlatformChild.h
+++ b/accessible/ipc/win/PlatformChild.h
@@ -2,32 +2,35 @@
 /* vim: set ts=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/. */
 
 #ifndef mozilla_a11y_PlatformChild_h
 #define mozilla_a11y_PlatformChild_h
 
+#include "mozilla/mscom/ActivationContext.h"
+#include "mozilla/mscom/Ptr.h"
 #include "mozilla/mscom/Registration.h"
 
 namespace mozilla {
 namespace a11y {
 
 class PlatformChild
 {
 public:
   PlatformChild();
 
   PlatformChild(PlatformChild&) = delete;
   PlatformChild(PlatformChild&&) = delete;
   PlatformChild& operator=(PlatformChild&) = delete;
   PlatformChild& operator=(PlatformChild&&) = delete;
 
 private:
+  mscom::MTADeletePtr<mozilla::mscom::ActivationContextRegion> mActCtxMTA;
   UniquePtr<mozilla::mscom::RegisteredProxy> mCustomProxy;
   UniquePtr<mozilla::mscom::RegisteredProxy> mIA2Proxy;
   UniquePtr<mozilla::mscom::RegisteredProxy> mAccTypelib;
   UniquePtr<mozilla::mscom::RegisteredProxy> mMiscTypelib;
   UniquePtr<mozilla::mscom::RegisteredProxy> mSdnTypelib;
 };
 
 } // namespace mozilla
--- a/accessible/ipc/win/handler/AccessibleHandler.cpp
+++ b/accessible/ipc/win/handler/AccessibleHandler.cpp
@@ -217,27 +217,22 @@ AccessibleHandler::ReadHandlerPayload(IS
   if (!deserializer.Read(&mCachedData, &IA2Payload_Decode)) {
     return E_FAIL;
   }
 
   if (!mCachedData.mGeckoBackChannel) {
     return S_OK;
   }
 
-  long pid = static_cast<long>(::GetCurrentProcessId());
-
-  RefPtr<IHandlerControl> ctl;
-  HRESULT hr = gControlFactory.CreateInstance(nullptr, IID_IHandlerControl,
-                                              getter_AddRefs(ctl));
-  if (SUCCEEDED(hr)) {
-    hr = mCachedData.mGeckoBackChannel->put_HandlerControl(pid, ctl);
-    MOZ_ASSERT(SUCCEEDED(hr));
+  RefPtr<AccessibleHandlerControl> ctl(gControlFactory.GetOrCreateSingleton());
+  if (!ctl) {
+    return E_OUTOFMEMORY;
   }
 
-  return hr;
+  return ctl->Register(WrapNotNull(mCachedData.mGeckoBackChannel));
 }
 
 REFIID
 AccessibleHandler::MarshalAs(REFIID aIid)
 {
   static_assert(&NEWEST_IA2_IID == &IID_IAccessible2_3,
                 "You have modified NEWEST_IA2_IID. This code needs updating.");
   if (aIid == IID_IAccessible2_3 || aIid == IID_IAccessible2_2 ||
--- a/accessible/ipc/win/handler/AccessibleHandlerControl.cpp
+++ b/accessible/ipc/win/handler/AccessibleHandlerControl.cpp
@@ -127,17 +127,18 @@ AccessibleHandlerControl::Create(Accessi
   }
 
   RefPtr<AccessibleHandlerControl> ctl(new AccessibleHandlerControl());
   ctl.forget(aOutObject);
   return S_OK;
 }
 
 AccessibleHandlerControl::AccessibleHandlerControl()
-  : mCacheGen(0)
+  : mIsRegistered(false)
+  , mCacheGen(0)
   , mIA2Proxy(mscom::RegisterProxy(L"ia2marshal.dll"))
   , mHandlerProxy(mscom::RegisterProxy())
 {
   MOZ_ASSERT(mIA2Proxy);
 }
 
 IMPL_IUNKNOWN1(AccessibleHandlerControl, IHandlerControl)
 
@@ -184,10 +185,24 @@ AccessibleHandlerControl::GetHandlerType
   if (!mHandlerProxy) {
     return E_UNEXPECTED;
   }
 
   return mHandlerProxy->GetTypeInfoForGuid(CLSID_AccessibleHandler,
                                            aOutTypeInfo);
 }
 
+HRESULT
+AccessibleHandlerControl::Register(NotNull<IGeckoBackChannel*> aGecko)
+{
+  if (mIsRegistered) {
+    return S_OK;
+  }
+
+  long pid = static_cast<long>(::GetCurrentProcessId());
+  HRESULT hr = aGecko->put_HandlerControl(pid, this);
+  mIsRegistered = SUCCEEDED(hr);
+  MOZ_ASSERT(mIsRegistered);
+  return hr;
+}
+
 } // namespace a11y
 } // namespace mozilla
--- a/accessible/ipc/win/handler/AccessibleHandlerControl.h
+++ b/accessible/ipc/win/handler/AccessibleHandlerControl.h
@@ -66,20 +66,23 @@ public:
     return mCacheGen;
   }
 
   HRESULT GetNewText(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutNewText);
   HRESULT GetOldText(long aIA2UniqueId, NotNull<IA2TextSegment*> aOutOldText);
 
   HRESULT GetHandlerTypeInfo(ITypeInfo** aOutTypeInfo);
 
+  HRESULT Register(NotNull<IGeckoBackChannel*> aGecko);
+
 private:
   AccessibleHandlerControl();
   ~AccessibleHandlerControl() = default;
 
+  bool mIsRegistered;
   uint32_t mCacheGen;
   detail::TextChange mTextChange;
   UniquePtr<mscom::RegisteredProxy> mIA2Proxy;
   UniquePtr<mscom::RegisteredProxy> mHandlerProxy;
 };
 
 extern mscom::SingletonFactory<AccessibleHandlerControl> gControlFactory;
 
--- a/accessible/ipc/win/moz.build
+++ b/accessible/ipc/win/moz.build
@@ -8,19 +8,31 @@ if CONFIG['COMPILE_ENVIRONMENT'] and CON
     DIRS += [
         'handler',
         'typelib',
     ]
 
 # With --disable-accessibility, we need to compile PDocAccessible.ipdl (which
 # also depends on COMPtrTypes.h), but not the C++.
 IPDL_SOURCES += ['PDocAccessible.ipdl']
-EXPORTS.mozilla.a11y += ['COMPtrTypes.h']
+
+EXPORTS.mozilla.a11y += [
+    'COMPtrTypes.h',
+]
 
 if CONFIG['ACCESSIBILITY']:
+    if not CONFIG['HAVE_64BIT_BUILD']:
+        EXPORTS += [
+            'IAccessible32.manifest',
+        ]
+
+    EXPORTS += [
+        'IAccessible64.manifest',
+    ]
+
     EXPORTS.mozilla.a11y += [
         'DocAccessibleChild.h',
         'HandlerProvider.h',
         'PlatformChild.h',
         'ProxyAccessible.h'
     ]
 
     SOURCES += [
--- a/accessible/jsat/AccessFu.jsm
+++ b/accessible/jsat/AccessFu.jsm
@@ -1,65 +1,65 @@
 /* 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/. */
 
 /* exported AccessFu */
 
-'use strict';
+"use strict";
 
 const {utils: Cu, interfaces: Ci} = Components;
 
-this.EXPORTED_SYMBOLS = ['AccessFu']; // jshint ignore:line
+this.EXPORTED_SYMBOLS = ["AccessFu"]; // jshint ignore:line
 
-Cu.import('resource://gre/modules/Services.jsm');
-Cu.import('resource://gre/modules/accessibility/Utils.jsm');
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/accessibility/Utils.jsm");
 
-if (Utils.MozBuildApp === 'mobile/android') {
-  Cu.import('resource://gre/modules/Messaging.jsm');
+if (Utils.MozBuildApp === "mobile/android") {
+  Cu.import("resource://gre/modules/Messaging.jsm");
 }
 
 const ACCESSFU_DISABLE = 0; // jshint ignore:line
 const ACCESSFU_ENABLE = 1;
 const ACCESSFU_AUTO = 2;
 
-const SCREENREADER_SETTING = 'accessibility.screenreader';
-const QUICKNAV_MODES_PREF = 'accessibility.accessfu.quicknav_modes';
-const QUICKNAV_INDEX_PREF = 'accessibility.accessfu.quicknav_index';
+const SCREENREADER_SETTING = "accessibility.screenreader";
+const QUICKNAV_MODES_PREF = "accessibility.accessfu.quicknav_modes";
+const QUICKNAV_INDEX_PREF = "accessibility.accessfu.quicknav_index";
 
 this.AccessFu = { // jshint ignore:line
   /**
    * Initialize chrome-layer accessibility functionality.
    * If accessibility is enabled on the platform, then a special accessibility
    * mode is started.
    */
   attach: function attach(aWindow) {
     Utils.init(aWindow);
 
-    if (Utils.MozBuildApp === 'mobile/android') {
-      EventDispatcher.instance.dispatch('Accessibility:Ready');
-      EventDispatcher.instance.registerListener(this, 'Accessibility:Settings');
+    if (Utils.MozBuildApp === "mobile/android") {
+      EventDispatcher.instance.dispatch("Accessibility:Ready");
+      EventDispatcher.instance.registerListener(this, "Accessibility:Settings");
     }
 
     this._activatePref = new PrefCache(
-      'accessibility.accessfu.activate', this._enableOrDisable.bind(this));
+      "accessibility.accessfu.activate", this._enableOrDisable.bind(this));
 
     this._enableOrDisable();
   },
 
   /**
    * Shut down chrome-layer accessibility functionality from the outside.
    */
   detach: function detach() {
     // Avoid disabling twice.
     if (this._enabled) {
       this._disable();
     }
-    if (Utils.MozBuildApp === 'mobile/android') {
-      EventDispatcher.instance.unregisterListener(this, 'Accessibility:Settings');
+    if (Utils.MozBuildApp === "mobile/android") {
+      EventDispatcher.instance.unregisterListener(this, "Accessibility:Settings");
     }
     delete this._activatePref;
     Utils.uninit();
   },
 
   /**
    * A lazy getter for event handler that binds the scope to AccessFu object.
    */
@@ -74,29 +74,29 @@ this.AccessFu = { // jshint ignore:line
    * with arrow keys.
    */
   _enable: function _enable() {
     if (this._enabled) {
       return;
     }
     this._enabled = true;
 
-    Cu.import('resource://gre/modules/accessibility/Utils.jsm');
-    Cu.import('resource://gre/modules/accessibility/PointerAdapter.jsm');
-    Cu.import('resource://gre/modules/accessibility/Presentation.jsm');
+    Cu.import("resource://gre/modules/accessibility/Utils.jsm");
+    Cu.import("resource://gre/modules/accessibility/PointerAdapter.jsm");
+    Cu.import("resource://gre/modules/accessibility/Presentation.jsm");
 
     for (let mm of Utils.AllMessageManagers) {
       this._addMessageListeners(mm);
       this._loadFrameScript(mm);
     }
 
     // Add stylesheet
-    let stylesheetURL = 'chrome://global/content/accessibility/AccessFu.css';
+    let stylesheetURL = "chrome://global/content/accessibility/AccessFu.css";
     let stylesheet = Utils.win.document.createProcessingInstruction(
-      'xml-stylesheet', 'href="' + stylesheetURL + '" type="text/css"');
+      "xml-stylesheet", `href="${stylesheetURL}" type="text/css"`);
     Utils.win.document.insertBefore(stylesheet, Utils.win.document.firstChild);
     this.stylesheet = Cu.getWeakReference(stylesheet);
 
 
     // Populate quicknav modes
     this._quicknavModesPref =
       new PrefCache(QUICKNAV_MODES_PREF, (aName, aValue, aFirstRun) => {
         this.Input.quickNavMode.updateModes(aValue);
@@ -108,139 +108,139 @@ this.AccessFu = { // jshint ignore:line
 
     this._quicknavCurrentModePref =
       new PrefCache(QUICKNAV_INDEX_PREF, (aName, aValue) => {
         this.Input.quickNavMode.updateCurrentMode(Number(aValue));
       }, true);
 
     // Check for output notification
     this._notifyOutputPref =
-      new PrefCache('accessibility.accessfu.notify_output');
+      new PrefCache("accessibility.accessfu.notify_output");
 
 
     this.Input.start();
     Output.start();
     PointerAdapter.start();
 
-    if (Utils.MozBuildApp === 'mobile/android') {
+    if (Utils.MozBuildApp === "mobile/android") {
       EventDispatcher.instance.registerListener(this, [
-        'Accessibility:ActivateObject',
-        'Accessibility:Focus',
-        'Accessibility:LongPress',
-        'Accessibility:MoveByGranularity',
-        'Accessibility:NextObject',
-        'Accessibility:PreviousObject',
-        'Accessibility:ScrollBackward',
-        'Accessibility:ScrollForward',
+        "Accessibility:ActivateObject",
+        "Accessibility:Focus",
+        "Accessibility:LongPress",
+        "Accessibility:MoveByGranularity",
+        "Accessibility:NextObject",
+        "Accessibility:PreviousObject",
+        "Accessibility:ScrollBackward",
+        "Accessibility:ScrollForward",
       ]);
     }
 
-    Services.obs.addObserver(this, 'remote-browser-shown');
-    Services.obs.addObserver(this, 'inprocess-browser-shown');
-    Utils.win.addEventListener('TabOpen', this);
-    Utils.win.addEventListener('TabClose', this);
-    Utils.win.addEventListener('TabSelect', this);
+    Services.obs.addObserver(this, "remote-browser-shown");
+    Services.obs.addObserver(this, "inprocess-browser-shown");
+    Utils.win.addEventListener("TabOpen", this);
+    Utils.win.addEventListener("TabClose", this);
+    Utils.win.addEventListener("TabSelect", this);
 
     if (this.readyCallback) {
       this.readyCallback();
       delete this.readyCallback;
     }
 
-    Logger.info('AccessFu:Enabled');
+    Logger.info("AccessFu:Enabled");
   },
 
   /**
    * Disable AccessFu and return to default interaction mode.
    */
   _disable: function _disable() {
     if (!this._enabled) {
       return;
     }
 
     this._enabled = false;
 
     Utils.win.document.removeChild(this.stylesheet.get());
 
     for (let mm of Utils.AllMessageManagers) {
-      mm.sendAsyncMessage('AccessFu:Stop');
+      mm.sendAsyncMessage("AccessFu:Stop");
       this._removeMessageListeners(mm);
     }
 
     this.Input.stop();
     Output.stop();
     PointerAdapter.stop();
 
-    Utils.win.removeEventListener('TabOpen', this);
-    Utils.win.removeEventListener('TabClose', this);
-    Utils.win.removeEventListener('TabSelect', this);
+    Utils.win.removeEventListener("TabOpen", this);
+    Utils.win.removeEventListener("TabClose", this);
+    Utils.win.removeEventListener("TabSelect", this);
 
-    Services.obs.removeObserver(this, 'remote-browser-shown');
-    Services.obs.removeObserver(this, 'inprocess-browser-shown');
+    Services.obs.removeObserver(this, "remote-browser-shown");
+    Services.obs.removeObserver(this, "inprocess-browser-shown");
 
-    if (Utils.MozBuildApp === 'mobile/android') {
+    if (Utils.MozBuildApp === "mobile/android") {
       EventDispatcher.instance.unregisterListener(this, [
-        'Accessibility:ActivateObject',
-        'Accessibility:Focus',
-        'Accessibility:LongPress',
-        'Accessibility:MoveByGranularity',
-        'Accessibility:NextObject',
-        'Accessibility:PreviousObject',
-        'Accessibility:ScrollBackward',
-        'Accessibility:ScrollForward',
+        "Accessibility:ActivateObject",
+        "Accessibility:Focus",
+        "Accessibility:LongPress",
+        "Accessibility:MoveByGranularity",
+        "Accessibility:NextObject",
+        "Accessibility:PreviousObject",
+        "Accessibility:ScrollBackward",
+        "Accessibility:ScrollForward",
       ]);
     }
 
     delete this._quicknavModesPref;
     delete this._notifyOutputPref;
 
     if (this.doneCallback) {
       this.doneCallback();
       delete this.doneCallback;
     }
 
-    Logger.info('AccessFu:Disabled');
+    Logger.info("AccessFu:Disabled");
   },
 
   _enableOrDisable: function _enableOrDisable() {
     try {
       if (!this._activatePref) {
         return;
       }
       let activatePref = this._activatePref.value;
       if (activatePref == ACCESSFU_ENABLE ||
           this._systemPref && activatePref == ACCESSFU_AUTO) {
         this._enable();
       } else {
         this._disable();
       }
     } catch (x) {
-      dump('Error ' + x.message + ' ' + x.fileName + ':' + x.lineNumber);
+      dump("Error " + x.message + " " + x.fileName + ":" + x.lineNumber);
     }
   },
 
   receiveMessage: function receiveMessage(aMessage) {
     Logger.debug(() => {
-      return ['Recieved', aMessage.name, JSON.stringify(aMessage.json)];
+      return ["Recieved", aMessage.name, JSON.stringify(aMessage.json)];
     });
 
     switch (aMessage.name) {
-      case 'AccessFu:Ready':
+      case "AccessFu:Ready":
         let mm = Utils.getMessageManager(aMessage.target);
         if (this._enabled) {
-          mm.sendAsyncMessage('AccessFu:Start',
-                              {method: 'start', buildApp: Utils.MozBuildApp});
+          mm.sendAsyncMessage("AccessFu:Start",
+                              {method: "start", buildApp: Utils.MozBuildApp});
         }
         break;
-      case 'AccessFu:Present':
+      case "AccessFu:Present":
         this._output(aMessage.json, aMessage.target);
         break;
-      case 'AccessFu:Input':
+      case "AccessFu:Input":
         this.Input.setEditState(aMessage.json);
         break;
-      case 'AccessFu:DoScroll':
+      case "AccessFu:DoScroll":
         this.Input.doScroll(aMessage.json);
         break;
     }
   },
 
   _output: function _output(aPresentationData, aBrowser) {
     if (!Utils.isAliveAndVisible(
       Utils.AccService.getAccessibleFor(aBrowser))) {
@@ -254,139 +254,139 @@ this.AccessFu = { // jshint ignore:line
       try {
         Output[presenter.type](presenter.details, aBrowser);
       } catch (x) {
         Logger.logException(x);
       }
     }
 
     if (this._notifyOutputPref.value) {
-      Services.obs.notifyObservers(null, 'accessibility-output',
+      Services.obs.notifyObservers(null, "accessibility-output",
                                    JSON.stringify(aPresentationData));
     }
   },
 
   _loadFrameScript: function _loadFrameScript(aMessageManager) {
     if (this._processedMessageManagers.indexOf(aMessageManager) < 0) {
       aMessageManager.loadFrameScript(
-        'chrome://global/content/accessibility/content-script.js', true);
+        "chrome://global/content/accessibility/content-script.js", true);
       this._processedMessageManagers.push(aMessageManager);
     } else if (this._enabled) {
       // If the content-script is already loaded and AccessFu is enabled,
       // send an AccessFu:Start message.
-      aMessageManager.sendAsyncMessage('AccessFu:Start',
-        {method: 'start', buildApp: Utils.MozBuildApp});
+      aMessageManager.sendAsyncMessage("AccessFu:Start",
+        {method: "start", buildApp: Utils.MozBuildApp});
     }
   },
 
   _addMessageListeners: function _addMessageListeners(aMessageManager) {
-    aMessageManager.addMessageListener('AccessFu:Present', this);
-    aMessageManager.addMessageListener('AccessFu:Input', this);
-    aMessageManager.addMessageListener('AccessFu:Ready', this);
-    aMessageManager.addMessageListener('AccessFu:DoScroll', this);
+    aMessageManager.addMessageListener("AccessFu:Present", this);
+    aMessageManager.addMessageListener("AccessFu:Input", this);
+    aMessageManager.addMessageListener("AccessFu:Ready", this);
+    aMessageManager.addMessageListener("AccessFu:DoScroll", this);
   },
 
   _removeMessageListeners: function _removeMessageListeners(aMessageManager) {
-    aMessageManager.removeMessageListener('AccessFu:Present', this);
-    aMessageManager.removeMessageListener('AccessFu:Input', this);
-    aMessageManager.removeMessageListener('AccessFu:Ready', this);
-    aMessageManager.removeMessageListener('AccessFu:DoScroll', this);
+    aMessageManager.removeMessageListener("AccessFu:Present", this);
+    aMessageManager.removeMessageListener("AccessFu:Input", this);
+    aMessageManager.removeMessageListener("AccessFu:Ready", this);
+    aMessageManager.removeMessageListener("AccessFu:DoScroll", this);
   },
 
   _handleMessageManager: function _handleMessageManager(aMessageManager) {
     if (this._enabled) {
       this._addMessageListeners(aMessageManager);
     }
     this._loadFrameScript(aMessageManager);
   },
 
-  onEvent: function (event, data, callback) {
+  onEvent: function(event, data, callback) {
     switch (event) {
-      case 'Accessibility:Settings':
+      case "Accessibility:Settings":
         this._systemPref = data.enabled;
         this._enableOrDisable();
         break;
-      case 'Accessibility:NextObject':
-      case 'Accessibility:PreviousObject': {
+      case "Accessibility:NextObject":
+      case "Accessibility:PreviousObject": {
         let rule = data ?
           data.rule.substr(0, 1).toUpperCase() + data.rule.substr(1).toLowerCase() :
-          'Simple';
-        let method = event.replace(/Accessibility:(\w+)Object/, 'move$1');
-        this.Input.moveCursor(method, rule, 'gesture');
+          "Simple";
+        let method = event.replace(/Accessibility:(\w+)Object/, "move$1");
+        this.Input.moveCursor(method, rule, "gesture");
         break;
       }
-      case 'Accessibility:ActivateObject':
+      case "Accessibility:ActivateObject":
         this.Input.activateCurrent(data);
         break;
-      case 'Accessibility:LongPress':
+      case "Accessibility:LongPress":
         this.Input.sendContextMenuMessage();
         break;
-      case 'Accessibility:ScrollForward':
-        this.Input.androidScroll('forward');
+      case "Accessibility:ScrollForward":
+        this.Input.androidScroll("forward");
         break;
-      case 'Accessibility:ScrollBackward':
-        this.Input.androidScroll('backward');
+      case "Accessibility:ScrollBackward":
+        this.Input.androidScroll("backward");
         break;
-      case 'Accessibility:Focus':
+      case "Accessibility:Focus":
         this._focused = data.gainFocus;
         if (this._focused) {
           this.autoMove({ forcePresent: true, noOpIfOnScreen: true });
         }
         break;
-      case 'Accessibility:MoveByGranularity':
+      case "Accessibility:MoveByGranularity":
         this.Input.moveByGranularity(data);
         break;
     }
   },
 
   observe: function observe(aSubject, aTopic, aData) {
     switch (aTopic) {
-      case 'remote-browser-shown':
-      case 'inprocess-browser-shown':
+      case "remote-browser-shown":
+      case "inprocess-browser-shown":
       {
         // Ignore notifications that aren't from a Browser
         let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
         if (!frameLoader.ownerIsMozBrowserFrame) {
           return;
         }
         this._handleMessageManager(frameLoader.messageManager);
         break;
       }
     }
   },
 
   _handleEvent: function _handleEvent(aEvent) {
     switch (aEvent.type) {
-      case 'TabOpen':
+      case "TabOpen":
       {
         let mm = Utils.getMessageManager(aEvent.target);
         this._handleMessageManager(mm);
         break;
       }
-      case 'TabClose':
+      case "TabClose":
       {
         let mm = Utils.getMessageManager(aEvent.target);
         let mmIndex = this._processedMessageManagers.indexOf(mm);
         if (mmIndex > -1) {
           this._removeMessageListeners(mm);
           this._processedMessageManagers.splice(mmIndex, 1);
         }
         break;
       }
-      case 'TabSelect':
+      case "TabSelect":
       {
         if (this._focused) {
           // We delay this for half a second so the awesomebar could close,
           // and we could use the current coordinates for the content item.
           // XXX TODO figure out how to avoid magic wait here.
-	  this.autoMove({
-	    delay: 500,
-	    forcePresent: true,
-	    noOpIfOnScreen: true,
-	    moveMethod: 'moveFirst' });
+          this.autoMove({
+            delay: 500,
+            forcePresent: true,
+            noOpIfOnScreen: true,
+            moveMethod: "moveFirst" });
         }
         break;
       }
       default:
       {
         // A settings change, it does not have an event type
         if (aEvent.settingName == SCREENREADER_SETTING) {
           this._systemPref = aEvent.settingValue;
@@ -394,17 +394,17 @@ this.AccessFu = { // jshint ignore:line
         }
         break;
       }
     }
   },
 
   autoMove: function autoMove(aOptions) {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
-    mm.sendAsyncMessage('AccessFu:AutoMove', aOptions);
+    mm.sendAsyncMessage("AccessFu:AutoMove", aOptions);
   },
 
   announce: function announce(aAnnouncement) {
     this._output(Presentation.announce(aAnnouncement), Utils.CurrentBrowser);
   },
 
   // So we don't enable/disable twice
   _enabled: false,
@@ -445,61 +445,61 @@ this.AccessFu = { // jshint ignore:line
       return bounds.expandToIntegers();
     }
 };
 
 var Output = {
   brailleState: {
     startOffset: 0,
     endOffset: 0,
-    text: '',
+    text: "",
     selectionStart: 0,
     selectionEnd: 0,
 
     init: function init(aOutput) {
-      if (aOutput && 'output' in aOutput) {
+      if (aOutput && "output" in aOutput) {
         this.startOffset = aOutput.startOffset;
         this.endOffset = aOutput.endOffset;
         // We need to append a space at the end so that the routing key
         // corresponding to the end of the output (i.e. the space) can be hit to
         // move the caret there.
-        this.text = aOutput.output + ' ';
-        this.selectionStart = typeof aOutput.selectionStart === 'number' ?
+        this.text = aOutput.output + " ";
+        this.selectionStart = typeof aOutput.selectionStart === "number" ?
                               aOutput.selectionStart : this.selectionStart;
-        this.selectionEnd = typeof aOutput.selectionEnd === 'number' ?
+        this.selectionEnd = typeof aOutput.selectionEnd === "number" ?
                             aOutput.selectionEnd : this.selectionEnd;
 
         return { text: this.text,
                  selectionStart: this.selectionStart,
                  selectionEnd: this.selectionEnd };
       }
 
       return null;
     },
 
     adjustText: function adjustText(aText) {
       let newBraille = [];
       let braille = {};
 
       let prefix = this.text.substring(0, this.startOffset).trim();
       if (prefix) {
-        prefix += ' ';
+        prefix += " ";
         newBraille.push(prefix);
       }
 
       newBraille.push(aText);
 
       let suffix = this.text.substring(this.endOffset).trim();
       if (suffix) {
-        suffix = ' ' + suffix;
+        suffix = " " + suffix;
         newBraille.push(suffix);
       }
 
       this.startOffset = braille.startOffset = prefix.length;
-      this.text = braille.text = newBraille.join('') + ' ';
+      this.text = braille.text = newBraille.join("") + " ";
       this.endOffset = braille.endOffset = braille.text.length - suffix.length;
       braille.selectionStart = this.selectionStart;
       braille.selectionEnd = this.selectionEnd;
 
       return braille;
     },
 
     adjustSelection: function adjustSelection(aSelection) {
@@ -513,93 +513,93 @@ var Output = {
       this.selectionEnd = braille.selectionEnd =
         aSelection.selectionEnd + this.startOffset;
 
       return braille;
     }
   },
 
   start: function start() {
-    Cu.import('resource://gre/modules/Geometry.jsm');
+    Cu.import("resource://gre/modules/Geometry.jsm");
   },
 
   stop: function stop() {
     if (this.highlightBox) {
       let highlightBox = this.highlightBox.get();
       if (highlightBox) {
         highlightBox.remove();
       }
       delete this.highlightBox;
     }
   },
 
   B2G: function B2G(aDetails) {
-    Utils.dispatchChromeEvent('accessibility-output', aDetails);
+    Utils.dispatchChromeEvent("accessibility-output", aDetails);
   },
 
   Visual: function Visual(aDetail, aBrowser) {
     switch (aDetail.eventType) {
-      case 'viewport-change':
-      case 'vc-change':
+      case "viewport-change":
+      case "vc-change":
       {
         let highlightBox = null;
         if (!this.highlightBox) {
           let doc = Utils.win.document;
           // Add highlight box
           highlightBox = Utils.win.document.
-            createElementNS('http://www.w3.org/1999/xhtml', 'div');
+            createElementNS("http://www.w3.org/1999/xhtml", "div");
           let parent = doc.body || doc.documentElement;
           parent.appendChild(highlightBox);
-          highlightBox.id = 'virtual-cursor-box';
+          highlightBox.id = "virtual-cursor-box";
 
           // Add highlight inset for inner shadow
           highlightBox.appendChild(
-            doc.createElementNS('http://www.w3.org/1999/xhtml', 'div'));
+            doc.createElementNS("http://www.w3.org/1999/xhtml", "div"));
 
           this.highlightBox = Cu.getWeakReference(highlightBox);
         } else {
           highlightBox = this.highlightBox.get();
         }
 
         let padding = aDetail.padding;
         let r = AccessFu.adjustContentBounds(aDetail.bounds, aBrowser, true);
 
         // First hide it to avoid flickering when changing the style.
-        highlightBox.classList.remove('show');
-        highlightBox.style.top = (r.top - padding) + 'px';
-        highlightBox.style.left = (r.left - padding) + 'px';
-        highlightBox.style.width = (r.width + padding*2) + 'px';
-        highlightBox.style.height = (r.height + padding*2) + 'px';
-        highlightBox.classList.add('show');
+        highlightBox.classList.remove("show");
+        highlightBox.style.top = (r.top - padding) + "px";
+        highlightBox.style.left = (r.left - padding) + "px";
+        highlightBox.style.width = (r.width + padding * 2) + "px";
+        highlightBox.style.height = (r.height + padding * 2) + "px";
+        highlightBox.classList.add("show");
 
         break;
       }
-      case 'tabstate-change':
+      case "tabstate-change":
       {
         let highlightBox = this.highlightBox ? this.highlightBox.get() : null;
         if (highlightBox) {
-          highlightBox.classList.remove('show');
+          highlightBox.classList.remove("show");
         }
         break;
       }
     }
   },
 
   Android: function Android(aDetails, aBrowser) {
     const ANDROID_VIEW_TEXT_CHANGED = 0x10;
     const ANDROID_VIEW_TEXT_SELECTION_CHANGED = 0x2000;
 
     for (let androidEvent of aDetails) {
-      androidEvent.type = 'Accessibility:Event';
+      androidEvent.type = "Accessibility:Event";
       if (androidEvent.bounds) {
         androidEvent.bounds = AccessFu.adjustContentBounds(
           androidEvent.bounds, aBrowser);
       }
 
-      switch(androidEvent.eventType) {
+      switch (androidEvent.eventType) {
         case ANDROID_VIEW_TEXT_CHANGED:
           androidEvent.brailleOutput = this.brailleState.adjustText(
             androidEvent.text);
           break;
         case ANDROID_VIEW_TEXT_SELECTION_CHANGED:
           androidEvent.brailleOutput = this.brailleState.adjustSelection(
             androidEvent.brailleOutput);
           break;
@@ -609,140 +609,140 @@ var Output = {
           break;
       }
 
       Utils.win.WindowEventDispatcher.sendRequest(androidEvent);
     }
   },
 
   Braille: function Braille(aDetails) {
-    Logger.debug('Braille output: ' + aDetails.output);
+    Logger.debug("Braille output: " + aDetails.output);
   }
 };
 
 var Input = {
   editState: {},
 
   start: function start() {
     // XXX: This is too disruptive on desktop for now.
     // Might need to add special modifiers.
-    if (Utils.MozBuildApp != 'browser') {
-      Utils.win.document.addEventListener('keypress', this, true);
+    if (Utils.MozBuildApp != "browser") {
+      Utils.win.document.addEventListener("keypress", this, true);
     }
-    Utils.win.addEventListener('mozAccessFuGesture', this, true);
+    Utils.win.addEventListener("mozAccessFuGesture", this, true);
   },
 
   stop: function stop() {
-    if (Utils.MozBuildApp != 'browser') {
-      Utils.win.document.removeEventListener('keypress', this, true);
+    if (Utils.MozBuildApp != "browser") {
+      Utils.win.document.removeEventListener("keypress", this, true);
     }
-    Utils.win.removeEventListener('mozAccessFuGesture', this, true);
+    Utils.win.removeEventListener("mozAccessFuGesture", this, true);
   },
 
   handleEvent: function Input_handleEvent(aEvent) {
     try {
       switch (aEvent.type) {
-      case 'keypress':
+      case "keypress":
         this._handleKeypress(aEvent);
         break;
-      case 'mozAccessFuGesture':
+      case "mozAccessFuGesture":
         this._handleGesture(aEvent.detail);
         break;
       }
     } catch (x) {
       Logger.logException(x);
     }
   },
 
   _handleGesture: function _handleGesture(aGesture) {
     let gestureName = aGesture.type + aGesture.touches.length;
-    Logger.debug('Gesture', aGesture.type,
-                 '(fingers: ' + aGesture.touches.length + ')');
+    Logger.debug("Gesture", aGesture.type,
+                 "(fingers: " + aGesture.touches.length + ")");
 
     switch (gestureName) {
-      case 'dwell1':
-      case 'explore1':
-        this.moveToPoint('Simple', aGesture.touches[0].x,
+      case "dwell1":
+      case "explore1":
+        this.moveToPoint("Simple", aGesture.touches[0].x,
           aGesture.touches[0].y);
         break;
-      case 'doubletap1':
+      case "doubletap1":
         this.activateCurrent();
         break;
-      case 'doubletaphold1':
-        Utils.dispatchChromeEvent('accessibility-control', 'quicknav-menu');
+      case "doubletaphold1":
+        Utils.dispatchChromeEvent("accessibility-control", "quicknav-menu");
         break;
-      case 'swiperight1':
-        this.moveCursor('moveNext', 'Simple', 'gestures');
+      case "swiperight1":
+        this.moveCursor("moveNext", "Simple", "gestures");
         break;
-      case 'swipeleft1':
-        this.moveCursor('movePrevious', 'Simple', 'gesture');
+      case "swipeleft1":
+        this.moveCursor("movePrevious", "Simple", "gesture");
         break;
-      case 'swipeup1':
+      case "swipeup1":
         this.moveCursor(
-          'movePrevious', this.quickNavMode.current, 'gesture', true);
+          "movePrevious", this.quickNavMode.current, "gesture", true);
         break;
-      case 'swipedown1':
-        this.moveCursor('moveNext', this.quickNavMode.current, 'gesture', true);
+      case "swipedown1":
+        this.moveCursor("moveNext", this.quickNavMode.current, "gesture", true);
         break;
-      case 'exploreend1':
-      case 'dwellend1':
+      case "exploreend1":
+      case "dwellend1":
         this.activateCurrent(null, true);
         break;
-      case 'swiperight2':
+      case "swiperight2":
         if (aGesture.edge) {
-          Utils.dispatchChromeEvent('accessibility-control',
-            'edge-swipe-right');
+          Utils.dispatchChromeEvent("accessibility-control",
+            "edge-swipe-right");
           break;
         }
         this.sendScrollMessage(-1, true);
         break;
-      case 'swipedown2':
+      case "swipedown2":
         if (aGesture.edge) {
-          Utils.dispatchChromeEvent('accessibility-control', 'edge-swipe-down');
+          Utils.dispatchChromeEvent("accessibility-control", "edge-swipe-down");
           break;
         }
         this.sendScrollMessage(-1);
         break;
-      case 'swipeleft2':
+      case "swipeleft2":
         if (aGesture.edge) {
-          Utils.dispatchChromeEvent('accessibility-control', 'edge-swipe-left');
+          Utils.dispatchChromeEvent("accessibility-control", "edge-swipe-left");
           break;
         }
         this.sendScrollMessage(1, true);
         break;
-      case 'swipeup2':
+      case "swipeup2":
         if (aGesture.edge) {
-          Utils.dispatchChromeEvent('accessibility-control', 'edge-swipe-up');
+          Utils.dispatchChromeEvent("accessibility-control", "edge-swipe-up");
           break;
         }
         this.sendScrollMessage(1);
         break;
-      case 'explore2':
+      case "explore2":
         Utils.CurrentBrowser.contentWindow.scrollBy(
           -aGesture.deltaX, -aGesture.deltaY);
         break;
-      case 'swiperight3':
-        this.moveCursor('moveNext', this.quickNavMode.current, 'gesture');
+      case "swiperight3":
+        this.moveCursor("moveNext", this.quickNavMode.current, "gesture");
         break;
-      case 'swipeleft3':
-        this.moveCursor('movePrevious', this.quickNavMode.current, 'gesture');
+      case "swipeleft3":
+        this.moveCursor("movePrevious", this.quickNavMode.current, "gesture");
         break;
-      case 'swipedown3':
+      case "swipedown3":
         this.quickNavMode.next();
-        AccessFu.announce('quicknav_' + this.quickNavMode.current);
+        AccessFu.announce("quicknav_" + this.quickNavMode.current);
         break;
-      case 'swipeup3':
+      case "swipeup3":
         this.quickNavMode.previous();
-        AccessFu.announce('quicknav_' + this.quickNavMode.current);
+        AccessFu.announce("quicknav_" + this.quickNavMode.current);
         break;
-      case 'tripletap3':
-        Utils.dispatchChromeEvent('accessibility-control', 'toggle-shade');
+      case "tripletap3":
+        Utils.dispatchChromeEvent("accessibility-control", "toggle-shade");
         break;
-      case 'tap2':
-        Utils.dispatchChromeEvent('accessibility-control', 'toggle-pause');
+      case "tap2":
+        Utils.dispatchChromeEvent("accessibility-control", "toggle-pause");
         break;
     }
   },
 
   _handleKeypress: function _handleKeypress(aEvent) {
     let target = aEvent.target;
 
     // Ignore keys with modifiers so the content could take advantage of them.
@@ -757,60 +757,60 @@ var Input = {
         // If it was pressed with meta, pass the key on without the meta.
         if (this.editState.editing) {
           return;
         }
 
         let key = String.fromCharCode(aEvent.charCode);
         try {
           let [methodName, rule] = this.keyMap[key];
-          this.moveCursor(methodName, rule, 'keyboard');
+          this.moveCursor(methodName, rule, "keyboard");
         } catch (x) {
           return;
         }
         break;
       case aEvent.DOM_VK_RIGHT:
         if (this.editState.editing) {
           if (!this.editState.atEnd) {
             // Don't move forward if caret is not at end of entry.
             // XXX: Fix for rtl
             return;
-          } else {
-            target.blur();
           }
+          target.blur();
+
         }
         this.moveCursor(aEvent.shiftKey ?
-          'moveLast' : 'moveNext', 'Simple', 'keyboard');
+          "moveLast" : "moveNext", "Simple", "keyboard");
         break;
       case aEvent.DOM_VK_LEFT:
         if (this.editState.editing) {
           if (!this.editState.atStart) {
             // Don't move backward if caret is not at start of entry.
             // XXX: Fix for rtl
             return;
-          } else {
-            target.blur();
           }
+          target.blur();
+
         }
         this.moveCursor(aEvent.shiftKey ?
-          'moveFirst' : 'movePrevious', 'Simple', 'keyboard');
+          "moveFirst" : "movePrevious", "Simple", "keyboard");
         break;
       case aEvent.DOM_VK_UP:
         if (this.editState.multiline) {
           if (!this.editState.atStart) {
             // Don't blur content if caret is not at start of text area.
             return;
-          } else {
-            target.blur();
           }
+          target.blur();
+
         }
 
-        if (Utils.MozBuildApp == 'mobile/android') {
+        if (Utils.MozBuildApp == "mobile/android") {
           // Return focus to native Android browser chrome.
-          Utils.win.WindowEventDispatcher.dispatch('ToggleChrome:Focus');
+          Utils.win.WindowEventDispatcher.dispatch("ToggleChrome:Focus");
         }
         break;
       case aEvent.DOM_VK_RETURN:
         if (this.editState.editing) {
           return;
         }
         this.activateCurrent();
         break;
@@ -821,137 +821,137 @@ var Input = {
     aEvent.preventDefault();
     aEvent.stopPropagation();
   },
 
   moveToPoint: function moveToPoint(aRule, aX, aY) {
     // XXX: Bug 1013408 - There is no alignment between the chrome window's
     // viewport size and the content viewport size in Android. This makes
     // sending mouse events beyond its bounds impossible.
-    if (Utils.MozBuildApp === 'mobile/android') {
+    if (Utils.MozBuildApp === "mobile/android") {
       let mm = Utils.getMessageManager(Utils.CurrentBrowser);
-      mm.sendAsyncMessage('AccessFu:MoveToPoint',
-        {rule: aRule, x: aX, y: aY, origin: 'top'});
+      mm.sendAsyncMessage("AccessFu:MoveToPoint",
+        {rule: aRule, x: aX, y: aY, origin: "top"});
     } else {
       let win = Utils.win;
-      Utils.winUtils.sendMouseEvent('mousemove',
+      Utils.winUtils.sendMouseEvent("mousemove",
         aX - win.mozInnerScreenX, aY - win.mozInnerScreenY, 0, 0, 0);
     }
   },
 
   moveCursor: function moveCursor(aAction, aRule, aInputType, aAdjustRange) {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
-    mm.sendAsyncMessage('AccessFu:MoveCursor',
+    mm.sendAsyncMessage("AccessFu:MoveCursor",
                         { action: aAction, rule: aRule,
-                          origin: 'top', inputType: aInputType,
+                          origin: "top", inputType: aInputType,
                           adjustRange: aAdjustRange });
   },
 
   androidScroll: function androidScroll(aDirection) {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
-    mm.sendAsyncMessage('AccessFu:AndroidScroll',
-                        { direction: aDirection, origin: 'top' });
+    mm.sendAsyncMessage("AccessFu:AndroidScroll",
+                        { direction: aDirection, origin: "top" });
   },
 
   moveByGranularity: function moveByGranularity(aDetails) {
     const GRANULARITY_PARAGRAPH = 8;
     const GRANULARITY_LINE = 4;
 
     if (!this.editState.editing) {
       if (aDetails.granularity & (GRANULARITY_PARAGRAPH | GRANULARITY_LINE)) {
-        this.moveCursor('move' + aDetails.direction, 'Simple', 'gesture');
+        this.moveCursor("move" + aDetails.direction, "Simple", "gesture");
         return;
       }
     } else {
       aDetails.atStart = this.editState.atStart;
       aDetails.atEnd = this.editState.atEnd;
     }
 
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
-    let type = this.editState.editing ? 'AccessFu:MoveCaret' :
-                                        'AccessFu:MoveByGranularity';
+    let type = this.editState.editing ? "AccessFu:MoveCaret" :
+                                        "AccessFu:MoveByGranularity";
     mm.sendAsyncMessage(type, aDetails);
   },
 
   activateCurrent: function activateCurrent(aData, aActivateIfKey = false) {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
-    let offset = aData && typeof aData.keyIndex === 'number' ?
+    let offset = aData && typeof aData.keyIndex === "number" ?
                  aData.keyIndex - Output.brailleState.startOffset : -1;
 
-    mm.sendAsyncMessage('AccessFu:Activate',
+    mm.sendAsyncMessage("AccessFu:Activate",
                         {offset: offset, activateIfKey: aActivateIfKey});
   },
 
   sendContextMenuMessage: function sendContextMenuMessage() {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
-    mm.sendAsyncMessage('AccessFu:ContextMenu', {});
+    mm.sendAsyncMessage("AccessFu:ContextMenu", {});
   },
 
   setEditState: function setEditState(aEditState) {
-    Logger.debug(() => { return ['setEditState', JSON.stringify(aEditState)] });
+    Logger.debug(() => { return ["setEditState", JSON.stringify(aEditState)] });
     this.editState = aEditState;
   },
 
   // XXX: This is here for backwards compatability with screen reader simulator
   // it should be removed when the extension is updated on amo.
   scroll: function scroll(aPage, aHorizontal) {
     this.sendScrollMessage(aPage, aHorizontal);
   },
 
   sendScrollMessage: function sendScrollMessage(aPage, aHorizontal) {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
-    mm.sendAsyncMessage('AccessFu:Scroll',
-      {page: aPage, horizontal: aHorizontal, origin: 'top'});
+    mm.sendAsyncMessage("AccessFu:Scroll",
+      {page: aPage, horizontal: aHorizontal, origin: "top"});
   },
 
   doScroll: function doScroll(aDetails) {
     let horizontal = aDetails.horizontal;
     let page = aDetails.page;
     let p = AccessFu.adjustContentBounds(
       aDetails.bounds, Utils.CurrentBrowser, true).center();
     Utils.winUtils.sendWheelEvent(p.x, p.y,
       horizontal ? page : 0, horizontal ? 0 : page, 0,
       Utils.win.WheelEvent.DOM_DELTA_PAGE, 0, 0, 0, 0);
   },
 
   get keyMap() {
     delete this.keyMap;
     this.keyMap = {
-      a: ['moveNext', 'Anchor'],
-      A: ['movePrevious', 'Anchor'],
-      b: ['moveNext', 'Button'],
-      B: ['movePrevious', 'Button'],
-      c: ['moveNext', 'Combobox'],
-      C: ['movePrevious', 'Combobox'],
-      d: ['moveNext', 'Landmark'],
-      D: ['movePrevious', 'Landmark'],
-      e: ['moveNext', 'Entry'],
-      E: ['movePrevious', 'Entry'],
-      f: ['moveNext', 'FormElement'],
-      F: ['movePrevious', 'FormElement'],
-      g: ['moveNext', 'Graphic'],
-      G: ['movePrevious', 'Graphic'],
-      h: ['moveNext', 'Heading'],
-      H: ['movePrevious', 'Heading'],
-      i: ['moveNext', 'ListItem'],
-      I: ['movePrevious', 'ListItem'],
-      k: ['moveNext', 'Link'],
-      K: ['movePrevious', 'Link'],
-      l: ['moveNext', 'List'],
-      L: ['movePrevious', 'List'],
-      p: ['moveNext', 'PageTab'],
-      P: ['movePrevious', 'PageTab'],
-      r: ['moveNext', 'RadioButton'],
-      R: ['movePrevious', 'RadioButton'],
-      s: ['moveNext', 'Separator'],
-      S: ['movePrevious', 'Separator'],
-      t: ['moveNext', 'Table'],
-      T: ['movePrevious', 'Table'],
-      x: ['moveNext', 'Checkbox'],
-      X: ['movePrevious', 'Checkbox']
+      a: ["moveNext", "Anchor"],
+      A: ["movePrevious", "Anchor"],
+      b: ["moveNext", "Button"],
+      B: ["movePrevious", "Button"],
+      c: ["moveNext", "Combobox"],
+      C: ["movePrevious", "Combobox"],
+      d: ["moveNext", "Landmark"],
+      D: ["movePrevious", "Landmark"],
+      e: ["moveNext", "Entry"],
+      E: ["movePrevious", "Entry"],
+      f: ["moveNext", "FormElement"],
+      F: ["movePrevious", "FormElement"],
+      g: ["moveNext", "Graphic"],
+      G: ["movePrevious", "Graphic"],
+      h: ["moveNext", "Heading"],
+      H: ["movePrevious", "Heading"],
+      i: ["moveNext", "ListItem"],
+      I: ["movePrevious", "ListItem"],
+      k: ["moveNext", "Link"],
+      K: ["movePrevious", "Link"],
+      l: ["moveNext", "List"],
+      L: ["movePrevious", "List"],
+      p: ["moveNext", "PageTab"],
+      P: ["movePrevious", "PageTab"],
+      r: ["moveNext", "RadioButton"],
+      R: ["movePrevious", "RadioButton"],
+      s: ["moveNext", "Separator"],
+      S: ["movePrevious", "Separator"],
+      t: ["moveNext", "Table"],
+      T: ["movePrevious", "Table"],
+      x: ["moveNext", "Checkbox"],
+      X: ["movePrevious", "Checkbox"]
     };
 
     return this.keyMap;
   },
 
   quickNavMode: {
     get current() {
       return this.modes[this._currentIndex];
@@ -966,21 +966,21 @@ var Input = {
     next: function quickNavMode_next() {
       Services.prefs.setIntPref(QUICKNAV_INDEX_PREF,
         this._currentIndex + 1 >= this.modes.length ?
           0 : this._currentIndex + 1);
     },
 
     updateModes: function updateModes(aModes) {
       if (aModes) {
-        this.modes = aModes.split(',');
+        this.modes = aModes.split(",");
       } else {
         this.modes = [];
       }
     },
 
     updateCurrentMode: function updateCurrentMode(aModeIndex) {
-      Logger.debug('Quicknav mode:', this.modes[aModeIndex]);
+      Logger.debug("Quicknav mode:", this.modes[aModeIndex]);
       this._currentIndex = aModeIndex;
     }
   }
 };
 AccessFu.Input = Input;
--- a/accessible/jsat/Constants.jsm
+++ b/accessible/jsat/Constants.jsm
@@ -1,59 +1,59 @@
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-this.EXPORTED_SYMBOLS = ['Roles', 'Events', 'Relations',
-                         'Filters', 'States', 'Prefilters'];
+this.EXPORTED_SYMBOLS = ["Roles", "Events", "Relations",
+                         "Filters", "States", "Prefilters"];
 
-function ConstantsMap (aObject, aPrefix, aMap = {}, aModifier = null) {
+function ConstantsMap(aObject, aPrefix, aMap = {}, aModifier = null) {
   let offset = aPrefix.length;
   for (var name in aObject) {
     if (name.indexOf(aPrefix) === 0) {
       aMap[name.slice(offset)] = aModifier ?
         aModifier(aObject[name]) : aObject[name];
     }
   }
 
   return aMap;
 }
 
 XPCOMUtils.defineLazyGetter(
-  this, 'Roles',
+  this, "Roles",
   function() {
-    return ConstantsMap(Ci.nsIAccessibleRole, 'ROLE_');
+    return ConstantsMap(Ci.nsIAccessibleRole, "ROLE_");
   });
 
 XPCOMUtils.defineLazyGetter(
-  this, 'Events',
+  this, "Events",
   function() {
-    return ConstantsMap(Ci.nsIAccessibleEvent, 'EVENT_');
+    return ConstantsMap(Ci.nsIAccessibleEvent, "EVENT_");
   });
 
 XPCOMUtils.defineLazyGetter(
-  this, 'Relations',
+  this, "Relations",
   function() {
-    return ConstantsMap(Ci.nsIAccessibleRelation, 'RELATION_');
+    return ConstantsMap(Ci.nsIAccessibleRelation, "RELATION_");
   });
 
 XPCOMUtils.defineLazyGetter(
-  this, 'Prefilters',
+  this, "Prefilters",
   function() {
-    return ConstantsMap(Ci.nsIAccessibleTraversalRule, 'PREFILTER_');
+    return ConstantsMap(Ci.nsIAccessibleTraversalRule, "PREFILTER_");
   });
 
 XPCOMUtils.defineLazyGetter(
-  this, 'Filters',
+  this, "Filters",
   function() {
-    return ConstantsMap(Ci.nsIAccessibleTraversalRule, 'FILTER_');
+    return ConstantsMap(Ci.nsIAccessibleTraversalRule, "FILTER_");
   });
 
 XPCOMUtils.defineLazyGetter(
-  this, 'States',
+  this, "States",
   function() {
-    let statesMap = ConstantsMap(Ci.nsIAccessibleStates, 'STATE_', {},
+    let statesMap = ConstantsMap(Ci.nsIAccessibleStates, "STATE_", {},
                                  (val) => { return { base: val, extended: 0 }; });
-    ConstantsMap(Ci.nsIAccessibleStates, 'EXT_STATE_', statesMap,
+    ConstantsMap(Ci.nsIAccessibleStates, "EXT_STATE_", statesMap,
                  (val) => { return { base: 0, extended: val }; });
     return statesMap;
   });
--- a/accessible/jsat/ContentControl.jsm
+++ b/accessible/jsat/ContentControl.jsm
@@ -1,175 +1,175 @@
 /* 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/. */
 
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, 'Services',
-  'resource://gre/modules/Services.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Utils',
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Logger',
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'TraversalRules',
-  'resource://gre/modules/accessibility/Traversal.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'TraversalHelper',
-  'resource://gre/modules/accessibility/Traversal.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Presentation',
-  'resource://gre/modules/accessibility/Presentation.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, "Services",
+  "resource://gre/modules/Services.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Logger",
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Roles",
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "TraversalRules",
+  "resource://gre/modules/accessibility/Traversal.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "TraversalHelper",
+  "resource://gre/modules/accessibility/Traversal.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Presentation",
+  "resource://gre/modules/accessibility/Presentation.jsm");
 
-this.EXPORTED_SYMBOLS = ['ContentControl'];
+this.EXPORTED_SYMBOLS = ["ContentControl"];
 
 const MOVEMENT_GRANULARITY_CHARACTER = 1;
 const MOVEMENT_GRANULARITY_WORD = 2;
 const MOVEMENT_GRANULARITY_PARAGRAPH = 8;
 
 this.ContentControl = function ContentControl(aContentScope) {
   this._contentScope = Cu.getWeakReference(aContentScope);
   this._childMessageSenders = new WeakMap();
 };
 
 this.ContentControl.prototype = {
-  messagesOfInterest: ['AccessFu:MoveCursor',
-                       'AccessFu:ClearCursor',
-                       'AccessFu:MoveToPoint',
-                       'AccessFu:AutoMove',
-                       'AccessFu:Activate',
-                       'AccessFu:MoveCaret',
-                       'AccessFu:MoveByGranularity',
-                       'AccessFu:AndroidScroll'],
+  messagesOfInterest: ["AccessFu:MoveCursor",
+                       "AccessFu:ClearCursor",
+                       "AccessFu:MoveToPoint",
+                       "AccessFu:AutoMove",
+                       "AccessFu:Activate",
+                       "AccessFu:MoveCaret",
+                       "AccessFu:MoveByGranularity",
+                       "AccessFu:AndroidScroll"],
 
   start: function cc_start() {
     let cs = this._contentScope.get();
     for (let message of this.messagesOfInterest) {
       cs.addMessageListener(message, this);
     }
-    cs.addEventListener('mousemove', this);
+    cs.addEventListener("mousemove", this);
   },
 
   stop: function cc_stop() {
     let cs = this._contentScope.get();
     for (let message of this.messagesOfInterest) {
       cs.removeMessageListener(message, this);
     }
-    cs.removeEventListener('mousemove', this);
+    cs.removeEventListener("mousemove", this);
   },
 
   get document() {
     return this._contentScope.get().content.document;
   },
 
   get window() {
     return this._contentScope.get().content;
   },
 
   get vc() {
     return Utils.getVirtualCursor(this.document);
   },
 
   receiveMessage: function cc_receiveMessage(aMessage) {
     Logger.debug(() => {
-      return ['ContentControl.receiveMessage',
+      return ["ContentControl.receiveMessage",
         aMessage.name,
         JSON.stringify(aMessage.json)];
     });
 
     // If we get an explicit message, we should immediately cancel any autoMove
     this.cancelAutoMove();
 
     try {
-      let func = this['handle' + aMessage.name.slice(9)]; // 'AccessFu:'.length
+      let func = this["handle" + aMessage.name.slice(9)]; // 'AccessFu:'.length
       if (func) {
         func.bind(this)(aMessage);
       } else {
-        Logger.warning('ContentControl: Unhandled message:', aMessage.name);
+        Logger.warning("ContentControl: Unhandled message:", aMessage.name);
       }
     } catch (x) {
       Logger.logException(
-        x, 'Error handling message: ' + JSON.stringify(aMessage.json));
+        x, "Error handling message: " + JSON.stringify(aMessage.json));
     }
   },
 
   handleAndroidScroll: function cc_handleAndroidScroll(aMessage) {
     let vc = this.vc;
     let position = vc.position;
 
-    if (aMessage.json.origin != 'child' && this.sendToChild(vc, aMessage)) {
+    if (aMessage.json.origin != "child" && this.sendToChild(vc, aMessage)) {
       // Forwarded succesfully to child cursor.
       return;
     }
 
     // Counter-intuitive, but scrolling backward (ie. up), actually should
     // increase range values.
-    if (this.adjustRange(position, aMessage.json.direction === 'backward')) {
+    if (this.adjustRange(position, aMessage.json.direction === "backward")) {
       return;
     }
 
-    this._contentScope.get().sendAsyncMessage('AccessFu:DoScroll',
+    this._contentScope.get().sendAsyncMessage("AccessFu:DoScroll",
       { bounds: Utils.getBounds(position, true),
-        page: aMessage.json.direction === 'forward' ? 1 : -1,
+        page: aMessage.json.direction === "forward" ? 1 : -1,
         horizontal: false });
   },
 
   handleMoveCursor: function cc_handleMoveCursor(aMessage) {
     let origin = aMessage.json.origin;
     let action = aMessage.json.action;
     let adjustRange = aMessage.json.adjustRange;
     let vc = this.vc;
 
-    if (origin != 'child' && this.sendToChild(vc, aMessage)) {
+    if (origin != "child" && this.sendToChild(vc, aMessage)) {
       // Forwarded succesfully to child cursor.
       return;
     }
 
-    if (adjustRange && this.adjustRange(vc.position, action === 'moveNext')) {
+    if (adjustRange && this.adjustRange(vc.position, action === "moveNext")) {
       return;
     }
 
     let moved = TraversalHelper.move(vc, action, aMessage.json.rule);
 
     if (moved) {
-      if (origin === 'child') {
+      if (origin === "child") {
         // We just stepped out of a child, clear child cursor.
         Utils.getMessageManager(aMessage.target).sendAsyncMessage(
-          'AccessFu:ClearCursor', {});
+          "AccessFu:ClearCursor", {});
       } else {
         // We potentially landed on a new child cursor. If so, we want to
         // either be on the first or last item in the child doc.
         let childAction = action;
-        if (action === 'moveNext') {
-          childAction = 'moveFirst';
-        } else if (action === 'movePrevious') {
-          childAction = 'moveLast';
+        if (action === "moveNext") {
+          childAction = "moveFirst";
+        } else if (action === "movePrevious") {
+          childAction = "moveLast";
         }
 
         // Attempt to forward move to a potential child cursor in our
         // new position.
         this.sendToChild(vc, aMessage, { action: childAction }, true);
       }
     } else if (!this._childMessageSenders.has(aMessage.target) &&
-               origin !== 'top') {
+               origin !== "top") {
       // We failed to move, and the message is not from a parent, so forward
       // to it.
       this.sendToParent(aMessage);
     } else {
-      this._contentScope.get().sendAsyncMessage('AccessFu:Present',
+      this._contentScope.get().sendAsyncMessage("AccessFu:Present",
         Presentation.noMove(action));
     }
   },
 
   handleEvent: function cc_handleEvent(aEvent) {
-    if (aEvent.type === 'mousemove') {
+    if (aEvent.type === "mousemove") {
       this.handleMoveToPoint(
-        { json: { x: aEvent.screenX, y: aEvent.screenY, rule: 'Simple' } });
+        { json: { x: aEvent.screenX, y: aEvent.screenY, rule: "Simple" } });
     }
     if (!Utils.getMessageManager(aEvent.target)) {
       aEvent.preventDefault();
     } else {
       aEvent.target.focus();
     }
   },
 
@@ -180,29 +180,29 @@ this.ContentControl.prototype = {
     let dpr = this.window.devicePixelRatio;
     this.vc.moveToPoint(rule, x * dpr, y * dpr, true);
   },
 
   handleClearCursor: function cc_handleClearCursor(aMessage) {
     let forwarded = this.sendToChild(this.vc, aMessage);
     this.vc.position = null;
     if (!forwarded) {
-      this._contentScope.get().sendAsyncMessage('AccessFu:CursorCleared');
+      this._contentScope.get().sendAsyncMessage("AccessFu:CursorCleared");
     }
     this.document.activeElement.blur();
   },
 
   handleAutoMove: function cc_handleAutoMove(aMessage) {
     this.autoMove(null, aMessage.json);
   },
 
   handleActivate: function cc_handleActivate(aMessage) {
     let activateAccessible = (aAccessible) => {
       Logger.debug(() => {
-        return ['activateAccessible', Logger.accessibleToString(aAccessible)];
+        return ["activateAccessible", Logger.accessibleToString(aAccessible)];
       });
       try {
         if (aMessage.json.activateIfKey &&
           !Utils.isActivatableOnFingerUp(aAccessible)) {
           // Only activate keys, don't do anything on other objects.
           return;
         }
       } catch (e) {
@@ -229,28 +229,28 @@ this.ContentControl.prototype = {
         let objX = {}, objY = {}, objW = {}, objH = {};
         aAccessible.getBounds(objX, objY, objW, objH);
 
         let x = Math.round((objX.value - docX.value) + objW.value / 2);
         let y = Math.round((objY.value - docY.value) + objH.value / 2);
 
         let node = aAccessible.DOMNode || aAccessible.parent.DOMNode;
 
-        for (let eventType of ['mousedown', 'mouseup']) {
-          let evt = this.document.createEvent('MouseEvents');
+        for (let eventType of ["mousedown", "mouseup"]) {
+          let evt = this.document.createEvent("MouseEvents");
           evt.initMouseEvent(eventType, true, true, this.window,
             x, y, 0, 0, 0, false, false, false, false, 0, null);
           node.dispatchEvent(evt);
         }
       }
 
       if (!Utils.isActivatableOnFingerUp(aAccessible)) {
         // Keys will typically have a sound of their own.
-        this._contentScope.get().sendAsyncMessage('AccessFu:Present',
-          Presentation.actionInvoked(aAccessible, 'click'));
+        this._contentScope.get().sendAsyncMessage("AccessFu:Present",
+          Presentation.actionInvoked(aAccessible, "click"));
       }
     };
 
     let focusedAcc = Utils.AccService.getAccessibleFor(
       this.document.activeElement);
     if (focusedAcc && this.vc.position === focusedAcc
         && focusedAcc.role === Roles.ENTRY) {
       let accText = focusedAcc.QueryInterface(Ci.nsIAccessibleText);
@@ -298,116 +298,116 @@ this.ContentControl.prototype = {
       return false;
     }
 
     let elem = acc.DOMNode;
     if (!elem) {
       return false;
     }
 
-    if (elem.tagName === 'INPUT' && elem.type === 'range') {
-      elem[aStepUp ? 'stepDown' : 'stepUp']();
-      let evt = this.document.createEvent('UIEvent');
-      evt.initEvent('change', true, true);
+    if (elem.tagName === "INPUT" && elem.type === "range") {
+      elem[aStepUp ? "stepDown" : "stepUp"]();
+      let evt = this.document.createEvent("UIEvent");
+      evt.initEvent("change", true, true);
       elem.dispatchEvent(evt);
     } else {
-      let evt = this.document.createEvent('KeyboardEvent');
+      let evt = this.document.createEvent("KeyboardEvent");
       let keycode = aStepUp ? evt.DOM_VK_DOWN : evt.DOM_VK_UP;
       evt.initKeyEvent(
         "keypress", false, true, null, false, false, false, false, keycode, 0);
       elem.dispatchEvent(evt);
     }
 
     return true;
   },
 
   handleMoveByGranularity: function cc_handleMoveByGranularity(aMessage) {
     // XXX: Add sendToChild. Right now this is only used in Android, so no need.
     let direction = aMessage.json.direction;
     let granularity;
 
-    switch(aMessage.json.granularity) {
+    switch (aMessage.json.granularity) {
       case MOVEMENT_GRANULARITY_CHARACTER:
         granularity = Ci.nsIAccessiblePivot.CHAR_BOUNDARY;
         break;
       case MOVEMENT_GRANULARITY_WORD:
         granularity = Ci.nsIAccessiblePivot.WORD_BOUNDARY;
         break;
       default:
         return;
     }
 
-    if (direction === 'Previous') {
+    if (direction === "Previous") {
       this.vc.movePreviousByText(granularity);
-    } else if (direction === 'Next') {
+    } else if (direction === "Next") {
       this.vc.moveNextByText(granularity);
     }
   },
 
   presentCaretChange: function cc_presentCaretChange(
     aText, aOldOffset, aNewOffset) {
     if (aOldOffset !== aNewOffset) {
       let msg = Presentation.textSelectionChanged(aText, aNewOffset, aNewOffset,
         aOldOffset, aOldOffset, true);
-      this._contentScope.get().sendAsyncMessage('AccessFu:Present', msg);
+      this._contentScope.get().sendAsyncMessage("AccessFu:Present", msg);
     }
   },
 
   handleMoveCaret: function cc_handleMoveCaret(aMessage) {
     let direction = aMessage.json.direction;
     let granularity = aMessage.json.granularity;
     let accessible = this.vc.position;
     let accText = accessible.QueryInterface(Ci.nsIAccessibleText);
     let oldOffset = accText.caretOffset;
     let text = accText.getText(0, accText.characterCount);
 
     let start = {}, end = {};
-    if (direction === 'Previous' && !aMessage.json.atStart) {
+    if (direction === "Previous" && !aMessage.json.atStart) {
       switch (granularity) {
         case MOVEMENT_GRANULARITY_CHARACTER:
           accText.caretOffset--;
           break;
         case MOVEMENT_GRANULARITY_WORD:
           accText.getTextBeforeOffset(accText.caretOffset,
             Ci.nsIAccessibleText.BOUNDARY_WORD_START, start, end);
           accText.caretOffset = end.value === accText.caretOffset ?
             start.value : end.value;
           break;
         case MOVEMENT_GRANULARITY_PARAGRAPH:
-          let startOfParagraph = text.lastIndexOf('\n', accText.caretOffset - 1);
+          let startOfParagraph = text.lastIndexOf("\n", accText.caretOffset - 1);
           accText.caretOffset = startOfParagraph !== -1 ? startOfParagraph : 0;
           break;
       }
-    } else if (direction === 'Next' && !aMessage.json.atEnd) {
+    } else if (direction === "Next" && !aMessage.json.atEnd) {
       switch (granularity) {
         case MOVEMENT_GRANULARITY_CHARACTER:
           accText.caretOffset++;
           break;
         case MOVEMENT_GRANULARITY_WORD:
           accText.getTextAtOffset(accText.caretOffset,
                                   Ci.nsIAccessibleText.BOUNDARY_WORD_END, start, end);
           accText.caretOffset = end.value;
           break;
         case MOVEMENT_GRANULARITY_PARAGRAPH:
-          accText.caretOffset = text.indexOf('\n', accText.caretOffset + 1);
+          accText.caretOffset = text.indexOf("\n", accText.caretOffset + 1);
           break;
       }
     }
 
     this.presentCaretChange(text, oldOffset, accText.caretOffset);
   },
 
   getChildCursor: function cc_getChildCursor(aAccessible) {
     let acc = aAccessible || this.vc.position;
     if (Utils.isAliveAndVisible(acc) && acc.role === Roles.INTERNAL_FRAME) {
       let domNode = acc.DOMNode;
       let mm = this._childMessageSenders.get(domNode, null);
       if (!mm) {
         mm = Utils.getMessageManager(domNode);
-        mm.addWeakMessageListener('AccessFu:MoveCursor', this);
+        mm.addWeakMessageListener("AccessFu:MoveCursor", this);
         this._childMessageSenders.set(domNode, mm);
       }
 
       return mm;
     }
 
     return null;
   },
@@ -421,29 +421,29 @@ this.ContentControl.prototype = {
     }
 
     if (aFocus) {
       position.takeFocus();
     }
 
     // XXX: This is a silly way to make a deep copy
     let newJSON = JSON.parse(JSON.stringify(aMessage.json));
-    newJSON.origin = 'parent';
+    newJSON.origin = "parent";
     for (let attr in aReplacer) {
       newJSON[attr] = aReplacer[attr];
     }
 
     mm.sendAsyncMessage(aMessage.name, newJSON);
     return true;
   },
 
   sendToParent: function cc_sendToParent(aMessage) {
     // XXX: This is a silly way to make a deep copy
     let newJSON = JSON.parse(JSON.stringify(aMessage.json));
-    newJSON.origin = 'child';
+    newJSON.origin = "child";
     aMessage.target.sendAsyncMessage(aMessage.name, newJSON);
   },
 
   /**
    * Move cursor and/or present its location.
    * aOptions could have any of these fields:
    * - delay: in ms, before actual move is performed. Another autoMove call
    *    would cancel it. Useful if we want to wait for a possible trailing
@@ -460,17 +460,17 @@ this.ContentControl.prototype = {
     let moveFunc = () => {
       let vc = this.vc;
       let acc = aAnchor;
       let rule = aOptions.onScreenOnly ?
         TraversalRules.SimpleOnScreen : TraversalRules.Simple;
       let forcePresentFunc = () => {
         if (aOptions.forcePresent) {
           this._contentScope.get().sendAsyncMessage(
-            'AccessFu:Present', Presentation.pivotChanged(
+            "AccessFu:Present", Presentation.pivotChanged(
               vc.position, null, Ci.nsIAccessiblePivot.REASON_NONE,
               vc.startOffset, vc.endOffset, false));
         }
       };
 
       if (aOptions.noOpIfOnScreen &&
         Utils.isAliveAndVisible(vc.position, true)) {
         forcePresentFunc();
@@ -478,30 +478,30 @@ this.ContentControl.prototype = {
       }
 
       if (aOptions.moveToFocused) {
         acc = Utils.AccService.getAccessibleFor(
           this.document.activeElement) || acc;
       }
 
       let moved = false;
-      let moveMethod = aOptions.moveMethod || 'moveNext'; // default is moveNext
-      let moveFirstOrLast = moveMethod in ['moveFirst', 'moveLast'];
+      let moveMethod = aOptions.moveMethod || "moveNext"; // default is moveNext
+      let moveFirstOrLast = moveMethod in ["moveFirst", "moveLast"];
       if (!moveFirstOrLast || acc) {
         // We either need next/previous or there is an anchor we need to use.
-        moved = vc[moveFirstOrLast ? 'moveNext' : moveMethod](rule, acc, true,
+        moved = vc[moveFirstOrLast ? "moveNext" : moveMethod](rule, acc, true,
                                                               false);
       }
       if (moveFirstOrLast && !moved) {
         // We move to first/last after no anchor move happened or succeeded.
         moved = vc[moveMethod](rule, false);
       }
 
       let sentToChild = this.sendToChild(vc, {
-        name: 'AccessFu:AutoMove',
+        name: "AccessFu:AutoMove",
         json: {
           moveMethod: aOptions.moveMethod,
           moveToFocused: aOptions.moveToFocused,
           noOpIfOnScreen: true,
           forcePresent: true
         }
       }, null, true);
 
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -1,36 +1,36 @@
 /* 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';
+"use strict";
 
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 const TEXT_NODE = 3;
 
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Services',
-  'resource://gre/modules/Services.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Utils',
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Logger',
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Presentation',
-  'resource://gre/modules/accessibility/Presentation.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Events',
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'States',
-  'resource://gre/modules/accessibility/Constants.jsm');
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Services",
+  "resource://gre/modules/Services.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Logger",
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Presentation",
+  "resource://gre/modules/accessibility/Presentation.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Roles",
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Events",
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "States",
+  "resource://gre/modules/accessibility/Constants.jsm");
 
-this.EXPORTED_SYMBOLS = ['EventManager'];
+this.EXPORTED_SYMBOLS = ["EventManager"];
 
 this.EventManager = function EventManager(aContentScope, aContentControl) {
   this.contentScope = aContentScope;
   this.contentControl = aContentControl;
   this.addEventListener = this.contentScope.addEventListener.bind(
     this.contentScope);
   this.removeEventListener = this.contentScope.removeEventListener.bind(
     this.contentScope);
@@ -42,108 +42,108 @@ this.EventManager = function EventManage
 };
 
 this.EventManager.prototype = {
   editState: { editing: false },
 
   start: function start() {
     try {
       if (!this._started) {
-        Logger.debug('EventManager.start');
+        Logger.debug("EventManager.start");
 
         this._started = true;
 
         AccessibilityEventObserver.addListener(this);
 
         this.webProgress.addProgressListener(this,
           (Ci.nsIWebProgress.NOTIFY_STATE_ALL |
            Ci.nsIWebProgress.NOTIFY_LOCATION));
-        this.addEventListener('wheel', this, true);
-        this.addEventListener('scroll', this, true);
-        this.addEventListener('resize', this, true);
+        this.addEventListener("wheel", this, true);
+        this.addEventListener("scroll", this, true);
+        this.addEventListener("resize", this, true);
         this._preDialogPosition = new WeakMap();
       }
-      this.present(Presentation.tabStateChanged(null, 'newtab'));
+      this.present(Presentation.tabStateChanged(null, "newtab"));
 
     } catch (x) {
-      Logger.logException(x, 'Failed to start EventManager');
+      Logger.logException(x, "Failed to start EventManager");
     }
   },
 
   // XXX: Stop is not called when the tab is closed (|TabClose| event is too
   // late). It is only called when the AccessFu is disabled explicitly.
   stop: function stop() {
     if (!this._started) {
       return;
     }
-    Logger.debug('EventManager.stop');
+    Logger.debug("EventManager.stop");
     AccessibilityEventObserver.removeListener(this);
     try {
       this._preDialogPosition = new WeakMap();
       this.webProgress.removeProgressListener(this);
-      this.removeEventListener('wheel', this, true);
-      this.removeEventListener('scroll', this, true);
-      this.removeEventListener('resize', this, true);
+      this.removeEventListener("wheel", this, true);
+      this.removeEventListener("scroll", this, true);
+      this.removeEventListener("resize", this, true);
     } catch (x) {
       // contentScope is dead.
     } finally {
       this._started = false;
     }
   },
 
   handleEvent: function handleEvent(aEvent) {
     Logger.debug(() => {
-      return ['DOMEvent', aEvent.type];
+      return ["DOMEvent", aEvent.type];
     });
 
     try {
       switch (aEvent.type) {
-      case 'wheel':
+      case "wheel":
       {
         let delta = aEvent.deltaX || aEvent.deltaY;
         this.contentControl.autoMove(
          null,
-         { moveMethod: delta > 0 ? 'moveNext' : 'movePrevious',
+         { moveMethod: delta > 0 ? "moveNext" : "movePrevious",
            onScreenOnly: true, noOpIfOnScreen: true, delay: 500 });
         break;
       }
-      case 'scroll':
-      case 'resize':
+      case "scroll":
+      case "resize":
       {
         // the target could be an element, document or window
         let window = null;
         if (aEvent.target instanceof Ci.nsIDOMWindow)
           window = aEvent.target;
         else if (aEvent.target instanceof Ci.nsIDOMDocument)
           window = aEvent.target.defaultView;
         else if (aEvent.target instanceof Ci.nsIDOMElement)
           window = aEvent.target.ownerGlobal;
         this.present(Presentation.viewportChanged(window));
         break;
       }
       }
     } catch (x) {
-      Logger.logException(x, 'Error handling DOM event');
+      Logger.logException(x, "Error handling DOM event");
     }
   },
 
   handleAccEvent: function handleAccEvent(aEvent) {
     Logger.debug(() => {
-      return ['A11yEvent', Logger.eventToString(aEvent),
+      return ["A11yEvent", Logger.eventToString(aEvent),
               Logger.accessibleToString(aEvent.accessible)];
     });
 
     // Don't bother with non-content events in firefox.
-    if (Utils.MozBuildApp == 'browser' &&
+    if (Utils.MozBuildApp == "browser" &&
         aEvent.eventType != Events.VIRTUALCURSOR_CHANGED &&
         // XXX Bug 442005 results in DocAccessible::getDocType returning
         // NS_ERROR_FAILURE. Checking for aEvent.accessibleDocument.docType ==
         // 'window' does not currently work.
         (aEvent.accessibleDocument.DOMDocument.doctype &&
-         aEvent.accessibleDocument.DOMDocument.doctype.name === 'window')) {
+         aEvent.accessibleDocument.DOMDocument.doctype.name === "window")) {
       return;
     }
 
     switch (aEvent.eventType) {
       case Events.VIRTUALCURSOR_CHANGED:
       {
         let pivot = aEvent.accessible.
           QueryInterface(Ci.nsIAccessibleDocument).virtualCursor;
@@ -170,39 +170,39 @@ this.EventManager.prototype = {
       {
         let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent);
         let state = Utils.getState(event);
         if (state.contains(States.CHECKED)) {
           if (aEvent.accessible.role === Roles.SWITCH) {
             this.present(
               Presentation.
                 actionInvoked(aEvent.accessible,
-                              event.isEnabled ? 'on' : 'off'));
+                              event.isEnabled ? "on" : "off"));
           } else {
             this.present(
               Presentation.
                 actionInvoked(aEvent.accessible,
-                              event.isEnabled ? 'check' : 'uncheck'));
+                              event.isEnabled ? "check" : "uncheck"));
           }
         } else if (state.contains(States.SELECTED)) {
           this.present(
             Presentation.
               actionInvoked(aEvent.accessible,
-                            event.isEnabled ? 'select' : 'unselect'));
+                            event.isEnabled ? "select" : "unselect"));
         }
         break;
       }
       case Events.NAME_CHANGE:
       {
         let acc = aEvent.accessible;
         if (acc === this.contentControl.vc.position) {
           this.present(Presentation.nameChanged(acc));
         } else {
           let {liveRegion, isPolite} = this._handleLiveRegion(aEvent,
-            ['text', 'all']);
+            ["text", "all"]);
           if (liveRegion) {
             this.present(Presentation.nameChanged(acc, isPolite));
           }
         }
         break;
       }
       case Events.SCROLLING_START:
       {
@@ -227,22 +227,22 @@ this.EventManager.prototype = {
           }
         }
         break;
       }
       case Events.OBJECT_ATTRIBUTE_CHANGED:
       {
         let evt = aEvent.QueryInterface(
           Ci.nsIAccessibleObjectAttributeChangedEvent);
-        if (evt.changedAttribute.toString() !== 'aria-hidden') {
+        if (evt.changedAttribute.toString() !== "aria-hidden") {
           // Only handle aria-hidden attribute change.
           break;
         }
         let hidden = Utils.isHidden(aEvent.accessible);
-        this[hidden ? '_handleHide' : '_handleShow'](evt);
+        this[hidden ? "_handleHide" : "_handleShow"](evt);
         if (this.inTest) {
           this.sendMsgFunc("AccessFu:AriaHidden", { hidden: hidden });
         }
         break;
       }
       case Events.SHOW:
       {
         this._handleShow(aEvent);
@@ -253,17 +253,17 @@ this.EventManager.prototype = {
         let evt = aEvent.QueryInterface(Ci.nsIAccessibleHideEvent);
         this._handleHide(evt);
         break;
       }
       case Events.TEXT_INSERTED:
       case Events.TEXT_REMOVED:
       {
         let {liveRegion, isPolite} = this._handleLiveRegion(aEvent,
-          ['text', 'all']);
+          ["text", "all"]);
         if (aEvent.isFromUserInput || liveRegion) {
           // Handle all text mutations coming from the user or if they happen
           // on a live region.
           this._handleText(aEvent, liveRegion, isPolite);
         }
         break;
       }
       case Events.FOCUS:
@@ -304,17 +304,17 @@ this.EventManager.prototype = {
       {
         let position = this.contentControl.vc.position;
         let target = aEvent.accessible;
         if (position === target ||
             Utils.getEmbeddedControl(position) === target) {
           this.present(Presentation.valueChanged(target));
         } else {
           let {liveRegion, isPolite} = this._handleLiveRegion(aEvent,
-            ['text', 'all']);
+            ["text", "all"]);
           if (liveRegion) {
             this.present(Presentation.valueChanged(target, isPolite));
           }
         }
       }
     }
   },
 
@@ -363,32 +363,32 @@ this.EventManager.prototype = {
       this.sendMsgFunc("AccessFu:Input", editState);
     }
 
     this.editState = editState;
   },
 
   _handleShow: function _handleShow(aEvent) {
     let {liveRegion, isPolite} = this._handleLiveRegion(aEvent,
-      ['additions', 'all']);
+      ["additions", "all"]);
     // Only handle show if it is a relevant live region.
     if (!liveRegion) {
       return;
     }
     // Show for text is handled by the EVENT_TEXT_INSERTED handler.
     if (aEvent.accessible.role === Roles.TEXT_LEAF) {
       return;
     }
     this._dequeueLiveEvent(Events.HIDE, liveRegion);
     this.present(Presentation.liveRegion(liveRegion, isPolite, false));
   },
 
   _handleHide: function _handleHide(aEvent) {
     let {liveRegion, isPolite} = this._handleLiveRegion(
-      aEvent, ['removals', 'all']);
+      aEvent, ["removals", "all"]);
     let acc = aEvent.accessible;
     if (liveRegion) {
       // Hide for text is handled by the EVENT_TEXT_REMOVED handler.
       if (acc.role === Roles.TEXT_LEAF) {
         return;
       }
       this._queueLiveEvent(Events.HIDE, liveRegion, isPolite);
     } else {
@@ -412,30 +412,30 @@ this.EventManager.prototype = {
     }
   },
 
   _handleText: function _handleText(aEvent, aLiveRegion, aIsPolite) {
     let event = aEvent.QueryInterface(Ci.nsIAccessibleTextChangeEvent);
     let isInserted = event.isInserted;
     let txtIface = aEvent.accessible.QueryInterface(Ci.nsIAccessibleText);
 
-    let text = '';
+    let text = "";
     try {
       text = txtIface.getText(0, Ci.nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT);
     } catch (x) {
       // XXX we might have gotten an exception with of a
       // zero-length text. If we did, ignore it (bug #749810).
       if (txtIface.characterCount) {
         throw x;
       }
     }
     // If there are embedded objects in the text, ignore them.
     // Assuming changes to the descendants would already be handled by the
     // show/hide event.
-    let modifiedText = event.modifiedText.replace(/\uFFFC/g, '');
+    let modifiedText = event.modifiedText.replace(/\uFFFC/g, "");
     if (modifiedText != event.modifiedText && !modifiedText.trim()) {
       return;
     }
 
     if (aLiveRegion) {
       if (aEvent.eventType === Events.TEXT_REMOVED) {
         this._queueLiveEvent(Events.TEXT_REMOVED, aLiveRegion, aIsPolite,
           modifiedText);
@@ -451,23 +451,23 @@ this.EventManager.prototype = {
   },
 
   _handleLiveRegion: function _handleLiveRegion(aEvent, aRelevant) {
     if (aEvent.isFromUserInput) {
       return {};
     }
     let parseLiveAttrs = function parseLiveAttrs(aAccessible) {
       let attrs = Utils.getAttributes(aAccessible);
-      if (attrs['container-live']) {
+      if (attrs["container-live"]) {
         return {
-          live: attrs['container-live'],
-          relevant: attrs['container-relevant'] || 'additions text',
-          busy: attrs['container-busy'],
-          atomic: attrs['container-atomic'],
-          memberOf: attrs['member-of']
+          live: attrs["container-live"],
+          relevant: attrs["container-relevant"] || "additions text",
+          busy: attrs["container-busy"],
+          atomic: attrs["container-atomic"],
+          memberOf: attrs["member-of"]
         };
       }
       return null;
     };
     // XXX live attributes are not set for hidden accessibles yet. Need to
     // climb up the tree to check for them.
     let getLiveAttributes = function getLiveAttributes(aEvent) {
       let liveAttrs = parseLiveAttrs(aEvent.accessible);
@@ -481,30 +481,30 @@ this.EventManager.prototype = {
           return liveAttrs;
         }
         parent = parent.parent
       }
       return {};
     };
     let {live, relevant, /* busy, atomic, memberOf */ } = getLiveAttributes(aEvent);
     // If container-live is not present or is set to |off| ignore the event.
-    if (!live || live === 'off') {
+    if (!live || live === "off") {
       return {};
     }
     // XXX: support busy and atomic.
 
     // Determine if the type of the mutation is relevant. Default is additions
     // and text.
     let isRelevant = Utils.matchAttributeValue(relevant, aRelevant);
     if (!isRelevant) {
       return {};
     }
     return {
       liveRegion: aEvent.accessible,
-      isPolite: live === 'polite'
+      isPolite: live === "polite"
     };
   },
 
   _dequeueLiveEvent: function _dequeueLiveEvent(aEventType, aLiveRegion) {
     let domNode = aLiveRegion.DOMNode;
     if (this._liveEventQueue && this._liveEventQueue.has(domNode)) {
       let queue = this._liveEventQueue.get(domNode);
       let nextEvent = queue[0];
@@ -537,39 +537,39 @@ this.EventManager.prototype = {
     }
   },
 
   present: function present(aPresentationData) {
     this.sendMsgFunc("AccessFu:Present", aPresentationData);
   },
 
   onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
-    let tabstate = '';
+    let tabstate = "";
 
     let loadingState = Ci.nsIWebProgressListener.STATE_TRANSFERRING |
       Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
     let loadedState = Ci.nsIWebProgressListener.STATE_STOP |
       Ci.nsIWebProgressListener.STATE_IS_NETWORK;
 
     if ((aStateFlags & loadingState) == loadingState) {
-      tabstate = 'loading';
+      tabstate = "loading";
     } else if ((aStateFlags & loadedState) == loadedState &&
                !aWebProgress.isLoadingDocument) {
-      tabstate = 'loaded';
+      tabstate = "loaded";
     }
 
     if (tabstate) {
       let docAcc = Utils.AccService.getAccessibleFor(aWebProgress.DOMWindow.document);
       this.present(Presentation.tabStateChanged(docAcc, tabstate));
     }
   },
 
   onLocationChange: function onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
     let docAcc = Utils.AccService.getAccessibleFor(aWebProgress.DOMWindow.document);
-    this.present(Presentation.tabStateChanged(docAcc, 'newdoc'));
+    this.present(Presentation.tabStateChanged(docAcc, "newdoc"));
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
                                          Ci.nsISupportsWeakReference,
                                          Ci.nsISupports,
                                          Ci.nsIObserver])
 };
 
@@ -592,28 +592,28 @@ const AccessibilityEventObserver = {
 
   /**
    * Start an AccessibilityEventObserver.
    */
   start: function start() {
     if (this.started || this.listenerCount === 0) {
       return;
     }
-    Services.obs.addObserver(this, 'accessible-event');
+    Services.obs.addObserver(this, "accessible-event");
     this.started = true;
   },
 
   /**
    * Stop an AccessibilityEventObserver.
    */
   stop: function stop() {
     if (!this.started) {
       return;
     }
-    Services.obs.removeObserver(this, 'accessible-event');
+    Services.obs.removeObserver(this, "accessible-event");
     // Clean up all registered event managers.
     this.eventManagers = new WeakMap();
     this.listenerCount = 0;
     this.started = false;
   },
 
   /**
    * Register an EventManager and start listening to the
@@ -624,17 +624,17 @@ const AccessibilityEventObserver = {
    */
   addListener: function addListener(aEventManager) {
     let content = aEventManager.contentScope.content;
     if (!this.eventManagers.has(content)) {
       this.listenerCount++;
     }
     this.eventManagers.set(content, aEventManager);
     // Since at least one EventManager was registered, start listening.
-    Logger.debug('AccessibilityEventObserver.addListener. Total:',
+    Logger.debug("AccessibilityEventObserver.addListener. Total:",
       this.listenerCount);
     this.start();
   },
 
   /**
    * Unregister an EventManager and, optionally, stop listening to the
    * 'accessible-event' messages.
    *
@@ -642,17 +642,17 @@ const AccessibilityEventObserver = {
    *        An EventManager object that was stopped in the specific content.
    */
   removeListener: function removeListener(aEventManager) {
     let content = aEventManager.contentScope.content;
     if (!this.eventManagers.delete(content)) {
       return;
     }
     this.listenerCount--;
-    Logger.debug('AccessibilityEventObserver.removeListener. Total:',
+    Logger.debug("AccessibilityEventObserver.removeListener. Total:",
       this.listenerCount);
     if (this.listenerCount === 0) {
       // If there are no EventManagers registered at the moment, stop listening
       // to the 'accessible-event' messages.
       this.stop();
     }
   },
 
@@ -674,42 +674,42 @@ const AccessibilityEventObserver = {
     }
     return this.getListener(parent);
   },
 
   /**
    * Handle the 'accessible-event' message.
    */
   observe: function observe(aSubject, aTopic, aData) {
-    if (aTopic !== 'accessible-event') {
+    if (aTopic !== "accessible-event") {
       return;
     }
     let event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
     if (!event.accessibleDocument) {
       Logger.warning(
-        'AccessibilityEventObserver.observe: no accessible document:',
+        "AccessibilityEventObserver.observe: no accessible document:",
         Logger.eventToString(event), "accessible:",
         Logger.accessibleToString(event.accessible));
       return;
     }
     let content = event.accessibleDocument.window;
     // Match the content window to its EventManager.
     let eventManager = this.getListener(content);
     if (!eventManager || !eventManager._started) {
-      if (Utils.MozBuildApp === 'browser' &&
+      if (Utils.MozBuildApp === "browser" &&
           !(content instanceof Ci.nsIDOMChromeWindow)) {
         Logger.warning(
-          'AccessibilityEventObserver.observe: ignored event:',
+          "AccessibilityEventObserver.observe: ignored event:",
           Logger.eventToString(event), "accessible:",
           Logger.accessibleToString(event.accessible), "document:",
           Logger.accessibleToString(event.accessibleDocument));
       }
       return;
     }
     try {
       eventManager.handleAccEvent(event);
     } catch (x) {
-      Logger.logException(x, 'Error handing accessible event');
+      Logger.logException(x, "Error handing accessible event");
     } finally {
       return;
     }
   }
 };
--- a/accessible/jsat/Gestures.jsm
+++ b/accessible/jsat/Gestures.jsm
@@ -1,15 +1,15 @@
 /* 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/. */
 
 /* exported GestureSettings, GestureTracker */
 
-/******************************************************************************
+/** ****************************************************************************
   All gestures have the following pathways when being resolved(v)/rejected(x):
                Tap -> DoubleTap        (x)
                    -> Dwell            (x)
                    -> Swipe            (x)
 
          DoubleTap -> TripleTap        (x)
                    -> TapHold          (x)
 
@@ -29,34 +29,34 @@
 
   DoubleTapHoldEnd -> Explore          (x)
 
         ExploreEnd -> Explore          (x)
 
            Explore -> ExploreEnd       (v)
 ******************************************************************************/
 
-'use strict';
+"use strict";
 
 const Cu = Components.utils;
 
-this.EXPORTED_SYMBOLS = ['GestureSettings', 'GestureTracker']; // jshint ignore:line
+this.EXPORTED_SYMBOLS = ["GestureSettings", "GestureTracker"]; // jshint ignore:line
 
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, 'Utils', // jshint ignore:line
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Logger', // jshint ignore:line
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'setTimeout', // jshint ignore:line
-  'resource://gre/modules/Timer.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'clearTimeout', // jshint ignore:line
-  'resource://gre/modules/Timer.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'PromiseUtils', // jshint ignore:line
-  'resource://gre/modules/PromiseUtils.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, "Utils", // jshint ignore:line
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Logger", // jshint ignore:line
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "setTimeout", // jshint ignore:line
+  "resource://gre/modules/Timer.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "clearTimeout", // jshint ignore:line
+  "resource://gre/modules/Timer.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils", // jshint ignore:line
+  "resource://gre/modules/PromiseUtils.jsm");
 
 // Default maximum duration of swipe
 const SWIPE_MAX_DURATION = 200;
 // Default maximum amount of time allowed for a gesture to be considered a
 // multitouch
 const MAX_MULTITOUCH = 125;
 // Default maximum consecutive pointer event timeout
 const MAX_CONSECUTIVE_GESTURE_DELAY = 200;
@@ -70,17 +70,17 @@ const TAP_MAX_RADIUS = 0.2;
 // consequent pointer move lines.
 const DIRECTNESS_COEFF = 1.44;
 // Amount in inches from the edges of the screen for it to be an edge swipe
 const EDGE = 0.1;
 // Multiply timeouts by this constant, x2 works great too for slower users.
 const TIMEOUT_MULTIPLIER = 1;
 // A single pointer down/up sequence periodically precedes the tripple swipe
 // gesture on Android. This delay acounts for that.
-const IS_ANDROID = Utils.MozBuildApp === 'mobile/android' &&
+const IS_ANDROID = Utils.MozBuildApp === "mobile/android" &&
   Utils.AndroidSdkVersion >= 14;
 
 /**
  * A point object containing distance travelled data.
  * @param {Object} aPoint A point object that looks like: {
  *   x: x coordinate in pixels,
  *   y: y coordinate in pixels
  * }
@@ -197,35 +197,35 @@ this.GestureTracker = { // jshint ignore
    * Create a new gesture object and attach resolution handler to it as well as
    * handle the incoming pointer event.
    * @param  {Object} aDetail A new pointer event detail.
    * @param  {Number} aTimeStamp A new pointer event timeStamp.
    * @param  {Function} aGesture A gesture constructor (default: Tap).
    */
   _init: function GestureTracker__init(aDetail, aTimeStamp, aGesture) {
     // Only create a new gesture on |pointerdown| event.
-    if (aDetail.type !== 'pointerdown') {
+    if (aDetail.type !== "pointerdown") {
       return;
     }
     let GestureConstructor = aGesture || (IS_ANDROID ? DoubleTap : Tap);
     this._create(GestureConstructor);
     this._update(aDetail, aTimeStamp);
   },
 
   /**
    * Handle the incoming pointer event with the existing gesture object(if
    * present) or with the newly created one.
    * @param  {Object} aDetail A new pointer event detail.
    * @param  {Number} aTimeStamp A new pointer event timeStamp.
    */
   handle: function GestureTracker_handle(aDetail, aTimeStamp) {
     Logger.gesture(() => {
-      return ['Pointer event', Utils.dpi, 'at:', aTimeStamp, JSON.stringify(aDetail)];
+      return ["Pointer event", Utils.dpi, "at:", aTimeStamp, JSON.stringify(aDetail)];
     });
-    this[this.current ? '_update' : '_init'](aDetail, aTimeStamp);
+    this[this.current ? "_update" : "_init"](aDetail, aTimeStamp);
   },
 
   /**
    * Create a new gesture object and attach resolution handler to it.
    * @param  {Function} aGesture A gesture constructor.
    * @param  {Number} aTimeStamp An original pointer event timeStamp.
    * @param  {Array} aPoints All changed points associated with the new pointer
    * event.
@@ -274,17 +274,17 @@ this.GestureTracker = { // jshint ignore
  * @param  {String} aType A gesture type.
  * @param  {Object} aPoints Gesture's points.
  * @param  {String} xKey A default key for the x coordinate. Default is
  * 'startX'.
  * @param  {String} yKey A default key for the y coordinate. Default is
  * 'startY'.
  * @return {Object} a mozAccessFuGesture detail structure.
  */
-function compileDetail(aType, aPoints, keyMap = {x: 'startX', y: 'startY'}) {
+function compileDetail(aType, aPoints, keyMap = {x: "startX", y: "startY"}) {
   let touches = [];
   let maxDeltaX = 0;
   let maxDeltaY = 0;
   for (let identifier in aPoints) {
     let point = aPoints[identifier];
     let touch = {};
     for (let key in keyMap) {
       touch[key] = point[keyMap[key]];
@@ -316,17 +316,17 @@ function compileDetail(aType, aPoints, k
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * Default is an empty object.
  * @param {?String} aLastEvent Last pointer event type.
  */
 function Gesture(aTimeStamp, aPoints = {}, aLastEvent = undefined) {
   this.startTime = Date.now();
-  Logger.gesture('Creating', this.id, 'gesture.');
+  Logger.gesture("Creating", this.id, "gesture.");
   this.points = aPoints;
   this.lastEvent = aLastEvent;
   this._deferred = PromiseUtils.defer();
   // Call this._handleResolve or this._handleReject when the promise is
   // fulfilled with either resolve or reject.
   this.promise = this._deferred.promise.then(this._handleResolve.bind(this),
     this._handleReject.bind(this));
   this.startTimer(aTimeStamp);
@@ -344,32 +344,32 @@ Gesture.prototype = {
     // reject this gesture promise.
     return GestureSettings.maxConsecutiveGestureDelay;
   },
 
   /**
    * Clear the existing timer.
    */
   clearTimer: function Gesture_clearTimer() {
-    Logger.gesture('clearTimeout', this.type);
+    Logger.gesture("clearTimeout", this.type);
     clearTimeout(this._timer);
     delete this._timer;
   },
 
   /**
    * Start the timer for gesture timeout.
    * @param {Number} aTimeStamp An original pointer event's timeStamp that
    * started the gesture resolution sequence.
    */
   startTimer: function Gesture_startTimer(aTimeStamp) {
-    Logger.gesture('startTimer', this.type);
+    Logger.gesture("startTimer", this.type);
     this.clearTimer();
     let delay = this._getDelay(aTimeStamp);
     let handler = () => {
-      Logger.gesture('timer handler');
+      Logger.gesture("timer handler");
       this.clearTimer();
       if (!this._inProgress) {
         this._deferred.reject();
       } else if (this._rejectToOnWait) {
         this._deferred.reject(this._rejectToOnWait);
       }
     };
     if (delay <= 0) {
@@ -403,17 +403,17 @@ Gesture.prototype = {
    */
   _update: function Gesture__update(aPoints, aType, aCanCreate = false, aNeedComplete = false) {
     let complete;
     let lastEvent;
     for (let point of aPoints) {
       let identifier = point.identifier;
       let gesturePoint = this.points[identifier];
       if (gesturePoint) {
-        if (aType === 'pointerdown' && aCanCreate) {
+        if (aType === "pointerdown" && aCanCreate) {
           // scratch the previous pointer with that id.
           this.points[identifier] = new Point(point);
         } else {
           gesturePoint.update(point);
         }
         if (aNeedComplete) {
           // Since the gesture is completing and at least one of the gesture
           // points is updated, set the return value to true.
@@ -435,49 +435,49 @@ Gesture.prototype = {
     return complete;
   },
 
   /**
    * Emit a mozAccessFuGesture (when the gesture is resolved).
    * @param  {Object} aDetail a compiled mozAccessFuGesture detail structure.
    */
   _emit: function Gesture__emit(aDetail) {
-    let evt = new Utils.win.CustomEvent('mozAccessFuGesture', {
+    let evt = new Utils.win.CustomEvent("mozAccessFuGesture", {
       bubbles: true,
       cancelable: true,
       detail: aDetail
     });
     Utils.win.dispatchEvent(evt);
   },
 
   /**
    * Handle the pointer down event.
    * @param  {Array} aPoints A new pointer down points.
    * @param  {Number} aTimeStamp A new pointer down timeStamp.
    */
   pointerdown: function Gesture_pointerdown(aPoints, aTimeStamp) {
     this._inProgress = true;
-    this._update(aPoints, 'pointerdown',
+    this._update(aPoints, "pointerdown",
       aTimeStamp - this.startTime < GestureSettings.maxMultitouch);
   },
 
   /**
    * Handle the pointer move event.
    * @param  {Array} aPoints A new pointer move points.
    */
   pointermove: function Gesture_pointermove(aPoints) {
-    this._update(aPoints, 'pointermove');
+    this._update(aPoints, "pointermove");
   },
 
   /**
    * Handle the pointer up event.
    * @param  {Array} aPoints A new pointer up points.
    */
   pointerup: function Gesture_pointerup(aPoints) {
-    let complete = this._update(aPoints, 'pointerup', false, true);
+    let complete = this._update(aPoints, "pointerup", false, true);
     if (complete) {
       this._deferred.resolve();
     }
   },
 
   /**
    * A subsequent gesture constructor to resolve the current one to. E.g.
    * tap->doubletap, dwell->dwellend, etc.
@@ -501,17 +501,17 @@ Gesture.prototype = {
    *   id: current gesture id,
    *   gestureType: an optional subsequent gesture constructor.
    * }
    */
   _handleResolve: function Gesture__handleResolve() {
     if (this.isComplete) {
       return;
     }
-    Logger.gesture('Resolving', this.id, 'gesture.');
+    Logger.gesture("Resolving", this.id, "gesture.");
     this.isComplete = true;
     this.clearTimer();
     let detail = this.compile();
     if (detail) {
       this._emit(detail);
     }
     return {
       id: this.id,
@@ -526,17 +526,17 @@ Gesture.prototype = {
    *   id: current gesture id,
    *   gestureType: an optional subsequent gesture constructor.
    * }
    */
   _handleReject: function Gesture__handleReject(aRejectTo) {
     if (this.isComplete) {
       return;
     }
-    Logger.gesture('Rejecting', this.id, 'gesture.');
+    Logger.gesture("Rejecting", this.id, "gesture.");
     this.isComplete = true;
     this.clearTimer();
     return {
       id: this.id,
       gestureType: aRejectTo
     };
   },
 
@@ -553,26 +553,26 @@ Gesture.prototype = {
 
 /**
  * A mixin for an explore related object.
  */
 function ExploreGesture() {
   this.compile = () => {
     // Unlike most of other gestures explore based gestures compile using the
     // current point position and not the start one.
-    return compileDetail(this.type, this.points, {x: 'x', y: 'y'});
+    return compileDetail(this.type, this.points, {x: "x", y: "y"});
   };
 }
 
 /**
  * Check the in progress gesture for completion.
  */
 function checkProgressGesture(aGesture) {
   aGesture._inProgress = true;
-  if (aGesture.lastEvent === 'pointerup') {
+  if (aGesture.lastEvent === "pointerup") {
     if (aGesture.test) {
       aGesture.test(true);
     }
     aGesture._deferred.resolve();
   }
 }
 
 /**
@@ -624,17 +624,17 @@ TravelGesture.prototype.test = function 
 function DwellEnd(aTimeStamp, aPoints, aLastEvent) {
   this._inProgress = true;
   // If the pointer travels, reject to Explore.
   TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent);
   checkProgressGesture(this);
 }
 
 DwellEnd.prototype = Object.create(TravelGesture.prototype);
-DwellEnd.prototype.type = 'dwellend';
+DwellEnd.prototype.type = "dwellend";
 
 /**
  * TapHoldEnd gesture. This gesture can be represented as the following diagram:
  * pointerdown-pointerup-pointerdown-*wait*-pointerup.
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
@@ -642,17 +642,17 @@ DwellEnd.prototype.type = 'dwellend';
 function TapHoldEnd(aTimeStamp, aPoints, aLastEvent) {
   this._inProgress = true;
   // If the pointer travels, reject to Explore.
   TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent);
   checkProgressGesture(this);
 }
 
 TapHoldEnd.prototype = Object.create(TravelGesture.prototype);
-TapHoldEnd.prototype.type = 'tapholdend';
+TapHoldEnd.prototype.type = "tapholdend";
 
 /**
  * DoubleTapHoldEnd gesture. This gesture can be represented as the following
  * diagram:
  * pointerdown-pointerup-pointerdown-pointerup-pointerdown-*wait*-pointerup.
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
@@ -661,17 +661,17 @@ TapHoldEnd.prototype.type = 'tapholdend'
 function DoubleTapHoldEnd(aTimeStamp, aPoints, aLastEvent) {
   this._inProgress = true;
   // If the pointer travels, reject to Explore.
   TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent);
   checkProgressGesture(this);
 }
 
 DoubleTapHoldEnd.prototype = Object.create(TravelGesture.prototype);
-DoubleTapHoldEnd.prototype.type = 'doubletapholdend';
+DoubleTapHoldEnd.prototype.type = "doubletapholdend";
 
 /**
  * A common tap gesture object.
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
  * @param {Function} aRejectToOnWait A constructor for the next gesture to
@@ -695,17 +695,17 @@ TapGesture.prototype._getDelay = functio
   // If, for TapGesture, no pointermove or pointerup happens within the
   // GestureSettings.dwellThreshold, reject.
   // Note: the original pointer event's timeStamp is irrelevant here.
   return GestureSettings.dwellThreshold;
 };
 
 TapGesture.prototype.pointerup = function TapGesture_pointerup(aPoints) {
     if (this._rejectToOnPointerDown) {
-      let complete = this._update(aPoints, 'pointerup', false, true);
+      let complete = this._update(aPoints, "pointerup", false, true);
       if (complete) {
         this.clearTimer();
         if (GestureSettings.maxGestureResolveTimeout) {
           this._pointerUpTimer = setTimeout(() => {
             clearTimeout(this._pointerUpTimer);
             delete this._pointerUpTimer;
             this._deferred.resolve();
           }, GestureSettings.maxGestureResolveTimeout);
@@ -737,48 +737,48 @@ TapGesture.prototype.pointerdown = funct
  * @param {?String} aLastEvent Last pointer event type.
  */
 function Tap(aTimeStamp, aPoints, aLastEvent) {
   // If the pointer travels, reject to Swipe.
   TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, Dwell, Swipe, DoubleTap);
 }
 
 Tap.prototype = Object.create(TapGesture.prototype);
-Tap.prototype.type = 'tap';
+Tap.prototype.type = "tap";
 
 
 /**
  * Double Tap gesture.
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
  */
 function DoubleTap(aTimeStamp, aPoints, aLastEvent) {
   this._inProgress = true;
   TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold, null, TripleTap);
 }
 
 DoubleTap.prototype = Object.create(TapGesture.prototype);
-DoubleTap.prototype.type = 'doubletap';
+DoubleTap.prototype.type = "doubletap";
 
 /**
  * Triple Tap gesture.
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
  */
 function TripleTap(aTimeStamp, aPoints, aLastEvent) {
   this._inProgress = true;
   TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, DoubleTapHold, null, null);
 }
 
 TripleTap.prototype = Object.create(TapGesture.prototype);
-TripleTap.prototype.type = 'tripletap';
+TripleTap.prototype.type = "tripletap";
 
 /**
  * Common base object for gestures that are created as resolved.
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
  */
@@ -797,63 +797,63 @@ ResolvedGesture.prototype = Object.creat
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
  */
 function Dwell(aTimeStamp, aPoints, aLastEvent) {
   ResolvedGesture.call(this, aTimeStamp, aPoints, aLastEvent);
 }
 
 Dwell.prototype = Object.create(ResolvedGesture.prototype);
-Dwell.prototype.type = 'dwell';
+Dwell.prototype.type = "dwell";
 Dwell.prototype.resolveTo = DwellEnd;
 
 /**
  * TapHold gesture
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
  */
 function TapHold(aTimeStamp, aPoints, aLastEvent) {
   ResolvedGesture.call(this, aTimeStamp, aPoints, aLastEvent);
 }
 
 TapHold.prototype = Object.create(ResolvedGesture.prototype);
-TapHold.prototype.type = 'taphold';
+TapHold.prototype.type = "taphold";
 TapHold.prototype.resolveTo = TapHoldEnd;
 
 /**
  * DoubleTapHold gesture
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
  */
 function DoubleTapHold(aTimeStamp, aPoints, aLastEvent) {
   ResolvedGesture.call(this, aTimeStamp, aPoints, aLastEvent);
 }
 
 DoubleTapHold.prototype = Object.create(ResolvedGesture.prototype);
-DoubleTapHold.prototype.type = 'doubletaphold';
+DoubleTapHold.prototype.type = "doubletaphold";
 DoubleTapHold.prototype.resolveTo = DoubleTapHoldEnd;
 
 /**
  * Explore gesture
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
  */
 function Explore(aTimeStamp, aPoints, aLastEvent) {
   ExploreGesture.call(this);
   ResolvedGesture.call(this, aTimeStamp, aPoints, aLastEvent);
 }
 
 Explore.prototype = Object.create(ResolvedGesture.prototype);
-Explore.prototype.type = 'explore';
+Explore.prototype.type = "explore";
 Explore.prototype.resolveTo = ExploreEnd;
 
 /**
  * ExploreEnd gesture.
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
@@ -862,34 +862,34 @@ function ExploreEnd(aTimeStamp, aPoints,
   this._inProgress = true;
   ExploreGesture.call(this);
   // If the pointer travels, reject to Explore.
   TravelGesture.call(this, aTimeStamp, aPoints, aLastEvent);
   checkProgressGesture(this);
 }
 
 ExploreEnd.prototype = Object.create(TravelGesture.prototype);
-ExploreEnd.prototype.type = 'exploreend';
+ExploreEnd.prototype.type = "exploreend";
 
 /**
  * Swipe gesture.
  * @param {Number} aTimeStamp An original pointer event's timeStamp that started
  * the gesture resolution sequence.
  * @param {Object} aPoints An existing set of points (from previous events).
  * @param {?String} aLastEvent Last pointer event type.
  */
 function Swipe(aTimeStamp, aPoints, aLastEvent) {
   this._inProgress = true;
   this._rejectToOnWait = Explore;
   Gesture.call(this, aTimeStamp, aPoints, aLastEvent);
   checkProgressGesture(this);
 }
 
 Swipe.prototype = Object.create(Gesture.prototype);
-Swipe.prototype.type = 'swipe';
+Swipe.prototype.type = "swipe";
 Swipe.prototype._getDelay = function Swipe__getDelay(aTimeStamp) {
   // Swipe should be completed within the GestureSettings.swipeMaxDuration from
   // the initial pointer down event.
   return GestureSettings.swipeMaxDuration - this.startTime + aTimeStamp;
 };
 
 /**
  * Determine wither the gesture was Swipe or Explore.
@@ -919,37 +919,37 @@ Swipe.prototype.test = function Swipe_te
 
 /**
  * Compile a swipe related mozAccessFuGesture event detail.
  * @return {Object} A mozAccessFuGesture detail object.
  */
 Swipe.prototype.compile = function Swipe_compile() {
   let type = this.type;
   let detail = compileDetail(type, this.points,
-    {x1: 'startX', y1: 'startY', x2: 'x', y2: 'y'});
+    {x1: "startX", y1: "startY", x2: "x", y2: "y"});
   let deltaX = detail.deltaX;
   let deltaY = detail.deltaY;
   let edge = EDGE * Utils.dpi;
   if (Math.abs(deltaX) > Math.abs(deltaY)) {
     // Horizontal swipe.
     let startPoints = detail.touches.map(touch => touch.x1);
     if (deltaX > 0) {
-      detail.type = type + 'right';
+      detail.type = type + "right";
       detail.edge = Math.min.apply(null, startPoints) <= edge;
     } else {
-      detail.type = type + 'left';
+      detail.type = type + "left";
       detail.edge =
         Utils.win.screen.width - Math.max.apply(null, startPoints) <= edge;
     }
   } else {
     // Vertical swipe.
     let startPoints = detail.touches.map(touch => touch.y1);
     if (deltaY > 0) {
-      detail.type = type + 'down';
+      detail.type = type + "down";
       detail.edge = Math.min.apply(null, startPoints) <= edge;
     } else {
-      detail.type = type + 'up';
+      detail.type = type + "up";
       detail.edge =
         Utils.win.screen.height - Math.max.apply(null, startPoints) <= edge;
     }
   }
   return detail;
 };
--- a/accessible/jsat/OutputGenerator.jsm
+++ b/accessible/jsat/OutputGenerator.jsm
@@ -1,40 +1,40 @@
 /* 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/. */
 
 /* exported UtteranceGenerator, BrailleGenerator */
 
-'use strict';
+"use strict";
 
 const {utils: Cu, interfaces: Ci} = Components;
 
 const INCLUDE_DESC = 0x01;
 const INCLUDE_NAME = 0x02;
 const INCLUDE_VALUE = 0x04;
 const NAME_FROM_SUBTREE_RULE = 0x10;
 const IGNORE_EXPLICIT_NAME = 0x20;
 
 const OUTPUT_DESC_FIRST = 0;
 const OUTPUT_DESC_LAST = 1;
 
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Utils', // jshint ignore:line
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'PrefCache', // jshint ignore:line
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Logger', // jshint ignore:line
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Roles', // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'States', // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Utils", // jshint ignore:line
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PrefCache", // jshint ignore:line
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Logger", // jshint ignore:line
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Roles", // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "States", // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
 
-this.EXPORTED_SYMBOLS = ['UtteranceGenerator', 'BrailleGenerator']; // jshint ignore:line
+this.EXPORTED_SYMBOLS = ["UtteranceGenerator", "BrailleGenerator"]; // jshint ignore:line
 
 var OutputGenerator = {
 
   defaultOutputOrder: OUTPUT_DESC_LAST,
 
   /**
    * Generates output for a PivotContext.
    * @param {PivotContext} aContext object that generates and caches
@@ -52,17 +52,17 @@ var OutputGenerator = {
     };
     let ignoreSubtree = function ignoreSubtree(aAccessible) {
       let roleString = Utils.AccService.getStringRole(aAccessible.role);
       let nameRule = self.roleRuleMap[roleString] || 0;
       // Ignore subtree if the name is explicit and the role's name rule is the
       // NAME_FROM_SUBTREE_RULE.
       return (((nameRule & INCLUDE_VALUE) && aAccessible.value) ||
               ((nameRule & NAME_FROM_SUBTREE_RULE) &&
-               (Utils.getAttributes(aAccessible)['explicit-name'] === 'true' &&
+               (Utils.getAttributes(aAccessible)["explicit-name"] === "true" &&
                !(nameRule & IGNORE_EXPLICIT_NAME))));
     };
 
     let contextStart = this._getContextStart(aContext);
 
     if (this.outputOrder === OUTPUT_DESC_FIRST) {
       contextStart.forEach(addOutput);
       addOutput(aContext.accessible);
@@ -161,65 +161,65 @@ var OutputGenerator = {
   /**
    * Adds an accessible name and description to the output if available.
    * @param {Array} aOutput Output array.
    * @param {nsIAccessible} aAccessible current accessible object.
    * @param {Number} aFlags output flags.
    */
   _addName: function _addName(aOutput, aAccessible, aFlags) {
     let name;
-    if ((Utils.getAttributes(aAccessible)['explicit-name'] === 'true' &&
+    if ((Utils.getAttributes(aAccessible)["explicit-name"] === "true" &&
          !(aFlags & IGNORE_EXPLICIT_NAME)) || (aFlags & INCLUDE_NAME)) {
       name = aAccessible.name;
     }
 
     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 = name || "";
         name = this.outputOrder === OUTPUT_DESC_FIRST ?
-          description + ' - ' + name :
-          name + ' - ' + description;
+          description + " - " + name :
+          name + " - " + description;
       }
     }
 
     if (!name || !name.trim()) {
       return;
     }
-    aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'push' : 'unshift'](name);
+    aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? "push" : "unshift"](name);
   },
 
   /**
    * Adds a landmark role to the output if available.
    * @param {Array} aOutput Output array.
    * @param {nsIAccessible} aAccessible current accessible object.
    */
   _addLandmark: function _addLandmark(aOutput, aAccessible) {
     let landmarkName = Utils.getLandmarkName(aAccessible);
     if (!landmarkName) {
       return;
     }
-    aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'unshift' : 'push']({
+    aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? "unshift" : "push"]({
       string: landmarkName
     });
   },
 
   /**
    * Adds math roles to the output, for a MathML accessible.
    * @param {Array} aOutput Output array.
    * @param {nsIAccessible} aAccessible current accessible object.
    * @param {String} aRoleStr aAccessible's role string.
    */
   _addMathRoles: function _addMathRoles(aOutput, aAccessible, aRoleStr) {
     // First, determine the actual role to use (e.g. mathmlfraction).
     let roleStr = aRoleStr;
-    switch(aAccessible.role) {
+    switch (aAccessible.role) {
       case Roles.MATHML_CELL:
       case Roles.MATHML_ENCLOSED:
       case Roles.MATHML_LABELED_ROW:
       case Roles.MATHML_ROOT:
       case Roles.MATHML_SQUARE_ROOT:
       case Roles.MATHML_TABLE:
       case Roles.MATHML_TABLE_ROW:
         // Use the default role string.
@@ -227,198 +227,198 @@ var OutputGenerator = {
       case Roles.MATHML_MULTISCRIPTS:
       case Roles.MATHML_OVER:
       case Roles.MATHML_SUB:
       case Roles.MATHML_SUB_SUP:
       case Roles.MATHML_SUP:
       case Roles.MATHML_UNDER:
       case Roles.MATHML_UNDER_OVER:
         // For scripted accessibles, use the string 'mathmlscripted'.
-        roleStr = 'mathmlscripted';
+        roleStr = "mathmlscripted";
         break;
       case Roles.MATHML_FRACTION:
         // From a semantic point of view, the only important point is to
         // distinguish between fractions that have a bar and those that do not.
         // Per the MathML 3 spec, the latter happens iff the linethickness
         // attribute is of the form [zero-float][optional-unit]. In that case,
         // we use the string 'mathmlfractionwithoutbar'.
         let linethickness = Utils.getAttributes(aAccessible).linethickness;
         if (linethickness) {
             let numberMatch = linethickness.match(/^(?:\d|\.)+/);
             if (numberMatch && !parseFloat(numberMatch[0])) {
-                roleStr += 'withoutbar';
+                roleStr += "withoutbar";
             }
         }
         break;
       default:
         // Otherwise, do not output the actual role.
         roleStr = null;
         break;
     }
 
     // Get the math role based on the position in the parent accessible
     // (e.g. numerator for the first child of a mathmlfraction).
     let mathRole = Utils.getMathRole(aAccessible);
     if (mathRole) {
-      aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'push' : 'unshift']
-        ({string: this._getOutputName(mathRole)});
+      aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? "push" : "unshift"]({
+        string: this._getOutputName(mathRole)});
     }
     if (roleStr) {
-      aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'push' : 'unshift']
-        ({string: this._getOutputName(roleStr)});
+      aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? "push" : "unshift"]({
+        string: this._getOutputName(roleStr)});
     }
   },
 
   /**
    * Adds MathML menclose notations to the output.
    * @param {Array} aOutput Output array.
    * @param {nsIAccessible} aAccessible current accessible object.
    */
   _addMencloseNotations: function _addMencloseNotations(aOutput, aAccessible) {
-    let notations = Utils.getAttributes(aAccessible).notation || 'longdiv';
-    aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'push' : 'unshift'].apply(
-      aOutput, notations.split(' ').map(notation => {
-        return { string: this._getOutputName('notation-' + notation) };
+    let notations = Utils.getAttributes(aAccessible).notation || "longdiv";
+    aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? "push" : "unshift"].apply(
+      aOutput, notations.split(" ").map(notation => {
+        return { string: this._getOutputName("notation-" + notation) };
       }));
   },
 
   /**
    * Adds an entry type attribute to the description if available.
    * @param {Array} aOutput Output array.
    * @param {nsIAccessible} aAccessible current accessible object.
    * @param {String} aRoleStr aAccessible's role string.
    */
   _addType: function _addType(aOutput, aAccessible, aRoleStr) {
-    if (aRoleStr !== 'entry') {
+    if (aRoleStr !== "entry") {
       return;
     }
 
-    let typeName = Utils.getAttributes(aAccessible)['text-input-type'];
+    let typeName = Utils.getAttributes(aAccessible)["text-input-type"];
     // Ignore the the input type="text" case.
-    if (!typeName || typeName === 'text') {
+    if (!typeName || typeName === "text") {
       return;
     }
-    aOutput.push({string: 'textInputType_' + typeName});
+    aOutput.push({string: "textInputType_" + typeName});
   },
 
   _addState: function _addState(aOutput, aState, aRoleStr) {}, // jshint ignore:line
 
   _addRole: function _addRole(aOutput, aAccessible, aRoleStr) {}, // jshint ignore:line
 
   get outputOrder() {
     if (!this._utteranceOrder) {
-      this._utteranceOrder = new PrefCache('accessibility.accessfu.utterance');
+      this._utteranceOrder = new PrefCache("accessibility.accessfu.utterance");
     }
-    return typeof this._utteranceOrder.value === 'number' ?
+    return typeof this._utteranceOrder.value === "number" ?
       this._utteranceOrder.value : this.defaultOutputOrder;
   },
 
   _getOutputName: function _getOutputName(aName) {
-    return aName.replace(/\s/g, '');
+    return aName.replace(/\s/g, "");
   },
 
   roleRuleMap: {
-    'menubar': INCLUDE_DESC,
-    'scrollbar': INCLUDE_DESC,
-    'grip': INCLUDE_DESC,
-    'alert': INCLUDE_DESC | INCLUDE_NAME,
-    'menupopup': INCLUDE_DESC,
-    'menuitem': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'tooltip': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'columnheader': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'rowheader': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'column': NAME_FROM_SUBTREE_RULE,
-    'row': NAME_FROM_SUBTREE_RULE,
-    'cell': INCLUDE_DESC | INCLUDE_NAME,
-    'application': INCLUDE_NAME,
-    'document': INCLUDE_NAME,
-    'grouping': INCLUDE_DESC | INCLUDE_NAME,
-    'toolbar': INCLUDE_DESC,
-    'table': INCLUDE_DESC | INCLUDE_NAME,
-    'link': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'helpballoon': NAME_FROM_SUBTREE_RULE,
-    'list': INCLUDE_DESC | INCLUDE_NAME,
-    'listitem': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'outline': INCLUDE_DESC,
-    'outlineitem': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'pagetab': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'graphic': INCLUDE_DESC,
-    'switch': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'pushbutton': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'checkbutton': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'radiobutton': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'buttondropdown': NAME_FROM_SUBTREE_RULE,
-    'combobox': INCLUDE_DESC | INCLUDE_VALUE,
-    'droplist': INCLUDE_DESC,
-    'progressbar': INCLUDE_DESC | INCLUDE_VALUE,
-    'slider': INCLUDE_DESC | INCLUDE_VALUE,
-    'spinbutton': INCLUDE_DESC | INCLUDE_VALUE,
-    'diagram': INCLUDE_DESC,
-    'animation': INCLUDE_DESC,
-    'equation': INCLUDE_DESC,
-    'buttonmenu': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'buttondropdowngrid': NAME_FROM_SUBTREE_RULE,
-    'pagetablist': INCLUDE_DESC,
-    'canvas': INCLUDE_DESC,
-    'check menu item': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'label': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'password text': INCLUDE_DESC,
-    'popup menu': INCLUDE_DESC,
-    'radio menu item': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'table column header': NAME_FROM_SUBTREE_RULE,
-    'table row header': NAME_FROM_SUBTREE_RULE,
-    'tear off menu item': NAME_FROM_SUBTREE_RULE,
-    'toggle button': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'parent menuitem': NAME_FROM_SUBTREE_RULE,
-    'header': INCLUDE_DESC,
-    'footer': INCLUDE_DESC,
-    'entry': INCLUDE_DESC | INCLUDE_NAME | INCLUDE_VALUE,
-    'caption': INCLUDE_DESC,
-    'document frame': INCLUDE_DESC,
-    'heading': INCLUDE_DESC,
-    'calendar': INCLUDE_DESC | INCLUDE_NAME,
-    'combobox option': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'listbox option': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
-    'listbox rich option': NAME_FROM_SUBTREE_RULE,
-    'gridcell': NAME_FROM_SUBTREE_RULE,
-    'check rich option': NAME_FROM_SUBTREE_RULE,
-    'term': NAME_FROM_SUBTREE_RULE,
-    'definition': NAME_FROM_SUBTREE_RULE,
-    'key': NAME_FROM_SUBTREE_RULE,
-    'image map': INCLUDE_DESC,
-    'option': INCLUDE_DESC,
-    'listbox': INCLUDE_DESC,
-    'definitionlist': INCLUDE_DESC | INCLUDE_NAME,
-    'dialog': INCLUDE_DESC | INCLUDE_NAME,
-    'chrome window': IGNORE_EXPLICIT_NAME,
-    'app root': IGNORE_EXPLICIT_NAME,
-    'statusbar': NAME_FROM_SUBTREE_RULE,
-    'mathml table': INCLUDE_DESC | INCLUDE_NAME,
-    'mathml labeled row': NAME_FROM_SUBTREE_RULE,
-    'mathml table row': NAME_FROM_SUBTREE_RULE,
-    'mathml cell': INCLUDE_DESC | INCLUDE_NAME,
-    'mathml fraction': INCLUDE_DESC,
-    'mathml square root': INCLUDE_DESC,
-    'mathml root': INCLUDE_DESC,
-    'mathml enclosed': INCLUDE_DESC,
-    'mathml sub': INCLUDE_DESC,
-    'mathml sup': INCLUDE_DESC,
-    'mathml sub sup': INCLUDE_DESC,
-    'mathml under': INCLUDE_DESC,
-    'mathml over': INCLUDE_DESC,
-    'mathml under over': INCLUDE_DESC,
-    'mathml multiscripts': INCLUDE_DESC,
-    'mathml identifier': INCLUDE_DESC,
-    'mathml number': INCLUDE_DESC,
-    'mathml operator': INCLUDE_DESC,
-    'mathml text': INCLUDE_DESC,
-    'mathml string literal': INCLUDE_DESC,
-    'mathml row': INCLUDE_DESC,
-    'mathml style': INCLUDE_DESC,
-    'mathml error': INCLUDE_DESC },
+    "menubar": INCLUDE_DESC,
+    "scrollbar": INCLUDE_DESC,
+    "grip": INCLUDE_DESC,
+    "alert": INCLUDE_DESC | INCLUDE_NAME,
+    "menupopup": INCLUDE_DESC,
+    "menuitem": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "tooltip": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "columnheader": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "rowheader": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "column": NAME_FROM_SUBTREE_RULE,
+    "row": NAME_FROM_SUBTREE_RULE,
+    "cell": INCLUDE_DESC | INCLUDE_NAME,
+    "application": INCLUDE_NAME,
+    "document": INCLUDE_NAME,
+    "grouping": INCLUDE_DESC | INCLUDE_NAME,
+    "toolbar": INCLUDE_DESC,
+    "table": INCLUDE_DESC | INCLUDE_NAME,
+    "link": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "helpballoon": NAME_FROM_SUBTREE_RULE,
+    "list": INCLUDE_DESC | INCLUDE_NAME,
+    "listitem": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "outline": INCLUDE_DESC,
+    "outlineitem": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "pagetab": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "graphic": INCLUDE_DESC,
+    "switch": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "pushbutton": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "checkbutton": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "radiobutton": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "buttondropdown": NAME_FROM_SUBTREE_RULE,
+    "combobox": INCLUDE_DESC | INCLUDE_VALUE,
+    "droplist": INCLUDE_DESC,
+    "progressbar": INCLUDE_DESC | INCLUDE_VALUE,
+    "slider": INCLUDE_DESC | INCLUDE_VALUE,
+    "spinbutton": INCLUDE_DESC | INCLUDE_VALUE,
+    "diagram": INCLUDE_DESC,
+    "animation": INCLUDE_DESC,
+    "equation": INCLUDE_DESC,
+    "buttonmenu": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "buttondropdowngrid": NAME_FROM_SUBTREE_RULE,
+    "pagetablist": INCLUDE_DESC,
+    "canvas": INCLUDE_DESC,
+    "check menu item": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "label": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "password text": INCLUDE_DESC,
+    "popup menu": INCLUDE_DESC,
+    "radio menu item": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "table column header": NAME_FROM_SUBTREE_RULE,
+    "table row header": NAME_FROM_SUBTREE_RULE,
+    "tear off menu item": NAME_FROM_SUBTREE_RULE,
+    "toggle button": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "parent menuitem": NAME_FROM_SUBTREE_RULE,
+    "header": INCLUDE_DESC,
+    "footer": INCLUDE_DESC,
+    "entry": INCLUDE_DESC | INCLUDE_NAME | INCLUDE_VALUE,
+    "caption": INCLUDE_DESC,
+    "document frame": INCLUDE_DESC,
+    "heading": INCLUDE_DESC,
+    "calendar": INCLUDE_DESC | INCLUDE_NAME,
+    "combobox option": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "listbox option": INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
+    "listbox rich option": NAME_FROM_SUBTREE_RULE,
+    "gridcell": NAME_FROM_SUBTREE_RULE,
+    "check rich option": NAME_FROM_SUBTREE_RULE,
+    "term": NAME_FROM_SUBTREE_RULE,
+    "definition": NAME_FROM_SUBTREE_RULE,
+    "key": NAME_FROM_SUBTREE_RULE,
+    "image map": INCLUDE_DESC,
+    "option": INCLUDE_DESC,
+    "listbox": INCLUDE_DESC,
+    "definitionlist": INCLUDE_DESC | INCLUDE_NAME,
+    "dialog": INCLUDE_DESC | INCLUDE_NAME,
+    "chrome window": IGNORE_EXPLICIT_NAME,
+    "app root": IGNORE_EXPLICIT_NAME,
+    "statusbar": NAME_FROM_SUBTREE_RULE,
+    "mathml table": INCLUDE_DESC | INCLUDE_NAME,
+    "mathml labeled row": NAME_FROM_SUBTREE_RULE,
+    "mathml table row": NAME_FROM_SUBTREE_RULE,
+    "mathml cell": INCLUDE_DESC | INCLUDE_NAME,
+    "mathml fraction": INCLUDE_DESC,
+    "mathml square root": INCLUDE_DESC,
+    "mathml root": INCLUDE_DESC,
+    "mathml enclosed": INCLUDE_DESC,
+    "mathml sub": INCLUDE_DESC,
+    "mathml sup": INCLUDE_DESC,
+    "mathml sub sup": INCLUDE_DESC,
+    "mathml under": INCLUDE_DESC,
+    "mathml over": INCLUDE_DESC,
+    "mathml under over": INCLUDE_DESC,
+    "mathml multiscripts": INCLUDE_DESC,
+    "mathml identifier": INCLUDE_DESC,
+    "mathml number": INCLUDE_DESC,
+    "mathml operator": INCLUDE_DESC,
+    "mathml text": INCLUDE_DESC,
+    "mathml string literal": INCLUDE_DESC,
+    "mathml row": INCLUDE_DESC,
+    "mathml style": INCLUDE_DESC,
+    "mathml error": INCLUDE_DESC },
 
   mathmlRolesSet: new Set([
     Roles.MATHML_MATH,
     Roles.MATHML_IDENTIFIER,
     Roles.MATHML_NUMBER,
     Roles.MATHML_OPERATOR,
     Roles.MATHML_TEXT,
     Roles.MATHML_STRING_LITERAL,
@@ -459,17 +459,17 @@ var OutputGenerator = {
 
         if (aFlags & INCLUDE_DESC) {
           this._addState(output, aState, aRoleStr);
           this._addType(output, aAccessible, aRoleStr);
           this._addRole(output, aAccessible, aRoleStr);
         }
 
         if (aFlags & INCLUDE_VALUE && aAccessible.value.trim()) {
-          output[this.outputOrder === OUTPUT_DESC_FIRST ? 'push' : 'unshift'](
+          output[this.outputOrder === OUTPUT_DESC_FIRST ? "push" : "unshift"](
             aAccessible.value);
         }
 
         this._addName(output, aAccessible, aFlags);
         this._addLandmark(output, aAccessible);
 
         return output;
       },
@@ -481,30 +481,30 @@ var OutputGenerator = {
         // we don't need the context.
         return [];
       }
 
       return this.objectOutputFunctions.defaultFunc.apply(this, arguments);
     },
 
     entry: function entry(aAccessible, aRoleStr, aState, aFlags) {
-      let rolestr = aState.contains(States.MULTI_LINE) ? 'textarea' : 'entry';
+      let rolestr = aState.contains(States.MULTI_LINE) ? "textarea" : "entry";
       return this.objectOutputFunctions.defaultFunc.apply(
         this, [aAccessible, rolestr, aState, aFlags]);
     },
 
     pagetab: function pagetab(aAccessible, aRoleStr, aState, aFlags) {
       let itemno = {};
       let itemof = {};
       aAccessible.groupPosition({}, itemof, itemno);
       let output = [];
       this._addState(output, aState);
       this._addRole(output, aAccessible, aRoleStr);
       output.push({
-        string: 'objItemOfN',
+        string: "objItemOfN",
         args: [itemno.value, itemof.value]
       });
 
       this._addName(output, aAccessible, aFlags);
       this._addLandmark(output, aAccessible);
 
       return output;
     },
@@ -520,20 +520,20 @@ var OutputGenerator = {
       } finally {
         // Check if it's a layout table, and bail out if true.
         // We don't want to speak any table information for layout tables.
         if (table.isProbablyForLayout()) {
           return output;
         }
         this._addRole(output, aAccessible, aRoleStr);
         output.push.call(output, {
-          string: this._getOutputName('tblColumnInfo'),
+          string: this._getOutputName("tblColumnInfo"),
           count: table.columnCount
         }, {
-          string: this._getOutputName('tblRowInfo'),
+          string: this._getOutputName("tblRowInfo"),
           count: table.rowCount
         });
         this._addName(output, aAccessible, aFlags);
         this._addLandmark(output, aAccessible);
         return output;
       }
     },
 
@@ -579,124 +579,123 @@ var OutputGenerator = {
  * For example {@link genForAction} might return ['button', 'clicked'] for a
  * clicked event. Speaking only 'clicked' makes sense. Speaking 'button' does
  * not.
  */
 this.UtteranceGenerator = {  // jshint ignore:line
   __proto__: OutputGenerator, // jshint ignore:line
 
   gActionMap: {
-    jump: 'jumpAction',
-    press: 'pressAction',
-    check: 'checkAction',
-    uncheck: 'uncheckAction',
-    on: 'onAction',
-    off: 'offAction',
-    select: 'selectAction',
-    unselect: 'unselectAction',
-    open: 'openAction',
-    close: 'closeAction',
-    switch: 'switchAction',
-    click: 'clickAction',
-    collapse: 'collapseAction',
-    expand: 'expandAction',
-    activate: 'activateAction',
-    cycle: 'cycleAction'
+    jump: "jumpAction",
+    press: "pressAction",
+    check: "checkAction",
+    uncheck: "uncheckAction",
+    on: "onAction",
+    off: "offAction",
+    select: "selectAction",
+    unselect: "unselectAction",
+    open: "openAction",
+    close: "closeAction",
+    switch: "switchAction",
+    click: "clickAction",
+    collapse: "collapseAction",
+    expand: "expandAction",
+    activate: "activateAction",
+    cycle: "cycleAction"
   },
 
-  //TODO: May become more verbose in the future.
+  // TODO: May become more verbose in the future.
   genForAction: function genForAction(aObject, aActionName) {
     return [{string: this.gActionMap[aActionName]}];
   },
 
   genForLiveRegion:
     function genForLiveRegion(aContext, aIsHide, aModifiedText) {
       let utterance = [];
       if (aIsHide) {
-        utterance.push({string: 'hidden'});
+        utterance.push({string: "hidden"});
       }
       return utterance.concat(aModifiedText || this.genForContext(aContext));
     },
 
   genForAnnouncement: function genForAnnouncement(aAnnouncement) {
     return [{
       string: aAnnouncement
     }];
   },
 
   genForTabStateChange: function genForTabStateChange(aObject, aTabState) {
     switch (aTabState) {
-      case 'newtab':
-        return [{string: 'tabNew'}];
-      case 'loading':
-        return [{string: 'tabLoading'}];
-      case 'loaded':
-        return [aObject.name, {string: 'tabLoaded'}];
-      case 'loadstopped':
-        return [{string: 'tabLoadStopped'}];
-      case 'reload':
-        return [{string: 'tabReload'}];
+      case "newtab":
+        return [{string: "tabNew"}];
+      case "loading":
+        return [{string: "tabLoading"}];
+      case "loaded":
+        return [aObject.name, {string: "tabLoaded"}];
+      case "loadstopped":
+        return [{string: "tabLoadStopped"}];
+      case "reload":
+        return [{string: "tabReload"}];
       default:
         return [];
     }
   },
 
   genForEditingMode: function genForEditingMode(aIsEditing) {
-    return [{string: aIsEditing ? 'editingMode' : 'navigationMode'}];
+    return [{string: aIsEditing ? "editingMode" : "navigationMode"}];
   },
 
   objectOutputFunctions: {
 
     __proto__: OutputGenerator.objectOutputFunctions, // jshint ignore:line
 
     defaultFunc: function defaultFunc() {
       return this.objectOutputFunctions._generateBaseOutput.apply(
         this, arguments);
     },
 
     heading: function heading(aAccessible, aRoleStr, aState, aFlags) {
       let level = {};
       aAccessible.groupPosition(level, {}, {});
-      let utterance = [{string: 'headingLevel', args: [level.value]}];
+      let utterance = [{string: "headingLevel", args: [level.value]}];
 
       this._addName(utterance, aAccessible, aFlags);
       this._addLandmark(utterance, aAccessible);
 
       return utterance;
     },
 
     listitem: function listitem(aAccessible, aRoleStr, aState, aFlags) {
       let itemno = {};
       let itemof = {};
       aAccessible.groupPosition({}, itemof, itemno);
       let utterance = [];
       if (itemno.value == 1) {
         // Start of list
-        utterance.push({string: 'listStart'});
-      }
-      else if (itemno.value == itemof.value) {
+        utterance.push({string: "listStart"});
+      } else if (itemno.value == itemof.value) {
         // last item
-        utterance.push({string: 'listEnd'});
+        utterance.push({string: "listEnd"});
       }
 
       this._addName(utterance, aAccessible, aFlags);
       this._addLandmark(utterance, aAccessible);
 
       return utterance;
     },
 
     list: function list(aAccessible, aRoleStr, aState, aFlags) {
-      return this._getListUtterance
-        (aAccessible, aRoleStr, aFlags, aAccessible.childCount);
+      return this._getListUtterance(aAccessible, aRoleStr, aFlags,
+        aAccessible.childCount);
     },
 
     definitionlist:
       function definitionlist(aAccessible, aRoleStr, aState, aFlags) {
-        return this._getListUtterance
-          (aAccessible, aRoleStr, aFlags, aAccessible.childCount / 2);
+        return this._getListUtterance(aAccessible, aRoleStr, aFlags,
+          aAccessible.childCount / 2);
       },
 
     application: function application(aAccessible, aRoleStr, aState, aFlags) {
       // Don't utter location of applications, it gets tiring.
       if (aAccessible.name != aAccessible.DOMNode.location) {
         return this.objectOutputFunctions.defaultFunc.apply(this,
           [aAccessible, aRoleStr, aState, aFlags]);
       }
@@ -720,22 +719,22 @@ this.UtteranceGenerator = {  // jshint i
           }
         };
         let addHeaders = function addHeaders(aUtterance, aHeaders) {
           if (aHeaders.length > 0) {
             aUtterance.push.apply(aUtterance, aHeaders);
           }
         };
 
-        addCellChanged(utterance, cell.columnChanged, 'columnInfo',
+        addCellChanged(utterance, cell.columnChanged, "columnInfo",
           cell.columnIndex);
-        addCellChanged(utterance, cell.rowChanged, 'rowInfo', cell.rowIndex);
+        addCellChanged(utterance, cell.rowChanged, "rowInfo", cell.rowIndex);
 
-        addExtent(utterance, cell.columnExtent, 'spansColumns');
-        addExtent(utterance, cell.rowExtent, 'spansRows');
+        addExtent(utterance, cell.columnExtent, "spansColumns");
+        addExtent(utterance, cell.rowExtent, "spansRows");
 
         addHeaders(utterance, cell.columnHeaders);
         addHeaders(utterance, cell.rowHeaders);
       }
 
       this._addName(utterance, aAccessible, aFlags);
       this._addLandmark(utterance, aAccessible);
 
@@ -769,72 +768,72 @@ this.UtteranceGenerator = {  // jshint i
     } else {
       aOutput.push({string: this._getOutputName(aRoleStr)});
     }
   },
 
   _addState: function _addState(aOutput, aState, aRoleStr) {
 
     if (aState.contains(States.UNAVAILABLE)) {
-      aOutput.push({string: 'stateUnavailable'});
+      aOutput.push({string: "stateUnavailable"});
     }
 
     if (aState.contains(States.READONLY)) {
-      aOutput.push({string: 'stateReadonly'});
+      aOutput.push({string: "stateReadonly"});
     }
 
     // Don't utter this in Jelly Bean, we let TalkBack do it for us there.
     // This is because we expose the checked information on the node itself.
     // XXX: this means the checked state is always appended to the end,
     // regardless of the utterance ordering preference.
-    if ((Utils.AndroidSdkVersion < 16 || Utils.MozBuildApp === 'browser') &&
+    if ((Utils.AndroidSdkVersion < 16 || Utils.MozBuildApp === "browser") &&
       aState.contains(States.CHECKABLE)) {
       let checked = aState.contains(States.CHECKED);
       let statetr;
-      if (aRoleStr === 'switch') {
-        statetr = checked ? 'stateOn' : 'stateOff';
+      if (aRoleStr === "switch") {
+        statetr = checked ? "stateOn" : "stateOff";
       } else {
-        statetr = checked ? 'stateChecked' : 'stateNotChecked';
+        statetr = checked ? "stateChecked" : "stateNotChecked";
       }
       aOutput.push({string: statetr});
     }
 
     if (aState.contains(States.PRESSED)) {
-      aOutput.push({string: 'statePressed'});
+      aOutput.push({string: "statePressed"});
     }
 
     if (aState.contains(States.EXPANDABLE)) {
       let statetr = aState.contains(States.EXPANDED) ?
-        'stateExpanded' : 'stateCollapsed';
+        "stateExpanded" : "stateCollapsed";
       aOutput.push({string: statetr});
     }
 
     if (aState.contains(States.REQUIRED)) {
-      aOutput.push({string: 'stateRequired'});
+      aOutput.push({string: "stateRequired"});
     }
 
     if (aState.contains(States.TRAVERSED)) {
-      aOutput.push({string: 'stateTraversed'});
+      aOutput.push({string: "stateTraversed"});
     }
 
     if (aState.contains(States.HASPOPUP)) {
-      aOutput.push({string: 'stateHasPopup'});
+      aOutput.push({string: "stateHasPopup"});
     }
 
     if (aState.contains(States.SELECTED)) {
-      aOutput.push({string: 'stateSelected'});
+      aOutput.push({string: "stateSelected"});
     }
   },
 
   _getListUtterance:
     function _getListUtterance(aAccessible, aRoleStr, aFlags, aItemCount) {
       let utterance = [];
       this._addRole(utterance, aAccessible, aRoleStr);
       utterance.push({
-        string: this._getOutputName('listItemsCount'),
+        string: this._getOutputName("listItemsCount"),
         count: aItemCount
       });
 
       this._addName(utterance, aAccessible, aFlags);
       this._addLandmark(utterance, aAccessible);
 
       return utterance;
     }
@@ -846,32 +845,32 @@ this.BrailleGenerator = {  // jshint ign
   genForContext: function genForContext(aContext) {
     let output = OutputGenerator.genForContext.apply(this, arguments);
 
     let acc = aContext.accessible;
 
     // add the static text indicating a list item; do this for both listitems or
     // direct first children of listitems, because these are both common
     // browsing scenarios
-    let addListitemIndicator = function addListitemIndicator(indicator = '*') {
+    let addListitemIndicator = function addListitemIndicator(indicator = "*") {
       output.unshift(indicator);
     };
 
     if (acc.indexInParent === 1 &&
         acc.parent.role == Roles.LISTITEM &&
         acc.previousSibling.role == Roles.STATICTEXT) {
       if (acc.parent.parent && acc.parent.parent.DOMNode &&
-          acc.parent.parent.DOMNode.nodeName == 'UL') {
+          acc.parent.parent.DOMNode.nodeName == "UL") {
         addListitemIndicator();
       } else {
         addListitemIndicator(acc.previousSibling.name.trim());
       }
     } else if (acc.role == Roles.LISTITEM && acc.firstChild &&
                acc.firstChild.role == Roles.STATICTEXT) {
-      if (acc.parent.DOMNode.nodeName == 'UL') {
+      if (acc.parent.DOMNode.nodeName == "UL") {
         addListitemIndicator();
       } else {
         addListitemIndicator(acc.firstChild.name.trim());
       }
     }
 
     return output;
   },
@@ -900,17 +899,17 @@ this.BrailleGenerator = {  // jshint ign
       if (cell) {
         let addHeaders = function addHeaders(aBraille, aHeaders) {
           if (aHeaders.length > 0) {
             aBraille.push.apply(aBraille, aHeaders);
           }
         };
 
         braille.push({
-          string: this._getOutputName('cellInfo'),
+          string: this._getOutputName("cellInfo"),
           args: [cell.columnIndex + 1, cell.rowIndex + 1]
         });
 
         addHeaders(braille, cell.columnHeaders);
         addHeaders(braille, cell.rowHeaders);
       }
 
       this._addName(braille, aAccessible, aFlags);
@@ -967,36 +966,36 @@ this.BrailleGenerator = {  // jshint ign
     if (aContext.accessible.parent.role == Roles.LINK) {
       return [aContext.accessible.parent];
     }
 
     return [];
   },
 
   _getOutputName: function _getOutputName(aName) {
-    return OutputGenerator._getOutputName(aName) + 'Abbr';
+    return OutputGenerator._getOutputName(aName) + "Abbr";
   },
 
   _addRole: function _addRole(aBraille, aAccessible, aRoleStr) {
     if (this.mathmlRolesSet.has(aAccessible.role)) {
       this._addMathRoles(aBraille, aAccessible, aRoleStr);
     } else {
       aBraille.push({string: this._getOutputName(aRoleStr)});
     }
   },
 
   _addState: function _addState(aBraille, aState, aRoleStr) {
     if (aState.contains(States.CHECKABLE)) {
       aBraille.push({
         string: aState.contains(States.CHECKED) ?
-          this._getOutputName('stateChecked') :
-          this._getOutputName('stateUnchecked')
+          this._getOutputName("stateChecked") :
+          this._getOutputName("stateUnchecked")
       });
     }
-    if (aRoleStr === 'toggle button') {
+    if (aRoleStr === "toggle button") {
       aBraille.push({
         string: aState.contains(States.PRESSED) ?
-          this._getOutputName('statePressed') :
-          this._getOutputName('stateUnpressed')
+          this._getOutputName("statePressed") :
+          this._getOutputName("stateUnpressed")
       });
     }
   }
 };
--- a/accessible/jsat/PointerAdapter.jsm
+++ b/accessible/jsat/PointerAdapter.jsm
@@ -1,130 +1,130 @@
 /* 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/. */
 
 /* exported PointerRelay, PointerAdapter */
 
-'use strict';
+"use strict";
 
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
-this.EXPORTED_SYMBOLS = ['PointerRelay', 'PointerAdapter']; // jshint ignore:line
+this.EXPORTED_SYMBOLS = ["PointerRelay", "PointerAdapter"]; // jshint ignore:line
 
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, 'Utils', // jshint ignore:line
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Logger', // jshint ignore:line
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'GestureSettings', // jshint ignore:line
-  'resource://gre/modules/accessibility/Gestures.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'GestureTracker', // jshint ignore:line
-  'resource://gre/modules/accessibility/Gestures.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, "Utils", // jshint ignore:line
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Logger", // jshint ignore:line
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "GestureSettings", // jshint ignore:line
+  "resource://gre/modules/accessibility/Gestures.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "GestureTracker", // jshint ignore:line
+  "resource://gre/modules/accessibility/Gestures.jsm");
 
 // The virtual touch ID generated by a mouse event.
-const MOUSE_ID = 'mouse';
+const MOUSE_ID = "mouse";
 // Synthesized touch ID.
 const SYNTH_ID = -1;
 
 var PointerRelay = { // jshint ignore:line
   /**
    * A mapping of events we should be intercepting. Entries with a value of
    * |true| are used for compiling high-level gesture events. Entries with a
    * value of |false| are cancelled and do not propogate to content.
    */
   get _eventsOfInterest() {
     delete this._eventsOfInterest;
 
     switch (Utils.widgetToolkit) {
-      case 'android':
+      case "android":
         this._eventsOfInterest = {
-          'touchstart' : true,
-          'touchmove' : true,
-          'touchend' : true };
+          "touchstart": true,
+          "touchmove": true,
+          "touchend": true };
         break;
 
-      case 'gonk':
+      case "gonk":
         this._eventsOfInterest = {
-          'touchstart' : true,
-          'touchmove' : true,
-          'touchend' : true,
-          'mousedown' : false,
-          'mousemove' : false,
-          'mouseup': false,
-          'click': false };
+          "touchstart": true,
+          "touchmove": true,
+          "touchend": true,
+          "mousedown": false,
+          "mousemove": false,
+          "mouseup": false,
+          "click": false };
         break;
 
       default:
         // Desktop.
         this._eventsOfInterest = {
-          'mousemove' : true,
-          'mousedown' : true,
-          'mouseup': true,
-          'click': false
+          "mousemove": true,
+          "mousedown": true,
+          "mouseup": true,
+          "click": false
         };
-        if ('ontouchstart' in Utils.win) {
-          for (let eventType of ['touchstart', 'touchmove', 'touchend']) {
+        if ("ontouchstart" in Utils.win) {
+          for (let eventType of ["touchstart", "touchmove", "touchend"]) {
             this._eventsOfInterest[eventType] = true;
           }
         }
         break;
     }
 
     return this._eventsOfInterest;
   },
 
   _eventMap: {
-    'touchstart' : 'pointerdown',
-    'mousedown' : 'pointerdown',
-    'touchmove' : 'pointermove',
-    'mousemove' : 'pointermove',
-    'touchend' : 'pointerup',
-    'mouseup': 'pointerup'
+    "touchstart": "pointerdown",
+    "mousedown": "pointerdown",
+    "touchmove": "pointermove",
+    "mousemove": "pointermove",
+    "touchend": "pointerup",
+    "mouseup": "pointerup"
   },
 
   start: function PointerRelay_start(aOnPointerEvent) {
-    Logger.debug('PointerRelay.start');
+    Logger.debug("PointerRelay.start");
     this.onPointerEvent = aOnPointerEvent;
     for (let eventType in this._eventsOfInterest) {
       Utils.win.addEventListener(eventType, this, true, true);
     }
   },
 
   stop: function PointerRelay_stop() {
-    Logger.debug('PointerRelay.stop');
+    Logger.debug("PointerRelay.stop");
     delete this.lastPointerMove;
     delete this.onPointerEvent;
     for (let eventType in this._eventsOfInterest) {
       Utils.win.removeEventListener(eventType, this, true, true);
     }
   },
 
   handleEvent: function PointerRelay_handleEvent(aEvent) {
     // Don't bother with chrome mouse events.
-    if (Utils.MozBuildApp === 'browser' &&
+    if (Utils.MozBuildApp === "browser" &&
       aEvent.view.top instanceof Ci.nsIDOMChromeWindow) {
       return;
     }
     if (aEvent.mozInputSource === Ci.nsIDOMMouseEvent.MOZ_SOURCE_UNKNOWN ||
         aEvent.isSynthesized) {
       // Ignore events that are scripted or clicks from the a11y API.
       return;
     }
 
     let changedTouches = aEvent.changedTouches || [{
       identifier: MOUSE_ID,
       screenX: aEvent.screenX,
       screenY: aEvent.screenY,
       target: aEvent.target
     }];
 
-    if (Utils.widgetToolkit === 'android' &&
+    if (Utils.widgetToolkit === "android" &&
       changedTouches.length === 1 && changedTouches[0].identifier === 1) {
       return;
     }
 
     if (changedTouches.length === 1 &&
         changedTouches[0].identifier === SYNTH_ID) {
       return;
     }
@@ -149,23 +149,23 @@ var PointerRelay = { // jshint ignore:li
         }
       )
     });
   }
 };
 
 this.PointerAdapter = { // jshint ignore:line
   start: function PointerAdapter_start() {
-    Logger.debug('PointerAdapter.start');
+    Logger.debug("PointerAdapter.start");
     GestureTracker.reset();
     PointerRelay.start(this.handleEvent);
   },
 
   stop: function PointerAdapter_stop() {
-    Logger.debug('PointerAdapter.stop');
+    Logger.debug("PointerAdapter.stop");
     PointerRelay.stop();
     GestureTracker.reset();
   },
 
   handleEvent: function PointerAdapter_handleEvent(aDetail) {
     let timeStamp = Date.now();
     GestureTracker.handle(aDetail, timeStamp);
   }
--- a/accessible/jsat/Presentation.jsm
+++ b/accessible/jsat/Presentation.jsm
@@ -1,46 +1,46 @@
 /* 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/. */
 
 /* exported Presentation */
 
-'use strict';
+"use strict";
 
 const {utils: Cu, interfaces: Ci} = Components;
 
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Logger', // jshint ignore:line
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'PivotContext', // jshint ignore:line
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'UtteranceGenerator', // jshint ignore:line
-  'resource://gre/modules/accessibility/OutputGenerator.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'BrailleGenerator', // jshint ignore:line
-  'resource://gre/modules/accessibility/OutputGenerator.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Roles', // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'States', // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Logger", // jshint ignore:line
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PivotContext", // jshint ignore:line
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "UtteranceGenerator", // jshint ignore:line
+  "resource://gre/modules/accessibility/OutputGenerator.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "BrailleGenerator", // jshint ignore:line
+  "resource://gre/modules/accessibility/OutputGenerator.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Roles", // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "States", // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
 
-this.EXPORTED_SYMBOLS = ['Presentation']; // jshint ignore:line
+this.EXPORTED_SYMBOLS = ["Presentation"]; // jshint ignore:line
 
 /**
  * The interface for all presenter classes. A presenter could be, for example,
  * a speech output module, or a visual cursor indicator.
  */
 function Presenter() {}
 
 Presenter.prototype = {
   /**
    * The type of presenter. Used for matching it with the appropriate output method.
    */
-  type: 'Base',
+  type: "Base",
 
   /**
    * The virtual cursor's position changed.
    * @param {PivotContext} aContext the context object for the new pivot
    *   position.
    * @param {int} aReason the reason for the pivot change.
    *   See nsIAccessiblePivot.
    * @param {bool} aIsFromUserInput the pivot change was invoked by the user
@@ -140,17 +140,17 @@ Presenter.prototype = {
 
 /**
  * Visual presenter. Draws a box around the virtual cursor's position.
  */
 function VisualPresenter() {}
 
 VisualPresenter.prototype = Object.create(Presenter.prototype);
 
-VisualPresenter.prototype.type = 'Visual';
+VisualPresenter.prototype.type = "Visual";
 
 /**
  * The padding in pixels between the object and the highlight border.
  */
 VisualPresenter.prototype.BORDER_PADDING = 2;
 
 VisualPresenter.prototype.viewportChanged =
   function VisualPresenter_viewportChanged(aWindow, aCurrentContext) {
@@ -163,17 +163,17 @@ VisualPresenter.prototype.viewportChange
     let end = aCurrentContext.endOffset;
     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',
+          eventType: "viewport-change",
           bounds: bounds,
           padding: this.BORDER_PADDING
         }
       };
     }
 
     return null;
   };
@@ -192,49 +192,49 @@ VisualPresenter.prototype.pivotChanged =
       let bounds = (aContext.startOffset === -1 && aContext.endOffset === -1) ?
             aContext.bounds : Utils.getTextBounds(aContext.accessibleForBounds,
                                                   aContext.startOffset,
                                                   aContext.endOffset);
 
       return {
         type: this.type,
         details: {
-          eventType: 'vc-change',
+          eventType: "vc-change",
           bounds: bounds,
           padding: this.BORDER_PADDING
         }
       };
     } catch (e) {
-      Logger.logException(e, 'Failed to get bounds');
+      Logger.logException(e, "Failed to get bounds");
       return null;
     }
   };
 
 VisualPresenter.prototype.tabSelected =
   function VisualPresenter_tabSelected(aDocContext, aVCContext) {
     return this.pivotChanged(aVCContext, Ci.nsIAccessiblePivot.REASON_NONE);
   };
 
 VisualPresenter.prototype.tabStateChanged =
   function VisualPresenter_tabStateChanged(aDocObj, aPageState) {
-    if (aPageState == 'newdoc') {
-      return {type: this.type, details: {eventType: 'tabstate-change'}};
+    if (aPageState == "newdoc") {
+      return {type: this.type, details: {eventType: "tabstate-change"}};
     }
 
     return null;
   };
 
 /**
  * Android presenter. Fires Android a11y events.
  */
 function AndroidPresenter() {}
 
 AndroidPresenter.prototype = Object.create(Presenter.prototype);
 
-AndroidPresenter.prototype.type = 'Android';
+AndroidPresenter.prototype.type = "Android";
 
 // Android AccessibilityEvent type constants.
 AndroidPresenter.prototype.ANDROID_VIEW_CLICKED = 0x01;
 AndroidPresenter.prototype.ANDROID_VIEW_LONG_CLICKED = 0x02;
 AndroidPresenter.prototype.ANDROID_VIEW_SELECTED = 0x04;
 AndroidPresenter.prototype.ANDROID_VIEW_FOCUSED = 0x08;
 AndroidPresenter.prototype.ANDROID_VIEW_TEXT_CHANGED = 0x10;
 AndroidPresenter.prototype.ANDROID_WINDOW_STATE_CHANGED = 0x20;
@@ -436,17 +436,17 @@ AndroidPresenter.prototype.viewportChang
 
 AndroidPresenter.prototype.editingModeChanged =
   function AndroidPresenter_editingModeChanged(aIsEditing) {
     return this.announce(UtteranceGenerator.genForEditingMode(aIsEditing));
   };
 
 AndroidPresenter.prototype.announce =
   function AndroidPresenter_announce(aAnnouncement) {
-    let localizedAnnouncement = Utils.localize(aAnnouncement).join(' ');
+    let localizedAnnouncement = Utils.localize(aAnnouncement).join(" ");
     return {
       type: this.type,
       details: [{
         eventType: (Utils.AndroidSdkVersion >= 16) ?
           this.ANDROID_ANNOUNCEMENT : this.ANDROID_VIEW_TEXT_CHANGED,
         text: [localizedAnnouncement],
         addedCount: localizedAnnouncement.length,
         removedCount: 0,
@@ -464,60 +464,60 @@ AndroidPresenter.prototype.liveRegion =
 
 AndroidPresenter.prototype.noMove =
   function AndroidPresenter_noMove(aMoveMethod) {
     return {
       type: this.type,
       details: [
       { eventType: this.ANDROID_VIEW_ACCESSIBILITY_FOCUSED,
         exitView: aMoveMethod,
-        text: ['']
+        text: [""]
       }]
     };
   };
 
 /**
  * A B2G presenter for Gaia.
  */
 function B2GPresenter() {}
 
 B2GPresenter.prototype = Object.create(Presenter.prototype);
 
-B2GPresenter.prototype.type = 'B2G';
+B2GPresenter.prototype.type = "B2G";
 
 B2GPresenter.prototype.keyboardEchoSetting =
-  new PrefCache('accessibility.accessfu.keyboard_echo');
+  new PrefCache("accessibility.accessfu.keyboard_echo");
 B2GPresenter.prototype.NO_ECHO = 0;
 B2GPresenter.prototype.CHARACTER_ECHO = 1;
 B2GPresenter.prototype.WORD_ECHO = 2;
 B2GPresenter.prototype.CHARACTER_AND_WORD_ECHO = 3;
 
 /**
  * A pattern used for haptic feedback.
  * @type {Array}
  */
 B2GPresenter.prototype.PIVOT_CHANGE_HAPTIC_PATTERN = [40];
 
 /**
  * Pivot move reasons.
  * @type {Array}
  */
-B2GPresenter.prototype.pivotChangedReasons = ['none', 'next', 'prev', 'first',
-                                              'last', 'text', 'point'];
+B2GPresenter.prototype.pivotChangedReasons = ["none", "next", "prev", "first",
+                                              "last", "text", "point"];
 
 B2GPresenter.prototype.pivotChanged =
   function B2GPresenter_pivotChanged(aContext, aReason, aIsUserInput) {
     if (!aContext.accessible) {
       return null;
     }
 
     return {
       type: this.type,
       details: {
-        eventType: 'vc-change',
+        eventType: "vc-change",
         data: UtteranceGenerator.genForContext(aContext),
         options: {
           pattern: this.PIVOT_CHANGE_HAPTIC_PATTERN,
           isKey: Utils.isActivatableOnFingerUp(aContext.accessible),
           reason: this.pivotChangedReasons[aReason],
           isUserInput: aIsUserInput,
           hints: aContext.interactionHints
         }
@@ -525,17 +525,17 @@ B2GPresenter.prototype.pivotChanged =
     };
   };
 
 B2GPresenter.prototype.nameChanged =
   function B2GPresenter_nameChanged(aAccessible, aIsPolite = true) {
     return {
       type: this.type,
       details: {
-        eventType: 'name-change',
+        eventType: "name-change",
         data: aAccessible.name,
         options: {enqueue: aIsPolite}
       }
     };
   };
 
 B2GPresenter.prototype.valueChanged =
   function B2GPresenter_valueChanged(aAccessible, aIsPolite = true) {
@@ -543,27 +543,27 @@ B2GPresenter.prototype.valueChanged =
     // the editable value changes are handled in the text changed presenter
     if (Utils.getState(aAccessible).contains(States.EDITABLE)) {
       return null;
     }
 
     return {
       type: this.type,
       details: {
-        eventType: 'value-change',
+        eventType: "value-change",
         data: aAccessible.value,
         options: {enqueue: aIsPolite}
       }
     };
   };
 
 B2GPresenter.prototype.textChanged = function B2GPresenter_textChanged(
   aAccessible, aIsInserted, aStart, aLength, aText, aModifiedText) {
     let echoSetting = this.keyboardEchoSetting.value;
-    let text = '';
+    let text = "";
 
     if (echoSetting == this.CHARACTER_ECHO ||
         echoSetting == this.CHARACTER_AND_WORD_ECHO) {
       text = aModifiedText;
     }
 
     // add word if word boundary is added
     if ((echoSetting == this.WORD_ECHO ||
@@ -579,89 +579,89 @@ B2GPresenter.prototype.textChanged = fun
       if (endBefore.value !== endAfter.value) {
         text += maybeWord;
       }
     }
 
     return {
       type: this.type,
       details: {
-        eventType: 'text-change',
+        eventType: "text-change",
         data: text
       }
     };
 
   };
 
 B2GPresenter.prototype.actionInvoked =
   function B2GPresenter_actionInvoked(aObject, aActionName) {
     return {
       type: this.type,
       details: {
-        eventType: 'action',
+        eventType: "action",
         data: UtteranceGenerator.genForAction(aObject, aActionName)
       }
     };
   };
 
 B2GPresenter.prototype.liveRegion = function B2GPresenter_liveRegion(aContext,
   aIsPolite, aIsHide, aModifiedText) {
     return {
       type: this.type,
       details: {
-        eventType: 'liveregion-change',
+        eventType: "liveregion-change",
         data: UtteranceGenerator.genForLiveRegion(aContext, aIsHide,
           aModifiedText),
         options: {enqueue: aIsPolite}
       }
     };
   };
 
 B2GPresenter.prototype.announce =
   function B2GPresenter_announce(aAnnouncement) {
     return {
       type: this.type,
       details: {
-        eventType: 'announcement',
+        eventType: "announcement",
         data: aAnnouncement
       }
     };
   };
 
 B2GPresenter.prototype.noMove =
   function B2GPresenter_noMove(aMoveMethod) {
     return {
       type: this.type,
       details: {
-        eventType: 'no-move',
+        eventType: "no-move",
         data: aMoveMethod
       }
     };
   };
 
 /**
  * A braille presenter
  */
 function BraillePresenter() {}
 
 BraillePresenter.prototype = Object.create(Presenter.prototype);
 
-BraillePresenter.prototype.type = 'Braille';
+BraillePresenter.prototype.type = "Braille";
 
 BraillePresenter.prototype.pivotChanged =
   function BraillePresenter_pivotChanged(aContext) {
     if (!aContext.accessible) {
       return null;
     }
 
     return {
       type: this.type,
       details: {
         output: Utils.localize(BrailleGenerator.genForContext(aContext)).join(
-          ' '),
+          " "),
         selectionStart: 0,
         selectionEnd: 0
       }
     };
   };
 
 BraillePresenter.prototype.textSelectionChanged =
   function BraillePresenter_textSelectionChanged(aText, aStart, aEnd) {
@@ -673,19 +673,19 @@ BraillePresenter.prototype.textSelection
       }
     };
   };
 
 this.Presentation = { // jshint ignore:line
   get presenters() {
     delete this.presenters;
     let presenterMap = {
-      'mobile/android': [VisualPresenter, AndroidPresenter],
-      'b2g': [VisualPresenter, B2GPresenter],
-      'browser': [VisualPresenter, B2GPresenter, AndroidPresenter]
+      "mobile/android": [VisualPresenter, AndroidPresenter],
+      "b2g": [VisualPresenter, B2GPresenter],
+      "browser": [VisualPresenter, B2GPresenter, AndroidPresenter]
     };
     this.presenters = presenterMap[Utils.MozBuildApp].map(P => new P());
     return this.presenters;
   },
 
   get displayedAccessibles() {
     delete this.displayedAccessibles;
     this.displayedAccessibles = new WeakMap();
--- a/accessible/jsat/Traversal.jsm
+++ b/accessible/jsat/Traversal.jsm
@@ -1,33 +1,33 @@
 /* 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/. */
 
 /* exported TraversalRules, TraversalHelper */
 
-'use strict';
+"use strict";
 
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
-this.EXPORTED_SYMBOLS = ['TraversalRules', 'TraversalHelper']; // jshint ignore:line
+this.EXPORTED_SYMBOLS = ["TraversalRules", "TraversalHelper"]; // jshint ignore:line
 
-Cu.import('resource://gre/modules/accessibility/Utils.jsm');
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Roles',  // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Filters',  // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'States',  // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Prefilters',  // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
+Cu.import("resource://gre/modules/accessibility/Utils.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Roles",  // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Filters",  // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "States",  // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Prefilters",  // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
 
-var gSkipEmptyImages = new PrefCache('accessibility.accessfu.skip_empty_images');
+var gSkipEmptyImages = new PrefCache("accessibility.accessfu.skip_empty_images");
 
 function BaseTraversalRule(aRoles, aMatchFunc, aPreFilter, aContainerRule) {
   this._explicitMatchRoles = new Set(aRoles);
   this._matchRoles = aRoles;
   if (aRoles.length) {
     if (aRoles.indexOf(Roles.LABEL) < 0) {
       this._matchRoles.push(Roles.LABEL);
     }
@@ -42,22 +42,21 @@ function BaseTraversalRule(aRoles, aMatc
 }
 
 BaseTraversalRule.prototype = {
     getMatchRoles: function BaseTraversalRule_getmatchRoles(aRoles) {
       aRoles.value = this._matchRoles;
       return aRoles.value.length;
     },
 
-    match: function BaseTraversalRule_match(aAccessible)
-    {
+    match: function BaseTraversalRule_match(aAccessible) {
       let role = aAccessible.role;
       if (role == Roles.INTERNAL_FRAME) {
         return (Utils.getMessageManager(aAccessible.DOMNode)) ?
-          Filters.MATCH  | Filters.IGNORE_SUBTREE : Filters.IGNORE;
+          Filters.MATCH | Filters.IGNORE_SUBTREE : Filters.IGNORE;
       }
 
       let matchResult =
         (this._explicitMatchRoles.has(role) || !this._explicitMatchRoles.size) ?
         this._matchFunc(aAccessible) : Filters.IGNORE;
 
       // If we are on a label that nests a checkbox/radio we should land on it.
       // It is a bigger touch target, and it reduces clutter.
@@ -189,24 +188,23 @@ this.TraversalRules = { // jshint ignore
 
   SimpleOnScreen: new BaseTraversalRule(
     gSimpleTraversalRoles, gSimpleMatchFunc,
     Prefilters.DEFUNCT | Prefilters.INVISIBLE | Prefilters.ARIA_HIDDEN |
     Prefilters.TRANSPARENT | Prefilters.OFFSCREEN),
 
   Anchor: new BaseTraversalRule(
     [Roles.LINK],
-    function Anchor_match(aAccessible)
-    {
+    function Anchor_match(aAccessible) {
       // We want to ignore links, only focus named anchors.
       if (Utils.getState(aAccessible).contains(States.LINKED)) {
         return Filters.IGNORE;
-      } else {
-        return Filters.MATCH;
       }
+      return Filters.MATCH;
+
     }),
 
   Button: new BaseTraversalRule(
     [Roles.PUSHBUTTON,
      Roles.SPINBUTTON,
      Roles.TOGGLE_BUTTON,
      Roles.BUTTONDROPDOWN,
      Roles.BUTTONDROPDOWNGRID]),
@@ -227,23 +225,23 @@ this.TraversalRules = { // jshint ignore
   Section: new BaseTraversalRule(
     [],
     function Section_match(aAccessible) {
       if (aAccessible.role === Roles.HEADING) {
         return Filters.MATCH;
       }
 
       let matchedRole = Utils.matchRoles(aAccessible, [
-        'banner',
-        'complementary',
-        'contentinfo',
-        'main',
-        'navigation',
-        'search',
-        'region'
+        "banner",
+        "complementary",
+        "contentinfo",
+        "main",
+        "navigation",
+        "search",
+        "region"
         ]);
 
       return matchedRole ? Filters.MATCH : Filters.IGNORE;
     }, null, true),
 
   Entry: new BaseTraversalRule(
     [Roles.ENTRY,
      Roles.PASSWORD_TEXT]),
@@ -279,24 +277,23 @@ this.TraversalRules = { // jshint ignore
     }),
 
   ListItem: new BaseTraversalRule(
     [Roles.LISTITEM,
      Roles.TERM]),
 
   Link: new BaseTraversalRule(
     [Roles.LINK],
-    function Link_match(aAccessible)
-    {
+    function Link_match(aAccessible) {
       // We want to ignore anchors, only focus real links.
       if (Utils.getState(aAccessible).contains(States.LINKED)) {
         return Filters.MATCH;
-      } else {
-        return Filters.IGNORE;
       }
+      return Filters.IGNORE;
+
     }),
 
   /* For TalkBack's "Control" granularity. Form conrols and links */
   Control: new BaseTraversalRule(
     [Roles.PUSHBUTTON,
      Roles.SPINBUTTON,
      Roles.TOGGLE_BUTTON,
      Roles.BUTTONDROPDOWN,
@@ -309,18 +306,17 @@ this.TraversalRules = { // jshint ignore
      Roles.RADIOBUTTON,
      Roles.RADIO_MENU_ITEM,
      Roles.SLIDER,
      Roles.CHECKBUTTON,
      Roles.CHECK_MENU_ITEM,
      Roles.SWITCH,
      Roles.LINK,
      Roles.MENUITEM],
-    function Control_match(aAccessible)
-    {
+    function Control_match(aAccessible) {
       // We want to ignore anchors, only focus real links.
       if (aAccessible.role == Roles.LINK &&
           !Utils.getState(aAccessible).contains(States.LINKED)) {
         return Filters.IGNORE;
       }
       return Filters.MATCH;
     }),
 
@@ -356,17 +352,17 @@ this.TraversalRules = { // jshint ignore
     [Roles.TABLE]),
 
   Checkbox: new BaseTraversalRule(
     [Roles.CHECKBUTTON,
      Roles.CHECK_MENU_ITEM,
      Roles.SWITCH /* A type of checkbox that represents on/off values */]),
 
   _shouldSkipImage: function _shouldSkipImage(aAccessible) {
-    if (gSkipEmptyImages.value && aAccessible.name === '') {
+    if (gSkipEmptyImages.value && aAccessible.name === "") {
       return Filters.IGNORE;
     }
     return Filters.MATCH;
   }
 };
 
 this.TraversalHelper = {
   _helperPivotCache: null,
@@ -404,14 +400,14 @@ this.TraversalHelper = {
           aVirtualCursor.modalRoot = null;
         } else {
           // If we failed to step to another container, break and return false.
           break;
         }
       }
 
       return moved;
-    } else {
-      return aVirtualCursor[aMethod](rule);
     }
+    return aVirtualCursor[aMethod](rule);
+
   }
 
 };
--- a/accessible/jsat/Utils.jsm
+++ b/accessible/jsat/Utils.jsm
@@ -1,49 +1,49 @@
 /* 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/. */
 
 /* exported Utils, Logger, PivotContext, PrefCache */
 
-'use strict';
+"use strict";
 
 const {classes: Cc, utils: Cu, interfaces: Ci} = Components;
 
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Services', // jshint ignore:line
-  'resource://gre/modules/Services.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Rect', // jshint ignore:line
-  'resource://gre/modules/Geometry.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Roles', // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Events', // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Relations', // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'States', // jshint ignore:line
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'PluralForm', // jshint ignore:line
-  'resource://gre/modules/PluralForm.jsm');
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Services", // jshint ignore:line
+  "resource://gre/modules/Services.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Rect", // jshint ignore:line
+  "resource://gre/modules/Geometry.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Roles", // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Events", // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Relations", // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "States", // jshint ignore:line
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", // jshint ignore:line
+  "resource://gre/modules/PluralForm.jsm");
 
-this.EXPORTED_SYMBOLS = ['Utils', 'Logger', 'PivotContext', 'PrefCache']; // jshint ignore:line
+this.EXPORTED_SYMBOLS = ["Utils", "Logger", "PivotContext", "PrefCache"]; // jshint ignore:line
 
 this.Utils = { // jshint ignore:line
   _buildAppMap: {
-    '{3c2e2abc-06d4-11e1-ac3b-374f68613e61}': 'b2g',
-    '{d1bfe7d9-c01e-4237-998b-7b5f960a4314}': 'graphene',
-    '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}': 'browser',
-    '{aa3c5121-dab2-40e2-81ca-7ea25febc110}': 'mobile/android',
-    '{a23983c0-fd0e-11dc-95ff-0800200c9a66}': 'mobile/xul'
+    "{3c2e2abc-06d4-11e1-ac3b-374f68613e61}": "b2g",
+    "{d1bfe7d9-c01e-4237-998b-7b5f960a4314}": "graphene",
+    "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}": "browser",
+    "{aa3c5121-dab2-40e2-81ca-7ea25febc110}": "mobile/android",
+    "{a23983c0-fd0e-11dc-95ff-0800200c9a66}": "mobile/xul"
   },
 
   init: function Utils_init(aWindow) {
     if (this._win) {
       // XXX: only supports attaching to one window now.
-      throw new Error('Only one top-level window could used with AccessFu');
+      throw new Error("Only one top-level window could used with AccessFu");
     }
     this._win = Cu.getWeakReference(aWindow);
   },
 
   uninit: function Utils_uninit() {
     if (!this._win) {
       return;
     }
@@ -63,17 +63,17 @@ this.Utils = { // jshint ignore:line
       return null;
     }
     return win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(
       Ci.nsIDOMWindowUtils);
   },
 
   get AccService() {
     if (!this._AccService) {
-      this._AccService = Cc['@mozilla.org/accessibilityService;1'].
+      this._AccService = Cc["@mozilla.org/accessibilityService;1"].
         getService(Ci.nsIAccessibilityService);
     }
 
     return this._AccService;
   },
 
   set MozBuildApp(value) {
     this._buildApp = value;
@@ -98,26 +98,26 @@ this.Utils = { // jshint ignore:line
       this._widgetToolkit = Services.appinfo.widgetToolkit;
     }
     return this._widgetToolkit;
   },
 
   get ScriptName() {
     if (!this._ScriptName) {
       this._ScriptName =
-        (Services.appinfo.processType == 2) ? 'AccessFuContent' : 'AccessFu';
+        (Services.appinfo.processType == 2) ? "AccessFuContent" : "AccessFu";
     }
     return this._ScriptName;
   },
 
   get AndroidSdkVersion() {
     if (!this._AndroidSdkVersion) {
-      if (Services.appinfo.OS == 'Android') {
+      if (Services.appinfo.OS == "Android") {
         this._AndroidSdkVersion = Services.sysinfo.getPropertyAsInt32(
-          'version');
+          "version");
       } else {
         // Most useful in desktop debugging.
         this._AndroidSdkVersion = 16;
       }
     }
     return this._AndroidSdkVersion;
   },
 
@@ -126,32 +126,32 @@ this.Utils = { // jshint ignore:line
     this._AndroidSdkVersion = value;
   },
 
   get BrowserApp() {
     if (!this.win) {
       return null;
     }
     switch (this.MozBuildApp) {
-      case 'mobile/android':
+      case "mobile/android":
         return this.win.BrowserApp;
-      case 'browser':
+      case "browser":
         return this.win.gBrowser;
-      case 'b2g':
+      case "b2g":
         return this.win.shell;
       default:
         return null;
     }
   },
 
   get CurrentBrowser() {
     if (!this.BrowserApp) {
       return null;
     }
-    if (this.MozBuildApp == 'b2g') {
+    if (this.MozBuildApp == "b2g") {
       return this.BrowserApp.contentBrowser;
     }
     return this.BrowserApp.selectedBrowser;
   },
 
   get CurrentContentDoc() {
     let browser = this.CurrentBrowser;
     return browser ? browser.contentDocument : null;
@@ -159,37 +159,37 @@ this.Utils = { // jshint ignore:line
 
   get AllMessageManagers() {
     let messageManagers = new Set();
 
     function collectLeafMessageManagers(mm) {
       for (let i = 0; i < mm.childCount; i++) {
         let childMM = mm.getChildAt(i);
 
-        if ('sendAsyncMessage' in childMM) {
+        if ("sendAsyncMessage" in childMM) {
           messageManagers.add(childMM);
         } else {
           collectLeafMessageManagers(childMM);
         }
       }
     }
 
     collectLeafMessageManagers(this.win.messageManager);
 
     let document = this.CurrentContentDoc;
 
     if (document) {
-      if (document.location.host === 'b2g') {
+      if (document.location.host === "b2g") {
         // The document is a b2g app chrome (ie. Mulet).
         let contentBrowser = this.win.content.shell.contentBrowser;
         messageManagers.add(this.getMessageManager(contentBrowser));
         document = contentBrowser.contentDocument;
       }
 
-      let remoteframes = document.querySelectorAll('iframe');
+      let remoteframes = document.querySelectorAll("iframe");
 
       for (let i = 0; i < remoteframes.length; ++i) {
         let mm = this.getMessageManager(remoteframes[i]);
         if (mm) {
           messageManagers.add(mm);
         }
       }
 
@@ -212,41 +212,41 @@ this.Utils = { // jshint ignore:line
     // Clean up the white space.
     return localized.filter(word => word).map(word => word.trim()).
       filter(trimmed => trimmed);
   },
 
   get stringBundle() {
     delete this.stringBundle;
     let bundle = Services.strings.createBundle(
-      'chrome://global/locale/AccessFu.properties');
+      "chrome://global/locale/AccessFu.properties");
     this.stringBundle = {
       get: function stringBundle_get(aDetails = {}) {
-        if (!aDetails || typeof aDetails === 'string') {
+        if (!aDetails || typeof aDetails === "string") {
           return aDetails;
         }
-        let str = '';
+        let str = "";
         let string = aDetails.string;
         if (!string) {
           return str;
         }
         try {
           let args = aDetails.args;
           let count = aDetails.count;
           if (args) {
             str = bundle.formatStringFromName(string, args, args.length);
           } else {
             str = bundle.GetStringFromName(string);
           }
           if (count) {
             str = PluralForm.get(count, str);
-            str = str.replace('#1', count);
+            str = str.replace("#1", count);
           }
         } catch (e) {
-          Logger.debug('Failed to get a string from a bundle for', string);
+          Logger.debug("Failed to get a string from a bundle for", string);
         } finally {
           return str;
         }
       }
     };
     return this.stringBundle;
   },
 
@@ -259,22 +259,22 @@ this.Utils = { // jshint ignore:line
     }
   },
 
   getState: function getState(aAccessibleOrEvent) {
     if (aAccessibleOrEvent instanceof Ci.nsIAccessibleStateChangeEvent) {
       return new State(
         aAccessibleOrEvent.isExtraState ? 0 : aAccessibleOrEvent.state,
         aAccessibleOrEvent.isExtraState ? aAccessibleOrEvent.state : 0);
-    } else {
+    }
       let state = {};
       let extState = {};
       aAccessibleOrEvent.getState(state, extState);
       return new State(state.value, extState.value);
-    }
+
   },
 
   getAttributes: function getAttributes(aAccessible) {
     let attributes = {};
 
     if (aAccessible && aAccessible.attributes) {
       let attributesEnum = aAccessible.attributes.enumerate();
 
@@ -359,43 +359,43 @@ this.Utils = { // jshint ignore:line
     while (acc) {
       if (acc == aSubTreeRoot) {
         return true;
       }
 
       try {
         acc = acc.parent;
       } catch (x) {
-        Logger.debug('Failed to get parent:', x);
+        Logger.debug("Failed to get parent:", x);
         acc = null;
       }
     }
 
     return false;
   },
 
   isHidden: function isHidden(aAccessible) {
     // Need to account for aria-hidden, so can't just check for INVISIBLE
     // state.
     let hidden = Utils.getAttributes(aAccessible).hidden;
-    return hidden && hidden === 'true';
+    return hidden && hidden === "true";
   },
 
   visibleChildCount: function visibleChildCount(aAccessible) {
     let count = 0;
     for (let child = aAccessible.firstChild; child; child = child.nextSibling) {
       if (!this.isHidden(child)) {
         ++count;
       }
     }
     return count;
   },
 
   inHiddenSubtree: function inHiddenSubtree(aAccessible) {
-    for (let acc=aAccessible; acc; acc=acc.parent) {
+    for (let acc = aAccessible; acc; acc = acc.parent) {
       if (this.isHidden(acc)) {
         return true;
       }
     }
     return false;
   },
 
   isAliveAndVisible: function isAliveAndVisible(aAccessible, aIsOnScreen) {
@@ -413,54 +413,54 @@ this.Utils = { // jshint ignore:line
     } catch (x) {
       return false;
     }
 
     return true;
   },
 
   matchAttributeValue: function matchAttributeValue(aAttributeValue, values) {
-    let attrSet = new Set(aAttributeValue.split(' '));
+    let attrSet = new Set(aAttributeValue.split(" "));
     for (let value of values) {
       if (attrSet.has(value)) {
         return value;
       }
     }
   },
 
   getLandmarkName: function getLandmarkName(aAccessible) {
     return this.matchRoles(aAccessible, [
-      'banner',
-      'complementary',
-      'contentinfo',
-      'main',
-      'navigation',
-      'search'
+      "banner",
+      "complementary",
+      "contentinfo",
+      "main",
+      "navigation",
+      "search"
     ]);
   },
 
   getMathRole: function getMathRole(aAccessible) {
     return this.matchRoles(aAccessible, [
-      'base',
-      'close-fence',
-      'denominator',
-      'numerator',
-      'open-fence',
-      'overscript',
-      'presubscript',
-      'presuperscript',
-      'root-index',
-      'subscript',
-      'superscript',
-      'underscript'
+      "base",
+      "close-fence",
+      "denominator",
+      "numerator",
+      "open-fence",
+      "overscript",
+      "presubscript",
+      "presuperscript",
+      "root-index",
+      "subscript",
+      "superscript",
+      "underscript"
     ]);
   },
 
   matchRoles: function matchRoles(aAccessible, aRoles) {
-    let roles = this.getAttributes(aAccessible)['xml-roles'];
+    let roles = this.getAttributes(aAccessible)["xml-roles"];
     if (!roles) {
       return;
     }
 
     // Looking up a role that would match any in the provided roles.
     return this.matchAttributeValue(roles, aRoles);
   },
 
@@ -476,29 +476,29 @@ this.Utils = { // jshint ignore:line
     }
 
     return null;
   },
 
   isListItemDecorator: function isListItemDecorator(aStaticText,
                                                     aExcludeOrdered) {
     let parent = aStaticText.parent;
-    if (aExcludeOrdered && parent.parent.DOMNode.nodeName === 'OL') {
+    if (aExcludeOrdered && parent.parent.DOMNode.nodeName === "OL") {
       return false;
     }
 
     return parent.role === Roles.LISTITEM && parent.childCount > 1 &&
       aStaticText.indexInParent === 0;
   },
 
   dispatchChromeEvent: function dispatchChromeEvent(aType, aDetails) {
     let details = {
       type: aType,
       details: JSON.stringify(
-        typeof aDetails === 'string' ? { eventType : aDetails } : aDetails)
+        typeof aDetails === "string" ? { eventType: aDetails } : aDetails)
     };
     let window = this.win;
     let shell = window.shell || window.content.shell;
     if (shell) {
       // On B2G device.
       shell.sendChromeEvent(details);
     } else {
       // Dispatch custom event to have support for desktop and screen reader
@@ -511,17 +511,17 @@ this.Utils = { // jshint ignore:line
     }
 
   },
 
   isActivatableOnFingerUp: function isActivatableOnFingerUp(aAccessible) {
     if (aAccessible.role === Roles.KEY) {
       return true;
     }
-    let quick_activate = this.getAttributes(aAccessible)['moz-quick-activate'];
+    let quick_activate = this.getAttributes(aAccessible)["moz-quick-activate"];
     return quick_activate && JSON.parse(quick_activate);
   }
 };
 
 /**
  * State object used internally to process accessible's states.
  * @param {Number} aBase     Base state.
  * @param {Number} aExtended Extended state.
@@ -537,41 +537,41 @@ State.prototype = {
   },
   toString: function State_toString() {
     let stateStrings = Utils.AccService.
       getStringStates(this.base, this.extended);
     let statesArray = new Array(stateStrings.length);
     for (let i = 0; i < statesArray.length; i++) {
       statesArray[i] = stateStrings.item(i);
     }
-    return '[' + statesArray.join(', ') + ']';
+    return "[" + statesArray.join(", ") + "]";
   }
 };
 
 this.Logger = { // jshint ignore:line
   GESTURE: -1,
   DEBUG: 0,
   INFO: 1,
   WARNING: 2,
   ERROR: 3,
-  _LEVEL_NAMES: ['GESTURE', 'DEBUG', 'INFO', 'WARNING', 'ERROR'],
+  _LEVEL_NAMES: ["GESTURE", "DEBUG", "INFO", "WARNING", "ERROR"],
 
   logLevel: 1, // INFO;
 
   test: false,
 
   log: function log(aLogLevel) {
     if (aLogLevel < this.logLevel) {
       return;
     }
 
     let args = Array.prototype.slice.call(arguments, 1);
-    let message = (typeof(args[0]) === 'function' ? args[0]() : args).join(' ');
-    message = '[' + Utils.ScriptName + '] ' + this._LEVEL_NAMES[aLogLevel + 1] +
-      ' ' + message + '\n';
+    let message = (typeof(args[0]) === "function" ? args[0]() : args).join(" ");
+    message = "[" + Utils.ScriptName + "] " + this._LEVEL_NAMES[aLogLevel + 1] +
+      " " + message + "\n";
     dump(message);
     // Note: used for testing purposes. If |this.test| is true, also log to
     // the console service.
     if (this.test) {
       try {
         Services.console.logStringMessage(message);
       } catch (ex) {
         // There was an exception logging to the console service.
@@ -600,72 +600,72 @@ this.Logger = { // jshint ignore:line
   },
 
   error: function error() {
     this.log.apply(
       this, [this.ERROR].concat(Array.prototype.slice.call(arguments)));
   },
 
   logException: function logException(
-    aException, aErrorMessage = 'An exception has occured') {
+    aException, aErrorMessage = "An exception has occured") {
     try {
-      let stackMessage = '';
+      let stackMessage = "";
       if (aException.stack) {
-        stackMessage = '  ' + aException.stack.replace(/\n/g, '\n  ');
+        stackMessage = "  " + aException.stack.replace(/\n/g, "\n  ");
       } else if (aException.location) {
         let frame = aException.location;
         let stackLines = [];
         while (frame && frame.lineNumber) {
           stackLines.push(
-            '  ' + frame.name + '@' + frame.filename + ':' + frame.lineNumber);
+            "  " + frame.name + "@" + frame.filename + ":" + frame.lineNumber);
           frame = frame.caller;
         }
-        stackMessage = stackLines.join('\n');
+        stackMessage = stackLines.join("\n");
       } else {
         stackMessage =
-          '(' + aException.fileName + ':' + aException.lineNumber + ')';
+          "(" + aException.fileName + ":" + aException.lineNumber + ")";
       }
-      this.error(aErrorMessage + ':\n ' +
-                 aException.message + '\n' +
+      this.error(aErrorMessage + ":\n " +
+                 aException.message + "\n" +
                  stackMessage);
     } catch (x) {
       this.error(x);
     }
   },
 
   accessibleToString: function accessibleToString(aAccessible) {
     if (!aAccessible) {
-      return '[ null ]';
+      return "[ null ]";
     }
 
     try {
-      return'[ ' + Utils.AccService.getStringRole(aAccessible.role) +
-        ' | ' + aAccessible.name + ' ]';
+      return "[ " + Utils.AccService.getStringRole(aAccessible.role) +
+        " | " + aAccessible.name + " ]";
     } catch (x) {
-      return '[ defunct ]';
+      return "[ defunct ]";
     }
   },
 
   eventToString: function eventToString(aEvent) {
     let str = Utils.AccService.getStringEventType(aEvent.eventType);
     if (aEvent.eventType == Events.STATE_CHANGE) {
       let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent);
       let stateStrings = event.isExtraState ?
         Utils.AccService.getStringStates(0, event.state) :
         Utils.AccService.getStringStates(event.state, 0);
-      str += ' (' + stateStrings.item(0) + ')';
+      str += " (" + stateStrings.item(0) + ")";
     }
 
     if (aEvent.eventType == Events.VIRTUALCURSOR_CHANGED) {
       let event = aEvent.QueryInterface(
         Ci.nsIAccessibleVirtualCursorChangeEvent);
       let pivot = aEvent.accessible.QueryInterface(
         Ci.nsIAccessibleDocument).virtualCursor;
-      str += ' (' + this.accessibleToString(event.oldAccessible) + ' -> ' +
-	this.accessibleToString(pivot.position) + ')';
+      str += " (" + this.accessibleToString(event.oldAccessible) + " -> " +
+        this.accessibleToString(pivot.position) + ")";
     }
 
     return str;
   },
 
   statesToString: function statesToString(aAccessible) {
     return Utils.getState(aAccessible).toString();
   },
@@ -675,23 +675,23 @@ this.Logger = { // jshint ignore:line
       return;
     }
 
     this._dumpTreeInternal(aLogLevel, aRootAccessible, 0);
   },
 
   _dumpTreeInternal:
     function _dumpTreeInternal(aLogLevel, aAccessible, aIndent) {
-      let indentStr = '';
+      let indentStr = "";
       for (let i = 0; i < aIndent; i++) {
-        indentStr += ' ';
+        indentStr += " ";
       }
       this.log(aLogLevel, indentStr,
                this.accessibleToString(aAccessible),
-               '(' + this.statesToString(aAccessible) + ')');
+               "(" + this.statesToString(aAccessible) + ")");
       for (let i = 0; i < aAccessible.childCount; i++) {
         this._dumpTreeInternal(aLogLevel, aAccessible.getChildAt(i),
           aIndent + 1);
       }
     }
 };
 
 /**
@@ -749,26 +749,26 @@ PivotContext.prototype = {
                             Ci.nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT)};
       let hypertextAcc = this._accessible.QueryInterface(
         Ci.nsIAccessibleHyperText);
 
       // Iterate through the links in backwards order so text replacements don't
       // affect the offsets of links yet to be processed.
       for (let i = hypertextAcc.linkCount - 1; i >= 0; i--) {
         let link = hypertextAcc.getLinkAt(i);
-        let linkText = '';
+        let linkText = "";
         if (link instanceof Ci.nsIAccessibleText) {
           linkText = link.QueryInterface(Ci.nsIAccessibleText).
                           getText(0,
                             Ci.nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT);
         }
 
         let start = link.startIndex;
         let end = link.endIndex;
-        for (let offset of ['startOffset', 'endOffset']) {
+        for (let offset of ["startOffset", "endOffset"]) {
           if (this[offset] >= end) {
             result[offset] += linkText.length - (end - start);
           }
         }
         result.text = result.text.substring(0, start) + linkText +
                       result.text.substring(end);
       }
 
@@ -787,17 +787,17 @@ PivotContext.prototype = {
     let ancestry = [];
     let parent = aAccessible;
     try {
       while (parent && (parent = parent.parent)) {
        ancestry.push(parent);
       }
     } catch (x) {
       // A defunct accessible will raise an exception geting parent.
-      Logger.debug('Failed to get parent:', x);
+      Logger.debug("Failed to get parent:", x);
     }
     return ancestry.reverse();
   },
 
   /**
    * A list of the old accessible's ancestry.
    */
   get oldAncestry() {
@@ -874,23 +874,23 @@ PivotContext.prototype = {
 
   /**
    * Get interaction hints for the context ancestry.
    * @return {Array} Array of interaction hints.
    */
   get interactionHints() {
     let hints = [];
     this.newAncestry.concat(this.accessible).reverse().forEach(aAccessible => {
-      let hint = Utils.getAttributes(aAccessible)['moz-hint'];
+      let hint = Utils.getAttributes(aAccessible)["moz-hint"];
       if (hint) {
         hints.push(hint);
       } else if (aAccessible.actionCount > 0) {
         hints.push({
           string: Utils.AccService.getStringRole(
-            aAccessible.role).replace(/\s/g, '') + '-hint'
+            aAccessible.role).replace(/\s/g, "") + "-hint"
         });
       }
     });
     return hints;
   },
 
   /*
    * A subtree generator function, used to generate a flattened
@@ -941,17 +941,17 @@ PivotContext.prototype = {
         yield enumerator.getNext().QueryInterface(Ci.nsIAccessible).name;
       }
     };
 
     cellInfo.current = getAccessibleCell(aAccessible);
 
     if (!cellInfo.current) {
       Logger.warning(aAccessible,
-        'does not support nsIAccessibleTableCell interface.');
+        "does not support nsIAccessibleTableCell interface.");
       this._cells.set(domNode, null);
       return null;
     }
 
     let table = cellInfo.current.table;
     if (table.isProbablyForLayout()) {
       this._cells.set(domNode, null);
       return null;
@@ -1053,21 +1053,21 @@ PrefCache.prototype = {
     } catch (x) {
       // Pref does not exist.
       return null;
     }
   },
 
   observe: function observe(aSubject) {
     this.value = this._getValue(aSubject.QueryInterface(Ci.nsIPrefBranch));
-    Logger.info('pref changed', this.name, this.value);
+    Logger.info("pref changed", this.name, this.value);
     if (this.callback) {
       try {
         this.callback(this.name, this.value, false);
       } catch (x) {
         Logger.logException(x);
       }
     }
   },
 
-  QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                           Ci.nsISupportsWeakReference])
 };
--- a/accessible/jsat/content-script.js
+++ b/accessible/jsat/content-script.js
@@ -2,152 +2,152 @@
  * 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/. */
 
 /* eslint-env mozilla/frame-script */
 
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Logger',
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Presentation',
-  'resource://gre/modules/accessibility/Presentation.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Utils',
-  'resource://gre/modules/accessibility/Utils.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'EventManager',
-  'resource://gre/modules/accessibility/EventManager.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'ContentControl',
-  'resource://gre/modules/accessibility/ContentControl.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
-  'resource://gre/modules/accessibility/Constants.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'States',
-  'resource://gre/modules/accessibility/Constants.jsm');
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Logger",
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Presentation",
+  "resource://gre/modules/accessibility/Presentation.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+  "resource://gre/modules/accessibility/Utils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "EventManager",
+  "resource://gre/modules/accessibility/EventManager.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ContentControl",
+  "resource://gre/modules/accessibility/ContentControl.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Roles",
+  "resource://gre/modules/accessibility/Constants.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "States",
+  "resource://gre/modules/accessibility/Constants.jsm");
 
-Logger.info('content-script.js', content.document.location);
+Logger.info("content-script.js", content.document.location);
 
 var eventManager = null;
 var contentControl = null;
 
 function forwardToParent(aMessage) {
   // XXX: This is a silly way to make a deep copy
   let newJSON = JSON.parse(JSON.stringify(aMessage.json));
-  newJSON.origin = 'child';
+  newJSON.origin = "child";
   sendAsyncMessage(aMessage.name, newJSON);
 }
 
 function forwardToChild(aMessage, aListener, aVCPosition) {
   let acc = aVCPosition || Utils.getVirtualCursor(content.document).position;
 
   if (!Utils.isAliveAndVisible(acc) || acc.role != Roles.INTERNAL_FRAME) {
     return false;
   }
 
   Logger.debug(() => {
-    return ['forwardToChild', Logger.accessibleToString(acc),
-            aMessage.name, JSON.stringify(aMessage.json, null, '  ')];
+    return ["forwardToChild", Logger.accessibleToString(acc),
+            aMessage.name, JSON.stringify(aMessage.json, null, "  ")];
   });
 
   let mm = Utils.getMessageManager(acc.DOMNode);
 
   if (aListener) {
     mm.addMessageListener(aMessage.name, aListener);
   }
 
   // XXX: This is a silly way to make a deep copy
   let newJSON = JSON.parse(JSON.stringify(aMessage.json));
-  newJSON.origin = 'parent';
+  newJSON.origin = "parent";
   if (Utils.isContentProcess) {
     // XXX: OOP content's screen offset is 0,
     // so we remove the real screen offset here.
     newJSON.x -= content.mozInnerScreenX;
     newJSON.y -= content.mozInnerScreenY;
   }
   mm.sendAsyncMessage(aMessage.name, newJSON);
   return true;
 }
 
 function activateContextMenu(aMessage) {
   let position = Utils.getVirtualCursor(content.document).position;
   if (!forwardToChild(aMessage, activateContextMenu, position)) {
     let center = Utils.getBounds(position, true).center();
 
-    let evt = content.document.createEvent('HTMLEvents');
-    evt.initEvent('contextmenu', true, true);
+    let evt = content.document.createEvent("HTMLEvents");
+    evt.initEvent("contextmenu", true, true);
     evt.clientX = center.x;
     evt.clientY = center.y;
     position.DOMNode.dispatchEvent(evt);
   }
 }
 
 function presentCaretChange(aText, aOldOffset, aNewOffset) {
   if (aOldOffset !== aNewOffset) {
     let msg = Presentation.textSelectionChanged(aText, aNewOffset, aNewOffset,
                                                 aOldOffset, aOldOffset, true);
-    sendAsyncMessage('AccessFu:Present', msg);
+    sendAsyncMessage("AccessFu:Present", msg);
   }
 }
 
 function scroll(aMessage) {
   let position = Utils.getVirtualCursor(content.document).position;
   if (!forwardToChild(aMessage, scroll, position)) {
-    sendAsyncMessage('AccessFu:DoScroll',
+    sendAsyncMessage("AccessFu:DoScroll",
                      { bounds: Utils.getBounds(position, true),
                        page: aMessage.json.page,
                        horizontal: aMessage.json.horizontal });
   }
 }
 
 addMessageListener(
-  'AccessFu:Start',
+  "AccessFu:Start",
   function(m) {
     if (m.json.logLevel) {
       Logger.logLevel = Logger[m.json.logLevel];
     }
 
-    Logger.debug('AccessFu:Start');
+    Logger.debug("AccessFu:Start");
     if (m.json.buildApp)
       Utils.MozBuildApp = m.json.buildApp;
 
-    addMessageListener('AccessFu:ContextMenu', activateContextMenu);
-    addMessageListener('AccessFu:Scroll', scroll);
+    addMessageListener("AccessFu:ContextMenu", activateContextMenu);
+    addMessageListener("AccessFu:Scroll", scroll);
 
     if (!contentControl) {
       contentControl = new ContentControl(this);
     }
     contentControl.start();
 
     if (!eventManager) {
       eventManager = new EventManager(this, contentControl);
     }
     eventManager.inTest = m.json.inTest;
     eventManager.start();
 
     function contentStarted() {
       let accDoc = Utils.AccService.getAccessibleFor(content.document);
       if (accDoc && !Utils.getState(accDoc).contains(States.BUSY)) {
-        sendAsyncMessage('AccessFu:ContentStarted');
+        sendAsyncMessage("AccessFu:ContentStarted");
       } else {
         content.setTimeout(contentStarted, 0);
       }
     }
 
     if (m.json.inTest) {
       // During a test we want to wait for the document to finish loading for
       // consistency.
       contentStarted();
     }
   });
 
 addMessageListener(
-  'AccessFu:Stop',
+  "AccessFu:Stop",
   function(m) {
-    Logger.debug('AccessFu:Stop');
+    Logger.debug("AccessFu:Stop");
 
-    removeMessageListener('AccessFu:ContextMenu', activateContextMenu);
-    removeMessageListener('AccessFu:Scroll', scroll);
+    removeMessageListener("AccessFu:ContextMenu", activateContextMenu);
+    removeMessageListener("AccessFu:Scroll", scroll);
 
     eventManager.stop();
     contentControl.stop();
   });
 
-sendAsyncMessage('AccessFu:Ready');
+sendAsyncMessage("AccessFu:Ready");
--- a/accessible/mac/AccessibleWrap.mm
+++ b/accessible/mac/AccessibleWrap.mm
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DocAccessible.h"
 #include "nsObjCExceptions.h"
 
 #include "Accessible-inl.h"
 #include "nsAccUtils.h"
 #include "Role.h"
+#include "gfxPlatform.h"
 
 #import "mozAccessible.h"
 #import "mozActionElements.h"
 #import "mozHTMLAccessible.h"
 #import "mozTableAccessible.h"
 #import "mozTextAccessible.h"
 
 using namespace mozilla;
@@ -181,16 +182,22 @@ AccessibleWrap::AncestorIsFlat()
   return false;
 }
 
 void
 a11y::FireNativeEvent(mozAccessible* aNativeAcc, uint32_t aEventType)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
+  // Under headless mode we don't have access to a native window, so we skip
+  // dispatching native events.
+  if (gfxPlatform::IsHeadless()) {
+    return;
+  }
+
   switch (aEventType) {
     case nsIAccessibleEvent::EVENT_FOCUS:
       [aNativeAcc didReceiveFocus];
       break;
     case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
     case nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE:
       [aNativeAcc valueDidChange];
       break;
--- a/accessible/mac/mozAccessible.mm
+++ b/accessible/mac/mozAccessible.mm
@@ -793,17 +793,17 @@ ConvertToNSArray(nsTArray<ProxyAccessibl
       return @"AXApplicationLog";
     if (roleAtom == nsGkAtoms::marquee)
       return @"AXApplicationMarquee";
     if (roleAtom == nsGkAtoms::math)
       return @"AXDocumentMath";
     if (roleAtom == nsGkAtoms::note_)
       return @"AXDocumentNote";
     if (roleAtom == nsGkAtoms::region)
-      return @"AXDocumentRegion";
+      return mRole == roles::REGION ? @"AXLandmarkRegion" : nil;
     if (roleAtom == nsGkAtoms::status)
       return @"AXApplicationStatus";
     if (roleAtom == nsGkAtoms::tabpanel)
       return @"AXTabPanel";
     if (roleAtom == nsGkAtoms::timer)
       return @"AXApplicationTimer";
     if (roleAtom == nsGkAtoms::tooltip)
       return @"AXUserInterfaceTooltip";
@@ -947,17 +947,16 @@ static const RoleDescrMap sRoleDescrMap[
   { @"AXApplicationStatus", NS_LITERAL_STRING("status") },
   { @"AXApplicationTimer", NS_LITERAL_STRING("timer") },
   { @"AXContentSeparator", NS_LITERAL_STRING("separator") },
   { @"AXDefinition", NS_LITERAL_STRING("definition") },
   { @"AXDocument", NS_LITERAL_STRING("document") },
   { @"AXDocumentArticle", NS_LITERAL_STRING("article") },
   { @"AXDocumentMath", NS_LITERAL_STRING("math") },
   { @"AXDocumentNote", NS_LITERAL_STRING("note") },
-  { @"AXDocumentRegion", NS_LITERAL_STRING("region") },
   { @"AXLandmarkApplication", NS_LITERAL_STRING("application") },
   { @"AXLandmarkBanner", NS_LITERAL_STRING("banner") },
   { @"AXLandmarkComplementary", NS_LITERAL_STRING("complementary") },
   { @"AXLandmarkContentInfo", NS_LITERAL_STRING("content") },
   { @"AXLandmarkMain", NS_LITERAL_STRING("main") },
   { @"AXLandmarkNavigation", NS_LITERAL_STRING("navigation") },
   { @"AXLandmarkRegion", NS_LITERAL_STRING("region") },
   { @"AXLandmarkSearch", NS_LITERAL_STRING("search") },
@@ -976,16 +975,19 @@ struct RoleDescrComparator
   }
 };
 
 - (NSString*)roleDescription
 {
   if (mRole == roles::DOCUMENT)
     return utils::LocalizedString(NS_LITERAL_STRING("htmlContent"));
 
+  if (mRole == roles::FIGURE)
+    return utils::LocalizedString(NS_LITERAL_STRING("figure"));
+
   if (mRole == roles::HEADING)
     return utils::LocalizedString(NS_LITERAL_STRING("heading"));
 
   NSString* subrole = [self subrole];
 
   if (subrole) {
     size_t idx = 0;
     if (BinarySearchIf(sRoleDescrMap, 0, ArrayLength(sRoleDescrMap),
--- a/accessible/moz.build
+++ b/accessible/moz.build
@@ -26,16 +26,19 @@ DIRS += [ 'aom',
 ]
 
 if CONFIG['MOZ_XUL']:
     DIRS += ['xul']
 
 TEST_DIRS += ['tests/mochitest']
 
 BROWSER_CHROME_MANIFESTS += [
+  'tests/browser/bounds/browser.ini',
   'tests/browser/browser.ini',
   'tests/browser/e10s/browser.ini',
+  'tests/browser/events/browser.ini',
   'tests/browser/scroll/browser.ini',
-  'tests/browser/states/browser.ini'
+  'tests/browser/states/browser.ini',
+  'tests/browser/tree/browser.ini'
 ]
 
 with Files("**"):
-    BUG_COMPONENT = ("Core", "Disability Access APIs")
\ No newline at end of file
+    BUG_COMPONENT = ("Core", "Disability Access APIs")
--- a/accessible/other/AccessibleWrap.cpp
+++ b/accessible/other/AccessibleWrap.cpp
@@ -3,17 +3,17 @@
  * 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/. */
 
 #include "AccessibleWrap.h"
 
 using namespace mozilla::a11y;
 
 //-----------------------------------------------------
-// construction 
+// construction
 //-----------------------------------------------------
 AccessibleWrap::
   AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :
   Accessible(aContent, aDoc)
 {
 }
 
 //-----------------------------------------------------
--- a/accessible/other/AccessibleWrap.h
+++ b/accessible/other/AccessibleWrap.h
@@ -1,14 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
-/* For documentation of the accessibility architecture, 
+/* For documentation of the accessibility architecture,
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 #ifndef mozilla_a11y_AccessibleWrap_h_
 #define mozilla_a11y_AccessibleWrap_h_
 
 #include "nsCOMPtr.h"
 #include "Accessible.h"
--- a/accessible/other/DocAccessibleWrap.h
+++ b/accessible/other/DocAccessibleWrap.h
@@ -1,14 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
-/* For documentation of the accessibility architecture, 
+/* For documentation of the accessibility architecture,
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 #ifndef mozilla_a11y_DocAccessibleWrap_h__
 #define mozilla_a11y_DocAccessibleWrap_h__
 
 #include "DocAccessible.h"
 
--- a/accessible/other/RootAccessibleWrap.h
+++ b/accessible/other/RootAccessibleWrap.h
@@ -1,14 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
-/* For documentation of the accessibility architecture, 
+/* For documentation of the accessibility architecture,
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 #ifndef mozilla_a11y_RootAccessibleWrap_h__
 #define mozilla_a11y_RootAccessibleWrap_h__
 
 #include "RootAccessible.h"
 
--- a/accessible/other/TextLeafAccessibleWrap.h
+++ b/accessible/other/TextLeafAccessibleWrap.h
@@ -5,15 +5,15 @@
 
 #ifndef mozilla_a11y_TextLeafAccessibleWrap_h__
 #define mozilla_a11y_TextLeafAccessibleWrap_h__
 
 #include "TextLeafAccessible.h"
 
 namespace mozilla {
 namespace a11y {
- 
+
 typedef class TextLeafAccessible TextLeafAccessibleWrap;
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/tests/browser/.eslintrc.js
+++ b/accessible/tests/browser/.eslintrc.js
@@ -13,17 +13,17 @@ module.exports = {
     "block-scoped-var": "error",
     "camelcase": "error",
     "comma-dangle": ["error", "never"],
     "complexity": ["error", 20],
     "consistent-this": "off",
     "curly": ["error", "multi-line"],
     "default-case": "off",
     "dot-location": ["error", "property"],
-    "dot-notation": "error",
+
     "eqeqeq": "off",
     "func-names": "off",
     "func-style": "off",
     "generator-star-spacing": "off",
     "handle-callback-err": ["error", "er"],
     "indent": ["error", 2, {"SwitchCase": 1}],
     "max-nested-callbacks": ["error", 4],
     "max-params": "off",
@@ -82,17 +82,16 @@ module.exports = {
     "space-in-parens": ["error", "never"],
     "space-unary-word-ops": "off",
     "strict": ["error", "global"],
     "valid-jsdoc": "off",
     "vars-on-top": "off",
     "wrap-iife": "off",
     "wrap-regex": "off",
     "yoda": "error",
-
     "guard-for-in": "off",
     "newline-after-var": "off",
     "no-alert": "off",
     "no-eq-null": "off",
     "no-func-assign": "off",
     "no-implied-eval": "off",
     "no-inner-declarations": "off",
     "no-invalid-regexp": "off",
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/bounds/browser.ini
@@ -0,0 +1,12 @@
+[DEFAULT]
+skip-if = e10s && os == 'win' && release_or_beta
+support-files =
+  head.js
+  !/accessible/tests/browser/events.js
+  !/accessible/tests/browser/shared-head.js
+  !/accessible/tests/mochitest/*.js
+  !/accessible/tests/mochitest/letters.gif
+
+[browser_test_zoom.js]
+[browser_test_zoom_text.js]
+skip-if = os == 'win' # Bug 1372296
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/bounds/browser_test_zoom.js
@@ -0,0 +1,68 @@
+/* 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";
+
+/* import-globals-from ../../mochitest/layout.js */
+
+async function getContentBoundsForDOMElm(browser, id) {
+  return ContentTask.spawn(browser, id, contentId => {
+    this.ok = ok;
+    return getBoundsForDOMElm(contentId);
+  });
+}
+
+async function testContentBounds(browser, acc) {
+  let [expectedX, expectedY, expectedWidth, expectedHeight] =
+    await getContentBoundsForDOMElm(browser, getAccessibleDOMNodeID(acc));
+
+  let [x, y, width, height] = getBounds(acc);
+  let prettyAccName = prettyName(acc);
+  is(x, expectedX, "Wrong x coordinate of " + prettyAccName);
+  is(y, expectedY, "Wrong y coordinate of " + prettyAccName);
+  is(width, expectedWidth, "Wrong width of " + prettyAccName);
+  is(height, expectedHeight, "Wrong height of " + prettyAccName);
+}
+
+async function runTests(browser, accDoc) {
+  loadFrameScripts(browser, { name: "layout.js", dir: MOCHITESTS_DIR });
+
+  let p1 = findAccessibleChildByID(accDoc, "p1");
+  let p2 = findAccessibleChildByID(accDoc, "p2");
+  let imgmap = findAccessibleChildByID(accDoc, "imgmap");
+  if (!imgmap.childCount) {
+    // An image map may not be available even after the doc and image load
+    // is complete. We don't recieve any DOM events for this change either,
+    // so we need to wait for a REORDER.
+    await waitForEvent(EVENT_REORDER, "imgmap");
+  }
+  let area = imgmap.firstChild;
+
+  await testContentBounds(browser, p1);
+  await testContentBounds(browser, p2);
+  await testContentBounds(browser, area);
+
+  await ContentTask.spawn(browser, {}, () => {
+    zoomDocument(document, 2.0);
+  });
+
+  await testContentBounds(browser, p1);
+  await testContentBounds(browser, p2);
+  await testContentBounds(browser, area);
+}
+
+/**
+ * Test accessible boundaries when page is zoomed
+ */
+addAccessibleTask(`
+<p id="p1">para 1</p><p id="p2">para 2</p>
+<map name="atoz_map" id="map">
+  <area id="area1" href="http://mozilla.org"
+        coords=17,0,30,14" alt="mozilla.org" shape="rect">
+</map>
+<img id="imgmap" width="447" height="15"
+     usemap="#atoz_map"
+     src="http://example.com/a11y/accessible/tests/mochitest/letters.gif">`,
+  runTests
+);
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/bounds/browser_test_zoom_text.js
@@ -0,0 +1,41 @@
+/* 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";
+
+/* import-globals-from ../../mochitest/layout.js */
+
+async function runTests(browser, accDoc) {
+  function testTextNode(id) {
+    let hyperTextNode = findAccessibleChildByID(accDoc, id);
+    let textNode = hyperTextNode.firstChild;
+
+    let [x, y, width, height] = getBounds(textNode);
+    testTextBounds(hyperTextNode, 0, -1, [x, y, width, height],
+                   COORDTYPE_SCREEN_RELATIVE);
+  }
+
+  loadFrameScripts(browser, { name: "layout.js", dir: MOCHITESTS_DIR });
+
+  testTextNode("p1");
+  testTextNode("p2");
+
+  await ContentTask.spawn(browser, {}, () => {
+    zoomDocument(document, 2.0);
+  });
+
+  testTextNode("p1");
+
+  await ContentTask.spawn(browser, {}, () => {
+    zoomDocument(document, 1.0);
+  });
+}
+
+/**
+ * Test the text range boundary when page is zoomed
+ */
+addAccessibleTask(`
+  <p id='p1' style='font-family: monospace;'>Tilimilitryamdiya</p>
+  <p id='p2'>ل</p>`, runTests
+);
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/bounds/head.js
@@ -0,0 +1,16 @@
+/* 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";
+
+// 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);
+
+// Loading and common.js from accessible/tests/mochitest/ for all tests, as
+// well as events.js.
+loadScripts({ name: "common.js", dir: MOCHITESTS_DIR },
+            { name: "layout.js", dir: MOCHITESTS_DIR }, "events.js");
--- a/accessible/tests/browser/browser_shutdown_acc_reference.js
+++ b/accessible/tests/browser/browser_shutdown_acc_reference.js
@@ -1,55 +1,55 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Create a11y service.
   let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
 
   await a11yInit;
-  ok(accService, 'Service initialized');
+  ok(accService, "Service initialized");
 
   // Accessible object reference will live longer than the scope of this
   // function.
   let acc = await new Promise(resolve => {
     let intervalId = setInterval(() => {
       let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
       if (tabAcc) {
         clearInterval(intervalId);
         resolve(tabAcc);
       }
     }, 10);
   });
-  ok(acc, 'Accessible object is created');
+  ok(acc, "Accessible object is created");
 
   let canShutdown = false;
   // This promise will resolve only if canShutdown flag is set to true. If
   // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
   // down, the promise will reject.
   let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
+      reject("Accessible service was shut down incorrectly")));
 
   accService = null;
-  ok(!accService, 'Service is removed');
+  ok(!accService, "Service is removed");
 
   // Force garbage collection that should not trigger shutdown because there is
   // a reference to an accessible object.
   forceGC();
   // Have some breathing room when removing a11y service references.
   await new Promise(resolve => executeSoon(resolve));
 
   // Now allow a11y service to shutdown.
   canShutdown = true;
   // Remove a reference to an accessible object.
   acc = null;
-  ok(!acc, 'Accessible object is removed');
+  ok(!acc, "Accessible object is removed");
 
   // Force garbage collection that should now trigger shutdown.
   forceGC();
   await a11yShutdown;
 });
--- a/accessible/tests/browser/browser_shutdown_doc_acc_reference.js
+++ b/accessible/tests/browser/browser_shutdown_doc_acc_reference.js
@@ -1,47 +1,47 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Create a11y service.
   let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
 
   await a11yInit;
-  ok(accService, 'Service initialized');
+  ok(accService, "Service initialized");
 
   // Accessible document reference will live longer than the scope of this
   // function.
   let docAcc = accService.getAccessibleFor(document);
-  ok(docAcc, 'Accessible document is created');
+  ok(docAcc, "Accessible document is created");
 
   let canShutdown = false;
   // This promise will resolve only if canShutdown flag is set to true. If
   // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
   // down, the promise will reject.
   let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
+      reject("Accessible service was shut down incorrectly")));
 
   accService = null;
-  ok(!accService, 'Service is removed');
+  ok(!accService, "Service is removed");
 
   // Force garbage collection that should not trigger shutdown because there is
   // a reference to an accessible document.
   forceGC();
   // Have some breathing room when removing a11y service references.
   await new Promise(resolve => executeSoon(resolve));
 
   // Now allow a11y service to shutdown.
   canShutdown = true;
   // Remove a reference to an accessible document.
   docAcc = null;
-  ok(!docAcc, 'Accessible document is removed');
+  ok(!docAcc, "Accessible document is removed");
 
   // Force garbage collection that should now trigger shutdown.
   forceGC();
   await a11yShutdown;
 });
--- a/accessible/tests/browser/browser_shutdown_multi_acc_reference_doc.js
+++ b/accessible/tests/browser/browser_shutdown_multi_acc_reference_doc.js
@@ -1,67 +1,67 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Create a11y service.
   let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
 
   await a11yInit;
-  ok(accService, 'Service initialized');
+  ok(accService, "Service initialized");
 
   let docAcc = accService.getAccessibleFor(document);
-  ok(docAcc, 'Accessible document is created');
+  ok(docAcc, "Accessible document is created");
 
   // Accessible object reference will live longer than the scope of this
   // function.
   let acc = await new Promise(resolve => {
     let intervalId = setInterval(() => {
       let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
       if (tabAcc) {
         clearInterval(intervalId);
         resolve(tabAcc);
       }
     }, 10);
   });
-  ok(acc, 'Accessible object is created');
+  ok(acc, "Accessible object is created");
 
   let canShutdown = false;
   // This promise will resolve only if canShutdown flag is set to true. If
   // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
   // down, the promise will reject.
   let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
+      reject("Accessible service was shut down incorrectly")));
 
   accService = null;
-  ok(!accService, 'Service is removed');
+  ok(!accService, "Service is removed");
 
   // Force garbage collection that should not trigger shutdown because there are
   // references to accessible objects.
   forceGC();
   // Have some breathing room when removing a11y service references.
   await new Promise(resolve => executeSoon(resolve));
 
   // Remove a reference to an accessible object.
   acc = null;
-  ok(!acc, 'Accessible object is removed');
+  ok(!acc, "Accessible object is removed");
   // Force garbage collection that should not trigger shutdown because there is
   // a reference to an accessible document.
   forceGC();
   // Have some breathing room when removing a11y service references.
   await new Promise(resolve => executeSoon(resolve));
 
   // Now allow a11y service to shutdown.
   canShutdown = true;
   // Remove a reference to an accessible document.
   docAcc = null;
-  ok(!docAcc, 'Accessible document is removed');
+  ok(!docAcc, "Accessible document is removed");
 
   // Force garbage collection that should now trigger shutdown.
   forceGC();
   await a11yShutdown;
 });
--- a/accessible/tests/browser/browser_shutdown_multi_acc_reference_obj.js
+++ b/accessible/tests/browser/browser_shutdown_multi_acc_reference_obj.js
@@ -1,67 +1,67 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Create a11y service.
   let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
 
   await a11yInit;
-  ok(accService, 'Service initialized');
+  ok(accService, "Service initialized");
 
   let docAcc = accService.getAccessibleFor(document);
-  ok(docAcc, 'Accessible document is created');
+  ok(docAcc, "Accessible document is created");
 
   // Accessible object reference will live longer than the scope of this
   // function.
   let acc = await new Promise(resolve => {
     let intervalId = setInterval(() => {
       let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
       if (tabAcc) {
         clearInterval(intervalId);
         resolve(tabAcc);
       }
     }, 10);
   });
-  ok(acc, 'Accessible object is created');
+  ok(acc, "Accessible object is created");
 
   let canShutdown = false;
   // This promise will resolve only if canShutdown flag is set to true. If
   // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
   // down, the promise will reject.
   let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
+      reject("Accessible service was shut down incorrectly")));
 
   accService = null;
-  ok(!accService, 'Service is removed');
+  ok(!accService, "Service is removed");
 
   // Force garbage collection that should not trigger shutdown because there are
   // references to accessible objects.
   forceGC();
   // Have some breathing room when removing a11y service references.
   await new Promise(resolve => executeSoon(resolve));
 
   // Remove a reference to an accessible document.
   docAcc = null;
-  ok(!docAcc, 'Accessible document is removed');
+  ok(!docAcc, "Accessible document is removed");
   // Force garbage collection that should not trigger shutdown because there is
   // a reference to an accessible object.
   forceGC();
   // Have some breathing room when removing a11y service references.
   await new Promise(resolve => executeSoon(resolve));
 
   // Now allow a11y service to shutdown.
   canShutdown = true;
   // Remove a reference to an accessible object.
   acc = null;
-  ok(!acc, 'Accessible object is removed');
+  ok(!acc, "Accessible object is removed");
 
   // Force garbage collection that should now trigger shutdown.
   forceGC();
   await a11yShutdown;
 });
--- a/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_doc.js
+++ b/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_doc.js
@@ -1,75 +1,75 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Making sure that the e10s is enabled on Windows for testing.
   await setE10sPrefs();
 
   let docLoaded = waitForEvent(
-    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
+    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, "body");
   let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
-  ok(accService, 'Service initialized');
+  ok(accService, "Service initialized");
   await a11yInit;
 
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: `data:text/html,
       <html>
         <head>
           <meta charset="utf-8"/>
           <title>Accessibility Test</title>
         </head>
         <body id="body"><div id="div"></div></body>
       </html>`
   }, async function(browser) {
     let docLoadedEvent = await docLoaded;
     let docAcc = docLoadedEvent.accessibleDocument;
-    ok(docAcc, 'Accessible document proxy is created');
+    ok(docAcc, "Accessible document proxy is created");
     // Remove unnecessary dangling references
     docLoaded = null;
     docLoadedEvent = null;
     forceGC();
 
     let acc = docAcc.getChildAt(0);
-    ok(acc, 'Accessible proxy is created');
+    ok(acc, "Accessible proxy is created");
 
     let canShutdown = false;
     let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
+      reject("Accessible service was shut down incorrectly")));
 
     accService = null;
-    ok(!accService, 'Service is removed');
+    ok(!accService, "Service is removed");
     // Force garbage collection that should not trigger shutdown because there
     // is a reference to an accessible proxy.
     forceGC();
     // Have some breathing room when removing a11y service references.
     await new Promise(resolve => executeSoon(resolve));
 
     // Remove a reference to an accessible proxy.
     acc = null;
-    ok(!acc, 'Accessible proxy is removed');
+    ok(!acc, "Accessible proxy is removed");
     // Force garbage collection that should not trigger shutdown because there is
     // a reference to an accessible document proxy.
     forceGC();
     // Have some breathing room when removing a11y service references.
     await new Promise(resolve => executeSoon(resolve));
 
     // Now allow a11y service to shutdown.
     canShutdown = true;
     // Remove a last reference to an accessible document proxy.
     docAcc = null;
-    ok(!docAcc, 'Accessible document proxy is removed');
+    ok(!docAcc, "Accessible document proxy is removed");
 
     // Force garbage collection that should now trigger shutdown.
     forceGC();
     await a11yShutdown;
   });
 
   // Unsetting e10s related preferences.
   await unsetE10sPrefs();
--- a/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_obj.js
+++ b/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_obj.js
@@ -1,75 +1,75 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Making sure that the e10s is enabled on Windows for testing.
   await setE10sPrefs();
 
   let docLoaded = waitForEvent(
-    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
+    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, "body");
   let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
-  ok(accService, 'Service initialized');
+  ok(accService, "Service initialized");
   await a11yInit;
 
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: `data:text/html,
       <html>
         <head>
           <meta charset="utf-8"/>
           <title>Accessibility Test</title>
         </head>
         <body id="body"><div id="div"></div></body>
       </html>`
   }, async function(browser) {
     let docLoadedEvent = await docLoaded;
     let docAcc = docLoadedEvent.accessibleDocument;
-    ok(docAcc, 'Accessible document proxy is created');
+    ok(docAcc, "Accessible document proxy is created");
     // Remove unnecessary dangling references
     docLoaded = null;
     docLoadedEvent = null;
     forceGC();
 
     let acc = docAcc.getChildAt(0);
-    ok(acc, 'Accessible proxy is created');
+    ok(acc, "Accessible proxy is created");
 
     let canShutdown = false;
     let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
+      reject("Accessible service was shut down incorrectly")));
 
     accService = null;
-    ok(!accService, 'Service is removed');
+    ok(!accService, "Service is removed");
     // Force garbage collection that should not trigger shutdown because there
     // is a reference to an accessible proxy.
     forceGC();
     // Have some breathing room when removing a11y service references.
     await new Promise(resolve => executeSoon(resolve));
 
     // Remove a reference to an accessible document proxy.
     docAcc = null;
-    ok(!docAcc, 'Accessible document proxy is removed');
+    ok(!docAcc, "Accessible document proxy is removed");
     // Force garbage collection that should not trigger shutdown because there is
     // a reference to an accessible proxy.
     forceGC();
     // Have some breathing room when removing a11y service references.
     await new Promise(resolve => executeSoon(resolve));
 
     // Now allow a11y service to shutdown.
     canShutdown = true;
     // Remove a last reference to an accessible proxy.
     acc = null;
-    ok(!acc, 'Accessible proxy is removed');
+    ok(!acc, "Accessible proxy is removed");
 
     // Force garbage collection that should now trigger shutdown.
     forceGC();
     await a11yShutdown;
   });
 
   // Unsetting e10s related preferences.
   await unsetE10sPrefs();
--- a/accessible/tests/browser/browser_shutdown_multi_reference.js
+++ b/accessible/tests/browser/browser_shutdown_multi_reference.js
@@ -1,48 +1,48 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
-  info('Creating a service');
+add_task(async function() {
+  info("Creating a service");
   // Create a11y service.
   let a11yInit = initPromise();
-  let accService1 = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService1 = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
   await a11yInit;
-  ok(accService1, 'Service initialized');
+  ok(accService1, "Service initialized");
 
   // Add another reference to a11y service. This will not trigger
   // 'a11y-init-or-shutdown' event
-  let accService2 = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService2 = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
-  ok(accService2, 'Service initialized');
+  ok(accService2, "Service initialized");
 
-  info('Removing all service references');
+  info("Removing all service references");
   let canShutdown = false;
   // This promise will resolve only if canShutdown flag is set to true. If
   // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
   // down, the promise will reject.
   let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ?
-      resolve() : reject('Accessible service was shut down incorrectly')));
+      resolve() : reject("Accessible service was shut down incorrectly")));
   // Remove first a11y service reference.
   accService1 = null;
-  ok(!accService1, 'Service is removed');
+  ok(!accService1, "Service is removed");
   // Force garbage collection that should not trigger shutdown because there is
   // another reference.
   forceGC();
 
   // Have some breathing room when removing a11y service references.
   await new Promise(resolve => executeSoon(resolve));
 
   // Now allow a11y service to shutdown.
   canShutdown = true;
   // Remove last a11y service reference.
   accService2 = null;
-  ok(!accService2, 'Service is removed');
+  ok(!accService2, "Service is removed");
   // Force garbage collection that should trigger shutdown.
   forceGC();
   await a11yShutdown;
 });
--- a/accessible/tests/browser/browser_shutdown_parent_own_reference.js
+++ b/accessible/tests/browser/browser_shutdown_parent_own_reference.js
@@ -1,71 +1,71 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Making sure that the e10s is enabled on Windows for testing.
   await setE10sPrefs();
 
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: `data:text/html,
       <html>
         <head>
           <meta charset="utf-8"/>
           <title>Accessibility Test</title>
         </head>
         <body></body>
       </html>`
   }, async function(browser) {
-    info('Creating a service in parent and waiting for service to be created ' +
-      'in content');
+    info("Creating a service in parent and waiting for service to be created " +
+      "in content");
     // Create a11y service in the main process. This will trigger creating of
     // the a11y service in parent as well.
     let parentA11yInit = initPromise();
     let contentA11yInit = initPromise(browser);
-    let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
       Ci.nsIAccessibilityService);
-    ok(accService, 'Service initialized in parent');
+    ok(accService, "Service initialized in parent");
     await Promise.all([parentA11yInit, contentA11yInit]);
 
-    info('Adding additional reference to accessibility service in content ' +
-      'process');
+    info("Adding additional reference to accessibility service in content " +
+      "process");
     // 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);`);
 
-    info('Trying to shut down a service in content and making sure it stays ' +
-      'alive as it was started by parent');
+    info("Trying to shut down a service in content and making sure it stays " +
+      "alive as it was started by parent");
     let contentCanShutdown = false;
     // 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
     // it can be shut down, the promise will reject.
     let contentA11yShutdown = new Promise((resolve, reject) =>
       shutdownPromise(browser).then(flag => contentCanShutdown ?
-        resolve() : reject('Accessible service was shut down incorrectly')));
+        resolve() : reject("Accessible service was shut down incorrectly")));
     // Remove a11y service reference in content and force garbage collection.
     // This should not trigger shutdown since a11y was originally initialized by
     // the main process.
     loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
 
     // Have some breathing room between a11y service shutdowns.
     await new Promise(resolve => executeSoon(resolve));
 
-    info('Removing a service in parent');
+    info("Removing a service in parent");
     // Now allow a11y service to shutdown in content.
     contentCanShutdown = true;
     // Remove the a11y service reference in the main process.
     let parentA11yShutdown = shutdownPromise();
     accService = null;
-    ok(!accService, 'Service is removed in parent');
+    ok(!accService, "Service is removed in parent");
     // Force garbage collection that should trigger shutdown in both parent and
     // content.
     forceGC();
     await Promise.all([parentA11yShutdown, contentA11yShutdown]);
 
     // Unsetting e10s related preferences.
     await unsetE10sPrefs();
   });
--- a/accessible/tests/browser/browser_shutdown_proxy_acc_reference.js
+++ b/accessible/tests/browser/browser_shutdown_proxy_acc_reference.js
@@ -1,63 +1,63 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Making sure that the e10s is enabled on Windows for testing.
   await setE10sPrefs();
 
   let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
-  ok(accService, 'Service initialized');
+  ok(accService, "Service initialized");
   await a11yInit;
 
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: `data:text/html,
       <html>
         <head>
           <meta charset="utf-8"/>
           <title>Accessibility Test</title>
         </head>
         <body><div id="div" style="visibility: hidden;"></div></body>
       </html>`
   }, async function(browser) {
-    let onShow = waitForEvent(Ci.nsIAccessibleEvent.EVENT_SHOW, 'div');
-    await invokeSetStyle(browser, 'div', 'visibility', 'visible');
+    let onShow = waitForEvent(Ci.nsIAccessibleEvent.EVENT_SHOW, "div");
+    await invokeSetStyle(browser, "div", "visibility", "visible");
     let showEvent = await onShow;
     let divAcc = showEvent.accessible;
-    ok(divAcc, 'Accessible proxy is created');
+    ok(divAcc, "Accessible proxy is created");
     // Remove unnecessary dangling references
     onShow = null;
     showEvent = null;
     forceGC();
 
     let canShutdown = false;
     let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
+      reject("Accessible service was shut down incorrectly")));
 
     accService = null;
-    ok(!accService, 'Service is removed');
+    ok(!accService, "Service is removed");
     // Force garbage collection that should not trigger shutdown because there
     // is a reference to an accessible proxy.
     forceGC();
     // Have some breathing room when removing a11y service references.
     await new Promise(resolve => executeSoon(resolve));
 
     // Now allow a11y service to shutdown.
     canShutdown = true;
     // Remove a last reference to an accessible proxy.
     divAcc = null;
-    ok(!divAcc, 'Accessible proxy is removed');
+    ok(!divAcc, "Accessible proxy is removed");
 
     // Force garbage collection that should now trigger shutdown.
     forceGC();
     await a11yShutdown;
   });
 
   // Unsetting e10s related preferences.
   await unsetE10sPrefs();
--- a/accessible/tests/browser/browser_shutdown_proxy_doc_acc_reference.js
+++ b/accessible/tests/browser/browser_shutdown_proxy_doc_acc_reference.js
@@ -1,63 +1,63 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Making sure that the e10s is enabled on Windows for testing.
   await setE10sPrefs();
 
   let docLoaded = waitForEvent(
-    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
+    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, "body");
   let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
-  ok(accService, 'Service initialized');
+  ok(accService, "Service initialized");
   await a11yInit;
 
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: `data:text/html,
       <html>
         <head>
           <meta charset="utf-8"/>
           <title>Accessibility Test</title>
         </head>
         <body id="body"></body>
       </html>`
   }, async function(browser) {
     let docLoadedEvent = await docLoaded;
     let docAcc = docLoadedEvent.accessibleDocument;
-    ok(docAcc, 'Accessible document proxy is created');
+    ok(docAcc, "Accessible document proxy is created");
     // Remove unnecessary dangling references
     docLoaded = null;
     docLoadedEvent = null;
     forceGC();
 
     let canShutdown = false;
     let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
+      reject("Accessible service was shut down incorrectly")));
 
     accService = null;
-    ok(!accService, 'Service is removed');
+    ok(!accService, "Service is removed");
     // Force garbage collection that should not trigger shutdown because there
     // is a reference to an accessible proxy.
     forceGC();
     // Have some breathing room when removing a11y service references.
     await new Promise(resolve => executeSoon(resolve));
 
     // Now allow a11y service to shutdown.
     canShutdown = true;
     // Remove a last reference to an accessible document proxy.
     docAcc = null;
-    ok(!docAcc, 'Accessible document proxy is removed');
+    ok(!docAcc, "Accessible document proxy is removed");
 
     // Force garbage collection that should now trigger shutdown.
     forceGC();
     await a11yShutdown;
   });
 
   // Unsetting e10s related preferences.
   await unsetE10sPrefs();
--- a/accessible/tests/browser/browser_shutdown_remote_no_reference.js
+++ b/accessible/tests/browser/browser_shutdown_remote_no_reference.js
@@ -1,47 +1,47 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Making sure that the e10s is enabled on Windows for testing.
   await setE10sPrefs();
 
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: `data:text/html,
       <html>
         <head>
           <meta charset="utf-8"/>
           <title>Accessibility Test</title>
         </head>
         <body></body>
       </html>`
   }, async function(browser) {
-    info('Creating a service in parent and waiting for service to be created ' +
-      'in content');
+    info("Creating a service in parent and waiting for service to be created " +
+      "in content");
     // Create a11y service in the main process. This will trigger creating of
     // the a11y service in parent as well.
     let parentA11yInit = initPromise();
     let contentA11yInit = initPromise(browser);
-    let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
       Ci.nsIAccessibilityService);
-    ok(accService, 'Service initialized in parent');
+    ok(accService, "Service initialized in parent");
     await Promise.all([parentA11yInit, contentA11yInit]);
 
-    info('Removing a service in parent and waiting for service to be shut ' +
-      'down in content');
+    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);
     accService = null;
-    ok(!accService, 'Service is removed in parent');
+    ok(!accService, "Service is removed in parent");
     // Force garbage collection that should trigger shutdown in both main and
     // content process.
     forceGC();
     await Promise.all([parentA11yShutdown, contentA11yShutdown]);
   });
 
   // Unsetting e10s related preferences.
   await unsetE10sPrefs();
--- a/accessible/tests/browser/browser_shutdown_remote_only.js
+++ b/accessible/tests/browser/browser_shutdown_remote_only.js
@@ -1,38 +1,38 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Making sure that the e10s is enabled on Windows for testing.
   await setE10sPrefs();
 
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: `data:text/html,
       <html>
         <head>
           <meta charset="utf-8"/>
           <title>Accessibility Test</title>
         </head>
         <body></body>
       </html>`
   }, async function(browser) {
-    info('Creating a service in content');
+    info("Creating a service in content");
     // Create a11y service in the content process.
     let a11yInit = initPromise(browser);
     loadFrameScripts(browser, `let accService = Components.classes[
       '@mozilla.org/accessibilityService;1'].getService(
         Components.interfaces.nsIAccessibilityService);`);
     await a11yInit;
 
-    info('Removing a service in content');
+    info("Removing a service in content");
     // Remove a11y service reference from the content process.
     let a11yShutdown = shutdownPromise(browser);
     // Force garbage collection that should trigger shutdown.
     loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
     await a11yShutdown;
 
     // Unsetting e10s related preferences.
     await unsetE10sPrefs();
--- a/accessible/tests/browser/browser_shutdown_remote_own_reference.js
+++ b/accessible/tests/browser/browser_shutdown_remote_own_reference.js
@@ -1,72 +1,72 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Making sure that the e10s is enabled on Windows for testing.
   await setE10sPrefs();
 
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: `data:text/html,
       <html>
         <head>
           <meta charset="utf-8"/>
           <title>Accessibility Test</title>
         </head>
         <body></body>
       </html>`
   }, async function(browser) {
-    info('Creating a service in parent and waiting for service to be created ' +
-      'in content');
+    info("Creating a service in parent and waiting for service to be created " +
+      "in content");
     // Create a11y service in the main process. This will trigger creating of
     // the a11y service in parent as well.
     let parentA11yInit = initPromise();
     let contentA11yInit = initPromise(browser);
-    let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
       Ci.nsIAccessibilityService);
-    ok(accService, 'Service initialized in parent');
+    ok(accService, "Service initialized in parent");
     await Promise.all([parentA11yInit, contentA11yInit]);
 
-    info('Adding additional reference to accessibility service in content ' +
-      'process');
+    info("Adding additional reference to accessibility service in content " +
+      "process");
     // 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);`);
 
-    info('Shutting down a service in parent and making sure the one in ' +
-      'content stays alive');
+    info("Shutting down a service in parent and making sure the one in " +
+      "content stays alive");
     let contentCanShutdown = false;
     let parentA11yShutdown = shutdownPromise();
     // 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
     // it can be shut down, the promise will reject.
     let contentA11yShutdown = new Promise((resolve, reject) =>
       shutdownPromise(browser).then(flag => contentCanShutdown ?
-        resolve() : reject('Accessible service was shut down incorrectly')));
+        resolve() : reject("Accessible service was shut down incorrectly")));
     // Remove a11y service reference in the main process and force garbage
     // collection. This should not trigger shutdown in content since a11y
     // service is used by XPCOM.
     accService = null;
-    ok(!accService, 'Service is removed in parent');
+    ok(!accService, "Service is removed in parent");
     // Force garbage collection that should not trigger shutdown because there
     // is a reference in a content process.
     forceGC();
     loadFrameScripts(browser, `Components.utils.forceGC();`);
     await parentA11yShutdown;
 
     // Have some breathing room between a11y service shutdowns.
     await new Promise(resolve => executeSoon(resolve));
 
-    info('Removing a service in content');
+    info("Removing a service in content");
     // Now allow a11y service to shutdown in content.
     contentCanShutdown = true;
     // Remove last reference to a11y service in content and force garbage
     // collection that should trigger shutdown.
     loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
     await contentA11yShutdown;
 
     // Unsetting e10s related preferences.
--- a/accessible/tests/browser/browser_shutdown_scope_lifecycle.js
+++ b/accessible/tests/browser/browser_shutdown_scope_lifecycle.js
@@ -1,21 +1,21 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
+add_task(async function() {
   // Create a11y service inside of the function scope. Its reference should be
   // released once the anonimous function is called.
   let a11yInitThenShutdown = initPromise().then(shutdownPromise);
 
   (function() {
-    let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+    let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
       Ci.nsIAccessibilityService);
-    ok(accService, 'Service initialized');
+    ok(accService, "Service initialized");
   })();
 
   // Force garbage collection that should trigger shutdown.
   forceGC();
   await a11yInitThenShutdown;
 });
--- a/accessible/tests/browser/browser_shutdown_start_restart.js
+++ b/accessible/tests/browser/browser_shutdown_start_restart.js
@@ -1,41 +1,41 @@
 /* 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';
+"use strict";
 
-add_task(async function () {
-  info('Creating a service');
+add_task(async function() {
+  info("Creating a service");
   // Create a11y service.
   let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+  let accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
   await a11yInit;
-  ok(accService, 'Service initialized');
+  ok(accService, "Service initialized");
 
-  info('Removing a service');
+  info("Removing a service");
   // Remove the only reference to an a11y service.
   let a11yShutdown = shutdownPromise();
   accService = null;
-  ok(!accService, 'Service is removed');
+  ok(!accService, "Service is removed");
   // Force garbage collection that should trigger shutdown.
   forceGC();
   await a11yShutdown;
 
-  info('Recreating a service');
+  info("Recreating a service");
   // Re-create a11y service.
   a11yInit = initPromise();
-  accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+  accService = Cc["@mozilla.org/accessibilityService;1"].getService(
     Ci.nsIAccessibilityService);
   await a11yInit;
-  ok(accService, 'Service initialized again');
+  ok(accService, "Service initialized again");
 
-  info('Removing a service again');
+  info("Removing a service again");
   // Remove the only reference to an a11y service again.
   a11yShutdown = shutdownPromise();
   accService = null;
-  ok(!accService, 'Service is removed again');
+  ok(!accService, "Service is removed again");
   // Force garbage collection that should trigger shutdown.
   forceGC();
   await a11yShutdown;
 });
--- a/accessible/tests/browser/e10s/browser_caching_attributes.js
+++ b/accessible/tests/browser/e10s/browser_caching_attributes.js
@@ -1,115 +1,115 @@
 /* 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';
+"use strict";
 
 /* import-globals-from ../../mochitest/attributes.js */
-loadScripts({ name: 'attributes.js', dir: MOCHITESTS_DIR });
+loadScripts({ name: "attributes.js", dir: MOCHITESTS_DIR });
 
 /**
  * Default textbox accessible attributes.
  */
 const defaultAttributes = {
-  'margin-top': '0px',
-  'margin-right': '0px',
-  'margin-bottom': '0px',
-  'margin-left': '0px',
-  'text-align': 'start',
-  'text-indent': '0px',
-  'id': 'textbox',
-  'tag': 'input',
-  'display': 'inline'
+  "margin-top": "0px",
+  "margin-right": "0px",
+  "margin-bottom": "0px",
+  "margin-left": "0px",
+  "text-align": "start",
+  "text-indent": "0px",
+  "id": "textbox",
+  "tag": "input",
+  "display": "inline"
 };
 
 /**
  * Test data has the format of:
  * {
  *   desc        {String}         description for better logging
  *   expected    {Object}         expected attributes for given accessibles
  *   unexpected  {Object}         unexpected attributes for given accessibles
  *
  *   action      {?AsyncFunction} an optional action that awaits a change in
  *                                attributes
  *   attrs       {?Array}         an optional list of attributes to update
  *   waitFor     {?Number}        an optional event to wait for
  * }
  */
 const attributesTests = [{
-  desc: 'Initiall accessible attributes',
+  desc: "Initiall accessible attributes",
   expected: defaultAttributes,
   unexpected: {
-    'line-number': '1',
-    'explicit-name': 'true',
-    'container-live': 'polite',
-    'live': 'polite'
+    "line-number": "1",
+    "explicit-name": "true",
+    "container-live": "polite",
+    "live": "polite"
   }
 }, {
-  desc: '@line-number attribute is present when textbox is focused',
+  desc: "@line-number attribute is present when textbox is focused",
   action: async function(browser) {
-    await invokeFocus(browser, 'textbox');
+    await invokeFocus(browser, "textbox");
   },
   waitFor: EVENT_FOCUS,
-  expected: Object.assign({}, defaultAttributes, { 'line-number': '1' }),
+  expected: Object.assign({}, defaultAttributes, { "line-number": "1" }),
   unexpected: {
-    'explicit-name': 'true',
-    'container-live': 'polite',
-    'live': 'polite'
+    "explicit-name": "true",
+    "container-live": "polite",
+    "live": "polite"
   }
 }, {
-  desc: '@aria-live sets container-live and live attributes',
+  desc: "@aria-live sets container-live and live attributes",
   attrs: [{
-    attr: 'aria-live',
-    value: 'polite'
+    attr: "aria-live",
+    value: "polite"
   }],
   expected: Object.assign({}, defaultAttributes, {
-    'line-number': '1',
-    'container-live': 'polite',
-    'live': 'polite'
+    "line-number": "1",
+    "container-live": "polite",
+    "live": "polite"
   }),
   unexpected: {
-    'explicit-name': 'true'
+    "explicit-name": "true"
   }
 }, {
-  desc: '@title attribute sets explicit-name attribute to true',
+  desc: "@title attribute sets explicit-name attribute to true",
   attrs: [{
-    attr: 'title',
-    value: 'textbox'
+    attr: "title",
+    value: "textbox"
   }],
   expected: Object.assign({}, defaultAttributes, {
-    'line-number': '1',
-    'explicit-name': 'true',
-    'container-live': 'polite',
-    'live': 'polite'
+    "line-number": "1",
+    "explicit-name": "true",
+    "container-live": "polite",
+    "live": "polite"
   }),
   unexpected: {}
 }];
 
 /**
  * Test caching of accessible object attributes
  */
 addAccessibleTask(`
   <input id="textbox" value="hello">`,
-  async function (browser, accDoc) {
-    let textbox = findAccessibleChildByID(accDoc, 'textbox');
+  async function(browser, accDoc) {
+    let textbox = findAccessibleChildByID(accDoc, "textbox");
     for (let { desc, action, attrs, expected, waitFor, unexpected } of attributesTests) {
       info(desc);
       let onUpdate;
 
       if (waitFor) {
-        onUpdate = waitForEvent(waitFor, 'textbox');
+        onUpdate = waitForEvent(waitFor, "textbox");
       }
 
       if (action) {
         await action(browser);
       } else if (attrs) {
         for (let { attr, value } of attrs) {
-          await invokeSetAttribute(browser, 'textbox', attr, value);
+          await invokeSetAttribute(browser, "textbox", attr, value);
         }
       }
 
       await onUpdate;
       testAttrs(textbox, expected);
       testAbsentAttrs(textbox, unexpected);
     }
   }
--- a/accessible/tests/browser/e10s/browser_caching_description.js
+++ b/accessible/tests/browser/e10s/browser_caching_description.js
@@ -1,163 +1,163 @@
 /* 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';
+"use strict";
 
 /* import-globals-from ../../mochitest/name.js */
-loadScripts({ name: 'name.js', dir: MOCHITESTS_DIR });
+loadScripts({ name: "name.js", dir: MOCHITESTS_DIR });
 
 /**
  * Test data has the format of:
  * {
  *   desc      {String}   description for better logging
  *   expected  {String}   expected description value for a given accessible
  *   attrs     {?Array}   an optional list of attributes to update
  *   waitFor   {?Array}   an optional list of accessible events to wait for when
  *                        attributes are updated
  * }
  */
 const tests = [{
-  desc: 'No description when there are no @alt, @title and @aria-describedby',
-  expected: ''
+  desc: "No description when there are no @alt, @title and @aria-describedby",
+  expected: ""
 }, {
-  desc: 'Description from @aria-describedby attribute',
+  desc: "Description from @aria-describedby attribute",
   attrs: [{
-    attr: 'aria-describedby',
-    value: 'description'
+    attr: "aria-describedby",
+    value: "description"
   }],
-  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
-  expected: 'aria description'
+  waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]],
+  expected: "aria description"
 }, {
-  desc: 'No description from @aria-describedby since it is the same as the ' +
-        '@alt attribute which is used as the name',
+  desc: "No description from @aria-describedby since it is the same as the " +
+        "@alt attribute which is used as the name",
   attrs: [{
-    attr: 'alt',
-    value: 'aria description'
+    attr: "alt",
+    value: "aria description"
   }],
-  waitFor: [{ eventType: EVENT_REORDER, id: 'body' }],
-  expected: ''
+  waitFor: [[EVENT_REORDER, "body"]],
+  expected: ""
 }, {
-  desc: 'Description from @aria-describedby attribute when @alt and ' +
-        '@aria-describedby are not the same',
+  desc: "Description from @aria-describedby attribute when @alt and " +
+        "@aria-describedby are not the same",
   attrs: [{
-    attr: 'aria-describedby',
-    value: 'description2'
+    attr: "aria-describedby",
+    value: "description2"
   }],
-  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
-  expected: 'another description'
+  waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]],
+  expected: "another description"
 }, {
-  desc: 'Description from @aria-describedby attribute when @title (used for ' +
-        'name) and @aria-describedby are not the same',
+  desc: "Description from @aria-describedby attribute when @title (used for " +
+        "name) and @aria-describedby are not the same",
   attrs: [{
-    attr: 'alt'
+    attr: "alt"
   }, {
-    attr: 'title',
-    value: 'title'
+    attr: "title",
+    value: "title"
   }],
-  waitFor: [{ eventType: EVENT_REORDER, id: 'body' }],
-  expected: 'another description'
+  waitFor: [[EVENT_REORDER, "body"]],
+  expected: "another description"
 }, {
-  desc: 'No description from @aria-describedby since it is the same as the ' +
-        '@title attribute which is used as the name',
+  desc: "No description from @aria-describedby since it is the same as the " +
+        "@title attribute which is used as the name",
   attrs: [{
-    attr: 'title',
-    value: 'another description'
+    attr: "title",
+    value: "another description"
   }],
-  waitFor: [{ eventType: EVENT_NAME_CHANGE, id: 'image' }],
-  expected: ''
+  waitFor: [[EVENT_NAME_CHANGE, "image"]],
+  expected: ""
 }, {
-  desc: 'No description with only @title attribute which is used as the name',
+  desc: "No description with only @title attribute which is used as the name",
   attrs: [{
-    attr: 'aria-describedby'
+    attr: "aria-describedby"
   }],
-  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
-  expected: ''
+  waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]],
+  expected: ""
 }, {
-  desc: 'Description from @title attribute when @alt and @atitle are not the ' +
-        'same',
+  desc: "Description from @title attribute when @alt and @atitle are not the " +
+        "same",
   attrs: [{
-    attr: 'alt',
-    value: 'aria description'
+    attr: "alt",
+    value: "aria description"
   }],
-  waitFor: [{ eventType: EVENT_REORDER, id: 'body' }],
-  expected: 'another description'
+  waitFor: [[EVENT_REORDER, "body"]],
+  expected: "another description"
 }, {
-  desc: 'No description from @title since it is the same as the @alt ' +
-        'attribute which is used as the name',
+  desc: "No description from @title since it is the same as the @alt " +
+        "attribute which is used as the name",
   attrs: [{
-    attr: 'alt',
-    value: 'another description'
+    attr: "alt",
+    value: "another description"
   }],
-  waitFor: [{ eventType: EVENT_NAME_CHANGE, id: 'image' }],
-  expected: ''
+  waitFor: [[EVENT_NAME_CHANGE, "image"]],
+  expected: ""
 }, {
-  desc: 'No description from @aria-describedby since it is the same as the ' +
-        '@alt (used for name) and @title attributes',
+  desc: "No description from @aria-describedby since it is the same as the " +
+        "@alt (used for name) and @title attributes",
   attrs: [{
-    attr: 'aria-describedby',
-    value: 'description2'
+    attr: "aria-describedby",
+    value: "description2"
   }],
-  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
-  expected: ''
+  waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]],
+  expected: ""
 }, {
-  desc: 'Description from @aria-describedby attribute when it is different ' +
-        'from @alt (used for name) and @title attributes',
+  desc: "Description from @aria-describedby attribute when it is different " +
+        "from @alt (used for name) and @title attributes",
   attrs: [{
-    attr: 'aria-describedby',
-    value: 'description'
+    attr: "aria-describedby",
+    value: "description"
   }],
-  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
-  expected: 'aria description'
+  waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]],
+  expected: "aria description"
 }, {
-  desc: 'No description from @aria-describedby since it is the same as the ' +
-        '@alt attribute (used for name) but different from title',
+  desc: "No description from @aria-describedby since it is the same as the " +
+        "@alt attribute (used for name) but different from title",
   attrs: [{
-    attr: 'alt',
-    value: 'aria description'
+    attr: "alt",
+    value: "aria description"
   }],
-  waitFor: [{ eventType: EVENT_NAME_CHANGE, id: 'image' }],
-  expected: ''
+  waitFor: [[EVENT_NAME_CHANGE, "image"]],
+  expected: ""
 }, {
-  desc: 'Description from @aria-describedby attribute when @alt (used for ' +
-        'name) and @aria-describedby are not the same but @title and ' +
-        'aria-describedby are',
+  desc: "Description from @aria-describedby attribute when @alt (used for " +
+        "name) and @aria-describedby are not the same but @title and " +
+        "aria-describedby are",
   attrs: [{
-    attr: 'aria-describedby',
-    value: 'description2'
+    attr: "aria-describedby",
+    value: "description2"
   }],
-  waitFor: [{ eventType: EVENT_DESCRIPTION_CHANGE, id: 'image' }],
-  expected: 'another description'
+  waitFor: [[EVENT_DESCRIPTION_CHANGE, "image"]],
+  expected: "another description"
 }];
 
 /**
  * Test caching of accessible object description
  */
 addAccessibleTask(`
   <p id="description">aria description</p>
   <p id="description2">another description</p>
   <img id="image" />`,
   async function(browser, accDoc) {
-    let imgAcc = findAccessibleChildByID(accDoc, 'image');
+    let imgAcc = findAccessibleChildByID(accDoc, "image");
 
     for (let { desc, waitFor, attrs, expected } of tests) {
       info(desc);
       let onUpdate;
       if (waitFor) {
-        onUpdate = waitForMultipleEvents(waitFor);
+        onUpdate = waitForOrderedEvents(waitFor);
       }
       if (attrs) {
         for (let { attr, value } of attrs) {
-          await invokeSetAttribute(browser, 'image', attr, value);
+          await invokeSetAttribute(browser, "image", attr, value);
         }
       }
       await onUpdate;
       // When attribute change (alt) triggers reorder event, accessible will
       // become defunct.
       if (isDefunct(imgAcc)) {
-        imgAcc = findAccessibleChildByID(accDoc, 'image');
+        imgAcc = findAccessibleChildByID(accDoc, "image");
       }
       testDescr(imgAcc, expected);
     }
   }
 );
--- a/accessible/tests/browser/e10s/browser_caching_name.js
+++ b/accessible/tests/browser/e10s/browser_caching_name.js
@@ -1,16 +1,16 @@
 /* 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';
+"use strict";
 
 /* import-globals-from ../../mochitest/name.js */
-loadScripts({ name: 'name.js', dir: MOCHITESTS_DIR });
+loadScripts({ name: "name.js", dir: MOCHITESTS_DIR });
 
 /**
  * Rules for name tests that are inspired by
  *   accessible/tests/mochitest/name/markuprules.xul
  *
  * Each element in the list of rules represents a name calculation rule for a
  * particular test case.
  *
@@ -21,187 +21,187 @@ loadScripts({ name: 'name.js', dir: MOCH
  *
  *
  * Options include:
  *   * recreated   - subrtee is recreated and the test should only continue
  *                   after a reorder event
  *   * textchanged - text is inserted into a subtree and the test should only
  *                   continue after a text inserted event
  */
-const ARIARule = [{ attr: 'aria-labelledby' }, { attr: 'aria-label' }];
-const HTMLControlHeadRule = [...ARIARule, { elm: 'label', isSibling: true }];
+const ARIARule = [{ attr: "aria-labelledby" }, { attr: "aria-label" }];
+const HTMLControlHeadRule = [...ARIARule, { elm: "label", isSibling: true }];
 const rules = {
-  CSSContent: [{ elm: 'style', isSibling: true }, { fromsubtree: true }],
-  HTMLARIAGridCell: [...ARIARule, { fromsubtree: true }, { attr: 'title' }],
+  CSSContent: [{ elm: "style", isSibling: true }, { fromsubtree: true }],
+  HTMLARIAGridCell: [...ARIARule, { fromsubtree: true }, { attr: "title" }],
   HTMLControl: [...HTMLControlHeadRule, { fromsubtree: true },
-    { attr: 'title' }],
-  HTMLElm: [...ARIARule, { attr: 'title' }],
-  HTMLImg: [...ARIARule, { attr: 'alt', recreated: true }, { attr: 'title' }],
-  HTMLImgEmptyAlt: [...ARIARule, { attr: 'title' }, { attr: 'alt' }],
-  HTMLInputButton: [...HTMLControlHeadRule, { attr: 'value' },
-    { attr: 'title' }],
-  HTMLInputImage: [...HTMLControlHeadRule, { attr: 'alt', recreated: true },
-    { attr: 'value', recreated: true }, { attr: 'title' }],
+    { attr: "title" }],
+  HTMLElm: [...ARIARule, { attr: "title" }],
+  HTMLImg: [...ARIARule, { attr: "alt", recreated: true }, { attr: "title" }],
+  HTMLImgEmptyAlt: [...ARIARule, { attr: "title" }, { attr: "alt" }],
+  HTMLInputButton: [...HTMLControlHeadRule, { attr: "value" },
+    { attr: "title" }],
+  HTMLInputImage: [...HTMLControlHeadRule, { attr: "alt", recreated: true },
+    { attr: "value", recreated: true }, { attr: "title" }],
   HTMLInputImageNoValidSrc: [...HTMLControlHeadRule,
-    { attr: 'alt', recreated: true }, { attr: 'value', recreated: true }],
+    { attr: "alt", recreated: true }, { attr: "value", recreated: true }],
   HTMLInputReset: [...HTMLControlHeadRule,
-    { attr: 'value', textchanged: true }],
+    { attr: "value", textchanged: true }],
   HTMLInputSubmit: [...HTMLControlHeadRule,
-    { attr: 'value', textchanged: true }],
-  HTMLLink: [...ARIARule, { fromsubtree: true }, { attr: 'title' }],
-  HTMLLinkImage: [...ARIARule, { elm: 'img' }, { attr: 'title' }],
-  HTMLOption: [...ARIARule, { attr: 'label' }, { fromsubtree: true },
-    { attr: 'title' }],
-  HTMLTable: [...ARIARule, { elm: 'caption' }, { attr: 'summary' },
-    { attr: 'title' }]
+    { attr: "value", textchanged: true }],
+  HTMLLink: [...ARIARule, { fromsubtree: true }, { attr: "title" }],
+  HTMLLinkImage: [...ARIARule, { elm: "img" }, { attr: "title" }],
+  HTMLOption: [...ARIARule, { attr: "label" }, { fromsubtree: true },
+    { attr: "title" }],
+  HTMLTable: [...ARIARule, { elm: "caption" }, { attr: "summary" },
+    { attr: "title" }]
 };
 
 const markupTests = [{
-  id: 'btn',
-  ruleset: 'HTMLControl',
+  id: "btn",
+  ruleset: "HTMLControl",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <label for="btn">test4</label>
     <button id="btn"
             aria-label="test1"
             aria-labelledby="l1 l2"
             title="test5">press me</button>`,
-  expected: ['test2 test3', 'test1', 'test4', 'press me', 'test5']
+  expected: ["test2 test3", "test1", "test4", "press me", "test5"]
 }, {
-  id: 'btn',
-  ruleset: 'HTMLInputButton',
+  id: "btn",
+  ruleset: "HTMLInputButton",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <label for="btn">test4</label>
     <input id="btn"
            type="button"
            aria-label="test1"
            aria-labelledby="l1 l2"
            value="name from value"
            alt="no name from al"
            src="no name from src"
            data="no name from data"
            title="name from title"/>`,
-  expected: ['test2 test3', 'test1', 'test4', 'name from value',
-    'name from title']
+  expected: ["test2 test3", "test1", "test4", "name from value",
+    "name from title"]
 }, {
-  id: 'btn-submit',
-  ruleset: 'HTMLInputSubmit',
+  id: "btn-submit",
+  ruleset: "HTMLInputSubmit",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <label for="btn-submit">test4</label>
     <input id="btn-submit"
            type="submit"
            aria-label="test1"
            aria-labelledby="l1 l2"
            value="name from value"
            alt="no name from atl"
            src="no name from src"
            data="no name from data"
            title="no name from title"/>`,
-  expected: ['test2 test3', 'test1', 'test4', 'name from value']
+  expected: ["test2 test3", "test1", "test4", "name from value"]
 }, {
-  id: 'btn-reset',
-  ruleset: 'HTMLInputReset',
+  id: "btn-reset",
+  ruleset: "HTMLInputReset",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <label for="btn-reset">test4</label>
     <input id="btn-reset"
            type="reset"
            aria-label="test1"
            aria-labelledby="l1 l2"
            value="name from value"
            alt="no name from alt"
            src="no name from src"
            data="no name from data"
            title="no name from title"/>`,
-  expected: ['test2 test3', 'test1', 'test4', 'name from value']
+  expected: ["test2 test3", "test1", "test4", "name from value"]
 }, {
-  id: 'btn-image',
-  ruleset: 'HTMLInputImage',
+  id: "btn-image",
+  ruleset: "HTMLInputImage",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <label for="btn-image">test4</label>
     <input id="btn-image"
            type="image"
            aria-label="test1"
            aria-labelledby="l1 l2"
            alt="name from alt"
            value="name from value"
            src="http://example.com/a11y/accessible/tests/mochitest/moz.png"
            data="no name from data"
            title="name from title"/>`,
-  expected: ['test2 test3', 'test1', 'test4', 'name from alt',
-    'name from value', 'name from title']
+  expected: ["test2 test3", "test1", "test4", "name from alt",
+    "name from value", "name from title"]
 }, {
-  id: 'btn-image',
-  ruleset: 'HTMLInputImageNoValidSrc',
+  id: "btn-image",
+  ruleset: "HTMLInputImageNoValidSrc",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <label for="btn-image">test4</label>
     <input id="btn-image"
            type="image"
            aria-label="test1"
            aria-labelledby="l1 l2"
            alt="name from alt"
            value="name from value"
            data="no name from data"
            title="no name from title"/>`,
-  expected: ['test2 test3', 'test1', 'test4', 'name from alt',
-    'name from value']
+  expected: ["test2 test3", "test1", "test4", "name from alt",
+    "name from value"]
 }, {
-  id: 'opt',
-  ruleset: 'HTMLOption',
+  id: "opt",
+  ruleset: "HTMLOption",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <select>
       <option id="opt"
               aria-label="test1"
               aria-labelledby="l1 l2"
               label="test4"
               title="test5">option1</option>
       <option>option2</option>
     </select>`,
-  expected: ['test2 test3', 'test1', 'test4', 'option1', 'test5']
+  expected: ["test2 test3", "test1", "test4", "option1", "test5"]
 }, {
-  id: 'img',
-  ruleset: 'HTMLImg',
+  id: "img",
+  ruleset: "HTMLImg",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <img id="img"
          aria-label="Logo of Mozilla"
          aria-labelledby="l1 l2"
          alt="Mozilla logo"
          title="This is a logo"
          src="http://example.com/a11y/accessible/tests/mochitest/moz.png"/>`,
-  expected: ['test2 test3', 'Logo of Mozilla', 'Mozilla logo', 'This is a logo']
+  expected: ["test2 test3", "Logo of Mozilla", "Mozilla logo", "This is a logo"]
 }, {
-  id: 'imgemptyalt',
-  ruleset: 'HTMLImgEmptyAlt',
+  id: "imgemptyalt",
+  ruleset: "HTMLImgEmptyAlt",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <img id="imgemptyalt"
          aria-label="Logo of Mozilla"
          aria-labelledby="l1 l2"
          title="This is a logo"
          alt=""
          src="http://example.com/a11y/accessible/tests/mochitest/moz.png"/>`,
-  expected: ['test2 test3', 'Logo of Mozilla', 'This is a logo', '']
+  expected: ["test2 test3", "Logo of Mozilla", "This is a logo", ""]
 }, {
-  id: 'tc',
-  ruleset: 'HTMLElm',
+  id: "tc",
+  ruleset: "HTMLElm",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <label for="tc">test4</label>
     <table>
       <tr>
         <td id="tc"
             aria-label="test1"
@@ -210,20 +210,20 @@ const markupTests = [{
           <p>This is a paragraph</p>
           <a href="#">This is a link</a>
           <ul>
             <li>This is a list</li>
           </ul>
         </td>
       </tr>
     </table>`,
-  expected: ['test2 test3', 'test1', 'test5']
+  expected: ["test2 test3", "test1", "test5"]
 }, {
-  id: 'gc',
-  ruleset: 'HTMLARIAGridCell',
+  id: "gc",
+  ruleset: "HTMLARIAGridCell",
   markup: `
     <span id="l1">test2</span>
     <span id="l2">test3</span>
     <label for="gc">test4</label>
     <table>
       <tr>
         <td id="gc"
             role="gridcell"
@@ -234,86 +234,86 @@ const markupTests = [{
           <a href="#">This is a link</a>
           <ul>
             <li>Listitem1</li>
             <li>Listitem2</li>
           </ul>
         </td>
       </tr>
     </table>`,
-  expected: ['test2 test3', 'test1',
-    'This is a paragraph This is a link \u2022 Listitem1 \u2022 Listitem2',
-    'This is a paragraph This is a link This is a list']
+  expected: ["test2 test3", "test1",
+    "This is a paragraph This is a link \u2022 Listitem1 \u2022 Listitem2",
+    "This is a paragraph This is a link This is a list"]
 }, {
-  id: 't',
-  ruleset: 'HTMLTable',
+  id: "t",
+  ruleset: "HTMLTable",
   markup: `
     <span id="l1">lby_tst6_1</span>
     <span id="l2">lby_tst6_2</span>
     <label for="t">label_tst6</label>
     <table id="t"
            aria-label="arialabel_tst6"
            aria-labelledby="l1 l2"
            summary="summary_tst6"
            title="title_tst6">
       <caption>caption_tst6</caption>
       <tr>
         <td>cell1</td>
         <td>cell2</td>
       </tr>
     </table>`,
-  expected: ['lby_tst6_1 lby_tst6_2', 'arialabel_tst6', 'caption_tst6',
-    'summary_tst6', 'title_tst6']
+  expected: ["lby_tst6_1 lby_tst6_2", "arialabel_tst6", "caption_tst6",
+    "summary_tst6", "title_tst6"]
 }, {
-  id: 'btn',
-  ruleset: 'CSSContent',
+  id: "btn",
+  ruleset: "CSSContent",
   markup: `
     <style>
       button::before {
         content: "do not ";
       }
     </style>
     <button id="btn">press me</button>`,
-  expected: ['do not press me', 'press me']
+  expected: ["do not press me", "press me"]
 }, {
   // TODO: uncomment when Bug-1256382 is resoved.
   // id: 'li',
   // ruleset: 'CSSContent',
   // markup: `
   //   <style>
   //     ul {
   //       list-style-type: decimal;
   //     }
   //   </style>
   //   <ul id="ul">