Merging old head via |hg debugsetparents 07f5580d8a54 0612e4747b5b|. CLOSED TREE DONTBUILD NO BUG
authorMozilla Release Engineering <release+merge@mozilla.com>
Mon, 17 Mar 2014 14:39:41 -0700
changeset 183425 7513169e17177120bb2246613a5f83e968abd604
parent 183424 07f5580d8a54e8311fa7641c907065a88de19e08 (diff)
parent 175502 0612e4747b5bb95c4ddd5d89dd8824404fceaf8d (current diff)
child 183426 806c0a61cfc0280e452b5e4e0c8713ea5ea4647f
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone29.0a2
Merging old head via |hg debugsetparents 07f5580d8a54 0612e4747b5b|. CLOSED TREE DONTBUILD NO BUG
new file mode 100644
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,1 @@
+BasedOnStyle: Mozilla
new file mode 100644
--- /dev/null
+++ b/.clang-format-ignore
@@ -0,0 +1,3 @@
+\mfbt/
+\js/
+\media/
--- a/.hgtags
+++ b/.hgtags
@@ -92,10 +92,21 @@ cf8750abee06cde395c659f8ecd8ae019d7512e3
 5bb309998e7050c9ee80b0147de1e473f008e221 FIREFOX_AURORA_20_BASE
 cc37417e2c284aed960f98ffa479de4ccdd5c7c3 FIREFOX_AURORA_21_BASE
 1c070ab0f9db59f13423b9c1db60419f7a9098f9 FIREFOX_AURORA_22_BASE
 d7ce9089999719d5186595d160f25123a4e63e39 FIREFOX_AURORA_23_BASE
 8d3810543edccf4fbe458178b88dd4a6e420b010 FIREFOX_AURORA_24_BASE
 ad0ae007aa9e03cd74e9005cd6652e544139b3b5 FIREFOX_AURORA_25_BASE
 2520866d58740851d862c7c59246a4e3f8b4a176 FIREFOX_AURORA_26_BASE
 05025f4889a0bf4dc99ce0c244c750adc002f015 FIREFOX_AURORA_27_BASE
-c6c843644fbf436929dae282ee7d44342c359a61 RELEASE_BASE_20140310
-30a46e893204b5c2c2de29cd62950b7192f077cd FIREFOX_BETA_28_END
+74cdc97dbc93a008ac4a498356295fe6c6c25d22 FIREFOX_AURORA_27_END
+ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_28_BASE
+78087f3c5da06283a27f824665396ad29e8ca6c9 FIREFOX_AURORA_26_END
+ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_29_BASE
+ba2cc1eda988a1614d8986ae145d28e1268409b9 FIREFOX_AURORA_28_BASE
+0000000000000000000000000000000000000000 FIREFOX_AURORA_28_BASE
+fc5ccac2b98ffb4cd4fe640b54ac1e85ac83c85e FIREFOX_AURORA_28_END
+fc5ccac2b98ffb4cd4fe640b54ac1e85ac83c85e FIREFOX_AURORA_28_END
+22866da7b90567af2332b07cf3ccc37d7eeb6d54 FIREFOX_AURORA_28_END
+22866da7b90567af2332b07cf3ccc37d7eeb6d54 FIREFOX_AURORA_28_END
+0000000000000000000000000000000000000000 FIREFOX_AURORA_28_END
+0000000000000000000000000000000000000000 FIREFOX_AURORA_28_END
+7edc4f8cb05584779596264ff205bb1beec41893 FIREFOX_AURORA_28_END
--- a/.lldbinit
+++ b/.lldbinit
@@ -1,7 +1,31 @@
 # .lldbinit file for debugging Mozilla
 
+# -----------------------------------------------------------------------------
+# For documentation on all of the commands and type summaries defined here
+# and in the accompanying Python scripts, see python/lldbutils/README.txt.
+# -----------------------------------------------------------------------------
+
+# Import the module that defines complex Gecko debugging commands.  This assumes
+# you are either running lldb from the top level source directory, the objdir,
+# or the dist/bin directory.  (.lldbinit files in the objdir and dist/bin set
+# topsrcdir appropriately.)
+script topsrcdir = topsrcdir if locals().has_key("topsrcdir") else "."; sys.path.append(os.path.join(topsrcdir, "python/lldbutils")); import lldbutils; lldbutils.init()
+
 # Mozilla's use of UNIFIED_SOURCES to include multiple source files into a
 # single compiled file breaks lldb breakpoint setting. This works around that.
 # See http://lldb.llvm.org/troubleshooting.html for more info.
 settings set target.inline-breakpoint-strategy always
 
+# Show the dynamic type of an object when using "expr".  This, for example,
+# will show a variable declared as "nsIFrame *" that points to an nsBlockFrame
+# object as being of type "nsBlockFrame *" rather than "nsIFrame *".
+settings set target.prefer-dynamic-value run-target
+
+# Show the string value in atoms.
+type summary add nsIAtom --summary-string "${var.mString}"
+
+# Show the value of text nodes.
+type summary add nsTextNode --summary-string "${var.mText}"
+
+# Dump the current JS stack.
+command alias js expr DumpJSStack()
--- a/CLOBBER
+++ b/CLOBBER
@@ -13,16 +13,13 @@
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
-<<<<<<< local
-Bug 908695 required a clobber on Windows because bug 928195
-=======
-Bug 934646 needs a clobber -- the icon resources previously copied
-into $OBJDIR/mobile/android/base/res will conflict with those in
-$BRANDING_DIRECTORY/res.
+# 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.
 
->>>>>>> other
+Bug 924839 - Touching ICU's configure scripts in this bug doesn't work without a clobber.  This is filed as bug 966038.
--- a/Makefile.in
+++ b/Makefile.in
@@ -12,56 +12,71 @@ ifneq ($(make_min_ver),$(firstword $(sor
 $(error GNU Make $(make_min_ver) or higher is required)
 endif
 endif
 
 export TOPLEVEL_BUILD := 1
 
 default::
 
+ifdef MOZ_BUILD_APP
 include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
+endif
 
 include $(topsrcdir)/config/config.mk
 
 ifndef LIBXUL_SDK
 ifdef COMPILE_ENVIRONMENT
+ifndef BUILDING_JS
 BUILD_JS = 1
 endif
 endif
+endif
 
 GARBAGE_DIRS += dist _javagen _profile staticlib
 DIST_GARBAGE = config.cache config.log config.status* config-defs.h \
    config/autoconf.mk \
    mozilla-config.h \
    netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
    .mozconfig.mk
 
+ifdef BUILDING_JS
+configure_dir = $(topsrcdir)/js/src
+else
+configure_dir = $(topsrcdir)
+endif
+
 ifndef MOZ_PROFILE_USE
 # We need to explicitly put backend.RecursiveMakeBackend here
 # otherwise the rule in rules.mk doesn't run early enough.
-libs binaries export tools:: CLOBBER $(topsrcdir)/configure config.status backend.RecursiveMakeBackend
+libs binaries export tools:: CLOBBER $(configure_dir)/configure config.status backend.RecursiveMakeBackend
 ifdef BUILD_JS
 libs binaries export tools:: js-config-status
 endif
 endif
 
+ifdef BUILDING_JS
+.PHONY: CLOBBER
+CLOBBER:
+else
 CLOBBER: $(topsrcdir)/CLOBBER
 	@echo 'STOP!  The CLOBBER file has changed.'
 	@echo 'Please run the build through a sanctioned build wrapper, such as'
 	@echo '"mach build" or client.mk.'
 	@exit 1
+endif
 
-$(topsrcdir)/configure: $(topsrcdir)/configure.in
+$(configure_dir)/configure: $(configure_dir)/configure.in
 	@echo 'STOP!  configure.in has changed, and your configure is out of date.'
 	@echo 'Please rerun autoconf and re-configure your build directory.'
 	@echo 'To ignore this message, touch "configure" in the source directory,'
 	@echo 'but your build might not succeed.'
 	@exit 1
 
-config.status: $(topsrcdir)/configure
+config.status: $(configure_dir)/configure
 	@echo 'STOP!  configure has changed and needs to be run in this build directory.'
 	@echo 'Please rerun configure.'
 	@echo 'To ignore this message, touch "config.status" in the build directory,'
 	@echo 'but your build might not succeed.'
 	@exit 1
 
 # Regenerate the build backend if it is out of date. We only have this rule in
 # this main make file because having it in rules.mk and applied to partial tree
@@ -85,28 +100,40 @@ ifdef BUILD_JS
 .PHONY: js-config-status
 js-config-status:
 	$(call SUBMAKE,backend.RecursiveMakeBackend,js/src,1)
 endif
 
 install_manifests := bin idl include public private sdk
 install_manifest_depends = \
   CLOBBER \
-  $(topsrcdir)/configure \
+  $(configure_dir)/configure \
   config.status \
   backend.RecursiveMakeBackend \
   $(NULL)
 
 ifdef BUILD_JS
 install_manifest_depends += js-config-status
 endif
 
 .PHONY: install-manifests
 install-manifests: $(addprefix install-dist-,$(install_manifests))
 
+# process_install_manifest needs to be invoked with --no-remove when building
+# js as standalone because automated builds are building nspr separately and
+# that would remove the resulting files. It is also necessary when building
+# js as part of gecko because that would remove the files exported from gecko.
+# Eventually, a standalone js build would just be able to build nspr itself,
+# removing the need for the former. But that won't likely happen before
+# finishing to merge gecko and js build systems, removing the need for the
+# latter.
+ifdef BUILDING_JS
+NO_REMOVE=1
+endif
+
 .PHONY: $(addprefix install-dist-,$(install_manifests))
 $(addprefix install-dist-,$(install_manifests)): install-dist-%: $(install_manifest_depends)
 	$(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )$(DIST)/$* _build_manifests/install/dist_$* $(if $(BUILD_JS),js/src/_build_manifests/install/dist_$*))
 
 .PHONY: install-tests
 install-manifests: install-tests
 install-tests: $(install_manifest_depends)
 	$(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )_tests _build_manifests/install/tests $(if $(BUILD_JS),js/src/_build_manifests/install/tests))
@@ -134,20 +161,22 @@ export:: install-manifests
 binaries::
 	@$(MAKE) install-manifests NO_REMOVE=1
 endif
 
 # For historical reasons that are unknown, $(DIST)/sdk is always blown away
 # with no regard for PGO passes. This decision could probably be revisited.
 export:: install-dist-sdk
 
+ifndef BUILDING_JS
 ifdef ENABLE_TESTS
 # Additional makefile targets to call automated test suites
 include $(topsrcdir)/testing/testsuite-targets.mk
 endif
+endif
 
 default all::
 	$(call BUILDSTATUS,TIERS export $(if $(COMPILE_ENVIRONMENT),$(if $(MOZ_PSEUDO_DERECURSE),compile ))libs tools)
 
 include $(topsrcdir)/config/rules.mk
 
 distclean::
 	$(RM) $(DIST_GARBAGE)
@@ -176,16 +205,17 @@ endif
 ifeq (,$(filter-out Linux SunOS,$(OS_ARCH)))
 MAKE_SYM_STORE_ARGS := -c --vcs-info
 DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms
 MAKE_SYM_STORE_PATH := $(DIST)/bin
 endif
 
 SYM_STORE_SOURCE_DIRS := $(topsrcdir)
 
+ifndef BUILDING_JS
 include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
 
 ifdef MOZ_SYMBOLS_EXTRA_BUILDID
 EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
 endif
 
 SYMBOL_INDEX_NAME = \
   $(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)-$(CPU_ARCH)$(EXTRA_BUILDID)-symbols.txt
@@ -220,16 +250,17 @@ ifdef MOZ_CRASHREPORTER
 	$(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(SYMBOL_INDEX_NAME) '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
 endif
 
 # MOZ_SOURCE_STAMP is defined in package-name.mk with a deferred assignment.
 # exporting it makes make run its $(shell) command for each invoked submake,
 # so transform it to an immediate assignment.
 MOZ_SOURCE_STAMP := $(MOZ_SOURCE_STAMP)
 export MOZ_SOURCE_STAMP
+endif
 
 #XXX: this is a hack, since we don't want to clobber for MSVC
 # PGO support, but we can't do this test in client.mk
 ifneq ($(OS_ARCH)_$(GNU_CC), WINNT_)
 # No point in clobbering if PGO has been explicitly disabled.
 ifndef NO_PROFILE_GUIDED_OPTIMIZE
 maybe_clobber_profiledbuild: clean
 else
@@ -245,21 +276,37 @@ endif
 
 # Look for R_386_PC32 relocations in shared libs, these
 # break x86_64 builds and SELinux users.
 ifeq ($(OS_TARGET)_$(TARGET_XPCOM_ABI),Linux_x86-gcc3)
 check::
 	@relcount=`find $(DIST)/bin -name '*.so' | xargs objdump -R | grep R_386_PC32 | wc -l` && if test $$relcount -gt 0; then echo 'FAILED: R_386_PC32 relocations detected in a shared library.  Did you use a system header without adding it to config/system-headers?'; exit 1; else echo 'PASSED'; fi
 endif
 
+ifdef BUILDING_JS
+# Delegate js-specific rules to js
+check-%:
+	$(MAKE) -C js/src $@
+
+source-package install:
+	$(MAKE) -C js/src $@
+
+# Every export rule depends on config/export, but the rule for config/export
+# doesn't exist when building js non-standalone.
+.PHONY: config/export
+config/export:
+
+else
+
 ifdef BUILD_JS
 js/src/Makefile: subsrcdir := js/src
 
 ifdef MOZ_PSEUDO_DERECURSE
 # Interdependencies for parallel export.
 js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export
 accessible/src/xpcom/export: xpcom/xpidl/export
 js/src/export: mfbt/export
 ifdef ENABLE_CLANG_PLUGIN
 js/src/export config/export: build/clang-plugin/export
 endif
 endif
 endif
+endif
--- a/README.txt
+++ b/README.txt
@@ -20,8 +20,9 @@ are accessible on Google Groups, or news
 
 You can download nightly development builds from the Mozilla FTP server.
 Keep in mind that nightly builds, which are used by Mozilla developers for
 testing, may be buggy. Firefox nightlies, for example, can be found at:
 
     ftp://ftp.mozilla.org/pub/firefox/nightly/latest-trunk/
             - or -
     http://nightly.mozilla.org/
+
--- a/accessible/src/atk/AccessibleWrap.cpp
+++ b/accessible/src/atk/AccessibleWrap.cpp
@@ -687,17 +687,17 @@ getRoleCB(AtkObject *aAtkObj)
       MOZ_CRASH("Unknown role.");
   };
 
 #undef ROLE
 
   return aAtkObj->role;
 }
 
-AtkAttributeSet*
+static AtkAttributeSet*
 ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes)
 {
     if (!aAttributes)
         return nullptr;
 
     AtkAttributeSet *objAttributeSet = nullptr;
     nsCOMPtr<nsISimpleEnumerator> propEnum;
     nsresult rv = aAttributes->Enumerate(getter_AddRefs(propEnum));
@@ -843,16 +843,20 @@ getIndexInParentCB(AtkObject *aAtkObj)
         return -1; // No parent
 
     return parent->GetIndexOfEmbeddedChild(accWrap);
 }
 
 static void
 TranslateStates(uint64_t aState, AtkStateSet* aStateSet)
 {
+  // atk doesn't have a read only state so read only things shouldn't be
+  // editable.
+  if (aState & states::READONLY)
+    aState &= ~states::EDITABLE;
 
   // Convert every state to an entry in AtkStateMap
   uint32_t stateIndex = 0;
   uint64_t bitMask = 1;
   while (gAtkStateMap[stateIndex].stateMapEntryType != kNoSuchState) {
     if (gAtkStateMap[stateIndex].atkState) { // There's potentially an ATK state for this
       bool isStateOn = (aState & bitMask) != 0;
       if (gAtkStateMap[stateIndex].stateMapEntryType == kMapOpposite) {
--- a/accessible/src/atk/nsMaiInterfaceText.cpp
+++ b/accessible/src/atk/nsMaiInterfaceText.cpp
@@ -7,22 +7,97 @@
 #include "InterfaceInitFuncs.h"
 
 #include "Accessible-inl.h"
 #include "HyperTextAccessible-inl.h"
 #include "nsMai.h"
 
 #include "nsIAccessibleTypes.h"
 #include "nsIPersistentProperties2.h"
+#include "nsISimpleEnumerator.h"
 
 #include "mozilla/Likely.h"
 
+using namespace mozilla;
 using namespace mozilla::a11y;
 
-AtkAttributeSet* ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes);
+static const char* sAtkTextAttrNames[ATK_TEXT_ATTR_LAST_DEFINED];
+
+static AtkAttributeSet*
+ConvertToAtkTextAttributeSet(nsIPersistentProperties* aAttributes)
+{
+  if (!aAttributes)
+    return nullptr;
+
+  AtkAttributeSet* objAttributeSet = nullptr;
+  nsCOMPtr<nsISimpleEnumerator> propEnum;
+  nsresult rv = aAttributes->Enumerate(getter_AddRefs(propEnum));
+  NS_ENSURE_SUCCESS(rv, nullptr);
+
+  bool hasMore = false;
+  while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) {
+    nsCOMPtr<nsISupports> sup;
+    rv = propEnum->GetNext(getter_AddRefs(sup));
+    NS_ENSURE_SUCCESS(rv, objAttributeSet);
+
+    nsCOMPtr<nsIPropertyElement> propElem(do_QueryInterface(sup));
+    NS_ENSURE_TRUE(propElem, objAttributeSet);
+
+    nsAutoCString name;
+    rv = propElem->GetKey(name);
+    NS_ENSURE_SUCCESS(rv, objAttributeSet);
+
+    nsAutoString value;
+    rv = propElem->GetValue(value);
+    NS_ENSURE_SUCCESS(rv, objAttributeSet);
+
+    AtkAttribute* objAttr = (AtkAttribute*)g_malloc(sizeof(AtkAttribute));
+    objAttr->name = g_strdup(name.get());
+    objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(value).get());
+    objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
+
+    // Handle attributes where atk has its own name.
+    const char* atkName = nullptr;
+    nsAutoString atkValue;
+    if (name.EqualsLiteral("color")) {
+      // The format of the atk attribute is r,g,b and the gecko one is
+      // rgb(r,g,b).
+      atkValue = Substring(value, 5, value.Length() - 1);
+      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR];
+    } else if (name.EqualsLiteral("background-color")) {
+      // The format of the atk attribute is r,g,b and the gecko one is
+      // rgb(r,g,b).
+      atkValue = Substring(value, 5, value.Length() - 1);
+      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR];
+    } else if (name.EqualsLiteral("font-family")) {
+      atkValue = value;
+      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME];
+    } else if (name.Equals("font-size")) {
+      // ATK wants the number of pixels without px at the end.
+      atkValue = StringHead(value, value.Length() - 2);
+      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE];
+    } else if (name.EqualsLiteral("font-weight")) {
+      atkValue = value;
+      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_WEIGHT];
+    } else if (name.EqualsLiteral("invalid")) {
+      atkValue = value;
+      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_INVALID];
+    }
+
+    if (atkName) {
+      objAttr = static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
+      objAttr->name = g_strdup(atkName);
+      objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(atkValue).get());
+      objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
+    }
+  }
+
+  // libatk-adaptor will free it
+  return objAttributeSet;
+}
 
 static void
 ConvertTexttoAsterisks(AccessibleWrap* accWrap, nsAString& aString)
 {
   // 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("*"));
@@ -107,28 +182,18 @@ getCharacterAtOffsetCB(AtkText* aText, g
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
   if (!accWrap)
     return 0;
 
   HyperTextAccessible* text = accWrap->AsHyperText();
   if (!text || !text->IsTextRole())
     return 0;
 
-  // PRUnichar is unsigned short in Mozilla
-  // gnuichar is guint32 in glib
-  PRUnichar uniChar = 0;
-  nsresult rv = text->GetCharacterAtOffset(aOffset, &uniChar);
-  if (NS_FAILED(rv))
-    return 0;
-
-  // Convert char to "*" when it's "password text".
-  if (accWrap->NativeRole() == roles::PASSWORD_TEXT)
-    uniChar = '*';
-
-  return static_cast<gunichar>(uniChar);
+  // char16_t is unsigned short in Mozilla, gnuichar is guint32 in glib.
+  return static_cast<gunichar>(text->CharAt(aOffset));
 }
 
 static gchar*
 getTextBeforeOffsetCB(AtkText *aText, gint aOffset,
                       AtkTextBoundary aBoundaryType,
                       gint *aStartOffset, gint *aEndOffset)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
@@ -183,32 +248,32 @@ getRunAttributesCB(AtkText *aText, gint 
 
   int32_t startOffset = 0, endOffset = 0;
   nsCOMPtr<nsIPersistentProperties> attributes =
     text->TextAttributes(false, aOffset, &startOffset, &endOffset);
 
   *aStartOffset = startOffset;
   *aEndOffset = endOffset;
 
-  return ConvertToAtkAttributeSet(attributes);
+  return ConvertToAtkTextAttributeSet(attributes);
 }
 
 static AtkAttributeSet*
 getDefaultAttributesCB(AtkText *aText)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
   if (!accWrap)
     return nullptr;
 
   HyperTextAccessible* text = accWrap->AsHyperText();
   if (!text || !text->IsTextRole())
     return nullptr;
 
   nsCOMPtr<nsIPersistentProperties> attributes = text->DefaultTextAttributes();
-  return ConvertToAtkAttributeSet(attributes);
+  return ConvertToAtkTextAttributeSet(attributes);
 }
 
 static void
 getCharacterExtentsCB(AtkText *aText, gint aOffset,
                       gint *aX, gint *aY,
                       gint *aWidth, gint *aHeight,
                       AtkCoordType aCoords)
 {
@@ -410,9 +475,14 @@ textInterfaceInitCB(AtkTextIface* aIface
   aIface->get_n_selections = getTextSelectionCountCB;
   aIface->get_selection = getTextSelectionCB;
 
     // set methods
   aIface->add_selection = addTextSelectionCB;
   aIface->remove_selection = removeTextSelectionCB;
   aIface->set_selection = setTextSelectionCB;
   aIface->set_caret_offset = setCaretOffsetCB;
+
+  // Cache the string values of the atk text attribute names.
+  for (uint32_t i = 0; i < ArrayLength(sAtkTextAttrNames); i++)
+    sAtkTextAttrNames[i] =
+      atk_text_attribute_get_name(static_cast<AtkTextAttribute>(i));
 }
--- a/accessible/src/base/AccGroupInfo.cpp
+++ b/accessible/src/base/AccGroupInfo.cpp
@@ -103,17 +103,17 @@ AccGroupInfo::AccGroupInfo(Accessible* a
 
     mSetSize++;
   }
 
   if (mParent)
     return;
 
   roles::Role parentRole = parent->Role();
-  if (IsConceptualParent(aRole, parentRole))
+  if (ShouldReportRelations(aRole, parentRole))
     mParent = parent;
 
   // ARIA tree and list can be arranged by using ARIA groups to organize levels.
   if (parentRole != roles::GROUPING)
     return;
 
   // Way #1 for ARIA tree (not ARIA treegrid): previous sibling of a group is a
   // parent. In other words the parent of the tree item will be a group and
@@ -166,19 +166,19 @@ AccGroupInfo::FirstItemOf(Accessible* aC
     item = item->FirstChild();
     if (item) {
       AccGroupInfo* itemGroupInfo = item->GetGroupInfo();
       if (itemGroupInfo && itemGroupInfo->ConceptualParent() == aContainer)
         return item;
     }
   }
 
-  // Otherwise it can be a direct child.
+  // Otherwise, it can be a direct child if the container is a list or tree.
   item = aContainer->FirstChild();
-  if (IsConceptualParent(BaseRole(item->Role()), containerRole))
+  if (ShouldReportRelations(item->Role(), containerRole))
     return item;
 
   return nullptr;
 }
 
 Accessible*
 AccGroupInfo::NextItemTo(Accessible* aItem)
 {
@@ -196,34 +196,26 @@ AccGroupInfo::NextItemTo(Accessible* aIt
     Accessible* nextItem = parent->GetChildAt(idx);
     AccGroupInfo* nextGroupInfo = nextItem->GetGroupInfo();
     if (nextGroupInfo &&
         nextGroupInfo->ConceptualParent() == groupInfo->ConceptualParent()) {
       return nextItem;
     }
   }
 
-  NS_NOTREACHED("Item in the midle of the group but there's no next item!");
+  NS_NOTREACHED("Item in the middle of the group but there's no next item!");
   return nullptr;
 }
 
 bool
-AccGroupInfo::IsConceptualParent(role aRole, role aParentRole)
+AccGroupInfo::ShouldReportRelations(role aRole, role aParentRole)
 {
+  // We only want to report hierarchy-based node relations for items in tree or
+  // list form.  ARIA level/owns relations are always reported.
   if (aParentRole == roles::OUTLINE && aRole == roles::OUTLINEITEM)
     return true;
-  if ((aParentRole == roles::TABLE || aParentRole == roles::TREE_TABLE) &&
-      aRole == roles::ROW)
+  if (aParentRole == roles::TREE_TABLE && aRole == roles::ROW)
     return true;
   if (aParentRole == roles::LIST && aRole == roles::LISTITEM)
     return true;
-  if (aParentRole == roles::COMBOBOX_LIST && aRole == roles::COMBOBOX_OPTION)
-    return true;
-  if (aParentRole == roles::LISTBOX && aRole == roles::OPTION)
-    return true;
-  if (aParentRole == roles::PAGETABLIST && aRole == roles::PAGETAB)
-    return true;
-  if ((aParentRole == roles::POPUP_MENU || aParentRole == roles::MENUPOPUP) &&
-      aRole == roles::MENUITEM)
-    return true;
 
   return false;
 }
--- a/accessible/src/base/AccGroupInfo.h
+++ b/accessible/src/base/AccGroupInfo.h
@@ -86,20 +86,20 @@ private:
 
     if (aRole == mozilla::a11y::roles::CHECK_RICH_OPTION)
       return mozilla::a11y::roles::RICH_OPTION;
 
     return aRole;
   }
 
   /**
-   * Return true if the given parent role is conceptual parent of the given
-   * role.
+   * Return true if the given parent and child roles should have their node
+   * relations reported.
    */
-  static bool IsConceptualParent(a11y::role aRole, a11y::role aParentRole);
+  static bool ShouldReportRelations(a11y::role aRole, a11y::role aParentRole);
 
   uint32_t mPosInSet;
   uint32_t mSetSize;
   Accessible* mParent;
 };
 
 } // namespace mozilla
 } // namespace a11y
--- a/accessible/src/base/DocManager.cpp
+++ b/accessible/src/base/DocManager.cpp
@@ -225,17 +225,17 @@ DocManager::OnLocationChange(nsIWebProgr
 {
   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DocManager::OnStatusChange(nsIWebProgress* aWebProgress,
                            nsIRequest* aRequest, nsresult aStatus,
-                           const PRUnichar* aMessage)
+                           const char16_t* aMessage)
 {
   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DocManager::OnSecurityChange(nsIWebProgress* aWebProgress,
                              nsIRequest* aRequest,
--- a/accessible/src/base/EventQueue.cpp
+++ b/accessible/src/base/EventQueue.cpp
@@ -221,30 +221,31 @@ EventQueue::CoalesceReorderEvents(AccEve
         thisEvent->mEventRule = AccEvent::eDoNotEmit;
       }
 
       return;
     }
 
     // If tailEvent contains thisEvent
     // then
-    //   if show of tailEvent contains a grand parent of thisEvent
-    //   then assert
-    //   else if hide of tailEvent contains a grand parent of thisEvent
+    //   if show or hide of tailEvent contains a grand parent of thisEvent
     //   then ignore thisEvent and its show and hide events
     //   otherwise ignore thisEvent but not its show and hide events
     Accessible* thisParent = thisEvent->mAccessible;
     while (thisParent && thisParent != mDocument) {
       if (thisParent->Parent() == aTailEvent->mAccessible) {
         AccReorderEvent* tailReorder = downcast_accEvent(aTailEvent);
         uint32_t eventType = tailReorder->IsShowHideEventTarget(thisParent);
 
-        if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
-           NS_ERROR("Accessible tree was created after it was modified! Huh?");
-        } else if (eventType == nsIAccessibleEvent::EVENT_HIDE) {
+        // Sometimes InvalidateChildren() and
+        // DocAccessible::CacheChildrenInSubtree() can conspire to reparent an
+        // accessible in this case no need for mutation events.  Se bug 883708
+        // for details.
+        if (eventType == nsIAccessibleEvent::EVENT_SHOW ||
+            eventType == nsIAccessibleEvent::EVENT_HIDE) {
           AccReorderEvent* thisReorder = downcast_accEvent(thisEvent);
           thisReorder->DoNotEmitAll();
         } else {
           thisEvent->mEventRule = AccEvent::eDoNotEmit;
         }
 
         return;
       }
--- a/accessible/src/base/SelectionManager.cpp
+++ b/accessible/src/base/SelectionManager.cpp
@@ -115,17 +115,17 @@ SelectionManager::ProcessTextSelChangeEv
 
   // Fire selection change event if it's not pure caret-move selection change.
   if (sel->GetRangeCount() != 1 || !sel->IsCollapsed())
     nsEventShell::FireEvent(aEvent);
 
   // Fire caret move event if there's a caret in the selection.
   nsINode* caretCntrNode =
     nsCoreUtils::GetDOMNodeFromDOMPoint(sel->GetFocusNode(),
-                                        sel->GetFocusOffset());
+                                        sel->FocusOffset());
   if (!caretCntrNode)
     return;
 
   HyperTextAccessible* caretCntr = nsAccUtils::GetTextContainer(caretCntrNode);
   NS_ASSERTION(caretCntr,
                "No text container for focus while there's one for common ancestor?!");
   if (!caretCntr)
     return;
--- a/accessible/src/base/TextAttrs.cpp
+++ b/accessible/src/base/TextAttrs.cpp
@@ -616,17 +616,17 @@ TextAttrsMgr::FontWeightTextAttr::
   // When there doesn't exist a bold font in the family and so the rendering of
   // a non-bold font face is changed so that the user sees what looks like a
   // bold font, i.e. synthetic bolding is used. IsSyntheticBold method is only
   // needed on Mac, but it is "safe" to use on all platforms.  (For non-Mac
   // platforms it always return false.)
   if (font->IsSyntheticBold())
     return 700;
 
-#ifdef MOZ_PANGO
+#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
   // On Linux, font->GetStyle()->weight will give the absolute weight requested
   // of the font face. The Linux code uses the gfxFontEntry constructor which
   // doesn't initialize the weight field.
   return font->GetStyle()->weight;
 #else
   // On Windows, font->GetStyle()->weight will give the same weight as
   // fontEntry->Weight(), the weight of the first font in the font group, which
   // may not be the weight of the font face used to render the characters.
--- a/accessible/src/base/moz.build
+++ b/accessible/src/base/moz.build
@@ -54,27 +54,27 @@ UNIFIED_SOURCES += [
 ]
 
 if a11y_log:
     UNIFIED_SOURCES += [
         'Logging.cpp',
     ]
 
 LOCAL_INCLUDES += [
-    '../../../content/xbl/src',
-    '../../../ipc/chromium/src',
-    '../../../layout/generic',
-    '../../../layout/style',
-    '../../../layout/svg',
-    '../../../layout/xul',
-    '../../../layout/xul/tree/',
     '../generic',
     '../html',
     '../xpcom',
     '../xul',
+    '/dom/xbl',
+    '/ipc/chromium/src',
+    '/layout/generic',
+    '/layout/style',
+    '/layout/svg',
+    '/layout/xul',
+    '/layout/xul/tree/',
 ]
 
 if CONFIG['MOZ_ENABLE_GTK']:
     LOCAL_INCLUDES += [
         '../atk',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     LOCAL_INCLUDES += [
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -157,17 +157,17 @@ NS_IMPL_ISUPPORTS_INHERITED4(nsAccessibi
                              nsIObserver,
                              nsISelectionListener) // from SelectionManager
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIObserver
 
 NS_IMETHODIMP
 nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
-                         const PRUnichar *aData)
+                         const char16_t *aData)
 {
   if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
     Shutdown();
 
   return NS_OK;
 }
 
 // nsIAccessibilityService
@@ -1001,18 +1001,18 @@ nsAccessibilityService::GetOrCreateAcces
       if (deckFrame && deckFrame->GetSelectedBox() != frame) {
         if (aIsSubtreeHidden)
           *aIsSubtreeHidden = true;
 
         return nullptr;
       }
     }
 
-    // Elements may implement nsIAccessibleProvider via XBL. This allows them to
-    // say what kind of accessible to create.
+    // XBL bindings may use @role attribute to point the accessible type
+    // they belong to.
     newAcc = CreateAccessibleByType(content, document);
 
     // Any XUL box can be used as tabpanel, make sure we create a proper
     // accessible for it.
     if (!newAcc && aContext->IsXULTabpanels() &&
         content->GetParent() == aContext->GetContent()) {
       nsIAtom* frameType = frame->GetType();
       if (frameType == nsGkAtoms::boxFrame ||
@@ -1080,17 +1080,17 @@ nsAccessibilityService::Init()
   // Add observers.
   nsCOMPtr<nsIObserverService> observerService =
     mozilla::services::GetObserverService();
   if (!observerService)
     return false;
 
   observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
 
-  static const PRUnichar kInitIndicator[] = { '1', 0 };
+  static const char16_t kInitIndicator[] = { '1', 0 };
   observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kInitIndicator);
 
 #ifdef A11Y_LOG
   logging::CheckEnv();
 #endif
 
   gApplicationAccessible = new ApplicationAccessibleWrap();
   NS_ADDREF(gApplicationAccessible); // will release in Shutdown()
@@ -1118,17 +1118,17 @@ void
 nsAccessibilityService::Shutdown()
 {
   // Remove observers.
   nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
   if (observerService) {
     observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
 
-    static const PRUnichar kShutdownIndicator[] = { '0', 0 };
+    static const char16_t kShutdownIndicator[] = { '0', 0 };
     observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kShutdownIndicator);
   }
 
   // Stop accessible document loader.
   DocManager::Shutdown();
 
   SelectionManager::Shutdown();
 
@@ -1539,18 +1539,22 @@ nsAccessibilityService::CreateAccessible
       break;
     case eHTMLTableType:
       newAcc = new HTMLTableAccessibleWrap(aContent, document);
       break;
     case eHTMLTableCellType:
       // Accessible HTML table cell should be a child of accessible HTML table
       // or its row (CSS HTML tables are polite to the used markup at
       // certain degree).
+      // Otherwise create a generic text accessible to avoid text jamming
+      // when reading by AT.
       if (aContext->IsHTMLTableRow() || aContext->IsHTMLTable())
         newAcc = new HTMLTableCellAccessibleWrap(aContent, document);
+      else
+        newAcc = new HyperTextAccessibleWrap(aContent, document);
       break;
 
     case eHTMLTableRowType: {
       // Accessible HTML table row must be a child of tbody/tfoot/thead of
       // accessible HTML table or must be a child of accessible of HTML table.
       if (aContext->IsTable()) {
         nsIContent* parentContent = aContent->GetParent();
         nsIFrame* parentFrame = parentContent->GetPrimaryFrame();
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -173,18 +173,17 @@ private:
   bool Init();
 
   /**
    * Shutdowns accessibility service.
    */
   void Shutdown();
 
   /**
-   * Create accessible for the element implementing nsIAccessibleProvider
-   * interface.
+   * Create accessible for the element having XBL bindings.
    */
   already_AddRefed<Accessible>
     CreateAccessibleByType(nsIContent* aContent, DocAccessible* aDoc);
 
   /**
    * Create accessible for HTML node by tag name.
    */
   already_AddRefed<Accessible>
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -5,17 +5,16 @@
 
 #include "nsCoreUtils.h"
 
 #include "nsIAccessibleTypes.h"
 
 #include "nsIBaseWindow.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocument.h"
-#include "nsIDOMDocument.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsRange.h"
 #include "nsIBoxObject.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDocShell.h"
 #include "nsEventListenerManager.h"
 #include "nsIPresShell.h"
@@ -29,16 +28,17 @@
 #include "nsView.h"
 #include "nsGkAtoms.h"
 #include "nsDOMTouchEvent.h"
 
 #include "nsComponentManagerUtils.h"
 
 #include "nsITreeBoxObject.h"
 #include "nsITreeColumns.h"
+#include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsCoreUtils
 ////////////////////////////////////////////////////////////////////////////////
 
 bool
@@ -211,28 +211,26 @@ nsCoreUtils::GetDOMNodeFromDOMPoint(nsIN
   return aNode;
 }
 
 nsIContent*
 nsCoreUtils::GetRoleContent(nsINode *aNode)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
   if (!content) {
-    nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(aNode));
-    if (domDoc) {
+    nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
+    if (doc) {
       nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(aNode));
       if (htmlDoc) {
         nsCOMPtr<nsIDOMHTMLElement> bodyElement;
         htmlDoc->GetBody(getter_AddRefs(bodyElement));
         content = do_QueryInterface(bodyElement);
       }
       else {
-        nsCOMPtr<nsIDOMElement> docElement;
-        domDoc->GetDocumentElement(getter_AddRefs(docElement));
-        content = do_QueryInterface(docElement);
+        return doc->GetDocumentElement();
       }
     }
   }
 
   return content;
 }
 
 bool
@@ -411,19 +409,17 @@ nsCoreUtils::IsRootDocument(nsIDocument 
 }
 
 bool
 nsCoreUtils::IsContentDocument(nsIDocument *aDocument)
 {
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = aDocument->GetDocShell();
   NS_ASSERTION(docShellTreeItem, "No document shell tree item for document!");
 
-  int32_t contentType;
-  docShellTreeItem->GetItemType(&contentType);
-  return (contentType == nsIDocShellTreeItem::typeContent);
+  return (docShellTreeItem->ItemType() == nsIDocShellTreeItem::typeContent);
 }
 
 bool
 nsCoreUtils::IsTabDocument(nsIDocument* aDocumentNode)
 {
   nsCOMPtr<nsIDocShellTreeItem> treeItem(aDocumentNode->GetDocShell());
 
   nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -302,17 +302,17 @@ public:
    * only. In contrast to nsWhitespaceTokenizer class it takes into account
    * non-breaking space (0xa0).
    */
   static bool IsWhitespaceString(const nsSubstring& aString);
 
   /**
    * Returns true if the given character is whitespace symbol.
    */
-  static bool IsWhitespace(PRUnichar aChar)
+  static bool IsWhitespace(char16_t aChar)
   {
     return aChar == ' ' || aChar == '\n' ||
       aChar == '\r' || aChar == '\t' || aChar == 0xa0;
   }
 };
 
 
 /**
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -125,33 +125,33 @@ nsTextEquivUtils::AppendTextEquivFromTex
         // If this text is inside a block level frame (as opposed to span
         // level), we need to add spaces around that block's text, so we don't
         // get words jammed together in final name.
         const nsStyleDisplay* display = frame->StyleDisplay();
         if (display->IsBlockOutsideStyle() ||
             display->mDisplay == NS_STYLE_DISPLAY_TABLE_CELL) {
           isHTMLBlock = true;
           if (!aString->IsEmpty()) {
-            aString->Append(PRUnichar(' '));
+            aString->Append(char16_t(' '));
           }
         }
       }
     }
     
     if (aContent->TextLength() > 0) {
       nsIFrame *frame = aContent->GetPrimaryFrame();
       if (frame) {
         nsresult rv = frame->GetRenderedText(aString);
         NS_ENSURE_SUCCESS(rv, rv);
       } else {
         // If aContent is an object that is display: none, we have no a frame.
         aContent->AppendTextTo(*aString);
       }
       if (isHTMLBlock && !aString->IsEmpty()) {
-        aString->Append(PRUnichar(' '));
+        aString->Append(char16_t(' '));
       }
     }
     
     return NS_OK;
   }
   
   if (aContent->IsHTML() &&
       aContent->NodeInfo()->Equals(nsGkAtoms::br)) {
@@ -329,22 +329,22 @@ bool
 nsTextEquivUtils::AppendString(nsAString *aString,
                                const nsAString& aTextEquivalent)
 {
   if (aTextEquivalent.IsEmpty())
     return false;
 
   // Insert spaces to insure that words from controls aren't jammed together.
   if (!aString->IsEmpty() && !nsCoreUtils::IsWhitespace(aString->Last()))
-    aString->Append(PRUnichar(' '));
+    aString->Append(char16_t(' '));
 
   aString->Append(aTextEquivalent);
 
   if (!nsCoreUtils::IsWhitespace(aString->Last()))
-    aString->Append(PRUnichar(' '));
+    aString->Append(char16_t(' '));
 
   return true;
 }
 
 uint32_t 
 nsTextEquivUtils::GetRoleRule(role aRole)
 {
 #define ROLE(geckoRole, stringRole, atkRole, \
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -24,17 +24,16 @@
 #include "RootAccessible.h"
 #include "States.h"
 #include "StyleInfo.h"
 #include "TableAccessible.h"
 #include "TableCellAccessible.h"
 #include "TreeWalker.h"
 
 #include "nsIDOMElement.h"
-#include "nsIDOMDocument.h"
 #include "nsIDOMNodeFilter.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMTreeWalker.h"
 #include "nsIDOMXULButtonElement.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDOMXULLabelElement.h"
@@ -78,16 +77,17 @@
 #endif
 
 #include "mozilla/Assertions.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/unused.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/TreeWalker.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible: nsISupports and cycle collection
 
@@ -378,19 +378,18 @@ Accessible::AccessKey() const
   if (!document)
     return KeyBinding();
 
   nsCOMPtr<nsIDocShellTreeItem> treeItem(document->GetDocShell());
   if (!treeItem)
     return KeyBinding();
 
   nsresult rv = NS_ERROR_FAILURE;
-  int32_t itemType = 0, modifierMask = 0;
-  treeItem->GetItemType(&itemType);
-  switch (itemType) {
+  int32_t modifierMask = 0;
+  switch (treeItem->ItemType()) {
     case nsIDocShellTreeItem::typeChrome:
       rv = Preferences::GetInt("ui.key.chromeAccess", &modifierMask);
       break;
     case nsIDocShellTreeItem::typeContent:
       rv = Preferences::GetInt("ui.key.contentAccess", &modifierMask);
       break;
   }
 
@@ -577,17 +576,16 @@ Accessible::VisibilityState()
     return states::INVISIBLE;
 
   // Walk the parent frame chain to see if there's invisible parent or the frame
   // is in background tab.
   if (!frame->StyleVisibility()->IsVisible())
     return states::INVISIBLE;
 
   nsIFrame* curFrame = frame;
-  nsPoint framePos(0, 0);
   do {
     nsView* view = curFrame->GetView();
     if (view && view->GetVisibility() == nsViewVisibility_kHide)
       return states::INVISIBLE;
 
     if (nsLayoutUtils::IsPopup(curFrame))
       return 0;
 
@@ -601,21 +599,21 @@ Accessible::VisibilityState()
         return states::OFFSCREEN;
 
       NS_NOTREACHED("Children of not selected deck panel are not accessible.");
       return states::INVISIBLE;
     }
 
     // If contained by scrollable frame then check that at least 12 pixels
     // around the object is visible, otherwise the object is offscreen.
-    framePos += curFrame->GetPosition();
     nsIScrollableFrame* scrollableFrame = do_QueryFrame(parentFrame);
     if (scrollableFrame) {
       nsRect scrollPortRect = scrollableFrame->GetScrollPortRect();
-      nsRect frameRect(framePos, frame->GetSize());
+      nsRect frameRect = nsLayoutUtils::TransformFrameRectToAncestor(
+        frame, frame->GetRectRelativeToSelf(), parentFrame);
       if (!scrollPortRect.Contains(frameRect)) {
         const nscoord kMinPixels = nsPresContext::CSSPixelsToAppUnits(12);
         scrollPortRect.Deflate(kMinPixels, kMinPixels);
         if (!scrollPortRect.Intersects(frameRect))
           return states::OFFSCREEN;
       }
     }
 
@@ -2115,20 +2113,19 @@ Accessible::RelationByType(RelationType 
         // Walk up the parent chain without crossing the boundary at which item
         // types change, preventing us from walking up out of tab content.
         nsCOMPtr<nsIDocShellTreeItem> root;
         docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
         if (root) {
           // If the item type is typeContent, we assume we are in browser tab
           // content. Note, this includes content such as about:addons,
           // for consistency.
-          int32_t itemType = 0;
-          root->GetItemType(&itemType);
-          if (itemType == nsIDocShellTreeItem::typeContent)
+          if (root->ItemType() == nsIDocShellTreeItem::typeContent) {
             return Relation(nsAccUtils::GetDocAccessibleFor(root));
+          }
         }
       }
       return  Relation();
     }
 
     case RelationType::CONTAINING_APPLICATION:
       return Relation(ApplicationAcc());
 
@@ -2645,17 +2642,17 @@ Accessible::RemoveChild(Accessible* aChi
   aChild->UnbindFromParent();
   mChildren.RemoveElementAt(index);
   mEmbeddedObjCollector = nullptr;
 
   return true;
 }
 
 Accessible*
-Accessible::GetChildAt(uint32_t aIndex)
+Accessible::GetChildAt(uint32_t aIndex) const
 {
   Accessible* child = mChildren.SafeElementAt(aIndex, nullptr);
   if (!child)
     return nullptr;
 
 #ifdef DEBUG
   Accessible* realParent = child->mParent;
   NS_ASSERTION(!realParent || realParent == this,
@@ -2667,22 +2664,16 @@ Accessible::GetChildAt(uint32_t aIndex)
 
 uint32_t
 Accessible::ChildCount() const
 {
   return mChildren.Length();
 }
 
 int32_t
-Accessible::GetIndexOf(Accessible* aChild)
-{
-  return (aChild->mParent != this) ? -1 : aChild->IndexInParent();
-}
-
-int32_t
 Accessible::IndexInParent() const
 {
   return mIndexInParent;
 }
 
 uint32_t
 Accessible::EmbeddedChildCount()
 {
@@ -3071,35 +3062,36 @@ Accessible::GetSiblingAtOffset(int32_t a
 
 Accessible* 
 Accessible::GetFirstAvailableAccessible(nsINode *aStartNode) const
 {
   Accessible* accessible = mDoc->GetAccessible(aStartNode);
   if (accessible)
     return accessible;
 
-  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aStartNode->OwnerDoc());
-  NS_ENSURE_TRUE(domDoc, nullptr);
-
-  nsCOMPtr<nsIDOMNode> currentNode = do_QueryInterface(aStartNode);
-  nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(GetNode());
-  nsCOMPtr<nsIDOMTreeWalker> walker;
-  domDoc->CreateTreeWalker(rootNode,
-                           nsIDOMNodeFilter::SHOW_ELEMENT | nsIDOMNodeFilter::SHOW_TEXT,
-                           nullptr, 1, getter_AddRefs(walker));
+  nsCOMPtr<nsIDocument> doc = aStartNode->OwnerDoc();
+
+  nsCOMPtr<nsINode> currentNode = aStartNode;
+  ErrorResult rv;
+  nsRefPtr<dom::TreeWalker> walker =
+    doc->CreateTreeWalker(*GetNode(),
+                          nsIDOMNodeFilter::SHOW_ELEMENT | nsIDOMNodeFilter::SHOW_TEXT,
+                          nullptr, rv);
   NS_ENSURE_TRUE(walker, nullptr);
 
-  walker->SetCurrentNode(currentNode);
+  walker->SetCurrentNode(*currentNode, rv);
+  if (rv.Failed())
+    return nullptr;
+
   while (true) {
-    walker->NextNode(getter_AddRefs(currentNode));
-    if (!currentNode)
+    currentNode = walker->NextNode(rv);
+    if (!currentNode || rv.Failed())
       return nullptr;
 
-    nsCOMPtr<nsINode> node(do_QueryInterface(currentNode));
-    Accessible* accessible = mDoc->GetAccessible(node);
+    Accessible* accessible = mDoc->GetAccessible(currentNode);
     if (accessible)
       return accessible;
   }
 
   return nullptr;
 }
 
 double
@@ -3262,46 +3254,46 @@ KeyBinding::ToPlatformFormat(nsAString& 
     stringBundleService->CreateBundle(
       "chrome://global-platform/locale/platformKeys.properties",
       getter_AddRefs(keyStringBundle));
 
   if (!keyStringBundle)
     return;
 
   nsAutoString separator;
-  keyStringBundle->GetStringFromName(NS_LITERAL_STRING("MODIFIER_SEPARATOR").get(),
+  keyStringBundle->GetStringFromName(MOZ_UTF16("MODIFIER_SEPARATOR"),
                                      getter_Copies(separator));
 
   nsAutoString modifierName;
   if (mModifierMask & kControl) {
-    keyStringBundle->GetStringFromName(NS_LITERAL_STRING("VK_CONTROL").get(),
+    keyStringBundle->GetStringFromName(MOZ_UTF16("VK_CONTROL"),
                                        getter_Copies(modifierName));
 
     aValue.Append(modifierName);
     aValue.Append(separator);
   }
 
   if (mModifierMask & kAlt) {
-    keyStringBundle->GetStringFromName(NS_LITERAL_STRING("VK_ALT").get(),
+    keyStringBundle->GetStringFromName(MOZ_UTF16("VK_ALT"),
                                        getter_Copies(modifierName));
 
     aValue.Append(modifierName);
     aValue.Append(separator);
   }
 
   if (mModifierMask & kShift) {
-    keyStringBundle->GetStringFromName(NS_LITERAL_STRING("VK_SHIFT").get(),
+    keyStringBundle->GetStringFromName(MOZ_UTF16("VK_SHIFT"),
                                        getter_Copies(modifierName));
 
     aValue.Append(modifierName);
     aValue.Append(separator);
   }
 
   if (mModifierMask & kMeta) {
-    keyStringBundle->GetStringFromName(NS_LITERAL_STRING("VK_META").get(),
+    keyStringBundle->GetStringFromName(MOZ_UTF16("VK_META"),
                                        getter_Copies(modifierName));
 
     aValue.Append(modifierName);
     aValue.Append(separator);
   }
 
   aValue.Append(mKey);
 }
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -384,27 +384,28 @@ public:
   /**
    * Return parent accessible.
    */
   Accessible* Parent() const { return mParent; }
 
   /**
    * Return child accessible at the given index.
    */
-  virtual Accessible* GetChildAt(uint32_t aIndex);
+  virtual Accessible* GetChildAt(uint32_t aIndex) const;
 
   /**
    * Return child accessible count.
    */
   virtual uint32_t ChildCount() const;
 
   /**
    * Return index of the given child accessible.
    */
-  virtual int32_t GetIndexOf(Accessible* aChild);
+  int32_t GetIndexOf(const Accessible* aChild) const
+    { return (aChild->mParent != this) ? -1 : aChild->IndexInParent(); }
 
   /**
    * Return index in parent accessible.
    */
   virtual int32_t IndexInParent() const;
 
   /**
    * Return true if accessible has children;
--- a/accessible/src/generic/ApplicationAccessible.cpp
+++ b/accessible/src/generic/ApplicationAccessible.cpp
@@ -77,17 +77,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(NS_LITERAL_STRING("brandShortName").get(),
+  rv = bundle->GetStringFromName(MOZ_UTF16("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/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -17,17 +17,16 @@
 
 #include "nsIMutableArray.h"
 #include "nsICommandManager.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIDOMAttr.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMDocumentType.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMXULPopupElement.h"
 #include "nsIEditingSession.h"
 #include "nsEventStateManager.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
@@ -36,17 +35,19 @@
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsUnicharUtils.h"
 #include "nsIURI.h"
 #include "nsIWebNavigation.h"
 #include "nsFocusManager.h"
+#include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
+#include "mozilla/dom/DocumentType.h"
 #include "mozilla/dom/Element.h"
 
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::a11y;
@@ -60,17 +61,17 @@ static nsIAtom** kRelationAttrs[] =
   &nsGkAtoms::aria_describedby,
   &nsGkAtoms::aria_owns,
   &nsGkAtoms::aria_controls,
   &nsGkAtoms::aria_flowto,
   &nsGkAtoms::_for,
   &nsGkAtoms::control
 };
 
-static const uint32_t kRelationAttrsLen = NS_ARRAY_LENGTH(kRelationAttrs);
+static const uint32_t kRelationAttrsLen = ArrayLength(kRelationAttrs);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Constructor/desctructor
 
 DocAccessible::
   DocAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
                   nsIPresShell* aPresShell) :
   HyperTextAccessibleWrap(aRootContent, this),
@@ -184,18 +185,17 @@ DocAccessible::Name(nsString& aName)
 // Accessible public method
 role
 DocAccessible::NativeRole()
 {
   nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mDocumentNode);
   if (docShell) {
     nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
     docShell->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
-    int32_t itemType;
-    docShell->GetItemType(&itemType);
+    int32_t itemType = docShell->ItemType();
     if (sameTypeRoot == docShell) {
       // Root of content or chrome tree
       if (itemType == nsIDocShellTreeItem::typeChrome)
         return roles::CHROME_WINDOW;
 
       if (itemType == nsIDocShellTreeItem::typeContent) {
 #ifdef MOZ_XUL
         nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocumentNode));
@@ -348,48 +348,49 @@ DocAccessible::GetURL(nsAString& aURL)
   }
   CopyUTF8toUTF16(theURL, aURL);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DocAccessible::GetTitle(nsAString& aTitle)
 {
-  nsCOMPtr<nsIDOMDocument> domDocument = do_QueryInterface(mDocumentNode);
-  if (!domDocument) {
+  if (!mDocumentNode) {
     return NS_ERROR_FAILURE;
   }
-  return domDocument->GetTitle(aTitle);
+  nsString title;
+  mDocumentNode->GetTitle(title);
+  aTitle = title;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 DocAccessible::GetMimeType(nsAString& aMimeType)
 {
-  nsCOMPtr<nsIDOMDocument> domDocument = do_QueryInterface(mDocumentNode);
-  if (!domDocument) {
+  if (!mDocumentNode) {
     return NS_ERROR_FAILURE;
   }
-  return domDocument->GetContentType(aMimeType);
+  return mDocumentNode->GetContentType(aMimeType);
 }
 
 NS_IMETHODIMP
 DocAccessible::GetDocType(nsAString& aDocType)
 {
-  nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mDocumentNode));
-  nsCOMPtr<nsIDOMDocumentType> docType;
-
 #ifdef MOZ_XUL
   nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocumentNode));
   if (xulDoc) {
     aDocType.AssignLiteral("window"); // doctype not implemented for XUL at time of writing - causes assertion
     return NS_OK;
   } else
 #endif
-  if (domDoc && NS_SUCCEEDED(domDoc->GetDoctype(getter_AddRefs(docType))) && docType) {
-    return docType->GetPublicId(aDocType);
+  if (mDocumentNode) {
+    dom::DocumentType* docType = mDocumentNode->GetDoctype();
+    if (docType) {
+      return docType->GetPublicId(aDocType);
+    }
   }
 
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 DocAccessible::GetNameSpaceURIForID(int16_t aNameSpaceID, nsAString& aNameSpaceURI)
 {
@@ -687,19 +688,17 @@ DocAccessible::GetBoundsRect(nsRect& aBo
 // DocAccessible protected member
 nsresult
 DocAccessible::AddEventListeners()
 {
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem(mDocumentNode->GetDocShell());
 
   // We want to add a command observer only if the document is content and has
   // an editor.
-  int32_t itemType;
-  docShellTreeItem->GetItemType(&itemType);
-  if (itemType == nsIDocShellTreeItem::typeContent) {
+  if (docShellTreeItem->ItemType() == nsIDocShellTreeItem::typeContent) {
     nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(docShellTreeItem);
     if (commandManager)
       commandManager->AddCommandObserver(this, "obs_documentCreated");
   }
 
   SelectionMgr()->AddDocSelectionListener(mPresShell);
 
   // Add document observer.
@@ -719,19 +718,17 @@ DocAccessible::RemoveEventListeners()
 
   if (mDocumentNode) {
     mDocumentNode->RemoveObserver(this);
 
     nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem(mDocumentNode->GetDocShell());
     NS_ASSERTION(docShellTreeItem, "doc should support nsIDocShellTreeItem.");
 
     if (docShellTreeItem) {
-      int32_t itemType;
-      docShellTreeItem->GetItemType(&itemType);
-      if (itemType == nsIDocShellTreeItem::typeContent) {
+      if (docShellTreeItem->ItemType() == nsIDocShellTreeItem::typeContent) {
         nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(docShellTreeItem);
         if (commandManager) {
           commandManager->RemoveCommandObserver(this, "obs_documentCreated");
         }
       }
     }
   }
 
@@ -791,17 +788,17 @@ DocAccessible::ScrollPositionDidChange(n
   mScrollPositionChangedTicks = 1;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIObserver
 
 NS_IMETHODIMP
 DocAccessible::Observe(nsISupports* aSubject, const char* aTopic,
-                       const PRUnichar* aData)
+                       const char16_t* aData)
 {
   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.
     nsRefPtr<AccEvent> event =
       new AccStateChangeEvent(this, states::EDITABLE, true);
@@ -1446,20 +1443,32 @@ void
 DocAccessible::CacheChildren()
 {
   // Search for accessible children starting from the document element since
   // some web pages tend to insert elements under it rather than document body.
   dom::Element* rootElm = mDocumentNode->GetRootElement();
   if (!rootElm)
     return;
 
+  // Ignore last HTML:br, copied from HyperTextAccessible.
   TreeWalker walker(this, rootElm);
+  Accessible* lastChild = nullptr;
+  while (Accessible* child = walker.NextChild()) {
+    if (lastChild)
+      AppendChild(lastChild);
 
-  Accessible* child = nullptr;
-  while ((child = walker.NextChild()) && AppendChild(child));
+    lastChild = child;
+  }
+
+  if (lastChild) {
+    if (lastChild->IsHTMLBr())
+      Document()->UnbindFromDocument(lastChild);
+    else
+      AppendChild(lastChild);
+  }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Protected members
 
 void
 DocAccessible::NotifyOfLoading(bool aIsReloading)
 {
@@ -1786,18 +1795,19 @@ DocAccessible::UpdateTree(Accessible* aC
       // when we are called aChildNode may already have been removed
       // from the DOM so we can't expect it to have a parent or what was it's
       // parent to have it as a child.
       nsINode* containerNode = aContainer->GetNode();
       for (uint32_t idx = 0; idx < aContainer->ContentChildCount();) {
         Accessible* child = aContainer->ContentChildAt(idx);
 
         // If accessible doesn't have its own content then we assume parent
-        // will handle its update.
-        if (!child->HasOwnContent()) {
+        // will handle its update.  If child is DocAccessible then we don't
+        // handle updating it here either.
+        if (!child->HasOwnContent() || child->IsDoc()) {
           idx++;
           continue;
         }
 
         nsINode* childNode = child->GetContent();
         while (childNode != aChildNode && childNode != containerNode &&
                (childNode = childNode->GetParentNode()));
 
@@ -1903,18 +1913,20 @@ DocAccessible::UpdateTreeInternal(Access
     if (parent)
       parent->RemoveChild(aChild);
 
     UncacheChildrenInSubtree(aChild);
   }
 
   // XXX: do we really want to send focus to focused DOM node not taking into
   // account active item?
-  if (focusedAcc)
+  if (focusedAcc) {
     FocusMgr()->DispatchFocusEvent(this, focusedAcc);
+    SelectionMgr()->SetControlSelectionListener(focusedAcc->GetNode()->AsElement());
+  }
 
   return updateFlags;
 }
 
 void
 DocAccessible::CacheChildrenInSubtree(Accessible* aRoot,
                                       Accessible** aFocusedAcc)
 {
@@ -2010,19 +2022,17 @@ DocAccessible::IsLoadEventTarget() const
     // b) frame/iframe document and its parent document is not in loading state
     // Note: we can get notifications while document is loading (and thus
     // while there's no parent document yet).
     DocAccessible* parentDoc = ParentDocument();
     return parentDoc && parentDoc->HasLoadState(eCompletelyLoaded);
   }
 
   // It's content (not chrome) root document.
-  int32_t contentType;
-  treeItem->GetItemType(&contentType);
-  return (contentType == nsIDocShellTreeItem::typeContent);
+  return (treeItem->ItemType() == nsIDocShellTreeItem::typeContent);
 }
 
 PLDHashOperator
 DocAccessible::CycleCollectorTraverseDepIDsEntry(const nsAString& aKey,
                                                  AttrRelProviderArray* aProviders,
                                                  void* aUserArg)
 {
   nsCycleCollectionTraversalCallback* cb =
--- a/accessible/src/generic/DocAccessible.h
+++ b/accessible/src/generic/DocAccessible.h
@@ -16,17 +16,16 @@
 #include "nsDataHashtable.h"
 #include "nsIDocument.h"
 #include "nsIDocumentObserver.h"
 #include "nsIEditor.h"
 #include "nsIObserver.h"
 #include "nsIScrollPositionListener.h"
 #include "nsITimer.h"
 #include "nsIWeakReference.h"
-#include "nsIDocShellTreeNode.h"
 
 class nsAccessiblePivot;
 
 class nsIScrollableView;
 
 const uint32_t kDefaultCacheSize = 256;
 
 namespace mozilla {
--- a/accessible/src/generic/HyperTextAccessible-inl.h
+++ b/accessible/src/generic/HyperTextAccessible-inl.h
@@ -123,26 +123,30 @@ HyperTextAccessible::ConvertMagicOffset(
 inline int32_t
 HyperTextAccessible::AdjustCaretOffset(int32_t aOffset) const
 {
   // It is the same character offset when the caret is visually at the very
   // end of a line or the start of a new line (soft line break). Getting text
   // at the line should provide the line with the visual caret, otherwise
   // screen readers will announce the wrong line as the user presses up or
   // down arrow and land at the end of a line.
-  if (aOffset > 0) {
-    nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
-    if (frameSelection &&
-      frameSelection->GetHint() == nsFrameSelection::HINTLEFT) {
-      return aOffset - 1;
-    }
-  }
+  if (aOffset > 0 && IsCaretAtEndOfLine())
+    return aOffset - 1;
+
   return aOffset;
 }
 
+inline bool
+HyperTextAccessible::IsCaretAtEndOfLine() const
+{
+  nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
+  return frameSelection &&
+    frameSelection->GetHint() == nsFrameSelection::HINTLEFT;
+}
+
 inline Selection*
 HyperTextAccessible::DOMSelection() const
 {
   nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
   return frameSelection ?
     frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL) :
     nullptr;
 }
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -22,17 +22,19 @@
 #include "nsIEditingSession.h"
 #include "nsIFrame.h"
 #include "nsFrameSelection.h"
 #include "nsILineIterator.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIScrollableFrame.h"
 #include "nsIServiceManager.h"
+#include "nsITextControlElement.h"
 #include "nsTextFragment.h"
+#include "mozilla/dom/Element.h"
 #include "mozilla/Selection.h"
 #include "mozilla/MathAlgorithms.h"
 #include "gfxSkipChars.h"
 #include <algorithm>
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
@@ -97,18 +99,17 @@ HyperTextAccessible::NativeRole()
   return roles::TEXT_CONTAINER; // In ATK this works
 }
 
 uint64_t
 HyperTextAccessible::NativeState()
 {
   uint64_t states = AccessibleWrap::NativeState();
 
-  nsCOMPtr<nsIEditor> editor = GetEditor();
-  if (editor) {
+  if (mContent->AsElement()->State().HasState(NS_EVENT_STATE_MOZ_READWRITE)) {
     states |= states::EDITABLE;
 
   } else if (mContent->Tag() == nsGkAtoms::article) {
     // We want <article> to behave like a document in terms of readonly state.
     states |= states::READONLY;
   }
 
   if (HasChildren())
@@ -177,197 +178,16 @@ HyperTextAccessible::GetBoundsInFrame(ns
     startContentOffset += frameSubStringLength;
     startContentOffsetInFrame = 0;
     frame = frame->GetNextContinuation();
   }
 
   return screenRect.ToNearestPixels(presContext->AppUnitsPerDevPixel());
 }
 
-/*
- * Gets the specified text.
- */
-nsIFrame*
-HyperTextAccessible::GetPosAndText(int32_t& aStartOffset, int32_t& aEndOffset,
-                                   nsAString* aText, nsIFrame** aEndFrame,
-                                   Accessible** aStartAcc,
-                                   Accessible** aEndAcc)
-{
-  aStartOffset = ConvertMagicOffset(aStartOffset);
-  aEndOffset = ConvertMagicOffset(aEndOffset);
-
-  int32_t startOffset = aStartOffset;
-  int32_t endOffset = aEndOffset;
-  // XXX this prevents text interface usage on <input type="password">
-  bool isPassword = (Role() == roles::PASSWORD_TEXT);
-
-  // Clear out parameters and set up loop
-  if (aText) {
-    aText->Truncate();
-  }
-  if (endOffset < 0) {
-    const int32_t kMaxTextLength = 32767;
-    endOffset = kMaxTextLength; // Max end offset
-  }
-  else if (startOffset > endOffset) {
-    return nullptr;
-  }
-
-  nsIFrame *startFrame = nullptr;
- nsIFrame* endFrame = nullptr;
-  if (aEndFrame) {
-    *aEndFrame = nullptr;
-  }
-  if (aStartAcc)
-    *aStartAcc = nullptr;
-  if (aEndAcc)
-    *aEndAcc = nullptr;
-
-  nsIntRect unionRect;
-  Accessible* lastAccessible = nullptr;
-
-  gfxSkipChars skipChars;
-  gfxSkipCharsIterator iter;
-
-  // Loop through children and collect valid offsets, text and bounds
-  // depending on what we need for out parameters.
-  uint32_t childCount = ChildCount();
-  for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
-    Accessible* childAcc = mChildren[childIdx];
-    lastAccessible = childAcc;
-
-    nsIFrame *frame = childAcc->GetFrame();
-    if (!frame) {
-      continue;
-    }
-    endFrame = frame;
-    if (!nsAccUtils::IsEmbeddedObject(childAcc)) {
-      // We only need info up to rendered offset -- that is what we're
-      // converting to content offset
-      int32_t substringEndOffset = -1;
-      uint32_t ourRenderedStart = 0;
-      int32_t ourContentStart = 0;
-      if (frame->GetType() == nsGkAtoms::textFrame) {
-        nsresult rv = frame->GetRenderedText(nullptr, &skipChars, &iter);
-        if (NS_SUCCEEDED(rv)) {
-          ourRenderedStart = iter.GetSkippedOffset();
-          ourContentStart = iter.GetOriginalOffset();
-          substringEndOffset =
-            iter.ConvertOriginalToSkipped(skipChars.GetOriginalCharCount() +
-                                          ourContentStart) - ourRenderedStart;
-        }
-      }
-      if (substringEndOffset < 0) {
-        // XXX for non-textframe text like list bullets,
-        // should go away after list bullet rewrite
-        substringEndOffset = nsAccUtils::TextLength(childAcc);
-      }
-      if (startOffset < substringEndOffset ||
-          (startOffset == substringEndOffset && (childIdx == childCount - 1))) {
-        // Our start is within this substring
-        if (startOffset > 0 || endOffset < substringEndOffset) {
-          // We don't want the whole string for this accessible
-          // Get out the continuing text frame with this offset
-          int32_t outStartLineUnused;
-          int32_t contentOffset;
-          if (frame->GetType() == nsGkAtoms::textFrame) {
-            contentOffset = iter.ConvertSkippedToOriginal(startOffset) +
-                            ourRenderedStart - ourContentStart;
-          }
-          else {
-            contentOffset = startOffset;
-          }
-          frame->GetChildFrameContainingOffset(contentOffset, true,
-                                               &outStartLineUnused, &frame);
-          if (aEndFrame) {
-            *aEndFrame = frame; // We ended in the current frame
-            if (aEndAcc)
-              NS_ADDREF(*aEndAcc = childAcc);
-          }
-          if (substringEndOffset > endOffset) {
-            // Need to stop before the end of the available text
-            substringEndOffset = endOffset;
-          }
-          aEndOffset = endOffset;
-        }
-        if (aText) {
-          if (isPassword) {
-            for (int32_t count = startOffset; count < substringEndOffset; count ++)
-              *aText += '*'; // Show *'s only for password text
-          }
-          else {
-            childAcc->AppendTextTo(*aText, startOffset,
-                                   substringEndOffset - startOffset);
-          }
-        }
-        if (!startFrame) {
-          startFrame = frame;
-          aStartOffset = startOffset;
-          if (aStartAcc)
-            NS_ADDREF(*aStartAcc = childAcc);
-        }
-        // We already started copying in this accessible's string,
-        // for the next accessible we'll start at offset 0
-        startOffset = 0;
-      }
-      else {
-        // We have not found the start position yet, get the new startOffset
-        // that is relative to next accessible
-        startOffset -= substringEndOffset;
-      }
-      // The endOffset needs to be relative to the new startOffset
-      endOffset -= substringEndOffset;
-    }
-    else {
-      // Embedded object, append marker
-      // XXX Append \n for <br>'s
-      if (startOffset >= 1) {
-        -- startOffset;
-      }
-      else {
-        if (endOffset > 0) {
-          if (aText) {
-            // XXX: should use nsIAccessible::AppendTextTo.
-            if (frame->GetType() == nsGkAtoms::brFrame) {
-              *aText += kForcedNewLineChar;
-            } else if (nsAccUtils::MustPrune(this)) {
-              *aText += kImaginaryEmbeddedObjectChar;
-              // Expose imaginary embedded object character if the accessible
-              // hans't children.
-            } else {
-              *aText += kEmbeddedObjectChar;
-            }
-          }
-        }
-        if (!startFrame) {
-          startFrame = frame;
-          aStartOffset = 0;
-          if (aStartAcc)
-            NS_ADDREF(*aStartAcc = childAcc);
-        }
-      }
-      -- endOffset;
-    }
-    if (endOffset <= 0 && startFrame) {
-      break; // If we don't have startFrame yet, get that in next loop iteration
-    }
-  }
-
-  if (aStartAcc && !*aStartAcc) {
-    NS_IF_ADDREF(*aStartAcc = lastAccessible);
-  }
-  if (aEndFrame && !*aEndFrame) {
-    *aEndFrame = endFrame;
-    if (aEndAcc && !*aEndAcc)
-      NS_IF_ADDREF(*aEndAcc = lastAccessible);
-  }
-
-  return startFrame;
-}
-
 void
 HyperTextAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOffset,
                                    nsAString& aText)
 {
   aText.Truncate();
 
   int32_t startOffset = ConvertMagicOffset(aStartOffset);
   int32_t endOffset = ConvertMagicOffset(aEndOffset);
@@ -495,28 +315,26 @@ HyperTextAccessible::DOMPointToHypertext
   Accessible* childAccAtOffset = nullptr;
   while (descendantAcc) {
     Accessible* parentAcc = descendantAcc->Parent();
     if (parentAcc == this) {
       childAccAtOffset = descendantAcc;
       break;
     }
 
-    // This offset no longer applies because the passed-in text object is not a child
-    // of the hypertext. This happens when there are nested hypertexts, e.g.
-    // <div>abc<h1>def</h1>ghi</div>
-    // If the passed-in DOM point was not on a direct child of the hypertext, we will
-    // return the offset for that entire hypertext
-    if (aIsEndOffset) {
-      // Not inclusive, the indicated char comes at index before this offset
-      // If the end offset is after the first character of the passed in object, use 1 for
-    // addTextOffset, to put us after the embedded object char. We'll only treat the offset as
-    // before the embedded object char if we end at the very beginning of the child.
-    addTextOffset = addTextOffset > 0;
-    } else
+    // This offset no longer applies because the passed-in text object is not
+    // a child of the hypertext. This happens when there are nested hypertexts,
+    // e.g. <div>abc<h1>def</h1>ghi</div>. Thus we need to adjust the offset
+    // to make it relative the hypertext.
+    // If the end offset is not supposed to be inclusive and the original point
+    // is not at 0 offset then the returned offset should be after an embedded
+    // character the original point belongs to.
+    if (aIsEndOffset)
+      addTextOffset = (addTextOffset > 0 || descendantAcc->IndexInParent() > 0) ? 1 : 0;
+    else
       addTextOffset = 0;
 
     descendantAcc = parentAcc;
   }
 
   // Loop through, adding offsets until we reach childAccessible
   // If childAccessible is null we will end up adding up the entire length of
   // the hypertext, which is good -- it just means our offset node
@@ -543,67 +361,83 @@ HyperTextAccessible::DOMPointToHypertext
       // If not at end of last text node, we will return the accessible we were in
       return childAccAtOffset;
     }
   }
 
   return nullptr;
 }
 
-nsresult
-HyperTextAccessible::HypertextOffsetsToDOMRange(int32_t aStartHTOffset,
-                                                int32_t aEndHTOffset,
-                                                nsRange* aRange)
+bool
+HyperTextAccessible::OffsetsToDOMRange(int32_t aStartOffset, int32_t aEndOffset,
+                                       nsRange* aRange)
 {
-  // If the given offsets are 0 and associated editor is empty then return
-  // collapsed range with editor root element as range container.
-  if (aStartHTOffset == 0 && aEndHTOffset == 0) {
+  DOMPoint startPoint = OffsetToDOMPoint(aStartOffset);
+  if (!startPoint.node)
+    return false;
+
+  aRange->SetStart(startPoint.node, startPoint.idx);
+  if (aStartOffset == aEndOffset) {
+    aRange->SetEnd(startPoint.node, startPoint.idx);
+    return true;
+  }
+
+  DOMPoint endPoint = OffsetToDOMPoint(aEndOffset);
+  if (!endPoint.node)
+    return false;
+
+  aRange->SetEnd(endPoint.node, endPoint.idx);
+  return true;
+}
+
+DOMPoint
+HyperTextAccessible::OffsetToDOMPoint(int32_t aOffset)
+{
+  // 0 offset is valid even if no children. In this case the associated editor
+  // is empty so return a DOM point for editor root element.
+  if (aOffset == 0) {
     nsCOMPtr<nsIEditor> editor = GetEditor();
     if (editor) {
       bool isEmpty = false;
       editor->GetDocumentIsEmpty(&isEmpty);
       if (isEmpty) {
         nsCOMPtr<nsIDOMElement> editorRootElm;
         editor->GetRootElement(getter_AddRefs(editorRootElm));
 
         nsCOMPtr<nsINode> editorRoot(do_QueryInterface(editorRootElm));
-        if (editorRoot) {
-          aRange->SetStart(editorRoot, 0);
-          aRange->SetEnd(editorRoot, 0);
-
-          return NS_OK;
-        }
+        return DOMPoint(editorRoot, 0);
       }
     }
   }
 
-  nsRefPtr<Accessible> startAcc, endAcc;
-  int32_t startOffset = aStartHTOffset, endOffset = aEndHTOffset;
-  nsIFrame *startFrame = nullptr, *endFrame = nullptr;
+  int32_t childIdx = GetChildIndexAtOffset(aOffset);
+  if (childIdx == -1)
+    return DOMPoint();
 
-  startFrame = GetPosAndText(startOffset, endOffset, nullptr, &endFrame,
-                             getter_AddRefs(startAcc), getter_AddRefs(endAcc));
-  if (!startAcc || !endAcc)
-    return NS_ERROR_FAILURE;
+  Accessible* child = GetChildAt(childIdx);
+  int32_t innerOffset = aOffset - GetChildOffset(childIdx);
 
-  DOMPoint startPoint, endPoint;
-  nsresult rv = GetDOMPointByFrameOffset(startFrame, startOffset, startAcc,
-                                         &startPoint);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = aRange->SetStart(startPoint.node, startPoint.idx);
-  NS_ENSURE_SUCCESS(rv, rv);
+  // A text leaf case. The point is inside the text node.
+  if (child->IsTextLeaf()) {
+    nsIContent* content = child->GetContent();
+    int32_t idx = 0;
+    if (NS_FAILED(RenderedToContentOffset(content->GetPrimaryFrame(),
+                                          innerOffset, &idx)))
+      return DOMPoint();
 
-  if (aStartHTOffset == aEndHTOffset)
-    return aRange->SetEnd(startPoint.node, startPoint.idx);
+    return DOMPoint(content, idx);
+  }
 
-  rv = GetDOMPointByFrameOffset(endFrame, endOffset, endAcc, &endPoint);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return aRange->SetEnd(endPoint.node, endPoint.idx);
+  // Case of embedded object. The point is either before or after the element.
+  NS_ASSERTION(innerOffset == 0 || innerOffset == 1, "A wrong inner offset!");
+  nsINode* node = child->GetNode();
+  nsINode* parentNode = node->GetParentNode();
+  return parentNode ?
+    DOMPoint(parentNode, parentNode->IndexOf(node) + innerOffset) :
+    DOMPoint();
 }
 
 int32_t
 HyperTextAccessible::FindOffset(int32_t aOffset, nsDirection aDirection,
                                 nsSelectionAmount aAmount,
                                 EWordMovementType aWordMovementType)
 {
   // Find a leaf accessible frame to start with. PeekOffset wants this.
@@ -748,37 +582,33 @@ HyperTextAccessible::FindLineBoundary(in
 }
 
 void
 HyperTextAccessible::TextBeforeOffset(int32_t aOffset,
                                       AccessibleTextBoundary aBoundaryType,
                                       int32_t* aStartOffset, int32_t* aEndOffset,
                                       nsAString& aText)
 {
-  if (aBoundaryType == BOUNDARY_CHAR) {
-    GetCharAt(aOffset, eGetBefore, aText, aStartOffset, aEndOffset);
-    return;
-  }
-
   *aStartOffset = *aEndOffset = 0;
   aText.Truncate();
 
   int32_t convertedOffset = ConvertMagicOffset(aOffset);
   if (convertedOffset < 0) {
     NS_ERROR("Wrong given offset!");
     return;
   }
 
   int32_t adjustedOffset = convertedOffset;
   if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
     adjustedOffset = AdjustCaretOffset(adjustedOffset);
 
   switch (aBoundaryType) {
     case BOUNDARY_CHAR:
-      MOZ_ASSUME_UNREACHABLE("Already handled!");
+      if (convertedOffset != 0)
+        CharAt(convertedOffset - 1, aText, aStartOffset, aEndOffset);
       break;
 
     case BOUNDARY_WORD_START: {
       // If the offset is a word start (except text length offset) then move
       // backward to find a start offset (end offset is the given offset).
       // Otherwise move backward twice to find both start and end offsets.
       if (adjustedOffset == CharacterCount()) {
         *aEndOffset = FindWordBoundary(adjustedOffset, eDirPrevious, eStartWord);
@@ -835,17 +665,22 @@ HyperTextAccessible::TextAtOffset(int32_
   int32_t adjustedOffset = ConvertMagicOffset(aOffset);
   if (adjustedOffset < 0) {
     NS_ERROR("Wrong given offset!");
     return;
   }
 
   switch (aBoundaryType) {
     case BOUNDARY_CHAR:
-      GetCharAt(aOffset, eGetAt, aText, aStartOffset, aEndOffset);
+      // Return no char if caret is at the end of wrapped line (case of no line
+      // end character). Returning a next line char is confusing for AT.
+      if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET && IsCaretAtEndOfLine())
+        *aStartOffset = *aEndOffset = adjustedOffset;
+      else
+        CharAt(adjustedOffset, aText, aStartOffset, aEndOffset);
       break;
 
     case BOUNDARY_WORD_START:
       if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
         adjustedOffset = AdjustCaretOffset(adjustedOffset);
 
       *aEndOffset = FindWordBoundary(adjustedOffset, eDirNext, eStartWord);
       *aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eStartWord);
@@ -883,37 +718,37 @@ HyperTextAccessible::TextAtOffset(int32_
 }
 
 void
 HyperTextAccessible::TextAfterOffset(int32_t aOffset,
                                      AccessibleTextBoundary aBoundaryType,
                                      int32_t* aStartOffset, int32_t* aEndOffset,
                                      nsAString& aText)
 {
-  if (aBoundaryType == BOUNDARY_CHAR) {
-    GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
-    return;
-  }
-
   *aStartOffset = *aEndOffset = 0;
   aText.Truncate();
 
   int32_t convertedOffset = ConvertMagicOffset(aOffset);
   if (convertedOffset < 0) {
     NS_ERROR("Wrong given offset!");
     return;
   }
 
   int32_t adjustedOffset = convertedOffset;
   if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
     adjustedOffset = AdjustCaretOffset(adjustedOffset);
 
   switch (aBoundaryType) {
     case BOUNDARY_CHAR:
-      MOZ_ASSUME_UNREACHABLE("Already handled!");
+      // If caret is at the end of wrapped line (case of no line end character)
+      // then char after the offset is a first char at next line.
+      if (adjustedOffset >= CharacterCount())
+        *aStartOffset = *aEndOffset = CharacterCount();
+      else
+        CharAt(adjustedOffset + 1, aText, aStartOffset, aEndOffset);
       break;
 
     case BOUNDARY_WORD_START:
       // Move word forward twice to find start and end offsets.
       *aStartOffset = FindWordBoundary(adjustedOffset, eDirNext, eStartWord);
       *aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eStartWord);
       TextSubstring(*aStartOffset, *aEndOffset, aText);
       break;
@@ -1319,17 +1154,17 @@ HyperTextAccessible::CaretOffset() const
     return -1;
 
   // Turn the focus node and offset of the selection into caret hypretext
   // offset.
   Selection* domSel = DOMSelection();
   NS_ENSURE_TRUE(domSel, -1);
 
   nsINode* focusNode = domSel->GetFocusNode();
-  int32_t focusOffset = domSel->GetFocusOffset();
+  uint32_t focusOffset = domSel->FocusOffset();
 
   // No caret if this DOM node is inside of focused node but the selection's
   // focus point is not inside of this DOM node.
   if (focusDisp == FocusManager::eContainedByFocus) {
     nsINode* resultNode =
       nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
 
     nsINode* thisNode = GetNode();
@@ -1361,17 +1196,17 @@ HyperTextAccessible::CaretLineNumber()
   if (!caretNode || !caretNode->IsContent())
     return -1;
 
   nsIContent* caretContent = caretNode->AsContent();
   if (!nsCoreUtils::IsAncestorOf(GetNode(), caretContent))
     return -1;
 
   int32_t returnOffsetUnused;
-  int32_t caretOffset = domSel->GetFocusOffset();
+  uint32_t caretOffset = domSel->FocusOffset();
   nsFrameSelection::HINT hint = frameSelection->GetHint();
   nsIFrame *caretFrame = frameSelection->GetFrameForNodeOffset(caretContent, caretOffset,
                                                                hint, &returnOffsetUnused);
   NS_ENSURE_TRUE(caretFrame, -1);
 
   int32_t lineNumber = 1;
   nsAutoLineIterator lineIterForCaret;
   nsIContent *hyperTextContent = IsContent() ? mContent.get() : nullptr;
@@ -1576,17 +1411,18 @@ HyperTextAccessible::SetSelectionBoundsA
   if (aSelectionNum == rangeCount)
     range = new nsRange(mContent);
   else
     range = domSel->GetRangeAt(aSelectionNum);
 
   if (!range)
     return false;
 
-  HypertextOffsetsToDOMRange(startOffset, endOffset, range);
+  if (!OffsetsToDOMRange(startOffset, endOffset, range))
+    return false;
 
   // If new range was created then add it, otherwise notify selection listeners
   // that existing selection range was changed.
   if (aSelectionNum == rangeCount)
     return NS_SUCCEEDED(domSel->AddRange(range));
 
   domSel->RemoveRange(range);
   return NS_SUCCEEDED(domSel->AddRange(range));
@@ -1606,18 +1442,17 @@ HyperTextAccessible::RemoveFromSelection
   return true;
 }
 
 void
 HyperTextAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
                                        uint32_t aScrollType)
 {
   nsRefPtr<nsRange> range = new nsRange(mContent);
-  nsresult rv = HypertextOffsetsToDOMRange(aStartOffset, aEndOffset, range);
-  if (NS_SUCCEEDED(rv))
+  if (OffsetsToDOMRange(aStartOffset, aEndOffset, range))
     nsCoreUtils::ScrollSubstringTo(GetFrame(), range, aScrollType);
 }
 
 void
 HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
                                             int32_t aEndOffset,
                                             uint32_t aCoordinateType,
                                             int32_t aX, int32_t aY)
@@ -1625,18 +1460,17 @@ HyperTextAccessible::ScrollSubstringToPo
   nsIFrame *frame = GetFrame();
   if (!frame)
     return;
 
   nsIntPoint coords = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType,
                                                         this);
 
   nsRefPtr<nsRange> range = new nsRange(mContent);
-  nsresult rv = HypertextOffsetsToDOMRange(aStartOffset, aEndOffset, range);
-  if (NS_FAILED(rv))
+  if (!OffsetsToDOMRange(aStartOffset, aEndOffset, range))
     return;
 
   nsPresContext* presContext = frame->PresContext();
   nsPoint coordsInAppUnits =
     coords.ToAppUnits(presContext->AppUnitsPerDevPixel());
 
   bool initialScrolled = false;
   nsIFrame *parentFrame = frame;
@@ -1654,17 +1488,17 @@ HyperTextAccessible::ScrollSubstringToPo
 
         // avoid divide by zero
         size.width = size.width ? size.width : 1;
         size.height = size.height ? size.height : 1;
 
         int16_t hPercent = offsetPointX * 100 / size.width;
         int16_t vPercent = offsetPointY * 100 / size.height;
 
-        rv = nsCoreUtils::ScrollSubstringTo(frame, range, vPercent, hPercent);
+        nsresult rv = nsCoreUtils::ScrollSubstringTo(frame, range, vPercent, hPercent);
         if (NS_FAILED(rv))
           return;
 
         initialScrolled = true;
       } else {
         // Substring was scrolled to the given point already inside its closest
         // scrollable area. If there are nested scrollable areas then make
         // sure we scroll lower areas to the given point inside currently
@@ -1817,38 +1651,19 @@ HyperTextAccessible::RenderedToContentOf
   *aContentOffset = iter.ConvertSkippedToOriginal(aRenderedOffset + ourRenderedStart) - ourContentStart;
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HyperTextAccessible public
 
-bool
-HyperTextAccessible::GetCharAt(int32_t aOffset, EGetTextType aShift,
-                               nsAString& aChar, int32_t* aStartOffset,
-                               int32_t* aEndOffset)
-{
-  aChar.Truncate();
-
-  int32_t offset = ConvertMagicOffset(aOffset) + static_cast<int32_t>(aShift);
-  if (!CharAt(offset, aChar))
-    return false;
-
-  if (aStartOffset)
-    *aStartOffset = offset;
-  if (aEndOffset)
-    *aEndOffset = aChar.IsEmpty() ? offset : offset + 1;
-
-  return true;
-}
-
 int32_t
 HyperTextAccessible::GetChildOffset(uint32_t aChildIndex,
-                                    bool aInvalidateAfter)
+                                    bool aInvalidateAfter) const
 {
   if (aChildIndex == 0) {
     if (aInvalidateAfter)
       mOffsets.Clear();
 
     return aChildIndex;
   }
 
@@ -1868,17 +1683,17 @@ HyperTextAccessible::GetChildOffset(uint
     lastOffset += nsAccUtils::TextLength(child);
     mOffsets.AppendElement(lastOffset);
   }
 
   return mOffsets[aChildIndex - 1];
 }
 
 int32_t
-HyperTextAccessible::GetChildIndexAtOffset(uint32_t aOffset)
+HyperTextAccessible::GetChildIndexAtOffset(uint32_t aOffset) const
 {
   uint32_t lastOffset = 0;
   uint32_t offsetCount = mOffsets.Length();
   if (offsetCount > 0) {
     lastOffset = mOffsets[offsetCount - 1];
     if (aOffset < lastOffset) {
       uint32_t low = 0, high = offsetCount;
       while (high > low) {
--- a/accessible/src/generic/HyperTextAccessible.h
+++ b/accessible/src/generic/HyperTextAccessible.h
@@ -12,27 +12,28 @@
 
 #include "nsFrameSelection.h"
 #include "nsISelectionController.h"
 
 namespace mozilla {
 namespace a11y {
 
 struct DOMPoint {
+  DOMPoint() : node(nullptr), idx(0) { }
+  DOMPoint(nsINode* aNode, int32_t aIdx) : node(aNode), idx(aIdx) { }
+
   nsINode* node;
   int32_t idx;
 };
 
-enum EGetTextType { eGetBefore=-1, eGetAt=0, eGetAfter=1 };
-
 // This character marks where in the text returned via nsIAccessibleText(),
 // that embedded object characters exist
-const PRUnichar kEmbeddedObjectChar = 0xfffc;
-const PRUnichar kImaginaryEmbeddedObjectChar = ' ';
-const PRUnichar kForcedNewLineChar = '\n';
+const char16_t kEmbeddedObjectChar = 0xfffc;
+const char16_t kImaginaryEmbeddedObjectChar = ' ';
+const char16_t kForcedNewLineChar = '\n';
 
 /**
   * Special Accessible that knows how contain both text and embedded objects
   */
 class HyperTextAccessible : public AccessibleWrap,
                             public xpcAccessibleHyperText
 {
 public:
@@ -123,88 +124,93 @@ public:
     *                       otherwise nullptr
     */
   Accessible* DOMPointToHypertextOffset(nsINode *aNode,
                                         int32_t aNodeOffset,
                                         int32_t* aHypertextOffset,
                                         bool aIsEndOffset = false) const;
 
   /**
-   * Turn a start and end hypertext offsets into DOM range.
+   * Convert start and end hypertext offsets into DOM range.
    *
-   * @param  aStartHTOffset  [in] the given start hypertext offset
-   * @param  aEndHTOffset    [in] the given end hypertext offset
-   * @param  aRange      [out] the range whose bounds to set
+   * @param  aStartOffset  [in] the given start hypertext offset
+   * @param  aEndOffset    [in] the given end hypertext offset
+   * @param  aRange        [in, out] the range whose bounds to set
+   * @return true   if conversion was successful
    */
-  nsresult HypertextOffsetsToDOMRange(int32_t aStartHTOffset,
-                                      int32_t aEndHTOffset,
-                                      nsRange* aRange);
+  bool OffsetsToDOMRange(int32_t aStartOffset, int32_t aEndOffset,
+                         nsRange* aRange);
+
+  /**
+   * Convert the given offset into DOM point.
+   *
+   * If offset is at text leaf then DOM point is (text node, offsetInTextNode),
+   * if before embedded object then (parent node, indexInParent), if after then
+   * (parent node, indexInParent + 1).
+   */
+  DOMPoint OffsetToDOMPoint(int32_t aOffset);
 
   /**
    * Return true if the used ARIA role (if any) allows the hypertext accessible
    * to expose text interfaces.
    */
   bool IsTextRole();
 
   //////////////////////////////////////////////////////////////////////////////
   // TextAccessible
 
   /**
    * Return character count within the hypertext accessible.
    */
-  uint32_t CharacterCount()
-  {
-    return GetChildOffset(ChildCount());
-  }
+  uint32_t CharacterCount() const
+    { return GetChildOffset(ChildCount()); }
 
   /**
    * Get a character at the given offset (don't support magic offsets).
    */
-  bool CharAt(int32_t aOffset, nsAString& aChar)
+  bool CharAt(int32_t aOffset, nsAString& aChar,
+              int32_t* aStartOffset = nullptr, int32_t* aEndOffset = nullptr)
   {
+    NS_ASSERTION(!aStartOffset == !aEndOffset,
+                 "Offsets should be both defined or both undefined!");
+
     int32_t childIdx = GetChildIndexAtOffset(aOffset);
     if (childIdx == -1)
       return false;
 
     Accessible* child = GetChildAt(childIdx);
     child->AppendTextTo(aChar, aOffset - GetChildOffset(childIdx), 1);
+
+    if (aStartOffset && aEndOffset) {
+      *aStartOffset = aOffset;
+      *aEndOffset = aOffset + aChar.Length();
+    }
     return true;
   }
 
+  char16_t CharAt(int32_t aOffset)
+  {
+    nsAutoString charAtOffset;
+    CharAt(aOffset, charAtOffset);
+    return charAtOffset.CharAt(0);
+  }
+
   /**
    * Return true if char at the given offset equals to given char.
    */
-  bool IsCharAt(int32_t aOffset, char aChar)
-  {
-    nsAutoString charAtOffset;
-    CharAt(aOffset, charAtOffset);
-    return charAtOffset.CharAt(0) == aChar;
-  }
+  bool IsCharAt(int32_t aOffset, char16_t aChar)
+    { return CharAt(aOffset) == aChar; }
 
   /**
    * Return true if terminal char is at the given offset.
    */
   bool IsLineEndCharAt(int32_t aOffset)
     { return IsCharAt(aOffset, '\n'); }
 
   /**
-   * Get a character before/at/after the given offset.
-   *
-   * @param aOffset       [in] the given offset
-   * @param aShift        [in] specifies whether to get a char before/at/after
-   *                        offset
-   * @param aChar         [out] the character
-   * @param aStartOffset  [out, optional] the start offset of the character
-   * @param aEndOffset    [out, optional] the end offset of the character
-   * @return               false if offset at the given shift is out of range
-   */
-  bool GetCharAt(int32_t aOffset, EGetTextType aShift, nsAString& aChar,
-                 int32_t* aStartOffset = nullptr, int32_t* aEndOffset = nullptr);
-
-  /**
    * Return text between given offsets.
    */
   void TextSubstring(int32_t aStartOffset, int32_t aEndOffset, nsAString& aText);
 
   /**
    * Return text before/at/after the given offset corresponding to
    * the boundary type.
    */
@@ -234,41 +240,41 @@ public:
    * Return text offset of the given child accessible within hypertext
    * accessible.
    *
    * @param  aChild           [in] accessible child to get text offset for
    * @param  aInvalidateAfter [in, optional] indicates whether invalidate
    *                           cached offsets for next siblings of the child
    */
   int32_t GetChildOffset(Accessible* aChild,
-                         bool aInvalidateAfter = false)
+                         bool aInvalidateAfter = false) const
   {
     int32_t index = GetIndexOf(aChild);
     return index == -1 ? -1 : GetChildOffset(index, aInvalidateAfter);
   }
 
   /**
    * Return text offset for the child accessible index.
    */
   int32_t GetChildOffset(uint32_t aChildIndex,
-                         bool aInvalidateAfter = false);
+                         bool aInvalidateAfter = false) const;
 
   /**
    * Return child accessible at the given text offset.
    *
    * @param  aOffset  [in] the given text offset
    */
-  int32_t GetChildIndexAtOffset(uint32_t aOffset);
+  int32_t GetChildIndexAtOffset(uint32_t aOffset) const;
 
   /**
    * Return child accessible at the given text offset.
    *
    * @param  aOffset  [in] the given text offset
    */
-  Accessible* GetChildAtOffset(uint32_t aOffset)
+  Accessible* GetChildAtOffset(uint32_t aOffset) const
   {
     return GetChildAt(GetChildIndexAtOffset(aOffset));
   }
 
   /**
    * Return true if the given offset/range is valid.
    */
   bool IsValidOffset(int32_t aOffset);
@@ -385,16 +391,21 @@ protected:
   int32_t ConvertMagicOffset(int32_t aOffset);
 
   /**
    * Adjust an offset the caret stays at to get a text by line boundary.
    */
   int32_t AdjustCaretOffset(int32_t aOffset) const;
 
   /**
+   * Return true if caret is at end of line.
+   */
+  bool IsCaretAtEndOfLine() const;
+
+  /**
    * Return true if the given offset points to terminal empty line if any.
    */
   bool IsEmptyLastLineOffset(int32_t aOffset)
   {
     return aOffset == static_cast<int32_t>(CharacterCount()) &&
       IsLineEndCharAt(aOffset - 1);
   }
 
@@ -432,45 +443,16 @@ protected:
    * Return an offset corresponding to the given direction and selection amount
    * relative the given offset. A helper used to find word or line boundaries.
    */
   virtual int32_t FindOffset(int32_t aOffset, nsDirection aDirection,
                              nsSelectionAmount aAmount,
                              EWordMovementType aWordMovementType = eDefaultBehavior);
 
   /**
-    * Provides information for substring that is defined by the given start
-    * and end offsets for this hyper text.
-    *
-    * @param  aStartOffset  [inout] the start offset into the hyper text. This
-    *                       is also an out parameter used to return the offset
-    *                       into the start frame's rendered text content
-    *                       (start frame is the @return)
-    *
-    * @param  aEndOffset    [inout] the end offset into the hyper text. This is
-    *                       also an out parameter used to return
-    *                       the offset into the end frame's rendered
-    *                       text content.
-    *
-    * @param  aText         [out, optional] return the substring's text
-    * @param  aEndFrame     [out, optional] return the end frame for this
-    *                       substring
-    * @param  aStartAcc     [out, optional] return the start accessible for this
-    *                       substring
-    * @param  aEndAcc       [out, optional] return the end accessible for this
-    *                       substring
-    * @return               the start frame for this substring
-    */
-  nsIFrame* GetPosAndText(int32_t& aStartOffset, int32_t& aEndOffset,
-                          nsAString *aText = nullptr,
-                          nsIFrame **aEndFrame = nullptr,
-                          Accessible** aStartAcc = nullptr,
-                          Accessible** aEndAcc = nullptr);
-
-  /**
    * Return the boundaries of the substring in case of textual frame or
    * frame boundaries in case of non textual frame, offsets are ignored.
    */
   nsIntRect GetBoundsInFrame(nsIFrame* aFrame,
                              uint32_t aStartRenderedOffset,
                              uint32_t aEndRenderedOffset);
 
   // Selection helpers
@@ -529,17 +511,17 @@ protected:
                                  int32_t *aStartOffset,
                                  int32_t *aEndOffset,
                                  nsIPersistentProperties *aAttributes);
 
 private:
   /**
    * End text offsets array.
    */
-  nsTArray<uint32_t> mOffsets;
+  mutable nsTArray<uint32_t> mOffsets;
 };
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible downcasting method
 
 inline HyperTextAccessible*
 Accessible::AsHyperText()
--- a/accessible/src/generic/RootAccessible.cpp
+++ b/accessible/src/generic/RootAccessible.cpp
@@ -79,19 +79,17 @@ RootAccessible::Name(nsString& aName)
   aName.Truncate();
 
   if (mRoleMapEntry) {
     Accessible::Name(aName);
     if (!aName.IsEmpty())
       return eNameOK;
   }
 
-  nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(mDocumentNode);
-  NS_ENSURE_TRUE(document, eNameOK);
-  document->GetTitle(aName);
+  mDocumentNode->GetTitle(aName);
   return eNameOK;
 }
 
 role
 RootAccessible::NativeRole()
 {
   // If it's a <dialog> or <wizard>, use roles::DIALOG instead
   dom::Element* rootElm = mDocumentNode->GetRootElement();
--- a/accessible/src/html/HTMLElementAccessibles.cpp
+++ b/accessible/src/html/HTMLElementAccessibles.cpp
@@ -42,17 +42,17 @@ uint64_t
 HTMLBRAccessible::NativeState()
 {
   return states::READONLY;
 }
 
 ENameValueFlag
 HTMLBRAccessible::NativeName(nsString& aName)
 {
-  aName = static_cast<PRUnichar>('\n');    // Newline char
+  aName = static_cast<char16_t>('\n');    // Newline char
   return eNameOK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLLabelAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLLabelAccessible, HyperTextAccessible)
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -9,28 +9,28 @@
 #include "nsAccUtils.h"
 #include "nsEventShell.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "States.h"
 
 #include "nsContentList.h"
-#include "nsCxPusher.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "nsIAccessibleRelation.h"
 #include "nsIDOMNSEditableElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIEditor.h"
 #include "nsIFormControl.h"
 #include "nsINameSpaceManager.h"
 #include "nsIPersistentProperties2.h"
 #include "nsISelectionController.h"
 #include "nsIServiceManager.h"
 #include "nsITextControlFrame.h"
+#include "mozilla/dom/ScriptSettings.h"
 
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::a11y;
 
@@ -372,33 +372,37 @@ HTMLTextFieldAccessible::ApplyARIAState(
     aria::MapToState(aria::eARIAAutoComplete, widgetElm->AsElement(), aState);
 }
 
 uint64_t
 HTMLTextFieldAccessible::NativeState()
 {
   uint64_t state = HyperTextAccessibleWrap::NativeState();
 
+  // Text fields are always editable, even if they are also read only or
+  // disabled.
+  state |= states::EDITABLE;
+
   // can be focusable, focused, protected. readonly, unavailable, selected
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
                             nsGkAtoms::password, eIgnoreCase)) {
     state |= states::PROTECTED;
   }
 
   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly)) {
     state |= states::READONLY;
   }
 
   // Is it an <input> or a <textarea> ?
   HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
   state |= input && input->IsSingleLineTextControl() ?
     states::SINGLE_LINE : states::MULTI_LINE;
 
-  if (!(state & states::EDITABLE) ||
-      (state & (states::PROTECTED | states::MULTI_LINE)))
+  if (state & (states::PROTECTED | states::MULTI_LINE | states::READONLY |
+               states::UNAVAILABLE))
     return state;
 
   // Expose autocomplete states if this input is part of autocomplete widget.
   Accessible* widget = ContainerWidget();
   if (widget && widget-IsAutoComplete()) {
     state |= states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION;
     return state;
   }
@@ -463,18 +467,17 @@ HTMLTextFieldAccessible::GetEditor() con
 {
   nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(mContent));
   if (!editableElt)
     return nullptr;
 
   // nsGenericHTMLElement::GetEditor has a security check.
   // Make sure we're not restricted by the permissions of
   // whatever script is currently running.
-  nsCxPusher pusher;
-  pusher.PushNull();
+  mozilla::dom::AutoSystemCaller asc;
 
   nsCOMPtr<nsIEditor> editor;
   editableElt->GetEditor(getter_AddRefs(editor));
 
   return editor.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/html/HTMLSelectAccessible.cpp
+++ b/accessible/src/html/HTMLSelectAccessible.cpp
@@ -213,16 +213,17 @@ HTMLSelectOptionAccessible::NativeState(
 
   if (selectState & states::OFFSCREEN) {
     state |= states::OFFSCREEN;
   } else if (selectState & states::COLLAPSED) {
     // <select> is COLLAPSED: add OFFSCREEN, if not the currently
     // visible option
     if (!selected) {
       state |= states::OFFSCREEN;
+      state ^= states::INVISIBLE;
     } else {
       // Clear offscreen and invisible for currently showing option
       state &= ~(states::OFFSCREEN | states::INVISIBLE);
       state |= selectState & states::OPAQUE1;
     }
   } else {
     // XXX list frames are weird, don't rely on Accessible's general
     // visibility implementation unless they get reimplemented in layout
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -15,17 +15,16 @@
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "States.h"
 #include "TreeWalker.h"
 
 #include "mozilla/dom/HTMLTableElement.h"
 #include "nsIDOMElement.h"
-#include "nsIDOMDocument.h"
 #include "nsIDOMRange.h"
 #include "nsISelectionPrivate.h"
 #include "nsINameSpaceManager.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMHTMLCollection.h"
 #include "nsIDocument.h"
 #include "nsIMutableArray.h"
 #include "nsIPersistentProperties2.h"
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -501,71 +501,109 @@ var Output = {
               'clicked.ogg'],
 
     earconBuffers: {},
 
     inited: false,
 
     webspeechEnabled: false,
 
+    deferredOutputs: [],
+
     init: function init() {
       let window = Utils.win;
       this.webspeechEnabled = !!window.speechSynthesis;
 
+      let settingsToGet = 2;
+      let settingsCallback = (aName, aSetting) => {
+        if (--settingsToGet > 0) {
+          return;
+        }
+
+        this.inited = true;
+
+        for (let actions of this.deferredOutputs) {
+          this.output(actions);
+        }
+      };
+
+      this._volumeSetting = new SettingCache(
+        'accessibility.screenreader-volume', settingsCallback,
+        { defaultValue: 1, callbackNow: true, callbackOnce: true });
+      this._rateSetting = new SettingCache(
+        'accessibility.screenreader-rate', settingsCallback,
+        { defaultValue: 0, callbackNow: true, callbackOnce: true });
+
       for (let earcon of this.EARCONS) {
         let earconName = /(^.*)\..*$/.exec(earcon)[1];
         this.earconBuffers[earconName] = new WeakMap();
         this.earconBuffers[earconName].set(
           window, new window.Audio('chrome://global/content/accessibility/' + earcon));
       }
+    },
 
-      this.inited = true;
+    uninit: function uninit() {
+      if (this.inited) {
+        delete this._volumeSetting;
+        delete this._rateSetting;
+      }
+      this.inited = false;
     },
 
     output: function output(aActions) {
       if (!this.inited) {
-        this.init();
+        this.deferredOutputs.push(aActions);
+        return;
       }
 
       for (let action of aActions) {
         let window = Utils.win;
         Logger.debug('tts.' + action.method, '"' + action.data + '"',
                      JSON.stringify(action.options));
 
         if (!action.options.enqueue && this.webspeechEnabled) {
           window.speechSynthesis.cancel();
         }
 
         if (action.method === 'speak' && this.webspeechEnabled) {
-          window.speechSynthesis.speak(
-            new window.SpeechSynthesisUtterance(action.data));
+          let utterance = new window.SpeechSynthesisUtterance(action.data);
+          let requestedRate = this._rateSetting.value;
+          utterance.volume = this._volumeSetting.value;
+          utterance.rate = requestedRate >= 0 ?
+            requestedRate + 1 : 1 / (Math.abs(requestedRate) + 1);
+          window.speechSynthesis.speak(utterance);
         } else if (action.method === 'playEarcon') {
           let audioBufferWeakMap = this.earconBuffers[action.data];
           if (audioBufferWeakMap) {
-            audioBufferWeakMap.get(window).cloneNode(false).play();
+            let node = audioBufferWeakMap.get(window).cloneNode(false);
+            node.volume = this._volumeSetting.value;
+            node.play();
           }
         }
       }
     }
   },
 
   start: function start() {
     Cu.import('resource://gre/modules/Geometry.jsm');
+    this.speechHelper.init();
   },
 
   stop: function stop() {
     if (this.highlightBox) {
       Utils.win.document.documentElement.removeChild(this.highlightBox.get());
       delete this.highlightBox;
     }
 
     if (this.announceBox) {
       Utils.win.document.documentElement.removeChild(this.announceBox.get());
       delete this.announceBox;
     }
+
+    this.speechHelper.uninit();
   },
 
   Speech: function Speech(aDetails, aBrowser) {
     this.speechHelper.output(aDetails.actions);
   },
 
   Visual: function Visual(aDetails, aBrowser) {
     switch (aDetails.method) {
--- a/accessible/src/jsat/Constants.jsm
+++ b/accessible/src/jsat/Constants.jsm
@@ -1,39 +1,52 @@
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 
-this.EXPORTED_SYMBOLS = ['Roles', 'Events', 'Relations', 'Filters'];
+this.EXPORTED_SYMBOLS = ['Roles', 'Events', 'Relations', 'Filters', 'States'];
 
-function ConstantsMap (aObject, aPrefix) {
+function ConstantsMap (aObject, aPrefix, aMap = {}, aModifier = null) {
   let offset = aPrefix.length;
   for (var name in aObject) {
     if (name.indexOf(aPrefix) === 0) {
-      this[name.slice(offset)] = aObject[name];
+      aMap[name.slice(offset)] = aModifier ?
+        aModifier(aObject[name]) : aObject[name];
     }
   }
+
+  return aMap;
 }
 
 XPCOMUtils.defineLazyGetter(
   this, 'Roles',
   function() {
-    return new ConstantsMap(Ci.nsIAccessibleRole, 'ROLE_');
+    return ConstantsMap(Ci.nsIAccessibleRole, 'ROLE_');
   });
 
 XPCOMUtils.defineLazyGetter(
   this, 'Events',
   function() {
-    return new ConstantsMap(Ci.nsIAccessibleEvent, 'EVENT_');
+    return ConstantsMap(Ci.nsIAccessibleEvent, 'EVENT_');
   });
 
 XPCOMUtils.defineLazyGetter(
   this, 'Relations',
   function() {
-    return new ConstantsMap(Ci.nsIAccessibleRelation, 'RELATION_');
+    return ConstantsMap(Ci.nsIAccessibleRelation, 'RELATION_');
   });
 
 XPCOMUtils.defineLazyGetter(
   this, 'Filters',
   function() {
-    return new ConstantsMap(Ci.nsIAccessibleTraversalRule, 'FILTER_');
+    return ConstantsMap(Ci.nsIAccessibleTraversalRule, 'FILTER_');
   });
+
+XPCOMUtils.defineLazyGetter(
+  this, 'States',
+  function() {
+    let statesMap = ConstantsMap(Ci.nsIAccessibleStates, 'STATE_', {},
+                                 (val) => { return { base: val, extended: 0 }; });
+    ConstantsMap(Ci.nsIAccessibleStates, 'EXT_STATE_', statesMap,
+                 (val) => { return { base: 0, extended: val }; });
+    return statesMap;
+  });
--- a/accessible/src/jsat/EventManager.jsm
+++ b/accessible/src/jsat/EventManager.jsm
@@ -19,16 +19,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, 'Presentation',
   'resource://gre/modules/accessibility/Presentation.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'TraversalRules',
   'resource://gre/modules/accessibility/TraversalRules.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.EventManager = function EventManager(aContentScope) {
   this.contentScope = aContentScope;
   this.addEventListener = this.contentScope.addEventListener.bind(
     this.contentScope);
   this.removeEventListener = this.contentScope.removeEventListener.bind(
@@ -50,16 +52,17 @@ this.EventManager.prototype = {
 
         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.present(Presentation.tabStateChanged(null, 'newtab'));
 
     } catch (x) {
       Logger.logException(x, 'Failed to start EventManager');
     }
@@ -70,28 +73,46 @@ this.EventManager.prototype = {
   stop: function stop() {
     if (!this._started) {
       return;
     }
     Logger.debug('EventManager.stop');
     AccessibilityEventObserver.removeListener(this);
     try {
       this.webProgress.removeProgressListener(this);
+      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) {
     try {
       switch (aEvent.type) {
+      case 'wheel':
+      {
+        let attempts = 0;
+        let vc = Utils.getVirtualCursor(this.contentScope.content.document);
+        let intervalId = this.contentScope.content.setInterval(() => {
+          if (!Utils.isAliveAndVisible(vc.position, true)) {
+            this.contentScope.content.clearInterval(intervalId);
+            let delta = aEvent.deltaX || aEvent.deltaY;
+            this.contentScope.content.setTimeout(() => {
+              vc[delta > 0 ? 'moveNext' : 'movePrevious'](TraversalRules.SimpleOnScreen);
+            }, 100);
+          } else if (++attempts > 5) {
+            this.contentScope.content.clearInterval(intervalId);
+          }
+        }, 150);
+        break;
+      }
       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)
@@ -142,23 +163,23 @@ this.EventManager.prototype = {
           Presentation.pivotChanged(position, event.oldAccessible, reason,
                                     pivot.startOffset, pivot.endOffset));
 
         break;
       }
       case Events.STATE_CHANGE:
       {
         let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent);
-        if (event.state == Ci.nsIAccessibleStates.STATE_CHECKED &&
-            !(event.isExtraState)) {
+        let state = Utils.getState(event);
+        if (state.contains(States.CHECKED)) {
           this.present(
             Presentation.
               actionInvoked(aEvent.accessible,
                             event.isEnabled ? 'check' : 'uncheck'));
-        } else if (event.state == Ci.nsIAccessibleStates.STATE_SELECTED) {
+        } else if (state.contains(States.SELECTED)) {
           this.present(
             Presentation.
               actionInvoked(aEvent.accessible,
                             event.isEnabled ? 'select' : 'unselect'));
         }
         break;
       }
       case Events.SCROLLING_START:
@@ -171,20 +192,20 @@ this.EventManager.prototype = {
       {
         let acc = aEvent.accessible;
         let characterCount = acc.
           QueryInterface(Ci.nsIAccessibleText).characterCount;
         let caretOffset = aEvent.
           QueryInterface(Ci.nsIAccessibleCaretMoveEvent).caretOffset;
 
         // Update editing state, both for presenter and other things
-        let [,extState] = Utils.getStates(acc);
+        let state = Utils.getState(acc);
         let editState = {
-          editing: !!(extState & Ci.nsIAccessibleStates.EXT_STATE_EDITABLE),
-          multiline: !!(extState & Ci.nsIAccessibleStates.EXT_STATE_MULTI_LINE),
+          editing: state.contains(States.EDITABLE),
+          multiline: state.contains(States.MULTI_LINE),
           atStart: caretOffset == 0,
           atEnd: caretOffset == characterCount
         };
 
         // Not interesting
         if (!editState.editing && editState.editing == this.editState.editing)
           break;
 
@@ -248,21 +269,30 @@ this.EventManager.prototype = {
         break;
       }
       case Events.FOCUS:
       {
         // Put vc where the focus is at
         let acc = aEvent.accessible;
         let doc = aEvent.accessibleDocument;
         if (acc.role != Roles.DOCUMENT && doc.role != Roles.CHROME_WINDOW) {
+          this.contentScope.content.clearTimeout(this._autoMove);
           let vc = Utils.getVirtualCursor(doc);
           vc.moveNext(TraversalRules.Simple, acc, true);
         }
         break;
       }
+      case Events.DOCUMENT_LOAD_COMPLETE:
+      {
+        this._autoMove = this.contentScope.content.setTimeout(() => {
+          Utils.getVirtualCursor(aEvent.accessibleDocument)
+            .moveNext(TraversalRules.Simple, aEvent.accessible, true);
+        }, 500);
+        break;
+      }
     }
   },
 
   _handleText: function _handleText(aEvent, aLiveRegion, aIsPolite) {
     let event = aEvent.QueryInterface(Ci.nsIAccessibleTextChangeEvent);
     let isInserted = event.isInserted;
     let txtIface = aEvent.accessible.QueryInterface(Ci.nsIAccessibleText);
 
--- a/accessible/src/jsat/OutputGenerator.jsm
+++ b/accessible/src/jsat/OutputGenerator.jsm
@@ -24,16 +24,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, 'PrefCache',
   'resource://gre/modules/accessibility/Utils.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Logger',
   'resource://gre/modules/accessibility/Utils.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'PluralForm',
   'resource://gre/modules/PluralForm.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
   'resource://gre/modules/accessibility/Constants.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'States',
+  'resource://gre/modules/accessibility/Constants.jsm');
 
 var gStringBundle = Cc['@mozilla.org/intl/stringbundle;1'].
   getService(Ci.nsIStringBundleService).
   createBundle('chrome://global/locale/AccessFu.properties');
 
 this.EXPORTED_SYMBOLS = ['UtteranceGenerator', 'BrailleGenerator'];
 
 this.OutputGenerator = {
@@ -92,36 +94,33 @@ this.OutputGenerator = {
   /**
    * Generates output for an object.
    * @param {nsIAccessible} aAccessible accessible object to generate output
    *    for.
    * @param {PivotContext} aContext object that generates and caches
    *    context information for a given accessible and its relationship with
    *    another accessible.
    * @return {Array} Two string array. The first string describes the object
-   *    and its states. The second string is the object's name. Whether the
+   *    and its state. The second string is the object's name. Whether the
    *    object's description or it's role is included is determined by
    *    {@link roleRuleMap}.
    */
   genForObject: function genForObject(aAccessible, aContext) {
     let roleString = Utils.AccRetrieval.getStringRole(aAccessible.role);
     let func = this.objectOutputFunctions[
       OutputGenerator._getOutputName(roleString)] ||
       this.objectOutputFunctions.defaultFunc;
 
     let flags = this.roleRuleMap[roleString] || 0;
 
     if (aAccessible.childCount == 0)
       flags |= INCLUDE_NAME;
 
-    let state = {};
-    let extState = {};
-    aAccessible.getState(state, extState);
-    let states = {base: state.value, ext: extState.value};
-    return func.apply(this, [aAccessible, roleString, states, flags, aContext]);
+    return func.apply(this, [aAccessible, roleString,
+                             Utils.getState(aAccessible), flags, aContext]);
   },
 
   /**
    * Generates output for an action performed.
    * @param {nsIAccessible} aAccessible accessible object that the action was
    *    invoked in.
    * @param {string} aActionName the name of the action, one of the keys in
    *    {@link gActionMap}.
@@ -235,17 +234,17 @@ this.OutputGenerator = {
   },
 
   _getOutputName: function _getOutputName(aName) {
     return aName.replace(' ', '');
   },
 
   _getLocalizedRole: function _getLocalizedRole(aRoleStr) {},
 
-  _getLocalizedStates: function _getLocalizedStates(aStates) {},
+  _getLocalizedState: function _getLocalizedState(aState) {},
 
   _getPluralFormString: function _getPluralFormString(aString, aCount) {
     let str = gStringBundle.GetStringFromName(this._getOutputName(aString));
     str = PluralForm.get(aCount, str);
     return str.replace('#1', aCount);
   },
 
   roleRuleMap: {
@@ -314,24 +313,25 @@ this.OutputGenerator = {
     '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},
+    'definitionlist': INCLUDE_DESC | INCLUDE_NAME,
+    'dialog': INCLUDE_DESC | INCLUDE_NAME },
 
   objectOutputFunctions: {
-    _generateBaseOutput: function _generateBaseOutput(aAccessible, aRoleStr, aStates, aFlags) {
+    _generateBaseOutput: function _generateBaseOutput(aAccessible, aRoleStr, aState, aFlags) {
       let output = [];
 
       if (aFlags & INCLUDE_DESC) {
-        let desc = this._getLocalizedStates(aStates);
+        let desc = this._getLocalizedState(aState);
         let roleStr = this._getLocalizedRole(aRoleStr);
         if (roleStr) {
           this._addType(desc, aAccessible, aRoleStr);
           desc.push(roleStr);
         }
         output.push(desc.join(' '));
       }
 
@@ -344,53 +344,52 @@ this.OutputGenerator = {
       }
 
       this._addName(output, aAccessible, aFlags);
       this._addLandmark(output, aAccessible);
 
       return output;
     },
 
-    label: function label(aAccessible, aRoleStr, aStates, aFlags, aContext) {
+    label: function label(aAccessible, aRoleStr, aState, aFlags, aContext) {
       if (aContext.isNestedControl ||
           aContext.accessible == Utils.getEmbeddedControl(aAccessible)) {
         // If we are on a nested control, or a nesting label,
         // we don't need the context.
         return [];
       }
 
       return this.objectOutputFunctions.defaultFunc.apply(this, arguments);
     },
 
-    entry: function entry(aAccessible, aRoleStr, aStates, aFlags) {
-      let rolestr = (aStates.ext & Ci.nsIAccessibleStates.EXT_STATE_MULTI_LINE) ?
-            'textarea' : 'entry';
+    entry: function entry(aAccessible, aRoleStr, aState, aFlags) {
+      let rolestr = aState.contains(States.MULTI_LINE) ? 'textarea' : 'entry';
       return this.objectOutputFunctions.defaultFunc.apply(
-        this, [aAccessible, rolestr, aStates, aFlags]);
+        this, [aAccessible, rolestr, aState, aFlags]);
     },
 
-    pagetab: function pagetab(aAccessible, aRoleStr, aStates, aFlags) {
+    pagetab: function pagetab(aAccessible, aRoleStr, aState, aFlags) {
       let localizedRole = this._getLocalizedRole(aRoleStr);
       let itemno = {};
       let itemof = {};
       aAccessible.groupPosition({}, itemof, itemno);
       let output = [];
-      let desc = this._getLocalizedStates(aStates);
+      let desc = this._getLocalizedState(aState);
       desc.push(
         gStringBundle.formatStringFromName(
           'objItemOf', [localizedRole, itemno.value, itemof.value], 3));
       output.push(desc.join(' '));
 
       this._addName(output, aAccessible, aFlags);
       this._addLandmark(output, aAccessible);
 
       return output;
     },
 
-    table: function table(aAccessible, aRoleStr, aStates, aFlags) {
+    table: function table(aAccessible, aRoleStr, aState, aFlags) {
       let output = [];
       let table;
       try {
         table = aAccessible.QueryInterface(Ci.nsIAccessibleTable);
       } catch (x) {
         Logger.logException(x);
         return output;
       } finally {
@@ -494,68 +493,68 @@ this.UtteranceGenerator = {
     return [gStringBundle.GetStringFromName(
               aIsEditing ? 'editingMode' : 'navigationMode')];
   },
 
   objectOutputFunctions: {
 
     __proto__: OutputGenerator.objectOutputFunctions,
 
-    defaultFunc: function defaultFunc(aAccessible, aRoleStr, aStates, aFlags) {
+    defaultFunc: function defaultFunc(aAccessible, aRoleStr, aState, aFlags) {
       return this.objectOutputFunctions._generateBaseOutput.apply(this, arguments);
     },
 
-    heading: function heading(aAccessible, aRoleStr, aStates, aFlags) {
+    heading: function heading(aAccessible, aRoleStr, aState, aFlags) {
       let level = {};
       aAccessible.groupPosition(level, {}, {});
       let utterance =
         [gStringBundle.formatStringFromName('headingLevel', [level.value], 1)];
 
       this._addName(utterance, aAccessible, aFlags);
       this._addLandmark(utterance, aAccessible);
 
       return utterance;
     },
 
-    listitem: function listitem(aAccessible, aRoleStr, aStates, aFlags) {
+    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(gStringBundle.GetStringFromName('listStart'));
       else if (itemno.value == itemof.value) // last item
         utterance.push(gStringBundle.GetStringFromName('listEnd'));
 
       this._addName(utterance, aAccessible, aFlags);
       this._addLandmark(utterance, aAccessible);
 
       return utterance;
     },
 
-    list: function list(aAccessible, aRoleStr, aStates, aFlags) {
+    list: function list(aAccessible, aRoleStr, aState, aFlags) {
       return this._getListUtterance
         (aAccessible, aRoleStr, aFlags, aAccessible.childCount);
     },
 
-    definitionlist: function definitionlist(aAccessible, aRoleStr, aStates, aFlags) {
+    definitionlist: function definitionlist(aAccessible, aRoleStr, aState, aFlags) {
       return this._getListUtterance
         (aAccessible, aRoleStr, aFlags, aAccessible.childCount / 2);
     },
 
-    application: function application(aAccessible, aRoleStr, aStates, aFlags) {
+    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, aStates, aFlags]);
+          [aAccessible, aRoleStr, aState, aFlags]);
 
       return [];
     },
 
-    cell: function cell(aAccessible, aRoleStr, aStates, aFlags, aContext) {
+    cell: function cell(aAccessible, aRoleStr, aState, aFlags, aContext) {
       let utterance = [];
       let cell = aContext.getCellInfo(aAccessible);
       if (cell) {
         let desc = [];
         let addCellChanged = function addCellChanged(aDesc, aChanged, aString, aIndex) {
           if (aChanged) {
             aDesc.push(gStringBundle.formatStringFromName(aString,
               [aIndex + 1], 1));
@@ -607,52 +606,52 @@ this.UtteranceGenerator = {
   _getLocalizedRole: function _getLocalizedRole(aRoleStr) {
     try {
       return gStringBundle.GetStringFromName(this._getOutputName(aRoleStr));
     } catch (x) {
       return '';
     }
   },
 
-  _getLocalizedStates: function _getLocalizedStates(aStates) {
+  _getLocalizedState: function _getLocalizedState(aState) {
     let stateUtterances = [];
 
-    if (aStates.base & Ci.nsIAccessibleStates.STATE_UNAVAILABLE) {
+    if (aState.contains(States.UNAVAILABLE)) {
       stateUtterances.push(gStringBundle.GetStringFromName('stateUnavailable'));
     }
 
     // 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 && aStates.base & Ci.nsIAccessibleStates.STATE_CHECKABLE) {
-      let stateStr = (aStates.base & Ci.nsIAccessibleStates.STATE_CHECKED) ?
+    if (Utils.AndroidSdkVersion < 16 && aState.contains(States.CHECKABLE)) {
+      let statetr = aState.contains(States.CHECKED) ?
         'stateChecked' : 'stateNotChecked';
-      stateUtterances.push(gStringBundle.GetStringFromName(stateStr));
+      stateUtterances.push(gStringBundle.GetStringFromName(statetr));
     }
 
-    if (aStates.ext & Ci.nsIAccessibleStates.EXT_STATE_EXPANDABLE) {
-      let stateStr = (aStates.base & Ci.nsIAccessibleStates.STATE_EXPANDED) ?
+    if (aState.contains(States.EXPANDABLE)) {
+      let statetr = aState.contains(States.EXPANDED) ?
         'stateExpanded' : 'stateCollapsed';
-      stateUtterances.push(gStringBundle.GetStringFromName(stateStr));
+      stateUtterances.push(gStringBundle.GetStringFromName(statetr));
     }
 
-    if (aStates.base & Ci.nsIAccessibleStates.STATE_REQUIRED) {
+    if (aState.contains(States.REQUIRED)) {
       stateUtterances.push(gStringBundle.GetStringFromName('stateRequired'));
     }
 
-    if (aStates.base & Ci.nsIAccessibleStates.STATE_TRAVERSED) {
+    if (aState.contains(States.TRAVERSED)) {
       stateUtterances.push(gStringBundle.GetStringFromName('stateTraversed'));
     }
 
-    if (aStates.base & Ci.nsIAccessibleStates.STATE_HASPOPUP) {
+    if (aState.contains(States.HASPOPUP)) {
       stateUtterances.push(gStringBundle.GetStringFromName('stateHasPopup'));
     }
 
-    if (aStates.base & Ci.nsIAccessibleStates.STATE_SELECTED) {
+    if (aState.contains(States.SELECTED)) {
       stateUtterances.push(gStringBundle.GetStringFromName('stateSelected'));
     }
 
     return stateUtterances;
   },
 
   _getListUtterance: function _getListUtterance(aAccessible, aRoleStr, aFlags, aItemCount) {
     let desc = [];
@@ -673,56 +672,69 @@ this.UtteranceGenerator = {
 
 this.BrailleGenerator = {
   __proto__: OutputGenerator,
 
   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 = '*') {
+      output.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') {
+        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') {
+        addListitemIndicator();
+      } else {
+        addListitemIndicator(acc.firstChild.name.trim());
+      }
+    }
+
     if (acc instanceof Ci.nsIAccessibleText) {
       output.endOffset = this.outputOrder === OUTPUT_DESC_FIRST ?
                          output.output.join(' ').length : acc.characterCount;
       output.startOffset = output.endOffset - acc.characterCount;
     }
 
     return output;
   },
 
   objectOutputFunctions: {
 
     __proto__: OutputGenerator.objectOutputFunctions,
 
-    defaultFunc: function defaultFunc(aAccessible, aRoleStr, aStates, aFlags) {
-      let braille = this.objectOutputFunctions._generateBaseOutput.apply(this, arguments);
-
-      if (aAccessible.indexInParent === 1 &&
-          aAccessible.parent.role == Roles.LISTITEM &&
-          aAccessible.previousSibling.role == Roles.STATICTEXT) {
-        if (aAccessible.parent.parent && aAccessible.parent.parent.DOMNode &&
-            aAccessible.parent.parent.DOMNode.nodeName == 'UL') {
-          braille.unshift('*');
-        } else {
-          braille.unshift(aAccessible.previousSibling.name);
-        }
-      }
-
-      return braille;
+    defaultFunc: function defaultFunc(aAccessible, aRoleStr, aState, aFlags) {
+      return this.objectOutputFunctions._generateBaseOutput.apply(this, arguments);
     },
 
-    listitem: function listitem(aAccessible, aRoleStr, aStates, aFlags) {
+    listitem: function listitem(aAccessible, aRoleStr, aState, aFlags) {
       let braille = [];
 
       this._addName(braille, aAccessible, aFlags);
       this._addLandmark(braille, aAccessible);
 
       return braille;
     },
 
-    cell: function cell(aAccessible, aRoleStr, aStates, aFlags, aContext) {
+    cell: function cell(aAccessible, aRoleStr, aState, aFlags, aContext) {
       let braille = [];
       let cell = aContext.getCellInfo(aAccessible);
       if (cell) {
         let desc = [];
         let addHeaders = function addHeaders(aDesc, aHeaders) {
           if (aHeaders.length > 0) {
             aDesc.push.apply(aDesc, aHeaders);
           }
@@ -745,47 +757,47 @@ this.BrailleGenerator = {
     columnheader: function columnheader() {
       return this.objectOutputFunctions.cell.apply(this, arguments);
     },
 
     rowheader: function rowheader() {
       return this.objectOutputFunctions.cell.apply(this, arguments);
     },
 
-    statictext: function statictext(aAccessible, aRoleStr, aStates, aFlags) {
+    statictext: function statictext(aAccessible, aRoleStr, aState, aFlags) {
       // Since we customize the list bullet's output, we add the static
       // text from the first node in each listitem, so skip it here.
       if (aAccessible.parent.role == Roles.LISTITEM) {
         return [];
       }
 
       return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
     },
 
-    _useStateNotRole: function _useStateNotRole(aAccessible, aRoleStr, aStates, aFlags) {
+    _useStateNotRole: function _useStateNotRole(aAccessible, aRoleStr, aState, aFlags) {
       let braille = [];
 
-      let desc = this._getLocalizedStates(aStates);
+      let desc = this._getLocalizedState(aState);
       braille.push(desc.join(' '));
 
       this._addName(braille, aAccessible, aFlags);
       this._addLandmark(braille, aAccessible);
 
       return braille;
     },
 
-    checkbutton: function checkbutton(aAccessible, aRoleStr, aStates, aFlags) {
+    checkbutton: function checkbutton(aAccessible, aRoleStr, aState, aFlags) {
       return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
     },
 
-    radiobutton: function radiobutton(aAccessible, aRoleStr, aStates, aFlags) {
+    radiobutton: function radiobutton(aAccessible, aRoleStr, aState, aFlags) {
       return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
     },
 
-    togglebutton: function radiobutton(aAccessible, aRoleStr, aStates, aFlags) {
+    togglebutton: function radiobutton(aAccessible, aRoleStr, aState, aFlags) {
       return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
     }
   },
 
   _getContextStart: function _getContextStart(aContext) {
     if (aContext.accessible.parent.role == Roles.LINK) {
       return [aContext.accessible.parent];
     }
@@ -805,32 +817,32 @@ this.BrailleGenerator = {
         return gStringBundle.GetStringFromName(
           OutputGenerator._getOutputName(aRoleStr));
       } catch (y) {
         return '';
       }
     }
   },
 
-  _getLocalizedStates: function _getLocalizedStates(aStates) {
+  _getLocalizedState: function _getLocalizedState(aState) {
     let stateBraille = [];
 
     let getCheckedState = function getCheckedState() {
       let resultMarker = [];
-      let state = aStates.base;
-      let fill = !!(state & Ci.nsIAccessibleStates.STATE_CHECKED) ||
-                 !!(state & Ci.nsIAccessibleStates.STATE_PRESSED);
+      let state = aState;
+      let fill = state.contains(States.CHECKED) ||
+        state.contains(States.PRESSED);
 
       resultMarker.push('(');
       resultMarker.push(fill ? 'x' : ' ');
       resultMarker.push(')');
 
       return resultMarker.join('');
     };
 
-    if (aStates.base & Ci.nsIAccessibleStates.STATE_CHECKABLE) {
+    if (aState.contains(States.CHECKABLE)) {
       stateBraille.push(getCheckedState());
     }
 
     return stateBraille;
   }
 
 };
--- a/accessible/src/jsat/Presentation.jsm
+++ b/accessible/src/jsat/Presentation.jsm
@@ -17,16 +17,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, 'PivotContext',
   'resource://gre/modules/accessibility/Utils.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'UtteranceGenerator',
   'resource://gre/modules/accessibility/OutputGenerator.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'BrailleGenerator',
   'resource://gre/modules/accessibility/OutputGenerator.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
   'resource://gre/modules/accessibility/Constants.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'States',
+  'resource://gre/modules/accessibility/Constants.jsm');
 
 this.EXPORTED_SYMBOLS = ['Presentation'];
 
 /**
  * The interface for all presenter classes. A presenter could be, for example,
  * a speech output module, or a visual cursor indicator.
  */
 function Presenter() {}
@@ -279,49 +281,47 @@ AndroidPresenter.prototype = {
         androidEvents.push({
           eventType: this.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
           text: [adjustedText.text],
           fromIndex: adjustedText.startOffset,
           toIndex: adjustedText.endOffset
         });
       }
     } else {
-      let state = Utils.getStates(aContext.accessible)[0];
+      let state = Utils.getState(aContext.accessible);
       androidEvents.push({eventType: (isExploreByTouch) ?
                            this.ANDROID_VIEW_HOVER_ENTER : focusEventType,
                          text: UtteranceGenerator.genForContext(aContext).output,
                          bounds: aContext.bounds,
                          clickable: aContext.accessible.actionCount > 0,
-                         checkable: !!(state &
-                                       Ci.nsIAccessibleStates.STATE_CHECKABLE),
-                         checked: !!(state &
-                                     Ci.nsIAccessibleStates.STATE_CHECKED),
+                         checkable: state.contains(States.CHECKABLE),
+                         checked: state.contains(States.CHECKED),
                          brailleOutput: brailleOutput});
     }
 
 
     return {
       type: this.type,
       details: androidEvents
     };
   },
 
   actionInvoked: function AndroidPresenter_actionInvoked(aObject, aActionName) {
-    let state = Utils.getStates(aObject)[0];
+    let state = Utils.getState(aObject);
 
     // Checkable objects will have a state changed event we will use instead.
-    if (state & Ci.nsIAccessibleStates.STATE_CHECKABLE)
+    if (state.contains(States.CHECKABLE))
       return null;
 
     return {
       type: this.type,
       details: [{
         eventType: this.ANDROID_VIEW_CLICKED,
         text: UtteranceGenerator.genForAction(aObject, aActionName),
-        checked: !!(state & Ci.nsIAccessibleStates.STATE_CHECKED)
+        checked: state.contains(States.CHECKED)
       }]
     };
   },
 
   tabSelected: function AndroidPresenter_tabSelected(aDocContext, aVCContext) {
     // Send a pivot change message with the full context utterance for this doc.
     return this.pivotChanged(aVCContext, Ci.nsIAccessiblePivot.REASON_NONE);
   },
--- a/accessible/src/jsat/TraversalRules.jsm
+++ b/accessible/src/jsat/TraversalRules.jsm
@@ -12,39 +12,37 @@ const Cr = Components.results;
 this.EXPORTED_SYMBOLS = ['TraversalRules'];
 
 Cu.import('resource://gre/modules/accessibility/Utils.jsm');
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
   'resource://gre/modules/accessibility/Constants.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Filters',
   'resource://gre/modules/accessibility/Constants.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'States',
+  'resource://gre/modules/accessibility/Constants.jsm');
 
 let gSkipEmptyImages = new PrefCache('accessibility.accessfu.skip_empty_images');
 
-function BaseTraversalRule(aRoles, aMatchFunc) {
+function BaseTraversalRule(aRoles, aMatchFunc, aPreFilter) {
   this._explicitMatchRoles = new Set(aRoles);
   this._matchRoles = aRoles;
   if (aRoles.indexOf(Roles.LABEL) < 0) {
     this._matchRoles.push(Roles.LABEL);
   }
   this._matchFunc = aMatchFunc || function (acc) { return Filters.MATCH; };
+  this.preFilter = aPreFilter || gSimplePreFilter;
 }
 
 BaseTraversalRule.prototype = {
     getMatchRoles: function BaseTraversalRule_getmatchRoles(aRules) {
       aRules.value = this._matchRoles;
       return aRules.value.length;
     },
 
-    preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
-    Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE |
-    Ci.nsIAccessibleTraversalRule.PREFILTER_ARIA_HIDDEN |
-    Ci.nsIAccessibleTraversalRule.PREFILTER_TRANSPARENT,
-
     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;
       }
 
@@ -89,79 +87,88 @@ var gSimpleTraversalRoles =
    Roles.HEADER,
    Roles.HEADING,
    Roles.SLIDER,
    Roles.SPINBUTTON,
    Roles.OPTION,
    // Used for traversing in to child OOP frames.
    Roles.INTERNAL_FRAME];
 
-this.TraversalRules = {
-  Simple: new BaseTraversalRule(
-    gSimpleTraversalRoles,
-    function Simple_match(aAccessible) {
-      function hasZeroOrSingleChildDescendants () {
-        for (let acc = aAccessible; acc.childCount > 0; acc = acc.firstChild) {
-          if (acc.childCount > 1) {
-            return false;
-          }
-        }
-
-        return true;
-      }
-
-      switch (aAccessible.role) {
-      case Roles.COMBOBOX:
-        // We don't want to ignore the subtree because this is often
-        // where the list box hangs out.
-        return Filters.MATCH;
-      case Roles.TEXT_LEAF:
-        {
-          // Nameless text leaves are boring, skip them.
-          let name = aAccessible.name;
-          if (name && name.trim())
-            return Filters.MATCH;
-          else
-            return Filters.IGNORE;
-        }
-      case Roles.STATICTEXT:
-        {
-          let parent = aAccessible.parent;
-          // Ignore prefix static text in list items. They are typically bullets or numbers.
-          if (parent.childCount > 1 && aAccessible.indexInParent == 0 &&
-              parent.role == Roles.LISTITEM)
-            return Filters.IGNORE;
-
-          return Filters.MATCH;
-        }
-      case Roles.GRAPHIC:
-        return TraversalRules._shouldSkipImage(aAccessible);
-      case Roles.LINK:
-      case Roles.HEADER:
-      case Roles.HEADING:
-        return hasZeroOrSingleChildDescendants() ?
-          (Filters.MATCH | Filters.IGNORE_SUBTREE) : (Filters.IGNORE);
-      default:
-        // Ignore the subtree, if there is one. So that we don't land on
-        // the same content that was already presented by its parent.
-        return Filters.MATCH |
-          Filters.IGNORE_SUBTREE;
+var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
+  function hasZeroOrSingleChildDescendants () {
+    for (let acc = aAccessible; acc.childCount > 0; acc = acc.firstChild) {
+      if (acc.childCount > 1) {
+        return false;
       }
     }
-  ),
+
+    return true;
+  }
+
+  switch (aAccessible.role) {
+  case Roles.COMBOBOX:
+    // We don't want to ignore the subtree because this is often
+    // where the list box hangs out.
+    return Filters.MATCH;
+  case Roles.TEXT_LEAF:
+    {
+      // Nameless text leaves are boring, skip them.
+      let name = aAccessible.name;
+      if (name && name.trim())
+        return Filters.MATCH;
+      else
+        return Filters.IGNORE;
+    }
+  case Roles.STATICTEXT:
+    {
+      let parent = aAccessible.parent;
+      // Ignore prefix static text in list items. They are typically bullets or numbers.
+      if (parent.childCount > 1 && aAccessible.indexInParent == 0 &&
+          parent.role == Roles.LISTITEM)
+        return Filters.IGNORE;
+
+      return Filters.MATCH;
+    }
+  case Roles.GRAPHIC:
+    return TraversalRules._shouldSkipImage(aAccessible);
+  case Roles.LINK:
+  case Roles.HEADER:
+  case Roles.HEADING:
+    return hasZeroOrSingleChildDescendants() ?
+      (Filters.MATCH | Filters.IGNORE_SUBTREE) : (Filters.IGNORE);
+  default:
+    // Ignore the subtree, if there is one. So that we don't land on
+    // the same content that was already presented by its parent.
+    return Filters.MATCH |
+      Filters.IGNORE_SUBTREE;
+  }
+};
+
+var gSimplePreFilter = Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
+  Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE |
+  Ci.nsIAccessibleTraversalRule.PREFILTER_ARIA_HIDDEN |
+  Ci.nsIAccessibleTraversalRule.PREFILTER_TRANSPARENT;
+
+this.TraversalRules = {
+  Simple: new BaseTraversalRule(gSimpleTraversalRoles, gSimpleMatchFunc),
+
+  SimpleOnScreen: new BaseTraversalRule(
+    gSimpleTraversalRoles, gSimpleMatchFunc,
+    Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
+      Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE |
+      Ci.nsIAccessibleTraversalRule.PREFILTER_ARIA_HIDDEN |
+      Ci.nsIAccessibleTraversalRule.PREFILTER_TRANSPARENT |
+      Ci.nsIAccessibleTraversalRule.PREFILTER_OFFSCREEN),
 
   Anchor: new BaseTraversalRule(
     [Roles.LINK],
     function Anchor_match(aAccessible)
     {
       // We want to ignore links, only focus named anchors.
-      let state = {};
-      let extraState = {};
-      aAccessible.getState(state, extraState);
-      if (state.value & Ci.nsIAccessibleStates.STATE_LINKED) {
+      if (Utils.getState(aAccessible).contains(States.LINKED)) {
         return Filters.IGNORE;
       } else {
         return Filters.MATCH;
       }
     }),
 
   Button: new BaseTraversalRule(
     [Roles.PUSHBUTTON,
@@ -216,20 +223,17 @@ this.TraversalRules = {
     [Roles.LISTITEM,
      Roles.TERM]),
 
   Link: new BaseTraversalRule(
     [Roles.LINK],
     function Link_match(aAccessible)
     {
       // We want to ignore anchors, only focus real links.
-      let state = {};
-      let extraState = {};
-      aAccessible.getState(state, extraState);
-      if (state.value & Ci.nsIAccessibleStates.STATE_LINKED) {
+      if (Utils.getState(aAccessible).contains(States.LINKED)) {
         return Filters.MATCH;
       } else {
         return Filters.IGNORE;
       }
     }),
 
   List: new BaseTraversalRule(
     [Roles.LIST,
--- a/accessible/src/jsat/Utils.jsm
+++ b/accessible/src/jsat/Utils.jsm
@@ -14,18 +14,20 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, 'Rect',
   'resource://gre/modules/Geometry.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
   'resource://gre/modules/accessibility/Constants.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Events',
   'resource://gre/modules/accessibility/Constants.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Relations',
   'resource://gre/modules/accessibility/Constants.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'States',
+  'resource://gre/modules/accessibility/Constants.jsm');
 
-this.EXPORTED_SYMBOLS = ['Utils', 'Logger', 'PivotContext', 'PrefCache'];
+this.EXPORTED_SYMBOLS = ['Utils', 'Logger', 'PivotContext', 'PrefCache', 'SettingCache'];
 
 this.Utils = {
   _buildAppMap: {
     '{3c2e2abc-06d4-11e1-ac3b-374f68613e61}': 'b2g',
     '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}': 'browser',
     '{aa3c5121-dab2-40e2-81ca-7ea25febc110}': 'mobile/android',
     '{a23983c0-fd0e-11dc-95ff-0800200c9a66}': 'mobile/xul'
   },
@@ -181,24 +183,46 @@ this.Utils = {
     switch (this.MozBuildApp) {
       case 'mobile/android':
         return aWindow.BrowserApp.selectedTab.getViewport();
       default:
         return null;
     }
   },
 
-  getStates: function getStates(aAccessible) {
-    if (!aAccessible)
-      return [0, 0];
+  getState: function getState(aAccessibleOrEvent) {
+    function State(aBase, aExtended) {
+      this.base = aBase;
+      this.extended = aExtended;
+
+      this.contains = (other) => {
+        return !!(this.base & other.base || this.extended & other.extended);
+      };
 
-    let state = {};
-    let extState = {};
-    aAccessible.getState(state, extState);
-    return [state.value, extState.value];
+      this.toString = () => {
+        let stateStrings = Utils.AccRetrieval.
+          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(', ') + ']';
+      };
+    }
+
+    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();
 
@@ -240,27 +264,25 @@ this.Utils = {
       let hidden = Utils.getAttributes(acc).hidden;
       if (hidden && JSON.parse(hidden)) {
         return true;
       }
     }
     return false;
   },
 
-  isAliveAndVisible: function isAliveAndVisible(aAccessible) {
+  isAliveAndVisible: function isAliveAndVisible(aAccessible, aIsOnScreen) {
     if (!aAccessible) {
       return false;
     }
 
     try {
-      let extstate = {};
-      let state = {};
-      aAccessible.getState(state, extstate);
-      if (extstate.value & Ci.nsIAccessibleStates.EXT_STATE_DEFUNCT ||
-          state.value & Ci.nsIAccessibleStates.STATE_INVISIBLE ||
+      let state = this.getState(aAccessible);
+      if (state.contains(States.DEFUNCT) || state.contains(States.INVISIBLE) ||
+          (aIsOnScreen && state.contains(States.OFFSCREEN)) ||
           Utils.inHiddenSubtree(aAccessible)) {
         return false;
       }
     } catch (x) {
       return false;
     }
 
     return true;
@@ -404,22 +426,17 @@ this.Logger = {
         Utils.AccRetrieval.getStringStates(event.state, 0);
       str += ' (' + stateStrings.item(0) + ')';
     }
 
     return str;
   },
 
   statesToString: function statesToString(aAccessible) {
-    let [state, extState] = Utils.getStates(aAccessible);
-    let stringArray = [];
-    let stateStrings = Utils.AccRetrieval.getStringStates(state, extState);
-    for (var i=0; i < stateStrings.length; i++)
-      stringArray.push(stateStrings.item(i));
-    return stringArray.join(' ');
+    return Utils.getState(aAccessible).toString();
   },
 
   dumpTree: function dumpTree(aLogLevel, aRootAccessible) {
     if (aLogLevel < this.logLevel)
       return;
 
     this._dumpTreeInternal(aLogLevel, aRootAccessible, 0);
   },
@@ -582,18 +599,17 @@ PivotContext.prototype = {
       return;
     }
     let child = aAccessible.firstChild;
     while (child) {
       let include;
       if (this._includeInvisible) {
         include = true;
       } else {
-        let [state,] = Utils.getStates(child);
-        include = !(state & Ci.nsIAccessibleStates.STATE_INVISIBLE);
+        include = !(Utils.getState(child).contains(States.INVISIBLE));
       }
       if (include) {
         if (aPreorder) {
           yield child;
           [yield node for (node of this._traverse(child, aPreorder, aStop))];
         } else {
           [yield node for (node of this._traverse(child, aPreorder, aStop))];
           yield child;
@@ -711,19 +727,17 @@ PivotContext.prototype = {
       this._bounds = Utils.getBounds(this.accessibleForBounds);
     }
 
     return this._bounds.clone();
   },
 
   _isDefunct: function _isDefunct(aAccessible) {
     try {
-      let extstate = {};
-      aAccessible.getState({}, extstate);
-      return !!(extstate.value & Ci.nsIAccessibleStates.EXT_STATE_DEFUNCT);
+      return Utils.getState(aAccessible).contains(States.DEFUNCT);
     } catch (x) {
       return true;
     }
   }
 };
 
 this.PrefCache = function PrefCache(aName, aCallback, aRunCallbackNow) {
   this.name = aName;
@@ -769,8 +783,45 @@ PrefCache.prototype = {
         Logger.logException(x);
       }
     }
   },
 
   QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver,
                                           Ci.nsISupportsWeakReference])
 };
+
+this.SettingCache = function SettingCache(aName, aCallback, aOptions = {}) {
+  this.value = aOptions.defaultValue;
+  let runCallback = () => {
+    if (aCallback) {
+      aCallback(aName, this.value);
+      if (aOptions.callbackOnce) {
+        runCallback = () => {};
+      }
+    }
+  };
+
+  let settings = Utils.win.navigator.mozSettings;
+  if (!settings) {
+    if (aOptions.callbackNow) {
+      runCallback();
+    }
+    return;
+  }
+
+
+  let lock = settings.createLock();
+  let req = lock.get(aName);
+
+  req.addEventListener('success', () => {
+    this.value = req.result[aName] == undefined ? aOptions.defaultValue : req.result[aName];
+    if (aOptions.callbackNow) {
+      runCallback();
+    }
+  });
+
+  settings.addObserver(aName,
+                       (evt) => {
+                         this.value = evt.settingValue;
+                         runCallback();
+                       });
+};
--- a/accessible/src/jsat/content-script.js
+++ b/accessible/src/jsat/content-script.js
@@ -15,18 +15,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, 'Presentation',
   'resource://gre/modules/accessibility/Presentation.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'TraversalRules',
   'resource://gre/modules/accessibility/TraversalRules.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Utils',
   'resource://gre/modules/accessibility/Utils.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'EventManager',
   'resource://gre/modules/accessibility/EventManager.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'ObjectWrapper',
-  'resource://gre/modules/ObjectWrapper.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
   'resource://gre/modules/accessibility/Constants.jsm');
 
 Logger.debug('content-script.js');
 
 let eventManager = null;
 
 function moveCursor(aMessage) {
@@ -158,19 +156,24 @@ function forwardToChild(aMessage, aListe
   }
   mm.sendAsyncMessage(aMessage.name, newJSON);
   return true;
 }
 
 function activateCurrent(aMessage) {
   Logger.debug('activateCurrent');
   function activateAccessible(aAccessible) {
-    if (aMessage.json.activateIfKey &&
-        aAccessible.role != Roles.KEY) {
-      // Only activate keys, don't do anything on other objects.
+    try {
+      if (aMessage.json.activateIfKey &&
+          aAccessible.role != Roles.KEY) {
+        // Only activate keys, don't do anything on other objects.
+        return;
+      }
+    } catch (e) {
+      // accessible is invalid. Silently fail.
       return;
     }
 
     if (aAccessible.actionCount > 0) {
       aAccessible.doAction(0);
     } else {
       let control = Utils.getEmbeddedControl(aAccessible);
       if (control && control.actionCount > 0) {
@@ -333,23 +336,32 @@ function scroll(aMessage) {
   let position = Utils.getVirtualCursor(content.document).position;
   if (!forwardToChild(aMessage, scroll, position)) {
     sendScrollCoordinates(position);
   }
 }
 
 function adjustRange(aMessage) {
   function sendUpDownKey(aAccessible) {
-    let evt = content.document.createEvent('KeyboardEvent');
-    let keycode = aMessage.json.direction == 'forward' ?
-      content.KeyEvent.DOM_VK_DOWN : content.KeyEvent.DOM_VK_UP;
-    evt.initKeyEvent(
-      "keypress", false, true, null, false, false, false, false, keycode, 0);
-    if (aAccessible.DOMNode) {
-      aAccessible.DOMNode.dispatchEvent(evt);
+    let acc = Utils.getEmbeddedControl(aAccessible) || aAccessible;
+    let elem = acc.DOMNode;
+    if (elem) {
+      if (elem.tagName === 'INPUT' && elem.type === 'range') {
+        elem[aMessage.json.direction === 'forward' ? 'stepDown' : 'stepUp']();
+        let changeEvent = content.document.createEvent('UIEvent');
+        changeEvent.initEvent('change', true, true);
+        elem.dispatchEvent(changeEvent);
+      } else {
+        let evt = content.document.createEvent('KeyboardEvent');
+        let keycode = aMessage.json.direction == 'forward' ?
+              content.KeyEvent.DOM_VK_DOWN : content.KeyEvent.DOM_VK_UP;
+        evt.initKeyEvent(
+          "keypress", false, true, null, false, false, false, false, keycode, 0);
+        elem.dispatchEvent(evt);
+      }
     }
   }
 
   let position = Utils.getVirtualCursor(content.document).position;
   if (!forwardToChild(aMessage, adjustRange, position)) {
     sendUpDownKey(position);
   }
 }
--- a/accessible/src/jsat/moz.build
+++ b/accessible/src/jsat/moz.build
@@ -11,8 +11,10 @@ EXTRA_JS_MODULES += [
     'Constants.jsm',
     'EventManager.jsm',
     'OutputGenerator.jsm',
     'Presentation.jsm',
     'TouchAdapter.jsm',
     'TraversalRules.jsm',
     'Utils.jsm'
 ]
+
+JAR_MANIFESTS += ['jar.mn']
\ No newline at end of file
--- a/accessible/src/windows/ia2/moz.build
+++ b/accessible/src/windows/ia2/moz.build
@@ -10,29 +10,34 @@ EXPORTS += [
     'ia2AccessibleComponent.h',
     'ia2AccessibleEditableText.h',
     'ia2AccessibleHyperlink.h',
     'ia2AccessibleHypertext.h',
     'ia2AccessibleText.h',
     'ia2AccessibleValue.h',
 ]
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'ia2Accessible.cpp',
     'ia2AccessibleAction.cpp',
     'ia2AccessibleComponent.cpp',
     'ia2AccessibleEditableText.cpp',
     'ia2AccessibleHyperlink.cpp',
     'ia2AccessibleHypertext.cpp',
     'ia2AccessibleImage.cpp',
     'ia2AccessibleRelation.cpp',
+    'ia2AccessibleText.cpp',
+    'ia2AccessibleValue.cpp',
+]
+
+# These files cannot be built in unified mode because they both include
+# AccessibleTable2_i.c.
+SOURCES += [
     'ia2AccessibleTable.cpp',
     'ia2AccessibleTableCell.cpp',
-    'ia2AccessibleText.cpp',
-    'ia2AccessibleValue.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '../../base',
     '../../generic',
     '../../html',
     '../../xpcom',
     '../../xul',
--- a/accessible/src/windows/msaa/moz.build
+++ b/accessible/src/windows/msaa/moz.build
@@ -9,45 +9,49 @@ EXPORTS += [
 ]
 
 EXPORTS.mozilla.a11y += [
     'AccessibleWrap.h',
     'Compatibility.h',
     'HyperTextAccessibleWrap.h',
 ]
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'AccessibleWrap.cpp',
     'ApplicationAccessibleWrap.cpp',
     'ARIAGridAccessibleWrap.cpp',
     'Compatibility.cpp',
     'DocAccessibleWrap.cpp',
     'EnumVariant.cpp',
     'HTMLTableAccessibleWrap.cpp',
     'HTMLWin32ObjectAccessible.cpp',
     'HyperTextAccessibleWrap.cpp',
     'ImageAccessibleWrap.cpp',
     'IUnknownImpl.cpp',
     'nsWinUtils.cpp',
     'Platform.cpp',
     'RootAccessibleWrap.cpp',
-    'ServiceProvider.cpp',
     'TextLeafAccessibleWrap.cpp',
 ]
 
+# This file cannot be built in unified mode because it includes ISimpleDOMNode_i.c.
+SOURCES += [
+    'ServiceProvider.cpp',
+]
+
 if CONFIG['MOZ_XUL']:
-    SOURCES += [
+    UNIFIED_SOURCES += [
         'XULListboxAccessibleWrap.cpp',
         'XULMenuAccessibleWrap.cpp',
         'XULTreeGridAccessibleWrap.cpp',
     ]
 
 LOCAL_INCLUDES += [
     '../../../../content/base/src',
-    '../../../../content/events/src',
+    '../../../../dom/events',
     '../../base',
     '../../generic',
     '../../html',
     '../../xpcom',
     '../../xul',
     '../ia2',
     '../sdn',
     '../uia',
--- a/accessible/src/windows/msaa/nsWinUtils.cpp
+++ b/accessible/src/windows/msaa/nsWinUtils.cpp
@@ -11,16 +11,17 @@
 #include "DocAccessible.h"
 #include "nsCoreUtils.h"
 
 #include "mozilla/Preferences.h"
 #include "nsArrayUtils.h"
 #include "nsIArray.h"
 #include "nsIDocument.h"
 #include "nsIDocShellTreeItem.h"
+#include "nsIXULRuntime.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 // Window property used by ipc related code in identifying accessible
 // tab windows.
 const wchar_t* kPropNameTabContent = L"AccessibleTabWindow";
 
@@ -53,17 +54,17 @@ nsWinUtils::GetComputedStyleDeclaration(
 
 bool
 nsWinUtils::MaybeStartWindowEmulation()
 {
   // Register window class that'll be used for document accessibles associated
   // with tabs.
   if (Compatibility::IsJAWS() || Compatibility::IsWE() ||
       Compatibility::IsDolphin() ||
-      Preferences::GetBool("browser.tabs.remote")) {
+      BrowserTabsRemote()) {
     RegisterNativeWindow(kClassNameTabContent);
     sHWNDCache = new nsRefPtrHashtable<nsPtrHashKey<void>, DocAccessible>(4);
     return true;
   }
 
   return false;
 }
 
--- a/accessible/src/windows/sdn/moz.build
+++ b/accessible/src/windows/sdn/moz.build
@@ -1,15 +1,15 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-SOURCES += [
+UNIFIED_SOURCES += [
     'sdnAccessible.cpp',
     'sdnDocAccessible.cpp',
     'sdnTextAccessible.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '../../base',
     '../../generic',
--- a/accessible/src/xpcom/xpcAccessibleHyperText.cpp
+++ b/accessible/src/xpcom/xpcAccessibleHyperText.cpp
@@ -123,32 +123,27 @@ xpcAccessibleHyperText::GetTextAfterOffs
     return NS_ERROR_FAILURE;
 
   text->TextAfterOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, aText);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetCharacterAtOffset(int32_t aOffset,
-                                             PRUnichar* aCharacter)
+                                             char16_t* aCharacter)
 {
   NS_ENSURE_ARG_POINTER(aCharacter);
   *aCharacter = L'\0';
 
   HyperTextAccessible* text = static_cast<HyperTextAccessible*>(this);
   if (text->IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAutoString character;
-  if (text->GetCharAt(aOffset, eGetAt, character)) {
-    *aCharacter = character.First();
-    return NS_OK;
-  }
-
-  return NS_ERROR_INVALID_ARG;
+  *aCharacter = text->CharAt(aOffset);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetTextAttributes(bool aIncludeDefAttrs,
                                           int32_t aOffset,
                                           int32_t* aStartOffset,
                                           int32_t* aEndOffset,
                                           nsIPersistentProperties** aAttributes)
--- a/accessible/src/xul/XULTabAccessible.cpp
+++ b/accessible/src/xul/XULTabAccessible.cpp
@@ -8,17 +8,16 @@
 #include "nsAccUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "States.h"
 
 // NOTE: alphabetically ordered
 #include "nsIAccessibleRelation.h"
 #include "nsIDocument.h"
-#include "nsIDOMDocument.h"
 #include "nsIDOMXULSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsIDOMXULRelatedElement.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTabAccessible
--- a/accessible/src/xul/XULTabAccessible.h
+++ b/accessible/src/xul/XULTabAccessible.h
@@ -70,20 +70,17 @@ public:
     { mType = eXULTabpanelsType; }
 
   // Accessible
   virtual a11y::role NativeRole();
 };
 
 
 /**
- * A tabpanel object, child elements of xul:tabpanels element. Note,the object
- * is created from nsAccessibilityService::GetAccessibleForDeckChildren()
- * method and we do not use nsIAccessibleProvider interface here because
- * all children of xul:tabpanels element acts as xul:tabpanel element.
+ * A tabpanel object, child elements of xul:tabpanels element.
  *
  * XXX: we need to move the class logic into generic class since
  * for example we do not create instance of this class for XUL textbox used as
  * a tabpanel.
  */
 class XULTabpanelAccessible : public AccessibleWrap
 {
 public:
--- a/accessible/src/xul/XULTreeAccessible.cpp
+++ b/accessible/src/xul/XULTreeAccessible.cpp
@@ -409,17 +409,17 @@ XULTreeAccessible::SelectAll()
 
   return false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeAccessible: Accessible implementation
 
 Accessible*
-XULTreeAccessible::GetChildAt(uint32_t aIndex)
+XULTreeAccessible::GetChildAt(uint32_t aIndex) const
 {
   uint32_t childCount = Accessible::ChildCount();
   if (aIndex < childCount)
     return Accessible::GetChildAt(aIndex);
 
   return GetTreeItemAccessible(aIndex - childCount);
 }
 
@@ -517,17 +517,17 @@ XULTreeAccessible::ContainerWidget() con
   }
   return nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeAccessible: public implementation
 
 Accessible*
-XULTreeAccessible::GetTreeItemAccessible(int32_t aRow)
+XULTreeAccessible::GetTreeItemAccessible(int32_t aRow) const
 {
   if (aRow < 0 || IsDefunct() || !mTreeView)
     return nullptr;
 
   int32_t rowCount = 0;
   nsresult rv = mTreeView->GetRowCount(&rowCount);
   if (NS_FAILED(rv) || aRow >= rowCount)
     return nullptr;
@@ -674,20 +674,21 @@ XULTreeAccessible::TreeViewChanged(nsITr
   ClearCache(mAccessibleCache);
   mTreeView = aView;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeAccessible: protected implementation
 
 already_AddRefed<Accessible>
-XULTreeAccessible::CreateTreeItemAccessible(int32_t aRow)
+XULTreeAccessible::CreateTreeItemAccessible(int32_t aRow) const
 {
   nsRefPtr<Accessible> accessible =
-    new XULTreeItemAccessible(mContent, mDoc, this, mTree, mTreeView, aRow);
+    new XULTreeItemAccessible(mContent, mDoc, const_cast<XULTreeAccessible*>(this),
+                              mTree, mTreeView, aRow);
 
   return accessible.forget();
 }
                              
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeItemAccessibleBase
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/accessible/src/xul/XULTreeAccessible.h
+++ b/accessible/src/xul/XULTreeAccessible.h
@@ -41,18 +41,18 @@ public:
   // Accessible
   virtual void Shutdown();
   virtual void Value(nsString& aValue);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild);
 
-  virtual Accessible* GetChildAt(uint32_t aIndex);
-  virtual uint32_t ChildCount() const;
+  virtual Accessible* GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE;
+  virtual uint32_t ChildCount() const MOZ_OVERRIDE;
   virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
   // SelectAccessible
   virtual already_AddRefed<nsIArray> SelectedItems();
   virtual uint32_t SelectedItemCount();
   virtual Accessible* GetSelectedItem(uint32_t aIndex);
   virtual bool IsItemSelected(uint32_t aIndex);
   virtual bool AddItemToSelection(uint32_t aIndex);
@@ -72,17 +72,17 @@ public:
   // XULTreeAccessible
 
   /**
    * Return tree item accessible at the givem row. If accessible doesn't exist
    * in the cache then create and cache it.
    *
    * @param aRow         [in] the given row index
    */
-  Accessible* GetTreeItemAccessible(int32_t aRow);
+  Accessible* GetTreeItemAccessible(int32_t aRow) const;
 
   /**
    * Invalidates the number of cached treeitem accessibles.
    *
    * @param aRow    [in] row index the invalidation starts from
    * @param aCount  [in] the number of treeitem accessibles to invalidate,
    *                 the number sign specifies whether rows have been
    *                 inserted (plus) or removed (minus)
@@ -105,21 +105,22 @@ public:
    * Invalidates children created for previous tree view.
    */
   void TreeViewChanged(nsITreeView* aView);
 
 protected:
   /**
    * Creates tree item accessible for the given row index.
    */
-  virtual already_AddRefed<Accessible> CreateTreeItemAccessible(int32_t aRow);
+  virtual already_AddRefed<Accessible>
+    CreateTreeItemAccessible(int32_t aRow) const;
 
   nsCOMPtr<nsITreeBoxObject> mTree;
   nsITreeView* mTreeView;
-  AccessibleHashtable mAccessibleCache;
+  mutable AccessibleHashtable mAccessibleCache;
 };
 
 /**
  * Base class for tree item accessibles.
  */
 
 #define XULTREEITEMBASEACCESSIBLE_IMPL_CID            \
 {  /* 1ab79ae7-766a-443c-940b-b1e6b0831dfc */         \
@@ -175,17 +176,17 @@ public:
    * Return row index associated with the accessible.
    */
   int32_t GetRowIndex() const { return mRow; }
 
   /**
    * Return cell accessible for the given column. If XUL tree accessible is not
    * accessible table then return null.
    */
-  virtual Accessible* GetCellAccessible(nsITreeColumn* aColumn)
+  virtual Accessible* GetCellAccessible(nsITreeColumn* aColumn) const
     { return nullptr; }
 
   /**
    * Proccess row invalidation. Used to fires name change events.
    */
   virtual void RowInvalidated(int32_t aStartColIdx, int32_t aEndColIdx) = 0;
 
 protected:
--- a/accessible/src/xul/XULTreeGridAccessible.cpp
+++ b/accessible/src/xul/XULTreeGridAccessible.cpp
@@ -232,20 +232,22 @@ XULTreeGridAccessible::NativeRole()
 
   return primaryColumn ? roles::TREE_TABLE : roles::TABLE;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridAccessible: XULTreeAccessible implementation
 
 already_AddRefed<Accessible>
-XULTreeGridAccessible::CreateTreeItemAccessible(int32_t aRow)
+XULTreeGridAccessible::CreateTreeItemAccessible(int32_t aRow) const
 {
   nsRefPtr<Accessible> accessible =
-    new XULTreeGridRowAccessible(mContent, mDoc, this, mTree, mTreeView, aRow);
+    new XULTreeGridRowAccessible(mContent, mDoc,
+                                 const_cast<XULTreeGridAccessible*>(this),
+                                 mTree, mTreeView, aRow);
 
   return accessible.forget();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridRowAccessible
 ////////////////////////////////////////////////////////////////////////////////
@@ -340,17 +342,17 @@ XULTreeGridRowAccessible::ChildAtPoint(i
   // Return if we failed to find tree cell in the row for the given point.
   if (row != mRow || !column)
     return nullptr;
 
   return GetCellAccessible(column);
 }
 
 Accessible*
-XULTreeGridRowAccessible::GetChildAt(uint32_t aIndex)
+XULTreeGridRowAccessible::GetChildAt(uint32_t aIndex) const
 {
   if (IsDefunct())
     return nullptr;
 
   nsCOMPtr<nsITreeColumn> column =
     nsCoreUtils::GetSensibleColumnAt(mTree, aIndex);
   if (!column)
     return nullptr;
@@ -363,28 +365,29 @@ XULTreeGridRowAccessible::ChildCount() c
 {
   return nsCoreUtils::GetSensibleColumnCount(mTree);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridRowAccessible: XULTreeItemAccessibleBase implementation
 
 Accessible*
-XULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn)
+XULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn) const
 {
   NS_PRECONDITION(aColumn, "No tree column!");
 
   void* key = static_cast<void*>(aColumn);
   Accessible* cachedCell = mAccessibleCache.GetWeak(key);
   if (cachedCell)
     return cachedCell;
 
   nsRefPtr<Accessible> cell =
-    new XULTreeGridCellAccessibleWrap(mContent, mDoc, this, mTree,
-                                      mTreeView, mRow, aColumn);
+    new XULTreeGridCellAccessibleWrap(mContent, mDoc,
+                                      const_cast<XULTreeGridRowAccessible*>(this),
+                                      mTree, mTreeView, mRow, aColumn);
   mAccessibleCache.Put(key, cell);
   Document()->BindToDocument(cell, nullptr);
   return cell;
 }
 
 void
 XULTreeGridRowAccessible::RowInvalidated(int32_t aStartColIdx,
                                          int32_t aEndColIdx)
--- a/accessible/src/xul/XULTreeGridAccessible.h
+++ b/accessible/src/xul/XULTreeGridAccessible.h
@@ -57,17 +57,18 @@ public:
   // Accessible
   virtual void Shutdown();
   virtual TableAccessible* AsTable() { return this; }
   virtual a11y::role NativeRole();
 
 protected:
 
   // XULTreeAccessible
-  virtual already_AddRefed<Accessible> CreateTreeItemAccessible(int32_t aRow);
+  virtual already_AddRefed<Accessible>
+    CreateTreeItemAccessible(int32_t aRow) const MOZ_OVERRIDE;
 };
 
 
 /**
  * Represents accessible for XUL tree item in the case when XUL tree has
  * multiple columns.
  */
 class XULTreeGridRowAccessible : public XULTreeItemAccessibleBase
@@ -86,30 +87,30 @@ public:
 
   // Accessible
   virtual void Shutdown();
   virtual a11y::role NativeRole();
   virtual ENameValueFlag Name(nsString& aName);
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild);
 
-  virtual Accessible* GetChildAt(uint32_t aIndex);
-  virtual uint32_t ChildCount() const;
+  virtual Accessible* GetChildAt(uint32_t aIndex) const MOZ_OVERRIDE;
+  virtual uint32_t ChildCount() const MOZ_OVERRIDE;
 
   // XULTreeItemAccessibleBase
-  virtual Accessible* GetCellAccessible(nsITreeColumn* aColumn);
+  virtual Accessible* GetCellAccessible(nsITreeColumn* aColumn) const MOZ_OVERRIDE;
   virtual void RowInvalidated(int32_t aStartColIdx, int32_t aEndColIdx);
 
 protected:
 
   // Accessible
   virtual void CacheChildren();
 
   // XULTreeItemAccessibleBase
-  AccessibleHashtable mAccessibleCache;
+  mutable AccessibleHashtable mAccessibleCache;
 };
 
 
 /**
  * Represents an accessible for XUL tree cell in the case when XUL tree has
  * multiple columns.
  */
 
--- a/accessible/tests/mochitest/attributes/test_obj_group.html
+++ b/accessible/tests/mochitest/attributes/test_obj_group.html
@@ -12,16 +12,23 @@
           src="../common.js"></script>
   <script type="application/javascript"
           src="../attributes.js"></script>
 
   <script type="application/javascript">
     function doTest()
     {
       //////////////////////////////////////////////////////////////////////////
+      // HTML select with no size attribute.
+      testGroupAttrs("opt1-nosize", 1, 4);
+      testGroupAttrs("opt2-nosize", 2, 4);
+      testGroupAttrs("opt3-nosize", 3, 4);
+      testGroupAttrs("opt4-nosize", 4, 4);
+
+      //////////////////////////////////////////////////////////////////////////
       // HTML select
       testGroupAttrs("opt1", 1, 2);
       testGroupAttrs("opt2", 2, 2);
 
       //////////////////////////////////////////////////////////////////////////
       // HTML select with options
       // XXX bug 469123
       //testGroupAttrs("select2_optgroup", 1, 3, 1);
@@ -191,22 +198,34 @@
      title="Expose level for nested lists in HTML">
     Mozilla Bug 468418
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=864224"
      title="Support nested ARIA listitems structured by role='group'">
     Bug 864224
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=907682"
+     title=" HTML:option group position is not correct when select is collapsed">
+    Mozilla Bug 907682
+  </a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
+  <select>
+    <option id="opt1-nosize">option1</option>
+    <option id="opt2-nosize">option2</option>
+    <option id="opt3-nosize">option3</option>
+    <option id="opt4-nosize">option4</option>
+  </select>
+
   <select size="4">
     <option id="opt1">option1</option>
     <option id="opt2">option2</option>
   </select>
 
   <select size="4">
     <optgroup id="select2_optgroup" label="group">
       <option id="select2_opt1">option1</option>
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -240,37 +240,30 @@ function getAccessible(aAccOrElmOrID, aI
 
       return null;
     }
   }
 
   if (!aInterfaces)
     return acc;
 
-  if (aInterfaces instanceof Array) {
-    for (var index = 0; index < aInterfaces.length; index++) {
-      try {
-        acc.QueryInterface(aInterfaces[index]);
-      } catch (e) {
-        if (!(aDoNotFailIf & DONOTFAIL_IF_NO_INTERFACE))
-          ok(false, "Can't query " + aInterfaces[index] + " for " + aAccOrElmOrID);
+  if (!(aInterfaces instanceof Array))
+    aInterfaces = [ aInterfaces ];
 
-        return null;
-      }
+  for (var index = 0; index < aInterfaces.length; index++) {
+    try {
+      acc.QueryInterface(aInterfaces[index]);
+    } catch (e) {
+      if (!(aDoNotFailIf & DONOTFAIL_IF_NO_INTERFACE))
+        ok(false, "Can't query " + aInterfaces[index] + " for " + aAccOrElmOrID);
+
+      return null;
     }
-    return acc;
   }
-  
-  try {
-    acc.QueryInterface(aInterfaces);
-  } catch (e) {
-    ok(false, "Can't query " + aInterfaces + " for " + aAccOrElmOrID);
-    return null;
-  }
-  
+
   return acc;
 }
 
 /**
  * Return true if the given identifier has an accessible, or exposes the wanted
  * interfaces.
  */
 function isAccessible(aAccOrElmOrID, aInterfaces)
--- a/accessible/tests/mochitest/editabletext/editabletext.js
+++ b/accessible/tests/mochitest/editabletext/editabletext.js
@@ -51,28 +51,27 @@ function editableTextTest(aID)
       this.unwrapNextTest();
       this.mEventQueueReady = true;
     }
   }
 
   /**
    * setTextContents test.
    */
-  this.setTextContents = function setTextContents(aValue, aTrailChar)
+  this.setTextContents = function setTextContents(aValue)
   {
     var testID = "setTextContents '" + aValue + "' for " + prettyName(aID);
 
     function setTextContentsInvoke()
     {
       var acc = getAccessible(aID, nsIAccessibleEditableText);
       acc.setTextContents(aValue);
     }
 
-    var newValue = aValue + (aTrailChar ? aTrailChar : "");
-    var insertTripple = newValue ? [0, newValue.length, newValue] : null;
+    var insertTripple = aValue ? [0, aValue.length, aValue] : null;
     var oldValue = getValue(aID);
     var removeTripple = oldValue ? [0, oldValue.length, oldValue] : null;
 
     this.generateTest(aID, removeTripple, insertTripple, setTextContentsInvoke,
                       getValueChecker(aID, aValue), testID);
   }
 
   /**
--- a/accessible/tests/mochitest/editabletext/test_1.html
+++ b/accessible/tests/mochitest/editabletext/test_1.html
@@ -15,24 +15,24 @@ https://bugzilla.mozilla.org/show_bug.cg
           src="../common.js"></script>
   <script type="application/javascript"
           src="../events.js"></script>
   <script type="application/javascript"
           src="editabletext.js"></script>
 
   <script type="application/javascript">
 
-    function addTestEditable(aID, aTestRun, aTrailChar)
+    function addTestEditable(aID, aTestRun)
     {
       var et = new editableTextTest(aID);
 
       //////////////////////////////////////////////////////////////////////////
       // setTextContents
       et.scheduleTest(et.setTextContents, "hello");
-      et.scheduleTest(et.setTextContents, "olleh", aTrailChar); // due to some reason this reports '\n' in the end
+      et.scheduleTest(et.setTextContents, "olleh");
       et.scheduleTest(et.setTextContents, "");
 
       //////////////////////////////////////////////////////////////////////////
       // insertText
       et.scheduleTest(et.insertText, "hello", 0, "hello");
       et.scheduleTest(et.insertText, "ma ", 0, "ma hello");
       et.scheduleTest(et.insertText, "ma", 2, "mama hello");
       et.scheduleTest(et.insertText, " hello", 10, "mama hello hello");
@@ -75,19 +75,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 
       testRun.run(); // Will call SimpleTest.finish();
     }
 
     function doTest()
     {
       // Prepare tested elements.
 
-      // Design mode on/off trigger document accessible subtree recreation.
+      // Design mode on/off triggers an editable state change event on
+      // the document accessible.
       var frame = getNode("frame");
-      waitForEvent(EVENT_REORDER, frame.contentDocument, runTest);
+      waitForEvent(EVENT_STATE_CHANGE, frame.contentDocument, runTest);
       frame.contentDocument.designMode = "on";
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
--- a/accessible/tests/mochitest/elm/test_HTMLSpec.html
+++ b/accessible/tests/mochitest/elm/test_HTMLSpec.html
@@ -700,18 +700,17 @@
             actions: "press"
           },
           {
             role: ROLE_PUSHBUTTON,
             actions: "press"
           }
         ]
       };
-      // number is disabled in v28
-      //testElm("input_number", obj);
+      testElm("input_number", obj);
 
       //////////////////////////////////////////////////////////////////////////
       // HTML:input@type="text" and etc
 
       obj = {
         role: ROLE_ENTRY,
         extraStates: EXT_STATE_EDITABLE | EXT_STATE_SINGLE_LINE,
         actions: "activate",
@@ -729,27 +728,39 @@
       //////////////////////////////////////////////////////////////////////////
       // HTML:input@type="password"
 
       obj = {
         role: ROLE_PASSWORD_TEXT,
         states: STATE_PROTECTED,
         extraStates: EXT_STATE_EDITABLE,
         actions: "activate",
-        children: [ ]
+        children: [
+        {
+            role: ROLE_TEXT_LEAF
+          }
+        ]
       };
       testElm("input_password", obj);
+      ok(getAccessible("input_password").firstChild.name != "44",
+         "text leaf for password shouldn't have its real value as its name!");
 
       obj = {
         role: ROLE_PASSWORD_TEXT,
         states: STATE_PROTECTED | STATE_READONLY,
         actions: "activate",
-        children: [ ]
+        children: [
+        {
+            role: ROLE_TEXT_LEAF
+          }
+        ]
       };
       testElm("input_password_readonly", obj);
+      ok(getAccessible("input_password_readonly").firstChild.name != "44",
+         "text leaf for password shouldn't have its real value as its name!");
 
       //////////////////////////////////////////////////////////////////////////
       // HTML:input@type="radio"
 
       obj = {
         role: ROLE_RADIOBUTTON,
         states: STATE_CHECKABLE,
         absentStates: STATE_CHECKED,
--- a/accessible/tests/mochitest/events/test_focus_general.html
+++ b/accessible/tests/mochitest/events/test_focus_general.html
@@ -91,17 +91,17 @@
       gQueue = new eventQueue();
 
       gQueue.push(new synthFocus("editablearea"));
       gQueue.push(new synthFocus("navarea"));
       gQueue.push(new synthTab("navarea", new focusChecker(frameDoc)));
       gQueue.push(new focusElmWhileSubdocIsFocused("link"));
 
       gQueue.push(new synthTab(editableDoc, new focusChecker(editableDoc)));
-      if (WIN) {
+      if (WIN || LINUX) {
         // Alt key is used to active menubar and focus menu item on Windows,
         // other platforms requires setting a ui.key.menuAccessKeyFocuses
         // preference.
         gQueue.push(new toggleTopMenu(editableDoc, new topMenuChecker()));
         gQueue.push(new toggleTopMenu(editableDoc, new focusChecker(editableDoc)));
       }
       gQueue.push(new synthContextMenu(editableDoc, new contextMenuChecker()));
       gQueue.push(new synthDownKey(editableDoc, new focusContextMenuItemChecker()));
--- a/accessible/tests/mochitest/events/test_menu.xul
+++ b/accessible/tests/mochitest/events/test_menu.xul
@@ -151,17 +151,17 @@
 
       gQueue.push(new openFileMenu());
       gQueue.push(new openEditMenu());
       gQueue.push(new closeEditMenu());
 
       // Alt key is used to active menubar and focus menu item on Windows,
       // other platforms requires setting a ui.key.menuAccessKeyFocuses
       // preference.
-      if (WIN) {
+      if (WIN || LINUX) {
         gQueue.push(new focusFileMenu());
         gQueue.push(new focusEditMenu());
         gQueue.push(new leaveMenubar());
       }
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
--- a/accessible/tests/mochitest/jsat/a11y.ini
+++ b/accessible/tests/mochitest/jsat/a11y.ini
@@ -1,14 +1,13 @@
 [DEFAULT]
 support-files =
   jsatcommon.js
   output.js
   doc_traversal.html
 
 [test_alive.html]
-[test_braille.html]
 [test_explicit_names.html]
 [test_landmarks.html]
 [test_live_regions.html]
+[test_output.html]
 [test_tables.html]
 [test_traversal.html]
-[test_utterance_order.html]
deleted file mode 100644
--- a/accessible/tests/mochitest/jsat/test_braille.html
+++ /dev/null
@@ -1,122 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=876475
--->
-  <head>
-    <title>[AccessFu] braille generation test</title>
-    <meta charset="utf-8">
-    <link rel="stylesheet" type="text/css"
-          href="chrome://mochikit/content/tests/SimpleTest/test.css" />
-    <script type="application/javascript"
-            src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-    <script type="application/javascript"
-            src="../common.js"></script>
-    <script type="application/javascript"
-            src="./output.js"></script>
-    <script type="application/javascript">
-
-      function doTest() {
-        // Test the following accOrElmOrID (with optional old accOrElmOrID).
-        // Note: each accOrElmOrID entry maps to a unique object braille
-        // generator function within the BrailleGenerator.
-        var tests = [{
-          accOrElmOrID: "link",
-          expected: [["lnk", "Link"], ["Link", "lnk"]]
-        },{
-          accOrElmOrID: "button",
-          expected: [["btn", "I am a button"], ["I am a button", "btn"]]
-        },{
-          accOrElmOrID: "password_input",
-          expected: [["passwdtxt", "Secret Password"], ["Secret Password", "passwdtxt"]]
-        },{
-          accOrElmOrID: "checkbox_unchecked",
-          expected: [["( )", "checkboxtext"], ["checkboxtext", "( )"]]
-        },{
-          accOrElmOrID: "checkbox_checked",
-          expected: [["(x)", "some more checkbox text"], ["some more checkbox text", "(x)"]]
-        },{
-          accOrElmOrID: "radio_unselected",
-          expected: [["( )", "any old radio button"], ["any old radio button", "( )"]]
-        },{
-          accOrElmOrID: "radio_selected",
-          expected: [["(x)", "a unique radio button"], ["a unique radio button", "(x)"]]
-        },{
-          accOrElmOrID: "togglebutton_notpressed",
-          expected: [["( )", "I ain't pressed"], ["I ain't pressed", "( )"]]
-        },{
-          accOrElmOrID: "togglebutton_pressed",
-          expected: [["(x)", "I am pressed!"], ["I am pressed!", "(x)"]]
-        },{
-          accOrElmOrID: "ul_li_one",
-          expected: [["*", "ul item 1"], ["*", "ul item 1"]]
-        },{
-          accOrElmOrID: "ol_li_one",
-          expected: [["1.", "ol item 1"], ["1.", "ol item 1"]]
-        },{
-          accOrElmOrID: "textarea",
-          expected: [["txtarea", "Here lies treasure."], ["Here lies treasure.", "txtarea"]]
-        },{
-          accOrElmOrID: "textentry",
-          expected: [["entry", "Mario", "First name:"], ["First name:", "Mario", "entry"]]
-        },{
-          accOrElmOrID: "range",
-          expected: [["slider", "3", "Points:"], ["Points:", "3", "slider"]]
-        }];
-
-        // Test all possible braille order preference values.
-        tests.forEach(function run(test) {
-          var brailleOrderValues = [0, 1];
-          brailleOrderValues.forEach(
-            function testBrailleOrder(brailleOrder) {
-              SpecialPowers.setIntPref(PREF_UTTERANCE_ORDER, brailleOrder);
-              var expected = test.expected[brailleOrder];
-              testOutput(expected, test.accOrElmOrID, test.oldAccOrElmOrID, 2);
-            }
-          );
-        });
-
-        // If there was an original utterance order preference, revert to it.
-        SpecialPowers.clearUserPref(PREF_UTTERANCE_ORDER);
-        SimpleTest.finish();
-      }
-
-      SimpleTest.waitForExplicitFinish();
-      addA11yLoadEvent(doTest);
-
-    </script>
-  </head>
-  <body>
-    <div id="root">
-      <p id="display"></p>
-      <div id="content" style="display: none"></div>
-      <pre id="test"></pre>
-      <a href="example.com" id="link">Link</a>
-      <button id="button">I am a button</button>
-      <label for="password_input">Secret Password</label><input id="password_input" type="password"></input>
-      <label for="checkbox_unchecked">checkboxtext</label><input id="checkbox_unchecked" type="checkbox"></input>
-      <label for="checkbox_checked">some more checkbox text</label><input id="checkbox_checked" type="checkbox" checked></input>
-      <label for="radio_unselected">any old radio button</label><input id="radio_unselected" type="radio"></input>
-      <label for="radio_selected">a unique radio button</label><input id="radio_selected" type="radio" checked></input>
-      <div id="togglebutton_notpressed" aria-pressed="false" role="button" tabindex="-1">I ain't pressed</div>
-      <div id="togglebutton_pressed" aria-pressed="true" role="button" tabindex="-1">I am pressed!</div>
-      <ol id="ordered_list">
-        <li id="ol_li_one">ol item 1</li>
-        <li id="ol_li_two">ol item 2</li>
-        <li id="ol_li_three">ol item 3</li>
-        <li id="ol_li_three">ol item 4</li>
-      </ol>
-      <ul id="unordered_list">
-        <li id="ul_li_one">ul item 1</li>
-        <li id="ul_li_two">ul item 2</li>
-        <li id="ul_li_three">ul item 3</li>
-        <li id="ul_li_three">ul item 4</li>
-      </ul>
-      <textarea id="textarea" cols="80" rows="5">
-        Here lies treasure.
-      </textarea>
-      <label>First name: <input id="textentry" value="Mario"></label>
-      <label>Points: <input id="range" type="range" name="points" min="1" max="10" value="3"></label>
-   </div>
-  </body>
-</html>
--- a/accessible/tests/mochitest/jsat/test_landmarks.html
+++ b/accessible/tests/mochitest/jsat/test_landmarks.html
@@ -70,19 +70,17 @@
           "another main area", "main"]],
         expectedBraille: [["main", "another main area"], ["another main area",
           "main"]]
       }, {
         accOrElmOrID: "complementary",
         expectedUtterance: [["list 1 item", "complementary", "First item",
           "A complementary"], ["A complementary", "First item",
           "complementary", "list 1 item"]],
-        // XXX: The '*' should probably come before all of the context
-        // utterance.
-        expectedBraille: [["complementary", "*", "A complementary"], ["*",
+        expectedBraille: [["*", "complementary", "A complementary"], ["*",
           "A complementary", "complementary"]]
       }, {
         accOrElmOrID: "parent_main",
         expectedUtterance: [["main", "a parent main", "complementary",
           "a child complementary"], ["a parent main", "a child complementary",
           "complementary", "main"]],
         expectedBraille: [["main", "a parent main", "complementary",
           "a child complementary"], ["a parent main", "a child complementary",
@@ -146,9 +144,9 @@
       </li>
     </ul>
     <main id="parent_main">
       a parent main
       <p id="child_complementary" role="complementary">a child complementary</article>
     </main>
   </div>
 </body>
-</html>
\ No newline at end of file
+</html>
rename from accessible/tests/mochitest/jsat/test_utterance_order.html
rename to accessible/tests/mochitest/jsat/test_output.html
--- a/accessible/tests/mochitest/jsat/test_utterance_order.html
+++ b/accessible/tests/mochitest/jsat/test_output.html
@@ -17,222 +17,346 @@ https://bugzilla.mozilla.org/show_bug.cg
     <script type="application/javascript">
 
       function doTest() {
         // Test the following accOrElmOrID (with optional old accOrElmOrID).
         // Note: each accOrElmOrID entry maps to a unique object utterance
         // generator function within the UtteranceGenerator.
         var tests = [{
           accOrElmOrID: "anchor",
-          expected: [["link", "title"], ["title", "link"]]
+          expectedUtterance: [["link", "title"], ["title", "link"]],
+          expectedBraille: [["lnk", "title"], ["title", "lnk"]]
         }, {
           accOrElmOrID: "anchor_titleandtext",
-          expected: [[
-            "link", "goes to the tests -", "Tests"
-          ], [
-            "Tests", "- goes to the tests", "link"
-          ]]
+          expectedUtterance: [["link", "goes to the tests -", "Tests"],
+                             ["Tests", "- goes to the tests", "link"]],
+          expectedBraille:   [["lnk", "goes to the tests -", "Tests"],
+                             ["Tests", "- goes to the tests", "lnk"]],
         }, {
           accOrElmOrID: "anchor_duplicatedtitleandtext",
-          expected: [["link", "Tests"], ["Tests", "link"]]
+          expectedUtterance: [["link", "Tests"], ["Tests", "link"]],
+          expectedBraille: [["lnk", "Tests"], ["Tests", "lnk"]]
         }, {
           accOrElmOrID: "anchor_arialabelandtext",
-          expected: [[
-            "link", "goes to the tests - Tests"
-          ], [
-            "Tests - goes to the tests", "link"
-          ]]
+          expectedUtterance: [["link", "goes to the tests - Tests"],
+                              ["Tests - goes to the tests", "link"]],
+          expectedBraille: [["lnk", "goes to the tests - Tests"],
+                              ["Tests - goes to the tests", "lnk"]],
         }, {
           accOrElmOrID: "textarea",
-          expected: [[
+          expectedUtterance: [[
             "text area", "This is the text area text."
           ], [
             "This is the text area text.", "text area"
-          ]]
+          ],],
+          expectedBraille: [[
+            "txtarea", "This is the text area text."
+          ], [
+            "This is the text area text.", "txtarea"
+          ],],
         }, {
           accOrElmOrID: "heading",
-          expected: [
+          expectedUtterance: [
             ["heading level 1", "Test heading"],
             ["Test heading", "heading level 1"]
+          ],
+          expectedBraille: [
+            ["heading", "Test heading"],
+            ["Test heading", "heading"]
           ]
         }, {
           accOrElmOrID: "list",
-          expected: [
+          expectedUtterance: [
             ["list 1 item", "First item", "1.", "list one"],
             ["1.", "list one", "First item", "list 1 item"]
+          ],
+          expectedBraille: [
+            ["list", "list one"],
+            ["list one", "list"]
           ]
         }, {
           accOrElmOrID: "dlist",
-          expected: [
+          expectedUtterance: [
             ["definition list 0.5 items", "dd one"],
             ["dd one", "definition list 0.5 items"]
+          ],
+          expectedBraille: [
+            ["definition list", "dd one"],
+            ["dd one", "definition list"]
           ]
         }, {
           accOrElmOrID: "li_one",
-          expected: [
+          expectedUtterance: [
             ["list 1 item", "First item", "1.", "list one"],
             ["1.", "list one", "First item", "list 1 item"]
+          ],
+          expectedBraille: [
+            ["1.", "list one"],
+            ["1.", "list one"]
           ]
         }, {
           accOrElmOrID: "cell",
-          expected: [[
+          expectedUtterance: [[
             "table with 1 column and 1 row", "Fruits and vegetables",
             "Column 1 Row 1", "list 4 items", "First item", "link", "Apples",
             "link", "Bananas", "link", "Peaches", "Last item", "link", "Plums"
           ], [
             "Apples", "link", "First item", "Bananas", "link", "Peaches",
             "link", "Plums", "link", "Last item", "list 4 items",
             "Column 1 Row 1", "Fruits and vegetables",
             "table with 1 column and 1 row"
+          ]],
+          expectedBraille: [[
+            "c1r1", "list", "lnk", "Apples", "lnk", "Bananas", "lnk",
+            "Peaches", "lnk", "Plums"
+          ], [
+            "Apples", "lnk", "Bananas", "lnk", "Peaches", "lnk", "Plums",
+            "lnk", "list", "c1r1"
           ]]
         }, {
           accOrElmOrID: "date",
-          expected: [["date entry", "2011-09-29"], ["2011-09-29", "date entry"]]
+          expectedUtterance: [["date entry", "2011-09-29"], ["2011-09-29", "date entry"]],
+          expectedBraille: [["date entry", "2011-09-29"], ["2011-09-29", "date entry"]]
         }, {
           accOrElmOrID: "email",
-          expected: [
+          expectedUtterance: [
+            ["e-mail entry", "test@example.com"],
+            ["test@example.com", "e-mail entry"]
+          ],
+          expectedBraille: [
             ["e-mail entry", "test@example.com"],
             ["test@example.com", "e-mail entry"]
           ]
         }, {
           accOrElmOrID: "search",
-          expected: [
+          expectedUtterance: [
+            ["search entry", "This is a search"],
+            ["This is a search", "search entry"]
+          ],
+          expectedBraille: [
             ["search entry", "This is a search"],
             ["This is a search", "search entry"]
           ]
         }, {
           accOrElmOrID: "tel",
-          expected: [
+          expectedUtterance: [
+            ["telephone entry", "555-5555"], ["555-5555", "telephone entry"]
+          ],
+          expectedBraille: [
             ["telephone entry", "555-5555"], ["555-5555", "telephone entry"]
           ]
         }, {
           accOrElmOrID: "url",
-          expected: [
+          expectedUtterance: [
+            ["URL entry", "http://example.com"],
+            ["http://example.com", "URL entry"]
+          ],
+          expectedBraille: [
             ["URL entry", "http://example.com"],
             ["http://example.com", "URL entry"]
           ]
         }, {
           accOrElmOrID: "textInput",
-          expected: [["entry", "This is text."], ["This is text.", "entry"]]
+          expectedUtterance: [["entry", "This is text."], ["This is text.", "entry"]],
+          expectedBraille: [["entry", "This is text."], ["This is text.", "entry"]]
         }, {
           // Test pivot to list from li_one.
           accOrElmOrID: "list",
           oldAccOrElmOrID: "li_one",
-          expected: [
+          expectedUtterance: [
             ["list 1 item", "First item", "1.", "list one"],
             ["1.", "list one", "First item", "list 1 item"]
+          ],
+          expectedBraille: [
+            ["list", "list one"],
+            ["list one", "list"]
           ]
         }, {
           // Test pivot to "apples" link from the table cell.
           accOrElmOrID: "apples",
           oldAccOrElmOrID: "cell",
-          expected: [
+          expectedUtterance: [
             ["list 4 items", "First item", "link", "Apples"],
             ["Apples", "link", "First item", "list 4 items"]
+          ],
+          expectedBraille: [
+            ["*", "lnk", "Apples"],
+            ["*", "Apples", "lnk"]
           ]
         }, {
           // Test pivot to 'bananas' link from 'apples' link.
           accOrElmOrID: "bananas",
           oldAccOrElmOrID: "apples",
-          expected: [["link", "Bananas"], ["Bananas", "link"]]
+          expectedUtterance: [["link", "Bananas"], ["Bananas", "link"]],
+          expectedBraille: [["*", "lnk", "Bananas"], ["*", "Bananas", "lnk"]]
         }, {
           // test unavailable state utterance
           accOrElmOrID: 'unavailableButton',
-          expected: [["unavailable button", "I am unavailable"],
-            ["I am unavailable", "unavailable button"]]
+          expectedUtterance: [["unavailable button", "I am unavailable"],
+            ["I am unavailable", "unavailable button"]],
+          expectedBraille: [["btn", "I am unavailable"],
+            ["I am unavailable", "btn"]]
         }, {
           // test expanded state utterance
           accOrElmOrID: 'expandedButton',
-          expected: [["expanded button", "I am expanded"],
-            ["I am expanded", "expanded button"]]
+          expectedUtterance: [["expanded button", "I am expanded"],
+            ["I am expanded", "expanded button"]],
+          expectedBraille: [["btn", "I am expanded"],
+            ["I am expanded", "btn"]]
         }, {
           // test collapsed state utterance
           accOrElmOrID: 'collapsedButton',
-          expected: [["collapsed button", "I am collapsed"],
-            ["I am collapsed", "collapsed button"]]
+          expectedUtterance: [["collapsed button", "I am collapsed"],
+            ["I am collapsed", "collapsed button"]],
+          expectedBraille: [["btn", "I am collapsed"],
+            ["I am collapsed", "btn"]]
         }, {
           // test required state utterance
           accOrElmOrID: 'requiredInput',
-          expected: [["required entry", "I am required"],
-            ["I am required", "required entry"]]
+          expectedUtterance: [["required entry", "I am required"],
+            ["I am required", "required entry"]],
+          expectedBraille: [["entry", "I am required"],
+            ["I am required", "entry"]]
         }, {
           // test has popup state utterance
           accOrElmOrID: 'hasPopupButton',
-          expected: [["has pop up button menu", "I have a popup"],
-            ["I have a popup", "has pop up button menu"]]
+          expectedUtterance: [["has pop up button menu", "I have a popup"],
+            ["I have a popup", "has pop up button menu"]],
+          expectedBraille: [["button menu", "I have a popup"],
+            ["I have a popup", "button menu"]]
         }, {
           // Test selected tab
           accOrElmOrID: 'tab1',
-          expected: [['tab list', 'selected tab 1 of 2', 'Account'],
-            ['Account', 'selected tab 1 of 2', 'tab list']]
+          expectedUtterance: [['tab list', 'selected tab 1 of 2', 'Account'],
+            ['Account', 'selected tab 1 of 2', 'tab list']],
+          expectedBraille: [['tab 1 of 2', 'Account'],
+            ['Account', 'tab 1 of 2']]
         }, {
           // Test unselected tab
           accOrElmOrID: 'tab2',
-          expected: [['tab list', 'tab 2 of 2', 'Advanced'],
-            ['Advanced', 'tab 2 of 2', 'tab list']]
+          expectedUtterance: [['tab list', 'tab 2 of 2', 'Advanced'],
+            ['Advanced', 'tab 2 of 2', 'tab list']],
+          expectedBraille: [['tab 2 of 2', 'Advanced'],
+            ['Advanced', 'tab 2 of 2']]
         },
 
         {
           // Landing on this label should mimic landing on the checkbox.
           accOrElmOrID: "label1",
-          expected: [['not checked check button', 'Orange'],
-                     ['Orange', 'not checked check button']]
+          expectedUtterance: [['not checked check button', 'Orange'],
+                     ['Orange', 'not checked check button']],
+          expectedBraille: [['( )', 'Orange'],
+                     ['Orange', '( )']]
         },
         {
           // Here we get a top-level view of the form.
           accOrElmOrID: "form1",
-          expected: [['label', 'not checked check button', 'Orange', 'Orange',
+          expectedUtterance: [['label', 'not checked check button', 'Orange', 'Orange',
                       'not checked check button', 'Blue', 'label', 'Blue'],
                      ['Orange', 'not checked check button', 'Orange', 'label',
-                      'Blue', 'not checked check button', 'Blue', 'label']]
+                      'Blue', 'not checked check button', 'Blue', 'label']],
+          expectedBraille: [['label', '( )', 'Orange', 'Orange',
+                      '( )', 'Blue', 'label', 'Blue'],
+                     ['Orange', '( )', 'Orange', 'label',
+                      'Blue', '( )', 'Blue', 'label']]
         },
         {
           // This is a non-nesting label.
           accOrElmOrID: "label2",
-          expected: [['label', 'Blue'], ['Blue', 'label']]
+          expectedUtterance: [['label', 'Blue'], ['Blue', 'label']],
+          expectedBraille: [['label', 'Blue'], ['Blue', 'label']]
         },
         {
           // This is a distinct control.
           accOrElmOrID: "input2",
-          expected: [['not checked check button', 'Blue'],
-                     ['Blue', 'not checked check button']]
+          expectedUtterance: [['not checked check button', 'Blue'],
+                     ['Blue', 'not checked check button']],
+          expectedBraille: [['( )', 'Blue'],
+                     ['Blue', '( )']]
         },
         {
           // This is a nested control.
           accOrElmOrID: "input1",
-          expected: [['not checked check button', 'Orange'],
-                     ['Orange', 'not checked check button']]
+          expectedUtterance: [['not checked check button', 'Orange'],
+                     ['Orange', 'not checked check button']],
+          expectedBraille: [['( )', 'Orange'],
+                     ['Orange', '( )']]
         },
         {
           // Landing on this label should mimic landing on the entry.
           accOrElmOrID: "label3",
-          expected: [['entry', 'Joe', 'First name:'],
+          expectedUtterance: [['entry', 'Joe', 'First name:'],
+                     ['First name:', 'Joe', 'entry']],
+          expectedBraille: [['entry', 'Joe', 'First name:'],
                      ['First name:', 'Joe', 'entry']]
         },
         {
           // This is a nested control with a value.
           accOrElmOrID: "input3",
-          expected: [['entry', 'Joe', 'First name:'],
+          expectedUtterance: [['entry', 'Joe', 'First name:'],
+                     ['First name:', 'Joe', 'entry']],
+          expectedBraille: [['entry', 'Joe', 'First name:'],
                      ['First name:', 'Joe', 'entry']]
         },
         {
           // This is a nested control with a value.
           accOrElmOrID: "input4",
-          expected: [['slider', '3', 'Points:'],
+          expectedUtterance: [['slider', '3', 'Points:'],
+                     ['Points:', '3', 'slider']],
+          expectedBraille: [['slider', '3', 'Points:'],
                      ['Points:', '3', 'slider']]
-        }];
+        },{
+          accOrElmOrID: "password",
+          expectedUtterance: [["password text", "Secret Password"],
+                              ["Secret Password", "password text"]],
+          expectedBraille: [["passwdtxt", "Secret Password"],
+                            ["Secret Password", "passwdtxt"]]
+        },{
+          accOrElmOrID: "input5",
+          expectedUtterance: [["checked check button", "Boring label"],
+                              ["Boring label", "checked check button"]],
+          expectedBraille: [["(x)", "Boring label"],
+                            ["Boring label", "(x)"]]
+        },{
+          accOrElmOrID: "radio_unselected",
+          expectedUtterance: [["not checked radio button", "any old radio button"],
+                              ["any old radio button", "not checked radio button"]],
+          expectedBraille: [["( )", "any old radio button"],
+                            ["any old radio button", "( )"]]
+        },{
+          accOrElmOrID: "radio_selected",
+          expectedUtterance: [["checked radio button", "a unique radio button"],
+                              ["a unique radio button", "checked radio button"]],
+          expectedBraille: [["(x)", "a unique radio button"],
+                            ["a unique radio button", "(x)"]]
+        },{
+          accOrElmOrID: "togglebutton_notpressed",
+          expectedUtterance: [["not checked toggle button", "I ain't pressed"],
+                              ["I ain't pressed", "not checked toggle button"]],
+          expectedBraille: [["( )", "I ain't pressed"],
+                            ["I ain't pressed", "( )"]]
+        },{
+          accOrElmOrID: "togglebutton_pressed",
+          expectedUtterance: [["not checked toggle button", "I am pressed!"],
+                              ["I am pressed!", "not checked toggle button"]],
+          expectedBraille: [["(x)", "I am pressed!"],
+                            ["I am pressed!", "(x)"]]
+        }
+        ];
 
         // Test all possible utterance order preference values.
         tests.forEach(function run(test) {
           var utteranceOrderValues = [0, 1];
           utteranceOrderValues.forEach(
             function testUtteranceOrder(utteranceOrder) {
               SpecialPowers.setIntPref(PREF_UTTERANCE_ORDER, utteranceOrder);
-              var expected = test.expected[utteranceOrder];
-              testOutput(expected, test.accOrElmOrID, test.oldAccOrElmOrID, 1);
+              testOutput(test.expectedUtterance[utteranceOrder],
+                         test.accOrElmOrID, test.oldAccOrElmOrID, 1);
+              testOutput(test.expectedBraille[utteranceOrder],
+                         test.accOrElmOrID, test.oldAccOrElmOrID, 0);
             }
           );
         });
 
         // If there was an original utterance order preference, revert to it.
         SpecialPowers.clearUserPref(PREF_UTTERANCE_ORDER);
         SimpleTest.finish();
       }
@@ -247,16 +371,28 @@ https://bugzilla.mozilla.org/show_bug.cg
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=753984"
          title="[AccessFu] utterance order test">
          Mozilla Bug 753984</a>
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=758675"
          title="[AccessFu] Add support for accDescription">
          Mozilla Bug 758675</a>
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=876475"
+         title="[AccessFu] Make braille output less verbose">
+         Mozilla Bug 876475</a>
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=924284"
+         title="[AccessFu] Output accessible values">
+         Mozilla Bug 924284</a>
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=925845"
+         title="[AccessFu] Unify output tests">
+         Mozilla Bug 925845</a>
       <p id="display"></p>
       <div id="content" style="display: none"></div>
       <pre id="test"></pre>
       <a id="anchor" href="#test" title="title"></a>
       <a id="anchor_titleandtext" href="#test" title="goes to the tests">Tests</a>
       <a id="anchor_duplicatedtitleandtext" href="#test" title="Tests">Tests</a>
       <a id="anchor_arialabelandtext" href="#test" aria-label="Tests" title="goes to the tests">Tests</a>
       <textarea id="textarea" cols="80" rows="5">
@@ -300,17 +436,24 @@ https://bugzilla.mozilla.org/show_bug.cg
       <form id="form1">
         <label id="label1"><input id="input1" type="checkbox">Orange</label>
         <input id="input2" type="checkbox"><label id="label2" for="input2">Blue</label>
       </form>
       <label id="label3">First name: <input id="input3" value="Joe"></label>
       <label id="label4">Points:
         <input id="input4" type="range" name="points" min="1" max="10" value="3">
       </label>
+      <label for="input5">Boring label</label><input id="input5" type="checkbox" checked></input>
+      <label for="password">Secret Password</label><input id="password" type="password"></input>
+      <label for="radio_unselected">any old radio button</label><input id="radio_unselected" type="radio"></input>
+      <label for="radio_selected">a unique radio button</label><input id="radio_selected" type="radio" checked></input>
       <input id="date" type="date" value="2011-09-29" />
       <input id="email" type="email" value="test@example.com" />
       <input id="search" type="search" value="This is a search" />
       <input id="tel" type="tel" value="555-5555" />
       <input id="url" type="url" value="http://example.com" />
       <input id="textInput" type="text" value="This is text." />
+      <label>Points: <input id="range" type="range" name="points" min="1" max="10" value="3"></label>
+      <div id="togglebutton_notpressed" aria-pressed="false" role="button" tabindex="-1">I ain't pressed</div>
+      <div id="togglebutton_pressed" aria-pressed="true" role="button" tabindex="-1">I am pressed!</div>
     </div>
   </body>
 </html>
--- a/accessible/tests/mochitest/relations.js
+++ b/accessible/tests/mochitest/relations.js
@@ -92,16 +92,71 @@ function testRelation(aIdentifier, aRelT
     for (var idx = 0; idx < targets.length && relatedAcc != targets[idx]; idx++);
 
     if (idx == targets.length)
       ok(false, "There is unexpected target" + prettyName(relatedAcc) + "of" + relDescr);
   }
 }
 
 /**
+ * Test that the given accessible relations don't exist.
+ *
+ * @param aIdentifier           [in] identifier to get an accessible, may be ID
+ *                              attribute or DOM element or accessible object
+ * @param aRelType              [in] relation type (see constants above)
+ * @param aUnrelatedIdentifiers [in] identifier or array of identifiers of
+ *                              accessibles that shouldn't exist for this
+ *                              relation.
+ */
+function testAbsentRelation(aIdentifier, aRelType, aUnrelatedIdentifiers)
+{
+  var relation = getRelationByType(aIdentifier, aRelType);
+
+  var relDescr = getRelationErrorMsg(aIdentifier, aRelType);
+  var relDescrStart = getRelationErrorMsg(aIdentifier, aRelType, true);
+
+  if (!aUnrelatedIdentifiers) {
+    ok(false, "No identifiers given for unrelated accessibles.");
+    return;
+  }
+
+  if (!relation || !relation.targetsCount) {
+    ok(true, "No relations exist.");
+    return;
+  }
+
+  var relatedIds = (aUnrelatedIdentifiers instanceof Array) ?
+    aUnrelatedIdentifiers : [aUnrelatedIdentifiers];
+
+  var targets = [];
+  for (var idx = 0; idx < relatedIds.length; idx++)
+    targets.push(getAccessible(relatedIds[idx]));
+
+  if (targets.length != relatedIds.length)
+    return;
+
+  var actualTargets = relation.getTargets();
+
+  // Any found targets that match given accessibles should be called out.
+  for (var idx = 0; idx < targets.length; idx++) {
+    var notFound = true;
+    var enumerate = actualTargets.enumerate();
+    while (enumerate.hasMoreElements()) {
+      var relatedAcc = enumerate.getNext().QueryInterface(nsIAccessible);
+      if (targets[idx] == relatedAcc) {
+        notFound = false;
+        break;
+      }
+    }
+
+    ok(notFound, prettyName(relatedIds[idx]) + " is a target of " + relDescr);
+  }
+}
+
+/**
  * Return related accessible for the given relation type.
  *
  * @param aIdentifier  [in] identifier to get an accessible, may be ID attribute
  *                     or DOM element or accessible object
  * @param aRelType     [in] relation type (see constants above)
  */
 function getRelationByType(aIdentifier, aRelType)
 {
--- a/accessible/tests/mochitest/relations/test_general.html
+++ b/accessible/tests/mochitest/relations/test_general.html
@@ -79,16 +79,28 @@
       testRelation("treeitem4", RELATION_NODE_CHILD_OF, "tree");
       testRelation("treeitem5", RELATION_NODE_CHILD_OF, "treeitem4");
       testRelation("treeitem6", RELATION_NODE_CHILD_OF, "tree");
       testRelation("treeitem7", RELATION_NODE_CHILD_OF, "treeitem6");
       testRelation("tree2_ti1", RELATION_NODE_CHILD_OF, "tree2");
       testRelation("tree2_ti1a", RELATION_NODE_CHILD_OF, "tree2_ti1");
       testRelation("tree2_ti1b", RELATION_NODE_CHILD_OF, "tree2_ti1");
 
+      // 'node child of' relation for row role in grid.
+      // Relation for row associated using aria-owns should exist.
+      testRelation("simplegrid-ownrow", RELATION_NODE_CHILD_OF, "simplegrid");
+      // Relation for row associated using aria-level should exist.
+      testRelation("simplegrid-row3", RELATION_NODE_CHILD_OF,
+                   "simplegrid-row2");
+      // Relations for hierarchical children elements shouldn't exist.
+      testAbsentRelation("simplegrid-row1", RELATION_NODE_CHILD_OF,
+                         "simplegrid");
+      testAbsentRelation("simplegrid-row2", RELATION_NODE_CHILD_OF,
+                         "simplegrid");
+
       // 'node child of' relation for row role of treegrid
       testRelation("treegridrow1", RELATION_NODE_CHILD_OF, "treegrid");
       testRelation("treegridrow2", RELATION_NODE_CHILD_OF, "treegrid");
       testRelation("treegridrow3", RELATION_NODE_CHILD_OF, "treegridrow2");
 
       // 'node child of' relation for lists organized by groups
       testRelation("listitem1", RELATION_NODE_CHILD_OF, "list");
       testRelation("listitem1.1", RELATION_NODE_CHILD_OF, "listitem1");
@@ -113,16 +125,24 @@
       testRelation("tree2", RELATION_NODE_PARENT_OF, "tree2_ti1"); // group role
       testRelation("tree2_ti1", RELATION_NODE_PARENT_OF,
                    ["tree2_ti1a", "tree2_ti1b"]); // group role
 
       testRelation("treegridrow2", RELATION_NODE_PARENT_OF, "treegridrow3");
       testRelation("treegrid", RELATION_NODE_PARENT_OF,
                    ["treegridrow1", "treegridrow2"]);
 
+      // 'node parent of' relation on ARIA grid.
+      // Should only have relation to child added through aria-owns.
+      testRelation("simplegrid", RELATION_NODE_PARENT_OF, "simplegrid-ownrow");
+      // 'node parent of' relation on ARIA grid's row.
+      // Should only have relation to child through aria-level.
+      testRelation("simplegrid-row2", RELATION_NODE_PARENT_OF,
+                   "simplegrid-row3");
+
       // 'node parent of' relation on ARIA list structured by groups
       testRelation("list", RELATION_NODE_PARENT_OF,
                    "listitem1");
       testRelation("listitem1", RELATION_NODE_PARENT_OF,
                    [ "listitem1.1", "listitem1.2" ]);
 
       // aria-atomic
       testRelation(getNode("atomic").firstChild, RELATION_MEMBER_OF, "atomic");
@@ -285,16 +305,32 @@
     <div role="treeitem" id="treeitem4" aria-level="1">Green</div>
     <div role="treeitem" id="treeitem5" aria-level="2">Light green</div>
     <div role="treeitem" id="treeitem6" aria-level="1">Green2</div>
     <div role="group">
       <div role="treeitem" id="treeitem7">Super light green</div>
     </div>
   </div>
 
+  <div aria-owns="simplegrid-ownrow" role="grid" id="simplegrid">
+    <div role="row" id="simplegrid-row1" aria-level="1">
+      <div role="gridcell">cell 1,1</div>
+      <div role="gridcell">cell 1,2</div>
+    </div>
+    <div role="row" id="simplegrid-row2" aria-level="1">
+      <div role="gridcell">cell 2,1</div>
+      <div role="gridcell">cell 2,2</div>
+    </div>
+    <div role="row" id="simplegrid-row3" aria-level="2">
+      <div role="gridcell">cell 3,1</div>
+      <div role="gridcell">cell 3,2</div>
+    </div>
+  </div>
+  <div role="row" id="simplegrid-ownrow"></div>
+
   <ul role="tree" id="tree2">
     <li role="treeitem" id="tree2_ti1">Item 1
       <ul role="group">
         <li role="treeitem" id="tree2_ti1a">Item 1A</li>
         <li role="treeitem" id="tree2_ti1b">Item 1B</li>
       </ul>
     </li>
   </ul>
--- a/accessible/tests/mochitest/role/test_aria.html
+++ b/accessible/tests/mochitest/role/test_aria.html
@@ -125,16 +125,20 @@
       for (a in abstract_roles)
         testRole(abstract_roles[a], ROLE_SECTION);
 
       //////////////////////////////////////////////////////////////////////////
       // roles transformed by ARIA state attributes
       testRole("togglebutton", ROLE_TOGGLE_BUTTON);
 
       //////////////////////////////////////////////////////////////////////////
+      // ignore unknown roles, take first known
+      testRole("unknown_roles", ROLE_PUSHBUTTON);
+
+      //////////////////////////////////////////////////////////////////////////
       // misc roles
       testRole("note", ROLE_NOTE);
       testRole("scrollbar", ROLE_SCROLLBAR);
       testRole("dir", ROLE_LIST);
 
       //////////////////////////////////////////////////////////////////////////
       // test document role map update
       var testDoc = getAccessible(document, [nsIAccessibleDocument]);
@@ -295,16 +299,19 @@
   <div role="select" id="select">select</div>
   <!-- test abstract structure roles -->
   <div role="section" id="section">section</div>
   <div role="sectionhead" id="sectionhead">sectionhead</div>
 
   <!-- roles transformed by ARIA state attributes -->
   <button aria-pressed="true" id="togglebutton">
 
+  <!-- take the first known mappable role -->
+  <div role="wiggly:worm abc123 button" id="unknown_roles">worm button</div>
+
   <!-- misc roles -->
   <div role="note" id="note">note</div>
   <div role="scrollbar" id="scrollbar">scrollbar</div>
 
   <div id="dir" role="directory">
     <div role="listitem">A</div>
     <div role="listitem">B</div>
     <div role="listitem">C</div>
--- a/accessible/tests/mochitest/states/test_inputs.html
+++ b/accessible/tests/mochitest/states/test_inputs.html
@@ -51,17 +51,17 @@
       }
 
       testStates(maybe_required[i] + "_disabled",
                  STATE_UNAVAILABLE, 0,
                  STATE_FOCUSABLE | STATE_READONLY | STATE_REQUIRED);
     }
 
     for (i in never_required) {
-      testStates(never_required[i], 0, 0, STATE_REQUIRED);
+      testStates(never_required[i], 0, 0, STATE_REQUIRED | EXT_STATE_EDITABLE);
     }
 
     ////////////////////////////////////////////////////////////////////////////
     // inherited 'unavailable' state
     testStates("f", STATE_UNAVAILABLE);
     testStates("f_input", STATE_UNAVAILABLE);
     testStates("f_input_disabled", STATE_UNAVAILABLE);
 
--- a/accessible/tests/mochitest/states/test_selects.html
+++ b/accessible/tests/mochitest/states/test_selects.html
@@ -68,16 +68,29 @@
       var opt1 = comboboxList.firstChild;
       testStates(opt1, STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE,
                  EXT_STATE_ACTIVE, STATE_FOCUSED, 0);
 
       var opt2 = comboboxList.lastChild;
       testStates(opt2, STATE_SELECTABLE | STATE_FOCUSABLE, 0, STATE_SELECTED, 0,
                  STATE_FOCUSED, EXT_STATE_ACTIVE);
 
+      // collapsed combobox
+      testStates("collapsedcombobox",
+                 STATE_COLLAPSED | STATE_FOCUSABLE, 0,
+                 STATE_FOCUSED, 0);
+
+      testStates("collapsed-1",
+                 STATE_FOCUSABLE | STATE_SELECTABLE, 0,
+                 STATE_OFFSCREEN | STATE_INVISIBLE, 0);
+
+      testStates("collapsed-2",
+                 STATE_OFFSCREEN, 0,
+                 STATE_INVISIBLE, 0);
+
       // listbox
       testStates("listbox",
                  STATE_FOCUSABLE, 0,
                  STATE_HASPOPUP | STATE_COLLAPSED | STATE_FOCUSED);
 
       testStates("listitem-active",
                  STATE_FOCUSABLE | STATE_SELECTABLE, EXT_STATE_ACTIVE,
                  STATE_SELECTED | STATE_FOCUSED);
@@ -145,26 +158,36 @@
      title="Expose active state on current item of selectable widgets">
     Mozilla Bug 689847
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=756983"
      title="Isolate focusable and unavailable states from State()">
     Mozilla Bug 756983
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=907682"
+     title=" HTML:option group position is not correct when select is collapsed">
+    Mozilla Bug 907682
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <select id="combobox">
     <option>item 1</option>
     <option>item 2</option>
   </select>
 
+  <select id="collapsedcombobox">
+    <option id="collapsed-1">item 1</option>
+    <option id="collapsed-2">item 2</option>
+  </select>
+
   <select id="listbox" name="component" size="3">
     <option id="listitem-active">Build</option>
     <option id="listitem">Disability Access APIs</option>
     <option id="listitem-disabled" disabled>General</option>
     <optgroup id="listgroup" label="group">
       <option>option</option>
     </optgroup>
     <optgroup id="listgroup-disabled" disabled label="group2">
--- a/accessible/tests/mochitest/states/test_visibility.html
+++ b/accessible/tests/mochitest/states/test_visibility.html
@@ -114,16 +114,17 @@
     gDocURI += "  <li>item4</li><li>item5</li><li id='li_last'>item6</li>";
     gDocURI += "</ul>";
     gDocURI += "</body></html>";
 
     function doTests()
     {
       testStates("div", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
       testStates("div_off", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+      testStates("div_transformed", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
       testStates("div_abschild", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
 
       gQueue = new eventQueue();
 
       gQueue.push(new addTabInvoker("about:blank", testBackgroundTab));
       gQueue.push(new loadURIInvoker(gDocURI, testScrolledOff));
 
       gQueue.onFinish = function() { closeBrowserWindow(); }
@@ -155,16 +156,19 @@
 
   <div id="outer_div">
 
     <!-- trivial cases -->
     <div id="div">div</div>
     <div id="div_off" style="position: absolute; left:-999px; top:-999px">
       offscreen!
     </div>
+    <div id="div_transformed" style="transform: translate(-999px, -999px);">
+      transformed!
+    </div>
 
     <!-- edge case: no rect but has out of flow child -->
     <div id="div_abschild">
       <p style="position: absolute; left: 120px; top:120px;">absolute</p>
     </div>
 
   </div>
 </body>
--- a/accessible/tests/mochitest/table/test_table_2.html
+++ b/accessible/tests/mochitest/table/test_table_2.html
@@ -10,33 +10,16 @@
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
 
   <script type="text/javascript">
 
 function doTest()
 {
-  // Test table with display:inline. We shouldn't create table accessible and
-  // table cell accessible in this case
-  var accNotCreated = (!isAccessible("table1"));
-  ok(accNotCreated, "wrongly created table accessible");
-  
-  if (accNotCreated) {
-    var accDiv = getAccessible("div");
-    is(accDiv.firstChild.name, "cell", "wrongly created table cell accessible");
-  }
-
-  // Test table with display:inline and have an another outside table
-  accNotCreated = (!isAccessible("table2"));
-  ok(accNotCreated, "wrongly created table accessible");
-
-  accNotCreated = (!isAccessible("cell"));
-  ok(accNotCreated, "wrongly created table cell accessible");
-
   // Test table with role=alert. 
   var tableInterfaceExposed = true;
   var accTable3 = getAccessible("table3", [nsIAccessibleTable], null, DONOTFAIL_IF_NO_INTERFACE);
   if (!accTable3)
     tableInterfaceExposed = false;  
   ok(tableInterfaceExposed, "table interface is not exposed");
 
   if (tableInterfaceExposed) {
@@ -61,24 +44,16 @@ function doTest()
     testRole(accTable4, ROLE_TABLE);
 
     is(accTable4.getCellAt(0,0).firstChild.name, "cell0", "wrong cell");
     is(accTable4.getCellAt(0,1).firstChild.name, "cell1", "wrong cell");
     is(accTable4.getCellAt(1,0).firstChild.name, "cell2", "wrong cell");
     is(accTable4.getCellAt(1,1).firstChild.name, "cell3", "wrong cell");
   }
 
-  // Test table with display:inline and an outside table. We shouldn't be fooled
-  // by the outside table and shouldn't create table accessible and table cell
-  // accessible in this case
-  accNotCreated = (!isAccessible("table5"));
-  ok(accNotCreated, "wrongly created table accessible");
-  accNotCreated = (!isAccessible("t5_cell"));
-  ok(accNotCreated, "wrongly created table cell accessible");
-
   // test crazy table
   var table6 = getAccessible("table6", [nsIAccessibleTable]);
   ok(!table6.getCellAt(0, 0),
      "We don't expect cell accessible for crazy table 6!");
 
   SimpleTest.finish();
 }
 SimpleTest.waitForExplicitFinish();
@@ -91,32 +66,16 @@ addA11yLoadEvent(doTest);
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <!-- Test Table -->
   <br><br><b> Testing Table:</b><br><br>
   <center>
-   <div id="div">
-     <table id="table1" border="1" style="display:inline">
-      <tr>
-       <td>cell</td>
-      </tr>
-     </table>
-   </div>
-
-   <table><tr><td>
-     <table id="table2" border="1" style="display:inline">
-      <tr>
-       <td id="cell">cell</td>
-      </tr>
-     </table>
-   </td></tr></table>
-
    <table id="table3" border="1" role="alert">
     <tr>
      <td>cell0</td>
      <td>cell1</td>
     </tr>
    </table>
 
    <table id="table4" border="1" role="log">
@@ -125,27 +84,16 @@ addA11yLoadEvent(doTest);
      <td>cell1</td>
     </tr>
     <tr>
      <td>cell2</td>
      <td>cell3</td>
     </tr>
    </table>
 
-   <table>
-   <tr>
-   <td style="display:block">
-     <table style="display:inline" id="table5">
-       <tr><td id="t5_cell">cell0</td></tr>
-     </table>
-   </td>
-   <td>cell1</td>
-   </tr>
-   </table>
-
   <div style="display:table;" id="table6">
     <input type="checkbox">
     <a href="bar">Bad checkbox</a>
   </div>
 
   </center>
  </body>
 </html>
--- a/accessible/tests/mochitest/text.js
+++ b/accessible/tests/mochitest/text.js
@@ -549,30 +549,37 @@ function testTextHelper(aID, aOffset, aB
     var text = aTextFunc(aOffset, aBoundaryType,
                          startOffsetObj, endOffsetObj);
 
     if (exceptionFlag) {
       ok(false, startMsg + "no expected failure at offset " + aOffset + endMsg);
       return;
     }
 
-    var isFunc1 = (aToDoFlag1 == kTodo) ? todo_is : is;
-    var isFunc2 = (aToDoFlag2 == kTodo) ? todo_is : is;
-    var isFunc3 = (aToDoFlag3 == kTodo) ? todo_is : is;
+    var isFunc1 = (aToDoFlag1 == kTodo) ? todo : ok;
+    var isFunc2 = (aToDoFlag2 == kTodo) ? todo : ok;
+    var isFunc3 = (aToDoFlag3 == kTodo) ? todo : ok;
 
-    isFunc1(text, aText,
-            startMsg + "wrong text, offset: " + aOffset + endMsg);
-    isFunc2(startOffsetObj.value, aStartOffset,
-            startMsg + "wrong start offset, offset: " + aOffset + endMsg);
-    isFunc3(endOffsetObj.value, aEndOffset,
-            startMsg + "wrong end offset, offset: " + aOffset + endMsg);
+    isFunc1(text == aText,
+            startMsg + "wrong text " +
+            "(got '" + text + "', expected: '" + aText + "')" +
+            ", offset: " + aOffset + endMsg);
+    isFunc2(startOffsetObj.value == aStartOffset,
+            startMsg + "wrong start offset" +
+            "(got '" + startOffsetObj.value + "', expected: '" + aStartOffset + "')" +
+            ", offset: " + aOffset + endMsg);
+    isFunc3(endOffsetObj.value == aEndOffset,
+            startMsg + "wrong end offset" +
+            "(got '" + endOffsetObj.value + "', expected: '" + aEndOffset + "')" +
+            ", offset: " + aOffset + endMsg);
 
   } catch (e) {
     var okFunc = exceptionFlag ? todo : ok;
-    okFunc(false, startMsg + "failed at offset " + aOffset + endMsg);
+    okFunc(false, startMsg + "failed at offset " + aOffset + endMsg +
+           ", exception: " + e);
   }
 }
 
 function boundaryToString(aBoundaryType)
 {
   switch (aBoundaryType) {
     case BOUNDARY_CHAR:
       return "char";
--- a/accessible/tests/mochitest/text/test_atcaretoffset.html
+++ b/accessible/tests/mochitest/text/test_atcaretoffset.html
@@ -30,17 +30,18 @@
     function traverseTextByLines(aQueue, aID, aLines)
     {
       var wholeText = "";
       for (var i = 0; i < aLines.length ; i++)
         wholeText += aLines[i][0] + aLines[i][1];
 
       var baseInvokerFunc = synthClick;
       var charIter = new charIterator(wholeText, aLines);
-      //charIter.debugOffset = 0;
+      //charIter.debugOffset = 10; // enable to run tests at given offset only
+
       while (charIter.next()) {
         aQueue.push(new tmpl_moveTo(aID, baseInvokerFunc, wholeText, charIter));
         baseInvokerFunc = synthRightKey;
       }
     }
 
     /**
      * Used to get test list for each traversed character.
@@ -142,17 +143,35 @@
               (useNextWordForAtWordEnd ? nWord : cWord).end ],
             [ testTextAfterOffset, BOUNDARY_WORD_START,
               nWord.start, nnWord.start ],
             [ testTextAfterOffset, BOUNDARY_WORD_END,
               (isAfterWordEnd ? nWord : cWord).end,
               (isAfterWordEnd ? nnWord : nWord).end ]
           ];
 
-          return lineTests.concat(wordTests);
+          // Character boundary tests.
+          var prevOffset = this.offset > 1 ? this.offset - 1 : 0;
+          var nextOffset = this.offset >= aWholeText.length ?
+            this.offset : this.offset + 1;
+          var nextAfterNextOffset = nextOffset >= aWholeText.length ?
+            nextOffset : nextOffset + 1;
+
+          var charTests = [
+            [ testTextBeforeOffset, BOUNDARY_CHAR,
+              prevOffset, this.offset ],
+            [ testTextAtOffset, BOUNDARY_CHAR,
+              this.offset,
+              this.mAtWrappedLineEnd ? this.offset : nextOffset ],
+            [ testTextAfterOffset, BOUNDARY_CHAR,
+              this.mAtWrappedLineEnd ? this.offset : nextOffset,
+              this.mAtWrappedLineEnd ? nextOffset : nextAfterNextOffset ]
+          ];
+
+          return lineTests.concat(wordTests.concat(charTests));
         }
       });
 
       Object.defineProperty(this, "failures", { get: function()
         {
           if (this.mOffset == this.mLine.start)
             return this.mLine.lineStartFailures;
           if (this.mOffset == this.mLine.end)
--- a/accessible/tests/mochitest/text/test_charboundary.html
+++ b/accessible/tests/mochitest/text/test_charboundary.html
@@ -30,25 +30,17 @@
       testCharAtOffset(IDs, 0, "h", 0, 1);
       testCharAtOffset(IDs, 1, "e", 1, 2);
       testCharAtOffset(IDs, 14, "d", 14, 15);
       testCharAtOffset(IDs, 15, "", 15, 15);
 
       testCharAfterOffset(IDs, 0, "e", 1, 2);
       testCharAfterOffset(IDs, 1, "l", 2, 3);
       testCharAfterOffset(IDs, 14, "", 15, 15);
-
-      // 15 is out of range offset for get text after, keep todos until we
-      // decide how to handle out of range values (ATK and IA2 seems to have
-      // different expectations.
-      testTextAfterOffset(15, BOUNDARY_CHAR, "", 15, 15,
-                          "i1", kOk, kTodo, kTodo,
-                          "d1", kOk, kTodo, kTodo,
-                          "e1", kOk, kTodo, kTodo,
-                          "t1", kOk, kTodo, kTodo);
+      testCharAfterOffset(IDs, 15, "", 15, 15);
 
       //////////////////////////////////////////////////////////////////////////
       //
       // __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n
       //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21
 
       IDs = [ "i2", "d2", "e2", "t2" ];
 
--- a/accessible/tests/mochitest/text/test_lineboundary.html
+++ b/accessible/tests/mochitest/text/test_lineboundary.html
@@ -104,21 +104,33 @@
       testTextAtOffset([ getAccessible("ht_2").firstChild.firstChild ],
                        BOUNDARY_LINE_START,
                        [ [ 0, 3, "foo", 0, 3 ] ]);
       testTextAtOffset([ getAccessible("ht_3").firstChild.firstChild ],
                        BOUNDARY_LINE_START,
                        [ [ 0, 3, "foo\n", 0, 4 ], [ 4, 4, "", 4, 4 ] ]);
 
       //////////////////////////////////////////////////////////////////////////
+      // 'Hello world ' (\n is rendered as space)
+
+      testTextAtOffset([ "ht_4" ], BOUNDARY_LINE_START,
+                       [ [ 0, 12, "Hello world ", 0, 12 ] ]);
+
+      //////////////////////////////////////////////////////////////////////////
       // list items
 
       testTextAtOffset([ "li1" ], BOUNDARY_LINE_START,
                        [ [ 0, 5, kDiscBulletChar + "Item", 0, 5 ] ]);
 
+      //////////////////////////////////////////////////////////////////////////
+      // Nested hypertexts
+
+      testTextAtOffset(["ht_5" ], BOUNDARY_LINE_START,
+                       [ [ 0, 0, kEmbedChar, 0, 1 ] ]);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
@@ -133,17 +145,22 @@
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=855732">
     Bug 855732
   </a>
   <a target="_blank"
      title=" getTextAfterOffset for line boundary on new rails"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=882292">
     Bug 882292
   </a>
-  
+  <a target="_blank"
+     title="getTextAtOffset broken for last object when closing tag is preceded by newline char"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=947170">
+    Bug 947170
+  </a>
+
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <input id="input" value="hello my friend"/>
   <div id="div">hello my friend</div>
   <div id="editable" contenteditable="true">hello my friend</div>
@@ -168,13 +185,23 @@ two words
 </textarea>
   </pre>
 
   <iframe id="ht_1" src="data:text/html,<html><body>a <a href=''>b</a> c</body></html>"></iframe>
 
   <iframe id="ht_2" src="data:text/html,<div contentEditable='true'>foo<br/></div>"></iframe>
   <iframe id="ht_3" src="data:text/html,<div contentEditable='true'>foo<br/><br/></div>"></iframe>
 
+  <p id="ht_4">Hello world
+</p>
+
   <ul>
     <li id="li1">Item</li>
   </ul>
+
+  <div id="ht_5">
+    <div>
+      <p>sectiounus</p>
+      <p>seciofarus</p>
+    </div>
+  </div>
 </body>
 </html>
--- a/accessible/tests/mochitest/tree/test_aria_globals.html
+++ b/accessible/tests/mochitest/tree/test_aria_globals.html
@@ -42,18 +42,19 @@
 
       for (var idx = 0; idx < globalIds.length; idx++) {
         ok(isAccessible(globalIds[idx]),
            "Must be accessible becuase of " + "aria-" + globalIds[idx] +
            " presence");
       }
 
       // Unfocusable elements, having ARIA global state or property with a valid
-      // IDREF value, and an inherited presentation role.
-      ok(!isAccessible("td_nothing"),
+      // IDREF value, and an inherited presentation role. A generic accessible
+      // is created (to prevent table cells text jamming).
+      ok(!isAccessible("td_nothing", nsIAccessibleTableCell),
          "inherited presentation role takes a place");
 
       for (var idx = 0; idx < globalIds.length; idx++) {
         ok(isAccessible("td_" + globalIds[idx]),
            "Inherited presentation role must be ignored becuase of " +
            "aria-" + globalIds[idx] + " presence");
       }
 
--- a/accessible/tests/mochitest/tree/test_aria_grid.html
+++ b/accessible/tests/mochitest/tree/test_aria_grid.html
@@ -42,20 +42,25 @@
             role: ROLE_ROW,
             tagName: "DIV",
             children: [
               { // caption text leaf
                 role: ROLE_TEXT_LEAF,
                 name: "caption",
                 children: [ ]
               },
-              { // th text leaf
-                role: ROLE_TEXT_LEAF,
-                name: "header1",
-                children: [ ]
+              { // th generic accessible
+                role: ROLE_TEXT_CONTAINER,
+                children: [
+                  { // th text leaf
+                    role: ROLE_TEXT_LEAF,
+                    name: "header1",
+                    children: [ ]
+                  }
+                ]
               },
               { // td@role="columnheader"
                 role: ROLE_COLUMNHEADER,
                 name: "header2",
                 children: [ { TEXT_LEAF: [ ] } ]
               }
             ]
           }
@@ -65,20 +70,25 @@
 
       accTree = {
         role: ROLE_TABLE,
         children: [
           { // tr@role="row"
             role: ROLE_ROW,
             tagName: "TR",
             children: [
-              { // td text leaf
-                role: ROLE_TEXT_LEAF,
-                name: "cell1",
-                children: [ ]
+              { // td generic accessible
+                role: ROLE_TEXT_CONTAINER,
+                children: [
+                  { // td text leaf
+                    role: ROLE_TEXT_LEAF,
+                    name: "cell1",
+                    children: [ ]
+                  }
+                ]
               },
               { // td@role="gridcell"
                 role: ROLE_GRID_CELL,
                 name: "cell2",
                 children: [ { TEXT_LEAF: [ ] } ]
               }
             ]
           }
@@ -90,20 +100,25 @@
         role: ROLE_TABLE,
         children: [
           { // div@role="row"
             role: ROLE_ROW,
             children: [
               { // div@role="gridcell"
                 role: ROLE_GRID_CELL,
                 children: [
-                  { // text leaf from presentational table
-                    role: ROLE_TEXT_LEAF,
-                    name: "cell3",
-                    children: [ ]
+                  { // td generic accessible
+                    role: ROLE_TEXT_CONTAINER,
+                    children: [
+                      { // text leaf from presentational table
+                        role: ROLE_TEXT_LEAF,
+                        name: "cell3",
+                        children: [ ]
+                      }
+                    ]
                   },
                 ]
               }
             ]
           }
         ]
       };
       testAccessibleTree("crazy_grid3", accTree);
@@ -126,20 +141,25 @@
                           { // td
                             role: ROLE_CELL,
                             children: [
                               { // caption text leaf of presentational table
                                  role: ROLE_TEXT_LEAF,
                                  name: "caption",
                                  children: [ ]
                               },
-                              { // td text leaf of presentational table
-                                role: ROLE_TEXT_LEAF,
-                                name: "cell4",
-                                children: [ ]
+                              { // td generic accessible
+                                role: ROLE_TEXT_CONTAINER,
+                                children: [
+                                  { // td text leaf of presentational table
+                                    role: ROLE_TEXT_LEAF,
+                                    name: "cell4",
+                                    children: [ ]
+                                  }
+                                ]
                               }
                             ]
                           }
                         ]
                       }
                     ]
                   }
                 ]
--- a/accessible/tests/mochitest/tree/test_aria_presentation.html
+++ b/accessible/tests/mochitest/tree/test_aria_presentation.html
@@ -32,17 +32,19 @@
           { TEXT_LEAF: [ ] }
         ] }
       ] };
     testAccessibleTree("btn_cnt", tree);
 
     // Presentation table, no table structure is exposed.
     tree =
       { SECTION: [ // container
-        { TEXT_LEAF: [ ] } // cell text
+        { TEXT_CONTAINER: [ // td generic accessible
+          { TEXT_LEAF: [ ] } // cell text
+        ] }
       ] };
     testAccessibleTree("tbl_cnt", tree);
 
     // Focusable table, presentation role is ignored.
     tree =
       { SECTION: [ // container
         { TABLE: [ // table
           { ROW: [ // tr
--- a/accessible/tests/mochitest/tree/test_brokencontext.html
+++ b/accessible/tests/mochitest/tree/test_brokencontext.html
@@ -11,38 +11,75 @@
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
   <script type="application/javascript"
           src="../states.js"></script>
 
   <script type="application/javascript">
+  /**
+   * Return true if TD element has a generic accessible.
+   */
+  function isTDGeneric(aID)
+  {
+    return isAccessible(aID) && !isAccessible(aID, nsIAccessibleTableCell);
+  }
+
+  function checkIfNotAccessible(aID)
+  {
+    ok(!isAccessible(aID), "'" + aID + "' shouldn't be accessible");
+  }
+  function checkIfTDGeneric(aID)
+  {
+    ok(isTDGeneric(aID), "'" + aID + "' shouldn't have cell accessible");
+  }
+
   function doTest()
   {
     ////////////////////////////////////////////////////////////////////////////
     // HTML table elements outside table context.
 
-    ok(!isAccessible("tr_in_presentation_table"), "tr shouldn't be accessible");
-    ok(!isAccessible("th_in_presentation_table"), "th shouldn't be accessible");
-    ok(!isAccessible("td_in_presentation_table"), "td shouldn't be accessible");
+    // HTML table role="presentation"
+    checkIfNotAccessible("tr_in_presentation_table");
+    checkIfTDGeneric("th_in_presentation_table");
+    checkIfTDGeneric("td_in_presentation_table");
 
+    // HTML table role="button"
     var tree =
       { PUSHBUTTON: [ // table
           { NOTHING: [ // tr
             { NOTHING: [ // th
               { TEXT_LEAF: [ ] }
             ] },
             { NOTHING: [ // td
               { TEXT_LEAF: [ ] }
             ] }
           ] }
       ] };
     testAccessibleTree("button_table", tree);
 
+    // HTML table display:inline
+    checkIfNotAccessible("inline_table1");
+    checkIfNotAccessible("tr_in_inline_table1");
+    checkIfTDGeneric("td1_in_inline_table1");
+    checkIfTDGeneric("td2_in_inline_table1");
+
+    // HTML table display:inline inside table. We shouldn't be fooled
+    // by the outside table and shouldn't create table accessible and table cell
+    // accessible in this case.
+    checkIfNotAccessible("inline_table2");
+    checkIfNotAccessible("tr_in_inline_table2");
+    checkIfTDGeneric("td_in_inline_table2");
+
+    // HTML table display:block inside table. 
+    checkIfNotAccessible("block_table");
+    checkIfNotAccessible("tr_in_block_table");
+    checkIfTDGeneric("td_in_block_table");
+
     ////////////////////////////////////////////////////////////////////////////
     // HTML list elements outside list context.
 
     ok(!isAccessible("presentation_ul"),
                      "presentational ul shouldn't be accessible");
     ok(!isAccessible("item_in_presentation_ul"),
                      "li in presentational ul shouldn't be accessible");
     ok(!isAccessible("styleditem_in_presentation_ul"),
@@ -120,22 +157,27 @@
   addA11yLoadEvent(doTest);
   </script>
 </head>
 
 <body>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=706849"
      title="Create accessible by tag name as fallback if table descendant style is used out of table context">
-    Mozilla Bug 706849
+    Bug 706849
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=804461"
      title="Build the context dependent tree ">
-    Mozilla Bug 804461
+    Bug 804461
+  </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=945435"
+     title="Create generic accessible for td to not jamm the cell text">
+    Bug 945435
   </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <!-- HTML table elements out of table -->
   <table role="presentation">
@@ -147,16 +189,44 @@
 
   <table role="button" id="button_table">
     <tr id="tr_in_button_table">
       <th id="th_in_button_table">not a header</th>
       <td id="td_in_button_table">not a cell</td>
     </tr>
   </table>
 
+   <table id="inline_table1" border="1" style="display:inline">
+    <tr id="tr_in_inline_table1">
+     <td id="td1_in_inline_table1">table1 cell1</td>
+     <td id="td2_in_inline_table1">table1 cell2</td>
+    </tr>
+   </table>
+
+   <table id="table_containing_inlinetable"><tr><td>
+     <table id="inline_table2" border="1" style="display:inline">
+      <tr id="tr_in_inline_table2">
+       <td id="td_in_inline_table2">cell</td>
+      </tr>
+     </table>
+   </td></tr></table>
+
+  <table>
+    <tr>
+      <td style="display:block">
+        <table id="block_table" style="display:inline">
+          <tr id="tr_in_block_table">
+            <td id="td_in_block_table">cell0</td>
+          </tr>
+        </table>
+      </td>
+      <td>cell1</td>
+   </tr>
+  </table>
+
   <!-- HTML list elements out of list -->
   <ul role="presentation" id="presentation_ul">
     <li id="item_in_presentation_ul">item</li>
     <span id="styleditem_in_presentation_ul"
           style="display:list-item">Oranges</span>
   </ul>
 
   <ol role="presentation" id="presentation_ol">
--- a/accessible/tests/mochitest/tree/test_formctrl.html
+++ b/accessible/tests/mochitest/tree/test_formctrl.html
@@ -65,18 +65,17 @@
 
       // input@type="number"
       accTree =
         { SPINBUTTON: [
           { ENTRY: [ ] },
           { PUSHBUTTON: [ ] },
           { PUSHBUTTON: [ ] }
         ] };
-      // number is disabled in v28
-      //testAccessibleTree("number", accTree);
+      testAccessibleTree("number", accTree);
 
       // output
       accTree = {
         role: ROLE_SECTION,
         children: [
           {
             role: ROLE_TEXT_LEAF
           }
--- a/accessible/tests/mochitest/tree/test_formctrl.xul
+++ b/accessible/tests/mochitest/tree/test_formctrl.xul
@@ -1,16 +1,24 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                  type="text/css"?>
 
+<!-- Firefox toolbar -->
+<?xml-stylesheet href="chrome://browser/content/browser.css"
+                 type="text/css"?>
+
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         title="Accessible XUL checkbox and radio hierarchy tests">
 
+  <!-- Firefox toolbar -->
+  <script type="application/javascript"
+          src="chrome://browser/content/browser.js"/>
+
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
 
   <script type="application/javascript"
           src="../common.js" />
   <script type="application/javascript"
           src="../role.js" />
 
@@ -71,16 +79,19 @@
             name: "hello",
             children: [ ]
           }
         ]
       };
 
       testAccessibleTree("toolbar2", accTree);
 
+      if (!SEAMONKEY)
+        testAccessibleTree("tb_customizable", { TOOLBAR: [] });
+
       SimpleTest.finish()
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
   </script>
 
@@ -105,13 +116,15 @@
         <radio label="radio2"/>
       </radiogroup>
       <toolbar id="toolbar" toolbarname="My toolbar">
         <toolbarbutton id="button1" label="hello"/>
       </toolbar>
       <toolbar id="toolbar2" toolbarname="2nd" aria-label="My second toolbar">
         <toolbarbutton id="button2" label="hello"/>
       </toolbar>
+
+      <toolbar id="tb_customizable" customizable="true"/>
     </vbox>
   </hbox>
 
 </window>
 
--- a/accessible/tests/mochitest/treeupdate/a11y.ini
+++ b/accessible/tests/mochitest/treeupdate/a11y.ini
@@ -1,12 +1,14 @@
 [DEFAULT]
 
 [test_ariadialog.html]
 [test_bug852150.xhtml]
+[test_bug883708.xhtml]
+[test_bug884251.xhtml]
 [test_bug895082.html]
 [test_canvas.html]
 [test_colorpicker.xul]
 [test_contextmenu.xul]
 [test_cssoverflow.html]
 [test_deck.xul]
 [test_doc.html]
 [test_gencontent.html]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/treeupdate/test_bug883708.xhtml
@@ -0,0 +1,33 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+<script>
+
+function boom()
+{
+  var newSpan = document.createElementNS("http://www.w3.org/1999/xhtml", "span");
+  c.insertBefore(newSpan, d);
+  a.style.visibility = "visible";
+  ok(true, "test didn't crash or assert");
+  SimpleTest.finish();
+}
+
+</script>
+</head>
+
+<body onload="boom();">
+  <a target="_blank"
+     title="test reparenting accessible subtree when inaccessible element becomes accessible"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=883708">
+    Mozilla Bug 883708
+  </a>
+
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+<div style="visibility: collapse;" id="a"><div style="float: right; visibility: visible;"><div id="c"><td id="d"></td></div></div></div></body>
+</html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/treeupdate/test_bug884251.xhtml
@@ -0,0 +1,21 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+<script>
+
+function boom()
+{
+  document.getElementById("k").removeAttribute("href");
+  ok(true, "changing iframe contents doesn't cause assertions");
+  SimpleTest.finish();
+}
+
+</script>
+</head>
+
+<body onload="boom();">
+<iframe src="data:text/html,1"><link id="k" href="data:text/html,2" /></iframe>
+</body>
+</html>
--- a/addon-sdk/moz.build
+++ b/addon-sdk/moz.build
@@ -1,6 +1,7 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
+BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/addon-sdk/source/README
+++ b/addon-sdk/source/README
@@ -1,38 +1,39 @@
 Add-on SDK README
 ==================
 
 Before proceeding, please make sure you've installed Python 2.5,
 2.6, or 2.7 (if it's not already on your system):
 
   http://python.org/download/
 
-Note that Python 3.0 and 3.1 are not supported in this release.
+Note that Python 3 is not supported on any platform, and Python 2.7.6 
+is not supported on Windows.
 
 For Windows users, MozillaBuild (https://wiki.mozilla.org/MozillaBuild)
 will install the correct version of Python and the MSYS package, which
 will make it easier to work with the SDK.
 
 To get started, first enter the same directory that this README file
 is in (the SDK's root directory) using a shell program. On Unix systems
 or on Windows with MSYS, you can execute the following command:
 
   source bin/activate
 
 Windows users using cmd.exe should instead run:
 
   bin\activate.bat
 
-Then go to https://addons.mozilla.org/developers/docs/sdk/latest/dev-guide to
-browse the SDK documentation.
+Then go to https://developer.mozilla.org/en-US/Add-ons/SDK/
+to browse the SDK documentation.
 
 If you get an error when running cfx or have any other problems getting
 started, see the "Troubleshooting" guide at:
-https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/tutorials/troubleshooting.html
+https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Troubleshooting
 
 Bugs
 -------
 
 * file a bug: https://bugzilla.mozilla.org/enter_bug.cgi?product=Add-on%20SDK
 
 
 Style Guidelines
--- a/addon-sdk/source/app-extension/bootstrap.js
+++ b/addon-sdk/source/app-extension/bootstrap.js
@@ -216,16 +216,18 @@ function startup(data, reasonCode) {
       prefixURI: prefixURI,
       // Add-on URI.
       rootURI: rootURI,
       // options used by system module.
       // File to write 'OK' or 'FAIL' (exit code emulation).
       resultFile: options.resultFile,
       // Arguments passed as --static-args
       staticArgs: options.staticArgs,
+      // Add-on preferences branch name
+      preferencesBranch: options.preferencesBranch,
 
       // Arguments related to test runner.
       modules: {
         '@test/options': {
           allTestModules: options.allTestModules,
           iterations: options.iterations,
           filter: options.filter,
           profileMemory: options.profileMemory,
--- a/addon-sdk/source/app-extension/install.rdf
+++ b/addon-sdk/source/app-extension/install.rdf
@@ -13,17 +13,17 @@
     <em:bootstrap>true</em:bootstrap>
     <em:unpack>false</em:unpack>
 
     <!-- Firefox -->
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>21.0</em:minVersion>
-        <em:maxVersion>25.0a1</em:maxVersion>
+        <em:maxVersion>29.0a1</em:maxVersion>
       </Description>
     </em:targetApplication>
 
     <!-- Front End MetaData -->
     <em:name>Test App</em:name>
     <em:description>Harness for tests.</em:description>
     <em:creator>Mozilla Corporation</em:creator>
     <em:homepageURL></em:homepageURL>
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/cfx-tool.md
+++ /dev/null
@@ -1,932 +0,0 @@
-<!-- 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/. -->
-
-# cfx #
-
-The `cfx` command-line tool gives you access to the SDK documentation and
-development servers as well as testing, running, and building add-ons.
-`cfx` usage is:
-
-<pre>
-  cfx [options] command [command-specific options]
-</pre>
-
-"Options" are global options applicable to the tool itself or to all
-commands (for example `--help`). `cfx` supports the following global options:
-
-<pre>
-  -h, --help        - show a help message and exit
-  -v, --verbose     - enable lots of output
-</pre>
-
-"Command-specific options" are documented alongside the commands.
-
-There are four supported cfx commands:
-
-<table>
-  <colgroup>
-    <col width="10%">
-    <col width="90%">
-  </colgroup>
-
-  <tr>
-    <td>
-      <a href="dev-guide/cfx-tool.html#cfx-init"><code>cfx init</code></a>
-    </td>
-    <td>
-      Create a skeleton add-on as a starting point for your own add-on.
-    </td>
-  </tr>
-
-  <tr>
-    <td>
-      <a href="dev-guide/cfx-tool.html#cfx-run"><code>cfx run</code></a>
-    </td>
-    <td>
-      Launch an instance of Firefox with your add-on installed.
-    </td>
-  </tr>
-
-  <tr>
-    <td>
-      <a href="dev-guide/cfx-tool.html#cfx-test"><code>cfx test</code></a>
-    </td>
-    <td>
-      Runs your add-on's unit tests.
-    </td>
-  </tr>
-
-  <tr>
-    <td>
-      <a href="dev-guide/cfx-tool.html#cfx-xpi"><code>cfx xpi</code></a>
-    </td>
-    <td>
-      Package your add-on as an <a href="https://developer.mozilla.org/en/XPI">XPI</a>
-      file, which is the install file format for Firefox add-ons.
-    </td>
-  </tr>
-
-</table>
-
-There are also a number of
-[internal commands](dev-guide/cfx-tool.html#internal-commands),
-which are more likely to be useful to SDK developers than to add-on developers.
-
-## <a name="cfx-init">cfx init</a> ##
-
-Create a new directory called "my-addon", change into it, and run `cfx init`.
-
-This command will create an skeleton add-on, as a starting point for your
-own add-on development, with the following file structure:
-
-<ul class="tree">
-  <li>my-addon
-    <ul>
-    <li>data</li>
-    <li>docs
-      <ul><li>main.md</li></ul>
-    </li>
-    <li>lib
-      <ul><li>main.js</li></ul>
-    </li>
-    <li>package.json</li>
-    <li>README.md</li>
-    <li>tests
-      <ul><li>test-main.js</li></ul>
-    </li>
-    </ul>
-  </li>
-</ul>
-
-<div style="clear:both"></div>
-
-## <a name="cfx-run">cfx run</a> ##
-This command is used to run the add-on. Called with no options it looks for a
-file called `package.json` in the current directory, loads the corresponding
-add-on, and runs it under the version of Firefox it finds in the platform's
-default install path.
-
-### Supported Options ####
-
-You can point `cfx run` at a different `package.json` file using the
-`--pkgdir` option, and pass arguments to your add-on using the
-`--static-args` option.
-
-You can specify a different version of the
-<a href="dev-guide/glossary.html#host-application">host application</a>
-using the `--binary` option, passing in the path to the application binary to
-run. The path may be specified as a full path or may be relative to the current
-directory. But note that the version must be 4.0b7 or later.
-
-`cfx run` runs the host application with a new
-[profile](http://support.mozilla.com/en-US/kb/profiles). You can specify an
-existing profile using the `--profiledir` option, and this gives you access to
-that profile's history, bookmarks, and other add-ons. This enables you to run
-your add-on alongside debuggers like [Firebug](http://getfirebug.com/).
-See <a href="dev-guide/cfx-tool.html#profiledir">
-"Using --profiledir"</a> for more information.
-
-<table>
-<colgroup>
-<col width="30%">
-<col width="70%">
-</colgroup>
-
-<tr>
-  <td>
-    <code>-b BINARY, --binary=BINARY</code>
-  </td>
-  <td>
-    Use the host application binary specified in BINARY. BINARY may be specified as
-    a full path or as a path relative to the current directory.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--binary-args=CMDARGS</code>
-  </td>
-  <td>
-    <p>Pass <a href="http://kb.mozillazine.org/Command_line_arguments">extra
-    arguments</a> to the binary being executed (for example, Firefox).</p>
-    <p>For example, to pass the
-    <code>-jsconsole</code> argument to Firefox, which will launch the
-    <a href="https://developer.mozilla.org/en/Error_Console">JavaScript
-    Error Console</a>, try the following:</p>
-    <pre>cfx run --binary-args -jsconsole</pre>
-    <p>To pass multiple arguments, or arguments containing spaces, quote them:</p>
-    <pre>cfx run --binary-args '-url "www.mozilla.org" -jsconsole'</pre>
-    </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--extra-packages=EXTRA_PACKAGES</code>
-  </td>
-  <td>
-    Extra packages to include, specified as a comma-separated list of package
-    names.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>-g CONFIG, --use-config=CONFIG</code>
-  </td>
-  <td>
-    Pass a set of options by
-    <a href="dev-guide/cfx-tool.html#configurations">referencing a named configuration</a>.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>-p PROFILEDIR, --profiledir=PROFILEDIR</code>
-  </td>
-  <td>
-    <p>Use an existing
-    <a href="http://support.mozilla.com/en-US/kb/profiles">profile</a>
-    located in PROFILEDIR. PROFILEDIR may be specified as
-    a full path or as a path relative to the current directory.</p>
-
-    <p>See <a href="dev-guide/cfx-tool.html#profiledir">
-    "Using --profiledir"</a> for more information.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--pkgdir=PKGDIR</code>
-  </td>
-  <td>
-    Use an add-on located in PKGDIR. PKGDIR may be specified as
-    a full path or as a path relative to the current directory.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--static-args=STATIC_ARGS</code>
-  </td>
-  <td>
-    <a href="dev-guide/cfx-tool.html#arguments">Pass arguments to your add-on</a>,
-    in JSON format.
-  </td>
-</tr>
-
-</table>
-
-### Experimental Options ###
-
-<table>
-<colgroup>
-<col width="30%">
-<col width="70%">
-</colgroup>
-
-<tr>
-  <td>
-    <code>-a APP, --app=APP</code>
-  </td>
-  <td>
-    By default, <code>cfx run</code> uses Firefox as the
-    <a href="dev-guide/glossary.html#host-application">host application</a>.
-    This option enables you to select a different host. You can specify
-    "firefox", "xulrunner", "fennec", or "thunderbird". But note that at
-    present only Firefox is supported.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--no-run</code>
-  </td>
-  <td>
-    <p>With this option <code>cfx</code> will not execute the command, but
-    will print out the command that it would have used to execute the
-    command.</p>
-    <p>For example, if you type:</p>
-    <pre>
-cfx run ---no-run</pre>
-    <p>you will see something like:</p>
-    <pre>
-To launch the application, enter the following command:
- /path/to/firefox/firefox-bin -profile
- /path/to/profile/tmpJDNlP6.mozrunner -foreground -no-remote</pre>
-    <p>This enables you to run the add-on without going through
-    <code>cfx</code>, which might be useful if you want to run it
-    inside a debugger like GDB.</p>
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>-o, --overload-modules</code>
-  </td>
-  <td>
-    <p>In early versions of the SDK, the SDK modules used by an add-on
-    were themselves included in the add-on. The SDK modules now ship as
-    part of Firefox. From Firefox 21 onwards, SDK add-ons built with
-    SDK 1.14 or higher will use the SDK modules that are built into Firefox,
-    even if the add-on includes its own copies of the SDK modules.</p>
-    <p>Use this flag to reverse that behavior: if this flag is set and
-    the add-on includes its own copies of the SDK modules, then the add-on
-    will use the SDK modules in the add-on, not the ones built into Firefox.</p>
-    <p>This flag is particularly useful for SDK developers or people working with
-    the development version of the SDK, who may want to run an add-on using newer
-    versions of the modules than than those shipping in Firefox.</p>
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--templatedir=TEMPLATEDIR</code>
-  </td>
-  <td>
-    The <code>cfx run</code> command constructs the add-on using a extension
-    template which you can find under the SDK root, in
-    <code>app-extension</code>.
-    Use the <code>--templatedir</code> option to specify a different template.
-    TEMPLATEDIR may be specified as a full path or as a path relative to the
-    current directory.
-  </td>
-</tr>
-
-</table>
-
-### Internal Options ###
-
-<table>
-<colgroup>
-<col width="30%">
-<col width="70%">
-</colgroup>
-
-<tr>
-  <td>
-    <code>--addons=ADDONS</code>
-  </td>
-  <td>
-    Paths of add-ons to install, comma-separated. ADDONS may be specified as
-    a full path or as a path relative to the current directory.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--e10s</code>
-  </td>
-  <td>
-    If this option is set then the add-on runs in a separate process.
-    This option is currently not implemented.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--keydir=KEYDIR</code>
-  </td>
-  <td>
-    Supply a different location for
-    <a href="dev-guide/guides/program-id.html">signing keys</a>.
-    KEYDIR may be specified as a full path or as a path relative to the
-    current directory.
-  </td>
-</tr>
-
-</table>
-
-## <a name="cfx-test">cfx test</a> ##
-Run available tests for the specified package.
-
-<span class="aside">Note the hyphen after "test" in the module name.
-`cfx test` will include a module called "test-myCode.js", but will exclude
-modules called "test_myCode.js" or "testMyCode.js".</span>
-
-Called with no options this command will look for a file called `package.json`
-in the current directory. If `package.json` exists, `cfx` will load the
-corresponding add-on, load from the `tests` directory
-any modules that start with the word `test-` and run the unit tests
-they contain.
-
-See the
-[tutorial on unit testing](dev-guide/tutorials/unit-testing.html) and the
-[reference documentation for the `assert` module](modules/sdk/test/assert.html)
-for details.
-
-### Supported Options ###
-
-As with `cfx run` you can use options to control which host application binary
-version to use, and to select a profile.
-
-You can also control which tests are run: you
-can test dependent packages, filter the tests by name and run tests multiple
-times.
-
-<table>
-<colgroup>
-<col width="30%">
-<col width="70%">
-</colgroup>
-
-<tr>
-  <td>
-    <code>-b BINARY, --binary=BINARY</code>
-  </td>
-  <td>
-    Use the host application binary specified in BINARY. BINARY may be specified as
-    a full path or as a path relative to the current directory.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--binary-args=CMDARGS</code>
-  </td>
-  <td>
-    <p>Pass <a href="http://kb.mozillazine.org/Command_line_arguments">extra
-    arguments</a> to the binary being executed (for example, Firefox).</p>
-    <p>For example, to pass the
-    <code>-jsconsole</code> argument to Firefox, which will launch the
-    <a href="https://developer.mozilla.org/en/Error_Console">JavaScript
-    Error Console</a>, try the following:</p>
-    <pre>cfx run --binary-args -jsconsole</pre>
-    <p>To pass multiple arguments, or arguments containing spaces, quote them:</p>
-    <pre>cfx run --binary-args '-url "www.mozilla.org" -jsconsole'</pre>
-    </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--dependencies</code>
-  </td>
-  <td>
-    Load and run any tests that are included with modules that your package
-    depends on.
-    <br>
-    For example: if your add-on depends on modules from the SDK, then
-    <code>cfx</code> will run the unit tests for the SDK's modules as well
-    as yours.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>-f FILENAME[:TESTNAME], --filter=FILENAME[:TESTNAME]</code>
-  </td>
-  <td>
-    Only run tests whose filenames match FILENAME and
-    optionally match TESTNAME, both regexps (test, testall, testex, testpkgs)
-    <br>
-    For example: if you specify <code>--filter data</code>, then
-    <code>cfx</code> will only run tests in those modules whose name contain
-    the string "data".
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>-g CONFIG, --use-config=CONFIG</code>
-  </td>
-  <td>
-    Pass a set of options by
-    <a href="dev-guide/cfx-tool.html#configurations">referencing a named configuration</a>.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>-p PROFILEDIR, --profiledir=PROFILEDIR</code>
-  </td>
-  <td>
-    <p>Use an existing
-    <a href="http://support.mozilla.com/en-US/kb/profiles">profile</a>
-    located in PROFILEDIR. PROFILEDIR may be specified as
-    a full path or as a path relative to the current directory.</p>
-
-    <p>See <a href="dev-guide/cfx-tool.html#profiledir">
-    "Using --profiledir"</a> for more information.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--times=ITERATIONS</code>
-  </td>
-  <td>
-    Execute tests ITERATIONS number of times.
-  </td>
-</tr>
-
-</table>
-
-### Experimental Options ###
-
-<table>
-<colgroup>
-<col width="30%">
-<col width="70%">
-</colgroup>
-
-<tr>
-  <td>
-    <code>-a APP, --app=APP</code>
-  </td>
-  <td>
-    By default, <code>cfx test</code> uses Firefox as the
-    <a href="dev-guide/glossary.html#host-application">host application</a>.
-    This option enables you to select a different host. You can specify
-    "firefox", "xulrunner", "fennec", or "thunderbird". But note that at
-    present only Firefox is supported.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--no-run</code>
-  </td>
-  <td>
-    <p>With this option <code>cfx</code> will not execute the command, but
-    will print out the command that it would have used to execute the
-    command.</p>
-    <p>For example, if you type:</p>
-    <pre>
-cfx run ---no-run</pre>
-    <p>you will see something like:</p>
-    <pre>
-To launch the application, enter the following command:
- /path/to/firefox/firefox-bin -profile
- /path/to/profile/tmpJDNlP6.mozrunner -foreground -no-remote</pre>
-    <p>This enables you to run the add-on without going through
-    <code>cfx</code>, which might be useful if you want to run it
-    inside a debugger like GDB.</p>
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>-o, --overload-modules</code>
-  </td>
-  <td>
-    <p>In early versions of the SDK, the SDK modules used by an add-on
-    were themselves included in the add-on. The SDK modules now ship as
-    part of Firefox. From Firefox 21 onwards, SDK add-ons built with
-    SDK 1.14 or higher will use the SDK modules that are built into Firefox,
-    even if the add-on includes its own copies of the SDK modules.</p>
-    <p>Use this flag to reverse that behavior: if this flag is set and
-    the add-on includes its own copies of the SDK modules, then the add-on
-    will use the SDK modules in the add-on, not the ones built into Firefox.</p>
-    <p>This flag is particularly useful for SDK developers or people working with
-    the development version of the SDK, who may want to run an add-on using newer
-    versions of the modules than than those shipping in Firefox.</p>
-  </td>
-</tr>
-
-</table>
-
-### Internal Options ###
-
-<table>
-<colgroup>
-<col width="30%">
-<col width="70%">
-</colgroup>
-
-<tr>
-  <td>
-    <code>--addons=ADDONS</code>
-  </td>
-  <td>
-    Paths of add-ons to install, comma-separated.
-    ADDONS may be specified as full paths or relative to the
-    current directory.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--e10s</code>
-  </td>
-  <td>
-    If this option is set then the add-on runs in a separate process.
-    This option is currently not implemented.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--keydir=KEYDIR</code>
-  </td>
-  <td>
-    Supply a different location for
-    <a href="dev-guide/guides/program-id.html">signing keys</a>.
-    KEYDIR may be specified as a full path or as a path relative to the
-    current directory.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--logfile=LOGFILE</code>
-  </td>
-  <td>
-    Log console output to the file specified by LOGFILE.
-    LOGFILE may be specified as a full path or as a path relative to the
-    current directory.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--profile-memory=PROFILEMEMORY</code>
-  </td>
-  <td>
-    If this option is given and PROFILEMEMORY is any non-zero integer, then
-    <code>cfx</code> dumps detailed memory usage information to the console
-    when the tests finish.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--test-runner-pkg=TEST_RUNNER_PKG</code>
-  </td>
-  <td>
-    Name of package containing test runner program. Defaults to
-    <code>test-harness</code>.
-  </td>
-</tr>
-
-</table>
-
-## <a name="cfx-xpi">cfx xpi</a> ##
-This tool is used to package your add-on as an
-[XPI](https://developer.mozilla.org/en/XPI) file, which is the install file
-format for Mozilla add-ons.
-
-Called with no options, this command looks for a file called `package.json` in
-the current directory and creates the corresponding XPI file.
-
-Once you have built an XPI file you can distribute your add-on by submitting
-it to [addons.mozilla.org](http://addons.mozilla.org).
-
-### updateURL and updateLink ###
-
-If you choose to host the XPI yourself you should enable the host application
-to find new versions of your add-on.
-
-To do this, include a URL in the XPI called the
-[updateURL](https://developer.mozilla.org/en/install_manifests#updateURL): the
-host application will go here to get information about updates. At the
-`updateURL` you host a file in the
-[update RDF](https://developer.mozilla.org/en/extension_versioning,_update_and_compatibility#Update_RDF_Format)
-format: among other things, this includes another URL called `updateLink` which
-points to the updated XPI itself.
-
-The `--update-link` and `--update-url` options simplify this process.
-Both options take a URL as an argument.
-
-The `--update-link` option builds an update RDF alongside the XPI, and embeds
-the supplied URL in the update RDF as the value of `updateLink`.
-
-The `--update-url` option embeds the supplied URL in the XPI file, as the value
-of `updateURL`.
-
-Note that as the [add-on documentation](https://developer.mozilla.org/en/extension_versioning,_update_and_compatibility#Securing_Updates)
-explains, you should make sure the update procedure for your add-on is secure,
-and this usually involves using HTTPS for the links.
-
-So if we run the following command:
-
-<pre>
-  cfx xpi --update-link https://example.com/addon/latest/pluginName.xpi --update-url https://example.com/addon/update_rdf/pluginName.update.rdf
-</pre>
-
-`cfx` will create two files:
-
-* an XPI file which embeds
-`https://example.com/addon/update_rdf/pluginName.update.rdf` as the value of `updateURL`
-* an RDF file which embeds `https://example.com/addon/latest/pluginName.xpi` as the value of
-`updateLink`.
-
-### Supported Options ###
-
-As with `cfx run` you can point `cfx` at a different `package.json` file using
-the `--pkgdir` option. You can also embed arguments in the XPI using the
-`--static-args` option: if you do this the arguments will be passed to your
-add-on whenever it is run.
-
-<table>
-<colgroup>
-<col width="50%">
-<col width="50%">
-</colgroup>
-
-<tr>
-  <td>
-    <code>--extra-packages=EXTRA_PACKAGES</code>
-  </td>
-  <td>
-   Extra packages to include, specified as a comma-separated list of package
-   names.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>-g CONFIG, --use-config=CONFIG</code>
-  </td>
-  <td>
-    Pass a set of options by
-    <a href="dev-guide/cfx-tool.html#configurations">referencing a named configuration</a>.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--pkgdir=PKGDIR</code>
-  </td>
-  <td>
-    Use an add-on located in PKGDIR.
-    PKGDIR may be specified as a full path or as a path relative to the
-    current directory.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--static-args=STATIC_ARGS</code>
-  </td>
-  <td>
-    <a href="dev-guide/cfx-tool.html#arguments">Pass arguments to your add-on</a>,
-    in JSON format.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--update-link=UPDATE_LINK</code>
-  </td>
-  <td>
-    Build an
-    <a href="https://developer.mozilla.org/en/extension_versioning,_update_and_compatibility#Update_RDF_Format">update RDF</a>
-    alongside the XPI file, and embed the URL supplied in UPDATE_LINK in it as
-    the value of <code>updateLink</code>.
-  </td>
-</tr>
-
-<tr>
-  <td>
-    <code>--update-link=UPDATE_URL</code>
-  </td>
-  <td>
-    Embed the URL supplied in UPDATE_URL in the XPI file, as the value
-    of <code>updateURL</code>.
-  </td>
-</tr>
-
-</table>
-
-### Experimental Options ###
-
-<table>
-<colgroup>
-<col width="50%">
-<col width="50%">
-</colgroup>
-
-<tr>
-  <td>
-    <code>--templatedir=TEMPLATEDIR</code>
-  </td>
-  <td>
-    The <code>cfx xpi</code> command constructs the add-on using a extension
-    template which you can find under the SDK root, in
-    <code>app-extension</code>.
-    Use the <code>--templatedir</code> option to specify a different template.
-    TEMPLATEDIR may be specified as a full path or as a path relative to the
-    current directory.
-  </td>
-</tr>
-
-</table>
-
-### Internal Options ###
-
-<table>
-<colgroup>
-<col width="50%">
-<col width="50%">
-</colgroup>
-
-<tr>
-  <td>
-    <code>--keydir=KEYDIR</code>
-  </td>
-  <td>
-    Supply a different location for
-    <a href="dev-guide/guides/program-id.html">signing keys</a>.
-    KEYDIR may be specified as a full path or as a path relative to the
-    current directory.
-  </td>
-</tr>
-
-</table>
-
-## <a name="internal-commands">Internal Commands</a> ##
-
-### cfx sdocs ###
-
-Executing this command builds a static HTML version of the SDK documentation
-that can be hosted on a web server.
-
-#### Options ####
-
-<table>
-<colgroup>
-<col width="50%">
-<col width="50%">
-</colgroup>
-
-<tr>
-  <td>
-    <code>--baseurl=BASEURL</code>
-  </td>
-  <td>
-    The root of the static docs tree, for example:
-    <code>http://example.com/sdk-docs/</code>.
-  </td>
-</tr>
-
-</table>
-
-### cfx testcfx ###
-
-This will run a number of tests on the cfx tool, including tests against the
-documentation. Use `cfx testcfx -v` for the specific list of tests.
-
-This accepts the same options as `cfx test`.
-
-### cfx testaddons ###
-
-This will run a number of test add-ons that are packaged with the SDK.
-
-This accepts the same options as `cfx test`.
-
-### cfx testpkgs ###
-
-This will test all of the available CommonJS packages. Note that the number
-of tests run and their success depends on what application they are run
-with, and which binary is used.
-
-This accepts the same options as `cfx test`.
-
-### cfx testex ###
-
-This will test all available example code. Note that the number
-of tests run and their success depends on what application they are run
-with, and which binary is used.
-
-This accepts the same options as `cfx test`.
-
-### cfx testall ###
-
-This will test *everything*: the cfx tool, all available CommonJS packages,
-and all examples.
-
-This accepts the same options as `cfx test`.
-
-## <a name="profiledir">Using --profiledir</a> ##
-
-By default, `cfx run` and `cfx test` use a new profile each time they
-are executed. This means that any profile-specific data entered from
-one run of `cfx` will not, by default, be available in the next run.
-
-This includes, for example, any extra add-ons you installed, or your
-history, or any data stored using the
-[simple-storage](modules/sdk/simple-storage.html) API.
-
-To make `cfx` use a specific profile, pass the `--profiledir` option,
-specifying the path to the profile you wish to use.
-
-If you give `--profiledir` a path to a nonexistent profile, `cfx`
-will create a profile there for you. So you just have to make up
-a path and name the first time, and keep using it:
-
-<pre>
-cfx run --profiledir="~/addon-dev/profiles/boogaloo"
-</pre>
-
-The path must contain at least one "/" (although you may specify
-just "./dir").
-
-## <a name="configurations">Using Configurations</a> ##
-
-The `--use-config` option enables you to specify a set of options as a named
-configuration in a file, then pass them to `cfx` by referencing the named set.
-
-You define configurations in a file called `local.json` which should live
-in the root directory of your SDK. Configurations are listed under a key called
-"configs".
-
-Suppose your the following `local.json` is as follows:
-
-<pre>
-  {
-      "configs": {
-          "ff40": ["-b", "/usr/bin/firefox-4.0"]
-      }
-  }
-</pre>
-
-You can run:
-
-<pre>
-  cfx test --use-config=ff40
-</pre>
-
-And it would be equivalent to:
-
-<pre>
-  cfx test -a firefox -b /usr/bin/firefox-4.0
-</pre>
-
-This method of defining configuration options can be used for all of the `run`,
-build, and test tools. If "default" is defined in the `local.json` cfx will use
-that configuration unless otherwise specified.
-
-## <a name="arguments">Passing Static Arguments</a> ##
-
-You can use the cfx `--static-args` option to pass arbitrary data to your
-program.  This may be especially useful if you run cfx from a script.
-
-The value of `--static-args` must be a JSON string.  The object encoded by the
-JSON becomes the `staticArgs` property of the
-[`system` module](modules/sdk/system.html).
-
-The default value of
-`--static-args` is `"{}"` (an empty object), so you don't have to worry about
-checking whether `staticArgs` exists in `system`.
-
-For example, if your add-on looks like this:
-
-    var system = require("sdk/system");
-    console.log(system.staticArgs.foo);
-
-And you run cfx like this:
-
-<pre>
-  cfx run --static-args="{ \"foo\": \"Hello from the command line\" }"
-</pre>
-
-Then your console should contain this:
-
-<pre>
-info: my-addon: Hello from the command line
-</pre>
-
-The `--static-args` option is recognized by two of the package-specific
-commands: `run` and `xpi`.  When used with the `xpi` command, the JSON is
-packaged with the XPI's harness options and will therefore be used whenever the
-program in the XPI is run.
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/console.md
+++ /dev/null
@@ -1,207 +0,0 @@
-<!-- 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/. -->
-
-# console #
-
-The `console` object enables your add-on to log messages. If you have started
-Firefox for your add-on from the command line with `cfx run` or `cfx test`
-then these messages appear in the command shell you used. If the add-on has
-been installed in Firefox, then the messages appear in the host application's
-[Error Console](https://developer.mozilla.org/en/Error_Console).
-
-If you're developing your add-on using the
-[Add-on Builder](https://builder.addons.mozilla.org/) or are using
-the [Extension Auto-installer](https://addons.mozilla.org/en-US/firefox/addon/autoinstaller/),
-then the add-on is installed in Firefox, meaning that messages will appear in
-the Error Console. But see the discussion of
-[logging levels](dev-guide/console.html#Logging Levels): by default, messages
-logged using  `log()`, `info()`, `trace()`, or `warn()` won't be logged in
-these situations.
-
-## Console Methods ##
-
-All console methods except `exception()` and `trace()` accept one or
-more JavaScript objects as arguments and log them to the console.
-Depending on the console's underlying implementation and user interface,
-you may be able to examine the properties of non-primitive objects
-that are logged.
-
-### <code>console.log(*object*[, *object*, ...])</code> ###
-
-Logs the arguments to the console, preceded by "info:" and the name of your
-add-on:
-
-    console.log("This is an informational message");
-
-<pre>
-info: my-addon: This is an informational message
-</pre>
-
-### <code>console.info(*object*[, *object*, ...])</code> ###
-
-A synonym for `console.log()`.
-
-### <code>console.warn(*object*[, *object*, ...])</code> ###
-
-Logs the arguments to the console, preceded by "warn:" and the name of your
-add-on:
-
-    console.warn("This is a warning message");
-
-<pre>
-warn: my-addon: This is a warning message
-</pre>
-
-### <code>console.error(*object*[, *object*, ...])</code> ###
-
-Logs the arguments to the console, preceded by "error:" and the name of your
-add-on:
-
-    console.error("This is an error message");
-
-<pre>
-error: my-addon: This is an error message
-</pre>
-
-### <code>console.debug(*object*[, *object*, ...])</code> ###
-
-Logs the arguments to the console, preceded by "debug:" and the name of your
-add-on:
-
-    console.error("This is a debug message");
-
-<pre>
-debug: my-addon: This is a debug message
-</pre>
-
-### <code>console.exception(*exception*)</code> ###
-
-Logs the given exception instance as an error, outputting information
-about the exception's stack traceback if one is available.
-
-    try {
-       doThing();
-    } catch (e) {
-       console.exception(e);
-    }
-
-    function UserException(message) {
-       this.message = message;
-       this.name = "UserException";
-    }
-
-    function doThing() {
-      throw new UserException("Thing could not be done!");
-    }
-
-<pre>
-error: my-addon: An exception occurred.
-UserException: Thing could not be done!
-</pre>
-
-### <code>console.trace()</code> ###
-
-Logs a stack trace at the point the function is called.
-
-<h2 id="Logging Levels">Logging Levels</h2>
-
-Logging's useful, of course, especially during development. But the more
-logging there is, the more noise you see in the console output.
-Especially when debug logging shows up in a production environment, the
-noise can make it harder, not easier, to debug issues.
-
-This is the problem that logging levels are designed to fix. The console
-defines a number of logging levels, from "more verbose" to "less verbose",
-and a number of different logging functions that correspond to these levels,
-which are arranged in order of "severity" from informational
-messages, through warnings, to errors.
-
-At a given logging level, only calls to the corresponding functions and
-functions with a higher severity will have any effect.
-
-For example, if the logging level is set to "info", then calls to `info()`,
-`log()`, `warn()`, and `error()` will all result in output being written.
-But if the logging level is "warn" then only calls to `warn()` and `error()`
-have any effect, and calls to `info()` and `log()` are simply discarded.
-
-This means that the same code can be more verbose in a development
-environment than in a production environment - you just need to arrange for
-the appropriate logging level to be set.
-
-The complete set of logging levels is given in the table below, along
-with the set of functions that will result in output at each level:
-
-<table>
-  <colgroup>
-    <col width="10%">
-    <col width="90%">
-  </colgroup>
-
-  <tr>
-    <th>Level</th>
-    <th>Will log calls to:</th>
-  </tr>
-
-  <tr>
-    <td>all</td>
-    <td>Any console method</td>
-  </tr>
-
-  <tr>
-    <td>debug</td>
-    <td><code>debug()</code>, <code>log()</code>, <code>info()</code>, <code>trace()</code>, <code>warn()</code>, <code>exception()</code>, <code>error()</code></td>
-  </tr>
-
-  <tr>
-    <td>info</td>
-    <td><code>log()</code>, <code>info()</code>, <code>trace()</code>, <code>warn()</code>, <code>exception()</code>, <code>error()</code></td>
-  </tr>
-
-  <tr>
-    <td>warn</td>
-    <td><code>warn()</code>, <code>exception()</code>, <code>error()</code></td>
-  </tr>
-
-  <tr>
-    <td>error</td>
-    <td><code>exception()</code>, <code>error()</code></td>
-  </tr>
-
-  <tr>
-    <td>off</td>
-    <td>Nothing</td>
-  </tr>
-
-</table>
-
-### Setting the Logging Level ###
-
-The logging level defaults to "error".
-
-There are two system preferences that can be used to override this default:
-
-* **extensions.sdk.console.logLevel**: if set, this determines the logging
-level for all installed SDK-based add-ons.
-
-* **extensions.[extension-id].sdk.console.logLevel**: if set, this determines
-the logging level for the specified add-on. This overrides the global
-preference if both are set.
-
-Both these preferences can be set programmatically using the
-[`preferences/service`](modules/sdk/preferences/service.html) API, or manually
-using [about:config](http://kb.mozillazine.org/About:config). The value for each
-preference is the desired logging level, given as a string. 
-
-When you run your add-on using `cfx run` or `cfx test`, the global
-**extensions.sdk.console.logLevel** preference is automatically set to "info".
-This means that calls to `console.log()` will appear in the console output.
-
-When you install an add-on into Firefox, the logging level will be "error"
-by default (that is, unless you have set one of the two preferences). This
-means that messages written using `debug()`, `log()`, `info()`, `trace()`,
-and `warn()` will not appear in the console.
-
-This includes add-ons being developed using the
-[Add-on Builder](https://builder.addons.mozilla.org/) or the
-[Extension Auto-installer](https://addons.mozilla.org/en-US/firefox/addon/autoinstaller/).
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/credits.md
+++ /dev/null
@@ -1,167 +0,0 @@
-<!-- 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/. -->
-
-# Credits #
-
-We'd like to thank our many Jetpack project contributors!  They include:
-
-### A ###
-
-* Adamantium
-* Ehsan Akhgari
-* arky
-* [Heather Arthur](https://github.com/harthur)
-* Dietrich Ayala
-
-### B ###
-
-* [Romain B](https://github.com/Niamor)
-* [Louis-Rémi Babé](https://github.com/louisremi)
-* Will Bamberg
-* Thomas Bassetto
-* Tomaz Bevec
-* Zbigniew Braniecki
-* Daniel Buchner
-* James Burke
-
-### C ###
-
-* [Shane Caraveo](https://github.com/mixedpuppy)
-* [Matěj Cepl](https://github.com/mcepl)
-* Marc Chevrier
-* [Timothy Guan-tin Chien](https://github.com/timdream)
-* Hernán Rodriguez Colmeiro
-* [David Creswick](https://github.com/dcrewi)
-
-### D ###
-
-* dexter
-* Christopher Dorn
-* Connor Dunn
-* dynamis
-
-### F ###
-
-* [Corey Farwell](http://github.com/frewsxcv)
-* [Matteo Ferretti](https://github.com/ZER0)
-* fuzzykiller
-
-### G ###
-
-* [Marcio Galli](https://github.com/taboca)
-* [Ben Gillbanks](http://www.iconfinder.com/browse/iconset/circular_icons/)
-* Felipe Gomes
-* Irakli Gozalishvili
-* Luca Greco
-* Jeff Griffiths
-* [David Guo](https://github.com/dglol)
-
-### H ###
-
-* Mark Hammond
-* Mark A. Hershberger
-* Lloyd Hilaiel
-* Bobby Holley
-
-### I ###
-
-* Shun Ikejima
-
-### J ###
-
-* Tomislav Jovanovic
-* Eric H. Jung
-
-### K ###
-
-* Hrishikesh Kale
-* Wes Kocher
-* Lajos Koszti
-* Kusanagi Kouichi
-* [Vladimir Kukushkin](https://github.com/kukushechkin)
-
-### L ###
-
-* Edward Lee
-* Gregg Lind
-
-### M ###
-
-* [Nils Maier](https://github.com/nmaier)
-* Gervase Markham
-* Dave Mason
-* Myk Melez
-* Zandr Milewski
-* Noelle Murata
-
-### N ###
-
-* Siavash Askari Nasr
-* Joe R. Nassimian ([placidrage](https://github.com/placidrage))
-* Dương H. Nguyễn
-* Nick Nguyen
-* nodeless
-
-### O ###
-
-* [ongaeshi](https://github.com/ongaeshi)
-* Paul O’Shannessy
-* Les Orchard
-
-### P ###
-
-* Robert Pankowecki
-* [Jamie Phelps](https://github.com/jxpx777)
-* [Alexandre Poirot](https://github.com/ochameau)
-* Nickolay Ponomarev
-
-### R ###
-
-* Aza Raskin
-
-### S ###
-
-* [Jordan Santell](https://github.com/jsantell)
-* Till Schneidereit
-* Justin Scott
-* Ayan Shah
-* [skratchdot](https://github.com/skratchdot)
-* Henrik Skupin
-* slash
-* Markus Stange
-* Dan Stevens
-* [J. Ryan Stinnett](https://github.com/jryans)
-* [Mihai Sucan](https://github.com/mihaisucan)
-* Sunny ([darkowlzz](https://github.com/darkowlzz))
-
-### T ###
-
-* taku0
-* Clint Talbert
-* Tim Taubert
-* Shane Tomlinson
-* Dave Townsend
-* [Fraser Tweedale](https://github.com/frasertweedale)
-* [Matthias Tylkowski](https://github.com/tylkomat)
-
-### V ###
-
-* Peter Van der Beken
-* Sander van Veen
-* Atul Varma
-* [Erik Vold](https://github.com/erikvold)
-* Vladimir Vukicevic
-
-### W ###
-
-* Brian Warner
-* [Henri Wiechers](https://github.com/hwiechers)
-* Drew Willcoxon
-* Blake Winton
-* Michal Wojciechowski
-
-### Z ###
-
-* Piotr Zalewa
-* Brett Zamir
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/glossary.md
+++ /dev/null
@@ -1,73 +0,0 @@
-<!-- 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/. -->
-
-# Glossary #
-
-This glossary contains a list of terms used in the Add-on SDK.
-
-__Add-on__: A software package that adds functionality to a Mozilla application,
-which can be built with either Mozilla's traditional add-on platform or the SDK.
-
-__Add-on SDK__: A toolchain and associated applications for developing add-ons.
-
-__API Utils__: A small, self-contained set of low-level modules that forms
-the base functionality for the SDK. The library can be "bootstrapped" into
-any Mozilla application or add-on.
-
-__CFX__: A command-line build, testing, and packaging tool for SDK-based code.
-
-__CommonJS__: A specification for a cross-platform JavaScript module
-system and standard library.  [Web site](http://commonjs.org/).
-
-__Extension__: Synonym for Add-on.
-
-__Globals__: The set of global variables and objects provided
-to all modules, such as `console` and `memory`. Includes
-CommonJS globals like `require` and standard JavaScript globals such
-as `Array` and `Math`.
-
-<span><a name="host-application">__Host Application__:</a> Add-ons are executed in
-the context of a host application, which is the application they are extending.
-Firefox and Thunderbird are the most obvious hosts for Mozilla add-ons, but
-at present only Firefox is supported as a host for add-ons developed using the
-Add-on SDK.</span>
-
-__Jetpack Prototype__: A Mozilla Labs experiment that predated and inspired
-the SDK. The SDK incorporates many ideas and some code from the prototype.
-
-__Loader__: An object capable of finding, evaluating, and
-exposing CommonJS modules to each other in a given security context,
-while providing each module with necessary globals and
-enforcing security boundaries between the modules as necessary. It's
-entirely possible for Loaders to create new Loaders.
-
-__Low-Level Module__: A module with the following properties:
-
-  * Has "chrome" access to the Mozilla platform (e.g. `Components.classes`)
-    and all globals.
-  * Is reloadable without leaking memory.
-  * Logs full exception tracebacks originating from client-provided
-    callbacks (i.e., does not allow the exceptions to propagate into
-    Mozilla platform code).
-  * Can exist side-by-side with multiple instances and versions of
-    itself.
-  * Contains documentation on security concerns and threat modeling.
-
-__Module__: A CommonJS module that is either a Low-Level Module
-or an Unprivileged Module.
-
-__Package__: A directory structure containing modules,
-documentation, tests, and related metadata. If a package contains
-a program and includes proper metadata, it can be built into
-a Mozilla application or add-on.
-
-__Program__: A module named `main` that optionally exports
-a `main()` function.  This module is intended either to start an application for
-an end-user or add features to an existing application.
-
-__Unprivileged Module__: A CommonJS module that may be run
-without unrestricted access to the Mozilla platform, and which may use
-all applicable globals that don't require chrome privileges.
-
-  [Low-Level Module Best Practices]: dev-guide/module-development/best-practices.html
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/accessing-the-dom.md
+++ /dev/null
@@ -1,164 +0,0 @@
-<!-- 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/. -->
-
-# Accessing the DOM #
-
-This page talks about the access content scripts have to DOM objects
-in the pages they are attached to.
-
-## XRayWrapper ##
-
-Content scripts need to be able to access DOM objects in arbitrary web
-pages, but this could cause two potential security problems:
-
-1. JavaScript values from the content script could be accessed by the page,
-enabling a malicious page to steal data or call privileged methods.
-2. a malicious page could redefine standard functions and properties of DOM
-objects so they don't do what the add-on expects.
-
-To deal with this, content scripts access DOM objects using
-`XRayWrapper`, (also known as
-[`XPCNativeWrapper`](https://developer.mozilla.org/en/XPCNativeWrapper)).
-These wrappers give the user access to the native values of DOM functions
-and properties, even if they have been redefined by a script.
-
-For example: the page below redefines `window.confirm()` to return
-`true` without showing a confirmation dialog:
-
-<script type="syntaxhighlighter" class="brush: html"><![CDATA[
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html lang='en' xml:lang='en' xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <script>
-    window.confirm = function(message) {
-      return true;
-    }
-    &lt;/script>
-  </head>
-</html>
-
-</script>
-
-But thanks to the wrapper, a content script which calls
-`window.confirm()` will get the native implementation:
-
-    var widgets = require("sdk/widget");
-    var tabs = require("sdk/tabs");
-    var data = require("sdk/self").data;
-
-    var widget = widgets.Widget({
-      id: "transfer",
-      label: "Transfer",
-      content: "Transfer",
-      width: 100,
-      onClick: function() {
-        tabs.activeTab.attach({
-          // native implementation of window.confirm will be used
-          contentScript: "console.log(window.confirm('Transfer all my money?'));"
-        });
-      }
-    });
-
-    tabs.open(data.url("xray.html"));
-
-The wrapper is transparent to content scripts: as far as the content script
-is concerned, it is accessing the DOM directly. But because it's not, some
-things that you might expect to work, won't. For example, if the page includes
-a library like [jQuery](http://www.jquery.com), or any other page script
-adds other objects to any DOM nodes, they won't be visible to the content
-script. So to use jQuery you'll typically have to add it as a content script,
-as in [this example](dev-guide/guides/content-scripts/reddit-example.html).
-
-### XRayWrapper Limitations ###
-
-There are some limitations with accessing objects through XRayWrapper.
-
-First, XRayWrappers don't inherit from JavaScript's
-[`Object`](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object),
-so methods like `valueOf`, `toSource`, and `watch` are not available.
-This issue is being tracked as
-[bug 787013](https://bugzilla.mozilla.org/show_bug.cgi?id=787013).
-
-Second, you can't access the prototype of an object through an XRayWrapper.
-Consider a script like this:
-
-    window.HTMLElement.prototype.foo = 'bar';
-    window.alert(window.document.body.foo);
-
-Run as a normal page script, this will work fine. But if you execute it as
-a content script you'll see an error like:
-
-<pre>
-TypeError: window.HTMLElement.prototype is undefined
-</pre>
-
-This issue is being tracked as
-[bug 787070](https://bugzilla.mozilla.org/show_bug.cgi?id=787070).
-
-The main effect of this is that certain features of the
-[Prototype JavaScript framework](http://www.prototypejs.org/) don't work
-if it is loaded as a content script. As a workaround you can
-disable these features by setting
-`Prototype.BrowserFeatures.SpecificElementExtensions` to `false`
-in `prototype.js`:
-
-<pre>
- if (Prototype.Browser.MobileSafari)
-   Prototype.BrowserFeatures.SpecificElementExtensions = false;
-
-+// Disable element extension in addon-sdk content scripts
-+Prototype.BrowserFeatures.SpecificElementExtensions = false;
-</pre>
-
-## Adding Event Listeners ##
-
-You can listen for DOM events in a content script just as you can in a normal
-page script, but there's one important difference: if you define an event
-listener by passing it as a string into
-[`setAttribute()`](https://developer.mozilla.org/en/DOM/element.setAttribute),
-then the listener is evaluated in the page's context, so it will not have
-access to any variables defined in the content script.
-
-For example, this content script will fail with the error "theMessage is not
-defined":
-
-    var theMessage = "Hello from content script!";
-
-    anElement.setAttribute("onclick", "alert(theMessage);");
-
-So using `setAttribute()` is not recommended. Instead, add a listener by
-assignment to
-[`onclick`](https://developer.mozilla.org/en/DOM/element.onclick) or by using
-[`addEventListener()`](https://developer.mozilla.org/en/DOM/element.addEventListener),
-in either case defining the listener as a function:
-
-    var theMessage = "Hello from content script!";
-
-    anElement.onclick = function() {
-      alert(theMessage);
-    };
-
-    anotherElement.addEventListener("click", function() {
-      alert(theMessage);
-    });
-
-Note that with both `onclick` assignment and `addEventListener()`, you must
-define the listener as a function. It cannot be defined as a string, whether
-in a content script or in a page script.
-
-## unsafeWindow ##
-
-If you really need direct access to the underlying DOM, you can use the
-global `unsafeWindow` object.
-
-To see the difference, try editing the example above
-so the content script uses `unsafeWindow.confirm()` instead of
-`window.confirm()`.
-
-Avoid using `unsafeWindow` if possible: it is the same concept as
-Greasemonkey's unsafeWindow, and the
-[warnings for that](http://wiki.greasespot.net/UnsafeWindow) apply equally
-here. Also, `unsafeWindow` isn't a supported API, so it could be removed or
-changed in a future version of the SDK.
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/communicating-with-other-scripts.md
+++ /dev/null
@@ -1,246 +0,0 @@
-<!-- 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/. -->
-
-# Communicating With Other Scripts #
-
-This section of the guide explains how content scripts can
-communicate with:
-
-* [your `main.js` file](dev-guide/guides/content-scripts/communicating-with-other-scripts.html#main.js),
-or any other modules in your add-on
-* [other content scripts loaded by your add-on](dev-guide/guides/content-scripts/communicating-with-other-scripts.html#Content Scripts)
-* [page scripts](dev-guide/guides/content-scripts/communicating-with-other-scripts.html#Page Scripts) (that is, scripts embedded in the web page or
-included using `<script>` tags) 
-
-## main.js ##
-
-Your content scripts can communicate with your add-on's "main.js"
-(or any other modules you're written for your add-on) by sending it messages,
-using either the `port.emit()` API or the `postMessage()` API. See the
-articles on
-[using `postMessage()`](dev-guide/guides/content-scripts/using-postmessage.html)
-and
-[using `port`](dev-guide/guides/content-scripts/using-port.html) for details.
-
-## Content Scripts ##
-
-Content scripts loaded into the same document can interact
-with each other directly as well as with the web content itself. However,
-content scripts which have been loaded into different documents
-cannot interact with each other.
-
-For example:
-
-* if an add-on creates a single `panel` object and loads several content
-scripts into the panel, then they can interact with each other
-* if an add-on creates two `panel` objects and loads a script into each
-one, they can't interact with each other.
-* if an add-on creates a single `page-mod` object and loads several content
-scripts into the page mod, then only content scripts associated with the
-same page can interact with each other: if two different matching pages are
-loaded, content scripts attached to page A cannot interact with those attached
-to page B.
-
-The web content has no access to objects created by the content script, unless
-the content script explicitly makes them available.
-
-## Page Scripts ##
-
-If a page includes its own scripts using `<script>` tags,
-either embedded in the page or linked to it using the `src` attribute, there
-are a couple of ways a content script can communicate with it:
-
-* using the [DOM `postMessage()` API](dev-guide/guides/content-scripts/communicating-with-other-scripts.html#Using the DOM postMessage API)
-* using [custom DOM events](dev-guide/guides/content-scripts/communicating-with-other-scripts.html#Using Custom DOM Events)
-
-### Using the DOM postMessage API ###
-
-You can communicate between the content script and page scripts using
-[`window.postMessage()`](https://developer.mozilla.org/en/DOM/window.postMessage),
-but there's a twist: in early versions of the SDK, the global `postMessage()`
-function in content scripts was used for communicating between the content
-script and the main add-on code. Although this has been
-[deprecated in favor of `self.postMessage`](https://wiki.mozilla.org/Labs/Jetpack/Release_Notes/1.0b5#Major_Changes),
-the old globals are still supported, so you can't currently use
-`window.postMessage()`. You must use `document.defaultView.postMessage()`
-instead.
-
-#### Messaging From Content Script To Page Script ####
-
-Suppose we have a page called "listen.html" hosted at "my-domain.org", and we want to send messages
-from the add-on to a script embedded in that page.
-
-In the main add-on code, we have a
-[`page-mod`](modules/sdk/page-mod.html) that attaches the content script
-"talk.js" to the right page:
-
-    var data = require("sdk/self").data;
-
-    var pageMod = require("sdk/page-mod");
-    pageMod.PageMod({
-      include: "http://my-domain.org/listen.html",
-      contentScriptFile: data.url("talk.js")
-    });
-
-The "talk.js" content script uses `document.defaultView.postMessage()` to send
-the message to the page:
-
-    document.defaultView.postMessage("Message from content script", "http://my-domain.org/");
-
-The second argument may be '*' which will allow communication with any domain.
-
-Finally, "listen.html" uses `window.addEventListener()` to listen for
-messages from the content script:
-
-<script type="syntaxhighlighter" class="brush: html"><![CDATA[
-&lt;!DOCTYPE html&gt;
-&lt;html&gt;
-  &lt;head&gt;&lt;/head&gt;
-  &lt;body&gt;
-    &lt;script&gt;
-      window.addEventListener('message', function(event) {
-        window.alert(event.data);
-      }, false);
-    &lt;/script&gt;
-  &lt;/body&gt;
-
-&lt;/html&gt;
-]]>
-</script>
-
-#### Messaging From Page Script To Content Script ####
-
-Sending messages from the page script to the content script is just
-the same, but in reverse.
-
-Here "main.js" creates a [`page-mod`](modules/sdk/page-mod.html)
-that attaches "listen.js" to the web page:
-
-    var data = require("sdk/self").data;
-
-    var pageMod = require("sdk/page-mod");
-    pageMod.PageMod({
-      include: "http://my-domain.org/talk.html",
-      contentScriptFile: data.url("listen.js")
-    });
-
-The web page "talk.html" embeds a script that uses `window.postMessage()`
-to send the content script a message when the user clicks a button:
-
-<script type="syntaxhighlighter" class="brush: html"><![CDATA[
-&lt;!DOCTYPE html&gt;
-&lt;html&gt;
-  &lt;head&gt;&lt;/head&gt;
-  &lt;body&gt;
-    &lt;script&gt;
-      function sendMessage() {
-        window.postMessage("Message from page script", "http://my-domain.org/");
-      }
-    &lt;/script&gt;
-    &lt;button onclick="sendMessage()"&gt;Send Message&lt;/button&gt;
-  &lt;/body&gt;
-
-&lt;/html&gt;
-</script>
-
-Finally, the content script "listen.js" uses
-`document.defaultView.addEventListener()` to listen for messages from the page
-script:
-
-    document.defaultView.addEventListener('message', function(event) {
-      console.log(event.data);
-      console.log(event.origin);
-    }, false);
-
-### Using Custom DOM Events ###
-
-As an alternative to using `postMessage()` you can use
-[custom DOM events](https://developer.mozilla.org/en/DOM/CustomEvent)
-to communicate between page scripts and content scripts.
-
-#### Messaging From Content Script To Page Script ####
-
-Here's an example showing how to use custom DOM events to send a message
-from a content script to a page script.
-
-First, "main.js" will create a [`page-mod`](modules/sdk/page-mod.html)
-that will attach "talk.js" to the target web page:
-
-    var data = require("sdk/self").data;
-
-    var pageMod = require("sdk/page-mod");
-    pageMod.PageMod({
-      include: "http://my-domain.org/listen.html",
-      contentScriptFile: data.url("talk.js")
-    });
-
-Next, "talk.js" creates and dispatches a custom event, passing the payload
-in the `detail` parameter to `initCustomEvent()`:
-
-<!-- This comment is used to terminate the Markdown list above -->
-
-    var event = document.createEvent('CustomEvent');
-    event.initCustomEvent("addon-message", true, true, { hello: 'world' });
-    document.documentElement.dispatchEvent(event);
-
-Finally "listen.html" listens for the new event and examines its
-`detail` attribute to retrieve the payload:
-
-<script type="syntaxhighlighter" class="brush: html"><![CDATA[
-&lt;!DOCTYPE html&gt;
-&lt;html&gt;
-  &lt;head&gt;&lt;/head&gt;
-  &lt;body&gt;
-    &lt;script&gt;
-      document.documentElement.addEventListener("addon-message", function(event) {
-        window.alert(JSON.stringify(event.detail))
-      }, false);
-    &lt;/script&gt;
-  &lt;/body&gt;
-&lt;/html&gt;
-</script>
-
-#### Messaging From Page Script to Content Script ####
-
-Sending messages using custom DOM events from the page script
-to the content script is just the same, but in reverse.
-
-Again, "main.js" creates a [`page-mod`](modules/sdk/page-mod.html)
-to target the page we are interested in:
-
-    var data = require("sdk/self").data;
-
-    var pageMod = require("sdk/page-mod");
-    pageMod.PageMod({
-      include: "http://my-domain.org/talk.html",
-      contentScriptFile: data.url("listen.js")
-    });
-
-The web page "talk.html" creates and dispatches a custom DOM event,
-using `initCustomEvent()`'s `detail` parameter to supply the payload:
-
-<script type="syntaxhighlighter" class="brush: html"><![CDATA[
-&lt;!DOCTYPE html&gt;
-&lt;html&gt;
-  &lt;head&gt;&lt;/head&gt;
-  &lt;body&gt;
-    &lt;script&gt;
-      function sendMessage() {
-        var event = document.createEvent('CustomEvent');
-        event.initCustomEvent("addon-message", true, true, { hello: 'world' });
-        document.documentElement.dispatchEvent(event);
-      }
-    &lt;/script&gt;
-    &lt;button onclick="sendMessage()"&gt;Send Message&lt;/button&gt;
-  &lt;/body&gt;
-&lt;/html&gt;
-</script>
-
-Finally, the content script "listen.js" listens for the new event
-and retrieves the payload from its `detail` attribute:
-
-    document.documentElement.addEventListener("addon-message", function(event) {
-      console.log(JSON.stringify(event.detail));
-    }, false);
-
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/cross-domain.md
+++ /dev/null
@@ -1,177 +0,0 @@
-<!-- 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/. -->
-
-# Cross-domain Content Scripts #
-
-By default, content scripts don't have any cross-domain privileges.
-In particular, they can't:
-
-* [access content hosted in an `iframe`, if that content is served from a different domain](dev-guide/guides/content-scripts/cross-domain.html#Cross-domain iframes)
-* [make cross-domain XMLHttpRequests](dev-guide/guides/content-scripts/cross-domain.html#Cross-domain XMLHttpRequest)
-
-However, you can enable these features for specific domains
-by adding them to your add-on's [package.json](dev-guide/package-spec.html)
-under the `"cross-domain-content"` key, which itself lives under the
-`"permissions"` key:
-
-<pre>
-"permissions": {
-    "cross-domain-content": ["http://example.org/", "http://example.com/"]
-}
-</pre>
-
-* The domains listed must include the scheme and fully qualified domain name,
-and these must exactly match the domains serving the content - so in the
-example above, the content script will not be allowed to access content
-served from `https://example.com/`.
-* Wildcards are not allowed.
-* This feature is currently only available for content scripts, not for page
-scripts included in HTML files shipped with your add-on.
-
-## Cross-domain iframes ##
-
-The following "main.js" creates a page-worker which loads a local HTML file
-called "page.html", attaches a content script called "page.js" to the
-page, waits for messages from the script, and logs the payload.
-
-    //main.js
-    var data = require("sdk/self").data;
-
-    var pageWorker = require("sdk/page-worker").Page({
-      contentURL: data.url("page.html"),
-      contentScriptFile: data.url("page-script.js")
-    });
-
-    pageWorker.on("message", function(message) {
-      console.log(message);
-    });
-
-The "page.html" file embeds an iframe whose content is
-served from "http://en.m.wikipedia.org/":
-
-<pre class="brush: html">
-    &lt;!doctype html&gt;
-    &lt;!-- page.html --&gt;
-    &lt;html&gt;
-      &lt;head>&lt;/head&gt;
-      &lt;body&gt;
-        &lt;iframe id="wikipedia" src="http://en.m.wikipedia.org/"&gt;&lt;/iframe&gt;
-      &lt;/body&gt;
-    &lt;/html&gt;
-</pre>
-
-The "page-script.js" file locates "Today's Featured Article" and sends its
-content to "main.js":
-
-    // page-script.js
-    var iframe = window.document.getElementById("wikipedia");
-    var todaysFeaturedArticle = iframe.contentWindow.document.getElementById("mp-tfa");
-    self.postMessage(todaysFeaturedArticle.textContent);
-
-For this to work, we need to add the `"cross-domain-content"` key to
-"package.json":
-
-<pre>
-"permissions": {
-  "cross-domain-content": ["http://en.m.wikipedia.org/"]
-}
-</pre>
-
-The add-on should successfully retrieve the iframe's content.
-
-## Cross-domain XMLHttpRequest ##
-
-The following add-on creates a panel whose content is the summary weather
-forecast for [Shetland](https://en.wikipedia.org/wiki/Shetland).
-If you want to try it out, you'll need to
-[register](http://www.metoffice.gov.uk/datapoint/support/API)
-and get an API key.
-
-The "main.js":
-
-* creates a panel whose content is supplied by "panel.html" and
-adds a content script "panel-script.js" to it
-* sends the panel a "show" message when it is shown
-* attaches the panel to a widget
-
-<!-- terminate Markdown list -->
-
-    // main.js
-    var data = require("sdk/self").data;
-
-    var forecast_panel = require("sdk/panel").Panel({
-      height: 50,
-      contentURL: data.url("panel.html"),
-      contentScriptFile: data.url("panel-script.js")
-    });
-
-    forecast_panel.on("show", function(){
-      forecast_panel.port.emit("show");
-    });
-
-    require("sdk/widget").Widget({
-      id: "forecast",
-      label: "Weather Forecast",
-      contentURL: "http://www.metoffice.gov.uk/favicon.ico",
-      panel: forecast_panel
-    });
-
-The "panel.html" just includes a `<div>` block for the forecast:
-
-<pre class="brush: html">
-&lt;!doctype HTML&gt;
-&lt;!-- panel.html --&gt;
-
-&lt;html&gt;
-  &lt;head&gt;&lt;/head&gt;
-  &lt;body&gt;
-    &lt;div id="forecast_summary">&lt;/div&gt;
-  &lt;/body&gt;
-&lt;/html&gt;
-</pre>
-
-The "panel-script.js" uses [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
-to fetch the latest forecast:
-
-    // panel-script.js
-
-    var url = "http://datapoint.metoffice.gov.uk/public/data/txt/wxfcs/regionalforecast/json/500?key=YOUR-API-KEY";
-
-    self.port.on("show", function () {
-      var request = new XMLHttpRequest();
-      request.open("GET", url, true);
-      request.onload = function () {
-        var jsonResponse = JSON.parse(request.responseText);
-        var summary = getSummary(jsonResponse);
-        var element = document.getElementById("forecast_summary");
-        element.textContent = summary;
-      };
-      request.send();
-    });
-
-    function getSummary(forecast) {
-      return forecast.RegionalFcst.FcstPeriods.Period[0].Paragraph[0].$;
-    }
-
-
-Finally, we need to add the `"cross-domain-content"` key to "package.json":
-
-<pre>
-"permissions": {
-  "cross-domain-content": ["http://datapoint.metoffice.gov.uk"]
-}
-</pre>
-
-## Content Permissions and unsafeWindow ##
-
-If you use `"cross-domain-content"`, then JavaScript values in content
-scripts will not be available from pages. Suppose your content script includes
-a line like:
-
-    // content-script.js:
-    unsafeWindow.myCustomAPI = function () {};
-
-If you have included the `"cross-domain-content"` key, when the page script
-tries to access `myCustomAPI` this will result in a "permission denied"
-exception.
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/index.md
+++ /dev/null
@@ -1,98 +0,0 @@
-<!-- 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/. -->
-
-# Content Scripts #
-
-Almost all interesting add-ons will need to interact with web content or the
-browser's user interface. For example, they may need to access and modify the
-content of web pages or be notified when the user clicks a link.
-
-The SDK provides several core modules to support this:
-
-**[context-menu](modules/sdk/context-menu.html)**<br>
-Add items to the browser's context menu.
-
-**[panel](modules/sdk/panel.html)**<br>
-Create a dialog that can host web content.
-
-**[page-worker](modules/sdk/page-worker.html)**<br>
-Retrieve a page and access its content, without displaying it to the user.
-
-**[page-mod](modules/sdk/page-mod.html)**<br>
-Execute scripts in the context of selected web pages.
-
-**[tabs](modules/sdk/tabs.html)**<br>
-Manipulate the browser's tabs, including the web content displayed in the tab.
-
-**[widget](modules/sdk/widget.html)**<br>
-Host an add-on's user interface, including web content.
-
-Firefox is moving towards a model in which it uses separate
-processes to display the UI, handle web content, and execute add-ons. The main
-add-on code will run in the add-on process and will not have direct access to
-any web content.
-
-This means that an add-on which needs to interact with web content needs to be
-structured in two parts:
-
-* the main script runs in the add-on process
-* any code that needs to interact with web content is loaded into the web
-content process as a separate script. These separate scripts are called
-_content scripts_.
-
-A single add-on may use multiple content scripts, and content scripts loaded
-into the same context can interact directly with each other as well as with
-the web content itself. See the chapter on
-<a href="dev-guide/guides/content-scripts/communicating-with-other-scripts.html">
-communicating with other scripts</a>.
-
-The add-on script and content script can't directly access each other's state.
-Instead, you can define your own events which each side can emit, and the
-other side can register listeners to handle them. The interfaces are similar
-to the event-handling interfaces described in the
-[Working with Events](dev-guide/guides/events.html) guide.
-
-The diagram below shows an overview of the main components and their
-relationships. The gray fill represents code written by the add-on developer.
-
-<img class="image-center" src="static-files/media/content-scripting-overview.png"
-alt="Content script events">
-
-This might sound complicated but it doesn't need to be. The following add-on
-uses the [page-mod](modules/sdk/page-mod.html) module to replace the
-content of any web page in the `.co.uk` domain by executing a content script
-in the context of that page:
-
-    var pageMod = require("sdk/page-mod");
-
-    pageMod.PageMod({
-      include: ["*.co.uk"],
-      contentScript: 'document.body.innerHTML = ' +
-                     '"<h1>this page has been eaten</h1>";'
-    });
-
-In this example the content script is supplied directly to the page mod via
-the `contentScript` option in its constructor, and does not need to be
-maintained as a separate file at all.
-
-The next few chapters explain content scripts in detail:
-
-* [Loading Content Scripts](dev-guide/guides/content-scripts/loading.html):
-how to attach content scripts to web pages, and how to control the point at
-which they are executed
-* [Accessing the DOM](dev-guide/guides/content-scripts/accessing-the-dom.html):
-detail about the access content scripts get to the DOM
-* [Communicating With Other Scripts](dev-guide/guides/content-scripts/communicating-with-other-scripts.html):
-detail about how content scripts can communicate with "main.js", with other
-content scripts, and with scripts loaded by the web page itself
-* [Communicating Using <code>port</code>](dev-guide/guides/content-scripts/using-port.html):
-how to communicate between your add-on and its content scripts using the
-<code>port</code> object
-* [Communicating using <code>postMessage()</code>](dev-guide/guides/content-scripts/using-postmessage.html):
-how to communicate between your add-on and its content scripts using the
-<code>postMessage()</code> API
-* [Cross-domain Content Scripts](dev-guide/guides/content-scripts/cross-domain.html):
-how to enable a content script to interact with content served from other domains.
-* [Example](dev-guide/guides/content-scripts/reddit-example.html):
-a simple example add-on using content scripts
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/loading.md
+++ /dev/null
@@ -1,79 +0,0 @@
-<!-- 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/. -->
-
-
-# Loading Content Scripts #
-
-The constructors for content-script-using objects such as panel and page-mod
-define a group of options for loading content scripts:
-
-<pre>
-  contentScript         string, array
-  contentScriptFile     string, array
-  contentScriptWhen     string
-  contentScriptOptions  object
-</pre>
-
-We have already seen the `contentScript` option, which enables you to pass
-in the text of the script itself as a string literal. This version of the API
-avoids the need to maintain a separate file for the content script.
-
-The `contentScriptFile` option enables you to pass in the local file URL from
-which the content script will be loaded. To supply the file
-"my-content-script.js", located in the /data subdirectory under your add-on's
-root directory, use a line like:
-
-    // "data" is supplied by the "self" module
-    var data = require("sdk/self").data;
-    ...
-    contentScriptFile: data.url("my-content-script.js")
-
-Both `contentScript` and `contentScriptFile` accept an array of strings, so you
-can load multiple scripts, which can also interact directly with each other in
-the content process:
-
-    // "data" is supplied by the "self" module
-    var data = require("sdk/self").data;
-    ...
-    contentScriptFile:
-        [data.url("jquery-1.4.2.min.js"), data.url("my-content-script.js")]
-
-Scripts specified using contentScriptFile are loaded before those specified
-using contentScript. This enables you to load a JavaScript library like jQuery
-by URL, then pass in a simple script inline that can use jQuery.
-
-<div class="warning">
-<p>Unless your content script is extremely simple and consists only of a
-static string, don't use <code>contentScript</code>: if you do, you may
-have problems getting your add-on approved on AMO.</p>
-<p>Instead, keep the script in a separate file and load it using
-<code>contentScriptFile</code>. This makes your code easier to maintain,
-secure, debug and review.</p>
-</div>
-
-The `contentScriptWhen` option specifies when the content script(s) should be
-loaded. It takes one of three possible values:
-
-* "start" loads the scripts immediately after the document element for the
-page is inserted into the DOM. At this point the DOM content hasn't been
-loaded yet, so the script won't be able to interact with it.
-
-* "ready" loads the scripts after the DOM for the page has been loaded: that
-is, at the point the
-[DOMContentLoaded](https://developer.mozilla.org/en/Gecko-Specific_DOM_Events)
-event fires. At this point, content scripts are able to interact with the DOM
-content, but externally-referenced stylesheets and images may not have finished
-loading.
-
-* "end" loads the scripts after all content (DOM, JS, CSS, images) for the page
-has been loaded, at the time the
-[window.onload event](https://developer.mozilla.org/en/DOM/window.onload)
-fires.
-
-The default value is "end".
-
-The `contentScriptOptions` is a json that is exposed to content scripts as a read
-only value under `self.options` property.
-
-Any kind of jsonable value (object, array, string, etc.) can be used here.
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/reddit-example.md
+++ /dev/null
@@ -1,71 +0,0 @@
-<!-- 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/. -->
-
-# Reddit Example #
-
-This example add-on creates a panel containing the mobile version of Reddit.
-When the user clicks on the title of a story in the panel, the add-on opens
-the linked story in a new tab in the main browser window.
-
-To accomplish this the add-on needs to run a content script in the context of
-the Reddit page which intercepts mouse clicks on each title link and fetches the
-link's target URL. The content script then needs to send the URL to the add-on
-script.
-
-This is the complete add-on script:
-
-    var data = require("sdk/self").data;
-
-    var reddit_panel = require("sdk/panel").Panel({
-      width: 240,
-      height: 320,
-      contentURL: "http://www.reddit.com/.mobile?keep_extension=True",
-      contentScriptFile: [data.url("jquery-1.4.4.min.js"),
-                          data.url("panel.js")]
-    });
-
-    reddit_panel.port.on("click", function(url) {
-      require("sdk/tabs").open(url);
-    });
-
-    require("sdk/widget").Widget({
-      id: "open-reddit-btn",
-      label: "Reddit",
-      contentURL: "http://www.reddit.com/static/favicon.ico",
-      panel: reddit_panel
-    });
-
-This code supplies two content scripts to the panel's constructor in the
-`contentScriptFile` option: the jQuery library and the script that intercepts
-link clicks.
-
-Finally, it registers a listener to the user-defined `click` event which in
-turn passes the URL into the `open` function of the
-[tabs](modules/sdk/tabs.html) module.
-
-This is the `panel.js` content script that intercepts link clicks:
-
-    $(window).click(function (event) {
-      var t = event.target;
-
-      // Don't intercept the click if it isn't on a link.
-      if (t.nodeName != "A")
-        return;
-
-      // Don't intercept the click if it was on one of the links in the header
-      // or next/previous footer, since those links should load in the panel itself.
-      if ($(t).parents('#header').length || $(t).parents('.nextprev').length)
-        return;
-
-      // Intercept the click, passing it to the addon, which will load it in a tab.
-      event.stopPropagation();
-      event.preventDefault();
-      self.port.emit('click', t.toString());
-    });
-
-This script uses jQuery to interact with the DOM of the page and the
-`self.port.emit` function to pass URLs back to the add-on script.
-
-See the `examples/reddit-panel` directory for the complete example (including
-the content script containing jQuery).
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/using-port.md
+++ /dev/null
@@ -1,292 +0,0 @@
-<!-- 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/. -->
-
-
-# Communicating using "port" #
-
-To enable add-on scripts and content scripts to communicate with each other,
-each end of the conversation has access to a `port` object.
-
-* to send messages from one side to the other, use `port.emit()`
-* to receive messages sent from the other side, use `port.on()`
-
-<img class="image-center" src="static-files/media/content-scripting-events.png"
-alt="Content script events">
-
-Messages are asynchronous: that is, the sender does not wait for a reply from
-the recipient but just emits the message and continues processing.
-
-Here's a simple add-on that sends a message to a content script using `port`:
-
-    var tabs = require("sdk/tabs");
-
-    var alertContentScript = "self.port.on('alert', function(message) {" +
-                             "  window.alert(message);" +
-                             "})";
-
-    tabs.on("ready", function(tab) {
-      worker = tab.attach({
-        contentScript: alertContentScript
-      });
-      worker.port.emit("alert", "Message from the add-on");
-    });
-
-    tabs.open("http://www.mozilla.org");
-
-In total, the `port` object defines four functions:
-
-* [`emit()`](dev-guide/guides/content-scripts/using-port.html#port.emit()):
-emit a message.
-* [`on()`](dev-guide/guides/content-scripts/using-port.html#port.on()):
-listen to a message.
-* [`removeListener()`](dev-guide/guides/content-scripts/using-port.html#port.removeListener()):
-stop listening to a message.
-* [`once()`](dev-guide/guides/content-scripts/using-port.html#port.once()):
-listen to only the first occurrence of a message.
-
-## Accessing `port` ##
-
-### Accessing `port` in the Content Script ###
-
-<span class="aside">Note that the global `self` object is completely
-different from the [`self` module](modules/sdk/self.html), which
-provides an API for an add-on to access its data files and ID.</span>
-
-In the content script the `port` object is available as a property of the
-global `self` object. Thus, to emit a message from a content script:
-
-    self.port.emit("myContentScriptMessage", myContentScriptMessagePayload);
-
-To receive a message from the add-on code:
-
-    self.port.on("myAddonMessage", function(myAddonMessagePayload) {
-      // Handle the message
-    });
-
-Compare this to the technique used to receive _built-in_ messages in the
-content script. For example, to receive the `context` message in a content script
-associated with a [context menu](modules/sdk/context-menu.html)
-object, you would call the `on` function attached to the global `self` object:
-
-    self.on("context", function() {
-      // Handle the message
-    });
-
-So the `port` property is essentially used here as a namespace for
-user-defined messages.
-
-### Accessing `port` in the Add-on Script ###
-
-In the add-on code, the channel of communication between the add-on and a
-particular content script context is encapsulated by the 
-[`worker`](modules/sdk/content/worker.html#Worker) object. Thus
-the `port` object for communicating with a content script is a property of the
-corresponding `worker` object.
-
-However, the worker is not exposed to add-on code in quite the same way
-in all modules. The `panel` and `page-worker` objects integrate the
-worker API directly. So to receive messages from a content script associated
-with a panel you use `panel.port.on()`:
-
-    var panel = require("sdk/panel").Panel({
-      contentScript: "self.port.emit('showing', 'panel is showing');"
-    });
-
-    panel.port.on("showing", function(text) {
-      console.log(text);
-    });
-
-    panel.show();
-
-Conversely, to emit user-defined messages from your add-on you can just call
-`panel.port.emit()`:
-
-    var panel = require("sdk/panel").Panel({
-      contentScript: "self.port.on('alert', function(text) {" +
-                     "  console.log(text);" +
-                     "});"
-    });
-
-    panel.show();
-    panel.port.emit("alert", "panel is showing");
-
-The `panel` and `page-worker` objects only host a single page at a time,
-so each distinct page object only needs a single channel of communication
-to its content scripts. But some modules, such as `page-mod`, might need to
-handle multiple pages, each with its own context in which the content scripts
-are executing, so it needs a separate channel (worker) for each page.
-
-So `page-mod` does not integrate the worker API directly: instead, each time a
-content script is attached to a page, the 
-[worker](modules/sdk/content/worker.html#Worker) associated with the page is
-supplied to the page-mod in its `onAttach` function. By supplying a target for
-this function in the page-mod's constructor you can register to receive
-messages from the content script, and take a reference to the worker so as to
-emit messages to the content script.
-
-    var pageModScript = "window.addEventListener('click', function(event) {" +
-                        "  self.port.emit('click', event.target.toString());" +
-                        "  event.stopPropagation();" +
-                        "  event.preventDefault();" +
-                        "}, false);" +
-                        "self.port.on('warning', function(message) {" +
-                        "window.alert(message);" +
-                        "});"
-
-    var pageMod = require('sdk/page-mod').PageMod({
-      include: ['*'],
-      contentScript: pageModScript,
-      onAttach: function(worker) {
-        worker.port.on('click', function(html) {
-          worker.port.emit('warning', 'Do not click this again');
-        });
-      }
-    });
-
-In the add-on above there are two user-defined messages:
-
-* `click` is sent from the page-mod to the add-on, when the user clicks an
-element in the page
-* `warning` sends a silly string back to the page-mod
-
-## port.emit() ##
-
-The `port.emit()` function sends a message from the "main.js", or another
-add-on module, to a content script, or vice versa.
-
-It may be called with any number of parameters, but is most likely to be
-called with a name for the message and an optional payload.
-The payload can be any value that is
-<a href = "dev-guide/guides/content-scripts/using-port.html#json_serializable">serializable to JSON</a>.
-
-From the content script to the main add-on code:
-
-    var myMessagePayload = "some data";
-    self.port.emit("myMessage", myMessagePayload);
-
-From the main add-on code (in this case a panel instance)
-to the content script:
-
-    var myMessagePayload = "some data";
-    panel.port.emit("myMessage", myMessagePayload);
-
-## port.on() ##
-
-The `port.on()` function registers a function as a listener for a specific
-named message sent from the other side using `port.emit()`.
-
-It takes two parameters: the name of the message and a function to handle it.
-
-In a content script, to listen for "myMessage" sent from the main
-add-on code:
-
-    self.port.on("myMessage", function handleMyMessage(myMessagePayload) {
-      // Handle the message
-    });
-
-In the main add-on code (in this case a panel instance), to listen for
-"myMessage" sent from a a content script:
-
-    panel.port.on("myMessage", function handleMyMessage(myMessagePayload) {
-      // Handle the message
-    });
-
-## port.removeListener() ##
-
-You can uses `port.on()` to listen for messages. To stop listening for a
-particular message, use `port.removeListener()`. This takes the
-same two parameters as `port.on()`: the name of the message, and the name
-of the listener function.
-
-For example, here's an add-on that creates a page-worker and a widget.
-The page-worker loads
-[http://en.wikipedia.org/wiki/Chalk](http://en.wikipedia.org/wiki/Chalk)
-alongside a content script "listener.js". The widget sends the content script
-a message called "get-first-para" when it is clicked:
-
-    pageWorker = require("sdk/page-worker").Page({
-      contentScriptFile: require("sdk/self").data.url("listener.js"),
-      contentURL: "http://en.wikipedia.org/wiki/Chalk"
-    });
-
-    require("sdk/widget").Widget({
-      id: "mozilla-icon",
-      label: "My Mozilla Widget",
-      contentURL: "http://www.mozilla.org/favicon.ico",
-      onClick: function() {
-        console.log("sending 'get-first-para'");
-        pageWorker.port.emit("get-first-para");
-      }
-    });
-
-The content script "listener.js" listens for "get-first-para". When it
-receives this message, the script logs the first paragraph of the document
-and then calls `removeListener()` to stop listening.
-
-    function getFirstParagraph() {
-      var paras = document.getElementsByTagName('p');
-      console.log(paras[0].textContent);
-      self.port.removeListener("get-first-para", getFirstParagraph);
-    }
-
-    self.port.on("get-first-para", getFirstParagraph);
-
-The result is that the paragraph is only logged the first time the widget
-is clicked.
-
-Due to [bug 816272](https://bugzilla.mozilla.org/show_bug.cgi?id=816272)
-the [`page-mod`](modules/sdk/page-mod.html)'s `removeListener()` function
-does not prevent the listener from receiving messages that are already queued.
-This means that if "main.js" sends the message twice in successive lines, and
-the listener stops listening as soon as it receives the first message, then
-the listener will still receive the second message.
-
-## port.once() ##
-
-Often you'll want to receive a message just once, then stop listening. The
-`port` object offers a shortcut to do this: the `once()` method.
-
-This example rewrites the "listener.js" content script in the
-[`port.removeListener()` example](dev-guide/guides/content-scripts/using-port.html#port.removeListener())
-so that it uses `once()`:
-
-    function getFirstParagraph() {
-      var paras = document.getElementsByTagName('p');
-      console.log(paras[0].textContent);
-    }
-
-    self.port.once("get-first-para", getFirstParagraph);
-
-## <a name="json_serializable">JSON-Serializable Values</a> ##
-
-The payload for an message can be any JSON-serializable value. When messages
-are sent their payloads are automatically serialized, and when messages are
-received their payloads are automatically deserialized, so you don't need to
-worry about serialization.
-
-However, you _do_ have to ensure that the payload can be serialized to JSON.
-This means that it needs to be a string, number, boolean, null, array of
-JSON-serializable values, or an object whose property values are themselves
-JSON-serializable. This means you can't send functions, and if the object
-contains methods they won't be encoded.
-
-For example, to include an array of strings in the payload:
-
-    var pageModScript = "self.port.emit('loaded'," +
-                        "  [" +
-                        "  document.location.toString()," +
-                        "  document.title" +
-                        "  ]" +
-                        ");"
-
-    var pageMod = require('page-mod').PageMod({
-      include: ['*'],
-      contentScript: pageModScript,
-      onAttach: function(worker) {
-        worker.port.on('loaded', function(pageInfo) {
-          console.log(pageInfo[0]);
-          console.log(pageInfo[1]);
-        });
-      }
-    });
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/using-postmessage.md
+++ /dev/null
@@ -1,140 +0,0 @@
-<!-- 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/. -->
-
-# Communicating using "postMessage()" #
-
-As an alternative to user-defined events content modules support the built-in
-`message` event. In most cases user-defined events are preferable to message
-events. However, the `context-menu` module does not support user-defined
-events, so to send messages from a content script to the add-on via a context
-menu object, you must use message events.
-
-## Handling Message Events in the Content Script ##
-
-To send a message from a content script, you use the `postMessage` function of
-the global `self` object:
-
-    self.postMessage(contentScriptMessage);
-
-This takes a single parameter, the message payload, which may be any
-<a href = "dev-guide/guides/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>.
-
-To receive a message from the add-on script, use `self`'s `on` function:
-
-    self.on("message", function(addonMessage) {
-      // Handle the message
-    });
-
-Like all event-registration functions, this takes two parameters: the name
-of the event, and the handler function. The handler function is passed the
-message payload.
-
-## Handling Message Events in the Add-on Script ##
-
-To send a message to a content script, use the worker's `postMessage`
-function. Again, `panel` and `page` integrate `worker` directly:
-
-    // Post a message to the panel's content scripts
-    panel.postMessage(addonMessage);
-
-However, for `page-mod` objects you need to listen to the `onAttach` event
-and use the [worker](modules/sdk/content/worker.html#Worker) supplied to that:
-
-    var pageMod = require('sdk/page-mod').PageMod({
-      include: ['*'],
-      contentScript: pageModScript,
-      onAttach: function(worker) {
-        worker.postMessage(addonMessage);
-      }
-    });
-
-To receive messages from a content script, use the worker's `on` function.
-To simplify this most content modules provide an `onMessage` property as an
-argument to the constructor:
-
-    panel = require("sdk/panel").Panel({
-      onMessage: function(contentScriptMessage) {
-        // Handle message from the content script
-      }
-    });
-
-## Message Events Versus User-Defined Events ##
-
-You can use message events as an alternative to user-defined events:
-
-    var pageModScript = "window.addEventListener('mouseover', function(event) {" +
-                        "  self.postMessage(event.target.toString());" +
-                        "}, false);";
-
-    var pageMod = require('sdk/page-mod').PageMod({
-      include: ['*'],
-      contentScript: pageModScript,
-      onAttach: function(worker) {
-        worker.on('message', function(message) {
-          console.log('mouseover: ' + message);
-        });
-      }
-    });
-
-The reason to prefer user-defined events is that as soon as you need to send
-more than one type of message, then both sending and receiving messages gets
-more complex.
-
-Suppose the content script wants to send `mouseout` events as well as
-`mouseover`. Now we have to embed the event type in the message payload, and
-implement a switch function in the receiver to dispatch the message:
-
-    var pageModScript = "window.addEventListener('mouseover', function(event) {" +
-                        "  self.postMessage({" +
-                        "    kind: 'mouseover'," +
-                        "    element: event.target.toString()" +
-                        "  });" +
-                        "}, false);" +
-                        "window.addEventListener('mouseout', function(event) {" +
-                        "  self.postMessage({" +
-                        "    kind: 'mouseout'," +
-                        "    element: event.target.toString()" +
-                        "  });" +
-                        " }, false);"
-
-
-    var pageMod = require('sdk/page-mod').PageMod({
-      include: ['*'],
-      contentScript: pageModScript,
-      onAttach: function(worker) {
-        worker.on('message', function(message) {
-        switch(message.kind) {
-          case 'mouseover':
-            console.log('mouseover: ' + message.element);
-            break;
-          case 'mouseout':
-            console.log('mouseout: ' + message.element);
-            break;
-          }
-        });
-      }
-    });
-
-Implementing the same add-on with user-defined events is shorter and more
-readable:
-
-    var pageModScript = "window.addEventListener('mouseover', function(event) {" +
-                        "  self.port.emit('mouseover', event.target.toString());" +
-                        "}, false);" +
-                        "window.addEventListener('mouseout', function(event) {" +
-                        "  self.port.emit('mouseout', event.target.toString());" +
-                        "}, false);";
-
-    var pageMod = require('sdk/page-mod').PageMod({
-      include: ['*'],
-      contentScript: pageModScript,
-      onAttach: function(worker) {
-        worker.port.on('mouseover', function(message) {
-          console.log('mouseover :' + message);
-        });
-        worker.port.on('mouseout', function(message) {
-          console.log('mouseout :' + message);
-        });
-      }
-    });
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/contributors-guide/classes-and-inheritance.md
+++ /dev/null
@@ -1,272 +0,0 @@
-<!-- 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/. -->
-
-#Classes and Inheritance
-A class is a blueprint from which individual objects are created. These
-individual objects are the instances of the class. Each class defines one or
-more members, which are initialized to a given value when the class is
-instantiated. Data members are properties that allow each instance to have
-their own state, whereas member functions are properties that allow instances to
-have behavior. Inheritance allows classes to inherit state and behavior from an
-existing classes, known as the base class. Unlike languages like C++ and Java,
-JavaScript does not have native support for classical inheritance. Instead, it
-uses something called prototypal inheritance. As it turns out, it is possible to
-emulate classical inheritance using prototypal inheritance, but not without
-writing a significant amount of boilerplate code.
-
-Classes in JavaScript are defined using constructor functions. Each constructor
-function has an associated object, known as its prototype, which is shared
-between all instances of that class. We will show how to define classes using
-constructors, and how to use prototypes to efficiently define member functions
-on each instance. Classical inheritance can be implemented in JavaScript using
-constructors and prototypes. We will show how to make inheritance work correctly
-with respect to constructors, prototypes, and the instanceof operator, and how
-to override methods in subclasses. The SDK uses a special constructor internally,
-known as `Class`, to create constructors that behave properly with respect to
-inheritance. The last section shows how to work with the `Class` constructor. It
-is possible to read this section on its own. However, to fully appreciate how
-`Class` works, and the problem it is supposed to solve, it is recommended that
-you read the entire article.
-
-##Constructors
-In JavaScript, a class is defined by defining a constructor function for that
-class. To illustrate this, let's define a simple constructor for a class
-`Shape`:
-
-    function Shape(x, y) {
-        this.x = x;
-        this.y = y;
-    }
-
-We can now use this constructor to create instances of `Shape`:
-
-    let shape = new Shape(2, 3);
-    shape instanceof Shape; // => true
-    shape.x; // => 2
-    shape.y; // => 3
-
-The keyword new tells JavaScript that we are performing a constructor call.
-Constructor calls differ from ordinary function calls in that JavaScript
-automatically creates a new object and binds it to the keyword this for the
-duration of the call. Moreover, if the constructor does not return a value, the
-result of the call defaults to the value of this. Constructors are just ordinary
-functions, however, so it is perfectly legal to perform ordinary function calls
-on them. In fact, some people (including the Add-on SDK team) prefer to use
-constructors this way. However, since the value of this is undefined for
-ordinary function calls, we need to add some boilerplate code to convert them to
-constructor calls:
-
-    function Shape(x, y) {
-        if (!this)
-            return new Shape(x, y);
-        this.x = x;
-        this.y = y;
-    }
-
-##Prototypes
-Every object has an implicit property, known as its prototype. When JavaScript
-looks for a property, it first looks for it in the object itself. If it cannot
-find the property there, it looks for it in the object's prototype. If the
-property is found on the prototype, the lookup succeeds, and JavaScript pretends
-that it found the property on the original object. Every function has an
-explicit property, known as `prototype`. When a function is used in a
-constructor call, JavaScript makes the value of this property the prototype of
-the newly created object:
-
-    let shape = Shape(2, 3);
-    Object.getPrototypeOf(shape) == Shape.prototype; // => true
-
-All instances of a class have the same prototype. This makes the prototype the
-perfect place to define properties that are shared between instances of the
-class. To illustrate this, let's add a member function to the class `Shape`:
-
-    Shape.prototype.draw = function () {
-        throw Error("not yet implemented");
-    }
-    let shape = Shape(2, 3);
-    Shape.draw(); // => Error: not yet implemented
-
-##Inheritance and Constructors
-Suppose we want to create a new class, `Circle`, and inherit it from `Shape`.
-Since every `Circle` is also a `Shape`, the constructor for `Circle` must be
-called every time we call the constructor for `Shape`. Since JavaScript does
-not have native support for inheritance, it doesn't do this automatically.
-Instead, we need to call the constructor for `Shape` explicitly. The resulting
-constructor looks as follows:
-
-    function Circle(x, y, radius) {
-       if (!this)
-           return new Circle(x, y, radius);
-       Shape.call(this, x, y);
-       this.radius = radius;
-    }
-
-Note that the constructor for `Shape` is called as an ordinary function, and
-reuses the object created for the constructor call to `Circle`. Had we used a
-constructor call instead, the constructor for `Shape` would have been applied to
-a different object than the constructor for `Circle`. We can now use the above
-constructor to create instances of the class `Circle`:
-
-    let circle = Circle(2, 3, 5);
-    circle instanceof Circle; // => true
-    circle.x; // => 2
-    circle.y; // => 3
-    circle.radius; // => 5
-
-##Inheritance and Prototypes
-There is a problem with the definition of `Circle` in the previous section that
-we have glossed over thus far. Consider the following:
-
-    let circle = Circle(2, 3, 5);
-    circle.draw(); // => TypeError: circle.draw is not a function
-
-This is not quite right. The method `draw` is defined on instances of `Shape`,
-so we definitely want it to be defined on instances of `Circle`. The problem is
-that `draw` is defined on the prototype of `Shape`, but not on the prototype of
-`Circle`. We could of course copy every property from the prototype of `Shape`
-over to the prototype of `Circle`, but this is needlessly inefficient. Instead,
-we use a clever trick, based on the observation that prototypes are ordinary
-objects. Since prototypes are objects, they have a prototype as well. We can
-thus override the prototype of `Circle` with an object which prototype is the
-prototype of `Shape`.
-
-    Circle.prototype = Object.create(Shape.prototype);
-
-Now when JavaScript looks for the method draw on an instance of Circle, it first
-looks for it on the object itself. When it cannot find the property there, it
-looks for it on the prototype of `Circle`. When it cannot find the property
-there either, it looks for it on `Shape`, at which point the lookup succeeds.
-The resulting behavior is what we were aiming for.
-
-##Inheritance and Instanceof
-The single line of code we added in the previous section solved the problem with
-prototypes, but introduced a new problem with the **instanceof** operator.
-Consider the following:
-
-    let circle = Circle(2, 3, 5);
-    circle instanceof Shape; // => false
-
-Since instances of `Circle` inherit from `Shape`, we definitely want the result
-of this expression to be true. To understand why it is not, we need to
-understand how **instanceof** works. Every prototype has a `constructor`
-property, which is a reference to the constructor for objects with this
-prototype. In other words:
-
-    Circle.prototype.constructor == Circle // => true
-
-The **instanceof** operator compares the `constructor` property of the prototype
-of the left hand side with that of the right hand side, and returns true if they
-are equal. Otherwise, it repeats the comparison for the prototype of the right
-hand side, and so on, until either it returns **true**, or the prototype becomes
-**null**, in which case it returns **false**. The problem is that when we
-overrode the prototype of `Circle` with an object whose prototype is the
-prototype of `Shape`, we didn't correctly set its `constructor` property. This
-property is set automatically for the `prototype` property of a constructor, but
-not for objects created with `Object.create`. The `constructor` property is
-supposed to be non-configurable, non-enumberable, and non-writable, so the
-correct way to define it is as follows:
-
-    Circle.prototype = Object.create(Shape.prototype, {
-        constructor: {
-            value: Circle
-        }
-    });
-
-##Overriding Methods
-As a final example, we show how to override the stub implementation of the
-method `draw` in `Shape` with a more specialized one in `Circle`. Recall that
-JavaScript returns the first property it finds when walking the prototype chain
-of an object from the bottom up. Consequently, overriding a method is as simple
-as providing a new definition on the prototype of the subclass:
-
-    Circle.prototype.draw = function (ctx) {
-        ctx.beginPath();
-        ctx.arc(this.x, this.y, this.radius,
-                0, 2 * Math.PI, false);
-        ctx.fill();
-    };
-
-With this definition in place, we get:
-
-    let shape = Shape(2, 3);
-    shape.draw(); // Error: not yet implemented 
-    let circle = Circle(2, 3, 5);
-    circle.draw(); // TypeError: ctx is not defined
-
-which is the behavior we were aiming for.
-
-##Classes in the Add-on SDK
-We have shown how to emulate classical inheritance in JavaScript using
-constructors and prototypes. However, as we have seen, this takes a significant
-amount of boilerplate code. The Add-on SDK team consists of highly trained
-professionals, but they are also lazy: that is why the SDK contains a helper
-function that handles this boilerplate code for us. It is defined in the module
-“core/heritage”:
-
-    const { Class } = require('sdk/core/heritage');
-
-The function `Class` is a meta-constructor: it creates constructors that behave
-properly with respect to inheritance. It takes a single argument, which is an
-object which properties will be defined on the prototype of the resulting
-constructor. The semantics of `Class` are based on what we've learned earlier.
-For instance, to define a constructor for a class `Shape` in terms of `Class`,
-we can write:
-
-    let Shape = Class({
-        initialize: function (x, y) {
-            this.x = x;
-            this.y = y;
-        },
-        draw: function () {
-            throw new Error("not yet implemented");
-        }
-    }); 
-
-The property `initialize` is special. When it is present, the call to the
-constructor is forwarded to it, as are any arguments passed to it (including the
-this object). In effect, initialize specifies the body of the constructor. Note
-that the constructors created with `Class` automatically check whether they are
-called as constructors, so an explicit check is no longer necessary.
-
-Another special property is `extends`. It specifies the base class from which
-this class inherits, if any. `Class` uses this information to automatically set
-up the prototype chain of the constructor. If the extends property is omitted,
-`Class` itself is used as the base class:
-
-    var shape = new Shape(2, 3);
-    shape instanceof Shape; // => true
-    shape instanceof Class; // => true
-
-To illustrate the use of the `extends` property, let's redefine the constructor
-for the class `Circle` in terms of `Class`:
-
-    var Circle = Class({
-        extends: Shape,
-        initialize: function(x, y, radius) {
-            Shape.prototype.initialize.call(this, x, y);
-            this.radius = radius;
-        },
-        draw: function () {
-            context.beginPath();
-            context.arc(this.x, this.y, this.radius,
-                        0, 2 * Math.PI, false);
-            context.fill();
-        }
-    });
-
-Unlike the definition of `Circle` in the previous section, we no longer have to
-override its prototype, or set its `constructor` property. This is all handled
-automatically. On the other hand, the call to the constructor for `Shape` still
-has to be made explicitly. This is done by forwarding to the initialize method
-of the prototype of the base class. Note that this is always safe, even if there
-is no `initialize` method defined on the base class: in that case the call is
-forwarded to a stub implementation defined on `Class` itself.
-
-The last special property we will look into is `implements`. It specifies a list
-of objects, which properties are to be copied to the prototype of the
-constructor. Note that only properties defined on the object itself are copied:
-properties defined on one of its prototypes are not. This allows objects to
-inherit from more than one class. It is not true multiple inheritance, however:
-no constructors are called for objects inherited via `implements`, and
-**instanceof** only works correctly for classes inherited via `extends`.
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/contributors-guide/content-processes.md
+++ /dev/null
@@ -1,149 +0,0 @@
-<!-- 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/. -->
-
-#Content Processes
-A content process was supposed to run all the code associated with a single tab.
-Conversely, an add-on process was supposed to run all the code associated with a
-single add-on. Neither content or add-on proceses were ever actually
-implemented, but by the time they were cancelled, the SDK was already designed
-with them in mind. To understand this article, it's probably best to read it as
-if content and add-on processes actually exist.
-
-To communicate between add-on and content processes, the SDK uses something
-called content scripts. These are explained in the first section. Content
-scripts communicate with add-on code using something called event emitters.
-These are explained in the next section. Content workers combine these ideas,
-allowing you to inject a content script into a content process, and
-automatically set up a communication channel between them. These are explained
-in the third section.
-
-In the next section, we will look at how content scripts interact with the DOM
-in a content process. There are several caveats here, all of them related to
-security, that might cause things to not behave in the way you might expect.
-
-The final section explains why the SDK still uses the notion of content scripts
-and message passing, even though the multiprocess model for which they were
-designed never materialized. This, too, is primarily related to security.
-
-##Content Scripts
-When the SDK was first designed, Firefox was being refactored towards a
-multiprocess model. In this model, the UI would be rendered in one process
-(called the chrome process), whereas each tab and each add-on would run in their
-own dedicated process (called content and add-on processes, respectively). The
-project behind this refactor was known as Electrolysis, or E10s. Although E10s
-has now been suspended, the SDK was designed with this multiprocess model in
-mind. Afterwards, it was decided to keep the design the way it is: even though
-its no longer necessary, it turns out that from a security point of view there
-are several important advantages to thinking about content and add-on code as
-living in different processes.
-
-Many add-ons have to interact with content. The problem with the multiprocess
-model is that add-ons and content are now in different processes, and scripts in
-one process cannot interact directly with scripts in another. We can, however,
-pass JSON messages between scripts in different processes. The solution we've
-come up with is to introduce the notion of content scripts. A content script is
-a script that is injected into a content process by the main script running in
-the add-on process. Content scripts differ from scripts that are loaded by the
-page itself in that they are provided with a messaging API that can be used to
-send messages back to the add-on script.
-
-##Event Emitters
-The messaging API we use to send JSON messages between scripts in different
-processes is based on the use of event emitters. An event emitter maintains a
-list of callbacks (or listeners) for one or more named events. Each event
-emitter has several methods: the method on is used to add a listener for an
-event. Conversely, the method removeListener is used to remove a listener for an
-event. The method once is a helper function which adds a listener for an event,
-and automatically removes it the first time it is called.
-
-Each event emitter has two associated emit functions. One emit function is
-associated with the event emitter itself. When this function is called with a
-given event name, it calls all the listeners currently associated with that
-event. The other emit function is associated with another event emitter: it was
-passed as an argument to the constructor of this event emitter, and made into a
-method. Calling this method causes an event to be emitted on the other event
-emitter.
-
-Suppose we have two event emitters in different processes, and we want them to
-be able to emit events to each other. In this case, we would replace the emit
-function passed to the constructor of each emitter with a function that sends a
-message to the other process. We can then hook up a listener to be called when
-this message arrives at the other process, which in turn calls the emit function
-on the other event emitter. The combination of this function and the
-corresponding listener is referred to as a pipe. 
-
-##Content Workers
-A content worker is an object that is used to inject content scripts into a
-content process, and to provide a pipe between each content script and the main
-add-on script. The idea is to use a single content worker for each content
-process. The constructor for the content worker takes an object containing one
-or more named options. Among other things, this allows us to specify one or more
-content scripts to be loaded.
-
-When a content script is first loaded, the content worker automatically imports
-a messaging API that allows the it to emit messages over a pipe. On the add-on
-side, this pipe is exposed via the the port property on the worker. In addition
-to the port property, workers also support the web worker API, which allows
-scripts to send messages to each other using the postMessage function. This
-function uses the same pipe internally, and causes a 'message' event to be
-emitted on the other side.
-
-As explained earlier, Firefox doesn't yet use separate processes for tabs or
-add-ons, so instead, each content script is loaded in a sandbox. Sandboxes were
-explained [this article]("dev-guide/guides/contributors-guide/modules.html").
-
-##Accessing the DOM
-The global for the content sandbox has the window object as its prototype. This
-allows the content script to access any property on the window object, even
-though that object lives outside the sandbox. Recall that the window object
-inside the sandbox is actually a wrapper to the real object. A potential
-problem with the content script having access to the window object is that a
-malicious page could override methods on the window object that it knows are
-being used by the add-on, in order to trick the add-on into doing something it
-does not expect. Similarly, if the content script defines any values on the
-window object, a malicious page could potentially steal that information.
-
-To avoid problems like this, content scripts should always see the built-in
-properties of the window object, even when they are overridden by another
-script. Conversely, other scripts should not see any properties added to the
-window object by the content script. This is where xray wrappers come in. Xray
-wrappers automatically wrap native objects like the window object, and only
-exposes their native properties, even if they have been overridden on the
-wrapped object. Conversely, any properties defined on the wrapper are not
-visible from the wrapped object. This avoids both problems we mentioned earlier.
-
-The fact that you can't override the properties of the window object via a
-content script is sometimes inconvenient, so it is possible to circumvent this:
-by defining the property on window.wrappedObject, the property is defined on the
-underlying object, rather than the wrapper itself. This feature should only be
-used when you really need it, however.
-
-##A few Notes on Security
-As we stated earlier, the SDK was designed with multiprocess support in mind,
-despite the fact that work on implementing this in Firefox has currently been
-suspended. Since both add-on modules and content scripts are currently loaded in
-sandboxes rather than separate processes, and sandboxes can communicate with
-each other directly (using imports/exports), you might be wondering why we have
-to go through all the trouble of passing messages between add-on and content
-scripts. The reason for this extra complexity is that the code for add-on
-modules and content scripts has different privileges. Every add-on module can
-get chrome privileges simply by asking for them, whereas content scripts have
-the same privileges as the page it is running on.
-
-When two sandboxes have the same privileges, a wrapper in one sandbox provides
-transparent access to an object in the other sandbox. When the two sandboxes
-have different privileges, things become more complicated, however. Code with
-content privileges should not be able to acces code with chrome privileges, so
-we use specialized wrappers, called security wrappers, to limit access to the
-object in the other sandbox. The xray wrappers we saw earlier are an example of
-such a security wrapper. Security wrappers are created automatically, by the
-underlying host application.
-
-A full discussion of the different kinds of security wrappers and how they work
-is out of scope for this document, but the main point is this: security wrappers
-are very complex, and very error-prone. They are subject to change, in order to
-fix some security leak that recently popped up. As a result, code that worked
-just fine last week suddenly does not work the way you expect. By only passing
-messages between add-on modules and content scripts, these problems can be
-avoided, making your add-on both easier to debug and to maintain.
deleted file mode 100644
--- a/addon-sdk/source/doc/dev-guide-source/guides/contributors-guide/getting-started.md
+++ /dev/null
@@ -1,318 +0,0 @@
-<!-- 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/. -->
-
-#Getting Started
-The contribution process consists of a number of steps. First, you need to get
-a copy of the code. Next, you need to open a bug for the bug or feature you want
-to work on, and assign it to yourself. Alternatively, you can take an existing
-bug to work on. Once you've taken a bug, you can start writing a patch. Once
-your patch is complete, you've made sure it doesn't break any tests, and you've
-gotten a positive review for it, the last step is to request for your patch to
-be merged with the main codebase.
-
-Although these individual steps are all obvious, there are quite some details
-involved. The rest of this article will cover each individual step of the
-contribution process in more detail.
-
-##Getting the Code
-The Add-on SDK code is hosted on GitHub. GitHub is a web-based hosting service
-for software projects that is based on Git, a distributed version control
-system. Both GitHub and Git are an integral part of our workflow. If you haven't
-familiarized yourself with Git before, I strongly suggest you do so now. You're
-free to ignore that suggestion if you want, but it's going to hurt you later on
-(don't come crying to me if you end up accidentally detaching your head, for
-instance). A full explanation of how to use Git is out of scope for this
-document, but a very good one
-[can be found online here](http://git-scm.com/book). Reading at least sections
-1-3 from that book should be enough to get you started.
-
-If you're already familiar with Git, or if you decided to ignore my advice and
-jump right in, the following steps will get you a local copy of the Add-on SDK
-code on your machine:
-
-1. Fork the SDK repository to your GitHub account
-2. Clone the forked repository to your machine
-
-A fork is similar to a clone in that it creates a complete copy of a repository,
-including the history of every file. The difference is that a fork copies the
-repository to your GitHub account, whereas a clone copies it to your machine. To
-create a fork of the SDK repository, you need a GitHub account. If you don't
-already have one, you can [create one here](https://github.com/) (don't worry:
-it's free!). Once you got yourself an account, go to
-[the Add-on SDK repository](https://github.com/mozilla/addon-sdk), and click the
-fork button in the upper-right corner. This will start the forking process.
-This could take anywhere between a couple of seconds and a couple of minutes.
-
-Once the forking process is complete, the forked repository will be available at
-https://github.com/\<your-username\>/addon-sdk. To create a clone of the this
-repository, you need to have Git installed on your machine. If you don’t have it
-already, you can [download it here](http://git-scm.com/). Once you have Git
-installed (make sure you also configured your name and e-mail
-address), open your terminal, and enter the following command from the directory
-where you want to have the clone stored:
-
-> `git clone ssh://github.com/<your-username>/addon-sdk`
-
-This will start the cloning process. Like the forking process, this could take
-anywhere between a couple of seconds and a couple of minutes, depending on the
-speed of your connection.
-
-If you did everything correctly so far, once the cloning process is complete,
-the cloned repository will have been stored inside the directory from which you
-ran the clone command, in a new directory called addon-sdk. Now we can start
-working with it. Yay!
-
-As a final note: it is possible to skip step 1, and clone the SDK repository
-directly to your machine. This is useful if you only want to study the SDK code.
-However, if your goal is to actually contribute to the SDK, skipping step 1 is a
-bad idea, because you won’t be able to make pull requests in that case.
-
-##Opening a Bug
-In any large software project, keeping track of bugs is crucially important.
-Without it, developers wouldn't be able to answer questions such as: what do I
-need to work on, who is working on what, etc. Mozilla uses its own web-based,
-general-purpose bugtracker, called Bugzilla, to keep track of bugs. Like GitHub
-and Git, Bugzilla is an integral part of our workflow. When you discover a new
-bug, or want to implement a new feature, you start by creating an entry for it
-in Bugzilla. By doing so, you give the SDK team a chance to confirm whether your
-bug isn't actually a feature, or your feature isn't actually a bug
-(that is, a feature we feel doesn't belong into the SDK).
-
-Within Bugzilla, the term _bug_ is often used interchangably to refer to both
-bugs and features. Similarly, the Bugzilla entry for a bug is also named bug,
-and the process of creating it is known as _opening a bug_. It is important that
-you understand this terminology, as other people will regularly refer to it.
-
-I really urge you to open a bug first and wait for it to get confirmed before
-you start working on something. Nothing sucks more than your patch getting
-rejected because we felt it shouldn't go into the SDK. Having this discussion
-first saves you from doing useless work. If you have questions about a bug, but
-don't know who to ask (or the person you need to ask isn't online), Bugzilla is
-the communication channel of choice. When you open a bug, the relevant people
-are automatically put on the cc-list, so they will get an e-mail every time you
-write a comment in the bug.
-
-To open a bug, you need a Bugzilla account. If you don't already have one, you
-can [create it here](https://bugzilla.mozilla.org/). Once you got yourself an
-account, click the "new" link in the upper-left corner. This will take you to a
-page where you need to select the product that is affected by your bug. It isn't
-immediately obvious what you should pick here (and with not immediately obvious
-I mean completely non-obvious), so I'll just point it out to you: as you might
-expect, the Add-on SDK is listed under "Other products", at the bottom of the
-page.
-
-After selecting the Add-on SDK, you will be taken to another page, where you
-need to fill out the details for the bug. The important fields are the component
-affected by this bug, the summary, and a short description of the bug (don't
-worry about coming up with the perfect description for your bug. If something is
-not clear, someone from the SDK team will simply write a comment asking for
-clarification). The other fields are optional, and you can leave them as is, if
-you so desire.
-
-Note that when you fill out the summary field, Bugzilla automatically looks for
-bugs that are possible duplicates of the one you're creating. If you spot such a
-duplicate, there's no need to create another bug. In fact, doing so is
-pointless, as duplicate bugs are almost always immediately closed. Don't worry
-about accidentally opening a duplicate bug though. Doing so is not considered a
-major offense (unless you do it on purpose, of course).
-
-After filling out the details for the bug, the final step is to click the
-"Submit Bug" button at the bottom of the page. Once you click this button, the
-bug will be stored in Bugzilla’s database, and the creation process is
-completed. The initial status