Merge mozilla-central to beta. a=merge, l10n=me on a CLOSED TREE
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 16 Jan 2018 09:30:32 -0500
changeset 451203 a6525ed16a32fcc025ecf7cc073d8200a79f6485
parent 450752 15129163c0eda61d010f114e19f73e11aa61f3fe (current diff)
parent 451202 e4107773cffb1baefd5446666fce22c4d6eb0517 (diff)
child 451210 4f3ef7e330c3dcd62d47190168034b494ab3e21c
push id8543
push userryanvm@gmail.com
push dateTue, 16 Jan 2018 14:33:22 +0000
treeherdermozilla-beta@a6525ed16a32 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone59.0
Merge mozilla-central to beta. a=merge, l10n=me on a CLOSED TREE
browser/base/content/test/general/browser_close_dependent_tabs.js
browser/components/sessionstore/test/browser_grouped_session_store.js
devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_property_provider.js
devtools/client/webconsole/test/browser_webconsole_property_provider.js
docshell/base/PendingGlobalHistoryEntry.cpp
docshell/base/PendingGlobalHistoryEntry.h
docshell/shistory/nsIGroupedSHistory.idl
docshell/shistory/nsIPartialSHistory.idl
docshell/shistory/nsIPartialSHistoryListener.idl
docshell/test/browser/browser_grouped_shistory_bfcache_cleaning.js
docshell/test/browser/browser_grouped_shistory_crossproc.js
docshell/test/browser/browser_grouped_shistory_dead_navigate.js
dom/base/GroupedSHistory.cpp
dom/base/GroupedSHistory.h
dom/base/PartialSHistory.cpp
dom/base/PartialSHistory.h
dom/base/test/chrome/test_groupedSHistory.xul
dom/base/test/chrome/window_groupedSHistory.xul
dom/bindings/test/file_focuser.html
dom/bindings/test/file_fullScreenPropertyAccessor.html
dom/bindings/test/test_blacklisted_prerendering_function.xul
dom/bindings/test/test_kill_longrunning_prerendered_content.xul
dom/tests/browser/browser_prerendering.js
dom/tests/browser/prerender.html
dom/tests/browser/prerender_target.html
dom/tests/mochitest/webcomponents/test_bug1176757.html
dom/xul/test/1061864.html
dom/xul/test/file_bug1069772.xul
dom/xul/test/file_bug1271240.xul
dom/xul/test/test_bug1061864_1.xul
dom/xul/test/test_bug1061864_2.xul
dom/xul/test/test_bug1069772.xul
dom/xul/test/test_bug1271240.xul
editor/nsPIEditorTransaction.idl
intl/l10n/test/dom/test_domloc_translateElement.html
js/src/tests/test262/built-ins/BigInt/parseInt/all-decimal-digits.js
js/src/tests/test262/built-ins/BigInt/parseInt/arg-boolean.js
js/src/tests/test262/built-ins/BigInt/parseInt/arg-number.js
js/src/tests/test262/built-ins/BigInt/parseInt/arg-primitive-coercion.js
js/src/tests/test262/built-ins/BigInt/parseInt/arg-string-obj.js
js/src/tests/test262/built-ins/BigInt/parseInt/arg-undefined-null.js
js/src/tests/test262/built-ins/BigInt/parseInt/binary-negative.js
js/src/tests/test262/built-ins/BigInt/parseInt/binary.js
js/src/tests/test262/built-ins/BigInt/parseInt/decimal-negative.js
js/src/tests/test262/built-ins/BigInt/parseInt/empty-with-radix.js
js/src/tests/test262/built-ins/BigInt/parseInt/empty.js
js/src/tests/test262/built-ins/BigInt/parseInt/hex-prefix-lc.js
js/src/tests/test262/built-ins/BigInt/parseInt/hex-prefix-uc.js
js/src/tests/test262/built-ins/BigInt/parseInt/hex.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-cr.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-ff.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-lf.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-ls.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-nbsp.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-ps.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-space.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-tab.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-u180e.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-vt.js
js/src/tests/test262/built-ins/BigInt/parseInt/leading-ws.js
js/src/tests/test262/built-ins/BigInt/parseInt/length.js
js/src/tests/test262/built-ins/BigInt/parseInt/mixed-case-signed.js
js/src/tests/test262/built-ins/BigInt/parseInt/mixed-case-unsigned.js
js/src/tests/test262/built-ins/BigInt/parseInt/name.js
js/src/tests/test262/built-ins/BigInt/parseInt/no-prototype.js
js/src/tests/test262/built-ins/BigInt/parseInt/not-constructor.js
js/src/tests/test262/built-ins/BigInt/parseInt/octal-prefix.js
js/src/tests/test262/built-ins/BigInt/parseInt/parseInt.js
js/src/tests/test262/built-ins/BigInt/parseInt/prop-desc.js
js/src/tests/test262/built-ins/BigInt/parseInt/radix-37.js
js/src/tests/test262/built-ins/BigInt/parseInt/radix-boolean.js
js/src/tests/test262/built-ins/BigInt/parseInt/radix-int32.js
js/src/tests/test262/built-ins/BigInt/parseInt/radix-number-obj.js
js/src/tests/test262/built-ins/BigInt/parseInt/radix-one.js
js/src/tests/test262/built-ins/BigInt/parseInt/radix-primitive-coercion.js
js/src/tests/test262/built-ins/BigInt/parseInt/radix-string.js
js/src/tests/test262/built-ins/BigInt/parseInt/radix-undefined-or-null.js
js/src/tests/test262/built-ins/BigInt/parseInt/radix-undefined.js
js/src/tests/test262/built-ins/BigInt/parseInt/radix-zero.js
js/src/tests/test262/built-ins/BigInt/parseInt/trailing-code-point.js
js/src/tests/test262/built-ins/BigInt/parseInt/trailing-invalid-digit-lc.js
js/src/tests/test262/built-ins/BigInt/parseInt/trailing-invalid-digit-uc.js
js/src/tests/test262/built-ins/BigInt/parseInt/trailing-non-digit-and-digit.js
js/src/tests/test262/built-ins/BigInt/parseInt/trailing-non-digit-lc.js
js/src/tests/test262/built-ins/BigInt/parseInt/trailing-non-digit-uc.js
js/src/tests/test262/harness/testbuiltinobject-function-badstring.js
js/src/tests/test262/harness/testbuiltinobject-function-expected-length.js
js/src/tests/test262/harness/testbuiltinobject-function-not-constructor-no-error.js
js/src/tests/test262/harness/testbuiltinobject-function-not-constructor-no-typeerror.js
js/src/tests/test262/harness/testbuiltinobject-non-extensible.js
js/src/tests/test262/harness/testbuiltinobject-not-function-badstring.js
js/src/tests/test262/harness/testbuiltinobject-prop-enumerable.js
js/src/tests/test262/harness/testbuiltinobject-prop-missing.js
js/src/tests/test262/harness/testbuiltinobject-prop-not-configurable.js
js/src/tests/test262/harness/testbuiltinobject-prop-not-writable.js
js/src/tests/test262/harness/testbuiltinobject-undefined.js
js/src/tests/test262/intl402/6.2.2_a.js
js/src/tests/test262/intl402/6.2.2_b.js
js/src/tests/test262/intl402/6.2.2_c.js
js/src/tests/test262/intl402/6.2.3_a.js
js/src/tests/test262/intl402/6.2.4.js
js/src/tests/test262/intl402/9.1_a.js
js/src/tests/test262/intl402/9.1_b.js
js/src/tests/test262/intl402/9.2.1_1.js
js/src/tests/test262/intl402/9.2.1_2.js
js/src/tests/test262/intl402/9.2.1_3.js
js/src/tests/test262/intl402/9.2.1_4.js
js/src/tests/test262/intl402/9.2.1_8_c_ii.js
js/src/tests/test262/intl402/9.2.1_8_c_vi.js
js/src/tests/test262/intl402/9.2.2.js
js/src/tests/test262/intl402/9.2.3_5.js
js/src/tests/test262/intl402/9.2.5_6.js
js/src/tests/test262/intl402/9.2.6_2.js
js/src/tests/test262/intl402/9.2.6_4.js
js/src/tests/test262/intl402/9.2.6_4_b.js
js/src/tests/test262/intl402/9.2.6_4_c.js
js/src/tests/test262/intl402/9.2.8_1_c.js
js/src/tests/test262/intl402/9.2.8_4.js
js/src/tests/test262/intl402/Collator/10.1.1_1.js
js/src/tests/test262/intl402/Collator/10.1.1_10.js
js/src/tests/test262/intl402/Collator/10.1.1_11.js
js/src/tests/test262/intl402/Collator/10.1.1_13.js
js/src/tests/test262/intl402/Collator/10.1.1_19_b.js
js/src/tests/test262/intl402/Collator/10.1.1_19_c.js
js/src/tests/test262/intl402/Collator/10.1.1_20.js
js/src/tests/test262/intl402/Collator/10.1.1_23.js
js/src/tests/test262/intl402/Collator/10.1.1_6.js
js/src/tests/test262/intl402/Collator/10.1.1_a.js
js/src/tests/test262/intl402/Collator/10.1.2_a.js
js/src/tests/test262/intl402/Collator/10.1.3.js
js/src/tests/test262/intl402/Collator/10.1_L15.js
js/src/tests/test262/intl402/Collator/10.2.3_b.js
js/src/tests/test262/intl402/Collator/10.4_a.js
js/src/tests/test262/intl402/Collator/9.2.5_11_g_ii_2.js
js/src/tests/test262/intl402/Collator/prototype/10.2.1.js
js/src/tests/test262/intl402/Collator/prototype/10.3_L15.js
js/src/tests/test262/intl402/Collator/prototype/10.3_a.js
js/src/tests/test262/intl402/Collator/prototype/10.3_b.js
js/src/tests/test262/intl402/Collator/prototype/compare/10.3.2_1_a_L15.js
js/src/tests/test262/intl402/Collator/prototype/compare/10.3.2_1_c.js
js/src/tests/test262/intl402/Collator/prototype/compare/10.3.2_CS_a.js
js/src/tests/test262/intl402/Collator/prototype/compare/10.3.2_CS_b_NN.js
js/src/tests/test262/intl402/Collator/prototype/compare/10.3.2_CS_c_NN.js
js/src/tests/test262/intl402/Collator/prototype/compare/10.3.2_CS_d_NN.js
js/src/tests/test262/intl402/Collator/prototype/compare/10.3.2_L15.js
js/src/tests/test262/intl402/Collator/prototype/constructor/10.3.1.js
js/src/tests/test262/intl402/Collator/prototype/resolvedOptions/10.3.3.js
js/src/tests/test262/intl402/Collator/prototype/resolvedOptions/10.3.3_L15.js
js/src/tests/test262/intl402/Collator/supportedLocalesOf/10.2.2_L15.js
js/src/tests/test262/intl402/Collator/supportedLocalesOf/10.2.2_a.js
js/src/tests/test262/intl402/Collator/supportedLocalesOf/10.2.2_b.js
js/src/tests/test262/intl402/Date/prototype/13.3.0_1.js
js/src/tests/test262/intl402/Date/prototype/13.3.0_2.js
js/src/tests/test262/intl402/Date/prototype/13.3.0_6_1.js
js/src/tests/test262/intl402/Date/prototype/13.3.0_6_2.js
js/src/tests/test262/intl402/Date/prototype/13.3.0_7.js
js/src/tests/test262/intl402/Date/prototype/toLocaleDateString/13.3.2_L15.js
js/src/tests/test262/intl402/Date/prototype/toLocaleString/13.3.1_L15.js
js/src/tests/test262/intl402/Date/prototype/toLocaleTimeString/13.3.3_L15.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.1_1.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.1_18.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.1_22.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.1_23.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.1_25.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.1_5.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.1_6.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.1_TDTO.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.1_a.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.2.js
js/src/tests/test262/intl402/DateTimeFormat/12.1.3.js
js/src/tests/test262/intl402/DateTimeFormat/12.1_L15.js
js/src/tests/test262/intl402/DateTimeFormat/12.2.3_b.js
js/src/tests/test262/intl402/DateTimeFormat/12.2.3_c.js
js/src/tests/test262/intl402/DateTimeFormat/12.4_a.js
js/src/tests/test262/intl402/DateTimeFormat/6.4_a.js
js/src/tests/test262/intl402/DateTimeFormat/6.4_b.js
js/src/tests/test262/intl402/DateTimeFormat/6.4_c.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/12.2.1.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/12.3_L15.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/12.3_a.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/12.3_b.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/12.3.1.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/format/12.3.2_1_a_L15.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/format/12.3.2_1_c.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/format/12.3.2_FDT_1.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/format/12.3.2_FDT_7_a_iv.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/format/12.3.2_L15.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/format/12.3.2_TLT_2.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/12.3.3.js
js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/12.3.3_L15.js
js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/12.2.2_L15.js
js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/12.2.2_a.js
js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/12.2.2_b.js
js/src/tests/test262/intl402/Intl/8.0.js
js/src/tests/test262/intl402/Intl/8.0_L15.js
js/src/tests/test262/intl402/Number/prototype/toLocaleString/13.2.1_1.js
js/src/tests/test262/intl402/Number/prototype/toLocaleString/13.2.1_4_1.js
js/src/tests/test262/intl402/Number/prototype/toLocaleString/13.2.1_4_2.js
js/src/tests/test262/intl402/Number/prototype/toLocaleString/13.2.1_5.js
js/src/tests/test262/intl402/Number/prototype/toLocaleString/13.2.1_L15.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_1.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_15.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_17.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_19.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_20_c.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_21.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_32.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_34.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_6.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_7.js
js/src/tests/test262/intl402/NumberFormat/11.1.1_a.js
js/src/tests/test262/intl402/NumberFormat/11.1.2.js
js/src/tests/test262/intl402/NumberFormat/11.1.3.js
js/src/tests/test262/intl402/NumberFormat/11.1_L15.js
js/src/tests/test262/intl402/NumberFormat/11.2.3_b.js
js/src/tests/test262/intl402/NumberFormat/11.4_a.js
js/src/tests/test262/intl402/NumberFormat/6.3.1_a.js
js/src/tests/test262/intl402/NumberFormat/6.3.1_b.js
js/src/tests/test262/intl402/NumberFormat/prototype/11.2.1.js
js/src/tests/test262/intl402/NumberFormat/prototype/11.3_L15.js
js/src/tests/test262/intl402/NumberFormat/prototype/11.3_a.js
js/src/tests/test262/intl402/NumberFormat/prototype/11.3_b.js
js/src/tests/test262/intl402/NumberFormat/prototype/constructor/11.3.1.js
js/src/tests/test262/intl402/NumberFormat/prototype/format/11.3.2_1_a_L15.js
js/src/tests/test262/intl402/NumberFormat/prototype/format/11.3.2_1_a_ii.js
js/src/tests/test262/intl402/NumberFormat/prototype/format/11.3.2_1_c.js
js/src/tests/test262/intl402/NumberFormat/prototype/format/11.3.2_FN_1.js
js/src/tests/test262/intl402/NumberFormat/prototype/format/11.3.2_FN_2.js
js/src/tests/test262/intl402/NumberFormat/prototype/format/11.3.2_FN_3_b.js
js/src/tests/test262/intl402/NumberFormat/prototype/format/11.3.2_FN_3_e.js
js/src/tests/test262/intl402/NumberFormat/prototype/format/11.3.2_L15.js
js/src/tests/test262/intl402/NumberFormat/prototype/format/11.3.2_TRF.js
js/src/tests/test262/intl402/NumberFormat/prototype/format/11.3.2_TRP.js
js/src/tests/test262/intl402/NumberFormat/prototype/resolvedOptions/11.3.3.js
js/src/tests/test262/intl402/NumberFormat/prototype/resolvedOptions/11.3.3_L15.js
js/src/tests/test262/intl402/NumberFormat/supportedLocalesOf/11.2.2_L15.js
js/src/tests/test262/intl402/NumberFormat/supportedLocalesOf/11.2.2_a.js
js/src/tests/test262/intl402/NumberFormat/supportedLocalesOf/11.2.2_b.js
js/src/tests/test262/intl402/String/prototype/localeCompare/13.1.1_1.js
js/src/tests/test262/intl402/String/prototype/localeCompare/13.1.1_2.js
js/src/tests/test262/intl402/String/prototype/localeCompare/13.1.1_3_1.js
js/src/tests/test262/intl402/String/prototype/localeCompare/13.1.1_3_2.js
js/src/tests/test262/intl402/String/prototype/localeCompare/13.1.1_6_1.js
js/src/tests/test262/intl402/String/prototype/localeCompare/13.1.1_6_2.js
js/src/tests/test262/intl402/String/prototype/localeCompare/13.1.1_7.js
js/src/tests/test262/intl402/String/prototype/localeCompare/13.1.1_L15.js
js/src/tests/test262/language/expressions/assignment/11.13.1-4-28-s-strict.js
js/src/tests/test262/language/expressions/assignment/11.13.1-4-29-s-strict.js
js/src/tests/test262/language/expressions/assignment/11.13.1-4-30-s-strict.js
js/src/tests/test262/language/expressions/assignment/11.13.1-4-31-s-strict.js
js/src/tests/test262/language/expressions/assignment/S11.13.1_A1.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-gen-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-gen-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-gen-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-gen-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-method-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-method-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-method-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-method-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-async-gen-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-async-gen-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-async-gen-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-async-gen-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-async-method-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-async-method-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-async-method-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-async-method-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-gen-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-gen-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-gen-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-gen-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-method-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-method-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-method-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-after-same-line-static-method-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-computed-name-static-propname-constructor.js
js/src/tests/test262/language/expressions/class/fields-computed-name-static-propname-prototype.js
js/src/tests/test262/language/expressions/class/fields-computed-variable-name-static-propname-constructor.js
js/src/tests/test262/language/expressions/class/fields-computed-variable-name-static-propname-prototype.js
js/src/tests/test262/language/expressions/class/fields-literal-name-static-propname-constructor.js
js/src/tests/test262/language/expressions/class/fields-literal-name-static-propname-prototype.js
js/src/tests/test262/language/expressions/class/fields-multiple-definitions-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-multiple-definitions-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-multiple-definitions-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-multiple-definitions-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-multiple-stacked-definitions-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-multiple-stacked-definitions-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-multiple-stacked-definitions-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-multiple-stacked-definitions-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-new-no-sc-line-method-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-new-no-sc-line-method-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-new-no-sc-line-method-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-new-no-sc-line-method-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-new-sc-line-gen-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-new-sc-line-gen-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-new-sc-line-gen-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-new-sc-line-gen-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-new-sc-line-method-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-new-sc-line-method-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-new-sc-line-method-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-new-sc-line-method-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-regular-definitions-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-regular-definitions-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-regular-definitions-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-regular-definitions-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-async-gen-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-async-gen-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-async-gen-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-async-gen-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-async-method-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-async-method-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-async-method-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-async-method-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-gen-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-gen-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-gen-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-gen-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-method-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-method-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-method-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-same-line-method-static-private-names.js
js/src/tests/test262/language/expressions/class/fields-static-comp-name-init-err-contains-arguments.js
js/src/tests/test262/language/expressions/class/fields-static-comp-name-init-err-contains-super.js
js/src/tests/test262/language/expressions/class/fields-static-computed-name-toprimitive-symbol.js
js/src/tests/test262/language/expressions/class/fields-static-computed-name-toprimitive.js
js/src/tests/test262/language/expressions/class/fields-static-literal-init-err-contains-arguments.js
js/src/tests/test262/language/expressions/class/fields-static-literal-init-err-contains-super.js
js/src/tests/test262/language/expressions/class/fields-static-private-init-err-contains-arguments.js
js/src/tests/test262/language/expressions/class/fields-static-private-init-err-contains-super.js
js/src/tests/test262/language/expressions/class/fields-static-redeclaration-symbol.js
js/src/tests/test262/language/expressions/class/fields-static-redeclaration.js
js/src/tests/test262/language/expressions/class/fields-static-string-literal-name-init-err-contains-arguments.js
js/src/tests/test262/language/expressions/class/fields-static-string-literal-name-init-err-contains-super.js
js/src/tests/test262/language/expressions/class/fields-string-name-static-propname-constructor.js
js/src/tests/test262/language/expressions/class/fields-string-name-static-propname-prototype.js
js/src/tests/test262/language/expressions/class/fields-wrapped-in-sc-static-computed-names.js
js/src/tests/test262/language/expressions/class/fields-wrapped-in-sc-static-computed-symbol-names.js
js/src/tests/test262/language/expressions/class/fields-wrapped-in-sc-static-literal-names.js
js/src/tests/test262/language/expressions/class/fields-wrapped-in-sc-static-private-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-gen-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-gen-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-gen-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-gen-static-private-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-method-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-method-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-method-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-method-static-private-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-async-gen-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-async-gen-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-async-gen-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-async-gen-static-private-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-async-method-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-async-method-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-async-method-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-async-method-static-private-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-gen-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-gen-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-gen-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-gen-static-private-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-method-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-method-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-method-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-after-same-line-static-method-static-private-names.js
js/src/tests/test262/language/statements/class/fields-comp-name-init-err-contains-arguments.js
js/src/tests/test262/language/statements/class/fields-comp-name-init-err-contains-super.js
js/src/tests/test262/language/statements/class/fields-computed-name-static-propname-constructor.js
js/src/tests/test262/language/statements/class/fields-computed-name-static-propname-prototype.js
js/src/tests/test262/language/statements/class/fields-computed-variable-name-static-propname-constructor.js
js/src/tests/test262/language/statements/class/fields-computed-variable-name-static-propname-prototype.js
js/src/tests/test262/language/statements/class/fields-literal-name-static-propname-constructor.js
js/src/tests/test262/language/statements/class/fields-literal-name-static-propname-prototype.js
js/src/tests/test262/language/statements/class/fields-multiple-definitions-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-multiple-definitions-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-multiple-definitions-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-multiple-definitions-static-private-names.js
js/src/tests/test262/language/statements/class/fields-multiple-stacked-definitions-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-multiple-stacked-definitions-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-multiple-stacked-definitions-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-multiple-stacked-definitions-static-private-names.js
js/src/tests/test262/language/statements/class/fields-new-no-sc-line-method-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-new-no-sc-line-method-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-new-no-sc-line-method-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-new-no-sc-line-method-static-private-names.js
js/src/tests/test262/language/statements/class/fields-new-sc-line-gen-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-new-sc-line-gen-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-new-sc-line-gen-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-new-sc-line-gen-static-private-names.js
js/src/tests/test262/language/statements/class/fields-new-sc-line-method-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-new-sc-line-method-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-new-sc-line-method-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-new-sc-line-method-static-private-names.js
js/src/tests/test262/language/statements/class/fields-regular-definitions-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-regular-definitions-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-regular-definitions-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-regular-definitions-static-private-names.js
js/src/tests/test262/language/statements/class/fields-same-line-async-gen-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-same-line-async-gen-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-same-line-async-gen-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-same-line-async-gen-static-private-names.js
js/src/tests/test262/language/statements/class/fields-same-line-async-method-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-same-line-async-method-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-same-line-async-method-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-same-line-async-method-static-private-names.js
js/src/tests/test262/language/statements/class/fields-same-line-gen-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-same-line-gen-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-same-line-gen-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-same-line-gen-static-private-names.js
js/src/tests/test262/language/statements/class/fields-same-line-method-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-same-line-method-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-same-line-method-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-same-line-method-static-private-names.js
js/src/tests/test262/language/statements/class/fields-static-comp-name-init-err-contains-arguments.js
js/src/tests/test262/language/statements/class/fields-static-comp-name-init-err-contains-super.js
js/src/tests/test262/language/statements/class/fields-static-computed-name-toprimitive-symbol.js
js/src/tests/test262/language/statements/class/fields-static-computed-name-toprimitive.js
js/src/tests/test262/language/statements/class/fields-static-literal-init-err-contains-arguments.js
js/src/tests/test262/language/statements/class/fields-static-literal-init-err-contains-super.js
js/src/tests/test262/language/statements/class/fields-static-private-init-err-contains-arguments.js
js/src/tests/test262/language/statements/class/fields-static-private-init-err-contains-super.js
js/src/tests/test262/language/statements/class/fields-static-redeclaration-symbol.js
js/src/tests/test262/language/statements/class/fields-static-redeclaration.js
js/src/tests/test262/language/statements/class/fields-static-string-literal-name-init-err-contains-arguments.js
js/src/tests/test262/language/statements/class/fields-static-string-literal-name-init-err-contains-super.js
js/src/tests/test262/language/statements/class/fields-string-name-static-propname-constructor.js
js/src/tests/test262/language/statements/class/fields-string-name-static-propname-prototype.js
js/src/tests/test262/language/statements/class/fields-wrapped-in-sc-static-computed-names.js
js/src/tests/test262/language/statements/class/fields-wrapped-in-sc-static-computed-symbol-names.js
js/src/tests/test262/language/statements/class/fields-wrapped-in-sc-static-literal-names.js
js/src/tests/test262/language/statements/class/fields-wrapped-in-sc-static-private-names.js
js/src/tests/test262/language/statements/class/static-classelementname-abrupt-completion.js
js/src/tests/test262/language/statements/class/static-fielddefinition-initializer-abrupt-completion.js
layout/style/test/display_mode_reflow_iframe.html
mobile/android/app/src/main/res/values-v13/search_styles.xml
mobile/android/app/src/main/res/values-v16/search_styles.xml
mobile/android/base/geckoview.ddf
mobile/android/base/java/org/mozilla/gecko/db/PerProfileDatabaseProvider.java
mobile/android/base/java/org/mozilla/gecko/home/HomeExpandableListView.java
mobile/android/base/resources/values-v17/themes.xml
mobile/android/build/classycle/LICENSE.txt
mobile/android/build/classycle/classycle-1.4.1.jar
netwerk/protocol/http/nsHttpTransaction.cpp
servo/components/selectors/gecko_like_types.rs
servo/components/selectors/size_of_tests.rs
taskcluster/scripts/builder/setup-ccache.sh
testing/marionette/doc/api/AsyncChromeSender.html
testing/marionette/doc/api/frame.Manager.html
testing/marionette/doc/api/frame.html
testing/marionette/doc/api/frame.js.html
testing/marionette/doc/api/proxy.SyncChromeSender.html
testing/marionette/doc/api/wait.html
testing/marionette/doc/api/wait.js.html
testing/marionette/harness/marionette_harness/tests/unit/test_clearing.py
testing/web-platform/meta/shadow-dom/Node-prototype-cloneNode.html.ini
testing/web-platform/meta/shadow-dom/ShadowRoot-interface.html.ini
testing/web-platform/meta/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/activeElement-confirm-return-null.html.ini
testing/web-platform/meta/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-007.html.ini
testing/web-platform/meta/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-010.html.ini
testing/web-platform/meta/shadow-dom/untriaged/user-interaction/active-element/test-001.html.ini
testing/web-platform/meta/shadow-dom/untriaged/user-interaction/active-element/test-002.html.ini
toolkit/components/filepicker/content/filepicker.js
toolkit/components/filepicker/content/filepicker.xul
toolkit/components/filepicker/jar.mn
toolkit/components/filepicker/moz.build
toolkit/components/filepicker/nsFilePicker.js
toolkit/components/filepicker/nsFilePicker.manifest
toolkit/components/filepicker/nsFileView.cpp
toolkit/components/filepicker/nsIFileView.idl
toolkit/components/filepicker/test/unit/.eslintrc.js
toolkit/components/filepicker/test/unit/test_filecomplete.js
toolkit/components/filepicker/test/unit/xpcshell.ini
toolkit/components/resistfingerprinting/nsRFPService.cpp
toolkit/components/resistfingerprinting/nsRFPService.h
toolkit/components/search/nsSearchService.js
toolkit/components/search/tests/xpcshell/xpcshell.ini
toolkit/locales/en-US/chrome/global/filepicker.dtd
toolkit/themes/linux/global/filepicker.css
toolkit/themes/linux/global/filepicker/Filepicker.png
widget/android/nsPrintOptionsAndroid.cpp
widget/android/nsPrintOptionsAndroid.h
widget/cocoa/nsPrintOptionsX.h
widget/cocoa/nsPrintOptionsX.mm
widget/gtk/nsPrintOptionsGTK.cpp
widget/gtk/nsPrintOptionsGTK.h
widget/nsPrintOptionsImpl.cpp
widget/nsPrintOptionsImpl.h
widget/windows/nsPrintOptionsWin.cpp
widget/windows/nsPrintOptionsWin.h
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -27,17 +27,16 @@ module.exports = {
   }, {
     // XXX Bug 1421969. These files/directories are still being fixed,
     // so turn off mozilla/use-services for them for now.
     "files": [
       // Browser: Bug 1421379
       "browser/extensions/shield-recipe-client/test/browser/head.js",
       "browser/modules/offlineAppCache.jsm",
       "devtools/**",
-      "dom/indexedDB/**",
       "extensions/pref/**",
       "mobile/android/**",
       "testing/**",
     ],
     "rules": {
       "mozilla/use-services": "off",
     }
   }]
--- a/.taskcluster.yml
+++ b/.taskcluster.yml
@@ -93,17 +93,17 @@ tasks:
               GECKO_HEAD_REPOSITORY: '${repoUrl}'
               GECKO_HEAD_REF: '${push.revision}'
               GECKO_HEAD_REV: '${push.revision}'
               GECKO_COMMIT_MSG: {$if: 'tasks_for != "action"', then: '${push.comment}'}
               HG_STORE_PATH: /builds/worker/checkouts/hg-store
               TASKCLUSTER_CACHES: /builds/worker/checkouts
             - $if: 'tasks_for == "action"'
               then:
-                ACTION_TASK_GROUP_ID: '${action.taskGroupId}'
+                ACTION_TASK_GROUP_ID: '${ownTaskId}'
                 ACTION_TASK_ID: {$json: {$eval: 'taskId'}}
                 ACTION_TASK: {$json: {$eval: 'task'}}
                 ACTION_INPUT: {$json: {$eval: 'input'}}
                 ACTION_CALLBACK: '${action.cb_name}'
                 ACTION_PARAMETERS: {$json: {$eval: 'parameters'}}
 
         cache:
           level-${repository.level}-checkouts-sparse-v1: /builds/worker/checkouts
@@ -180,9 +180,12 @@ tasks:
               parent: '${action.taskGroupId}'
               action:
                 name: '${action.name}'
                 context:
                   taskGroupId: '${action.taskGroupId}'
                   taskId: {$eval: 'taskId'}
                   input: {$eval: 'input'}
                   parameters: {$eval: 'parameters'}
+          - $if: 'tasks_for == "cron"'
+            then:
+              cron: {$json: {$eval: 'cron'}}
           - tasks_for: '${tasks_for}'
--- a/accessible/base/nsAccUtils.cpp
+++ b/accessible/base/nsAccUtils.cpp
@@ -363,17 +363,17 @@ nsAccUtils::GetScreenCoordsForParent(Acc
   if (!parent)
     return nsIntPoint(0, 0);
 
   nsIFrame *parentFrame = parent->GetFrame();
   if (!parentFrame)
     return nsIntPoint(0, 0);
 
   nsRect rect = parentFrame->GetScreenRectInAppUnits();
-  return nsPoint(rect.x, rect.y).
+  return nsPoint(rect.X(), rect.Y()).
     ToNearestPixels(parentFrame->PresContext()->AppUnitsPerDevPixel());
 }
 
 bool
 nsAccUtils::GetLiveAttrValue(uint32_t aRule, nsAString& aValue)
 {
   switch (aRule) {
     case eOffLiveAttr:
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -477,17 +477,17 @@ class PluginTimerCallBack final : public
 {
   ~PluginTimerCallBack() {}
 
 public:
   explicit PluginTimerCallBack(nsIContent* aContent) : mContent(aContent) {}
 
   NS_DECL_ISUPPORTS
 
-  NS_IMETHOD Notify(nsITimer* aTimer) final
+  NS_IMETHOD Notify(nsITimer* aTimer) final override
   {
     if (!mContent->IsInUncomposedDoc())
       return NS_OK;
 
     nsIPresShell* ps = mContent->OwnerDoc()->GetShell();
     if (ps) {
       DocAccessible* doc = ps->GetDocAccessible();
       if (doc) {
@@ -501,17 +501,17 @@ public:
 
     // We couldn't get a doc accessible so presumably the document went away.
     // In this case don't leak our ref to the content or timer.
     sPendingPlugins->RemoveElement(mContent);
     sPluginTimers->RemoveElement(aTimer);
     return NS_OK;
   }
 
-  NS_IMETHOD GetName(nsACString& aName) final
+  NS_IMETHOD GetName(nsACString& aName) final override
   {
     aName.AssignLiteral("PluginTimerCallBack");
     return NS_OK;
   }
 
 private:
   nsCOMPtr<nsIContent> mContent;
 };
@@ -1337,19 +1337,16 @@ nsAccessibilityService::Init()
 
 #if defined(XP_WIN)
   // This information needs to be initialized before the observer fires.
   if (XRE_IsParentProcess()) {
     Compatibility::Init();
   }
 #endif // defined(XP_WIN)
 
-  static const char16_t kInitIndicator[] = { '1', 0 };
-  observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kInitIndicator);
-
   // Subscribe to EventListenerService.
   nsCOMPtr<nsIEventListenerService> eventListenerService =
     do_GetService("@mozilla.org/eventlistenerservice;1");
   if (!eventListenerService)
     return false;
 
   eventListenerService->AddListenerChangeListener(this);
 
@@ -1401,16 +1398,19 @@ nsAccessibilityService::Init()
 #endif
 
   // Now its safe to start platform accessibility.
   if (XRE_IsParentProcess())
     PlatformInit();
 
   statistics::A11yInitialized();
 
+  static const char16_t kInitIndicator[] = { '1', 0 };
+  observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kInitIndicator);
+
   return true;
 }
 
 void
 nsAccessibilityService::Shutdown()
 {
   // Application is going to be closed, shutdown accessibility and mark
   // accessibility service as shutdown to prevent calls of its methods.
@@ -1420,19 +1420,16 @@ nsAccessibilityService::Shutdown()
   MOZ_ASSERT(gConsumers, "Accessibility was shutdown already");
   UnsetConsumers(eXPCOM | eMainProcess | ePlatformAPI);
 
   // Remove observers.
   nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
   if (observerService) {
     observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
-
-    static const char16_t kShutdownIndicator[] = { '0', 0 };
-    observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kShutdownIndicator);
   }
 
   // Stop accessible document loader.
   DocManager::Shutdown();
 
   SelectionManager::Shutdown();
 
 #ifdef XP_WIN
@@ -1452,16 +1449,21 @@ nsAccessibilityService::Shutdown()
   NS_RELEASE(gApplicationAccessible);
   gApplicationAccessible = nullptr;
 
   NS_IF_RELEASE(gXPCApplicationAccessible);
   gXPCApplicationAccessible = nullptr;
 
   NS_RELEASE(gAccessibilityService);
   gAccessibilityService = nullptr;
+
+  if (observerService) {
+    static const char16_t kShutdownIndicator[] = { '0', 0 };
+    observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kShutdownIndicator);
+  }
 }
 
 already_AddRefed<Accessible>
 nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
                                                DocAccessible* aDoc)
 {
   nsAutoString role;
   nsCoreUtils::XBLBindingRole(aContent, role);
--- a/accessible/base/nsAccessiblePivot.cpp
+++ b/accessible/base/nsAccessiblePivot.cpp
@@ -581,18 +581,17 @@ nsAccessiblePivot::MoveToPoint(nsIAccess
     if (filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE)
       match = nullptr;
 
     // Match if no node below this is a match
     if ((filtered & nsIAccessibleTraversalRule::FILTER_MATCH) && !match) {
       nsIntRect childRect = child->Bounds();
       // Double-check child's bounds since the deepest child may have been out
       // of bounds. This assures we don't return a false positive.
-      if (aX >= childRect.x && aX < childRect.x + childRect.width &&
-          aY >= childRect.y && aY < childRect.y + childRect.height)
+      if (childRect.Contains(aX, aY))
         match = child;
     }
 
     child = child->Parent();
   }
 
   if (match || !aIgnoreNoMatch)
     *aResult = MovePivotInternal(match, nsIAccessiblePivot::REASON_POINT,
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -297,17 +297,17 @@ nsCoreUtils::ScrollFrameToPoint(nsIFrame
 {
   nsIScrollableFrame* scrollableFrame = do_QueryFrame(aScrollableFrame);
   if (!scrollableFrame)
     return;
 
   nsPoint point =
     ToAppUnits(aPoint, aFrame->PresContext()->AppUnitsPerDevPixel());
   nsRect frameRect = aFrame->GetScreenRectInAppUnits();
-  nsPoint deltaPoint(point.x - frameRect.x, point.y - frameRect.y);
+  nsPoint deltaPoint = point - frameRect.TopLeft();
 
   nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
   scrollPoint -= deltaPoint;
 
   scrollableFrame->ScrollTo(scrollPoint, nsIScrollableFrame::INSTANT);
 }
 
 void
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -509,18 +509,17 @@ Accessible::FocusedChild()
 Accessible*
 Accessible::ChildAtPoint(int32_t aX, int32_t aY,
                          EWhichChildAtPoint aWhichChild)
 {
   // If we can't find the point in a child, we will return the fallback answer:
   // we return |this| if the point is within it, otherwise nullptr.
   Accessible* fallbackAnswer = nullptr;
   nsIntRect rect = Bounds();
-  if (aX >= rect.x && aX < rect.x + rect.width &&
-      aY >= rect.y && aY < rect.y + rect.height)
+  if (rect.Contains(aX, aY))
     fallbackAnswer = this;
 
   if (nsAccUtils::MustPrune(this))  // Do not dig any further
     return fallbackAnswer;
 
   // Search an accessible at the given point starting from accessible document
   // because containing block (see CSS2) for out of flow element (for example,
   // absolutely positioned element) may be different from its DOM parent and
@@ -538,17 +537,17 @@ Accessible::ChildAtPoint(int32_t aX, int
   // Check whether the point is at popup content.
   nsIWidget* rootWidget = rootFrame->GetView()->GetNearestWidget(nullptr);
   NS_ENSURE_TRUE(rootWidget, nullptr);
 
   LayoutDeviceIntRect rootRect = rootWidget->GetScreenBounds();
 
   WidgetMouseEvent dummyEvent(true, eMouseMove, rootWidget,
                               WidgetMouseEvent::eSynthesized);
-  dummyEvent.mRefPoint = LayoutDeviceIntPoint(aX - rootRect.x, aY - rootRect.y);
+  dummyEvent.mRefPoint = LayoutDeviceIntPoint(aX - rootRect.X(), aY - rootRect.Y());
 
   nsIFrame* popupFrame = nsLayoutUtils::
     GetPopupFrameForEventCoordinates(accDocument->PresContext()->GetRootPresContext(),
                                      &dummyEvent);
   if (popupFrame) {
     // If 'this' accessible is not inside the popup then ignore the popup when
     // searching an accessible at point.
     DocAccessible* popupDoc =
@@ -560,18 +559,18 @@ Accessible::ChildAtPoint(int32_t aX, int
       popupChild = popupChild->Parent();
 
     if (popupChild == popupAcc)
       startFrame = popupFrame;
   }
 
   nsPresContext* presContext = startFrame->PresContext();
   nsRect screenRect = startFrame->GetScreenRectInAppUnits();
-    nsPoint offset(presContext->DevPixelsToAppUnits(aX) - screenRect.x,
-                   presContext->DevPixelsToAppUnits(aY) - screenRect.y);
+  nsPoint offset(presContext->DevPixelsToAppUnits(aX) - screenRect.X(),
+                 presContext->DevPixelsToAppUnits(aY) - screenRect.Y());
   nsIFrame* foundFrame = nsLayoutUtils::GetFrameForPoint(startFrame, offset);
 
   nsIContent* content = nullptr;
   if (!foundFrame || !(content = foundFrame->GetContent()))
     return fallbackAnswer;
 
   // Get accessible for the node with the point or the first accessible in
   // the DOM parent chain.
@@ -612,18 +611,17 @@ Accessible::ChildAtPoint(int32_t aX, int
   // where layout won't walk into things for us, such as image map areas and
   // sub documents (XXX: subdocuments should be handled by methods of
   // OuterDocAccessibles).
   uint32_t childCount = accessible->ChildCount();
   for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
     Accessible* child = accessible->GetChildAt(childIdx);
 
     nsIntRect childRect = child->Bounds();
-    if (aX >= childRect.x && aX < childRect.x + childRect.width &&
-        aY >= childRect.y && aY < childRect.y + childRect.height &&
+    if (childRect.Contains(aX, aY) &&
         (child->State() & states::INVISIBLE) == 0) {
 
       if (aWhichChild == eDeepestChild)
         return child->ChildAtPoint(aX, aY, eDeepestChild);
 
       return child;
     }
   }
@@ -676,27 +674,26 @@ Accessible::Bounds() const
 {
   nsIFrame* boundingFrame = nullptr;
   nsRect unionRectTwips = RelativeBounds(&boundingFrame);
   if (!boundingFrame)
     return nsIntRect();
 
   nsIntRect screenRect;
   nsPresContext* presContext = mDoc->PresContext();
-  screenRect.x = presContext->AppUnitsToDevPixels(unionRectTwips.x);
-  screenRect.y = presContext->AppUnitsToDevPixels(unionRectTwips.y);
-  screenRect.width = presContext->AppUnitsToDevPixels(unionRectTwips.width);
-  screenRect.height = presContext->AppUnitsToDevPixels(unionRectTwips.height);
+  screenRect.SetRect(presContext->AppUnitsToDevPixels(unionRectTwips.X()),
+                     presContext->AppUnitsToDevPixels(unionRectTwips.Y()),
+                     presContext->AppUnitsToDevPixels(unionRectTwips.Width()),
+                     presContext->AppUnitsToDevPixels(unionRectTwips.Height()));
 
   // We have the union of the rectangle, now we need to put it in absolute
   // screen coords.
   nsIntRect orgRectPixels = boundingFrame->GetScreenRectInAppUnits().
     ToNearestPixels(presContext->AppUnitsPerDevPixel());
-  screenRect.x += orgRectPixels.x;
-  screenRect.y += orgRectPixels.y;
+  screenRect.MoveBy(orgRectPixels.X(), orgRectPixels.Y());
 
   return screenRect;
 }
 
 void
 Accessible::SetSelected(bool aSelect)
 {
   if (!HasOwnContent())
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -136,18 +136,18 @@ HyperTextAccessible::GetBoundsInFrame(ns
     rv = frame->GetPointFromOffset(startContentOffset, &frameTextStartPoint);
     NS_ENSURE_SUCCESS(rv, nsIntRect());
 
     // Use the point for the end offset to calculate the width
     nsPoint frameTextEndPoint;
     rv = frame->GetPointFromOffset(startContentOffset + frameSubStringLength, &frameTextEndPoint);
     NS_ENSURE_SUCCESS(rv, nsIntRect());
 
-    frameScreenRect.x += std::min(frameTextStartPoint.x, frameTextEndPoint.x);
-    frameScreenRect.width = mozilla::Abs(frameTextStartPoint.x - frameTextEndPoint.x);
+    frameScreenRect.SetRectX(frameScreenRect.X() + std::min(frameTextStartPoint.x, frameTextEndPoint.x),
+                             mozilla::Abs(frameTextStartPoint.x - frameTextEndPoint.x));
 
     screenRect.UnionRect(frameScreenRect, screenRect);
 
     // Get ready to loop back for next frame continuation
     startContentOffset += frameSubStringLength;
     startContentOffsetInFrame = 0;
     frame = frame->GetNextContinuation();
   }
@@ -1172,18 +1172,18 @@ HyperTextAccessible::OffsetAtPoint(int32
   nsPresContext* presContext = mDoc->PresContext();
   nsPoint coordsInAppUnits =
     ToAppUnits(coords, presContext->AppUnitsPerDevPixel());
 
   nsRect frameScreenRect = hyperFrame->GetScreenRectInAppUnits();
   if (!frameScreenRect.Contains(coordsInAppUnits.x, coordsInAppUnits.y))
     return -1; // Not found
 
-  nsPoint pointInHyperText(coordsInAppUnits.x - frameScreenRect.x,
-                           coordsInAppUnits.y - frameScreenRect.y);
+  nsPoint pointInHyperText(coordsInAppUnits.x - frameScreenRect.X(),
+                           coordsInAppUnits.y - frameScreenRect.Y());
 
   // Go through the frames to check if each one has the point.
   // When one does, add up the character offsets until we have a match
 
   // We have an point in an accessible child of this, now we need to add up the
   // offsets before it to what we already have
   int32_t offset = 0;
   uint32_t childCount = ChildCount();
@@ -1262,17 +1262,20 @@ HyperTextAccessible::TextBounds(int32_t 
 
     bounds.UnionRect(bounds, GetBoundsInFrame(frame, offset1,
                                               nextOffset - prevOffset));
 
     prevOffset = nextOffset;
     offset1 = 0;
   }
 
-  nsAccUtils::ConvertScreenCoordsTo(&bounds.x, &bounds.y, aCoordType, this);
+  auto boundsX = bounds.X();
+  auto boundsY = bounds.Y();
+  nsAccUtils::ConvertScreenCoordsTo(&boundsX, &boundsY, aCoordType, this);
+  bounds.MoveTo(boundsX, boundsY);
   return bounds;
 }
 
 already_AddRefed<TextEditor>
 HyperTextAccessible::GetEditor() const
 {
   if (!mContent->HasFlag(NODE_IS_EDITABLE)) {
     // If we're inside an editable container, then return that container's editor
@@ -1517,18 +1520,17 @@ HyperTextAccessible::GetCaretRect(nsIWid
 
   // Correct for character size, so that caret always matches the size of
   // the character. This is important for font size transitions, and is
   // necessary because the Gecko caret uses the previous character's size as
   // the user moves forward in the text by character.
   nsIntRect charRect = CharBounds(CaretOffset(),
                                   nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
   if (!charRect.IsEmpty()) {
-    caretRect.height -= charRect.y - caretRect.y;
-    caretRect.y = charRect.y;
+    caretRect.SetTopEdge(charRect.Y());
   }
   return caretRect;
 }
 
 void
 HyperTextAccessible::GetSelectionDOMRanges(SelectionType aSelectionType,
                                            nsTArray<nsRange*>* aRanges)
 {
@@ -1709,18 +1711,18 @@ HyperTextAccessible::ScrollSubstringToPo
   nsIFrame *parentFrame = frame;
   while ((parentFrame = parentFrame->GetParent())) {
     nsIScrollableFrame *scrollableFrame = do_QueryFrame(parentFrame);
     if (scrollableFrame) {
       if (!initialScrolled) {
         // Scroll substring to the given point. Turn the point into percents
         // relative scrollable area to use nsCoreUtils::ScrollSubstringTo.
         nsRect frameRect = parentFrame->GetScreenRectInAppUnits();
-        nscoord offsetPointX = coordsInAppUnits.x - frameRect.x;
-        nscoord offsetPointY = coordsInAppUnits.y - frameRect.y;
+        nscoord offsetPointX = coordsInAppUnits.x - frameRect.X();
+        nscoord offsetPointY = coordsInAppUnits.y - frameRect.Y();
 
         nsSize size(parentFrame->GetSize());
 
         // 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;
--- a/accessible/generic/ImageAccessible.cpp
+++ b/accessible/generic/ImageAccessible.cpp
@@ -143,19 +143,19 @@ ImageAccessible::DoAction(uint8_t aIndex
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // ImageAccessible
 
 nsIntPoint
 ImageAccessible::Position(uint32_t aCoordType)
 {
-  nsIntRect rect = Bounds();
-  nsAccUtils::ConvertScreenCoordsTo(&rect.x, &rect.y, aCoordType, this);
-  return rect.TopLeft();
+  nsIntPoint point = Bounds().TopLeft();
+  nsAccUtils::ConvertScreenCoordsTo(&point.x, &point.y, aCoordType, this);
+  return point;
 }
 
 nsIntSize
 ImageAccessible::Size()
 {
   return Bounds().Size();
 }
 
--- a/accessible/generic/OuterDocAccessible.cpp
+++ b/accessible/generic/OuterDocAccessible.cpp
@@ -65,18 +65,17 @@ OuterDocAccessible::NativeRole()
   return roles::INTERNAL_FRAME;
 }
 
 Accessible*
 OuterDocAccessible::ChildAtPoint(int32_t aX, int32_t aY,
                                  EWhichChildAtPoint aWhichChild)
 {
   nsIntRect docRect = Bounds();
-  if (aX < docRect.x || aX >= docRect.x + docRect.width ||
-      aY < docRect.y || aY >= docRect.y + docRect.height)
+  if (!docRect.Contains(aX, aY))
     return nullptr;
 
   // Always return the inner doc as direct child accessible unless bounds
   // outside of it.
   Accessible* child = GetChildAt(0);
   NS_ENSURE_TRUE(child, nullptr);
 
   if (aWhichChild == eDeepestChild)
--- a/accessible/html/HTMLImageMapAccessible.cpp
+++ b/accessible/html/HTMLImageMapAccessible.cpp
@@ -217,12 +217,11 @@ HTMLAreaAccessible::RelativeBounds(nsIFr
   nsRect bounds;
   nsresult rv = map->GetBoundsForAreaContent(mContent, bounds);
   if (NS_FAILED(rv))
     return nsRect();
 
   // XXX Areas are screwy; they return their rects as a pair of points, one pair
   // stored into the width and height.
   *aBoundingFrame = frame;
-  bounds.width -= bounds.x;
-  bounds.height -= bounds.y;
+  bounds.SizeTo(bounds.Width() - bounds.X(), bounds.Height() - bounds.Y());
   return bounds;
 }
--- a/accessible/html/HTMLListAccessible.cpp
+++ b/accessible/html/HTMLListAccessible.cpp
@@ -82,18 +82,18 @@ nsIntRect
 HTMLLIAccessible::Bounds() const
 {
   nsIntRect rect = AccessibleWrap::Bounds();
   if (rect.IsEmpty() || !mBullet || mBullet->IsInside())
     return rect;
 
   nsIntRect bulletRect = mBullet->Bounds();
 
-  rect.width += rect.x - bulletRect.x;
-  rect.x = bulletRect.x; // Move x coordinate of list item over to cover bullet as well
+  // Move x coordinate of list item over to cover bullet as well
+  rect.SetLeftEdge(bulletRect.X());
   return rect;
 }
 
 bool
 HTMLLIAccessible::InsertChildAt(uint32_t aIndex, Accessible* aChild)
 {
   // Adjust index if there's a bullet.
   if (mBullet && aIndex == 0 && aChild != mBullet) {
--- a/accessible/html/HTMLSelectAccessible.cpp
+++ b/accessible/html/HTMLSelectAccessible.cpp
@@ -208,18 +208,18 @@ HTMLSelectOptionAccessible::NativeState(
     // XXX list frames are weird, don't rely on Accessible's general
     // visibility implementation unless they get reimplemented in layout
     state &= ~states::OFFSCREEN;
     // <select> is not collapsed: compare bounds to calculate OFFSCREEN
     Accessible* listAcc = Parent();
     if (listAcc) {
       nsIntRect optionRect = Bounds();
       nsIntRect listRect = listAcc->Bounds();
-      if (optionRect.y < listRect.y ||
-          optionRect.y + optionRect.height > listRect.y + listRect.height) {
+      if (optionRect.Y() < listRect.Y() ||
+          optionRect.YMost() > listRect.YMost()) {
         state |= states::OFFSCREEN;
       }
     }
   }
 
   return state;
 }
 
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -618,18 +618,18 @@ DocAccessibleParent::MaybeInitWindowEmul
   RootAccessible* rootDocument = outerDoc->RootAccessible();
   MOZ_ASSERT(rootDocument);
 
   bool isActive = true;
   nsIntRect rect(CW_USEDEFAULT, CW_USEDEFAULT, 0, 0);
   if (Compatibility::IsDolphin()) {
     rect = Bounds();
     nsIntRect rootRect = rootDocument->Bounds();
-    rect.x = rootRect.x - rect.x;
-    rect.y -= rootRect.y;
+    rect.MoveToX(rootRect.X() - rect.X());
+    rect.MoveToY(rect.Y() - rootRect.Y());
 
     auto tab = static_cast<dom::TabParent*>(Manager());
     tab->GetDocShellIsActive(&isActive);
   }
 
   nsWinUtils::NativeWindowCreateProc onCreate([this](HWND aHwnd) -> void {
     IDispatchHolder hWndAccHolder;
 
@@ -647,18 +647,18 @@ DocAccessibleParent::MaybeInitWindowEmul
 
     Unused << SendEmulatedWindow(reinterpret_cast<uintptr_t>(mEmulatedWindowHandle),
                                  hWndAccHolder);
   });
 
   HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
   DebugOnly<HWND> hWnd = nsWinUtils::CreateNativeWindow(kClassNameTabContent,
                                                         parentWnd,
-                                                        rect.x, rect.y,
-                                                        rect.width, rect.height,
+                                                        rect.X(), rect.Y(),
+                                                        rect.Width(), rect.Height(),
                                                         isActive, &onCreate);
   MOZ_ASSERT(hWnd);
 }
 
 /**
  * @param aCOMProxy COM Proxy to the document in the content process.
  */
 void
--- a/accessible/ipc/win/ProxyAccessible.cpp
+++ b/accessible/ipc/win/ProxyAccessible.cpp
@@ -226,20 +226,17 @@ ProxyAccessible::Bounds()
   long left;
   long top;
   long width;
   long height;
   HRESULT hr = acc->accLocation(&left, &top, &width, &height, kChildIdSelf);
   if (FAILED(hr)) {
     return rect;
   }
-  rect.x = left;
-  rect.y = top;
-  rect.width = width;
-  rect.height = height;
+  rect.SetRect(left, top, width, height);
   return rect;
 }
 
 void
 ProxyAccessible::Language(nsString& aLocale)
 {
   aLocale.Truncate();
 
--- a/accessible/windows/ia2/ia2AccessibleComponent.cpp
+++ b/accessible/windows/ia2/ia2AccessibleComponent.cpp
@@ -57,26 +57,26 @@ ia2AccessibleComponent::get_locationInPa
     return S_OK;
 
   nsIntRect rect = acc->Bounds();
 
   // The coordinates of the returned position are relative to this object's
   // parent or relative to the screen on which this object is rendered if it
   // has no parent.
   if (!acc->Parent()) {
-    *aX = rect.x;
-    *aY = rect.y;
+    *aX = rect.X();
+    *aY = rect.Y();
     return S_OK;
   }
 
   // The coordinates of the bounding box are given relative to the parent's
   // coordinate system.
   nsIntRect parentRect = acc->Parent()->Bounds();
-  *aX = rect.x - parentRect.x;
-  *aY = rect.y - parentRect.y;
+  *aX = rect.X() - parentRect.X();
+  *aY = rect.Y() - parentRect.Y();
   return S_OK;
 }
 
 STDMETHODIMP
 ia2AccessibleComponent::get_foreground(IA2Color* aForeground)
 {
   if (!aForeground)
     return E_INVALIDARG;
--- a/accessible/windows/ia2/ia2AccessibleText.cpp
+++ b/accessible/windows/ia2/ia2AccessibleText.cpp
@@ -105,20 +105,21 @@ ia2AccessibleText::get_characterExtents(
   nsIntRect rect;
   MOZ_ASSERT(!HyperTextProxyFor(this));
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   rect = textAcc->CharBounds(aOffset, geckoCoordType);
 
-  *aX = rect.x;
-  *aY = rect.y;
-  *aWidth = rect.width;
-  *aHeight = rect.height;
+  // Can't use GetRect() because of long vs. int32_t mismatch
+  *aX = rect.X();
+  *aY = rect.Y();
+  *aWidth = rect.Width();
+  *aHeight = rect.Height();
   return S_OK;
 }
 
 STDMETHODIMP
 ia2AccessibleText::get_nSelections(long* aNSelections)
 {
   if (!aNSelections)
     return E_INVALIDARG;
--- a/accessible/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/windows/msaa/AccessibleWrap.cpp
@@ -897,20 +897,20 @@ AccessibleWrap::accLocation(
 
   if (accessible) {
     return accessible->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight,
                                    kVarChildIdSelf);
   }
 
   nsIntRect rect = Bounds();
 
-  *pxLeft = rect.x;
-  *pyTop = rect.y;
-  *pcxWidth = rect.width;
-  *pcyHeight = rect.height;
+  *pxLeft = rect.X();
+  *pyTop = rect.Y();
+  *pcxWidth = rect.Width();
+  *pcyHeight = rect.Height();
   return S_OK;
 }
 
 STDMETHODIMP
 AccessibleWrap::accNavigate(
       /* [in] */ long navDir,
       /* [optional][in] */ VARIANT varStart,
       /* [retval][out] */ VARIANT __RPC_FAR *pvarEndUpAt)
@@ -1656,22 +1656,22 @@ AccessibleWrap::UpdateSystemCaretFor(HWN
                                      const LayoutDeviceIntRect& aCaretRect)
 {
   if (!aCaretWnd || aCaretRect.IsEmpty()) {
     return;
   }
 
   // Create invisible bitmap for caret, otherwise its appearance interferes
   // with Gecko caret
-  nsAutoBitmap caretBitMap(CreateBitmap(1, aCaretRect.height, 1, 1, nullptr));
-  if (::CreateCaret(aCaretWnd, caretBitMap, 1, aCaretRect.height)) {  // Also destroys the last caret
+  nsAutoBitmap caretBitMap(CreateBitmap(1, aCaretRect.Height(), 1, 1, nullptr));
+  if (::CreateCaret(aCaretWnd, caretBitMap, 1, aCaretRect.Height())) {  // Also destroys the last caret
     ::ShowCaret(aCaretWnd);
     RECT windowRect;
     ::GetWindowRect(aCaretWnd, &windowRect);
-    ::SetCaretPos(aCaretRect.x - windowRect.left, aCaretRect.y - windowRect.top);
+    ::SetCaretPos(aCaretRect.X() - windowRect.left, aCaretRect.Y() - windowRect.top);
   }
 }
 
 ITypeInfo*
 AccessibleWrap::GetTI(LCID lcid)
 {
   if (gTypeInfo)
     return gTypeInfo;
--- a/accessible/windows/msaa/DocAccessibleWrap.cpp
+++ b/accessible/windows/msaa/DocAccessibleWrap.cpp
@@ -149,33 +149,33 @@ DocAccessibleWrap::DoInitialUpdate()
     // Create window for tab document.
     if (mDocFlags & eTabDocument) {
       a11y::RootAccessible* rootDocument = RootAccessible();
       bool isActive = true;
       nsIntRect rect(CW_USEDEFAULT, CW_USEDEFAULT, 0, 0);
       if (Compatibility::IsDolphin()) {
         rect = Bounds();
         nsIntRect rootRect = rootDocument->Bounds();
-        rect.x = rootRect.x - rect.x;
-        rect.y -= rootRect.y;
+        rect.MoveToX(rootRect.X() - rect.X());
+        rect.MoveByY(-rootRect.Y());
 
         nsCOMPtr<nsISupports> container = mDocumentNode->GetContainer();
         nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
         docShell->GetIsActive(&isActive);
       }
 
       RefPtr<DocAccessibleWrap> self(this);
       nsWinUtils::NativeWindowCreateProc onCreate([self](HWND aHwnd) -> void {
         ::SetPropW(aHwnd, kPropNameDocAcc, reinterpret_cast<HANDLE>(self.get()));
       });
 
       HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());
       mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent, parentWnd,
-                                             rect.x, rect.y,
-                                             rect.width, rect.height, isActive,
+                                             rect.X(), rect.Y(),
+                                             rect.Width(), rect.Height(), isActive,
                                              &onCreate);
     } else {
       DocAccessible* parentDocument = ParentDocument();
       if (parentDocument)
         mHWND = parentDocument->GetNativeWindow();
     }
   }
 }
--- a/accessible/windows/sdn/sdnTextAccessible.cpp
+++ b/accessible/windows/sdn/sdnTextAccessible.cpp
@@ -70,20 +70,20 @@ sdnTextAccessible::get_clippedSubstringB
                "There must always be a doc accessible, but there isn't. Crash!");
 
   nsIntRect docRect = document->Bounds();
   nsIntRect unclippedRect(x, y, width, height);
 
   nsIntRect clippedRect;
   clippedRect.IntersectRect(unclippedRect, docRect);
 
-  *aX = clippedRect.x;
-  *aY = clippedRect.y;
-  *aWidth = clippedRect.width;
-  *aHeight = clippedRect.height;
+  *aX = clippedRect.X();
+  *aY = clippedRect.Y();
+  *aWidth = clippedRect.Width();
+  *aHeight = clippedRect.Height();
   return S_OK;
 }
 
 STDMETHODIMP
 sdnTextAccessible::get_unclippedSubstringBounds(unsigned int aStartIndex,
                                                 unsigned int aEndIndex,
                                                 int __RPC_FAR* aX,
                                                 int __RPC_FAR* aY,
@@ -107,27 +107,27 @@ sdnTextAccessible::get_unclippedSubstrin
     return E_FAIL;
 
   nsRect sum;
   nsIFrame* iter = startFrame;
   nsIFrame* stopLoopFrame = endFrame->GetNextContinuation();
   for (; iter != stopLoopFrame; iter = iter->GetNextContinuation()) {
     nsRect rect = iter->GetScreenRectInAppUnits();
     nscoord start = (iter == startFrame) ? startPoint.x : 0;
-    nscoord end = (iter == endFrame) ? endPoint.x : rect.width;
-    rect.x += start;
-    rect.width = end - start;
+    nscoord end = (iter == endFrame) ? endPoint.x : rect.Width();
+    rect.MoveByX(start);
+    rect.SetWidth(end - start);
     sum.UnionRect(sum, rect);
   }
 
   nsPresContext* presContext = mAccessible->Document()->PresContext();
-  *aX = presContext->AppUnitsToDevPixels(sum.x);
-  *aY = presContext->AppUnitsToDevPixels(sum.y);
-  *aWidth = presContext->AppUnitsToDevPixels(sum.width);
-  *aHeight = presContext->AppUnitsToDevPixels(sum.height);
+  *aX = presContext->AppUnitsToDevPixels(sum.X());
+  *aY = presContext->AppUnitsToDevPixels(sum.Y());
+  *aWidth = presContext->AppUnitsToDevPixels(sum.Width());
+  *aHeight = presContext->AppUnitsToDevPixels(sum.Height());
 
   return S_OK;
 }
 
 STDMETHODIMP
 sdnTextAccessible::scrollToSubstring(unsigned int aStartIndex,
                                      unsigned int aEndIndex)
 {
--- a/accessible/xpcom/xpcAccessible.cpp
+++ b/accessible/xpcom/xpcAccessible.cpp
@@ -447,21 +447,17 @@ xpcAccessible::GetBounds(int32_t* aX, in
 
   nsIntRect rect;
   if (Accessible* acc = IntlGeneric().AsAccessible()) {
     rect = acc->Bounds();
   } else {
     rect = IntlGeneric().AsProxy()->Bounds();
   }
 
-  *aX = rect.x;
-  *aY = rect.y;
-  *aWidth = rect.width;
-  *aHeight = rect.height;
-
+  rect.GetRect(aX, aY, aWidth, aHeight);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessible::GroupPosition(int32_t* aGroupLevel,
                              int32_t* aSimilarItemsInGroup,
                              int32_t* aPositionInGroup)
 {
--- a/accessible/xpcom/xpcAccessibleHyperText.cpp
+++ b/accessible/xpcom/xpcAccessibleHyperText.cpp
@@ -265,18 +265,17 @@ xpcAccessibleHyperText::GetCharacterExte
     rect = Intl()->CharBounds(aOffset, aCoordType);
   } else {
 #if defined(XP_WIN)
     return NS_ERROR_NOT_IMPLEMENTED;
 #else
     rect = mIntl.AsProxy()->CharBounds(aOffset, aCoordType);
 #endif
   }
-  *aX = rect.x; *aY = rect.y;
-  *aWidth = rect.width; *aHeight = rect.height;
+  rect.GetRect(aX, aY, aWidth, aHeight);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetRangeExtents(int32_t aStartOffset, int32_t aEndOffset,
                                         int32_t* aX, int32_t* aY,
                                         int32_t* aWidth, int32_t* aHeight,
                                         uint32_t aCoordType)
@@ -295,18 +294,17 @@ xpcAccessibleHyperText::GetRangeExtents(
     rect = Intl()->TextBounds(aStartOffset, aEndOffset, aCoordType);
   } else {
 #if defined(XP_WIN)
     return NS_ERROR_NOT_IMPLEMENTED;
 #else
     rect = mIntl.AsProxy()->TextBounds(aStartOffset, aEndOffset, aCoordType);
 #endif
   }
-  *aX = rect.x; *aY = rect.y;
-  *aWidth = rect.width; *aHeight = rect.height;
+  rect.GetRect(aX, aY, aWidth, aHeight);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleHyperText::GetOffsetAtPoint(int32_t aX, int32_t aY,
                                          uint32_t aCoordType, int32_t* aOffset)
 {
   NS_ENSURE_ARG_POINTER(aOffset);
--- a/accessible/xul/XULTreeAccessible.cpp
+++ b/accessible/xul/XULTreeAccessible.cpp
@@ -188,18 +188,18 @@ XULTreeAccessible::ChildAtPoint(int32_t 
   nsPresContext *presContext = frame->PresContext();
   nsIPresShell* presShell = presContext->PresShell();
 
   nsIFrame *rootFrame = presShell->GetRootFrame();
   NS_ENSURE_TRUE(rootFrame, nullptr);
 
   CSSIntRect rootRect = rootFrame->GetScreenRect();
 
-  int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.x;
-  int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.y;
+  int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.X();
+  int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.Y();
 
   int32_t row = -1;
   nsCOMPtr<nsITreeColumn> column;
   nsAutoString childEltUnused;
   mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
                    childEltUnused);
 
   // If we failed to find tree cell for the given point then it might be
--- a/accessible/xul/XULTreeGridAccessible.cpp
+++ b/accessible/xul/XULTreeGridAccessible.cpp
@@ -322,18 +322,18 @@ XULTreeGridRowAccessible::ChildAtPoint(i
   nsPresContext *presContext = frame->PresContext();
   nsIPresShell* presShell = presContext->PresShell();
 
   nsIFrame *rootFrame = presShell->GetRootFrame();
   NS_ENSURE_TRUE(rootFrame, nullptr);
 
   CSSIntRect rootRect = rootFrame->GetScreenRect();
 
-  int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.x;
-  int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.y;
+  int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.X();
+  int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.Y();
 
   int32_t row = -1;
   nsCOMPtr<nsITreeColumn> column;
   nsAutoString childEltUnused;
   mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
                    childEltUnused);
 
   // Return if we failed to find tree cell in the row for the given point.
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<blocklist lastupdate="1511530749075" xmlns="http://www.mozilla.org/2006/addons-blocklist">
+<blocklist lastupdate="1500496563565" xmlns="http://www.mozilla.org/2006/addons-blocklist">
   <emItems>
     <emItem blockID="i988" id="{b12785f5-d8d0-4530-a3ea-5c4263b85bef}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i398" id="{377e5d4d-77e5-476a-8716-7e70a9272da0}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
@@ -3429,46 +3429,37 @@
       <serialNumber>F5Bg6C237Q==</serialNumber>
     </certItem>
     <certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
       <serialNumber>Ai7cBJYqBE0I9NdyoZfRrw==</serialNumber>
     </certItem>
     <certItem issuerName="MIGLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMRUwEwYDVQQLEwxNaWNyb3NvZnQgSVQxHjAcBgNVBAMTFU1pY3Jvc29mdCBJVCBTU0wgU0hBMg==">
       <serialNumber>WgAFElcDxFjoswSzjAABAAUSVw==</serialNumber>
     </certItem>
-    <certItem issuerName="MHExCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNEZXV0c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLExZULVRlbGVTZWMgVHJ1c3QgQ2VudGVyMSMwIQYDVQQDExpEZXV0c2NoZSBUZWxla29tIFJvb3QgQ0EgMg==">
-      <serialNumber>AImQERVYPoeb</serialNumber>
-    </certItem>
-    <certItem issuerName="MGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAy">
-      <serialNumber>GpO48aJ8GngtwECqZhm/xA==</serialNumber>
-    </certItem>
-    <certItem issuerName="MDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUw=">
-      <serialNumber>CdYL9vSQCEKzBwjO10ud2w==</serialNumber>
-    </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
       <serialNumber>UKM/CNF2OvC4giYnAUG/Ag==</serialNumber>
     </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
       <serialNumber>LzVYePklc3vH3jkk0BZr9g==</serialNumber>
     </certItem>
     <certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
       <serialNumber>BYOGvG32ukb1Yxj2oKoFyw==</serialNumber>
     </certItem>
-    <certItem issuerName="MDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMCREU=">
-      <serialNumber>a12RvBNhznU=</serialNumber>
-    </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
       <serialNumber>P4sUnc++hlU/bXj0zSTlcQ==</serialNumber>
     </certItem>
     <certItem issuerName="MIGFMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDErMCkGA1UEAxMiQ09NT0RPIFJTQSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==">
       <serialNumber>AKrMYlJmUUin8FOM/0TJrmk=</serialNumber>
     </certItem>
     <certItem issuerName="MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMw==">
       <serialNumber>A7uy+rmTav6tDH4dRrsnvXGH</serialNumber>
     </certItem>
+    <certItem issuerName="MFQxCzAJBgNVBAYTAkJNMRkwFwYDVQQKDBBRdW9WYWRpcyBMaW1pdGVkMSowKAYDVQQDDCFRdW9WYWRpcyBFbnRlcnByaXNlIFRydXN0IENBIDIgRzM=">
+      <serialNumber>bqapwACCtKhVagTl7cEP7KFbM0E=</serialNumber>
+    </certItem>
     <certItem issuerName="MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMw==">
       <serialNumber>RUT1Gehd1KKYPfqOlgspoQ==</serialNumber>
     </certItem>
     <certItem issuerName="MHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWU=">
       <serialNumber>KuzHPJLdK5hNgJRo3R47Ag==</serialNumber>
     </certItem>
     <certItem issuerName="MGsxCzAJBgNVBAYTAklUMQ4wDAYDVQQHDAVNaWxhbjEjMCEGA1UECgwaQWN0YWxpcyBTLnAuQS4vMDMzNTg1MjA5NjcxJzAlBgNVBAMMHkFjdGFsaXMgQXV0aGVudGljYXRpb24gUm9vdCBDQQ==">
       <serialNumber>WJ2qHzWUqTk=</serialNumber>
@@ -3486,16 +3477,19 @@
       <serialNumber>OOkLFZaa4CXGyJlLTIEjUQ==</serialNumber>
     </certItem>
     <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
       <serialNumber>Byc85g==</serialNumber>
     </certItem>
     <certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
       <serialNumber>BAAAAAABRE7wRk4=</serialNumber>
     </certItem>
+    <certItem issuerName="MFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQKDBBWZXJpem9uIEJ1c2luZXNzMREwDwYDVQQLDAhPbW5pUm9vdDEfMB0GA1UEAwwWVmVyaXpvbiBHbG9iYWwgUm9vdCBDQQ==">
+      <serialNumber>BFA=</serialNumber>
+    </certItem>
     <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
       <serialNumber>ByeQ9g==</serialNumber>
     </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>OYBKgxEHpW/8XGAGAlvJyMA=</serialNumber>
     </certItem>
     <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>bzTw0uq05TUYEGS98bh0Ww==</serialNumber>
@@ -3825,16 +3819,19 @@
       <serialNumber>GN2Hrh9LtnE=</serialNumber>
     </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
       <serialNumber>UT6GtTGbEC6SXJteWAKy2g==</serialNumber>
     </certItem>
     <certItem issuerName="MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>P6G7IYSL2RZxtzTh8I6qPA==</serialNumber>
     </certItem>
+    <certItem issuerName="MIGSMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE4MDYGA1UEAxMvQ09NT0RPIFJTQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFNlY3VyZSBTZXJ2ZXIgQ0E=">
+      <serialNumber>TasC8Zd8BT8kXEE67cFQmA==</serialNumber>
+    </certItem>
     <certItem issuerName="MGcxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpGcmF1bmhvZmVyMSEwHwYDVQQLExhGcmF1bmhvZmVyIENvcnBvcmF0ZSBQS0kxIDAeBgNVBAMTF0ZyYXVuaG9mZXIgUm9vdCBDQSAyMDA3">
       <serialNumber>YR3YYQAAAAAABA==</serialNumber>
     </certItem>
     <certItem issuerName="MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=">
       <serialNumber>GN2Hrh9LtnQ=</serialNumber>
     </certItem>
     <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
       <serialNumber>ByfNeA==</serialNumber>
@@ -3900,16 +3897,19 @@
       <serialNumber>CuUEKEJM4xhxlFXraPcSpQ==</serialNumber>
     </certItem>
     <certItem issuerName="MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UEAxMORFNUIFJvb3QgQ0EgWDM=">
       <serialNumber>CgFBQQAAATjkOB1sAAAAAg==</serialNumber>
     </certItem>
     <certItem issuerName="MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5">
       <serialNumber>QOu0a5Z9rCkw6Nk7Rg1/AQ==</serialNumber>
     </certItem>
+    <certItem issuerName="MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=">
+      <serialNumber>ByfNbw==</serialNumber>
+    </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBSU0EgUm9vdCAtIEcx">
       <serialNumber>ElBUYv/f+6+gnbAJ23qnAA==</serialNumber>
     </certItem>
     <certItem issuerName="MIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEdMBsGA1UEAxMUVVROLVVTRVJGaXJzdC1PYmplY3Q=">
       <serialNumber>a9rf7/BmG9JkKvRuy7J5QA==</serialNumber>
     </certItem>
     <certItem issuerName="MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==">
       <serialNumber>QM1zZ4GZ4gfwpQtUYye3Ne0=</serialNumber>
@@ -4752,16 +4752,19 @@
       <serialNumber>ESDu2nhlLPzfx+LYgjlYFP/k</serialNumber>
     </certItem>
     <certItem issuerName="MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA2IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHNQ==">
       <serialNumber>buROL/l2GuXISv+/JVLkdA==</serialNumber>
     </certItem>
     <certItem issuerName="MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=">
       <serialNumber>CqZgEvHAsnzkT//QV9KjXw==</serialNumber>
     </certItem>
+    <certItem issuerName="MHMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExGjAYBgNVBAoTEUludGVsIENvcnBvcmF0aW9uMSUwIwYDVQQDExxJbnRlbCBFeHRlcm5hbCBJc3N1aW5nIENBIDZC">
+      <serialNumber>HwAABsvzDP+DIzUG6QAAAAAGyw==</serialNumber>
+    </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>HZyLf+K70FKc+jomm8DiDw==</serialNumber>
     </certItem>
     <certItem issuerName="MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h">
       <serialNumber>Ew==</serialNumber>
     </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
       <serialNumber>IARKrBjlKQLyVGA4X52L7w==</serialNumber>
@@ -4849,16 +4852,19 @@
     </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
       <serialNumber>CGo/+42e75JBJ2JcOEaMFw==</serialNumber>
     </certItem>
     <certItem issuerName="MGMxCzAJBgNVBAYTAkZSMRMwEQYDVQQKEwpDZXJ0aW5vbWlzMRcwFQYDVQQLEw4wMDAyIDQzMzk5ODkwMzEmMCQGA1UEAwwdQ2VydGlub21pcyAtIEF1dG9yaXTDqSBSYWNpbmU=">
       <serialNumber>Eg==</serialNumber>
     </certItem>
     <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
+      <serialNumber>UDE/uwr4z5V8eZI4+1gkAw==</serialNumber>
+    </certItem>
+    <certItem issuerName="MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=">
       <serialNumber>ezdAeCxKH7BFs7vn3byYaw==</serialNumber>
     </certItem>
     <certItem issuerName="MIGFMQswCQYDVQQGEwJVUzEgMB4GA1UECgwXV2VsbHMgRmFyZ28gV2VsbHNTZWN1cmUxHDAaBgNVBAsME1dlbGxzIEZhcmdvIEJhbmsgTkExNjA0BgNVBAMMLVdlbGxzU2VjdXJlIFB1YmxpYyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eQ==">
       <serialNumber>AZ0=</serialNumber>
     </certItem>
     <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
       <serialNumber>CcHC1w==</serialNumber>
     </certItem>
@@ -4992,16 +4998,19 @@
       <serialNumber>TA6BjA==</serialNumber>
     </certItem>
     <certItem issuerName="MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu">
       <serialNumber>BAAAAAABMYnGRuw=</serialNumber>
     </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
       <serialNumber>a2GKnRbYMZ0oZkRzJE8NIw==</serialNumber>
     </certItem>
+    <certItem issuerName="MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290">
+      <serialNumber>Eg==</serialNumber>
+    </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazEtMCsGA1UEAxMkVmVyaVNpZ24gQ2xhc3MgMyBTU1AgSW50ZXJtZWRpYXRlIENB">
       <serialNumber>G8sz+bm+vQjTpQNBh5CfMg==</serialNumber>
     </certItem>
     <certItem issuerName="MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDI=">
       <serialNumber>EM8bDLBnnoYe4LnWpLIhS4esr3I=</serialNumber>
     </certItem>
     <certItem issuerName="MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=">
       <serialNumber>Cfk9oA==</serialNumber>
@@ -5049,10 +5058,22 @@
       <serialNumber>ESByYNtAIfizf2L3NMzCH8zZ</serialNumber>
     </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
       <serialNumber>QspbHxzWb41SX9TUhF1N1A==</serialNumber>
     </certItem>
     <certItem issuerName="MHYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEnMCUGA1UEAxMeU3ltYW50ZWMgV2ViIFBLSSBFQ0MgUm9vdCAtIEcx">
       <serialNumber>KNhgX8XuJduYciIyatpOQg==</serialNumber>
     </certItem>
+    <certItem issuerName="MHExCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNEZXV0c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLExZULVRlbGVTZWMgVHJ1c3QgQ2VudGVyMSMwIQYDVQQDExpEZXV0c2NoZSBUZWxla29tIFJvb3QgQ0EgMg==">
+      <serialNumber>AImQERVYPoeb</serialNumber>
+    </certItem>
+    <certItem issuerName="MGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAy">
+      <serialNumber>GpO48aJ8GngtwECqZhm/xA==</serialNumber>
+    </certItem>
+    <certItem issuerName="MDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUw=">
+      <serialNumber>CdYL9vSQCEKzBwjO10ud2w==</serialNumber>
+    </certItem>
+    <certItem issuerName="MDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMCREU=">
+      <serialNumber>a12RvBNhznU=</serialNumber>
+    </certItem>
   </certItems>
 </blocklist>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -126,17 +126,21 @@ pref("app.update.altwindowtype", "Browse
 pref("app.update.log", false);
 
 // The number of general background check failures to allow before notifying the
 // user of the failure. User initiated update checks always notify the user of
 // the failure.
 pref("app.update.backgroundMaxErrors", 10);
 
 // Whether or not app updates are enabled
+#ifdef MOZ_UPDATER
 pref("app.update.enabled", true);
+#else
+pref("app.update.enabled", false);
+#endif
 
 // Whether or not to use the doorhanger application update UI.
 pref("app.update.doorhanger", true);
 
 // Ids of the links to the "What's new" update documentation
 pref("app.update.link.updateAvailableWhatsNew", "update-available-whats-new");
 pref("app.update.link.updateManualWhatsNew", "update-manual-whats-new");
 
--- a/browser/base/content/browser-ctrlTab.js
+++ b/browser/base/content/browser-ctrlTab.js
@@ -283,16 +283,20 @@ var ctrlTab = {
 
     if (this._selectedIndex == -1) {
       // Focus is already in the panel.
       this.previews[selectedIndex].focus();
     } else {
       this._selectedIndex = selectedIndex;
     }
 
+    if (this.previews[selectedIndex]._tab) {
+      gBrowser.warmupTab(this.previews[selectedIndex]._tab);
+    }
+
     if (this._timer) {
       clearTimeout(this._timer);
       this._timer = null;
       this._openPanel();
     }
   },
 
   _mouseOverFocus: function ctrlTab_mouseOverFocus(aPreview) {
@@ -343,16 +347,17 @@ var ctrlTab = {
   open: function ctrlTab_open() {
     if (this.isOpen)
       return;
 
     document.addEventListener("keyup", this, true);
 
     this.updatePreviews();
     this._selectedIndex = 1;
+    gBrowser.warmupTab(this.selected._tab);
 
     // Add a slight delay before showing the UI, so that a quick
     // "ctrl-tab" keypress just flips back to the MRU tab.
     this._timer = setTimeout(function(self) {
       self._timer = null;
       self._openPanel();
     }, 200, this);
   },
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3144,34 +3144,17 @@ var BrowserOnClick = {
       // There is no button for reporting errors since Google doesn't currently
       // provide a URL endpoint for these reports.
     } else if (reason === "harmful") {
       title = gNavigatorBundle.getString("safebrowsing.reportedHarmfulSite");
       // There is no button for reporting errors since Google doesn't currently
       // provide a URL endpoint for these reports.
     }
 
-    let notificationBox = gBrowser.getNotificationBox();
-    let value = "blocked-badware-page";
-
-    let previousNotification = notificationBox.getNotificationWithValue(value);
-    if (previousNotification) {
-      notificationBox.removeNotification(previousNotification);
-    }
-
-    let notification = notificationBox.appendNotification(
-      title,
-      value,
-      "chrome://global/skin/icons/blacklist_favicon.png",
-      notificationBox.PRIORITY_CRITICAL_HIGH,
-      buttons
-    );
-    // Persist the notification until the user removes so it
-    // doesn't get removed on redirects.
-    notification.persistence = -1;
+    SafeBrowsingNotificationBox.show(title, buttons);
   },
 };
 
 /**
  * Re-direct the browser to a known-safe page.  This function is
  * used when, for example, the user browses to a known malware page
  * and is presented with about:blocked.  The "Get me out of here!"
  * button should take the user to the default start page so that even
@@ -4583,16 +4566,18 @@ var XULBrowserWindow = {
       URLBarSetURI(aLocationURI);
 
       BookmarkingUI.onLocationChange();
 
       gIdentityHandler.onLocationChange();
 
       BrowserPageActions.onLocationChange();
 
+      SafeBrowsingNotificationBox.onLocationChange(aLocationURI);
+
       gTabletModePageCounter.inc();
 
       // Utility functions for disabling find
       var shouldDisableFind = function(aDocument) {
         let docElt = aDocument.documentElement;
         return docElt && docElt.getAttribute("disablefastfind") == "true";
       };
 
@@ -8903,16 +8888,63 @@ var AboutPrivateBrowsingListener = {
     window.messageManager.addMessageListener(
       "AboutPrivateBrowsing:DontShowIntroPanelAgain",
       msg => {
         TrackingProtection.dontShowIntroPanelAgain();
     });
   }
 };
 
+const SafeBrowsingNotificationBox = {
+  _currentURIBaseDomain: null,
+  show(title, buttons) {
+    let uri = gBrowser.currentURI;
+
+    // start tracking host so that we know when we leave the domain
+    this._currentURIBaseDomain = Services.eTLD.getBaseDomain(uri);
+
+    let notificationBox = gBrowser.getNotificationBox();
+    let value = "blocked-badware-page";
+
+    let previousNotification = notificationBox.getNotificationWithValue(value);
+    if (previousNotification) {
+      notificationBox.removeNotification(previousNotification);
+    }
+
+    let notification = notificationBox.appendNotification(
+      title,
+      value,
+      "chrome://global/skin/icons/blacklist_favicon.png",
+      notificationBox.PRIORITY_CRITICAL_HIGH,
+      buttons
+    );
+    // Persist the notification until the user removes so it
+    // doesn't get removed on redirects.
+    notification.persistence = -1;
+  },
+  onLocationChange(aLocationURI) {
+    // take this to represent that you haven't visited a bad place
+    if (!this._currentURIBaseDomain) {
+      return;
+    }
+
+    let newURIBaseDomain = Services.eTLD.getBaseDomain(aLocationURI);
+
+    if (newURIBaseDomain !== this._currentURIBaseDomain) {
+      let notificationBox = gBrowser.getNotificationBox();
+      let notification = notificationBox.getNotificationWithValue("blocked-badware-page");
+      if (notification) {
+        notificationBox.removeNotification(notification, false);
+      }
+
+      this._currentURIBaseDomain = null;
+    }
+  }
+};
+
 function TabModalPromptBox(browser) {
   this._weakBrowserRef = Cu.getWeakReference(browser);
 }
 
 TabModalPromptBox.prototype = {
   _promptCloseCallback(onCloseCallback, principalToAllowFocusFor, allowFocusCheckbox, ...args) {
     if (principalToAllowFocusFor && allowFocusCheckbox &&
         allowFocusCheckbox.checked) {
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -597,17 +597,17 @@
 #endif
 
 <deck flex="1" id="tab-view-deck">
 <vbox flex="1" id="browser-panel">
 
   <toolbox id="navigator-toolbox">
     <!-- Menu -->
     <toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true"
-             mode="icons" iconsize="small"
+             mode="icons"
 #ifdef MENUBAR_CAN_AUTOHIDE
              toolbarname="&menubarCmd.label;"
              accesskey="&menubarCmd.accesskey;"
              autohide="true"
 #endif
              context="toolbar-context-menu">
       <toolbaritem id="menubar-items" align="center">
 # The entire main menubar is placed into browser-menubar.inc, so that it can be shared by
@@ -623,17 +623,16 @@
 #endif
 #endif
     </toolbar>
 
     <toolbar id="TabsToolbar"
              fullscreentoolbar="true"
              customizable="true"
              mode="icons"
-             iconsize="small"
              aria-label="&tabsToolbar.label;"
              context="toolbar-context-menu"
              collapsed="true">
 
 #ifdef CAN_DRAW_IN_TITLEBAR
       <hbox class="titlebar-placeholder" type="pre-tabs"
             skipintoolbarset="true"/>
 #endif
@@ -706,17 +705,16 @@
             skipintoolbarset="true"/>
 #endif
 #endif
     </toolbar>
 
     <toolbar id="nav-bar"
              aria-label="&navbarCmd.label;"
              fullscreentoolbar="true" mode="icons" customizable="true"
-             iconsize="small"
              customizationtarget="nav-bar-customization-target"
              overflowable="true"
              overflowbutton="nav-bar-overflow-button"
              overflowtarget="widget-overflow-list"
              overflowpanel="widget-overflow"
              context="toolbar-context-menu">
 
       <hbox id="nav-bar-customization-target" flex="1">
@@ -974,17 +972,17 @@
 
         <toolbarbutton id="close-button"
                        tooltiptext="&fullScreenClose.tooltip;"
                        oncommand="BrowserTryToCloseWindow();"/>
       </hbox>
     </toolbar>
 
     <toolbar id="PersonalToolbar"
-             mode="icons" iconsize="small"
+             mode="icons"
              class="chromeclass-directories"
              context="toolbar-context-menu"
              toolbarname="&personalbarCmd.label;" accesskey="&personalbarCmd.accesskey;"
              collapsed="true"
              customizable="true">
       <toolbaritem id="personal-bookmarks"
                    title="&bookmarksToolbarItem.label;"
                    cui-areatype="toolbar"
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -859,34 +859,39 @@ nsContextMenu.prototype = {
 
   reload(event) {
     BrowserReloadOrDuplicate(event);
   },
 
   // View Partial Source
   viewPartialSource(aContext) {
     let inWindow = !Services.prefs.getBoolPref("view_source.tab");
+    let {browser} = this;
     let openSelectionFn = inWindow ? null : function() {
       let tabBrowser = gBrowser;
       // In the case of popups, we need to find a non-popup browser window.
-      if (!tabBrowser || !window.toolbar.visible) {
+      // We might also not have a tabBrowser reference (if this isn't in a
+      // a tabbrowser scope) or might have a fake/stub tabbrowser reference
+      // (in the sidebar). Deal with those cases:
+      if (!tabBrowser || !tabBrowser.loadOneTab || !window.toolbar.visible) {
         // This returns only non-popup browser windows by default.
         let browserWindow = RecentWindow.getMostRecentBrowserWindow();
         tabBrowser = browserWindow.gBrowser;
       }
+      let relatedToCurrent = gBrowser && gBrowser.selectedBrowser == browser;
       let tab = tabBrowser.loadOneTab("about:blank", {
-        relatedToCurrent: true,
+        relatedToCurrent,
         inBackground: false,
         triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
       });
       return tabBrowser.getBrowserForTab(tab);
     };
 
     let target = aContext == "mathml" ? this.target : null;
-    top.gViewSourceUtils.viewPartialSourceInBrowser(gBrowser.selectedBrowser, target, openSelectionFn);
+    top.gViewSourceUtils.viewPartialSourceInBrowser(browser, target, openSelectionFn);
   },
 
   // Open new "view source" window with the frame's URL.
   viewFrameSource() {
     BrowserViewSourceOfDocument({
       browser: this.browser,
       URL: gContextMenuContentData.docLocation,
       outerWindowID: this.frameOuterWindowID,
@@ -1151,17 +1156,17 @@ nsContextMenu.prototype = {
                     loadingPrincipal: this.principal,
                     contentPolicyType: Ci.nsIContentPolicy.TYPE_SAVEAS_DOWNLOAD,
                     securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS,
                   });
 
     if (linkDownload)
       channel.contentDispositionFilename = linkDownload;
     if (channel instanceof Ci.nsIPrivateBrowsingChannel) {
-      let docIsPrivate = PrivateBrowsingUtils.isBrowserPrivate(gBrowser.selectedBrowser);
+      let docIsPrivate = PrivateBrowsingUtils.isBrowserPrivate(this.browser);
       channel.setPrivate(docIsPrivate);
     }
     channel.notificationCallbacks = new callbacks();
 
     let flags = Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
 
     if (bypassCache)
       flags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -597,108 +597,16 @@ addEventListener("unload", () => {
 }, false);
 
 addMessageListener("Browser:AppTab", function(message) {
   if (docShell) {
     docShell.isAppTab = message.data.isAppTab;
   }
 });
 
-let PrerenderContentHandler = {
-  init() {
-    this._pending = [];
-    this._idMonotonic = 0;
-    this._initialized = true;
-    addMessageListener("Prerender:Canceled", this);
-    addMessageListener("Prerender:Swapped", this);
-  },
-
-  get initialized() {
-    return !!this._initialized;
-  },
-
-  receiveMessage(aMessage) {
-    switch (aMessage.name) {
-      case "Prerender:Canceled": {
-        for (let i = 0; i < this._pending.length; ++i) {
-          if (this._pending[i].id === aMessage.data.id) {
-            if (this._pending[i].failure) {
-              this._pending[i].failure.run();
-            }
-            // Remove the item from the array
-            this._pending.splice(i, 1);
-            break;
-          }
-        }
-        break;
-      }
-      case "Prerender:Swapped": {
-        for (let i = 0; i < this._pending.length; ++i) {
-          if (this._pending[i].id === aMessage.data.id) {
-            if (this._pending[i].success) {
-              this._pending[i].success.run();
-            }
-            // Remove the item from the array
-            this._pending.splice(i, 1);
-            break;
-          }
-        }
-        break;
-      }
-    }
-  },
-
-  startPrerenderingDocument(aHref, aReferrer, aTriggeringPrincipal) {
-    // XXX: Make this constant a pref
-    if (this._pending.length >= 2) {
-      return;
-    }
-
-    let id = ++this._idMonotonic;
-    sendAsyncMessage("Prerender:Request", {
-      href: aHref.spec,
-      referrer: aReferrer ? aReferrer.spec : null,
-      id,
-      triggeringPrincipal: Utils.serializePrincipal(aTriggeringPrincipal),
-    });
-
-    this._pending.push({
-      href: aHref,
-      referrer: aReferrer,
-      id,
-      success: null,
-      failure: null,
-    });
-  },
-
-  shouldSwitchToPrerenderedDocument(aHref, aReferrer, aSuccess, aFailure) {
-    // Check if we think there is a prerendering document pending for the given
-    // href and referrer. If we think there is one, we will send a message to
-    // the parent process asking it to do a swap, and hook up the success and
-    // failure listeners.
-    for (let i = 0; i < this._pending.length; ++i) {
-      let p = this._pending[i];
-      if (p.href.equals(aHref) && p.referrer.equals(aReferrer)) {
-        p.success = aSuccess;
-        p.failure = aFailure;
-        sendAsyncMessage("Prerender:Swap", {id: p.id});
-        return true;
-      }
-    }
-
-    return false;
-  }
-};
-
-if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
-  // We only want to initialize the PrerenderContentHandler in the content
-  // process. Outside of the content process, this should be unused.
-  PrerenderContentHandler.init();
-}
-
 var WebBrowserChrome = {
   onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab) {
     return BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
   },
 
   // Check whether this URI should load in the current process
   shouldLoadURI(aDocShell, aURI, aReferrer, aHasPostData, aTriggeringPrincipal) {
     if (!E10SUtils.shouldLoadURI(aDocShell, aURI, aReferrer, aHasPostData)) {
@@ -712,30 +620,16 @@ var WebBrowserChrome = {
   shouldLoadURIInThisProcess(aURI) {
     return E10SUtils.shouldLoadURIInThisProcess(aURI);
   },
 
   // Try to reload the currently active or currently loading page in a new process.
   reloadInFreshProcess(aDocShell, aURI, aReferrer, aTriggeringPrincipal, aLoadFlags) {
     E10SUtils.redirectLoad(aDocShell, aURI, aReferrer, aTriggeringPrincipal, true, aLoadFlags);
     return true;
-  },
-
-  startPrerenderingDocument(aHref, aReferrer, aTriggeringPrincipal) {
-    if (PrerenderContentHandler.initialized) {
-      PrerenderContentHandler.startPrerenderingDocument(aHref, aReferrer, aTriggeringPrincipal);
-    }
-  },
-
-  shouldSwitchToPrerenderedDocument(aHref, aReferrer, aSuccess, aFailure) {
-    if (PrerenderContentHandler.initialized) {
-      return PrerenderContentHandler.shouldSwitchToPrerenderedDocument(
-        aHref, aReferrer, aSuccess, aFailure);
-    }
-    return false;
   }
 };
 
 if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
   let tabchild = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                          .getInterface(Ci.nsITabChild);
   tabchild.webBrowserChrome = WebBrowserChrome;
 }
--- a/browser/base/content/tabbrowser.css
+++ b/browser/base/content/tabbrowser.css
@@ -5,20 +5,16 @@
 .tabbrowser-tabpanels {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabpanels");
 }
 
 .tabbrowser-arrowscrollbox {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-arrowscrollbox");
 }
 
-.tab-close-button {
-  -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-close-tab-button");
-}
-
 .tab-close-button[pinned],
 #tabbrowser-tabs[closebuttons="activetab"] > .tabbrowser-tab > .tab-stack > .tab-content > .tab-close-button:not([selected="true"]),
 .tab-icon-image:not([src]):not([pinned]):not([crashed])[selected],
 .tab-icon-image:not([src]):not([pinned]):not([crashed]):not([sharing]),
 .tab-icon-image[busy],
 .tab-throbber:not([busy]),
 .tab-throbber-fallback:not([busy]),
 .tab-icon-sound:not([soundplaying]):not([muted]):not([activemedia-blocked]),
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1727,17 +1727,16 @@
             var aForceNotRemote;
             var aPreferredRemoteType;
             var aNoReferrer;
             var aUserContextId;
             var aSameProcessAsFrameLoader;
             var aOriginPrincipal;
             var aOpener;
             var aOpenerBrowser;
-            var aIsPrerendered;
             var aCreateLazyBrowser;
             var aNextTabParentId;
             var aFocusUrlBar;
             var aName;
             if (arguments.length == 2 &&
                 typeof arguments[1] == "object" &&
                 !(arguments[1] instanceof Ci.nsIURI)) {
               let params = arguments[1];
@@ -1755,17 +1754,16 @@
               aForceNotRemote           = params.forceNotRemote;
               aPreferredRemoteType      = params.preferredRemoteType;
               aNoReferrer               = params.noReferrer;
               aUserContextId            = params.userContextId;
               aSameProcessAsFrameLoader = params.sameProcessAsFrameLoader;
               aOriginPrincipal          = params.originPrincipal;
               aOpener                   = params.opener;
               aOpenerBrowser            = params.openerBrowser;
-              aIsPrerendered            = params.isPrerendered;
               aCreateLazyBrowser        = params.createLazyBrowser;
               aNextTabParentId          = params.nextTabParentId;
               aFocusUrlBar              = params.focusUrlBar;
               aName                     = params.name;
             }
 
             var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
                          Services.prefs.getBoolPref("browser.tabs.loadInBackground");
@@ -1787,17 +1785,16 @@
                                   createLazyBrowser: aCreateLazyBrowser,
                                   preferredRemoteType: aPreferredRemoteType,
                                   noReferrer: aNoReferrer,
                                   userContextId: aUserContextId,
                                   originPrincipal: aOriginPrincipal,
                                   sameProcessAsFrameLoader: aSameProcessAsFrameLoader,
                                   opener: aOpener,
                                   openerBrowser: aOpenerBrowser,
-                                  isPrerendered: aIsPrerendered,
                                   nextTabParentId: aNextTabParentId,
                                   focusUrlBar: aFocusUrlBar,
                                   name: aName });
             if (!bgLoad)
               this.selectedTab = tab;
 
             return tab;
          ]]>
@@ -2196,32 +2193,28 @@
       </method>
 
       <method name="_createBrowser">
         <parameter name="aParams"/>
         <body>
           <![CDATA[
             // Supported parameters:
             // userContextId, remote, remoteType, isPreloadBrowser,
-            // uriIsAboutBlank, sameProcessAsFrameLoader, isPrerendered
+            // uriIsAboutBlank, sameProcessAsFrameLoader
 
             const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
             let b = document.createElementNS(NS_XUL, "browser");
             b.permanentKey = {};
             b.setAttribute("type", "content");
             b.setAttribute("message", "true");
             b.setAttribute("messagemanagergroup", "browsers");
             b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
             b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
 
-            if (aParams.isPrerendered) {
-              b.setAttribute("prerendered", "true");
-            }
-
             if (aParams.userContextId) {
               b.setAttribute("usercontextid", aParams.userContextId);
             }
 
             // remote parameter used by some addons, use default in this case.
             if (aParams.remote && !aParams.remoteType) {
               aParams.remoteType = E10SUtils.DEFAULT_REMOTE_TYPE;
             }
@@ -2600,17 +2593,16 @@
             var aNoReferrer;
             var aUserContextId;
             var aEventDetail;
             var aSameProcessAsFrameLoader;
             var aOriginPrincipal;
             var aDisallowInheritPrincipal;
             var aOpener;
             var aOpenerBrowser;
-            var aIsPrerendered;
             var aCreateLazyBrowser;
             var aSkipBackgroundNotify;
             var aNextTabParentId;
             var aNoInitialLabel;
             var aFocusUrlBar;
             var aName;
             if (arguments.length == 2 &&
                 typeof arguments[1] == "object" &&
@@ -2632,17 +2624,16 @@
               aNoReferrer               = params.noReferrer;
               aUserContextId            = params.userContextId;
               aEventDetail              = params.eventDetail;
               aSameProcessAsFrameLoader = params.sameProcessAsFrameLoader;
               aOriginPrincipal          = params.originPrincipal;
               aDisallowInheritPrincipal = params.disallowInheritPrincipal;
               aOpener                   = params.opener;
               aOpenerBrowser            = params.openerBrowser;
-              aIsPrerendered            = params.isPrerendered;
               aCreateLazyBrowser        = params.createLazyBrowser;
               aSkipBackgroundNotify     = params.skipBackgroundNotify;
               aNextTabParentId          = params.nextTabParentId;
               aNoInitialLabel           = params.noInitialLabel;
               aFocusUrlBar              = params.focusUrlBar;
               aName                     = params.name;
             }
 
@@ -2690,20 +2681,16 @@
               if (isBlankPageURL(aURI)) {
                 t.setAttribute("label", gTabBrowserBundle.GetStringFromName("tabs.emptyTabTitle"));
               } else {
                 // Set URL as label so that the tab isn't empty initially.
                 this.setInitialTabTitle(t, aURI, { beforeTabOpen: true });
               }
             }
 
-            if (aIsPrerendered) {
-              t.setAttribute("hidden", "true");
-            }
-
             // Related tab inherits current tab's user context unless a different
             // usercontextid is specified
             if (aUserContextId == null && openerTab) {
               aUserContextId = openerTab.getAttribute("usercontextid") || 0;
             }
 
             if (aUserContextId) {
               t.setAttribute("usercontextid", aUserContextId);
@@ -2790,17 +2777,16 @@
 
               if (!b) {
                 // No preloaded browser found, create one.
                 b = this._createBrowser({ remoteType,
                                           uriIsAboutBlank,
                                           userContextId: aUserContextId,
                                           sameProcessAsFrameLoader: aSameProcessAsFrameLoader,
                                           openerWindow: aOpener,
-                                          isPrerendered: aIsPrerendered,
                                           nextTabParentId: aNextTabParentId,
                                           name: aName });
               }
 
               t.linkedBrowser = b;
 
               if (aFocusUrlBar) {
                 b._urlbarFocused = true;
@@ -5819,86 +5805,16 @@
 
                 notificationBox.appendNotification(message, "refresh-blocked",
                                                    "chrome://browser/skin/notification-icons/popup.svg",
                                                    notificationBox.PRIORITY_INFO_MEDIUM,
                                                    buttons);
               }
               break;
             }
-
-            case "Prerender:Request": {
-              let sendCancelPrerendering = () => {
-                browser.frameloader.messageManager.
-                  sendAsyncMessage("Prerender:Canceled", { id: data.id });
-              };
-
-              let tab = this.getTabForBrowser(browser);
-              if (!tab) {
-                // No tab?
-                sendCancelPrerendering();
-                break;
-              }
-
-              if (tab.hidden) {
-                // Skip prerender on hidden tab.
-                sendCancelPrerendering();
-                break;
-              }
-
-              if (browser.canGoForward) {
-                // Skip prerender on history navigation as we don't support it
-                // yet. Remove this check once bug 1323650 is implemented.
-                sendCancelPrerendering();
-                break;
-              }
-
-              if (!data.href) {
-                // If we don't have data.href, loadOneTab will load about:blank
-                // which is meaningless for prerendering.
-                sendCancelPrerendering();
-                break;
-              }
-
-              let groupedSHistory = browser.frameLoader.ensureGroupedSHistory();
-
-              let newTab = this.loadOneTab(data.href, {
-                referrerURI: (data.referrer ? makeURI(data.referrer) : null),
-                referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
-                postData: null,
-                allowThirdPartyFixup: true,
-                relatedToCurrent: true,
-                isPrerendered: true,
-                triggeringPrincipal: Utils.deserializePrincipal(data.triggeringPrincipal),
-              });
-              let partialSHistory = newTab.linkedBrowser.frameLoader.partialSHistory;
-              groupedSHistory.addPrerenderingPartialSHistory(partialSHistory, data.id);
-              break;
-            }
-
-            case "Prerender:Cancel": {
-              let groupedSHistory = browser.frameLoader.groupedSHistory;
-              if (groupedSHistory) {
-                groupedSHistory.cancelPrerendering(data.id);
-              }
-              break;
-            }
-
-            case "Prerender:Swap": {
-              let frameloader = browser.frameLoader;
-              let groupedSHistory = browser.frameLoader.groupedSHistory;
-              if (groupedSHistory) {
-                groupedSHistory.activatePrerendering(data.id).then(
-                  () => frameloader.messageManager.sendAsyncMessage("Prerender:Swapped", data),
-                  () => frameloader.messageManager.sendAsyncMessage("Prerender:Canceled", data),
-                );
-              }
-              break;
-            }
-
           }
           return undefined;
         ]]></body>
       </method>
 
       <method name="observe">
         <parameter name="aSubject"/>
         <parameter name="aTopic"/>
@@ -6055,21 +5971,16 @@
           messageManager.addMessageListener("Browser:WindowCreated", this);
 
           // To correctly handle keypresses for potential FindAsYouType, while
           // the tab's find bar is not yet initialized.
           this._findAsYouType = Services.prefs.getBoolPref("accessibility.typeaheadfind");
           Services.prefs.addObserver("accessibility.typeaheadfind", this);
           messageManager.addMessageListener("Findbar:Keypress", this);
 
-          // Add listeners for prerender messages
-          messageManager.addMessageListener("Prerender:Request", this);
-          messageManager.addMessageListener("Prerender:Cancel", this);
-          messageManager.addMessageListener("Prerender:Swap", this);
-
           XPCOMUtils.defineLazyPreferenceGetter(this, "animationsEnabled",
                                                 "toolkit.cosmeticAnimations.enabled", true);
           XPCOMUtils.defineLazyPreferenceGetter(this, "schedulePressureDefaultCount",
                                                 "browser.schedulePressure.defaultCount", 3);
           XPCOMUtils.defineLazyPreferenceGetter(this, "tabWarmingEnabled",
                                                 "browser.tabs.remote.warmup.enabled", false);
           XPCOMUtils.defineLazyPreferenceGetter(this, "tabWarmingMax",
                                                 "browser.tabs.remote.warmup.maxTabs", 3);
@@ -7294,17 +7205,16 @@
         // as double-clicking the titlebar
         if (TabsInTitlebar.enabled || this.parentNode._dragBindingAlive)
           return;
 
         if (event.button != 0 ||
             event.originalTarget.localName != "box")
           return;
 
-        // See hack note in the tabbrowser-close-tab-button binding
         if (!this._blockDblClick)
           BrowserOpenTab();
 
         event.preventDefault();
       ]]></handler>
 
       <handler event="click" button="0" phase="capturing"><![CDATA[
         /* Catches extra clicks meant for the in-tab close button.
@@ -7343,18 +7253,17 @@
           }
         }
 
         /* Protects from close-tab-button errant doubleclick:
          * Since we're removing the event target, if the user
          * double-clicks the button, the dblclick event will be dispatched
          * with the tabbar as its event target (and explicit/originalTarget),
          * which treats that as a mouse gesture for opening a new tab.
-         * In this context, we're manually blocking the dblclick event
-         * (see tabbrowser-close-tab-button dblclick handler).
+         * In this context, we're manually blocking the dblclick event.
          */
         if (this._blockDblClick) {
           if (!("_clickedTabBarOnce" in this)) {
             this._clickedTabBarOnce = true;
             return;
           }
           delete this._clickedTabBarOnce;
           this._blockDblClick = false;
@@ -7825,44 +7734,16 @@
           return;
 
         this._tabDropIndicator.collapsed = true;
         event.stopPropagation();
       ]]></handler>
     </handlers>
   </binding>
 
-  <!-- close-tab-button binding
-       This binding relies on the structure of the tabbrowser binding.
-       Therefore it should only be used as a child of the tab or the tabs
-       element (in both cases, when they are anonymous nodes of <tabbrowser>).
-  -->
-  <binding id="tabbrowser-close-tab-button">
-    <handlers>
-      <handler event="click" button="0"><![CDATA[
-        var bindingParent = document.getBindingParent(this);
-        var tabContainer = bindingParent.parentNode;
-        tabContainer.tabbrowser.removeTab(bindingParent, {animate: true,
-                byMouse: event.mozInputSource == MouseEvent.MOZ_SOURCE_MOUSE});
-        // This enables double-click protection for the tab container
-        // (see tabbrowser-tabs 'click' handler).
-        tabContainer._blockDblClick = true;
-      ]]></handler>
-
-      <handler event="dblclick" button="0" phase="capturing">
-        // for the one-close-button case
-        event.stopPropagation();
-      </handler>
-
-      <handler event="dragstart">
-        event.stopPropagation();
-      </handler>
-    </handlers>
-  </binding>
-
   <binding id="tabbrowser-tab" display="xul:hbox"
            extends="chrome://global/content/bindings/tabbox.xml#tab">
     <resources>
       <stylesheet src="chrome://browser/content/tabbrowser.css"/>
     </resources>
 
     <content context="tabContextMenu">
       <xul:stack class="tab-stack" flex="1">
@@ -8232,61 +8113,81 @@
           ContextualIdentityService.setTabStyle(this);
         ]]>
         </body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="mouseover"><![CDATA[
-        let anonid = event.originalTarget.getAttribute("anonid");
-        if (anonid == "close-button")
+        if (event.originalTarget.getAttribute("anonid") == "close-button") {
           this.mOverCloseButton = true;
+        }
 
         this._mouseenter();
       ]]></handler>
       <handler event="mouseout"><![CDATA[
-        let anonid = event.originalTarget.getAttribute("anonid");
-        if (anonid == "close-button")
+        if (event.originalTarget.getAttribute("anonid") == "close-button") {
           this.mOverCloseButton = false;
+        }
 
         this._mouseleave();
       ]]></handler>
+
       <handler event="dragstart" phase="capturing">
         this.style.MozUserFocus = "";
       </handler>
+
+      <handler event="dragstart"><![CDATA[
+        if (this.mOverCloseButton) {
+          event.stopPropagation();
+        }
+      ]]></handler>
+
       <handler event="mousedown" phase="capturing">
       <![CDATA[
         if (this.selected) {
           this.style.MozUserFocus = "ignore";
         } else if (this.mOverCloseButton ||
                    this._overPlayingIcon) {
           // Prevent tabbox.xml from selecting the tab.
           event.stopPropagation();
         }
       ]]>
       </handler>
       <handler event="mouseup">
         this.style.MozUserFocus = "";
       </handler>
-      <handler event="click">
-      <![CDATA[
-        if (event.button != 0) {
-          return;
-        }
-
+
+      <handler event="click" button="0"><![CDATA[
         if (this._overPlayingIcon) {
           this.toggleMuteAudio();
+          return;
         }
-      ]]>
-      </handler>
+
+        if (event.originalTarget.getAttribute("anonid") == "close-button") {
+          let tabContainer = this.parentNode;
+          tabContainer.tabbrowser.removeTab(this, {animate: true,
+                  byMouse: event.mozInputSource == MouseEvent.MOZ_SOURCE_MOUSE});
+          // This enables double-click protection for the tab container
+          // (see tabbrowser-tabs 'click' handler).
+          tabContainer._blockDblClick = true;
+        }
+      ]]></handler>
+
+      <handler event="dblclick" button="0" phase="capturing"><![CDATA[
+        // for the one-close-button case
+        if (event.originalTarget.getAttribute("anonid") == "close-button") {
+          event.stopPropagation();
+        }
+      ]]></handler>
+
       <handler event="animationend">
       <![CDATA[
-        let anonid = event.originalTarget.getAttribute("anonid");
-        if (anonid == "tab-loading-burst") {
+        if (event.originalTarget.getAttribute("anonid") == "tab-loading-burst") {
           this.removeAttribute("bursting");
         }
       ]]>
       </handler>
     </handlers>
   </binding>
 
   <binding id="tabbrowser-alltabs-popup"
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -583,11 +583,8 @@ tags = fullscreen
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_newWindowDrop.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_newwindow_focus.js]
 skip-if = (os == "linux" && !e10s) # Bug 1263254 - Perma fails on Linux without e10s for some reason.
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
 [browser_bug1299667.js]
 # DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
-[browser_close_dependent_tabs.js]
-skip-if = !e10s # GroupedSHistory is e10s-only
-# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
deleted file mode 100644
--- a/browser/base/content/test/general/browser_close_dependent_tabs.js
+++ /dev/null
@@ -1,78 +0,0 @@
-add_task(async function() {
-  await SpecialPowers.pushPrefEnv({
-    set: [["browser.groupedhistory.enabled", true],
-          ["dom.linkPrerender.enabled", true]]
-  });
-
-  // Wait for a process change and then fulfil the promise.
-  function awaitProcessChange(browser) {
-    return new Promise(resolve => {
-      browser.addEventListener("BrowserChangedProcess", function(e) {
-        ok(true, "The browser changed process!");
-        resolve();
-      }, {once: true});
-    });
-  }
-
-  // Wait for given number tabs being closed.
-  function awaitTabClose(number) {
-    return new Promise(resolve => {
-      let seen = 0;
-      gBrowser.tabContainer.addEventListener("TabClose", function f() {
-        if (++seen == number) {
-          gBrowser.tabContainer.removeEventListener("TabClose", f);
-          resolve();
-        }
-      });
-    });
-  }
-
-  // Test 1: Create prerendered browser, and don't switch to it, then close the tab
-  let closed1 = awaitTabClose(2);
-  await BrowserTestUtils.withNewTab({ gBrowser, url: "data:text/html,a" }, async function(browser1) {
-    // Set up the grouped SHEntry setup
-
-    let requestMade = new Promise(resolve => {
-      browser1.messageManager.addMessageListener("Prerender:Request", function f() {
-        browser1.messageManager.removeMessageListener("Prerender:Request", f);
-        ok(true, "Successfully received the prerender request");
-        resolve();
-      });
-    });
-
-    is(gBrowser.tabs.length, 2);
-    await ContentTask.spawn(browser1, null, function() {
-      let link = content.document.createElement("link");
-      link.setAttribute("rel", "prerender");
-      link.setAttribute("href", "data:text/html,b");
-      content.document.body.appendChild(link);
-    });
-    await requestMade;
-
-    is(gBrowser.tabs.length, 3);
-  });
-  await closed1;
-
-  // At this point prerendered tab should be closed
-  is(gBrowser.tabs.length, 1, "The new tab and the prerendered 'tab' should be closed");
-
-  // Test 2: Create prerendered browser, switch to it, then close the tab
-  let closed2 = awaitTabClose(2);
-  await BrowserTestUtils.withNewTab({ gBrowser, url: "data:text/html,a" }, async function(browser1) {
-    // Set up the grouped SHEntry setup
-    let tab2 = gBrowser.loadOneTab("data:text/html,b", {
-      referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
-      allowThirdPartyFixup: true,
-      relatedToCurrent: true,
-      isPrerendered: true,
-      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
-    });
-    await BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
-    browser1.frameLoader.appendPartialSHistoryAndSwap(tab2.linkedBrowser.frameLoader);
-    await awaitProcessChange(browser1);
-  });
-  await closed2;
-
-  // At this point prerendered tab should be closed
-  is(gBrowser.tabs.length, 1, "The new tab and the prerendered 'tab' should be closed");
-});
--- a/browser/base/content/test/general/browser_contextmenu.js
+++ b/browser/base/content/test/general/browser_contextmenu.js
@@ -979,16 +979,75 @@ add_task(async function test_svg_link() 
      "context-copylink",      true,
      "context-searchselect",  true,
      "---",                   null,
      "context-sendlinktodevice", true, [], null,
     ]
   );
 });
 
+add_task(async function test_svg_relative_link() {
+  await test_contextmenu("#svg-with-relative-link > a",
+    ["context-openlinkintab", true,
+     ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []),
+     // We need a blank entry here because the containers submenu is
+     // dynamically generated with no ids.
+     ...(hasContainers ? ["", null] : []),
+     "context-openlink",      true,
+     "context-openlinkprivate", true,
+     "---",                   null,
+     "context-bookmarklink",  true,
+     "context-savelink",      true,
+     ...(hasPocket ? ["context-savelinktopocket", true] : []),
+     "context-copylink",      true,
+     "context-searchselect",  true,
+     "---",                   null,
+     "context-sendlinktodevice", true, [], null,
+    ]
+  );
+
+  await test_contextmenu("#svg-with-relative-link2 > a",
+    ["context-openlinkintab", true,
+     ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []),
+     // We need a blank entry here because the containers submenu is
+     // dynamically generated with no ids.
+     ...(hasContainers ? ["", null] : []),
+     "context-openlink",      true,
+     "context-openlinkprivate", true,
+     "---",                   null,
+     "context-bookmarklink",  true,
+     "context-savelink",      true,
+     ...(hasPocket ? ["context-savelinktopocket", true] : []),
+     "context-copylink",      true,
+     "context-searchselect",  true,
+     "---",                   null,
+     "context-sendlinktodevice", true, [], null,
+    ]
+  );
+
+  await test_contextmenu("#svg-with-relative-link3 > a",
+    ["context-openlinkintab", true,
+     ...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []),
+     // We need a blank entry here because the containers submenu is
+     // dynamically generated with no ids.
+     ...(hasContainers ? ["", null] : []),
+     "context-openlink",      true,
+     "context-openlinkprivate", true,
+     "---",                   null,
+     "context-bookmarklink",  true,
+     "context-savelink",      true,
+     ...(hasPocket ? ["context-savelinktopocket", true] : []),
+     "context-copylink",      true,
+     "context-searchselect",  true,
+     "---",                   null,
+     "context-sendlinktodevice", true, [], null,
+    ]
+  );
+});
+
 add_task(async function test_cleanup_html() {
   gBrowser.removeCurrentTab();
 });
 
 /**
  * Selects the text of the element that matches the provided `selector`
  *
  * @param {String} selector
--- a/browser/base/content/test/general/subtst_contextmenu.html
+++ b/browser/base/content/test/general/subtst_contextmenu.html
@@ -67,10 +67,13 @@ Browser context menu subtest.
 <input id="test-select-input-text" type="text" value="input">
 <input id="test-select-input-text-type-password" type="password" value="password">
 <embed id="test-plugin" style="width: 200px; height: 200px;" type="application/x-test"></embed>
 <img id="test-longdesc" src="ctxmenu-image.png" longdesc="http://www.mozilla.org"></embed>
 <iframe id="test-srcdoc" width="98"  height="98" srcdoc="Hello World" style="border: 1px solid black"></iframe>
 <svg id="svg-with-link" width=10 height=10><a xlink:href="http://example.com/"><circle cx="50%" cy="50%" r="50%" fill="blue"/></a></svg>
 <svg id="svg-with-link2" width=10 height=10><a xlink:href="http://example.com/" xlink:type="simple"><circle cx="50%" cy="50%" r="50%" fill="green"/></a></svg>
 <svg id="svg-with-link3" width=10 height=10><a href="http://example.com/"><circle cx="50%" cy="50%" r="50%" fill="red"/></a></svg>
+<svg id="svg-with-relative-link" width=10 height=10><a xlink:href="/"><circle cx="50%" cy="50%" r="50%" fill="blue"/></a></svg>
+<svg id="svg-with-relative-link2" width=10 height=10><a xlink:href="/" xlink:type="simple"><circle cx="50%" cy="50%" r="50%" fill="green"/></a></svg>
+<svg id="svg-with-relative-link3" width=10 height=10><a href="/"><circle cx="50%" cy="50%" r="50%" fill="red"/></a></svg>
 </body>
 </html>
--- a/browser/base/content/test/popupNotifications/browser.ini
+++ b/browser/base/content/test/popupNotifications/browser.ini
@@ -9,16 +9,18 @@ skip-if = (os == "linux" && (debug || as
 [browser_popupNotification_2.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_3.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_4.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_5.js]
 skip-if = true # bug 1332646
+[browser_popupNotification_accesskey.js]
+skip-if = (os == "linux" && (debug || asan)) || os == "mac"
 [browser_popupNotification_checkbox.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_selection_required.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_keyboard.js]
 skip-if = (os == "linux" && (debug || asan))
 [browser_popupNotification_no_anchors.js]
 skip-if = (os == "linux" && (debug || asan))
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/popupNotifications/browser_popupNotification_accesskey.js
@@ -0,0 +1,43 @@
+/* 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/. */
+
+function test() {
+  waitForExplicitFinish();
+
+  ok(PopupNotifications, "PopupNotifications object exists");
+  ok(PopupNotifications.panel, "PopupNotifications panel exists");
+
+  setup();
+}
+
+let buttonPressed = false;
+
+function commandTriggered() {
+  buttonPressed = true;
+}
+
+var tests = [
+  // This test ensures that the accesskey closes the popup.
+  { id: "Test#1",
+    run() {
+      this.notifyObj = new BasicNotification(this.id);
+      showNotification(this.notifyObj);
+    },
+    onShown(popup) {
+      window.addEventListener("command", commandTriggered, true);
+      checkPopup(popup, this.notifyObj);
+      EventUtils.synthesizeKey("VK_ALT", { type: "keydown" });
+      EventUtils.synthesizeKey("M", { altKey: true });
+      EventUtils.synthesizeKey("VK_ALT", { type: "keyup" });
+
+      // If bug xxx was present, then the popup would be in the
+      // process of being hidden right now.
+      isnot(popup.state, "hiding", "popup is not hiding");
+    },
+    onHidden(popup) {
+      window.removeEventListener("command", commandTriggered, true);
+      ok(buttonPressed, "button pressed");
+    }
+  }
+ ];
--- a/browser/base/content/test/urlbar/browser_urlbarOneOffs.js
+++ b/browser/base/content/test/urlbar/browser_urlbarOneOffs.js
@@ -223,16 +223,35 @@ add_task(async function oneOffReturn() {
     BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false,
                                    "http://mochi.test:8888/?terms=foo.bar");
   EventUtils.synthesizeKey("VK_RETURN", {});
   await resultsPromise;
 
   gBrowser.removeTab(gBrowser.selectedTab);
 });
 
+add_task(async function collapsedOneOffs() {
+  // Disable all the engines but the current one, check the oneoffs are
+  // collapsed and that moving up selects the last match.
+  let engines = Services.search.getVisibleEngines()
+                               .filter(e => e.name != Services.search.currentEngine.name);
+  await SpecialPowers.pushPrefEnv({"set": [
+    [ "browser.search.hiddenOneOffs", engines.map(e => e.name).join(",") ]
+  ]});
+
+  let typedValue = "foo";
+  await promiseAutocompleteResultPopup(typedValue, window, true);
+  await waitForAutocompleteResultAt(0);
+  assertState(0, -1);
+  Assert.ok(gURLBar.popup.oneOffSearchButtons.buttons.collapsed,
+    "The one-off buttons should be collapsed");
+  EventUtils.synthesizeKey("VK_UP", {});
+  assertState(1, -1);
+  await hidePopup();
+});
 
 function assertState(result, oneOff, textValue = undefined) {
   Assert.equal(gURLBar.popup.selectedIndex, result,
                "Expected result should be selected");
   Assert.equal(gURLBar.popup.oneOffSearchButtons.selectedButtonIndex, oneOff,
                "Expected one-off should be selected");
   if (textValue !== undefined) {
     Assert.equal(gURLBar.textValue, textValue, "Expected textValue");
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -154,22 +154,29 @@ var gUIStateBeforeReset = {
   uiCustomizationState: null,
   drawInTitlebar: null,
   extraDragSpace: null,
   currentTheme: null,
   uiDensity: null,
   autoTouchMode: null,
 };
 
+XPCOMUtils.defineLazyPreferenceGetter(this, "gDebuggingEnabled", kPrefCustomizationDebug, false,
+  (pref, oldVal, newVal) => {
+    if (typeof log != "undefined") {
+      log.maxLogLevel = newVal ? "all" : "log";
+    }
+  }
+);
+
 XPCOMUtils.defineLazyGetter(this, "log", () => {
   let scope = {};
   Cu.import("resource://gre/modules/Console.jsm", scope);
-  let debug = Services.prefs.getBoolPref(kPrefCustomizationDebug, false);
   let consoleOptions = {
-    maxLogLevel: debug ? "all" : "log",
+    maxLogLevel: gDebuggingEnabled ? "all" : "log",
     prefix: "CustomizableUI",
   };
   return new scope.ConsoleAPI(consoleOptions);
 });
 
 var CustomizableUIInternal = {
   initialize() {
     log.debug("Initializing");
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -2312,20 +2312,16 @@ CustomizeMode.prototype = {
     return aElement.closest(areas.map(a => "#" + CSS.escape(a)).join(","));
   },
 
   _getDragOverNode(aEvent, aAreaElement, aAreaType, aDraggedItemId) {
     let expectedParent = aAreaElement.customizationTarget || aAreaElement;
     if (!expectedParent.contains(aEvent.target)) {
       return expectedParent;
     }
-    // Our tests are stupid. Cope:
-    if (!aEvent.clientX && !aEvent.clientY) {
-      return aEvent.target;
-    }
     // Offset the drag event's position with the offset to the center of
     // the thing we're dragging
     let dragX = aEvent.clientX - this._dragOffset.x;
     let dragY = aEvent.clientY - this._dragOffset.y;
 
     // Ensure this is within the container
     let boundsContainer = expectedParent;
     let bounds = this._dwu.getBoundsWithoutFlushing(boundsContainer);
--- a/browser/components/customizableui/content/toolbar.xml
+++ b/browser/components/customizableui/content/toolbar.xml
@@ -21,35 +21,16 @@
           let CustomizableUI = scope.CustomizableUI;
           // Add an early overflow event listener that will mark if the
           // toolbar overflowed during construction.
           if (CustomizableUI.isAreaOverflowable(this.id)) {
             this.addEventListener("overflow", this);
             this.addEventListener("underflow", this);
           }
 
-          // Bug 989289: Forcibly set the now unsupported "mode" and "iconsize"
-          // attributes, just in case they accidentally get restored from
-          // persistence from a user that's been upgrading and downgrading.
-          if (CustomizableUI.isBuiltinToolbar(this.id)) {
-            const kAttributes = new Map([["mode", "icons"], ["iconsize", "small"]]);
-            for (let [attribute, value] of kAttributes) {
-              if (this.getAttribute(attribute) != value) {
-                this.setAttribute(attribute, value);
-                document.persist(this.id, attribute);
-              }
-              if (this.toolbox) {
-                if (this.toolbox.getAttribute(attribute) != value) {
-                  this.toolbox.setAttribute(attribute, value);
-                  document.persist(this.toolbox.id, attribute);
-                }
-              }
-            }
-          }
-
           // Searching for the toolbox palette in the toolbar binding because
           // toolbars are constructed first.
           let toolbox = this.toolbox;
           if (toolbox && !toolbox.palette) {
             for (let node of toolbox.children) {
               if (node.localName == "toolbarpalette") {
                 // Hold on to the palette but remove it from the document.
                 toolbox.palette = node;
@@ -136,19 +117,16 @@
         <getter><![CDATA[
           if (this._toolbox)
             return this._toolbox;
 
           let toolboxId = this.getAttribute("toolboxid");
           if (toolboxId) {
             let toolbox = document.getElementById(toolboxId);
             if (toolbox) {
-              if (toolbox.externalToolbars.indexOf(this) == -1)
-                toolbox.externalToolbars.push(this);
-
               this._toolbox = toolbox;
             }
           }
 
           if (!this._toolbox && this.parentNode &&
               this.parentNode.localName == "toolbox") {
             this._toolbox = this.parentNode;
           }
--- a/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js
+++ b/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js
@@ -9,53 +9,60 @@ const kAPIWidgetId = "feed-button";
 const kPanel = CustomizableUI.AREA_FIXED_OVERFLOW_PANEL;
 const kToolbar = CustomizableUI.AREA_NAVBAR;
 const kVisiblePalette = "customization-palette";
 
 function checkWrapper(id) {
   is(document.querySelectorAll("#wrapper-" + id).length, 1, "There should be exactly 1 wrapper for " + id + " in the customizing window.");
 }
 
-async function ensureVisibleIfInPalette(node) {
-    if (node.parentNode.parentNode == gNavToolbox.palette) {
-      node.scrollIntoView();
-      window.QueryInterface(Ci.nsIInterfaceRequestor);
-      let dwu = window.getInterface(Ci.nsIDOMWindowUtils);
-      await BrowserTestUtils.waitForCondition(() => {
-        let nodeBounds = dwu.getBoundsWithoutFlushing(node);
-        let paletteBounds = dwu.getBoundsWithoutFlushing(gNavToolbox.palette);
-        return nodeBounds.top >= paletteBounds.top && nodeBounds.bottom <= paletteBounds.bottom;
-      });
+async function ensureVisible(node) {
+  let isInPalette = node.parentNode.parentNode == gNavToolbox.palette;
+  if (isInPalette) {
+    node.scrollIntoView();
+  }
+  window.QueryInterface(Ci.nsIInterfaceRequestor);
+  let dwu = window.getInterface(Ci.nsIDOMWindowUtils);
+  await BrowserTestUtils.waitForCondition(() => {
+    let nodeBounds = dwu.getBoundsWithoutFlushing(node);
+    if (isInPalette) {
+      let paletteBounds = dwu.getBoundsWithoutFlushing(gNavToolbox.palette);
+      if (!(nodeBounds.top >= paletteBounds.top && nodeBounds.bottom <= paletteBounds.bottom)) {
+        return false;
+      }
     }
+    return nodeBounds.height && nodeBounds.width;
+  });
 }
 
 var move = {
   "drag": async function(id, target) {
     let targetNode = document.getElementById(target);
     if (targetNode.customizationTarget) {
       targetNode = targetNode.customizationTarget;
     }
     let nodeToMove = document.getElementById(id);
-    await ensureVisibleIfInPalette(nodeToMove);
-    simulateItemDrag(nodeToMove, targetNode);
+    await ensureVisible(nodeToMove);
+
+    simulateItemDrag(nodeToMove, targetNode, "end");
   },
   "dragToItem": async function(id, target) {
     let targetNode = document.getElementById(target);
     if (targetNode.customizationTarget) {
       targetNode = targetNode.customizationTarget;
     }
     let items = targetNode.querySelectorAll("toolbarpaletteitem");
     if (target == kPanel) {
       targetNode = items[items.length - 1];
     } else {
       targetNode = items[0];
     }
     let nodeToMove = document.getElementById(id);
-    await ensureVisibleIfInPalette(nodeToMove);
-    simulateItemDrag(nodeToMove, targetNode);
+    await ensureVisible(nodeToMove);
+    simulateItemDrag(nodeToMove, targetNode, "start");
   },
   "API": function(id, target) {
     if (target == kVisiblePalette) {
       return CustomizableUI.removeWidgetFromArea(id);
     }
     return CustomizableUI.addWidgetToArea(id, target, null);
   }
 };
@@ -145,16 +152,21 @@ async function checkPanel(id, method) {
 }
 
 async function checkPalette(id, method) {
   // Move back to palette:
   await move[method](id, kVisiblePalette);
   ok(CustomizableUI.inDefaultState, "Should end in default state");
   let visibleChildren = gCustomizeMode.visiblePalette.children;
   let expectedChild = method == "dragToItem" ? visibleChildren[0] : visibleChildren[visibleChildren.length - 1];
+  // Items dragged to the end of the palette should be the final item. That they're the penultimate
+  // item when dragged is tracked in bug 1395950. Once that's fixed, this hack can be removed.
+  if (method == "drag") {
+    expectedChild = expectedChild.previousElementSibling;
+  }
   is(expectedChild.firstChild.id, id, "Widget " + id + " was moved using " + method + " and should now be wrapped in palette in customizing window.");
   if (id == kXULWidgetId) {
     ok(otherWin.gNavToolbox.palette.querySelector("#" + id), "Widget " + id + " should be in invisible palette in other window.");
   }
   checkWrapper(id);
 }
 
 // This test needs a XUL button that's in the palette by default. No such
--- a/browser/components/customizableui/test/browser_878452_drag_to_panel.js
+++ b/browser/components/customizableui/test/browser_878452_drag_to_panel.js
@@ -10,17 +10,17 @@ add_task(async function() {
   await startCustomizing();
   let btn = document.getElementById("feed-button");
   let placements = getAreaWidgetIds(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
 
   let lastButtonIndex = placements.length - 1;
   let lastButton = placements[lastButtonIndex];
   let placementsAfterInsert = placements.slice(0, lastButtonIndex).concat(["feed-button", lastButton]);
   let lastButtonNode = document.getElementById(lastButton);
-  simulateItemDrag(btn, lastButtonNode);
+  simulateItemDrag(btn, lastButtonNode, "start");
   assertAreaPlacements(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, placementsAfterInsert);
   ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
   let palette = document.getElementById("customization-palette");
   simulateItemDrag(btn, palette);
   CustomizableUI.removeWidgetFromArea("cui-panel-item-to-drag-to");
   ok(CustomizableUI.inDefaultState, "Should be in default state again.");
 });
 
@@ -58,12 +58,13 @@ add_task(async function() {
   simulateItemDrag(btn, panel);
   assertAreaPlacements(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, placementsAfterAppend);
   ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
   let palette = document.getElementById("customization-palette");
   simulateItemDrag(btn, palette);
   assertAreaPlacements(panel.id, []);
 });
 
-add_task(async function asyncCleanup() {
+registerCleanupFunction(async function asyncCleanup() {
+  CustomizableUI.destroyWidget("cui-panel-item-to-drag-to");
   await endCustomizing();
   await resetCustomization();
 });
--- a/browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js
+++ b/browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js
@@ -13,23 +13,24 @@ add_task(async function() {
   skippedItem = document.createElement("toolbarbutton");
   skippedItem.id = "test-skipintoolbarset-item";
   skippedItem.setAttribute("label", "Test");
   skippedItem.setAttribute("skipintoolbarset", "true");
   skippedItem.setAttribute("removable", "true");
   navbar.customizationTarget.appendChild(skippedItem);
   let libraryButton = document.getElementById("library-button");
   await startCustomizing();
+  await waitForElementShown(skippedItem);
   ok(CustomizableUI.inDefaultState, "Should still be in default state");
-  simulateItemDrag(skippedItem, libraryButton);
+  simulateItemDrag(skippedItem, libraryButton, "start");
   ok(CustomizableUI.inDefaultState, "Should still be in default state");
   let skippedItemWrapper = skippedItem.parentNode;
   is(skippedItemWrapper.nextSibling && skippedItemWrapper.nextSibling.id,
      libraryButton.parentNode.id, "Should be next to library button");
-  simulateItemDrag(libraryButton, skippedItem);
+  simulateItemDrag(libraryButton, skippedItem, "start");
   let libraryWrapper = libraryButton.parentNode;
   is(libraryWrapper.nextSibling && libraryWrapper.nextSibling.id,
      skippedItem.parentNode.id, "Should be next to skipintoolbarset item");
   ok(CustomizableUI.inDefaultState, "Should still be in default state");
 });
 
 add_task(async function asyncCleanup() {
   await endCustomizing();
--- a/browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js
+++ b/browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js
@@ -40,17 +40,17 @@ add_task(async function() {
   // Make sure we have some hidden items at the end of the nav-bar.
   navbar.insertItem(hidden1.id);
   navbar.insertItem(hidden2.id);
 
   // Drag an item and drop it onto the nav-bar customization target, but
   // not over a particular item.
   await startCustomizing();
   let homeButton = document.getElementById("home-button");
-  simulateItemDrag(homeButton, navbar.customizationTarget);
+  simulateItemDrag(homeButton, navbar.customizationTarget, "end");
 
   await endCustomizing();
 
   is(homeButton.previousSibling.id, lastVisible.id,
      "The downloads button should be placed after the last visible item.");
 
   await resetCustomization();
 });
--- a/browser/components/customizableui/test/browser_newtab_button_customizemode.js
+++ b/browser/components/customizableui/test/browser_newtab_button_customizemode.js
@@ -27,46 +27,49 @@ function assertNewTabButton(which) {
   }
 }
 
 /**
  * Add and remove items *after* the new tab button in customize mode.
  */
 add_task(async function addremove_after_newtab_customizemode() {
   await startCustomizing();
-  simulateItemDrag(document.getElementById("home-button"),
-                   kGlobalNewTabButton.parentNode.nextElementSibling);
+  await waitForElementShown(kGlobalNewTabButton);
+  simulateItemDrag(document.getElementById("home-button"), kGlobalNewTabButton, "end");
   ok(gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
     "tabs should have the adjacent newtab attribute");
   await endCustomizing();
   assertNewTabButton("inner");
 
   await startCustomizing();
-  simulateItemDrag(document.getElementById("home-button"),
-    document.getElementById("stop-reload-button").parentNode.nextElementSibling);
+  let dropTarget = document.getElementById("stop-reload-button");
+  await waitForElementShown(dropTarget);
+  simulateItemDrag(document.getElementById("home-button"), dropTarget, "end");
   ok(gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
     "tabs should still have the adjacent newtab attribute");
   await endCustomizing();
   assertNewTabButton("inner");
   ok(CustomizableUI.inDefaultState, "Should be in default state");
 });
 
 /**
  * Add and remove items *before* the new tab button in customize mode.
  */
 add_task(async function addremove_before_newtab_customizemode() {
   await startCustomizing();
-  simulateItemDrag(document.getElementById("home-button"), kGlobalNewTabButton);
+  await waitForElementShown(kGlobalNewTabButton);
+  simulateItemDrag(document.getElementById("home-button"), kGlobalNewTabButton, "start");
   ok(!gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
     "tabs should no longer have the adjacent newtab attribute");
   await endCustomizing();
   assertNewTabButton("global");
   await startCustomizing();
-  simulateItemDrag(document.getElementById("home-button"),
-    document.getElementById("stop-reload-button").parentNode.nextElementSibling);
+  let dropTarget = document.getElementById("stop-reload-button");
+  await waitForElementShown(dropTarget);
+  simulateItemDrag(document.getElementById("home-button"), dropTarget, "end");
   ok(gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
     "tabs should have the adjacent newtab attribute again");
   await endCustomizing();
   assertNewTabButton("inner");
   ok(CustomizableUI.inDefaultState, "Should be in default state");
 });
 
 /**
@@ -105,17 +108,18 @@ add_task(async function addremove_before
   ok(CustomizableUI.inDefaultState, "Should be in default state");
 });
 
 /**
   * Reset to defaults in customize mode to see if that doesn't break things.
   */
 add_task(async function reset_before_newtab_customizemode() {
   await startCustomizing();
-  simulateItemDrag(document.getElementById("home-button"), kGlobalNewTabButton);
+  await waitForElementShown(kGlobalNewTabButton);
+  simulateItemDrag(document.getElementById("home-button"), kGlobalNewTabButton, "start");
   ok(!gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
     "tabs should no longer have the adjacent newtab attribute");
   await endCustomizing();
   assertNewTabButton("global");
   await startCustomizing();
   await gCustomizeMode.reset();
   ok(gBrowser.tabContainer.hasAttribute("hasadjacentnewtabbutton"),
     "tabs should have the adjacent newtab attribute again");
--- a/browser/components/customizableui/test/browser_remove_customized_specials.js
+++ b/browser/components/customizableui/test/browser_remove_customized_specials.js
@@ -10,19 +10,20 @@ add_task(async function() {
   await startCustomizing();
   CustomizableUI.addWidgetToArea("spring", "nav-bar", 5);
   await gCustomizeMode.reset();
   let springs = document.querySelectorAll("#nav-bar toolbarspring");
   let lastSpring = springs[springs.length - 1];
   let expectedPlacements = CustomizableUI.getWidgetIdsInArea("nav-bar");
   info("Placements before drag: " + expectedPlacements.join(","));
   let lastItem = document.getElementById(expectedPlacements[expectedPlacements.length - 1]);
-  simulateItemDrag(lastSpring, lastItem);
+  await waitForElementShown(lastItem);
+  simulateItemDrag(lastSpring, lastItem, "end");
   expectedPlacements.splice(expectedPlacements.indexOf(lastSpring.id), 1);
-  expectedPlacements.splice(expectedPlacements.length - 1, 0, lastSpring.id);
+  expectedPlacements.push(lastSpring.id);
   let actualPlacements = CustomizableUI.getWidgetIdsInArea("nav-bar");
   // Log these separately because Assert.deepEqual truncates the stringified versions...
   info("Actual placements: " + actualPlacements.join(","));
   info("Expected placements: " + expectedPlacements.join(","));
   Assert.deepEqual(expectedPlacements, actualPlacements, "Should be able to move spring");
   await gCustomizeMode.reset();
   await endCustomizing();
 });
--- a/browser/components/customizableui/test/head.js
+++ b/browser/components/customizableui/test/head.js
@@ -164,18 +164,32 @@ function todoAssertAreaPlacements(areaId
   todo(isPassing, "The area placements for " + areaId +
                   " should equal the expected placements.");
 }
 
 function getAreaWidgetIds(areaId) {
   return CustomizableUI.getWidgetIdsInArea(areaId);
 }
 
-function simulateItemDrag(aToDrag, aTarget) {
-  synthesizeDrop(aToDrag.parentNode, aTarget);
+function simulateItemDrag(aToDrag, aTarget, aEvent = {}) {
+  let ev = aEvent;
+  if (ev == "end" || ev == "start") {
+    let win = aTarget.ownerGlobal;
+    win.QueryInterface(Ci.nsIInterfaceRequestor);
+    const dwu = win.getInterface(Ci.nsIDOMWindowUtils);
+    let bounds = dwu.getBoundsWithoutFlushing(aTarget);
+    if (ev == "end") {
+      ev = {clientX: bounds.right - 2, clientY: bounds.bottom - 2};
+    } else {
+      ev = {clientX: bounds.left + 2, clientY: bounds.top + 2};
+    }
+  }
+  ev._domDispatchOnly = true;
+  synthesizeDrop(aToDrag.parentNode, aTarget, null, null,
+                 aToDrag.ownerGlobal, aTarget.ownerGlobal, ev);
 }
 
 function endCustomizing(aWindow = window) {
   if (aWindow.document.documentElement.getAttribute("customizing") != "true") {
     return true;
   }
   return new Promise(resolve => {
     function onCustomizationEnds() {
@@ -492,17 +506,21 @@ function checkContextMenu(aContextMenu, 
       is(menuItemDisabled, !aExpectedEntries[i][1], "disabled state for " + selector);
     } catch (e) {
       ok(false, "Exception when checking context menu: " + e);
     }
   }
 }
 
 function waitForOverflowButtonShown(win = window) {
+  let ov = win.document.getElementById("nav-bar-overflow-button");
+  let icon = win.document.getAnonymousElementByAttribute(ov, "class", "toolbarbutton-icon");
+  return waitForElementShown(icon);
+}
+function waitForElementShown(element) {
+  let win = element.ownerGlobal;
   let dwu = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
   return BrowserTestUtils.waitForCondition(() => {
     info("Waiting for overflow button to have non-0 size");
-    let ov = win.document.getElementById("nav-bar-overflow-button");
-    let icon = win.document.getAnonymousElementByAttribute(ov, "class", "toolbarbutton-icon");
-    let bounds = dwu.getBoundsWithoutFlushing(icon);
+    let bounds = dwu.getBoundsWithoutFlushing(element);
     return bounds.width > 0 && bounds.height > 0;
   });
 }
--- a/browser/components/feeds/test/mochitest.ini
+++ b/browser/components/feeds/test/mochitest.ini
@@ -7,8 +7,9 @@ support-files =
   bug589543-data.xml
   valid-feed.xml
   valid-unsniffable-feed.xml
 
 [test_bug436801.html]
 [test_bug494328.html]
 [test_bug589543.html]
 [test_registerHandler.html]
+[test_registerHandler_disabled.html]
--- a/browser/components/feeds/test/test_registerHandler.html
+++ b/browser/components/feeds/test/test_registerHandler.html
@@ -7,77 +7,85 @@ https://bugzilla.mozilla.org/show_bug.cg
   <title>Test for Bug 402788</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=402788">Mozilla Bug 402788</a>
 <p id="display"></p>
 <div id="content" style="display: none">
-  
+
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 402788 **/
+  SimpleTest.waitForExplicitFinish();
 
   // return false if an exception has been catched, true otherwise
   function testRegisterHandler(aIsProtocol, aTxt, aUri, aTitle) {
     try {
       if (aIsProtocol)
         navigator.registerProtocolHandler(aTxt, aUri, aTitle);
       else
         navigator.registerContentHandler(aTxt, aUri, aTitle);
     } catch (e) {
       return false;
     }
 
     return true;
   }
 
-  ok(navigator.registerProtocolHandler, "navigator.registerProtocolHandler should be defined");
-  ok(navigator.registerContentHandler, "navigator.registerContentHandler should be defined");
+  async function tests() {
+    await SpecialPowers.pushPrefEnv({
+      set: [["dom.registerContentHandler.enabled", true]]
+    });
+    ok(navigator.registerContentHandler, "navigator.registerContentHandler should be defined");
 
-  // testing a generic case
-  is(testRegisterHandler(true, "foo", "http://mochi.test:8888/%s", "Foo handler"), true, "registering a foo protocol handler should work");
-  is(testRegisterHandler(false, "application/rss+xml", "http://mochi.test:8888/%s", "Foo handler"), true, "registering a foo content handler should work");
+    // testing a generic case
+    is(testRegisterHandler(true, "foo", "http://mochi.test:8888/%s", "Foo handler"), true, "registering a foo protocol handler should work");
+    is(testRegisterHandler(false, "application/rss+xml", "http://mochi.test:8888/%s", "Foo handler"), true, "registering a foo content handler should work");
 
-  // testing with wrong uris
-  is(testRegisterHandler(true, "foo", "http://mochi.test:8888/", "Foo handler"), false, "a protocol handler uri should contain %s");
-  is(testRegisterHandler(false, "application/rss+xml", "http://mochi.test:8888/", "Foo handler"), false, "a content handler uri should contain %s");
+    // testing with wrong uris
+    is(testRegisterHandler(true, "foo", "http://mochi.test:8888/", "Foo handler"), false, "a protocol handler uri should contain %s");
+    is(testRegisterHandler(false, "application/rss+xml", "http://mochi.test:8888/", "Foo handler"), false, "a content handler uri should contain %s");
 
-  // the spec explicitly allows relative urls to be passed
-  is(testRegisterHandler(true, "foo", "foo/%s", "Foo handler"), true, "a protocol handler uri should be valid");
-  is(testRegisterHandler(false, "application/rss+xml", "foo/%s", "Foo handler"), true, "a content handler uri should be valid");
+    // the spec explicitly allows relative urls to be passed
+    is(testRegisterHandler(true, "foo", "foo/%s", "Foo handler"), true, "a protocol handler uri should be valid");
+    is(testRegisterHandler(false, "application/rss+xml", "foo/%s", "Foo handler"), true, "a content handler uri should be valid");
 
-  // we should only accept to register when the handler has the same host as the current page (bug 402287)
-  is(testRegisterHandler(true, "foo", "http://remotehost:8888/%s", "Foo handler"), false, "registering a foo protocol handler with a different host should not work");
-  is(testRegisterHandler(false, "application/rss+xml", "http://remotehost:8888/%s", "Foo handler"), false, "registering a foo content handler with a different host should not work");
+    // we should only accept to register when the handler has the same host as the current page (bug 402287)
+    is(testRegisterHandler(true, "foo", "http://remotehost:8888/%s", "Foo handler"), false, "registering a foo protocol handler with a different host should not work");
+    is(testRegisterHandler(false, "application/rss+xml", "http://remotehost:8888/%s", "Foo handler"), false, "registering a foo content handler with a different host should not work");
 
-  // restriction to http(s) for the uri of the handler (bug 401343)
-  // https should work (http already tested in the generic case)
-  is(testRegisterHandler(true, "foo", "https://mochi.test:8888/%s", "Foo handler"), true, "registering a foo protocol handler with https scheme should work");
-  is(testRegisterHandler(false, "application/rss+xml", "https://mochi.test:8888/%s", "Foo handler"), true, "registering a foo content handler with https scheme should work");
-  // ftp should not work
-  is(testRegisterHandler(true, "foo", "ftp://mochi.test:8888/%s", "Foo handler"), false, "registering a foo protocol handler with ftp scheme should not work");
-  is(testRegisterHandler(false, "application/rss+xml", "ftp://mochi.test:8888/%s", "Foo handler"), false, "registering a foo content handler with ftp scheme should not work");
-  // chrome should not work
-  is(testRegisterHandler(true, "foo", "chrome://mochi.test:8888/%s", "Foo handler"), false, "registering a foo protocol handler with chrome scheme should not work");
-  is(testRegisterHandler(false, "application/rss+xml", "chrome://mochi.test:8888/%s", "Foo handler"), false, "registering a foo content handler with chrome scheme should not work");
-  // foo should not work
-  is(testRegisterHandler(true, "foo", "foo://mochi.test:8888/%s", "Foo handler"), false, "registering a foo protocol handler with foo scheme should not work");
-  is(testRegisterHandler(false, "application/rss+xml", "foo://mochi.test:8888/%s", "Foo handler"), false, "registering a foo content handler with foo scheme should not work");
+    // restriction to http(s) for the uri of the handler (bug 401343)
+    // https should work (http already tested in the generic case)
+    is(testRegisterHandler(true, "foo", "https://mochi.test:8888/%s", "Foo handler"), true, "registering a foo protocol handler with https scheme should work");
+    is(testRegisterHandler(false, "application/rss+xml", "https://mochi.test:8888/%s", "Foo handler"), true, "registering a foo content handler with https scheme should work");
+    // ftp should not work
+    is(testRegisterHandler(true, "foo", "ftp://mochi.test:8888/%s", "Foo handler"), false, "registering a foo protocol handler with ftp scheme should not work");
+    is(testRegisterHandler(false, "application/rss+xml", "ftp://mochi.test:8888/%s", "Foo handler"), false, "registering a foo content handler with ftp scheme should not work");
+    // chrome should not work
+    is(testRegisterHandler(true, "foo", "chrome://mochi.test:8888/%s", "Foo handler"), false, "registering a foo protocol handler with chrome scheme should not work");
+    is(testRegisterHandler(false, "application/rss+xml", "chrome://mochi.test:8888/%s", "Foo handler"), false, "registering a foo content handler with chrome scheme should not work");
+    // foo should not work
+    is(testRegisterHandler(true, "foo", "foo://mochi.test:8888/%s", "Foo handler"), false, "registering a foo protocol handler with foo scheme should not work");
+    is(testRegisterHandler(false, "application/rss+xml", "foo://mochi.test:8888/%s", "Foo handler"), false, "registering a foo content handler with foo scheme should not work");
 
-  // for security reasons, protocol handlers should never be registered for some schemes (chrome, vbscript, ...) (bug 402788)
-  is(testRegisterHandler(true, "chrome", "http://mochi.test:8888/%s", "chrome handler"), false, "registering a chrome protocol handler should not work");
-  is(testRegisterHandler(true, "vbscript", "http://mochi.test:8888/%s", "vbscript handler"), false, "registering a vbscript protocol handler should not work");
-  is(testRegisterHandler(true, "javascript", "http://mochi.test:8888/%s", "javascript handler"), false, "registering a javascript protocol handler should not work");
-  is(testRegisterHandler(true, "moz-icon", "http://mochi.test:8888/%s", "moz-icon handler"), false, "registering a moz-icon protocol handler should not work");
+    // for security reasons, protocol handlers should never be registered for some schemes (chrome, vbscript, ...) (bug 402788)
+    is(testRegisterHandler(true, "chrome", "http://mochi.test:8888/%s", "chrome handler"), false, "registering a chrome protocol handler should not work");
+    is(testRegisterHandler(true, "vbscript", "http://mochi.test:8888/%s", "vbscript handler"), false, "registering a vbscript protocol handler should not work");
+    is(testRegisterHandler(true, "javascript", "http://mochi.test:8888/%s", "javascript handler"), false, "registering a javascript protocol handler should not work");
+    is(testRegisterHandler(true, "moz-icon", "http://mochi.test:8888/%s", "moz-icon handler"), false, "registering a moz-icon protocol handler should not work");
 
-  // for security reasons, content handlers should never be registered for some types (html, ...)
-  is(testRegisterHandler(false, "application/rss+xml", "http://mochi.test:8888/%s", "Foo handler"), true, "registering rss content handlers should work");
-  is(testRegisterHandler(false, "application/atom+xml", "http://mochi.test:8888/%s", "Foo handler"), true, "registering atom content handlers should work");
-  todo_is(testRegisterHandler(false, "text/html", "http://mochi.test:8888/%s", "Foo handler"), false, "registering html content handlers should not work"); // bug 403798
+    // for security reasons, content handlers should never be registered for some types (html, ...)
+    is(testRegisterHandler(false, "application/rss+xml", "http://mochi.test:8888/%s", "Foo handler"), true, "registering rss content handlers should work");
+    is(testRegisterHandler(false, "application/atom+xml", "http://mochi.test:8888/%s", "Foo handler"), true, "registering atom content handlers should work");
+    todo_is(testRegisterHandler(false, "text/html", "http://mochi.test:8888/%s", "Foo handler"), false, "registering html content handlers should not work"); // bug 403798
+    SimpleTest.finish();
+  }
+
+  tests();
 
 </script>
 </pre>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/browser/components/feeds/test/test_registerHandler_disabled.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=402788
+-->
+<head>
+  <title>Test for Bug 1398169</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1398169">Mozilla Bug 1398169</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+  SimpleTest.waitForExplicitFinish();
+
+  async function tests() {
+    await SpecialPowers.pushPrefEnv({
+      set: [["dom.registerContentHandler.enabled", true]]
+    });
+    ok(navigator.registerContentHandler, "navigator.registerContentHandler should be defined");
+    SimpleTest.finish();
+  }
+
+  tests();
+
+</script>
+</pre>
+</body>
+</html>
--- a/browser/components/newtab/aboutNewTabService.js
+++ b/browser/components/newtab/aboutNewTabService.js
@@ -16,17 +16,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource:///modules/AboutNewTab.jsm");
 
 const LOCAL_NEWTAB_URL = "chrome://browser/content/newtab/newTab.xhtml";
 const TOPIC_APP_QUIT = "quit-application-granted";
 const TOPIC_LOCALES_CHANGE = "intl:requested-locales-changed";
 
 // Automated tests ensure packaged locales are in this list. Copied output of:
 // https://github.com/mozilla/activity-stream/blob/master/bin/render-activity-stream-html.js
-const ACTIVITY_STREAM_LOCALES = new Set("en-US ach ar ast az be bg bn-BD bn-IN br bs ca cak cs cy da de dsb el en-GB eo es-AR es-CL es-ES es-MX et eu fa ff fi fr fy-NL ga-IE gd gl gn gu-IN he hi-IN hr hsb hu hy-AM ia id it ja ka kab kk km kn ko lij lo lt ltg lv mk ml mr ms my nb-NO ne-NP nl nn-NO pa-IN pl pt-BR pt-PT rm ro ru si sk sl sq sr sv-SE ta te th tl tr uk ur uz vi zh-CN zh-TW".split(" "));
+const ACTIVITY_STREAM_LOCALES = "en-US ach ar ast az be bg bn-BD bn-IN br bs ca cak cs cy da de dsb el en-GB eo es-AR es-CL es-ES es-MX et eu fa ff fi fr fy-NL ga-IE gd gl gn gu-IN he hi-IN hr hsb hu hy-AM ia id it ja ka kab kk km kn ko lij lo lt ltg lv mk ml mr ms my nb-NO ne-NP nl nn-NO pa-IN pl pt-BR pt-PT rm ro ru si sk sl sq sr sv-SE ta te th tl tr uk ur uz vi zh-CN zh-TW".split(" ");
 
 const ABOUT_URL = "about:newtab";
 
 const IS_MAIN_PROCESS = Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_DEFAULT;
 
 const IS_RELEASE_OR_BETA = AppConstants.RELEASE_OR_BETA;
 
 // Pref that tells if activity stream is enabled
@@ -174,36 +174,24 @@ AboutNewTabService.prototype = {
     return true;
   },
 
   /**
    * Figure out what path under prerendered to use based on current state.
    */
   updatePrerenderedPath() {
     // Debug files are specially packaged in a non-localized directory
-    let path;
-    if (this._activityStreamDebug) {
-      path = "static";
-    } else {
-      // Use the exact match locale if it's packaged
-      const locale = Services.locale.getRequestedLocale();
-      if (ACTIVITY_STREAM_LOCALES.has(locale)) {
-        path = locale;
-      } else {
-        // Fall back to a shared-language packaged locale
-        const language = locale.split("-")[0];
-        if (ACTIVITY_STREAM_LOCALES.has(language)) {
-          path = language;
-        } else {
-          // Just use the default locale as a final fallback
-          path = "en-US";
-        }
-      }
-    }
-    this._activityStreamPath = `${path}/`;
+    this._activityStreamPath = `${this._activityStreamDebug ? "static" :
+      // Pick the best available locale to match the app locales
+      Services.locale.negotiateLanguages(
+        Services.locale.getAppLocalesAsLangTags(),
+        ACTIVITY_STREAM_LOCALES,
+        // defaultLocale's strings aren't necessarily packaged, but en-US' are
+        "en-US"
+      )[0]}/`;
   },
 
   /*
    * Returns the default URL.
    *
    * This URL only depends on the browser.newtabpage.activity-stream.enabled pref. Overriding
    * the newtab page has no effect on the result of this function.
    *
--- a/browser/components/newtab/tests/browser/browser.ini
+++ b/browser/components/newtab/tests/browser/browser.ini
@@ -1,4 +1,5 @@
 [DEFAULT]
 
 [browser_packaged_as_locales.js]
+skip-if=true # bug 1423703 comment 20
 [browser_newtab_overrides.js]
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1769,17 +1769,17 @@ BrowserGlue.prototype = {
       if (toolbarIsCustomized || getToolbarFolderCount() > NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE) {
         xulStore.setValue(BROWSER_DOCURL, "PersonalToolbar", "collapsed", "false");
       }
     }
   },
 
   // eslint-disable-next-line complexity
   _migrateUI: function BG__migrateUI() {
-    const UI_VERSION = 61;
+    const UI_VERSION = 62;
     const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
 
     let currentUIVersion;
     if (Services.prefs.prefHasUserValue("browser.migration.version")) {
       currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
     } else {
       // This is a new profile, nothing to migrate.
       Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
@@ -1834,27 +1834,16 @@ BrowserGlue.prototype = {
             currentset = currentset.replace(/(^|,)window-controls($|,)/,
                                             "$1bookmarks-menu-button,window-controls$2");
           }
           xulStore.setValue(BROWSER_DOCURL, "nav-bar", "currentset", currentset);
         }
       }
     }
 
-    if (currentUIVersion < 18) {
-      // Remove iconsize and mode from all the toolbars
-      let toolbars = ["navigator-toolbox", "nav-bar", "PersonalToolbar",
-                      "TabsToolbar", "toolbar-menubar"];
-      for (let resourceName of ["mode", "iconsize"]) {
-        for (let toolbarId of toolbars) {
-          xulStore.removeValue(BROWSER_DOCURL, toolbarId, resourceName);
-        }
-      }
-    }
-
     if (currentUIVersion < 19) {
       let detector = null;
       try {
         detector = Services.prefs.getComplexValue("intl.charset.detector",
                                                   Ci.nsIPrefLocalizedString).data;
       } catch (ex) {}
       if (!(detector == "" ||
             detector == "ja_parallel_state_machine" ||
@@ -2265,16 +2254,27 @@ BrowserGlue.prototype = {
       this._migrateMatchBucketsPrefForUIVersion60();
     }
 
     if (currentUIVersion < 61) {
       // Remove persisted toolbarset from navigator toolbox
       xulStore.removeValue(BROWSER_DOCURL, "navigator-toolbox", "toolbarset");
     }
 
+    if (currentUIVersion < 62) {
+      // Remove iconsize and mode from all the toolbars
+      let toolbars = ["navigator-toolbox", "nav-bar", "PersonalToolbar",
+                      "TabsToolbar", "toolbar-menubar"];
+      for (let resourceName of ["mode", "iconsize"]) {
+        for (let toolbarId of toolbars) {
+          xulStore.removeValue(BROWSER_DOCURL, toolbarId, resourceName);
+        }
+      }
+    }
+
     // Update the migration version.
     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
   },
 
   _checkForDefaultBrowser() {
     // Perform default browser checking.
     if (!ShellService) {
       return;
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -620,17 +620,17 @@ var gEditItemOverlay = {
   },
 
   async onNamePickerChange() {
     if (this.readOnly || !(this._paneInfo.isItem || this._paneInfo.isTag))
       return;
 
     // Here we update either the item title or its cached static title
     let newTitle = this._namePicker.value;
-    if (!newTitle && this._paneInfo.parentGuid == PlacesUtils.bookmarks.tagsGuid) {
+    if (!newTitle && this._paneInfo.isTag) {
       // We don't allow setting an empty title for a tag, restore the old one.
       this._initNamePicker();
     } else {
       this._mayUpdateFirstEditField("namePicker");
       if (!PlacesUIUtils.useAsyncTransactions) {
         let txn = new PlacesEditItemTitleTransaction(this._paneInfo.itemId,
                                                      newTitle);
         PlacesUtils.transactionManager.doTransaction(txn);
@@ -1103,50 +1103,50 @@ var gEditItemOverlay = {
       // Any tags change should be reflected in the tags selector.
       if (this._element("tagsSelector")) {
         this._rebuildTagsSelectorList();
       }
     }
   },
 
   _onItemTitleChange(aItemId, aNewTitle) {
-    if (!this._paneInfo.isBookmark)
-      return;
     if (aItemId == this._paneInfo.itemId) {
       this._paneInfo.title = aNewTitle;
       this._initTextField(this._namePicker, aNewTitle);
     } else if (this._paneInfo.visibleRows.has("folderRow")) {
       // If the title of a folder which is listed within the folders
       // menulist has been changed, we need to update the label of its
       // representing element.
       let menupopup = this._folderMenuList.menupopup;
       for (let menuitem of menupopup.childNodes) {
         if ("folderId" in menuitem && menuitem.folderId == aItemId) {
           menuitem.label = aNewTitle;
           break;
         }
       }
     }
     // We need to also update title of recent folders.
-    for (let folder of this._recentFolders) {
-      if (folder.folderId == aItemId) {
-        folder.title = aNewTitle;
-        break;
+    if (this._recentFolders) {
+      for (let folder of this._recentFolders) {
+        if (folder.folderId == aItemId) {
+          folder.title = aNewTitle;
+          break;
+        }
       }
     }
   },
 
   // nsINavBookmarkObserver
   onItemChanged(aItemId, aProperty, aIsAnnotationProperty, aValue,
                 aLastModified, aItemType, aParentId, aGuid) {
     if (aProperty == "tags" && this._paneInfo.visibleRows.has("tagsRow")) {
       this._onTagsChange(aGuid).catch(Components.utils.reportError);
       return;
     }
-    if (aProperty == "title" && this._paneInfo.isItem) {
+    if (aProperty == "title" && (this._paneInfo.isItem || this._paneInfo.isTag)) {
       // This also updates titles of folders in the folder menu list.
       this._onItemTitleChange(aItemId, aValue);
       return;
     }
 
     if (!this._paneInfo.isItem || this._paneInfo.itemId != aItemId) {
       return;
     }
--- a/browser/components/places/tests/browser/browser_bookmarkProperties_editTagContainer.js
+++ b/browser/components/places/tests/browser/browser_bookmarkProperties_editTagContainer.js
@@ -55,16 +55,21 @@ add_task(async function() {
 
       await promiseTitleChangeNotification;
 
       Assert.equal(namepicker.value, "tag2", "Node title has been properly edited");
 
       // Check the shortcut's title.
       Assert.equal(tree.selectedNode.title, "tag2", "The node has the correct title");
 
+      // Try to set an empty title, it should restore the previous one.
+      fillBookmarkTextField("editBMPanel_namePicker", "", dialogWin);
+      Assert.equal(namepicker.value, "tag2", "Title has not been changed");
+      Assert.equal(tree.selectedNode.title, "tag2", "The node has the correct title");
+
       // Check the tags have been edited.
       let tags = PlacesUtils.tagging.getTagsForURI(uri);
       Assert.equal(tags.length, 1, "Found the right number of tags");
       Assert.ok(tags.includes("tag2"), "Found the expected tag");
 
       // Ensure that the addition really is finished before we hit cancel.
       await PlacesTestUtils.promiseAsyncUpdates();
     }
--- a/browser/components/places/tests/browser/head.js
+++ b/browser/components/places/tests/browser/head.js
@@ -386,18 +386,22 @@ var waitForCondition = async function(co
  *        dialog window
  * @param [optional] blur
  *        whether to blur at the end.
  */
 function fillBookmarkTextField(id, text, win, blur = true) {
   let elt = win.document.getElementById(id);
   elt.focus();
   elt.select();
-  for (let c of text.split("")) {
-    EventUtils.synthesizeKey(c, {}, win);
+  if (!text) {
+    EventUtils.synthesizeKey("VK_DELETE", {}, win);
+  } else {
+    for (let c of text.split("")) {
+      EventUtils.synthesizeKey(c, {}, win);
+    }
   }
   if (blur)
     elt.blur();
 }
 
 /**
  * Executes a task after opening the bookmarks or history sidebar. Takes care
  * of closing the sidebar once done.
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -32,17 +32,16 @@ const PREF_DISABLED_PLUGIN_TYPES = "plug
 const PREF_CONTAINERS_EXTENSION = "privacy.userContext.extension";
 
 // Preferences that affect which entries to show in the list.
 const PREF_SHOW_PLUGINS_IN_LIST = "browser.download.show_plugins_in_list";
 const PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS =
   "browser.download.hide_plugins_without_extensions";
 
 // Strings to identify ExtensionSettingsStore overrides
-const PREF_SETTING_TYPE = "prefs";
 const CONTAINERS_KEY = "privacy.containers";
 const HOMEPAGE_OVERRIDE_KEY = "homepage_override";
 const URL_OVERRIDES_TYPE = "url_overrides";
 const NEW_TAB_KEY = "newTabURL";
 
 /*
  * Preferences where we store handling information about the feed type.
  *
--- a/browser/components/preferences/in-content/preferences.js
+++ b/browser/components/preferences/in-content/preferences.js
@@ -26,16 +26,19 @@ Cu.import("resource://gre/modules/AppCon
 
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionSettingsStore",
                                   "resource://gre/modules/ExtensionSettingsStore.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
                                   "resource://gre/modules/AddonManager.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "formAutofillParent",
                                   "resource://formautofill/FormAutofillParent.jsm");
 
+XPCOMUtils.defineLazyPreferenceGetter(this, "trackingprotectionUiEnabled",
+                                      "privacy.trackingprotection.ui.enabled");
+
 var gLastHash = "";
 
 var gCategoryInits = new Map();
 function init_category_if_required(category) {
   let categoryInfo = gCategoryInits.get(category);
   if (!categoryInfo) {
     throw "Unknown in-content prefs category! Can't init " + category;
   }
@@ -413,119 +416,147 @@ function appendSearchKeywords(aId, keywo
   let element = document.getElementById(aId);
   let searchKeywords = element.getAttribute("searchkeywords");
   if (searchKeywords) {
     keywords.push(searchKeywords);
   }
   element.setAttribute("searchkeywords", keywords.join(" "));
 }
 
+const PREF_SETTING_TYPE = "prefs";
+
 let extensionControlledContentIds = {
   "privacy.containers": "browserContainersExtensionContent",
   "homepage_override": "browserHomePageExtensionContent",
   "newTabURL": "browserNewTabExtensionContent",
   "defaultSearch": "browserDefaultSearchExtensionContent",
+  get "websites.trackingProtectionMode"() {
+    return {
+      button: "trackingProtectionExtensionContentButton",
+      section:
+        trackingprotectionUiEnabled ?
+          "trackingProtectionExtensionContentLabel" :
+          "trackingProtectionPBMExtensionContentLabel",
+    };
+  }
 };
 
 let extensionControlledIds = {};
 
 /**
   * Check if a pref is being managed by an extension.
   */
 async function getControllingExtensionInfo(type, settingName) {
   await ExtensionSettingsStore.initialize();
   return ExtensionSettingsStore.getSetting(type, settingName);
 }
 
-function getControllingExtensionEl(settingName) {
-  return document.getElementById(extensionControlledContentIds[settingName]);
+function getControllingExtensionEls(settingName) {
+  let idInfo = extensionControlledContentIds[settingName];
+  let section = document.getElementById(idInfo.section || idInfo);
+  let button = idInfo.button ?
+    document.getElementById(idInfo.button) :
+    section.querySelector("button");
+  return {
+    section,
+    button,
+    description: section.querySelector("description"),
+  };
 }
 
 async function handleControllingExtension(type, settingName) {
   let info = await getControllingExtensionInfo(type, settingName);
   let addon = info && info.id
     && await AddonManager.getAddonByID(info.id);
 
   // Sometimes the ExtensionSettingsStore gets in a bad state where it thinks
   // an extension is controlling a setting but the extension has been uninstalled
   // outside of the regular lifecycle. If the extension isn't currently installed
   // then we should treat the setting as not being controlled.
   // See https://bugzilla.mozilla.org/show_bug.cgi?id=1411046 for an example.
   if (addon) {
     extensionControlledIds[settingName] = info.id;
     showControllingExtension(settingName, addon);
   } else {
-    if (extensionControlledIds[settingName] && !document.hidden) {
+    let elements = getControllingExtensionEls(settingName);
+    if (extensionControlledIds[settingName]
+        && !document.hidden
+        && elements.button) {
       showEnableExtensionMessage(settingName);
     } else {
       hideControllingExtension(settingName);
     }
     delete extensionControlledIds[settingName];
   }
 
   return !!addon;
 }
 
 async function showControllingExtension(settingName, addon) {
   // Tell the user what extension is controlling the setting.
-  let extensionControlledContent = getControllingExtensionEl(settingName);
-  extensionControlledContent.classList.remove("extension-controlled-disabled");
+  let elements = getControllingExtensionEls(settingName);
+
+  elements.section.classList.remove("extension-controlled-disabled");
   const defaultIcon = "chrome://mozapps/skin/extensions/extensionGeneric.svg";
   let stringParts = document
     .getElementById("bundlePreferences")
     .getString(`extensionControlled.${settingName}`)
     .split("%S");
-  let description = extensionControlledContent.querySelector("description");
+  let description = elements.description;
 
   // Remove the old content from the description.
   while (description.firstChild) {
     description.firstChild.remove();
   }
 
   // Populate the description.
   description.appendChild(document.createTextNode(stringParts[0]));
   let image = document.createElement("image");
   image.setAttribute("src", addon.iconURL || defaultIcon);
   image.classList.add("extension-controlled-icon");
   description.appendChild(image);
   description.appendChild(document.createTextNode(` ${addon.name}`));
   description.appendChild(document.createTextNode(stringParts[1]));
 
-  let disableButton = extensionControlledContent.querySelector("button");
-  if (disableButton) {
-    disableButton.hidden = false;
+  if (elements.button) {
+    elements.button.hidden = false;
   }
 
   // Show the controlling extension row and hide the old label.
-  extensionControlledContent.hidden = false;
+  elements.section.hidden = false;
 }
 
 function hideControllingExtension(settingName) {
-  getControllingExtensionEl(settingName).hidden = true;
+  let elements = getControllingExtensionEls(settingName);
+  elements.section.hidden = true;
+  if (elements.button) {
+    elements.button.hidden = true;
+  }
 }
 
 function showEnableExtensionMessage(settingName) {
-  let extensionControlledContent = getControllingExtensionEl(settingName);
-  extensionControlledContent.classList.add("extension-controlled-disabled");
+  let elements = getControllingExtensionEls(settingName);
+
+  elements.button.hidden = true;
+  elements.section.classList.add("extension-controlled-disabled");
   let icon = url => `<image src="${url}" class="extension-controlled-icon"/>`;
   let addonIcon = icon("chrome://mozapps/skin/extensions/extensionGeneric-16.svg");
   let toolbarIcon = icon("chrome://browser/skin/menu.svg");
   let message = document
     .getElementById("bundlePreferences")
     .getFormattedString("extensionControlled.enable", [addonIcon, toolbarIcon]);
-  let description = extensionControlledContent.querySelector("description");
   // eslint-disable-next-line no-unsanitized/property
-  description.innerHTML = message;
+  elements.description.innerHTML = message;
   let dismissButton = document.createElement("image");
   dismissButton.setAttribute("class", "extension-controlled-icon close-icon");
   dismissButton.addEventListener("click", function dismissHandler() {
     hideControllingExtension(settingName);
     dismissButton.removeEventListener("click", dismissHandler);
   });
-  description.appendChild(dismissButton);
+  elements.description.appendChild(dismissButton);
 }
 
 function makeDisableControllingExtension(type, settingName) {
   return async function disableExtension() {
     let {id} = await getControllingExtensionInfo(type, settingName);
     let addon = await AddonManager.getAddonByID(id);
     addon.userDisabled = true;
   };
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -12,20 +12,27 @@ Components.utils.import("resource://gre/
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
   "resource://gre/modules/PluralForm.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
   "resource://gre/modules/LoginHelper.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "SiteDataManager",
   "resource:///modules/SiteDataManager.jsm");
 
+XPCOMUtils.defineLazyPreferenceGetter(this, "trackingprotectionUiEnabled",
+                                      "privacy.trackingprotection.ui.enabled");
+
 Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 const PREF_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
 
+const TRACKING_PROTECTION_KEY = "websites.trackingProtectionMode";
+const TRACKING_PROTECTION_PREFS = ["privacy.trackingprotection.enabled",
+                                   "privacy.trackingprotection.pbmode.enabled"];
+
 XPCOMUtils.defineLazyGetter(this, "AlertsServiceDND", function() {
   try {
     let alertsService = Cc["@mozilla.org/alerts-service;1"]
       .getService(Ci.nsIAlertsService)
       .QueryInterface(Ci.nsIAlertsDoNotDisturb);
     // This will throw if manualDoNotDisturb isn't implemented.
     alertsService.manualDoNotDisturb;
     return alertsService;
@@ -128,17 +135,17 @@ var gPrivacyPane = {
    */
   _shouldPromptForRestart: true,
 
   /**
    * Show the Tracking Protection UI depending on the
    * privacy.trackingprotection.ui.enabled pref, and linkify its Learn More link
    */
   _initTrackingProtection() {
-    if (!Services.prefs.getBoolPref("privacy.trackingprotection.ui.enabled")) {
+    if (!trackingprotectionUiEnabled) {
       return;
     }
 
     let link = document.getElementById("trackingProtectionLearnMore");
     let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "tracking-protection";
     link.setAttribute("href", url);
 
     this.trackingProtectionReadPrefs();
@@ -148,19 +155,81 @@ var gPrivacyPane = {
     document.getElementById("trackingProtectionPBMBox").hidden = true;
   },
 
   /**
    * Linkify the Learn More link of the Private Browsing Mode Tracking
    * Protection UI.
    */
   _initTrackingProtectionPBM() {
-    let link = document.getElementById("trackingProtectionPBMLearnMore");
+    if (trackingprotectionUiEnabled) {
+      return;
+    }
+
+    let link = document.getElementById("trackingProtectionLearnMore");
     let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "tracking-protection-pbm";
     link.setAttribute("href", url);
+
+    this._updateTrackingProtectionUI();
+  },
+
+  /**
+   * Update the tracking protection UI to deal with extension control.
+   */
+  _updateTrackingProtectionUI() {
+    let isLocked = TRACKING_PROTECTION_PREFS.some(
+      pref => Services.prefs.prefIsLocked(pref));
+
+    function setInputsDisabledState(isControlled) {
+      let disabled = isLocked || isControlled;
+      if (trackingprotectionUiEnabled) {
+        document.querySelectorAll("#trackingProtectionRadioGroup > radio")
+          .forEach((element) => {
+            element.disabled = disabled;
+          });
+        document.querySelector("#trackingProtectionDesc > label")
+          .disabled = disabled;
+      } else {
+        document.getElementById("trackingProtectionPBM").disabled = disabled;
+        document.getElementById("trackingProtectionPBMLabel")
+          .disabled = disabled;
+      }
+    }
+
+    if (isLocked) {
+      // An extension can't control this setting if either pref is locked.
+      hideControllingExtension(TRACKING_PROTECTION_KEY);
+      setInputsDisabledState(false);
+    } else {
+      handleControllingExtension(
+        PREF_SETTING_TYPE,
+        TRACKING_PROTECTION_KEY)
+          .then(setInputsDisabledState);
+    }
+  },
+
+  /**
+   * Set up handlers for showing and hiding controlling extension info
+   * for tracking protection.
+   */
+  _initTrackingProtectionExtensionControl() {
+    let trackingProtectionObserver = {
+      observe(subject, topic, data) {
+        gPrivacyPane._updateTrackingProtectionUI();
+      },
+    };
+
+    for (let pref of TRACKING_PROTECTION_PREFS) {
+      Services.prefs.addObserver(pref, trackingProtectionObserver);
+    }
+    window.addEventListener("unload", () => {
+      for (let pref of TRACKING_PROTECTION_PREFS) {
+        Services.prefs.removeObserver(pref, trackingProtectionObserver);
+      }
+    });
   },
 
   /**
    * Initialize autocomplete to ensure prefs are in sync.
    */
   _initAutocomplete() {
     Components.classes["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
       .getService(Components.interfaces.mozIPlacesAutoComplete);
@@ -178,16 +247,17 @@ var gPrivacyPane = {
 
     this._updateSanitizeSettingsButton();
     this.initializeHistoryMode();
     this.updateHistoryModePane();
     this.updatePrivacyMicroControls();
     this.initAutoStartPrivateBrowsingReverter();
     this._initTrackingProtection();
     this._initTrackingProtectionPBM();
+    this._initTrackingProtectionExtensionControl();
     this._initAutocomplete();
 
     Preferences.get("privacy.sanitize.sanitizeOnShutdown").on("change",
       gPrivacyPane._updateSanitizeSettingsButton.bind(gPrivacyPane));
     Preferences.get("browser.privatebrowsing.autostart").on("change",
       gPrivacyPane.updatePrivacyMicroControls.bind(gPrivacyPane));
     setEventListener("historyMode", "command", function() {
       gPrivacyPane.updateHistoryModePane();
@@ -222,16 +292,19 @@ var gPrivacyPane = {
     setEventListener("privateBrowsingAutoStart", "command",
       gPrivacyPane.updateAutostart);
     setEventListener("cookieExceptions", "command",
       gPrivacyPane.showCookieExceptions);
     setEventListener("showCookiesButton", "command",
       gPrivacyPane.showCookies);
     setEventListener("clearDataSettings", "command",
       gPrivacyPane.showClearPrivateDataSettings);
+    setEventListener("disableTrackingProtectionExtension", "command",
+      makeDisableControllingExtension(
+        PREF_SETTING_TYPE, TRACKING_PROTECTION_KEY));
     setEventListener("trackingProtectionRadioGroup", "command",
       gPrivacyPane.trackingProtectionWritePrefs);
     setEventListener("trackingProtectionExceptions", "command",
       gPrivacyPane.showTrackingProtectionExceptions);
     setEventListener("changeBlockList", "command",
       gPrivacyPane.showBlockLists);
     setEventListener("passwordExceptions", "command",
       gPrivacyPane.showPasswordExceptions);
@@ -414,16 +487,18 @@ var gPrivacyPane = {
   /**
    * Selects the right item of the Tracking Protection radiogroup.
    */
   trackingProtectionReadPrefs() {
     let enabledPref = Preferences.get("privacy.trackingprotection.enabled");
     let pbmPref = Preferences.get("privacy.trackingprotection.pbmode.enabled");
     let radiogroup = document.getElementById("trackingProtectionRadioGroup");
 
+    this._updateTrackingProtectionUI();
+
     // Global enable takes precedence over enabled in Private Browsing.
     if (enabledPref.value) {
       radiogroup.value = "always";
     } else if (pbmPref.value) {
       radiogroup.value = "private";
     } else {
       radiogroup.value = "never";
     }
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -318,51 +318,65 @@
 
 <!-- Tracking -->
 <groupbox id="trackingGroup" data-category="panePrivacy" hidden="true">
   <caption><label>&trackingProtectionHeader2.label;</label></caption>
   <vbox>
     <hbox align="start">
       <vbox flex="1">
         <description>
-          &trackingProtection2.description;
+          &trackingProtection3.description;
+          <label id="trackingProtectionLearnMore" class="learnMore text-link">&trackingProtectionLearnMore2.label;</label>
         </description>
       </vbox>
       <spacer flex="1"/>
     </hbox>
     <hbox>
       <vbox id="trackingProtectionBox" flex="1" hidden="true">
-        <description id="trackingProtectionDesc"
-                     control="trackingProtectionRadioGroup">
-           <label class="tail-with-learn-more">&trackingProtection2.radioGroupLabel;</label>
-           <label id="trackingProtectionLearnMore" class="learnMore text-link">&trackingProtectionLearnMore.label;</label>
-        </description>
-        <radiogroup id="trackingProtectionRadioGroup" aria-labelledby="trackingProtectionDesc">
-          <radio value="always"
-                 label="&trackingProtectionAlways.label;"
-                 accesskey="&trackingProtectionAlways.accesskey;"/>
-          <radio value="private"
-                 label="&trackingProtectionPrivate.label;"
-                 accesskey="&trackingProtectionPrivate.accesskey;"/>
-          <radio value="never"
-                 label="&trackingProtectionNever.label;"
-                 accesskey="&trackingProtectionNever.accesskey;"/>
-        </radiogroup>
+        <vbox>
+          <hbox id="trackingProtectionExtensionContentLabel" align="center" hidden="true">
+            <description control="disableTrackingProtectionExtension" flex="1"/>
+          </hbox>
+          <vbox>
+            <description id="trackingProtectionDesc"
+                         control="trackingProtectionRadioGroup">
+               <label>&trackingProtection3.radioGroupLabel;</label>
+            </description>
+            <radiogroup id="trackingProtectionRadioGroup" aria-labelledby="trackingProtectionDesc">
+              <radio value="always"
+                     label="&trackingProtectionAlways.label;"
+                     accesskey="&trackingProtectionAlways.accesskey;"/>
+              <radio value="private"
+                     label="&trackingProtectionPrivate.label;"
+                     accesskey="&trackingProtectionPrivate.accesskey;"/>
+              <radio value="never"
+                     label="&trackingProtectionNever.label;"
+                     accesskey="&trackingProtectionNever.accesskey;"/>
+            </radiogroup>
+          </vbox>
+        </vbox>
       </vbox>
       <vbox id="trackingProtectionPBMBox" flex="1">
-        <hbox align="center">
+        <hbox id="trackingProtectionPBMExtensionContentLabel" align="center" hidden="true">
+          <description control="disableTrackingProtectionExtension" flex="1"/>
+        </hbox>
+        <hbox align="start">
           <checkbox id="trackingProtectionPBM"
                     preference="privacy.trackingprotection.pbmode.enabled"
                     accesskey="&trackingProtectionPBM6.accesskey;"/>
-          <label flex="1">&trackingProtectionPBM6.label;<spacer class="tail-with-learn-more" /><label id="trackingProtectionPBMLearnMore"
-                 class="learnMore text-link">&trackingProtectionPBMLearnMore.label;</label>
-          </label>
+          <label id="trackingProtectionPBMLabel" flex="1">&trackingProtectionPBM6.label;</label>
         </hbox>
       </vbox>
       <vbox id="trackingProtectionAdvancedSettings">
+        <hbox id="trackingProtectionExtensionContentButton" hidden="true">
+          <button id="disableTrackingProtectionExtension"
+                  class="extension-controlled-button accessory-button"
+                  flex="1"
+                  label="&disableExtension.label;"/>
+        </hbox>
         <!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
         <hbox>
           <button id="trackingProtectionExceptions"
                   class="accessory-button"
                   flex="1"
                   hidden="true"
                   label="&trackingProtectionExceptions.label;"
                   accesskey="&trackingProtectionExceptions.accesskey;"
--- a/browser/components/preferences/in-content/tests/browser_basic_rebuild_fonts_test.js
+++ b/browser/components/preferences/in-content/tests/browser_basic_rebuild_fonts_test.js
@@ -12,20 +12,70 @@ add_task(async function() {
   let doc = gBrowser.contentDocument;
   // eslint-disable-next-line mozilla/no-cpows-in-tests
   let contentWindow = gBrowser.contentWindow;
   var langGroup = Services.prefs.getComplexValue("font.language.group", Ci.nsIPrefLocalizedString).data;
   is(contentWindow.Preferences.get("font.language.group").value, langGroup,
      "Language group should be set correctly.");
 
   let defaultFontType = Services.prefs.getCharPref("font.default." + langGroup);
-  let fontFamily = Services.prefs.getCharPref("font.name." + defaultFontType + "." + langGroup);
+  let fontFamilyPref = "font.name." + defaultFontType + "." + langGroup;
+  let fontFamily = Services.prefs.getCharPref(fontFamilyPref);
   let fontFamilyField = doc.getElementById("defaultFont");
   is(fontFamilyField.value, fontFamily, "Font family should be set correctly.");
 
+  function dispatchMenuItemCommand(menuItem) {
+    const cmdEvent = doc.createEvent("xulcommandevent");
+    cmdEvent.initCommandEvent("command", true, true, contentWindow, 0, false, false, false, false, null, 0);
+    menuItem.dispatchEvent(cmdEvent);
+  }
+
+  /**
+   * Return a promise that resolves when the fontFamilyPref changes.
+   *
+   * Font prefs are the only ones whose form controls set "delayprefsave",
+   * which delays the pref change when a user specifies a new value
+   * for the pref.  Thus, in order to confirm that the pref gets changed
+   * when the test selects a new value in a font field, we need to await
+   * the change.  Awaiting this function does so for fontFamilyPref.
+   */
+  function fontFamilyPrefChanged() {
+    return new Promise(resolve => {
+      const observer = {
+        observe(aSubject, aTopic, aData) {
+          // Check for an exact match to avoid the ambiguity of nsIPrefBranch's
+          // prefix-matching algorithm for notifying pref observers.
+          if (aData == fontFamilyPref) {
+            Services.prefs.removeObserver(fontFamilyPref, observer);
+            resolve();
+          }
+        }
+      };
+      Services.prefs.addObserver(fontFamilyPref, observer);
+    });
+  }
+
+  const menuItems = fontFamilyField.querySelectorAll("menuitem");
+  ok(menuItems.length > 1, "There are multiple font menuitems.");
+  ok(menuItems[0].selected, "The first (default) font menuitem is selected.");
+
+  dispatchMenuItemCommand(menuItems[1]);
+  ok(menuItems[1].selected, "The second font menuitem is selected.");
+
+  await fontFamilyPrefChanged();
+  fontFamily = Services.prefs.getCharPref(fontFamilyPref);
+  is(fontFamilyField.value, fontFamily, "The font family has been updated.");
+
+  dispatchMenuItemCommand(menuItems[0]);
+  ok(menuItems[0].selected, "The first (default) font menuitem is selected again.");
+
+  await fontFamilyPrefChanged();
+  fontFamily = Services.prefs.getCharPref(fontFamilyPref);
+  is(fontFamilyField.value, fontFamily, "The font family has been updated.");
+
   let defaultFontSize = Services.prefs.getIntPref("font.size.variable." + langGroup);
   let fontSizeField = doc.getElementById("defaultFontSize");
   is(fontSizeField.value, defaultFontSize, "Font size should be set correctly.");
 
   let promiseSubDialogLoaded = promiseLoadSubDialog("chrome://browser/content/preferences/fonts.xul");
   doc.getElementById("advancedFonts").click();
   let win = await promiseSubDialogLoaded;
   doc = win.document;
--- a/browser/components/preferences/in-content/tests/browser_extension_controlled.js
+++ b/browser/components/preferences/in-content/tests/browser_extension_controlled.js
@@ -1,8 +1,10 @@
+/* eslint-env webextensions */
+
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionSettingsStore",
                                   "resource://gre/modules/ExtensionSettingsStore.jsm");
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
 const TEST_DIR = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
 const CHROME_URL_ROOT = TEST_DIR + "/";
@@ -462,8 +464,143 @@ add_task(async function testExtensionCon
 
   // Reload the ExtensionSettingsStore again so it clears the data we added.
   // Don't finalize the current store since it will write out the bad data.
   await ExtensionSettingsStore._reloadFile(false);
 
   is(ExtensionSettingsStore.getSetting("prefs", "homepage_override"), null,
      "The ExtensionSettingsStore is left empty.");
 });
+
+add_task(async function testExtensionControlledTrackingProtection() {
+  const TP_UI_PREF = "privacy.trackingprotection.ui.enabled";
+  const TP_PREF = "privacy.trackingprotection.enabled";
+  const TP_DEFAULT = false;
+  const EXTENSION_ID = "@set_tp";
+  const CONTROLLED_LABEL_ID = {
+    new: "trackingProtectionExtensionContentLabel",
+    old: "trackingProtectionPBMExtensionContentLabel"
+  };
+  const CONTROLLED_BUTTON_ID = "trackingProtectionExtensionContentButton";
+
+  let tpEnabledPref = () => Services.prefs.getBoolPref(TP_PREF);
+
+  await SpecialPowers.pushPrefEnv(
+    {"set": [[TP_PREF, TP_DEFAULT], [TP_UI_PREF, true]]});
+
+  function background() {
+    browser.privacy.websites.trackingProtectionMode.set({value: "always"});
+  }
+
+  function verifyState(isControlled) {
+    is(tpEnabledPref(), isControlled, "TP pref is set to the expected value.");
+
+    let controlledLabel = doc.getElementById(CONTROLLED_LABEL_ID[uiType]);
+
+    is(controlledLabel.hidden, !isControlled, "The extension controlled row's visibility is as expected.");
+    is(controlledButton.hidden, !isControlled, "The disable extension button's visibility is as expected.");
+    if (isControlled) {
+      let controlledDesc = controlledLabel.querySelector("description");
+      // There are two spaces before "set_tp" because it's " <image /> set_tp".
+      is(controlledDesc.textContent, "An extension,  set_tp, is controlling tracking protection.",
+         "The user is notified that an extension is controlling TP.");
+    }
+
+    if (uiType === "new") {
+      for (let element of doc.querySelectorAll("#trackingProtectionRadioGroup > radio")) {
+        is(element.disabled, isControlled, "TP controls are enabled.");
+      }
+      is(doc.querySelector("#trackingProtectionDesc > label").disabled,
+         isControlled,
+         "TP control label is enabled.");
+    } else {
+      is(doc.getElementById("trackingProtectionPBM").disabled,
+         isControlled,
+         "TP control is enabled.");
+      is(doc.getElementById("trackingProtectionPBMLabel").disabled,
+         isControlled,
+         "TP control label is enabled.");
+    }
+  }
+
+  async function disableViaClick() {
+    let labelId = CONTROLLED_LABEL_ID[uiType];
+    let controlledLabel = doc.getElementById(labelId);
+
+    let enableMessageShown = waitForEnableMessage(labelId);
+    doc.getElementById("disableTrackingProtectionExtension").click();
+    await enableMessageShown;
+
+    // The user is notified how to enable the extension.
+    let controlledDesc = controlledLabel.querySelector("description");
+    is(controlledDesc.textContent, "To enable the extension go to  Add-ons in the  menu.",
+       "The user is notified of how to enable the extension again");
+
+    // The user can dismiss the enable instructions.
+    let hidden = waitForMessageHidden(labelId);
+    controlledLabel.querySelector("image:last-of-type").click();
+    await hidden;
+  }
+
+  async function reEnableExtension(addon) {
+    let controlledMessageShown = waitForMessageShown(CONTROLLED_LABEL_ID[uiType]);
+    addon.userDisabled = false;
+    await controlledMessageShown;
+  }
+
+  let uiType = "new";
+
+  await openPreferencesViaOpenPreferencesAPI("panePrivacy", {leaveOpen: true});
+  // eslint-disable-next-line mozilla/no-cpows-in-tests
+  let doc = gBrowser.contentDocument;
+
+  is(gBrowser.currentURI.spec, "about:preferences#privacy",
+   "#privacy should be in the URI for about:preferences");
+
+  let controlledButton = doc.getElementById(CONTROLLED_BUTTON_ID);
+
+  verifyState(false);
+
+  // Install an extension that sets Tracking Protection.
+  let extension = ExtensionTestUtils.loadExtension({
+    useAddonManager: "permanent",
+    manifest: {
+      name: "set_tp",
+      applications: {gecko: {id: EXTENSION_ID}},
+      permissions: ["privacy"],
+    },
+    background,
+  });
+
+  let messageShown = waitForMessageShown(CONTROLLED_LABEL_ID[uiType]);
+  await extension.startup();
+  await messageShown;
+  let addon = await AddonManager.getAddonByID(EXTENSION_ID);
+
+  verifyState(true);
+
+  await disableViaClick();
+
+  verifyState(false);
+
+  // Switch to the "old" Tracking Protection UI.
+  uiType = "old";
+  Services.prefs.setBoolPref(TP_UI_PREF, false);
+
+  verifyState(false);
+
+  await reEnableExtension(addon);
+
+  verifyState(true);
+
+  await disableViaClick();
+
+  verifyState(false);
+
+  // Enable the extension so we get the UNINSTALL event, which is needed by
+  // ExtensionPreferencesManager to clean up properly.
+  // TODO: BUG 1408226
+  await reEnableExtension(addon);
+
+  await extension.unload();
+
+  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -1553,21 +1553,23 @@
             this.buttons.firstChild.remove();
           // Remove the trailing empty text node introduced by the binding's
           // content markup above.
           if (this.settingsButtonCompact.nextSibling)
             this.settingsButtonCompact.nextSibling.remove();
 
           let engines = this.engines;
           let oneOffCount = engines.length;
+          let collapsed = !oneOffCount ||
+                          (oneOffCount == 1 && engines[0].name == Services.search.currentEngine.name);
 
           // header is a xul:deck so collapsed doesn't work on it, see bug 589569.
-          this.header.hidden = this.buttons.collapsed = !oneOffCount;
+          this.header.hidden = this.buttons.collapsed = collapsed;
 
-          if (!oneOffCount)
+          if (collapsed)
             return;
 
           let panelWidth = parseInt(this.popup.clientWidth);
 
           // There's one weird thing to guard against: when layout pixels
           // aren't an integral multiple of device pixels, the last button
           // of each row sometimes gets pushed to the next row, depending on the
           // panel and button widths.
@@ -1986,16 +1988,18 @@
       </method>
 
       <method name="_handleKeyPress">
         <parameter name="event"/>
         <parameter name="numListItems"/>
         <parameter name="allowEmptySelection"/>
         <parameter name="textboxUserValue"/>
         <body><![CDATA[
+          if (this.compact && this.buttons.collapsed)
+            return false;
           if (event.keyCode == KeyEvent.DOM_VK_RIGHT &&
               this.selectedButton &&
               this.selectedButton.getAttribute("anonid") ==
                 "addengine-menu-button") {
             // If the add-engine overflow menu item is selected and the user
             // presses the right arrow key, open the submenu.  Unfortunately
             // handling the left arrow key -- to close the popup -- isn't
             // straightforward.  Once the popup is open, it consumes all key
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -3893,21 +3893,17 @@ var SessionStoreInternal = {
       uri = loadArguments.uri;
       if (loadArguments.userContextId) {
         browser.setAttribute("usercontextid", loadArguments.userContextId);
       }
     }
 
     this.markTabAsRestoring(aTab);
 
-    // We need a new frameloader if we are reloading into a browser with a
-    // grouped session history (as we don't support restoring into browsers
-    // with grouped session histories directly).
-    let newFrameloader =
-      aOptions.newFrameloader || !!browser.frameLoader.groupedSHistory;
+    let newFrameloader = aOptions.newFrameloader;
 
     let isRemotenessUpdate;
     if (aOptions.remoteType !== undefined) {
       // We already have a selected remote type so we update to that.
       isRemotenessUpdate =
         tabbrowser.updateBrowserRemoteness(browser, !!aOptions.remoteType,
                                            { remoteType: aOptions.remoteType,
                                              newFrameloader });
--- a/browser/components/sessionstore/content/content-sessionStore.js
+++ b/browser/components/sessionstore/content/content-sessionStore.js
@@ -228,26 +228,17 @@ var MessageListener = {
         break;
       case "SessionStore:resetRestore":
         gContentRestore.resetRestore();
         break;
       case "SessionStore:flush":
         this.flush(data);
         break;
       case "SessionStore:becomeActiveProcess":
-        let shistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
-        // Check if we are at the end of the current session history, if we are,
-        // it is safe for us to collect and transmit our session history, so
-        // transmit all of it. Otherwise, we only want to transmit our index changes,
-        // so collect from kLastIndex.
-        if (shistory.globalCount - shistory.globalIndexOffset == shistory.count) {
-          SessionHistoryListener.collect();
-        } else {
-          SessionHistoryListener.collectFrom(kLastIndex);
-        }
+        SessionHistoryListener.collect();
         break;
       default:
         debug("received unknown message '" + name + "'");
         break;
     }
   },
 
   restoreHistory({epoch, tabData, loadArguments, isRemotenessUpdate}) {
--- a/browser/components/sessionstore/test/browser.ini
+++ b/browser/components/sessionstore/test/browser.ini
@@ -253,18 +253,16 @@ skip-if = os == "linux" && !debug
 run-if = e10s
 [browser_background_tab_crash.js]
 run-if = e10s && crashreporter
 
 # Disabled on debug for frequent intermittent failures:
 [browser_undoCloseById.js]
 skip-if = debug
 [browser_docshell_uuid_consistency.js]
-[browser_grouped_session_store.js]
-skip-if = !e10s # GroupedSHistory is e10s-only
 
 [browser_closed_objects_changed_notifications_tabs.js]
 [browser_closed_objects_changed_notifications_windows.js]
 [browser_duplicate_history.js]
 [browser_tabicon_after_bg_tab_crash.js]
 skip-if = !crashreporter || !e10s # Tabs can't crash without e10s
 
 [browser_cookies.js]
deleted file mode 100644
--- a/browser/components/sessionstore/test/browser_grouped_session_store.js
+++ /dev/null
@@ -1,143 +0,0 @@
-add_task(async function() {
-  const URIs = [
-    "data:text/html,1",
-    "data:text/html,2",
-    "data:text/html,3",
-    "data:text/html,4",
-    "data:text/html,5",
-  ];
-
-  const {TabStateCache} = Cu.import("resource:///modules/sessionstore/TabStateCache.jsm", {});
-  const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
-
-  await SpecialPowers.pushPrefEnv({
-    set: [["browser.groupedhistory.enabled", true]]
-  });
-
-  // Check that the data stored in the TabStateCache is correct for the current state.
-  async function validate(browser, length, index) {
-    await TabStateFlusher.flush(browser);
-    let {history} = TabStateCache.get(browser);
-    is(history.entries.length, length, "Lengths match");
-    for (let i = 0; i < length; ++i) {
-      is(history.entries[i].url, URIs[i], "URI at index " + i + " matches");
-    }
-    is(history.index, index, "Index matches");
-    await ContentTask.spawn(browser, [index, length], async function([expectedIndex, expectedLength]) {
-      let webNav = content.window.QueryInterface(Ci.nsIInterfaceRequestor)
-            .getInterface(Ci.nsIWebNavigation);
-      is(webNav.sessionHistory.globalIndexOffset + webNav.sessionHistory.index,
-         expectedIndex - 1, "In content index matches");
-      is(webNav.canGoForward, expectedIndex < expectedLength, "canGoForward is correct");
-      is(webNav.canGoBack, expectedIndex > 1, "canGoBack is correct");
-    });
-  }
-
-  // Wait for a process change, followed by a locationchange event, and then
-  // fulfil the promise.
-  function awaitProcessChange(browser) {
-    return new Promise(resolve => {
-      let locChangeListener = {
-        onLocationChange: () => {
-          gBrowser.removeProgressListener(locChangeListener);
-          resolve();
-        },
-      };
-
-      browser.addEventListener("BrowserChangedProcess", function(e) {
-        gBrowser.addProgressListener(locChangeListener);
-      }, {once: true});
-    });
-  }
-
-  // Order of events:
-  // Load [0], load [1], prerender [2], load [2], load [3]
-  // Back [2], Back [1], Forward [2], Back [0], Forward [3]
-  // Prerender [4], Back [0], Forward [2], Load [3'], Back [0].
-  await BrowserTestUtils.withNewTab({ gBrowser, url: URIs[0] }, async function(browser1) {
-    await validate(browser1, 1, 1);
-
-    browser1.loadURI(URIs[1], null, null);
-    await BrowserTestUtils.browserLoaded(browser1);
-    await validate(browser1, 2, 2);
-
-    // Create a new hidden prerendered tab to swap to.
-    let tab2 = gBrowser.loadOneTab(URIs[2], {
-      referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
-      allowThirdPartyFixup: true,
-      relatedToCurrent: true,
-      isPrerendered: true,
-      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
-    });
-    await BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
-    browser1.frameLoader.appendPartialSHistoryAndSwap(tab2.linkedBrowser.frameLoader);
-    await awaitProcessChange(browser1);
-    await validate(browser1, 3, 3);
-
-    browser1.loadURI(URIs[3], null, null);
-    await BrowserTestUtils.browserLoaded(browser1);
-    await validate(browser1, 4, 4);
-
-    // In process navigate back.
-    let p = BrowserTestUtils.waitForContentEvent(browser1, "pageshow");
-    browser1.goBack();
-    await p;
-    await validate(browser1, 4, 3);
-
-    // Cross process navigate back.
-    browser1.goBack();
-    await awaitProcessChange(browser1);
-    await validate(browser1, 4, 2);
-
-    // Cross process navigate forward.
-    browser1.goForward();
-    await awaitProcessChange(browser1);
-    await validate(browser1, 4, 3);
-
-    // Navigate across process to a page which was not recently loaded.
-    browser1.gotoIndex(0);
-    await awaitProcessChange(browser1);
-    await validate(browser1, 4, 1);
-
-    // Navigate across process to a page which was not recently loaded in the other direction.
-    browser1.gotoIndex(3);
-    await awaitProcessChange(browser1);
-    await validate(browser1, 4, 4);
-
-    // Create a new hidden prerendered tab to swap to
-    let tab3 = gBrowser.loadOneTab(URIs[4], {
-      referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
-      allowThirdPartyFixup: true,
-      relatedToCurrent: true,
-      isPrerendered: true,
-      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
-    });
-    await BrowserTestUtils.browserLoaded(tab3.linkedBrowser);
-    browser1.frameLoader.appendPartialSHistoryAndSwap(tab3.linkedBrowser.frameLoader);
-    await awaitProcessChange(browser1);
-    await validate(browser1, 5, 5);
-
-    browser1.gotoIndex(0);
-    await awaitProcessChange(browser1);
-    await validate(browser1, 5, 1);
-
-    browser1.gotoIndex(2);
-    await awaitProcessChange(browser1);
-    await validate(browser1, 5, 3);
-
-    // Load a new page and make sure it throws out all of the following entries.
-    URIs[3] = "data:text/html,NEW";
-    browser1.loadURI(URIs[3]);
-    await BrowserTestUtils.browserLoaded(browser1);
-    await validate(browser1, 4, 4);
-
-    browser1.gotoIndex(0);
-    await awaitProcessChange(browser1);
-    await validate(browser1, 4, 1);
-
-    // XXX: This will be removed automatically by the owning tab closing in the
-    // future, but this is not supported yet.
-    gBrowser.removeTab(tab2);
-    gBrowser.removeTab(tab3);
-  });
-});
--- a/browser/config/mozconfigs/linux32/debug-asan
+++ b/browser/config/mozconfigs/linux32/debug-asan
@@ -5,17 +5,19 @@ ac_add_options --enable-optimize="-O1"
 
 . $topsrcdir/build/mozconfig.stylo
 
 # ASan specific options on Linux
 ac_add_options --enable-valgrind
 
 . $topsrcdir/build/unix/mozconfig.asan
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
+fi
 
 # Enable Telemetry
 export MOZ_TELEMETRY_REPORTING=1
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 # Need this to prevent name conflicts with the normal nightly build packages
--- a/browser/config/mozconfigs/linux32/nightly-asan
+++ b/browser/config/mozconfigs/linux32/nightly-asan
@@ -4,17 +4,19 @@ ac_add_options --enable-optimize="-O2 -g
 
 . $topsrcdir/build/mozconfig.stylo
 
 # ASan specific options on Linux
 ac_add_options --enable-valgrind
 
 . $topsrcdir/build/unix/mozconfig.asan
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
+fi
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 # Enable Telemetry
 export MOZ_TELEMETRY_REPORTING=1
 
 # Need this to prevent name conflicts with the normal nightly build packages
--- a/browser/config/mozconfigs/linux64/debug-asan
+++ b/browser/config/mozconfigs/linux64/debug-asan
@@ -5,17 +5,19 @@ ac_add_options --enable-optimize="-O1"
 
 . $topsrcdir/build/mozconfig.stylo
 
 # ASan specific options on Linux
 ac_add_options --enable-valgrind
 
 . $topsrcdir/build/unix/mozconfig.asan
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig
+fi
 
 # Enable Telemetry
 export MOZ_TELEMETRY_REPORTING=1
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 # Need this to prevent name conflicts with the normal nightly build packages
--- a/browser/config/mozconfigs/linux64/debug-searchfox-clang
+++ b/browser/config/mozconfigs/linux64/debug-searchfox-clang
@@ -14,11 +14,13 @@ export CC="$topsrcdir/clang/bin/clang"
 export CXX="$topsrcdir/clang/bin/clang++"
 
 # Add the static checker
 ac_add_options --enable-clang-plugin
 ac_add_options --enable-mozsearch-plugin
 
 . "$topsrcdir/build/unix/mozconfig.stdcxx"
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig
+fi
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/debug-static-analysis-clang
+++ b/browser/config/mozconfigs/linux64/debug-static-analysis-clang
@@ -13,11 +13,13 @@ ac_add_options --enable-dmd
 export CC="$topsrcdir/clang/bin/clang"
 export CXX="$topsrcdir/clang/bin/clang++"
 
 # Add the static checker
 ac_add_options --enable-clang-plugin
 
 . "$topsrcdir/build/unix/mozconfig.stdcxx"
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig
+fi
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/hazards
+++ b/browser/config/mozconfigs/linux64/hazards
@@ -35,11 +35,13 @@ ac_add_options --with-compiler-wrapper=$
 ac_add_options --without-ccache
 
 ac_add_options --disable-replace-malloc
 
 CFLAGS="$CFLAGS -Wno-attributes"
 CPPFLAGS="$CPPFLAGS -Wno-attributes"
 CXXFLAGS="$CXXFLAGS -Wno-attributes"
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig
+fi
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/nightly-asan
+++ b/browser/config/mozconfigs/linux64/nightly-asan
@@ -4,17 +4,19 @@ ac_add_options --enable-optimize="-O2 -g
 
 . $topsrcdir/build/mozconfig.stylo
 
 # ASan specific options on Linux
 ac_add_options --enable-valgrind
 
 . $topsrcdir/build/unix/mozconfig.asan
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig
+fi
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 # Need this to prevent name conflicts with the normal nightly build packages
 export MOZ_PKG_SPECIAL=asan
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/nightly-asan-reporter
+++ b/browser/config/mozconfigs/linux64/nightly-asan-reporter
@@ -6,14 +6,16 @@ ac_add_options --enable-optimize="-O2 -g
 
 # ASan specific options on Linux
 ac_add_options --enable-valgrind
 
 . $topsrcdir/build/unix/mozconfig.asan
 
 ac_add_options --enable-address-sanitizer-reporter
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig
+fi
 
 # Need this to prevent name conflicts with the normal nightly build packages
 export MOZ_PKG_SPECIAL=asan-reporter
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/nightly-fuzzing-asan
+++ b/browser/config/mozconfigs/linux64/nightly-fuzzing-asan
@@ -7,17 +7,19 @@ ac_add_options --enable-optimize="-O2 -g
 # ASan specific options on Linux
 ac_add_options --enable-valgrind
 
 . $topsrcdir/build/unix/mozconfig.fuzzing
 
 ac_add_options --enable-fuzzing
 unset MOZ_STDCXX_COMPAT
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig
+fi
 
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 # Need this to prevent name conflicts with the normal nightly build packages
 export MOZ_PKG_SPECIAL=asan
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/opt-static-analysis-clang
+++ b/browser/config/mozconfigs/linux64/opt-static-analysis-clang
@@ -12,11 +12,13 @@ ac_add_options --enable-dmd
 CC="$topsrcdir/clang/bin/clang"
 CXX="$topsrcdir/clang/bin/clang++"
 
 # Add the static checker
 ac_add_options --enable-clang-plugin
 
 . "$topsrcdir/build/unix/mozconfig.stdcxx"
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig
+fi
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/opt-tsan
+++ b/browser/config/mozconfigs/linux64/opt-tsan
@@ -1,8 +1,10 @@
 . $topsrcdir/build/unix/mozconfig.tsan
 
+if [ -f /etc/redhat-release ]; then
 export PKG_CONFIG_LIBDIR=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig
+fi
 
 # Need this to prevent name conflicts with the normal nightly build packages
 export MOZ_PKG_SPECIAL=tsan
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/extensions/activity-stream/common/Actions.jsm
+++ b/browser/extensions/activity-stream/common/Actions.jsm
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 this.MAIN_MESSAGE_TYPE = "ActivityStream:Main";
 this.CONTENT_MESSAGE_TYPE = "ActivityStream:Content";
+this.PRELOAD_MESSAGE_TYPE = "ActivityStream:PreloadedBrowser";
 this.UI_CODE = 1;
 this.BACKGROUND_PROCESS = 2;
 
 /**
  * globalImportContext - Are we in UI code (i.e. react, a dom) or some kind of background process?
  *                       Use this in action creators if you need different logic
  *                       for ui/background processes.
  */
@@ -151,16 +152,29 @@ function SendToContent(action, target) {
   return _RouteMessage(action, {
     from: MAIN_MESSAGE_TYPE,
     to: CONTENT_MESSAGE_TYPE,
     toTarget: target
   });
 }
 
 /**
+ * SendToPreloaded - Creates a message that will be sent to the preloaded tab.
+ *
+ * @param  {object} action Any redux action (required)
+ * @return {object} An action with added .meta properties
+ */
+function SendToPreloaded(action) {
+  return _RouteMessage(action, {
+    from: MAIN_MESSAGE_TYPE,
+    to: PRELOAD_MESSAGE_TYPE
+  });
+}
+
+/**
  * UserEvent - A telemetry ping indicating a user action. This should only
  *                   be sent from the UI during a user session.
  *
  * @param  {object} data Fields to include in the ping (source, etc.)
  * @return {object} An SendToMain action
  */
 function UserEvent(data) {
   return SendToMain({
@@ -224,16 +238,17 @@ this.actionTypes = actionTypes;
 this.actionCreators = {
   BroadcastToContent,
   UserEvent,
   UndesiredEvent,
   PerfEvent,
   ImpressionStats,
   SendToContent,
   SendToMain,
+  SendToPreloaded,
   SetPref
 };
 
 // These are helpers to test for certain kinds of actions
 this.actionUtils = {
   isSendToMain(action) {
     if (!action.meta) {
       return false;
@@ -253,16 +268,23 @@ this.actionUtils = {
     if (!action.meta) {
       return false;
     }
     if (action.meta.to === CONTENT_MESSAGE_TYPE && action.meta.toTarget) {
       return true;
     }
     return false;
   },
+  isSendToPreloaded(action) {
+    if (!action.meta) {
+      return false;
+    }
+    return action.meta.to === PRELOAD_MESSAGE_TYPE &&
+      action.meta.from === MAIN_MESSAGE_TYPE;
+  },
   isFromMain(action) {
     if (!action.meta) {
       return false;
     }
     return action.meta.from === MAIN_MESSAGE_TYPE &&
       action.meta.to === CONTENT_MESSAGE_TYPE;
   },
   getPortIdOfSender(action) {
@@ -274,10 +296,11 @@ this.actionUtils = {
 this.EXPORTED_SYMBOLS = [
   "actionTypes",
   "actionCreators",
   "actionUtils",
   "globalImportContext",
   "UI_CODE",
   "BACKGROUND_PROCESS",
   "MAIN_MESSAGE_TYPE",
-  "CONTENT_MESSAGE_TYPE"
+  "CONTENT_MESSAGE_TYPE",
+  "PRELOAD_MESSAGE_TYPE"
 ];
--- a/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
+++ b/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
@@ -60,45 +60,57 @@
 /******/ 	__webpack_require__.p = "";
 /******/
 /******/ 	// Load entry module and return exports
 /******/ 	return __webpack_require__(__webpack_require__.s = 10);
 /******/ })
 /************************************************************************/
 /******/ ([
 /* 0 */
-/***/ (function(module, exports, __webpack_require__) {
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
+/* unused harmony export MAIN_MESSAGE_TYPE */
+/* unused harmony export CONTENT_MESSAGE_TYPE */
+/* unused harmony export PRELOAD_MESSAGE_TYPE */
+/* unused harmony export UI_CODE */
+/* unused harmony export BACKGROUND_PROCESS */
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return actionCreators; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return actionUtils; });
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 var MAIN_MESSAGE_TYPE = "ActivityStream:Main";
 var CONTENT_MESSAGE_TYPE = "ActivityStream:Content";
+var PRELOAD_MESSAGE_TYPE = "ActivityStream:PreloadedBrowser";
 var UI_CODE = 1;
 var BACKGROUND_PROCESS = 2;
 
 /**
  * globalImportContext - Are we in UI code (i.e. react, a dom) or some kind of background process?
  *                       Use this in action creators if you need different logic
  *                       for ui/background processes.
  */
 
 const globalImportContext = typeof Window === "undefined" ? BACKGROUND_PROCESS : UI_CODE;
+/* unused harmony export globalImportContext */
+
 // Export for tests
 
-
 // Create an object that avoids accidental differing key/value pairs:
 // {
 //   INIT: "INIT",
 //   UNINIT: "UNINIT"
 // }
 const actionTypes = {};
+/* harmony export (immutable) */ __webpack_exports__["b"] = actionTypes;
+
+
 for (const type of ["BLOCK_URL", "BOOKMARK_URL", "DELETE_BOOKMARK_BY_ID", "DELETE_HISTORY_URL", "DELETE_HISTORY_URL_CONFIRM", "DIALOG_CANCEL", "DIALOG_OPEN", "DISABLE_ONBOARDING", "INIT", "MIGRATION_CANCEL", "MIGRATION_COMPLETED", "MIGRATION_START", "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_REHYDRATED", "NEW_TAB_STATE_REQUEST", "NEW_TAB_UNLOAD", "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "PAGE_PRERENDERED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_CHANGED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINKS_DELETED", "PLACES_LINK_BLOCKED", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "RICH_ICON_MISSING", "SAVE_SESSION_PERF_DATA", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_DISABLE", "SECTION_ENABLE", "SECTION_OPTIONS_CHANGED", "SECTION_REGISTER", "SECTION_UPDATE", "SECTION_UPDATE_CARD", "SETTINGS_CLOSE", "SETTINGS_OPEN", "SET_PREF", "SHOW_FIREFOX_ACCOUNTS", "SNIPPETS_BLOCKLIST_UPDATED", "SNIPPETS_DATA", "SNIPPETS_RESET", "SNIPPET_BLOCKED", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_EDIT", "TOP_SITES_INSERT", "TOP_SITES_PIN", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "UNINIT"]) {
   actionTypes[type] = type;
 }
 
 // Helper function for creating routed actions between content and main
 // Not intended to be used by consumers
 function _RouteMessage(action, options) {
   const meta = action.meta ? Object.assign({}, action.meta) : {};
@@ -160,16 +172,29 @@ function SendToContent(action, target) {
   return _RouteMessage(action, {
     from: MAIN_MESSAGE_TYPE,
     to: CONTENT_MESSAGE_TYPE,
     toTarget: target
   });
 }
 
 /**
+ * SendToPreloaded - Creates a message that will be sent to the preloaded tab.
+ *
+ * @param  {object} action Any redux action (required)
+ * @return {object} An action with added .meta properties
+ */
+function SendToPreloaded(action) {
+  return _RouteMessage(action, {
+    from: MAIN_MESSAGE_TYPE,
+    to: PRELOAD_MESSAGE_TYPE
+  });
+}
+
+/**
  * UserEvent - A telemetry ping indicating a user action. This should only
  *                   be sent from the UI during a user session.
  *
  * @param  {object} data Fields to include in the ping (source, etc.)
  * @return {object} An SendToMain action
  */
 function UserEvent(data) {
   return SendToMain({
@@ -231,16 +256,17 @@ function SetPref(name, value, importCont
 var actionCreators = {
   BroadcastToContent,
   UserEvent,
   UndesiredEvent,
   PerfEvent,
   ImpressionStats,
   SendToContent,
   SendToMain,
+  SendToPreloaded,
   SetPref
 };
 
 // These are helpers to test for certain kinds of actions
 
 var actionUtils = {
   isSendToMain(action) {
     if (!action.meta) {
@@ -261,37 +287,33 @@ var actionUtils = {
     if (!action.meta) {
       return false;
     }
     if (action.meta.to === CONTENT_MESSAGE_TYPE && action.meta.toTarget) {
       return true;
     }
     return false;
   },
+  isSendToPreloaded(action) {
+    if (!action.meta) {
+      return false;
+    }
+    return action.meta.to === PRELOAD_MESSAGE_TYPE && action.meta.from === MAIN_MESSAGE_TYPE;
+  },
   isFromMain(action) {
     if (!action.meta) {
       return false;
     }
     return action.meta.from === MAIN_MESSAGE_TYPE && action.meta.to === CONTENT_MESSAGE_TYPE;
   },
   getPortIdOfSender(action) {
     return action.meta && action.meta.fromTarget || null;
   },
   _RouteMessage
 };
-module.exports = {
-  actionTypes,
-  actionCreators,
-  actionUtils,
-  globalImportContext,
-  UI_CODE,
-  BACKGROUND_PROCESS,
-  MAIN_MESSAGE_TYPE,
-  CONTENT_MESSAGE_TYPE
-};
 
 /***/ }),
 /* 1 */
 /***/ (function(module, exports) {
 
 module.exports = React;
 
 /***/ }),
@@ -330,29 +352,73 @@ try {
 // We return undefined, instead of nothing here, so it's
 // easier to handle this case. if(!global) { ...}
 
 module.exports = g;
 
 
 /***/ }),
 /* 5 */
-/***/ (function(module, exports, __webpack_require__) {
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
+
+// EXTERNAL MODULE: ./system-addon/common/Actions.jsm
+var Actions = __webpack_require__(0);
+
+// CONCATENATED MODULE: ./system-addon/common/Dedupe.jsm
+class Dedupe {
+  constructor(createKey) {
+    this.createKey = createKey || this.defaultCreateKey;
+  }
+
+  defaultCreateKey(item) {
+    return item;
+  }
+
+  /**
+   * Dedupe any number of grouped elements favoring those from earlier groups.
+   *
+   * @param {Array} groups Contains an arbitrary number of arrays of elements.
+   * @returns {Array} A matching array of each provided group deduped.
+   */
+  group(...groups) {
+    const globalKeys = new Set();
+    const result = [];
+    for (const values of groups) {
+      const valueMap = new Map();
+      for (const value of values) {
+        const key = this.createKey(value);
+        if (!globalKeys.has(key) && !valueMap.has(key)) {
+          valueMap.set(key, value);
+        }
+      }
+      result.push(valueMap);
+      valueMap.forEach((value, key) => globalKeys.add(key));
+    }
+    return result.map(m => Array.from(m.values()));
+  }
+}
+// CONCATENATED MODULE: ./system-addon/common/Reducers.jsm
+/* unused harmony export insertPinned */
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return reducers; });
 /* 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/. */
 
 
-const { actionTypes: at } = __webpack_require__(0);
-const { Dedupe } = __webpack_require__(13);
+
 
 const TOP_SITES_DEFAULT_LENGTH = 6;
+/* harmony export (immutable) */ __webpack_exports__["a"] = TOP_SITES_DEFAULT_LENGTH;
+
 const TOP_SITES_SHOWMORE_LENGTH = 12;
+/* harmony export (immutable) */ __webpack_exports__["b"] = TOP_SITES_SHOWMORE_LENGTH;
+
+
 
 const dedupe = new Dedupe(site => site && site.url);
 
 const INITIAL_STATE = {
   App: {
     // Have we received real data from the app yet?
     initialized: false,
     // The version of the system-addon
@@ -377,20 +443,23 @@ const INITIAL_STATE = {
   },
   Dialog: {
     visible: false,
     data: {}
   },
   Sections: [],
   PreferencesPane: { visible: false }
 };
+/* unused harmony export INITIAL_STATE */
+
+
 
 function App(prevState = INITIAL_STATE.App, action) {
   switch (action.type) {
-    case at.INIT:
+    case Actions["b" /* actionTypes */].INIT:
       return Object.assign({}, prevState, action.data || {}, { initialized: true });
     default:
       return prevState;
   }
 }
 
 /**
  * insertPinned - Inserts pinned links in their specified slots
@@ -422,51 +491,52 @@ function insertPinned(links, pinned) {
     } else {
       newLinks.splice(index, 0, link);
     }
   });
 
   return newLinks;
 }
 
+
 function TopSites(prevState = INITIAL_STATE.TopSites, action) {
   let hasMatch;
   let newRows;
   switch (action.type) {
-    case at.TOP_SITES_UPDATED:
+    case Actions["b" /* actionTypes */].TOP_SITES_UPDATED:
       if (!action.data) {
         return prevState;
       }
       return Object.assign({}, prevState, { initialized: true, rows: action.data });
-    case at.TOP_SITES_EDIT:
+    case Actions["b" /* actionTypes */].TOP_SITES_EDIT:
       return Object.assign({}, prevState, { editForm: { visible: true, index: action.data.index } });
-    case at.TOP_SITES_CANCEL_EDIT:
+    case Actions["b" /* actionTypes */].TOP_SITES_CANCEL_EDIT:
       return Object.assign({}, prevState, { editForm: { visible: false } });
-    case at.SCREENSHOT_UPDATED:
+    case Actions["b" /* actionTypes */].SCREENSHOT_UPDATED:
       newRows = prevState.rows.map(row => {
         if (row && row.url === action.data.url) {
           hasMatch = true;
           return Object.assign({}, row, { screenshot: action.data.screenshot });
         }
         return row;
       });
       return hasMatch ? Object.assign({}, prevState, { rows: newRows }) : prevState;
-    case at.PLACES_BOOKMARK_ADDED:
+    case Actions["b" /* actionTypes */].PLACES_BOOKMARK_ADDED:
       if (!action.data) {
         return prevState;
       }
       newRows = prevState.rows.map(site => {
         if (site && site.url === action.data.url) {
           const { bookmarkGuid, bookmarkTitle, dateAdded } = action.data;
           return Object.assign({}, site, { bookmarkGuid, bookmarkTitle, bookmarkDateCreated: dateAdded });
         }
         return site;
       });
       return Object.assign({}, prevState, { rows: newRows });
-    case at.PLACES_BOOKMARK_REMOVED:
+    case Actions["b" /* actionTypes */].PLACES_BOOKMARK_REMOVED:
       if (!action.data) {
         return prevState;
       }
       newRows = prevState.rows.map(site => {
         if (site && site.url === action.data.url) {
           const newSite = Object.assign({}, site);
           delete newSite.bookmarkGuid;
           delete newSite.bookmarkTitle;
@@ -478,48 +548,48 @@ function TopSites(prevState = INITIAL_ST
       return Object.assign({}, prevState, { rows: newRows });
     default:
       return prevState;
   }
 }
 
 function Dialog(prevState = INITIAL_STATE.Dialog, action) {
   switch (action.type) {
-    case at.DIALOG_OPEN:
+    case Actions["b" /* actionTypes */].DIALOG_OPEN:
       return Object.assign({}, prevState, { visible: true, data: action.data });
-    case at.DIALOG_CANCEL:
+    case Actions["b" /* actionTypes */].DIALOG_CANCEL:
       return Object.assign({}, prevState, { visible: false });
-    case at.DELETE_HISTORY_URL:
+    case Actions["b" /* actionTypes */].DELETE_HISTORY_URL:
       return Object.assign({}, INITIAL_STATE.Dialog);
     default:
       return prevState;
   }
 }
 
 function Prefs(prevState = INITIAL_STATE.Prefs, action) {
   let newValues;
   switch (action.type) {
-    case at.PREFS_INITIAL_VALUES:
+    case Actions["b" /* actionTypes */].PREFS_INITIAL_VALUES:
       return Object.assign({}, prevState, { initialized: true, values: action.data });
-    case at.PREF_CHANGED:
+    case Actions["b" /* actionTypes */].PREF_CHANGED:
       newValues = Object.assign({}, prevState.values);
       newValues[action.data.name] = action.data.value;
       return Object.assign({}, prevState, { values: newValues });
     default:
       return prevState;
   }
 }
 
 function Sections(prevState = INITIAL_STATE.Sections, action) {
   let hasMatch;
   let newState;
   switch (action.type) {
-    case at.SECTION_DEREGISTER:
+    case Actions["b" /* actionTypes */].SECTION_DEREGISTER:
       return prevState.filter(section => section.id !== action.data);
-    case at.SECTION_REGISTER:
+    case Actions["b" /* actionTypes */].SECTION_REGISTER:
       // If section exists in prevState, update it
       newState = prevState.map(section => {
         if (section && section.id === action.data.id) {
           hasMatch = true;
           return Object.assign({}, section, action.data);
         }
         return section;
       });
@@ -542,17 +612,17 @@ function Sections(prevState = INITIAL_ST
           order = action.data.order !== undefined ? action.data.order : 0;
           index = 0;
         }
 
         const section = Object.assign({ title: "", rows: [], order, enabled: false }, action.data, { initialized });
         newState.splice(index, 0, section);
       }
       return newState;
-    case at.SECTION_UPDATE:
+    case Actions["b" /* actionTypes */].SECTION_UPDATE:
       newState = prevState.map(section => {
         if (section && section.id === action.data.id) {
           // If the action is updating rows, we should consider initialized to be true.
           // This can be overridden if initialized is defined in the action.data
           const initialized = action.data.rows ? { initialized: true } : {};
           return Object.assign({}, section, initialized, action.data);
         }
         return section;
@@ -574,30 +644,30 @@ function Sections(prevState = INITIAL_ST
             return Object.assign({}, section, { rows: dedupedRows });
           }
 
           return section;
         });
       });
 
       return newState;
-    case at.SECTION_UPDATE_CARD:
+    case Actions["b" /* actionTypes */].SECTION_UPDATE_CARD:
       return prevState.map(section => {
         if (section && section.id === action.data.id && section.rows) {
           const newRows = section.rows.map(card => {
             if (card.url === action.data.url) {
               return Object.assign({}, card, action.data.options);
             }
             return card;
           });
           return Object.assign({}, section, { rows: newRows });
         }
         return section;
       });
-    case at.PLACES_BOOKMARK_ADDED:
+    case Actions["b" /* actionTypes */].PLACES_BOOKMARK_ADDED:
       if (!action.data) {
         return prevState;
       }
       return prevState.map(section => Object.assign({}, section, {
         rows: section.rows.map(item => {
           // find the item within the rows that is attempted to be bookmarked
           if (item.url === action.data.url) {
             const { bookmarkGuid, bookmarkTitle, dateAdded } = action.data;
@@ -606,17 +676,17 @@ function Sections(prevState = INITIAL_ST
               bookmarkTitle,
               bookmarkDateCreated: dateAdded,
               type: "bookmark"
             });
           }
           return item;
         })
       }));
-    case at.PLACES_BOOKMARK_REMOVED:
+    case Actions["b" /* actionTypes */].PLACES_BOOKMARK_REMOVED:
       if (!action.data) {
         return prevState;
       }
       return prevState.map(section => Object.assign({}, section, {
         rows: section.rows.map(item => {
           // find the bookmark within the rows that is attempted to be removed
           if (item.url === action.data.url) {
             const newSite = Object.assign({}, item);
@@ -626,65 +696,57 @@ function Sections(prevState = INITIAL_ST
             if (!newSite.type || newSite.type === "bookmark") {
               newSite.type = "history";
             }
             return newSite;
           }
           return item;
         })
       }));
-    case at.PLACES_LINKS_DELETED:
+    case Actions["b" /* actionTypes */].PLACES_LINKS_DELETED:
       return prevState.map(section => Object.assign({}, section, { rows: section.rows.filter(site => !action.data.includes(site.url)) }));
-    case at.PLACES_LINK_BLOCKED:
+    case Actions["b" /* actionTypes */].PLACES_LINK_BLOCKED:
       return prevState.map(section => Object.assign({}, section, { rows: section.rows.filter(site => site.url !== action.data.url) }));
     default:
       return prevState;
   }
 }
 
 function Snippets(prevState = INITIAL_STATE.Snippets, action) {
   switch (action.type) {
-    case at.SNIPPETS_DATA:
+    case Actions["b" /* actionTypes */].SNIPPETS_DATA:
       return Object.assign({}, prevState, { initialized: true }, action.data);
-    case at.SNIPPETS_RESET:
+    case Actions["b" /* actionTypes */].SNIPPETS_RESET:
       return INITIAL_STATE.Snippets;
     default:
       return prevState;
   }
 }
 
 function PreferencesPane(prevState = INITIAL_STATE.PreferencesPane, action) {
   switch (action.type) {
-    case at.SETTINGS_OPEN:
+    case Actions["b" /* actionTypes */].SETTINGS_OPEN:
       return Object.assign({}, prevState, { visible: true });
-    case at.SETTINGS_CLOSE:
+    case Actions["b" /* actionTypes */].SETTINGS_CLOSE:
       return Object.assign({}, prevState, { visible: false });
     default:
       return prevState;
   }
 }
 
 var reducers = { TopSites, App, Snippets, Prefs, Dialog, Sections, PreferencesPane };
-module.exports = {
-  reducers,
-  INITIAL_STATE,
-  insertPinned,
-  TOP_SITES_DEFAULT_LENGTH,
-  TOP_SITES_SHOWMORE_LENGTH
-};
 
 /***/ }),
 /* 6 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 
 // EXTERNAL MODULE: ./system-addon/common/Actions.jsm
 var Actions = __webpack_require__(0);
-var Actions_default = /*#__PURE__*/__webpack_require__.n(Actions);
 
 // EXTERNAL MODULE: external "React"
 var external__React_ = __webpack_require__(1);
 var external__React__default = /*#__PURE__*/__webpack_require__.n(external__React_);
 
 // CONCATENATED MODULE: ./system-addon/content-src/components/ContextMenu/ContextMenu.jsx
 
 
@@ -778,115 +840,115 @@ var external__ReactIntl__default = /*#__
  * LinkMenu. All functions take the site as the first parameter, and optionally
  * the index of the site.
  */
 const LinkMenuOptions = {
   Separator: () => ({ type: "separator" }),
   RemoveBookmark: site => ({
     id: "menu_action_remove_bookmark",
     icon: "bookmark-added",
-    action: Actions["actionCreators"].SendToMain({
-      type: Actions["actionTypes"].DELETE_BOOKMARK_BY_ID,
+    action: Actions["a" /* actionCreators */].SendToMain({
+      type: Actions["b" /* actionTypes */].DELETE_BOOKMARK_BY_ID,
       data: site.bookmarkGuid
     }),
     userEvent: "BOOKMARK_DELETE"
   }),
   AddBookmark: site => ({
     id: "menu_action_bookmark",
     icon: "bookmark-hollow",
-    action: Actions["actionCreators"].SendToMain({
-      type: Actions["actionTypes"].BOOKMARK_URL,
+    action: Actions["a" /* actionCreators */].SendToMain({
+      type: Actions["b" /* actionTypes */].BOOKMARK_URL,
       data: { url: site.url, title: site.title, type: site.type }
     }),
     userEvent: "BOOKMARK_ADD"
   }),
   OpenInNewWindow: site => ({
     id: "menu_action_open_new_window",
     icon: "new-window",
-    action: Actions["actionCreators"].SendToMain({
-      type: Actions["actionTypes"].OPEN_NEW_WINDOW,
+    action: Actions["a" /* actionCreators */].SendToMain({
+      type: Actions["b" /* actionTypes */].OPEN_NEW_WINDOW,
       data: { url: site.url, referrer: site.referrer }
     }),
     userEvent: "OPEN_NEW_WINDOW"
   }),
   OpenInPrivateWindow: site => ({
     id: "menu_action_open_private_window",
     icon: "new-window-private",
-    action: Actions["actionCreators"].SendToMain({
-      type: Actions["actionTypes"].OPEN_PRIVATE_WINDOW,
+    action: Actions["a" /* actionCreators */].SendToMain({
+      type: Actions["b" /* actionTypes */].OPEN_PRIVATE_WINDOW,
       data: { url: site.url, referrer: site.referrer }
     }),
     userEvent: "OPEN_PRIVATE_WINDOW"
   }),
   BlockUrl: (site, index, eventSource) => ({
     id: "menu_action_dismiss",
     icon: "dismiss",
-    action: Actions["actionCreators"].SendToMain({
-      type: Actions["actionTypes"].BLOCK_URL,
+    action: Actions["a" /* actionCreators */].SendToMain({
+      type: Actions["b" /* actionTypes */].BLOCK_URL,
       data: site.url
     }),
-    impression: Actions["actionCreators"].ImpressionStats({
+    impression: Actions["a" /* actionCreators */].ImpressionStats({
       source: eventSource,
       block: 0,
       tiles: [{ id: site.guid, pos: index }]
     }),
     userEvent: "BLOCK"
   }),
   DeleteUrl: site => ({
     id: "menu_action_delete",
     icon: "delete",
     action: {
-      type: Actions["actionTypes"].DIALOG_OPEN,
+      type: Actions["b" /* actionTypes */].DIALOG_OPEN,
       data: {
-        onConfirm: [Actions["actionCreators"].SendToMain({ type: Actions["actionTypes"].DELETE_HISTORY_URL, data: { url: site.url, forceBlock: site.bookmarkGuid } }), Actions["actionCreators"].UserEvent({ event: "DELETE" })],
+        onConfirm: [Actions["a" /* actionCreators */].SendToMain({ type: Actions["b" /* actionTypes */].DELETE_HISTORY_URL, data: { url: site.url, forceBlock: site.bookmarkGuid } }), Actions["a" /* actionCreators */].UserEvent({ event: "DELETE" })],
         body_string_id: ["confirm_history_delete_p1", "confirm_history_delete_notice_p2"],
         confirm_button_string_id: "menu_action_delete",
         cancel_button_string_id: "topsites_form_cancel_button",
         icon: "modal-delete"
       }
     },
     userEvent: "DIALOG_OPEN"
   }),
   PinTopSite: (site, index) => ({
     id: "menu_action_pin",
     icon: "pin",
-    action: Actions["actionCreators"].SendToMain({
-      type: Actions["actionTypes"].TOP_SITES_PIN,
+    action: Actions["a" /* actionCreators */].SendToMain({
+      type: Actions["b" /* actionTypes */].TOP_SITES_PIN,
       data: { site: { url: site.url }, index }
     }),
     userEvent: "PIN"
   }),
   UnpinTopSite: site => ({
     id: "menu_action_unpin",
     icon: "unpin",
-    action: Actions["actionCreators"].SendToMain({
-      type: Actions["actionTypes"].TOP_SITES_UNPIN,
+    action: Actions["a" /* actionCreators */].SendToMain({
+      type: Actions["b" /* actionTypes */].TOP_SITES_UNPIN,
       data: { site: { url: site.url } }
     }),
     userEvent: "UNPIN"
   }),
   SaveToPocket: (site, index, eventSource) => ({
     id: "menu_action_save_to_pocket",
     icon: "pocket",
-    action: Actions["actionCreators"].SendToMain({
-      type: Actions["actionTypes"].SAVE_TO_POCKET,
+    action: Actions["a" /* actionCreators */].SendToMain({
+      type: Actions["b" /* actionTypes */].SAVE_TO_POCKET,
       data: { site: { url: site.url, title: site.title } }
     }),
-    impression: Actions["actionCreators"].ImpressionStats({
+    impression: Actions["a" /* actionCreators */].ImpressionStats({
       source: eventSource,
       pocket: 0,
       tiles: [{ id: site.guid, pos: index }]
     }),
     userEvent: "SAVE_TO_POCKET"
   }),
   EditTopSite: (site, index) => ({
     id: "edit_topsites_button_text",
     icon: "edit",
     action: {
-      type: Actions["actionTypes"].TOP_SITES_EDIT,
+      type: Actions["b" /* actionTypes */].TOP_SITES_EDIT,
       data: { index }
     }
   }),
   CheckBookmark: site => site.bookmarkGuid ? LinkMenuOptions.RemoveBookmark(site) : LinkMenuOptions.AddBookmark(site),
   CheckPinTopSite: (site, index) => site.isPinned ? LinkMenuOptions.UnpinTopSite(site) : LinkMenuOptions.PinTopSite(site, index)
 };
 // CONCATENATED MODULE: ./system-addon/content-src/components/LinkMenu/LinkMenu.jsx
 
@@ -907,17 +969,17 @@ class LinkMenu__LinkMenu extends externa
 
     const options = propOptions.map(o => LinkMenuOptions[o](site, index, source)).map(option => {
       const { action, impression, id, type, userEvent } = option;
       if (!type && id) {
         option.label = props.intl.formatMessage(option);
         option.onClick = () => {
           props.dispatch(action);
           if (userEvent) {
-            props.dispatch(Actions["actionCreators"].UserEvent({
+            props.dispatch(Actions["a" /* actionCreators */].UserEvent({
               event: userEvent,
               source,
               action_position: index
             }));
           }
           if (impression && props.shouldSendImpressionStats) {
             props.dispatch(impression);
           }
@@ -948,17 +1010,16 @@ const LinkMenu = Object(external__ReactI
 
 
 /***/ }),
 /* 7 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__ = __webpack_require__(0);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_react_intl__ = __webpack_require__(2);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_react_intl___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_react_intl__);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_react__ = __webpack_require__(1);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_react__);
 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
 
 
 
@@ -1002,18 +1063,18 @@ class Info extends __WEBPACK_IMPORTED_MO
   }
   onInfoLeave(event) {
     // We currently have an active (true) info state, so keep it true only if we
     // have a related event target that is contained "within" the current target
     // (section-info-option) as itself or a descendant. Set to false otherwise.
     this._setInfoState(event && event.relatedTarget && (event.relatedTarget === event.currentTarget || event.relatedTarget.compareDocumentPosition(event.currentTarget) & Node.DOCUMENT_POSITION_CONTAINS));
   }
   onManageClick() {
-    this.props.dispatch({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionTypes"].SETTINGS_OPEN });
-    this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionCreators"].UserEvent({ event: "OPEN_NEWTAB_PREFS" }));
+    this.props.dispatch({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SETTINGS_OPEN });
+    this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].UserEvent({ event: "OPEN_NEWTAB_PREFS" }));
   }
   render() {
     const { infoOption, intl } = this.props;
     const infoOptionIconA11yAttrs = {
       "aria-haspopup": "true",
       "aria-controls": "info-option",
       "aria-expanded": this.state.infoActive ? "true" : "false",
       "role": "note",
@@ -1070,18 +1131,18 @@ const InfoIntl = Object(__WEBPACK_IMPORT
 
 class Disclaimer extends __WEBPACK_IMPORTED_MODULE_2_react___default.a.PureComponent {
   constructor(props) {
     super(props);
     this.onAcknowledge = this.onAcknowledge.bind(this);
   }
 
   onAcknowledge() {
-    this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionCreators"].SetPref(this.props.disclaimerPref, false));
-    this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionCreators"].UserEvent({ event: "SECTION_DISCLAIMER_ACKNOWLEDGED", source: this.props.eventSource }));
+    this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SetPref(this.props.disclaimerPref, false));
+    this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].UserEvent({ event: "SECTION_DISCLAIMER_ACKNOWLEDGED", source: this.props.eventSource }));
   }
 
   render() {
     const disclaimer = this.props.disclaimer;
     return __WEBPACK_IMPORTED_MODULE_2_react___default.a.createElement(
       "div",
       { className: "section-disclaimer" },
       __WEBPACK_IMPORTED_MODULE_2_react___default.a.createElement(
@@ -1165,17 +1226,17 @@ class _CollapsibleSection extends __WEBP
     this._setInfoState(event && event.relatedTarget && (event.relatedTarget === event.currentTarget || event.relatedTarget.compareDocumentPosition(event.currentTarget) & Node.DOCUMENT_POSITION_CONTAINS));
   }
   onHeaderClick() {
     // Get the current height of the body so max-height transitions can work
     this.setState({
       isAnimating: true,
       maxHeight: `${this.sectionBody.scrollHeight}px`
     });
-    this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionCreators"].SetPref(this.props.prefName, !getCollapsed(this.props)));
+    this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SetPref(this.props.prefName, !getCollapsed(this.props)));
   }
   onTransitionEnd(event) {
     // Only update the animating state for our own transition (not a child's)
     if (event.target === event.currentTarget) {
       this.setState({ isAnimating: false });
     }
   }
   renderIcon() {
@@ -1242,34 +1303,32 @@ const CollapsibleSection = Object(__WEBP
 /* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(4)))
 
 /***/ }),
 /* 8 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__ = __webpack_require__(0);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_common_PerfService_jsm__ = __webpack_require__(9);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_common_PerfService_jsm___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_common_PerfService_jsm__);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_react__ = __webpack_require__(1);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_react__);
 
 
 
 
 // Currently record only a fixed set of sections. This will prevent data
 // from custom sections from showing up or from topstories.
 const RECORDED_SECTIONS = ["highlights", "topsites"];
 
 class ComponentPerfTimer extends __WEBPACK_IMPORTED_MODULE_2_react___default.a.Component {
   constructor(props) {
     super(props);
     // Just for test dependency injection:
-    this.perfSvc = this.props.perfSvc || __WEBPACK_IMPORTED_MODULE_1_common_PerfService_jsm__["perfService"];
+    this.perfSvc = this.props.perfSvc || __WEBPACK_IMPORTED_MODULE_1_common_PerfService_jsm__["a" /* perfService */];
 
     this._sendBadStateEvent = this._sendBadStateEvent.bind(this);
     this._sendPaintedEvent = this._sendPaintedEvent.bind(this);
     this._reportMissingData = false;
     this._timestampHandled = false;
     this._recordedFirstRender = false;
   }
 
@@ -1365,18 +1424,18 @@ class ComponentPerfTimer extends __WEBPA
     // highlights_data_ready_ts, topsites_data_ready_ts.
     const dataReadyKey = `${this.props.id}_data_ready_ts`;
     this.perfSvc.mark(dataReadyKey);
 
     try {
       const firstRenderKey = `${this.props.id}_first_render_ts`;
       // value has to be Int32.
       const value = parseInt(this.perfSvc.getMostRecentAbsMarkStartByName(dataReadyKey) - this.perfSvc.getMostRecentAbsMarkStartByName(firstRenderKey), 10);
-      this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionCreators"].SendToMain({
-        type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionTypes"].SAVE_SESSION_PERF_DATA,
+      this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({
+        type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SAVE_SESSION_PERF_DATA,
         // highlights_data_late_by_ms, topsites_data_late_by_ms.
         data: { [`${this.props.id}_data_late_by_ms`]: value }
       }));
     } catch (ex) {
       // If this failed, it's likely because the `privacy.resistFingerprinting`
       // pref is true.
     }
   }
@@ -1390,18 +1449,18 @@ class ComponentPerfTimer extends __WEBPA
     // topsites_first_painted_ts.
     const key = `${this.props.id}_first_painted_ts`;
     this.perfSvc.mark(key);
 
     try {
       const data = {};
       data[key] = this.perfSvc.getMostRecentAbsMarkStartByName(key);
 
-      this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionCreators"].SendToMain({
-        type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionTypes"].SAVE_SESSION_PERF_DATA,
+      this.props.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({
+        type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SAVE_SESSION_PERF_DATA,
         data
       }));
     } catch (ex) {
       // If this failed, it's likely because the `privacy.resistFingerprinting`
       // pref is true.  We should at least not blow up, and should continue
       // to set this._timestampHandled to avoid going through this again.
     }
   }
@@ -1414,19 +1473,21 @@ class ComponentPerfTimer extends __WEBPA
     return this.props.children;
   }
 }
 /* harmony export (immutable) */ __webpack_exports__["a"] = ComponentPerfTimer;
 
 
 /***/ }),
 /* 9 */
-/***/ (function(module, exports, __webpack_require__) {
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
+/* unused harmony export _PerfService */
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return perfService; });
 /* globals Services */
 
 
 /* istanbul ignore if */
 // Note: normally we would just feature detect Components.utils here, but
 // unfortunately that throws an ugly warning in content if we do.
 
 if (typeof Window === "undefined" && typeof Components !== "undefined" && Components.utils) {
@@ -1448,25 +1509,26 @@ if (typeof Services !== "undefined") {
   // This is a dummy object so this file doesn't crash in the node prerendering
   // task.
   usablePerfObj = {
     now() {},
     mark() {}
   };
 }
 
-var _PerfService = function _PerfService(options) {
+function _PerfService(options) {
   // For testing, so that we can use a fake Window.performance object with
   // known state.
   if (options && options.performanceObj) {
     this._perf = options.performanceObj;
   } else {
     this._perf = usablePerfObj;
   }
-};
+}
+
 
 _PerfService.prototype = {
   /**
    * Calls the underlying mark() method on the appropriate Window.performance
    * object to add a mark with the given name to the appropriate performance
    * timeline.
    *
    * @param  {String} name  the name to give the current mark
@@ -1544,60 +1606,54 @@ var _PerfService = function _PerfService
     }
 
     let mostRecentEntry = entries[entries.length - 1];
     return this._perf.timeOrigin + mostRecentEntry.startTime;
   }
 };
 
 var perfService = new _PerfService();
-module.exports = {
-  _PerfService,
-  perfService
-};
 
 /***/ }),
 /* 10 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__ = __webpack_require__(0);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_content_src_lib_snippets__ = __webpack_require__(11);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_content_src_components_Base_Base__ = __webpack_require__(12);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_content_src_lib_detect_user_session_start__ = __webpack_require__(19);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_content_src_lib_init_store__ = __webpack_require__(20);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_content_src_lib_detect_user_session_start__ = __webpack_require__(17);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_content_src_lib_init_store__ = __webpack_require__(18);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_react_redux__ = __webpack_require__(3);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_react_redux___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react_redux__);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_react__ = __webpack_require__(1);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_react__);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_react_dom__ = __webpack_require__(22);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_react_dom__ = __webpack_require__(20);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_react_dom___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_react_dom__);
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_common_Reducers_jsm__ = __webpack_require__(5);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8_common_Reducers_jsm___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_common_Reducers_jsm__);
-
-
-
-
-
-
-
-
-
-
-const store = Object(__WEBPACK_IMPORTED_MODULE_4_content_src_lib_init_store__["a" /* initStore */])(__WEBPACK_IMPORTED_MODULE_8_common_Reducers_jsm__["reducers"], global.gActivityStreamPrerenderedState);
+
+
+
+
+
+
+
+
+
+
+const store = Object(__WEBPACK_IMPORTED_MODULE_4_content_src_lib_init_store__["a" /* initStore */])(__WEBPACK_IMPORTED_MODULE_8_common_Reducers_jsm__["c" /* reducers */], global.gActivityStreamPrerenderedState);
 
 new __WEBPACK_IMPORTED_MODULE_3_content_src_lib_detect_user_session_start__["a" /* DetectUserSessionStart */](store).sendEventOrAddListener();
 
 // If we are starting in a prerendered state, we must wait until the first render
 // to request state rehydration (see Base.jsx). If we are NOT in a prerendered state,
 // we can request it immedately.
 if (!global.gActivityStreamPrerenderedState) {
-  store.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionCreators"].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionTypes"].NEW_TAB_STATE_REQUEST }));
+  store.dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].NEW_TAB_STATE_REQUEST }));
 }
 
 __WEBPACK_IMPORTED_MODULE_7_react_dom___default.a.render(__WEBPACK_IMPORTED_MODULE_6_react___default.a.createElement(
   __WEBPACK_IMPORTED_MODULE_5_react_redux__["Provider"],
   { store: store },
   __WEBPACK_IMPORTED_MODULE_6_react___default.a.createElement(__WEBPACK_IMPORTED_MODULE_2_content_src_components_Base_Base__["a" /* Base */], {
     isPrerendered: !!global.gActivityStreamPrerenderedState,
     locale: global.document.documentElement.lang,
@@ -1609,17 +1665,16 @@ Object(__WEBPACK_IMPORTED_MODULE_1_conte
 
 /***/ }),
 /* 11 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (immutable) */ __webpack_exports__["a"] = addSnippetsSubscriber;
 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__ = __webpack_require__(0);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__);
 const DATABASE_NAME = "snippets_db";
 const DATABASE_VERSION = 1;
 const SNIPPETS_OBJECTSTORE_NAME = "snippets";
 const SNIPPETS_UPDATE_INTERVAL_MS = 14400000;
 /* unused harmony export SNIPPETS_UPDATE_INTERVAL_MS */
  // 4 hours.
 
 const SNIPPETS_ENABLED_EVENT = "Snippets:Enabled";
@@ -1670,27 +1725,27 @@ class SnippetsMap extends Map {
    */
   async blockSnippetById(id) {
     if (!id) {
       return;
     }
     let blockList = this.blockList;
     if (!blockList.includes(id)) {
       blockList.push(id);
-      this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionCreators"].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionTypes"].SNIPPETS_BLOCKLIST_UPDATED, data: blockList }));
+      this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SNIPPETS_BLOCKLIST_UPDATED, data: blockList }));
       await this.set("blockList", blockList);
     }
   }
 
   disableOnboarding() {
-    this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionCreators"].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionTypes"].DISABLE_ONBOARDING }));
+    this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].DISABLE_ONBOARDING }));
   }
 
   showFirefoxAccounts() {
-    this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionCreators"].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionTypes"].SHOW_FIREFOX_ACCOUNTS }));
+    this._dispatch(__WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["a" /* actionCreators */].SendToMain({ type: __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SHOW_FIREFOX_ACCOUNTS }));
   }
 
   /**
    * connect - Attaches an indexedDB back-end to the Map so that any set values
    *           are also cached in a store. It also restores any existing values
    *           that are already stored in the indexedDB store.
    *
    * @return {type}  description
@@ -1876,17 +1931,17 @@ class SnippetsProvider {
     for (const scriptEl of snippetsEl.getElementsByTagName("script")) {
       const relocatedScript = document.createElement("script");
       relocatedScript.text = scriptEl.text;
       scriptEl.parentNode.replaceChild(relocatedScript, scriptEl);
     }
   }
 
   _onAction(msg) {
-    if (msg.data.type === __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["actionTypes"].SNIPPET_BLOCKED) {
+    if (msg.data.type === __WEBPACK_IMPORTED_MODULE_0_common_Actions_jsm__["b" /* actionTypes */].SNIPPET_BLOCKED) {
       this.snippetsMap.set("blockList", msg.data.data);
       document.getElementById("snippets-container").style.display = "none";
     }
   }
 
   /**
    * init - Fetch the snippet payload and show snippets
    *
@@ -1988,17 +2043,16 @@ function addSnippetsSubscriber(store) {
 /***/ }),
 /* 12 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 
 // EXTERNAL MODULE: ./system-addon/common/Actions.jsm
 var Actions = __webpack_require__(0);
-var Actions_default = /*#__PURE__*/__webpack_require__.n(Actions);
 
 // EXTERNAL MODULE: external "ReactIntl"
 var external__ReactIntl_ = __webpack_require__(2);
 var external__ReactIntl__default = /*#__PURE__*/__webpack_require__.n(external__ReactIntl_);
 
 // EXTERNAL MODULE: external "ReactRedux"
 var external__ReactRedux_ = __webpack_require__(3);
 var external__ReactRedux__default = /*#__PURE__*/__webpack_require__.n(external__ReactRedux_);
@@ -2035,18 +2089,18 @@ var external__React__default = /*#__PURE
 class ConfirmDialog__ConfirmDialog extends external__React__default.a.PureComponent {
   constructor(props) {
     super(props);
     this._handleCancelBtn = this._handleCancelBtn.bind(this);
     this._handleConfirmBtn = this._handleConfirmBtn.bind(this);
   }
 
   _handleCancelBtn() {
-    this.props.dispatch({ type: Actions["actionTypes"].DIALOG_CANCEL });
-    this.props.dispatch(Actions["actionCreators"].UserEvent({ event: Actions["actionTypes"].DIALOG_CANCEL }));
+    this.props.dispatch({ type: Actions["b" /* actionTypes */].DIALOG_CANCEL });
+    this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({ event: Actions["b" /* actionTypes */].DIALOG_CANCEL }));
   }
 
   _handleConfirmBtn() {
     this.props.data.onConfirm.forEach(this.props.dispatch);
   }
 
   _renderModalMessage() {
     const message_body = this.props.data.body_string_id;
@@ -2120,23 +2174,23 @@ const ConfirmDialog = Object(external__R
  */
 class ManualMigration__ManualMigration extends external__React__default.a.PureComponent {
   constructor(props) {
     super(props);
     this.onLaunchTour = this.onLaunchTour.bind(this);
     this.onCancelTour = this.onCancelTour.bind(this);
   }
   onLaunchTour() {
-    this.props.dispatch(Actions["actionCreators"].SendToMain({ type: Actions["actionTypes"].MIGRATION_START }));
-    this.props.dispatch(Actions["actionCreators"].UserEvent({ event: Actions["actionTypes"].MIGRATION_START }));
+    this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({ type: Actions["b" /* actionTypes */].MIGRATION_START }));
+    this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({ event: Actions["b" /* actionTypes */].MIGRATION_START }));
   }
 
   onCancelTour() {
-    this.props.dispatch(Actions["actionCreators"].SendToMain({ type: Actions["actionTypes"].MIGRATION_CANCEL }));
-    this.props.dispatch(Actions["actionCreators"].UserEvent({ event: Actions["actionTypes"].MIGRATION_CANCEL }));
+    this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({ type: Actions["b" /* actionTypes */].MIGRATION_CANCEL }));
+    this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({ event: Actions["b" /* actionTypes */].MIGRATION_CANCEL }));
   }
 
   render() {
     return external__React__default.a.createElement(
       "div",
       { className: "manual-migration-container" },
       external__React__default.a.createElement(
         "p",
@@ -2158,19 +2212,18 @@ class ManualMigration__ManualMigration e
           external__React__default.a.createElement(external__ReactIntl_["FormattedMessage"], { id: "manual_migration_import_button" })
         )
       )
     );
   }
 }
 
 const ManualMigration = Object(external__ReactRedux_["connect"])()(ManualMigration__ManualMigration);
-// EXTERNAL MODULE: ./system-addon/common/Reducers.jsm
+// EXTERNAL MODULE: ./system-addon/common/Reducers.jsm + 1 modules
 var Reducers = __webpack_require__(5);
-var Reducers_default = /*#__PURE__*/__webpack_require__.n(Reducers);
 
 // CONCATENATED MODULE: ./system-addon/content-src/components/PreferencesPane/PreferencesPane.jsx
 
 
 
 
 
 
@@ -2229,33 +2282,33 @@ class PreferencesPane__PreferencesPane e
       this.togglePane();
     }
   }
   handlePrefChange(event) {
     const target = event.target;
     const { name, checked } = target;
     let value = checked;
     if (name === "topSitesCount") {
-      value = checked ? Reducers["TOP_SITES_SHOWMORE_LENGTH"] : Reducers["TOP_SITES_DEFAULT_LENGTH"];
+      value = checked ? Reducers["b" /* TOP_SITES_SHOWMORE_LENGTH */] : Reducers["a" /* TOP_SITES_DEFAULT_LENGTH */];
     }
-    this.props.dispatch(Actions["actionCreators"].SetPref(name, value));
+    this.props.dispatch(Actions["a" /* actionCreators */].SetPref(name, value));
   }
   handleSectionChange(event) {
     const target = event.target;
     const id = target.name;
-    const type = target.checked ? Actions["actionTypes"].SECTION_ENABLE : Actions["actionTypes"].SECTION_DISABLE;
-    this.props.dispatch(Actions["actionCreators"].SendToMain({ type, data: id }));
+    const type = target.checked ? Actions["b" /* actionTypes */].SECTION_ENABLE : Actions["b" /* actionTypes */].SECTION_DISABLE;
+    this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({ type, data: id }));
   }
   togglePane() {
     if (this.isSidebarOpen()) {
-      this.props.dispatch({ type: Actions["actionTypes"].SETTINGS_CLOSE });
-      this.props.dispatch(Actions["actionCreators"].UserEvent({ event: "CLOSE_NEWTAB_PREFS" }));
+      this.props.dispatch({ type: Actions["b" /* actionTypes */].SETTINGS_CLOSE });
+      this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({ event: "CLOSE_NEWTAB_PREFS" }));
     } else {
-      this.props.dispatch({ type: Actions["actionTypes"].SETTINGS_OPEN });
-      this.props.dispatch(Actions["actionCreators"].UserEvent({ event: "OPEN_NEWTAB_PREFS" }));
+      this.props.dispatch({ type: Actions["b" /* actionTypes */].SETTINGS_OPEN });
+      this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({ event: "OPEN_NEWTAB_PREFS" }));
     }
   }
   onWrapperMount(wrapper) {
     this.wrapper = wrapper;
   }
   render() {
     const props = this.props;
     const prefs = props.Prefs.values;
@@ -2307,17 +2360,17 @@ class PreferencesPane__PreferencesPane e
                 value: prefs.showTopSites,
                 onChange: this.handlePrefChange,
                 titleString: { id: "settings_pane_topsites_header" },
                 descString: { id: "settings_pane_topsites_body" } },
               external__React__default.a.createElement(PreferencesInput, {
                 className: "showMoreTopSites",
                 prefName: "topSitesCount",
                 disabled: !prefs.showTopSites,
-                value: prefs.topSitesCount !== Reducers["TOP_SITES_DEFAULT_LENGTH"],
+                value: prefs.topSitesCount !== Reducers["a" /* TOP_SITES_DEFAULT_LENGTH */],
                 onChange: this.handlePrefChange,
                 titleString: { id: "settings_pane_topsites_options_showmore" },
                 labelClassName: "icon icon-topsites" })
             ),
             sections.filter(section => !section.shouldHidePref).map(({ id, title, enabled, pref }) => external__React__default.a.createElement(
               PreferencesInput,
               {
                 key: id,
@@ -2357,22 +2410,102 @@ class PreferencesPane__PreferencesPane e
   }
 }
 
 const PreferencesPane = Object(external__ReactRedux_["connect"])(state => ({
   Prefs: state.Prefs,
   PreferencesPane: state.PreferencesPane,
   Sections: state.Sections
 }))(Object(external__ReactIntl_["injectIntl"])(PreferencesPane__PreferencesPane));
-// EXTERNAL MODULE: ./system-addon/common/PrerenderData.jsm
-var PrerenderData = __webpack_require__(14);
-var PrerenderData_default = /*#__PURE__*/__webpack_require__.n(PrerenderData);
-
+// CONCATENATED MODULE: ./system-addon/common/PrerenderData.jsm
+class _PrerenderData {
+  constructor(options) {
+    this.initialPrefs = options.initialPrefs;
+    this.initialSections = options.initialSections;
+    this._setValidation(options.validation);
+  }
+
+  get validation() {
+    return this._validation;
+  }
+
+  set validation(value) {
+    this._setValidation(value);
+  }
+
+  get invalidatingPrefs() {
+    return this._invalidatingPrefs;
+  }
+
+  // This is needed so we can use it in the constructor
+  _setValidation(value = []) {
+    this._validation = value;
+    this._invalidatingPrefs = value.reduce((result, next) => {
+      if (typeof next === "string") {
+        result.push(next);
+        return result;
+      } else if (next && next.oneOf) {
+        return result.concat(next.oneOf);
+      }
+      throw new Error("Your validation configuration is not properly configured");
+    }, []);
+  }
+
+  arePrefsValid(getPref) {
+    for (const prefs of this.validation) {
+      // {oneOf: ["foo", "bar"]}
+      if (prefs && prefs.oneOf && !prefs.oneOf.some(name => getPref(name) === this.initialPrefs[name])) {
+        return false;
+
+        // "foo"
+      } else if (getPref(prefs) !== this.initialPrefs[prefs]) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
+var PrerenderData = new _PrerenderData({
+  initialPrefs: {
+    "migrationExpired": true,
+    "showTopSites": true,
+    "showSearch": true,
+    "topSitesCount": 12,
+    "collapseTopSites": false,
+    "section.highlights.collapsed": false,
+    "section.topstories.collapsed": false,
+    "feeds.section.topstories": true,
+    "feeds.section.highlights": true
+  },
+  // Prefs listed as invalidating will prevent the prerendered version
+  // of AS from being used if their value is something other than what is listed
+  // here. This is required because some preferences cause the page layout to be
+  // too different for the prerendered version to be used. Unfortunately, this
+  // will result in users who have modified some of their preferences not being
+  // able to get the benefits of prerendering.
+  validation: ["showTopSites", "showSearch", "topSitesCount", "collapseTopSites", "section.highlights.collapsed", "section.topstories.collapsed",
+  // This means if either of these are set to their default values,
+  // prerendering can be used.
+  { oneOf: ["feeds.section.topstories", "feeds.section.highlights"] }],
+  initialSections: [{
+    enabled: true,
+    icon: "pocket",
+    id: "topstories",
+    order: 1,
+    title: { id: "header_recommended_by", values: { provider: "Pocket" } }
+  }, {
+    enabled: true,
+    id: "highlights",
+    icon: "highlights",
+    order: 2,
+    title: { id: "header_highlights" }
+  }]
+});
 // EXTERNAL MODULE: ./system-addon/content-src/lib/constants.js
-var constants = __webpack_require__(15);
+var constants = __webpack_require__(13);
 
 // CONCATENATED MODULE: ./system-addon/content-src/components/Search/Search.jsx
 /* globals ContentSearchUIController */
 
 
 
 
 
@@ -2384,17 +2517,17 @@ class Search__Search extends external__R
     super(props);
     this.onClick = this.onClick.bind(this);
     this.onInputMount = this.onInputMount.bind(this);
   }
 
   handleEvent(event) {
     // Also track search events with our own telemetry
     if (event.detail.type === "Search") {
-      this.props.dispatch(Actions["actionCreators"].UserEvent({ event: "SEARCH" }));
+      this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({ event: "SEARCH" }));
     }
   }
   onClick(event) {
     window.gContentSearchController.search(event);
   }
   componentWillUnmount() {
     delete window.gContentSearchController;
   }
@@ -2464,17 +2597,17 @@ class Search__Search extends external__R
         )
       )
     );
   }
 }
 
 const Search = Object(external__ReactRedux_["connect"])()(Object(external__ReactIntl_["injectIntl"])(Search__Search));
 // EXTERNAL MODULE: ./system-addon/content-src/components/Sections/Sections.jsx
-var Sections = __webpack_require__(16);
+var Sections = __webpack_require__(14);
 
 // CONCATENATED MODULE: ./system-addon/content-src/components/TopSites/TopSitesConstants.js
 const TOP_SITES_SOURCE = "TOP_SITES";
 const TOP_SITES_CONTEXT_MENU_OPTIONS = ["CheckPinTopSite", "EditTopSite", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl", "DeleteUrl"];
 // minimum size necessary to show a rich icon instead of a screenshot
 const MIN_RICH_FAVICON_SIZE = 96;
 // minimum size necessary to show any icon in the top left corner with a screenshot
 const MIN_CORNER_FAVICON_SIZE = 16;
@@ -2626,17 +2759,17 @@ class TopSite_TopSite extends external__
   }
   toggleContextMenu(event, index) {
     this.setState({
       activeTile: index,
       showContextMenu: true
     });
   }
   userEvent(event) {
-    this.props.dispatch(Actions["actionCreators"].UserEvent({
+    this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
       event,
       source: TOP_SITES_SOURCE,
       action_position: this.props.index
     }));
   }
   onLinkClick(ev) {
     if (this.props.onEdit) {
       // Ignore clicks if we are in the edit modal.
@@ -2650,38 +2783,38 @@ class TopSite_TopSite extends external__
     this.toggleContextMenu(event, this.props.index);
   }
   onMenuUpdate(showContextMenu) {
     this.setState({ showContextMenu });
   }
   onDismissButtonClick() {
     const { link } = this.props;
     if (link.isPinned) {
-      this.props.dispatch(Actions["actionCreators"].SendToMain({
-        type: Actions["actionTypes"].TOP_SITES_UNPIN,
+      this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
+        type: Actions["b" /* actionTypes */].TOP_SITES_UNPIN,
         data: { site: { url: link.url } }
       }));
     }
-    this.props.dispatch(Actions["actionCreators"].SendToMain({
-      type: Actions["actionTypes"].BLOCK_URL,
+    this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
+      type: Actions["b" /* actionTypes */].BLOCK_URL,
       data: link.url
     }));
     this.userEvent("BLOCK");
   }
   onPinButtonClick() {
     const { link, index } = this.props;
     if (link.isPinned) {
-      this.props.dispatch(Actions["actionCreators"].SendToMain({
-        type: Actions["actionTypes"].TOP_SITES_UNPIN,
+      this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
+        type: Actions["b" /* actionTypes */].TOP_SITES_UNPIN,
         data: { site: { url: link.url } }
       }));
       this.userEvent("UNPIN");
     } else {
-      this.props.dispatch(Actions["actionCreators"].SendToMain({
-        type: Actions["actionTypes"].TOP_SITES_PIN,
+      this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
+        type: Actions["b" /* actionTypes */].TOP_SITES_PIN,
         data: { site: { url: link.url }, index }
       }));
       this.userEvent("PIN");
     }
   }
   onEditButtonClick() {
     this.props.onEdit(this.props.index);
   }
@@ -2749,17 +2882,17 @@ TopSite_TopSite.defaultProps = {
 
 class TopSite_TopSitePlaceholder extends external__React__default.a.PureComponent {
   constructor(props) {
     super(props);
     this.onEditButtonClick = this.onEditButtonClick.bind(this);
   }
   onEditButtonClick() {
     this.props.dispatch({
-      type: Actions["actionTypes"].TOP_SITES_EDIT,
+      type: Actions["b" /* actionTypes */].TOP_SITES_EDIT,
       data: { index: this.props.index }
     });
   }
   render() {
     return external__React__default.a.createElement(
       TopSite_TopSiteLink,
       _extends({ className: "placeholder", isDraggable: false }, this.props),
       external__React__default.a.createElement("button", { className: "context-menu-button edit-button icon",
@@ -2786,17 +2919,17 @@ class TopSite__TopSiteList extends exter
       const newTopSites = nextProps.TopSites && nextProps.TopSites.rows;
       if (prevTopSites && prevTopSites[this.state.draggedIndex] && prevTopSites[this.state.draggedIndex].url === this.state.draggedSite.url && (!newTopSites[this.state.draggedIndex] || newTopSites[this.state.draggedIndex].url !== this.state.draggedSite.url)) {
         // We got the new order from the redux store via props. We can clear state now.
         this.setState(this.DEFAULT_STATE);
       }
     }
   }
   userEvent(event, index) {
-    this.props.dispatch(Actions["actionCreators"].UserEvent({
+    this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
       event,
       source: TOP_SITES_SOURCE,
       action_position: index
     }));
   }
   onDragEvent(event, index, link, title) {
     switch (event.type) {
       case "dragstart":
@@ -2814,18 +2947,18 @@ class TopSite__TopSiteList extends exter
         if (index === this.state.draggedIndex) {
           this.setState({ topSitesPreview: null });
         } else {
           this.setState({ topSitesPreview: this._makeTopSitesPreview(index) });
         }
         break;
       case "drop":
         if (index !== this.state.draggedIndex) {
-          this.props.dispatch(Actions["actionCreators"].SendToMain({
-            type: Actions["actionTypes"].TOP_SITES_INSERT,
+          this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
+            type: Actions["b" /* actionTypes */].TOP_SITES_INSERT,
             data: { site: { url: this.state.draggedSite.url, label: this.state.draggedTitle }, index }
           }));
           this.userEvent("DROP", index);
         }
         break;
     }
   }
   _getTopSites() {
@@ -2952,39 +3085,39 @@ class TopSiteForm_TopSiteForm extends ex
   }
   onAddButtonClick(ev) {
     ev.preventDefault();
     if (this.validateForm()) {
       let site = { url: this.cleanUrl() };
       if (this.state.label !== "") {
         site.label = this.state.label;
       }
-      this.props.dispatch(Actions["actionCreators"].SendToMain({
-        type: Actions["actionTypes"].TOP_SITES_INSERT,
+      this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
+        type: Actions["b" /* actionTypes */].TOP_SITES_INSERT,
         data: { site }
       }));
-      this.props.dispatch(Actions["actionCreators"].UserEvent({
+      this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
         source: TOP_SITES_SOURCE,
         event: "TOP_SITES_ADD"
       }));
       this.props.onClose();
     }
   }
   onSaveButtonClick(ev) {
     ev.preventDefault();
     if (this.validateForm()) {
       let site = { url: this.cleanUrl() };
       if (this.state.label !== "") {
         site.label = this.state.label;
       }
-      this.props.dispatch(Actions["actionCreators"].SendToMain({
-        type: Actions["actionTypes"].TOP_SITES_PIN,
+      this.props.dispatch(Actions["a" /* actionCreators */].SendToMain({
+        type: Actions["b" /* actionTypes */].TOP_SITES_PIN,
         data: { site, index: this.props.index }
       }));
-      this.props.dispatch(Actions["actionCreators"].UserEvent({
+      this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
         source: TOP_SITES_SOURCE,
         event: "TOP_SITES_EDIT",
         action_position: this.props.index
       }));
       this.props.onClose();
     }
   }
   cleanUrl() {
@@ -3113,54 +3246,54 @@ class TopSitesEdit__TopSitesEdit extends
     this.onModalOverlayClick = this.onModalOverlayClick.bind(this);
     this.onAddButtonClick = this.onAddButtonClick.bind(this);
     this.onFormClose = this.onFormClose.bind(this);
     this.onEdit = this.onEdit.bind(this);
   }
   onEditButtonClick() {
     this.setState({ showEditModal: !this.state.showEditModal });
     const event = this.state.showEditModal ? "TOP_SITES_EDIT_OPEN" : "TOP_SITES_EDIT_CLOSE";
-    this.props.dispatch(Actions["actionCreators"].UserEvent({
+    this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
       source: TOP_SITES_SOURCE,
       event
     }));
   }
   onModalOverlayClick() {
     this.setState({ showEditModal: false, showAddForm: false, showEditForm: false });
-    this.props.dispatch(Actions["actionCreators"].UserEvent({
+    this.props.dispatch(Actions["a" /* actionCreators */].UserEvent({
       source: TOP_SITES_SOURCE,
       event: "TOP_SITES_EDIT_CLOSE"
     }));
-    this.props.dispatch({ type: Actions["actionTypes"].TOP_SITES_CANCEL_EDIT });
+    this.props.dispatch({ type: Actions["b" /* actionTypes */].TOP_SITES_CANCEL_EDIT });
   }
   onShowMoreLessClick() {
-    const prefIsSetToDefault = this.props.TopSitesCount === Reducers["TOP_SITES_DEFAULT_LENGTH"];
-    this.props.dispatch(Actions["actionCreators"].SendToMain({
-      type: