Bug 1331599 - script-generated patch to replace removeEventListener calls with the once option when possible, r=jaws.
authorFlorian Quèze <florian@queze.net>
Wed, 25 Jan 2017 07:01:52 +0100
changeset 379968 ec0f3678bb31c8e5273d72c27aed48edc899e71c
parent 379967 d7181326507e1c832265f9716e6272ddc6c96242
child 379969 59db8fffcf9a3418541e146bed60c3bb3a5e12fc
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs1331599
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1331599 - script-generated patch to replace removeEventListener calls with the once option when possible, r=jaws.
addon-sdk/source/lib/sdk/addon/window.js
addon-sdk/source/lib/sdk/deprecated/unit-test.js
addon-sdk/source/lib/sdk/preferences/utils.js
addon-sdk/source/lib/sdk/ui/frame/view.js
addon-sdk/source/lib/sdk/window/utils.js
addon-sdk/source/test/addons/content-permissions/main.js
addon-sdk/source/test/addons/e10s-content/lib/test-content-script.js
addon-sdk/source/test/addons/e10s-content/lib/test-content-worker.js
addon-sdk/source/test/leak/test-leak-event-dom-closed-window.js
addon-sdk/source/test/leak/test-leak-tab-events.js
addon-sdk/source/test/leak/test-leak-window-events.js
addon-sdk/source/test/tabs/utils.js
addon-sdk/source/test/test-content-script.js
addon-sdk/source/test/test-content-sync-worker.js
addon-sdk/source/test/test-content-worker.js
addon-sdk/source/test/test-frame-utils.js
addon-sdk/source/test/test-page-mod.js
addon-sdk/source/test/test-ui-sidebar.js
addon-sdk/source/test/test-window-utils.js
addon-sdk/source/test/test-xhr.js
b2g/components/OrientationChangeHandler.jsm
b2g/components/test/mochitest/systemapp_helper.js
b2g/components/test/mochitest/test_sandbox_permission.html
browser/base/content/aboutaccounts/aboutaccounts.js
browser/base/content/abouthome/aboutHome.js
browser/base/content/browser.js
browser/base/content/contentSearchUI.js
browser/base/content/newtab/customize.js
browser/base/content/sync/utils.js
browser/base/content/tabbrowser.xml
browser/base/content/test/alerts/head.js
browser/base/content/test/general/browser_aboutHome.js
browser/base/content/test/general/browser_backButtonFitts.js
browser/base/content/test/general/browser_bug321000.js
browser/base/content/test/general/browser_bug406216.js
browser/base/content/test/general/browser_bug432599.js
browser/base/content/test/general/browser_bug460146.js
browser/base/content/test/general/browser_bug479408.js
browser/base/content/test/general/browser_bug491431.js
browser/base/content/test/general/browser_bug517902.js
browser/base/content/test/general/browser_bug553455.js
browser/base/content/test/general/browser_bug581242.js
browser/base/content/test/general/browser_bug581253.js
browser/base/content/test/general/browser_bug592338.js
browser/base/content/test/general/browser_bug623893.js
browser/base/content/test/general/browser_bug664672.js
browser/base/content/test/general/browser_bug678392.js
browser/base/content/test/general/browser_bug734076.js
browser/base/content/test/general/browser_bug749738.js
browser/base/content/test/general/browser_bug767836_perwindowpb.js
browser/base/content/test/general/browser_bug817947.js
browser/base/content/test/general/browser_bug832435.js
browser/base/content/test/general/browser_clipboard_pastefile.js
browser/base/content/test/general/browser_close_dependent_tabs.js
browser/base/content/test/general/browser_datachoices_notification.js
browser/base/content/test/general/browser_discovery.js
browser/base/content/test/general/browser_documentnavigation.js
browser/base/content/test/general/browser_focusonkeydown.js
browser/base/content/test/general/browser_hide_removing.js
browser/base/content/test/general/browser_keywordBookmarklets.js
browser/base/content/test/general/browser_keywordSearch.js
browser/base/content/test/general/browser_newwindow_focus.js
browser/base/content/test/general/browser_offlineQuotaNotification.js
browser/base/content/test/general/browser_pageInfo.js
browser/base/content/test/general/browser_sanitizeDialog.js
browser/base/content/test/general/browser_save_link_when_window_navigates.js
browser/base/content/test/general/browser_selectpopup.js
browser/base/content/test/general/browser_subframe_favicons_not_used.js
browser/base/content/test/general/browser_tabfocus.js
browser/base/content/test/general/browser_tabs_isActive.js
browser/base/content/test/general/browser_visibleTabs_bookmarkAllTabs.js
browser/base/content/test/general/contentSearchUI.js
browser/base/content/test/general/file_fullscreen-window-open.html
browser/base/content/test/general/head.js
browser/base/content/test/newtab/head.js
browser/base/content/test/plugins/head.js
browser/base/content/test/popupNotifications/head.js
browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab.js
browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab3.js
browser/base/content/test/social/browser_blocklist.js
browser/base/content/test/social/browser_share.js
browser/base/content/test/social/browser_social_activation.js
browser/base/content/test/urlbar/browser_URLBarSetURI.js
browser/base/content/test/urlbar/browser_bug1104165-switchtab-decodeuri.js
browser/base/content/test/urlbar/browser_bug304198.js
browser/base/content/test/urlbar/browser_locationBarCommand.js
browser/base/content/test/urlbar/browser_locationBarExternalLoad.js
browser/base/content/test/urlbar/browser_urlbarAboutHomeLoading.js
browser/base/content/test/urlbar/browser_urlbarSearchSuggestionsNotification.js
browser/base/content/test/webrtc/browser_devices_get_user_media.js
browser/base/content/test/webrtc/browser_devices_get_user_media_anim.js
browser/base/content/test/webrtc/browser_devices_get_user_media_in_frame.js
browser/base/content/test/webrtc/browser_devices_get_user_media_screen.js
browser/base/content/test/webrtc/browser_devices_get_user_media_tear_off_tab.js
browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js
browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access_in_frame.js
browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access_tear_off_tab.js
browser/base/content/test/webrtc/browser_webrtc_hooks.js
browser/base/content/test/webrtc/head.js
browser/components/contextualidentity/test/browser/browser_middleClick.js
browser/components/customizableui/CustomizableUI.jsm
browser/components/customizableui/ScrollbarSampler.jsm
browser/components/customizableui/content/panelUI.js
browser/components/customizableui/test/browser_947914_button_newPrivateWindow.js
browser/components/customizableui/test/browser_947914_button_newWindow.js
browser/components/customizableui/test/browser_967000_button_sync.js
browser/components/customizableui/test/head.js
browser/components/downloads/DownloadsCommon.jsm
browser/components/downloads/test/browser/browser_downloads_panel_block.js
browser/components/downloads/test/browser/head.js
browser/components/extensions/ext-tabs.js
browser/components/extensions/ext-utils.js
browser/components/extensions/ext-windows.js
browser/components/extensions/test/browser/head.js
browser/components/newtab/tests/browser/browser_PreviewProvider.js
browser/components/originattributes/test/browser/head.js
browser/components/places/tests/browser/browser_555547.js
browser/components/places/tests/browser/browser_bookmarksProperties.js
browser/components/places/tests/browser/browser_forgetthissite_single.js
browser/components/places/tests/browser/browser_sidebarpanels_click.js
browser/components/places/tests/browser/browser_views_liveupdate.js
browser/components/places/tests/browser/head.js
browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js
browser/components/preferences/in-content/tests/head.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cache.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_opendir.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_theming.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
browser/components/privatebrowsing/test/browser/head.js
browser/components/search/test/browser_abouthome_behavior.js
browser/components/search/test/browser_amazon_behavior.js
browser/components/search/test/browser_bing_behavior.js
browser/components/search/test/browser_contextmenu.js
browser/components/search/test/browser_ddg_behavior.js
browser/components/search/test/browser_google_behavior.js
browser/components/search/test/browser_yahoo_behavior.js
browser/components/sessionstore/test/browser_464620_b.html
browser/components/sessionstore/test/browser_466937_sample.html
browser/components/sessionstore/test/browser_514751.js
browser/components/sessionstore/test/browser_580512.js
browser/components/sessionstore/test/browser_586068-browser_state_interrupted.js
browser/components/sessionstore/test/browser_586068-multi_window.js
browser/components/sessionstore/test/browser_588426.js
browser/components/sessionstore/test/browser_589246.js
browser/components/sessionstore/test/browser_590563.js
browser/components/sessionstore/test/browser_615394-SSWindowState_events.js
browser/components/sessionstore/test/browser_628270.js
browser/components/sessionstore/test/browser_636279.js
browser/components/sessionstore/test/browser_644409-scratchpads.js
browser/components/sessionstore/test/browser_659591.js
browser/components/sessionstore/test/browser_662812.js
browser/components/sessionstore/test/browser_grouped_session_store.js
browser/components/sessionstore/test/browser_windowRestore_perwindowpb.js
browser/components/sessionstore/test/head.js
browser/components/syncedtabs/test/browser/browser_sidebar_syncedtabslist.js
browser/components/tests/browser/browser_bug538331.js
browser/components/translation/test/browser_translation_exceptions.js
browser/components/translation/test/browser_translation_infobar.js
browser/components/translation/translation-infobar.xml
browser/components/uitour/UITour.jsm
browser/components/uitour/test/browser_UITour.js
browser/components/uitour/test/browser_UITour_resetProfile.js
browser/components/uitour/test/head.js
browser/extensions/mortar/host/pdf/chrome/js/l20n.js
browser/extensions/mortar/host/pdf/chrome/js/toolbar.js
browser/extensions/pdfjs/test/browser_pdfjs_navigation.js
browser/modules/test/browser_ContentSearch.js
browser/modules/test/browser_ProcessHangNotifications.js
browser/modules/webrtcUI.jsm
browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Preferences.jsm
devtools/client/aboutdebugging/initializer.js
devtools/client/canvasdebugger/test/head.js
devtools/client/commandline/test/browser_cmd_screenshot.js
devtools/client/debugger/test/mochitest/browser_dbg_on-pause-raise.js
devtools/client/debugger/test/mochitest/browser_dbg_sources-contextmenu-02.js
devtools/client/debugger/test/mochitest/code_frame-script.js
devtools/client/debugger/test/mochitest/doc_closure-optimized-out.html
devtools/client/debugger/test/mochitest/doc_closures.html
devtools/client/debugger/test/mochitest/doc_event-listeners-01.html
devtools/client/debugger/test/mochitest/doc_event-listeners-02.html
devtools/client/debugger/test/mochitest/doc_event-listeners-03.html
devtools/client/debugger/test/mochitest/head.js
devtools/client/debugger/views/global-search-view.js
devtools/client/framework/connect/connect.js
devtools/client/framework/test/browser_toolbox_options_enable_serviceworkers_testing_frame_script.js
devtools/client/framework/test/browser_two_tabs.js
devtools/client/inspector/local-toolbox.js
devtools/client/netmonitor/test/service-workers/status-codes.html
devtools/client/projecteditor/lib/plugins/app-manager/app-project-editor.js
devtools/client/projecteditor/test/head.js
devtools/client/responsive.html/index.js
devtools/client/responsive.html/test/browser/browser_touch_simulation.js
devtools/client/scratchpad/test/browser_scratchpad_browser_last_window_closing.js
devtools/client/scratchpad/test/browser_scratchpad_chrome_context_pref.js
devtools/client/scratchpad/test/browser_scratchpad_contexts.js
devtools/client/scratchpad/test/browser_scratchpad_display_non_error_exceptions.js
devtools/client/scratchpad/test/browser_scratchpad_display_outputs_errors.js
devtools/client/scratchpad/test/browser_scratchpad_edit_ui_updates.js
devtools/client/scratchpad/test/browser_scratchpad_eval_func.js
devtools/client/scratchpad/test/browser_scratchpad_execute_print.js
devtools/client/scratchpad/test/browser_scratchpad_falsy.js
devtools/client/scratchpad/test/browser_scratchpad_files.js
devtools/client/scratchpad/test/browser_scratchpad_goto_line_ui.js
devtools/client/scratchpad/test/browser_scratchpad_help_key.js
devtools/client/scratchpad/test/browser_scratchpad_initialization.js
devtools/client/scratchpad/test/browser_scratchpad_inspect.js
devtools/client/scratchpad/test/browser_scratchpad_long_string.js
devtools/client/scratchpad/test/browser_scratchpad_modeline.js
devtools/client/scratchpad/test/browser_scratchpad_open_error_console.js
devtools/client/scratchpad/test/browser_scratchpad_pprint-02.js
devtools/client/scratchpad/test/browser_scratchpad_pprint.js
devtools/client/scratchpad/test/browser_scratchpad_pprint_error_goto_line.js
devtools/client/scratchpad/test/browser_scratchpad_recent_files.js
devtools/client/scratchpad/test/browser_scratchpad_reload_and_run.js
devtools/client/scratchpad/test/browser_scratchpad_remember_view_options.js
devtools/client/scratchpad/test/browser_scratchpad_reset_undo.js
devtools/client/scratchpad/test/browser_scratchpad_revert_to_saved.js
devtools/client/scratchpad/test/browser_scratchpad_run_error_goto_line.js
devtools/client/scratchpad/test/browser_scratchpad_tab.js
devtools/client/scratchpad/test/browser_scratchpad_tab_switch.js
devtools/client/scratchpad/test/browser_scratchpad_throw_output.js
devtools/client/scratchpad/test/browser_scratchpad_ui.js
devtools/client/scratchpad/test/browser_scratchpad_wrong_window_focus.js
devtools/client/scratchpad/test/head.js
devtools/client/shadereditor/test/head.js
devtools/client/shared/frame-script-utils.js
devtools/client/shared/test/browser_tableWidget_keyboard_interaction.js
devtools/client/shared/test/browser_tableWidget_mouse_interaction.js
devtools/client/shared/test/browser_telemetry_button_scratchpad.js
devtools/client/shared/test/browser_treeWidget_keyboard_interaction.js
devtools/client/shared/test/test-actor.js
devtools/client/shared/widgets/Graphs.js
devtools/client/sourceeditor/test/browser_editor_find_again.js
devtools/client/sourceeditor/test/head.js
devtools/client/styleeditor/test/browser_styleeditor_opentab.js
devtools/client/styleeditor/test/head.js
devtools/client/webaudioeditor/test/head.js
devtools/client/webconsole/console-output.js
devtools/client/webconsole/hudservice.js
devtools/client/webconsole/jsterm.js
devtools/client/webconsole/new-console-output/test/mochitest/browser_webconsole_context_menu_open_url.js
devtools/client/webconsole/panel.js
devtools/client/webconsole/test/browser_bug_871156_ctrlw_close_tab.js
devtools/client/webconsole/test/browser_netmonitor_shows_reqs_in_webconsole.js
devtools/client/webconsole/test/browser_webconsole_bug_595934_message_categories.js
devtools/client/webconsole/test/browser_webconsole_bug_653531_highlighter_console_helper.js
devtools/client/webconsole/test/browser_webconsole_bug_764572_output_open_url.js
devtools/client/webconsole/test/browser_webconsole_dont_navigate_on_doubleclick.js
devtools/client/webconsole/test/browser_webconsole_output_dom_elements_04.js
devtools/client/webconsole/test/browser_webconsole_shows_reqs_in_netmonitor.js
devtools/client/webconsole/test/head.js
devtools/client/webconsole/test/test-closure-optimized-out.html
devtools/client/webconsole/test/test-error.html
devtools/client/webide/content/addons.js
devtools/client/webide/content/details.js
devtools/client/webide/content/devicepreferences.js
devtools/client/webide/content/logs.js
devtools/client/webide/content/monitor.js
devtools/client/webide/content/newapp.js
devtools/client/webide/content/prefs.js
devtools/client/webide/content/project-listing.js
devtools/client/webide/content/runtime-listing.js
devtools/client/webide/content/runtimedetails.js
devtools/client/webide/content/webide.js
devtools/client/webide/content/wifi-auth.js
devtools/client/webide/modules/runtimes.js
devtools/client/webide/test/head.js
devtools/server/tests/browser/browser_navigateEvents.js
devtools/server/tests/browser/browser_webextension_inspected_window.js
devtools/shared/heapsnapshot/tests/mochitest/test_saveHeapSnapshot_e10s_01.html
devtools/shared/security/prompt.js
devtools/shared/webconsole/test/common.js
devtools/shared/webconsole/test/test_console_serviceworker_cached.html
docshell/test/browser/browser_bug554155.js
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
docshell/test/browser/head.js
docshell/test/chrome/test_private_hidden_window.html
docshell/test/navigation/test_bug430723.html
dom/base/test/browser_bug1058164.js
dom/base/test/browser_bug593387.js
dom/base/test/browser_pagehide_on_tab_close.js
dom/base/test/iframe_bug962251.html
dom/base/test/test_bug564863.xhtml
dom/base/test/test_bug588990.html
dom/base/test/test_bug962251.html
dom/base/test/test_bug976673.html
dom/base/test/test_domwindowutils.html
dom/broadcastchannel/tests/browser_private_browsing.js
dom/browser-element/mochitest/browserElement_Alert.js
dom/browser-element/mochitest/browserElement_Auth.js
dom/browser-element/mochitest/browserElement_CopyPaste.js
dom/browser-element/mochitest/browserElement_DataURI.js
dom/browser-element/mochitest/browserElement_ExecuteScript.js
dom/browser-element/mochitest/browserElement_OpenNamed.js
dom/browser-element/mochitest/browserElement_SetVisibleFrames2.js
dom/browser-element/mochitest/browserElement_getWebManifest.js
dom/browser-element/mochitest/file_browserElement_XFrameOptionsAllowFrom.html
dom/browser-element/mochitest/file_browserElement_XFrameOptionsDeny.html
dom/browser-element/mochitest/priority/test_HighPriority.html
dom/crypto/test/test_indexedDB.html
dom/events/test/pointerevents/mochitest_support_external.js
dom/events/test/test_bug1128787-1.html
dom/events/test/test_bug1128787-2.html
dom/events/test/test_bug1128787-3.html
dom/events/test/test_bug534833.html
dom/events/test/test_bug822898.html
dom/events/test/test_bug930374-chrome.html
dom/events/test/test_bug930374-content.html
dom/events/test/test_error_events.html
dom/filesystem/compat/tests/test_formSubmission.html
dom/filesystem/tests/test_webkitdirectory.html
dom/html/test/file_fullscreen-navigation.html
dom/html/test/forms/test_formaction_attribute.html
dom/html/test/forms/test_meter_element.html
dom/html/test/forms/test_novalidate_attribute.html
dom/html/test/forms/test_progress_element.html
dom/html/test/forms/test_save_restore_radio_groups.html
dom/html/test/test_bug369370.html
dom/html/test/test_bug557087-1.html
dom/html/test/test_bug561636.html
dom/html/test/test_bug566046.html
dom/html/test/test_bug567938-4.html
dom/html/test/test_bug582412-1.html
dom/html/test/test_bug582412-2.html
dom/html/test/test_bug592802.html
dom/html/test/test_bug601030.html
dom/html/test/test_bug612730.html
dom/html/test/test_bug615833.html
dom/html/test/test_bug619278.html
dom/html/test/test_bug622558.html
dom/html/test/test_bug622597.html
dom/html/test/test_bug633058.html
dom/html/test/test_bug651956.html
dom/html/test/test_fullscreen-api.html
dom/html/test/test_ignoreuserfocus.html
dom/indexedDB/test/browser_forgetThisSite.js
dom/indexedDB/test/browser_permissionsPromptAllow.js
dom/indexedDB/test/browser_permissionsPromptDeny.js
dom/indexedDB/test/browser_permissionsPromptWorker.js
dom/indexedDB/test/browser_perwindow_privateBrowsing.js
dom/manifest/test/test_window_onappinstalled_event.html
dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek.html
dom/media/mediasource/test/test_HaveMetadataUnbufferedSeek_mp4.html
dom/media/mediasource/test/test_SeekableBeforeEndOfStreamSplit.html
dom/media/mediasource/test/test_SeekableBeforeEndOfStreamSplit_mp4.html
dom/media/test/test_texttrackcue.html
dom/media/test/test_webvtt_positionalign.html
dom/network/tests/file_udpsocket_iframe.html
dom/network/tests/test_udpsocket.html
dom/plugins/test/mochitest/head.js
dom/plugins/test/mochitest/plugin-utils.js
dom/plugins/test/mochitest/test_pluginstream_3rdparty.html
dom/power/test/browser_wakelocks.js
dom/presentation/tests/mochitest/file_presentation_1ua_receiver.html
dom/presentation/tests/mochitest/file_presentation_mixed_security_contexts.html
dom/presentation/tests/mochitest/file_presentation_receiver.html
dom/presentation/tests/mochitest/file_presentation_sandboxed_presentation.html
dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway.js
dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver.js
dom/presentation/tests/mochitest/test_presentation_dc_receiver_oop.html
dom/presentation/tests/mochitest/test_presentation_dc_sender.html
dom/presentation/tests/mochitest/test_presentation_device_info.html
dom/presentation/tests/mochitest/test_presentation_reconnect.html
dom/presentation/tests/mochitest/test_presentation_tcp_sender.html
dom/presentation/tests/mochitest/test_presentation_terminate.js
dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error.js
dom/smil/test/test_smilHyperlinking.xhtml
dom/tests/browser/browser_ConsoleStoragePBTest_perwindowpb.js
dom/tests/browser/browser_localStorage_privatestorageevent.js
dom/tests/browser/browser_prerendering.js
dom/tests/browser/prevent_return_key.html
dom/tests/mochitest/bugs/test_bug1171215.html
dom/tests/mochitest/bugs/test_errorReporting.html
dom/tests/mochitest/general/file_clonewrapper.html
dom/tests/mochitest/general/test_contentViewer_overrideDPPX.html
dom/tests/mochitest/localstorage/test_localStorageBasePrivateBrowsing_perwindowpb.html
dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html
dom/workers/test/head.js
dom/workers/test/serviceworkers/browser_download.js
dom/workers/test/serviceworkers/test_file_blob_response.html
dom/workers/test/serviceworkers/test_file_blob_upload.html
dom/workers/test/serviceworkers/test_privateBrowsing.html
dom/workers/test/test_sharedWorker_privateBrowsing.html
dom/xbl/test/file_bug944407.xml
editor/composer/test/test_bug519928.html
editor/libeditor/tests/test_CF_HTML_clipboard.html
editor/libeditor/tests/test_bug289384.html
editor/libeditor/tests/test_bug597331.html
editor/libeditor/tests/test_bug600570.html
editor/libeditor/tests/test_bug611182.html
editor/libeditor/tests/test_bug966155.html
editor/libeditor/tests/test_bug966552.html
editor/libeditor/tests/test_keypress_untrusted_event.html
gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js
image/test/browser/browser_image.js
js/xpconnect/tests/mochitest/test_crossOriginObjects.html
layout/base/tests/bug970964_inner.html
layout/forms/test/test_bug1305282.html
layout/forms/test/test_bug572649.html
layout/reftests/css-animations/no-stacking-context-opacity-removing-animation-in-delay.html
layout/reftests/css-animations/no-stacking-context-transform-removing-animation-in-delay.html
layout/reftests/layers/component-alpha-exit-1.html
layout/tools/reftest/bootstrap.js
layout/xul/test/browser_bug1163304.js
mobile/android/chrome/content/WebcompatReporter.js
mobile/android/chrome/content/aboutAccounts.js
mobile/android/chrome/content/browser.js
mobile/android/extensions/flyweb/bootstrap.js
mobile/android/tests/browser/chrome/test_awsy_lite.html
mobile/android/tests/browser/chrome/test_video_discovery.html
mobile/android/tests/browser/robocop/robocop_input.html
mobile/android/tests/browser/robocop/roboextender/bootstrap.js
mobile/android/tests/browser/robocop/testBrowserDiscovery.js
mobile/android/tests/browser/robocop/testHistoryService.js
mobile/android/tests/browser/robocop/testTrackingProtection.js
mobile/android/tests/browser/robocop/testVideoControls.js
netwerk/test/browser/browser_NetUtil.js
parser/htmlparser/tests/mochitest/test_img_picture_preload.html
security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js
security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js
security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js
security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js
security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js
security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js
services/sync/tps/extensions/tps/resource/modules/windows.jsm
testing/marionette/components/marionette.js
testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
testing/mochitest/bootstrap.js
testing/mochitest/browser-test.js
testing/mochitest/redirect.html
testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html
toolkit/components/addoncompat/tests/addon/bootstrap.js
toolkit/components/alerts/test/test_alerts_requireinteraction.html
toolkit/components/alerts/test/test_multiple_alerts.html
toolkit/components/extensions/ExtensionUtils.jsm
toolkit/components/extensions/test/mochitest/head.js
toolkit/components/formautofill/test/chrome/loader.js
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/test/chrome/test_privbrowsing_perwindowpb.html
toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_upgrade.html
toolkit/components/passwordmgr/test/mochitest/test_autofocus_js.html
toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html
toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation_negative.html
toolkit/components/places/tests/browser/browser_favicon_privatebrowsing_perwindowpb.js
toolkit/components/places/tests/browser/browser_history_post.js
toolkit/components/prompts/test/prompt_common.js
toolkit/components/remotebrowserutils/tests/browser/browser_RemoteWebNavigation.js
toolkit/components/satchel/test/test_form_autocomplete.html
toolkit/components/satchel/test/test_form_autocomplete_with_list.html
toolkit/components/startup/tests/browser/browser_bug511456.js
toolkit/components/startup/tests/browser/browser_bug537449.js
toolkit/components/thumbnails/test/browser_thumbnails_bug726727.js
toolkit/components/thumbnails/test/head.js
toolkit/components/tooltiptext/tests/browser_input_file_tooltips.js
toolkit/components/url-classifier/tests/mochitest/test_donottrack.html
toolkit/components/url-classifier/tests/mochitest/test_privatebrowsing_trackingprotection.html
toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_bug1157081.html
toolkit/components/url-classifier/tests/mochitest/test_trackingprotection_whitelist.html
toolkit/components/viewsource/test/browser/head.js
toolkit/components/windowwatcher/test/test_storage_copied.html
toolkit/content/aboutNetworking.js
toolkit/content/aboutProfiles.js
toolkit/content/aboutServiceWorkers.js
toolkit/content/aboutTelemetry.js
toolkit/content/tests/browser/browser_bug1170531.js
toolkit/content/tests/browser/browser_findbar.js
toolkit/content/tests/chrome/test_about_networking.html
toolkit/content/tests/mochitest/test_autocomplete_change_after_focus.html
toolkit/content/tests/widgets/test_videocontrols_standalone.html
toolkit/content/tests/widgets/videocontrols_direction_test.js
toolkit/modules/tests/browser/browser_WebRequest_cookies.js
toolkit/modules/tests/browser/browser_WebRequest_filtering.js
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/test/browser/browser_bug523784.js
toolkit/mozapps/extensions/test/browser/browser_bug557956.js
toolkit/mozapps/extensions/test/browser/browser_bug586574.js
toolkit/mozapps/extensions/test/browser/browser_bug591465.js
toolkit/mozapps/extensions/test/browser/browser_cancelCompatCheck.js
toolkit/mozapps/extensions/test/browser/browser_details.js
toolkit/mozapps/extensions/test/browser/browser_manualupdates.js
toolkit/mozapps/extensions/test/browser/browser_metadataTimeout.js
toolkit/mozapps/extensions/test/browser/browser_newaddon.js
toolkit/mozapps/extensions/test/browser/browser_purchase.js
toolkit/mozapps/extensions/test/browser/browser_recentupdates.js
toolkit/mozapps/extensions/test/browser/browser_tabsettings.js
toolkit/mozapps/extensions/test/browser/head.js
toolkit/mozapps/update/tests/chrome/utils.js
--- a/addon-sdk/source/lib/sdk/addon/window.js
+++ b/addon-sdk/source/lib/sdk/addon/window.js
@@ -46,20 +46,19 @@ docShell.createAboutBlankContentViewer(a
 // such document into that would allow us to create XUL iframes, that
 // are necessary for hidden frames etc..
 var window = docShell.contentViewer.DOMDocument.defaultView;
 window.location = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window/>";
 
 // Create a promise that is delivered once add-on window is interactive,
 // used by add-on runner to defer add-on loading until window is ready.
 var { promise, resolve } = defer();
-eventTarget.addEventListener("DOMContentLoaded", function handler(event) {
-  eventTarget.removeEventListener("DOMContentLoaded", handler);
+eventTarget.addEventListener("DOMContentLoaded", function(event) {
   resolve();
-});
+}, {once: true});
 
 exports.ready = promise;
 exports.window = window;
 
 // Still close window on unload to claim memory back early.
 unload(function() {
   window.close()
   frame.parentNode.removeChild(frame);
--- a/addon-sdk/source/lib/sdk/deprecated/unit-test.js
+++ b/addon-sdk/source/lib/sdk/deprecated/unit-test.js
@@ -312,20 +312,19 @@ TestRunner.prototype = {
 
     let wins = windows(null, { includePrivate: true });
     let winPromises = wins.map(win => {
       return new Promise(resolve => {
         if (["interactive", "complete"].indexOf(win.document.readyState) >= 0) {
           resolve()
         }
         else {
-          win.addEventListener("DOMContentLoaded", function onLoad() {
-            win.removeEventListener("DOMContentLoaded", onLoad);
+          win.addEventListener("DOMContentLoaded", function() {
             resolve();
-          });
+          }, {once: true});
         }
       });
     });
 
     PromiseDebugging.flushUncaughtErrors();
     PromiseDebugging.removeUncaughtErrorObserver(this._uncaughtErrorObserver);
 
 
--- a/addon-sdk/source/lib/sdk/preferences/utils.js
+++ b/addon-sdk/source/lib/sdk/preferences/utils.js
@@ -14,29 +14,28 @@ const { getMostRecentBrowserWindow } = r
 // Opens about:addons in a new tab, then displays the inline
 // preferences of the provided add-on
 const open = ({ id }) => new Promise((resolve, reject) => {
   // opening the about:addons page in a new tab
   let tab = openTab(getMostRecentBrowserWindow(), "about:addons");
   let browser = getBrowserForTab(tab);
 
   // waiting for the about:addons page to load
-  browser.addEventListener("load", function onPageLoad() {
-    browser.removeEventListener("load", onPageLoad, true);
+  browser.addEventListener("load", function() {
     let window = browser.contentWindow;
 
     // wait for the add-on's "addon-options-displayed"
     on("addon-options-displayed", function onPrefDisplayed({ subject: doc, data }) {
       if (data === id) {
         off("addon-options-displayed", onPrefDisplayed);
         resolve({
           id: id,
           tabId: getTabId(tab),
           "document": doc
         });
       }
     }, true);
 
     // display the add-on inline preferences page
     window.gViewController.commands.cmd_showItemDetails.doCommand({ id: id }, true);
-  }, true);
+  }, {capture: true, once: true});
 });
 exports.open = open;
--- a/addon-sdk/source/lib/sdk/ui/frame/view.js
+++ b/addon-sdk/source/lib/sdk/ui/frame/view.js
@@ -69,34 +69,32 @@ const registerFrame = ({id, url}) => {
       outerFrame.setAttribute("data-is-sdk-outer-frame", true);
       outerFrame.setAttribute("type", "content");
       outerFrame.setAttribute("transparent", true);
       outerFrame.setAttribute("flex", 2);
       outerFrame.setAttribute("style", "overflow: hidden;");
       outerFrame.setAttribute("scrolling", "no");
       outerFrame.setAttribute("disablehistory", true);
       outerFrame.setAttribute("seamless", "seamless");
-      outerFrame.addEventListener("load", function onload() {
-        outerFrame.removeEventListener("load", onload, true);
-
+      outerFrame.addEventListener("load", function() {
         let doc = outerFrame.contentDocument;
 
         let innerFrame = doc.createElementNS(HTML_NS, "iframe");
         innerFrame.setAttribute("id", id);
         innerFrame.setAttribute("src", url);
         innerFrame.setAttribute("seamless", "seamless");
         innerFrame.setAttribute("sandbox", "allow-scripts");
         innerFrame.setAttribute("scrolling", "no");
         innerFrame.setAttribute("data-is-sdk-inner-frame", true);
         innerFrame.setAttribute("style", [ "border:none",
           "position:absolute", "width:100%", "top: 0",
           "left: 0", "overflow: hidden"].join(";"));
 
         doc.body.appendChild(innerFrame);
-      }, true);
+      }, {capture: true, once: true});
 
       view.appendChild(outerFrame);
 
       return view;
     }
   });
 };
 
--- a/addon-sdk/source/lib/sdk/window/utils.js
+++ b/addon-sdk/source/lib/sdk/window/utils.js
@@ -208,20 +208,19 @@ exports.open = open;
 
 function onFocus(window) {
   let { resolve, promise } = defer();
 
   if (isFocused(window)) {
     resolve(window);
   }
   else {
-    window.addEventListener("focus", function focusListener() {
-      window.removeEventListener("focus", focusListener, true);
+    window.addEventListener("focus", function() {
       resolve(window);
-    }, true);
+    }, {capture: true, once: true});
   }
 
   return promise;
 }
 exports.onFocus = onFocus;
 
 var isFocused = dispatcher("window-isFocused");
 isFocused.when(x => x instanceof Ci.nsIDOMWindow, (window) => {
--- a/addon-sdk/source/test/addons/content-permissions/main.js
+++ b/addon-sdk/source/test/addons/content-permissions/main.js
@@ -16,20 +16,19 @@ exports.testCrossDomainIframe = function
     response.write("<html><body>foo</body></html>");
   });
 
   let pageMod = PageMod({
     include: TEST_TAB_URL,
     contentScript: "new " + function ContentScriptScope() {
       self.on("message", function (url) {
         let iframe = document.createElement("iframe");
-        iframe.addEventListener("load", function onload() {
-          iframe.removeEventListener("load", onload);
+        iframe.addEventListener("load", function() {
           self.postMessage(iframe.contentWindow.document.body.innerHTML);
-        });
+        }, {once: true});
         iframe.setAttribute("src", url);
         document.documentElement.appendChild(iframe);
       });
     },
     onAttach: function(w) {
       w.on("message", function (body) {
         assert.equal(body, "foo", "received iframe html content");
         pageMod.destroy();
--- a/addon-sdk/source/test/addons/e10s-content/lib/test-content-script.js
+++ b/addon-sdk/source/test/addons/e10s-content/lib/test-content-script.js
@@ -168,31 +168,30 @@ exports["test Shared To String Proxies"]
 */
 
 // Ensure that postMessage is working correctly across documents with an iframe
 var html = '<iframe id="iframe" name="test" src="data:text/html;charset=utf-8," />';
 exports["test postMessage"] = createProxyTest(html, function (helper, assert) {
   let ifWindow = helper.xrayWindow.document.getElementById("iframe").contentWindow;
   // Listen without proxies, to check that it will work in regular case
   // simulate listening from a web document.
-  ifWindow.addEventListener("message", function listener(event) {
-    ifWindow.removeEventListener("message", listener);
+  ifWindow.addEventListener("message", function(event) {
     // As we are in system principal, event is an XrayWrapper
     // xrays use current compartments when calling postMessage method.
     // Whereas js proxies was using postMessage method compartment,
     // not the caller one.
     assert.strictEqual(event.source, helper.xrayWindow,
                       "event.source is the top window");
     assert.equal(event.origin, testHost, "origin matches testHost");
 
     assert.equal(event.data, "{\"foo\":\"bar\\n \\\"escaped\\\".\"}",
                      "message data is correct");
 
     helper.done();
-  });
+  }, {once: true});
 
   helper.createWorker(
     'new ' + function ContentScriptScope() {
       var json = JSON.stringify({foo : "bar\n \"escaped\"."});
 
       document.getElementById("iframe").contentWindow.postMessage(json, "*");
     }
   );
@@ -654,18 +653,16 @@ exports["test Listeners"] = createProxyT
 
       function onclick() {};
       input.onclick = onclick;
       assert(input.onclick === onclick, "on* attributes are equal to original function set");
 
       let addEventListenerCalled = false;
       let expandoCalled = false;
       input.addEventListener("click", function onclick(event) {
-        input.removeEventListener("click", onclick, true);
-
         assert(!addEventListenerCalled, "closure given to addEventListener is called once");
         if (addEventListenerCalled)
           return;
         addEventListenerCalled = true;
 
         assert(!event.target.ownerDocument.defaultView.documentGlobal, "event object is still wrapped and doesn't expose document globals");
 
         let input2 = document.getElementById("input2");
@@ -684,17 +681,17 @@ exports["test Listeners"] = createProxyT
           }, 0);
 
         }
 
         setTimeout(function () {
           input.click();
         }, 0);
 
-      }, true);
+      }, {capture: true, once: true});
 
       input.click();
     }
   );
 
 });
 
 exports["test requestAnimationFrame"] = createProxyTest("", function (helper) {
@@ -742,31 +739,28 @@ exports["test Cross Domain Iframe"] = cr
   });
 
   let worker = helper.createWorker(
     'new ' + function ContentScriptScope() {
       // Waits for the server page url
       self.on("message", function (url) {
         // Creates an iframe with this page
         let iframe = document.createElement("iframe");
-        iframe.addEventListener("load", function onload() {
-          iframe.removeEventListener("load", onload, true);
+        iframe.addEventListener("load", function() {
           try {
             // Try to communicate with iframe's content
-            window.addEventListener("message", function onmessage(event) {
-              window.removeEventListener("message", onmessage, true);
-
+            window.addEventListener("message", function(event) {
               assert(event.data == "hello world", "COW works properly");
               self.port.emit("end");
-            }, true);
+            }, {capture: true, once: true});
             iframe.contentWindow.postMessage("hello", "*");
           } catch(e) {
             assert(false, "COW fails : "+e.message);
           }
-        }, true);
+        }, {capture: true, once: true});
         iframe.setAttribute("src", url);
         document.body.appendChild(iframe);
       });
     }
   );
 
   worker.port.on("end", function () {
     server.stop(helper.done);
--- a/addon-sdk/source/test/addons/e10s-content/lib/test-content-worker.js
+++ b/addon-sdk/source/test/addons/e10s-content/lib/test-content-worker.js
@@ -70,32 +70,31 @@ function loadAndWait(browser, url, callb
 // with a <browser> element loaded on a given content URL
 // The callback receive 3 arguments:
 // - test: reference to the jetpack test object
 // - browser: a reference to the <browser> xul node
 // - done: a callback to call when test is over
 function WorkerTest(url, callback) {
   return function testFunction(assert, done) {
     let chromeWindow = makeWindow();
-    chromeWindow.addEventListener("load", function onload() {
-      chromeWindow.removeEventListener("load", onload, true);
+    chromeWindow.addEventListener("load", function() {
       let browser = chromeWindow.document.createElement("browser");
       browser.setAttribute("type", "content");
       chromeWindow.document.documentElement.appendChild(browser);
       // Wait for about:blank load event ...
       listenOnce(browser, "load", function onAboutBlankLoad() {
         // ... before loading the expected doc and waiting for its load event
         loadAndWait(browser, url, function onDocumentLoaded() {
           callback(assert, browser, function onTestDone() {
 
             close(chromeWindow).then(done);
           });
         });
       });
-    }, true);
+    }, {capture: true, once: true});
   };
 }
 
 exports["test:sample"] = WorkerTest(
   DEFAULT_CONTENT_URL,
   function(assert, browser, done) {
 
     assert.notEqual(browser.contentWindow.location.href, "about:blank",
@@ -762,18 +761,17 @@ exports["test:check worker API with page
 
       // We have to wait before going back into history,
       // otherwise `goBack` won't do anything.
       setTimeout(function () {
         browser.goBack();
       }, 0);
 
       // Wait for the document to be hidden
-      browser.addEventListener("pagehide", function onpagehide() {
-        browser.removeEventListener("pagehide", onpagehide);
+      browser.addEventListener("pagehide", function() {
         // Now any event sent to this worker should be cached
 
         worker.postMessage("message");
         worker.port.emit("event");
 
         // Display the page with attached content script back in order to resume
         // its timeout and receive the expected message.
         // We have to delay this in order to not break the history.
@@ -803,17 +801,17 @@ exports["test:check worker API with page
               })
             ]);
             promise.then(done);
           });
 
           browser.goForward();
         }, 500);
 
-      });
+      }, {once: true});
     });
 
   }
 );
 
 exports['test:conentScriptFile as URL instance'] = WorkerTest(
   DEFAULT_CONTENT_URL,
   function(assert, browser, done) {
--- a/addon-sdk/source/test/leak/test-leak-event-dom-closed-window.js
+++ b/addon-sdk/source/test/leak/test-leak-event-dom-closed-window.js
@@ -8,22 +8,21 @@ const { Loader } = require('sdk/test/loa
 const openWindow = require("sdk/window/utils").open;
 
 exports["test sdk/event/dom does not leak when attached to closed window"] = function*(assert) {
   yield asyncWindowLeakTest(assert, _ => {
     return new Promise(resolve => {
       let loader = Loader(module);
       let { open } = loader.require('sdk/event/dom');
       let w = openWindow();
-      w.addEventListener("DOMWindowClose", function windowClosed(evt) {
-        w.removeEventListener("DOMWindowClose", windowClosed);
+      w.addEventListener("DOMWindowClose", function(evt) {
         // The sdk/event/dom module tries to clean itself up when DOMWindowClose
         // is fired.  Verify that it doesn't leak if its attached to an
         // already closed window either. (See bug 1268898.)
         open(w.document, "TestEvent1");
         resolve(loader);
-      });
+      }, {once: true});
       w.close();
     });
   });
 }
 
 require("sdk/test").run(exports);
--- a/addon-sdk/source/test/leak/test-leak-tab-events.js
+++ b/addon-sdk/source/test/leak/test-leak-tab-events.js
@@ -8,39 +8,35 @@ const { Loader } = require('sdk/test/loa
 const openWindow = require("sdk/window/utils").open;
 
 exports["test sdk/tab/events does not leak new window"] = function*(assert) {
   yield asyncWindowLeakTest(assert, _ => {
     return new Promise(resolve => {
       let loader = Loader(module);
       let { events } = loader.require('sdk/tab/events');
       let w = openWindow();
-      w.addEventListener("load", function windowLoaded(evt) {
-        w.removeEventListener("load", windowLoaded);
-        w.addEventListener("DOMWindowClose", function windowClosed(evt) {
-          w.removeEventListener("DOMWindowClose", windowClosed);
+      w.addEventListener("load", function(evt) {
+        w.addEventListener("DOMWindowClose", function(evt) {
           resolve(loader);
-        });
+        }, {once: true});
         w.close();
-      });
+      }, {once: true});
     });
   });
 }
 
 exports["test sdk/tab/events does not leak when attached to existing window"] = function*(assert) {
   yield asyncWindowLeakTest(assert, _ => {
     return new Promise(resolve => {
       let loader = Loader(module);
       let w = openWindow();
-      w.addEventListener("load", function windowLoaded(evt) {
-        w.removeEventListener("load", windowLoaded);
+      w.addEventListener("load", function(evt) {
         let { events } = loader.require('sdk/tab/events');
-        w.addEventListener("DOMWindowClose", function windowClosed(evt) {
-          w.removeEventListener("DOMWindowClose", windowClosed);
+        w.addEventListener("DOMWindowClose", function(evt) {
           resolve(loader);
-        });
+        }, {once: true});
         w.close();
-      });
+      }, {once: true});
     });
   });
 }
 
 require("sdk/test").run(exports);
--- a/addon-sdk/source/test/leak/test-leak-window-events.js
+++ b/addon-sdk/source/test/leak/test-leak-window-events.js
@@ -44,22 +44,20 @@ exports["test window/events for leaks"] 
   });
 };
 
 exports["test window/events for leaks with existing window"] = function*(assert) {
   yield asyncWindowLeakTest(assert, _ => {
     return new Promise((resolve, reject) => {
       let loader = Loader(module);
       let w = open();
-      w.addEventListener("load", function windowLoaded(evt) {
-        w.removeEventListener("load", windowLoaded);
+      w.addEventListener("load", function(evt) {
         let { events } = loader.require("sdk/window/events");
-        w.addEventListener("DOMWindowClose", function windowClosed(evt) {
-          w.removeEventListener("DOMWindowClose", windowClosed);
+        w.addEventListener("DOMWindowClose", function(evt) {
           resolve(loader);
-        });
+        }, {once: true});
         w.close();
-      });
+      }, {once: true});
     });
   });
 };
 
 require("sdk/test").run(exports);
--- a/addon-sdk/source/test/tabs/utils.js
+++ b/addon-sdk/source/test/tabs/utils.js
@@ -8,17 +8,16 @@ const { openTab: makeTab, getTabContentW
 function openTab(rawWindow, url) {
   return new Promise(resolve => {
     let tab = makeTab(rawWindow, url);
     let window = getTabContentWindow(tab);
     if (window.document.readyState == "complete") {
       return resolve();
     }
 
-    window.addEventListener("load", function onLoad() {
-      window.removeEventListener("load", onLoad, true);
+    window.addEventListener("load", function() {
       resolve();
-    }, true);
+    }, {capture: true, once: true});
 
     return null;
   })
 }
 exports.openTab = openTab;
--- a/addon-sdk/source/test/test-content-script.js
+++ b/addon-sdk/source/test/test-content-script.js
@@ -168,31 +168,30 @@ exports["test Shared To String Proxies"]
 */
 
 // Ensure that postMessage is working correctly across documents with an iframe
 var html = '<iframe id="iframe" name="test" src="data:text/html;charset=utf-8," />';
 exports["test postMessage"] = createProxyTest(html, function (helper, assert) {
   let ifWindow = helper.xrayWindow.document.getElementById("iframe").contentWindow;
   // Listen without proxies, to check that it will work in regular case
   // simulate listening from a web document.
-  ifWindow.addEventListener("message", function listener(event) {
-    ifWindow.removeEventListener("message", listener);
+  ifWindow.addEventListener("message", function(event) {
     // As we are in system principal, event is an XrayWrapper
     // xrays use current compartments when calling postMessage method.
     // Whereas js proxies was using postMessage method compartment,
     // not the caller one.
     assert.strictEqual(event.source, helper.xrayWindow,
                       "event.source is the top window");
     assert.equal(event.origin, testHost, "origin matches testHost");
 
     assert.equal(event.data, "{\"foo\":\"bar\\n \\\"escaped\\\".\"}",
                      "message data is correct");
 
     helper.done();
-  });
+  }, {once: true});
 
   helper.createWorker(
     'new ' + function ContentScriptScope() {
       var json = JSON.stringify({foo : "bar\n \"escaped\"."});
 
       document.getElementById("iframe").contentWindow.postMessage(json, "*");
     }
   );
@@ -654,18 +653,16 @@ exports["test Listeners"] = createProxyT
 
       function onclick() {};
       input.onclick = onclick;
       assert(input.onclick === onclick, "on* attributes are equal to original function set");
 
       let addEventListenerCalled = false;
       let expandoCalled = false;
       input.addEventListener("click", function onclick(event) {
-        input.removeEventListener("click", onclick, true);
-
         assert(!addEventListenerCalled, "closure given to addEventListener is called once");
         if (addEventListenerCalled)
           return;
         addEventListenerCalled = true;
 
         assert(!event.target.ownerDocument.defaultView.documentGlobal, "event object is still wrapped and doesn't expose document globals");
 
         let input2 = document.getElementById("input2");
@@ -684,17 +681,17 @@ exports["test Listeners"] = createProxyT
           }, 0);
 
         }
 
         setTimeout(function () {
           input.click();
         }, 0);
 
-      }, true);
+      }, {capture: true, once: true});
 
       input.click();
     }
   );
 
 });
 
 exports["test requestAnimationFrame"] = createProxyTest("", function (helper) {
@@ -742,31 +739,28 @@ exports["test Cross Domain Iframe"] = cr
   });
 
   let worker = helper.createWorker(
     'new ' + function ContentScriptScope() {
       // Waits for the server page url
       self.on("message", function (url) {
         // Creates an iframe with this page
         let iframe = document.createElement("iframe");
-        iframe.addEventListener("load", function onload() {
-          iframe.removeEventListener("load", onload, true);
+        iframe.addEventListener("load", function() {
           try {
             // Try to communicate with iframe's content
-            window.addEventListener("message", function onmessage(event) {
-              window.removeEventListener("message", onmessage, true);
-
+            window.addEventListener("message", function(event) {
               assert(event.data == "hello world", "COW works properly");
               self.port.emit("end");
-            }, true);
+            }, {capture: true, once: true});
             iframe.contentWindow.postMessage("hello", "*");
           } catch(e) {
             assert(false, "COW fails : "+e.message);
           }
-        }, true);
+        }, {capture: true, once: true});
         iframe.setAttribute("src", url);
         document.body.appendChild(iframe);
       });
     }
   );
 
   worker.port.on("end", function () {
     server.stop(helper.done);
--- a/addon-sdk/source/test/test-content-sync-worker.js
+++ b/addon-sdk/source/test/test-content-sync-worker.js
@@ -69,32 +69,31 @@ function loadAndWait(browser, url, callb
 // with a <browser> element loaded on a given content URL
 // The callback receive 3 arguments:
 // - test: reference to the jetpack test object
 // - browser: a reference to the <browser> xul node
 // - done: a callback to call when test is over
 function WorkerTest(url, callback) {
   return function testFunction(assert, done) {
     let chromeWindow = makeWindow();
-    chromeWindow.addEventListener("load", function onload() {
-      chromeWindow.removeEventListener("load", onload, true);
+    chromeWindow.addEventListener("load", function() {
       let browser = chromeWindow.document.createElement("browser");
       browser.setAttribute("type", "content");
       chromeWindow.document.documentElement.appendChild(browser);
       // Wait for about:blank load event ...
       listenOnce(browser, "load", function onAboutBlankLoad() {
         // ... before loading the expected doc and waiting for its load event
         loadAndWait(browser, url, function onDocumentLoaded() {
           callback(assert, browser, function onTestDone() {
 
             close(chromeWindow).then(done);
           });
         });
       });
-    }, true);
+    }, {capture: true, once: true});
   };
 }
 
 exports["test:sample"] = WorkerTest(
   DEFAULT_CONTENT_URL,
   function(assert, browser, done) {
 
     assert.notEqual(browser.contentWindow.location.href, "about:blank",
@@ -746,18 +745,17 @@ exports["test:check worker API with page
 
       // We have to wait before going back into history,
       // otherwise `goBack` won't do anything.
       setTimeout(function () {
         browser.goBack();
       }, 0);
 
       // Wait for the document to be hidden
-      browser.addEventListener("pagehide", function onpagehide() {
-        browser.removeEventListener("pagehide", onpagehide);
+      browser.addEventListener("pagehide", function() {
         // Now any event sent to this worker should throw
 
         assert.throws(
             function () { worker.postMessage("data"); },
             /The page is currently hidden and can no longer be used/,
             "postMessage should throw when the page is hidden in history"
             );
 
@@ -776,17 +774,17 @@ exports["test:check worker API with page
         setTimeout(function () {
           worker.on("message", function (data) {
             assert.ok(data, "timeout restored");
             done();
           });
           browser.goForward();
         }, 500);
 
-      });
+      }, {once: true});
     });
 
   }
 );
 
 exports['test:conentScriptFile as URL instance'] = WorkerTest(
   DEFAULT_CONTENT_URL,
   function(assert, browser, done) {
--- a/addon-sdk/source/test/test-content-worker.js
+++ b/addon-sdk/source/test/test-content-worker.js
@@ -70,32 +70,31 @@ function loadAndWait(browser, url, callb
 // with a <browser> element loaded on a given content URL
 // The callback receive 3 arguments:
 // - test: reference to the jetpack test object
 // - browser: a reference to the <browser> xul node
 // - done: a callback to call when test is over
 function WorkerTest(url, callback) {
   return function testFunction(assert, done) {
     let chromeWindow = makeWindow();
-    chromeWindow.addEventListener("load", function onload() {
-      chromeWindow.removeEventListener("load", onload, true);
+    chromeWindow.addEventListener("load", function() {
       let browser = chromeWindow.document.createElement("browser");
       browser.setAttribute("type", "content");
       chromeWindow.document.documentElement.appendChild(browser);
       // Wait for about:blank load event ...
       listenOnce(browser, "load", function onAboutBlankLoad() {
         // ... before loading the expected doc and waiting for its load event
         loadAndWait(browser, url, function onDocumentLoaded() {
           callback(assert, browser, function onTestDone() {
 
             close(chromeWindow).then(done);
           });
         });
       });
-    }, true);
+    }, {capture: true, once: true});
   };
 }
 
 exports["test:sample"] = WorkerTest(
   DEFAULT_CONTENT_URL,
   function(assert, browser, done) {
 
     assert.notEqual(browser.contentWindow.location.href, "about:blank",
@@ -763,18 +762,17 @@ exports["test:check worker API with page
 
       // We have to wait before going back into history,
       // otherwise `goBack` won't do anything.
       setTimeout(function () {
         browser.goBack();
       }, 0);
 
       // Wait for the document to be hidden
-      browser.addEventListener("pagehide", function onpagehide() {
-        browser.removeEventListener("pagehide", onpagehide);
+      browser.addEventListener("pagehide", function() {
         // Now any event sent to this worker should be cached
 
         worker.postMessage("message");
         worker.port.emit("event");
 
         // Display the page with attached content script back in order to resume
         // its timeout and receive the expected message.
         // We have to delay this in order to not break the history.
@@ -804,17 +802,17 @@ exports["test:check worker API with page
               })
             ]);
             promise.then(done);
           });
 
           browser.goForward();
         }, 500);
 
-      });
+      }, {once: true});
     });
 
   }
 );
 
 exports['test:conentScriptFile as URL instance'] = WorkerTest(
   DEFAULT_CONTENT_URL,
   function(assert, browser, done) {
--- a/addon-sdk/source/test/test-frame-utils.js
+++ b/addon-sdk/source/test/test-frame-utils.js
@@ -24,36 +24,34 @@ exports['test frame creation'] = functio
 };
 
 exports['test fram has js disabled by default'] = function(assert, done) {
   open('data:text/html;charset=utf-8,window').then(function (window) {
     let frame = create(window.document, {
       uri: 'data:text/html;charset=utf-8,<script>document.documentElement.innerHTML' +
            '= "J" + "S"</script>',
     });
-    frame.contentWindow.addEventListener('DOMContentLoaded', function ready() {
-      frame.contentWindow.removeEventListener('DOMContentLoaded', ready);
+    frame.contentWindow.addEventListener('DOMContentLoaded', function() {
       assert.ok(!~frame.contentDocument.documentElement.innerHTML.indexOf('JS'),
                 'JS was executed');
 
       close(window).then(done);
-    });
+    }, {once: true});
   });
 };
 
 exports['test frame with js enabled'] = function(assert, done) {
   open('data:text/html;charset=utf-8,window').then(function (window) {
     let frame = create(window.document, {
       uri: 'data:text/html;charset=utf-8,<script>document.documentElement.innerHTML' +
            '= "J" + "S"</script>',
       allowJavascript: true
     });
-    frame.contentWindow.addEventListener('DOMContentLoaded', function ready() {
-      frame.contentWindow.removeEventListener('DOMContentLoaded', ready);
+    frame.contentWindow.addEventListener('DOMContentLoaded', function() {
       assert.ok(~frame.contentDocument.documentElement.innerHTML.indexOf('JS'),
                 'JS was executed');
 
       close(window).then(done);
-    });
+    }, {once: true});
   });
 };
 
 require('sdk/test').run(exports);
--- a/addon-sdk/source/test/test-page-mod.js
+++ b/addon-sdk/source/test/test-page-mod.js
@@ -1022,54 +1022,51 @@ exports.testAttachToTabsOnly = function(
   });
 
   function openHiddenFrame() {
     assert.pass('Open iframe in hidden window');
     let hiddenFrames = require('sdk/frame/hidden-frame');
     let hiddenFrame = hiddenFrames.add(hiddenFrames.HiddenFrame({
       onReady: function () {
         let element = this.element;
-        element.addEventListener('DOMContentLoaded', function onload() {
-          element.removeEventListener('DOMContentLoaded', onload);
+        element.addEventListener('DOMContentLoaded', function() {
           hiddenFrames.remove(hiddenFrame);
 
           if (!xulApp.is("Fennec")) {
             openToplevelWindow();
           }
           else {
             openBrowserIframe();
           }
-        });
+        }, {once: true});
         element.setAttribute('src', 'data:text/html;charset=utf-8,foo');
       }
     }));
   }
 
   function openToplevelWindow() {
     assert.pass('Open toplevel window');
     let win = open('data:text/html;charset=utf-8,bar');
-    win.addEventListener('DOMContentLoaded', function onload() {
-      win.removeEventListener('DOMContentLoaded', onload);
+    win.addEventListener('DOMContentLoaded', function() {
       win.close();
       openBrowserIframe();
-    });
+    }, {once: true});
   }
 
   function openBrowserIframe() {
     assert.pass('Open iframe in browser window');
     let window = require('sdk/deprecated/window-utils').activeBrowserWindow;
     let document = window.document;
     let iframe = document.createElement('iframe');
     iframe.setAttribute('type', 'content');
     iframe.setAttribute('src', 'data:text/html;charset=utf-8,foobar');
-    iframe.addEventListener('DOMContentLoaded', function onload() {
-      iframe.removeEventListener('DOMContentLoaded', onload);
+    iframe.addEventListener('DOMContentLoaded', function() {
       iframe.parentNode.removeChild(iframe);
       openTabWithIframes();
-    });
+    }, {once: true});
     document.documentElement.appendChild(iframe);
   }
 
   // Only these three documents will be accepted by the page-mod
   function openTabWithIframes() {
     assert.pass('Open iframes in a tab');
     let subContent = '<iframe src="data:text/html;charset=utf-8,sub frame" />'
     let content = '<iframe src="data:text/html;charset=utf-8,' +
--- a/addon-sdk/source/test/test-ui-sidebar.js
+++ b/addon-sdk/source/test/test-ui-sidebar.js
@@ -1090,20 +1090,19 @@ exports.testSidebarLeakCheckDestroyAfter
 
   sidebar.on('hide', () => {
     assert.fail('the sidebar hide listener should have been removed');
   });
   assert.pass('added a sidebar hide listener');
 
   yield new Promise(resolve => {
     let panelBrowser = window.document.getElementById('sidebar').contentDocument.getElementById('web-panels-browser');
-    panelBrowser.contentWindow.addEventListener('unload', function onUnload() {
-      panelBrowser.contentWindow.removeEventListener('unload', onUnload);
+    panelBrowser.contentWindow.addEventListener('unload', function() {
       resolve();
-    });
+    }, {once: true});
     sidebar.destroy();
   });
 
   assert.pass('the sidebar web panel was unloaded properly');
 }
 
 exports.testSidebarLeakCheckUnloadAfterAttach = function*(assert) {
   const loader = Loader(module);
@@ -1132,20 +1131,19 @@ exports.testSidebarLeakCheckUnloadAfterA
 
   sidebar.on('hide', function() {
     assert.fail('the sidebar hide listener should have been removed');
   });
   assert.pass('added a sidebar hide listener');
 
   let panelBrowser = window.document.getElementById('sidebar').contentDocument.getElementById('web-panels-browser');
   yield new Promise(resolve => {
-    panelBrowser.contentWindow.addEventListener('unload', function onUnload() {
-      panelBrowser.contentWindow.removeEventListener('unload', onUnload);
+    panelBrowser.contentWindow.addEventListener('unload', function() {
       resolve();
-    });
+    }, {once: true});
     loader.unload();
   });
 
   assert.pass('the sidebar web panel was unloaded properly');
 }
 
 exports.testTwoSidebarsWithSameTitleAndURL = function(assert) {
   const { Sidebar } = require('sdk/ui/sidebar');
--- a/addon-sdk/source/test/test-window-utils.js
+++ b/addon-sdk/source/test/test-window-utils.js
@@ -36,18 +36,17 @@ function makeEmptyWindow(options) {
     }
   });
 }
 
 exports.testWindowTracker = function(assert, done) {
   var myWindow = makeEmptyWindow();
   assert.pass('window was created');
 
-  myWindow.addEventListener("load", function onload() {
-    myWindow.removeEventListener("load", onload);
+  myWindow.addEventListener("load", function() {
     assert.pass("test window has opened");
 
     // test bug 638007 (new is optional), using new
     var wt = new windowUtils.WindowTracker({
       onTrack: window => {
         if (window === myWindow) {
           assert.pass("onTrack() called with our test window");
           close(window);
@@ -56,17 +55,17 @@ exports.testWindowTracker = function(ass
       onUntrack: window => {
         if (window === myWindow) {
           assert.pass("onUntrack() called with our test window");
           wt.unload();
           timer.setTimeout(done);
         }
       }
     });
-  });
+  }, {once: true});
 };
 
 exports['test window watcher untracker'] = function(assert, done) {
   var myWindow;
   var tracks = 0;
   var unloadCalled = false;
 
   var delegate = {
--- a/addon-sdk/source/test/test-xhr.js
+++ b/addon-sdk/source/test/test-xhr.js
@@ -46,22 +46,21 @@ exports.testLocalXhr = function(assert, 
   req.overrideMimeType('text/plain');
   req.open('GET', data.url('testLocalXhr.json'));
   req.onreadystatechange = function() {
     if (req.readyState == 4 && (req.status == 0 || req.status == 200)) {
       ready = true;
       assert.equal(req.responseText, '{}\n', 'XMLHttpRequest should get local files');
     }
   };
-  req.addEventListener('load', function onload() {
-    req.removeEventListener('load', onload);
+  req.addEventListener('load', function() {
     assert.pass('addEventListener for load event worked');
     assert.ok(ready, 'onreadystatechange listener worked');
     done();
-  });
+  }, {once: true});
   req.send(null);
 };
 
 
 exports.testResponseHeaders = function(assert, done) {
   let req = new XMLHttpRequest();
 
   req.overrideMimeType('text/plain');
--- a/b2g/components/OrientationChangeHandler.jsm
+++ b/b2g/components/OrientationChangeHandler.jsm
@@ -55,16 +55,15 @@ var OrientationChangeHandler = {
     }
 
     // 180deg rotation, no resize
     if (fullSwitch) {
       window.setTimeout(trigger);
       return;
     }
 
-    window.addEventListener("resize", function waitForResize(e) {
-      window.removeEventListener("resize", waitForResize);
+    window.addEventListener("resize", function(e) {
       trigger();
-    });
+    }, {once: true});
   }
 };
 
 OrientationChangeHandler.init();
--- a/b2g/components/test/mochitest/systemapp_helper.js
+++ b/b2g/components/test/mochitest/systemapp_helper.js
@@ -108,32 +108,31 @@ var steps = [
     }
     SystemAppProxy.addEventListener("mozChromeEvent", removedListener);
     SystemAppProxy.removeEventListener("mozChromeEvent", removedListener);
 
     // Register it to the JSM
     SystemAppProxy.registerFrame(frame);
     assert.ok(true, "Frame created and registered");
 
-    frame.contentWindow.addEventListener("load", function onload() {
-      frame.contentWindow.removeEventListener("load", onload);
+    frame.contentWindow.addEventListener("load", function() {
       assert.ok(true, "Frame document loaded");
 
       // Declare that the iframe is now loaded.
       // That should dispatch early events
       isLoaded = true;
       SystemAppProxy.setIsLoaded();
       assert.ok(true, "Frame declared as loaded");
 
       let gotFrame = SystemAppProxy.getFrame();
       assert.equal(gotFrame, frame, "getFrame returns the frame we passed");
 
       // Once pending events are received,
       // we will run checkEventDispatching from `listener` function
-    });
+    }, {once: true});
 
     frame.setAttribute("src", "data:text/html,system app");
   },
 
   function checkEventPendingBeforeLoad() {
     // Frame is loaded but not ready,
     // these events should queue before the System app is ready.
     SystemAppProxy._sendCustomEvent("custom", { name: "third" });
--- a/b2g/components/test/mochitest/test_sandbox_permission.html
+++ b/b2g/components/test/mochitest/test_sandbox_permission.html
@@ -45,20 +45,19 @@ function runNext() {
 
 // Create a sanbox iframe.
 function loadBrowser() {
   iframe = document.createElement("iframe");
   SpecialPowers.wrap(iframe).mozbrowser = true;
   iframe.src = 'about:blank';
   document.body.appendChild(iframe);
 
-  iframe.addEventListener("load", function onLoad() {
-    iframe.removeEventListener("load", onLoad);
+  iframe.addEventListener("load", function() {
     runNext();
-  });
+  }, {once: true});
 }
 
 gScript.addMessageListener("permission-request", function (detail) {
   let permissions = detail.permissions;
   let expectedValue = gResult.shift();
   let permissionTypes = Object.keys(permissions);
 
   is(permissionTypes.length, Object.keys(expectedValue).length, "expected number of permissions");
--- a/browser/base/content/aboutaccounts/aboutaccounts.js
+++ b/browser/base/content/aboutaccounts/aboutaccounts.js
@@ -492,31 +492,30 @@ function migrateToDevEdition(urlParams) 
 // overridden in tests.
 function getDefaultProfilePath() {
   let defaultProfile = Cc["@mozilla.org/toolkit/profile-service;1"]
                         .getService(Ci.nsIToolkitProfileService)
                         .defaultProfile;
   return defaultProfile.rootDir.path;
 }
 
-document.addEventListener("DOMContentLoaded", function onload() {
-  document.removeEventListener("DOMContentLoaded", onload, true);
+document.addEventListener("DOMContentLoaded", function() {
   init();
   var buttonGetStarted = document.getElementById("buttonGetStarted");
   buttonGetStarted.addEventListener("click", getStarted);
 
   var buttonRetry = document.getElementById("buttonRetry");
   buttonRetry.addEventListener("click", retry);
 
   var oldsync = document.getElementById("oldsync");
   oldsync.addEventListener("click", handleOldSync);
 
   var buttonOpenPrefs = document.getElementById("buttonOpenPrefs")
   buttonOpenPrefs.addEventListener("click", openPrefs);
-}, true);
+}, {capture: true, once: true});
 
 function initObservers() {
   function observe(subject, topic, data) {
     log("about:accounts observed " + topic);
     if (topic == fxAccountsCommon.ONLOGOUT_NOTIFICATION) {
       // All about:account windows get changed to action=signin on logout.
       window.location = "about:accounts?action=signin";
       return;
--- a/browser/base/content/abouthome/aboutHome.js
+++ b/browser/base/content/abouthome/aboutHome.js
@@ -221,20 +221,19 @@ function setupSearch() {
   // high contrast mode).
   document.getElementById("searchSubmit").value =
     document.body.getAttribute("dir") == "ltr" ? "\u25B6" : "\u25C0";
 
   // The "autofocus" attribute doesn't focus the form element
   // immediately when the element is first drawn, so the
   // attribute is also used for styling when the page first loads.
   searchText = document.getElementById("searchText");
-  searchText.addEventListener("blur", function searchText_onBlur() {
-    searchText.removeEventListener("blur", searchText_onBlur);
+  searchText.addEventListener("blur", function() {
     searchText.removeAttribute("autofocus");
-  });
+  }, {once: true});
 
   if (!gContentSearchController) {
     gContentSearchController =
       new ContentSearchUIController(searchText, searchText.parentNode,
                                     "abouthome", "homepage");
   }
 }
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1938,20 +1938,19 @@ function loadOneOrMoreURIs(aURIString) {
 
 function focusAndSelectUrlBar() {
   // In customize mode, the url bar is disabled. If a new tab is opened or the
   // user switches to a different tab, this function gets called before we've
   // finished leaving customize mode, and the url bar will still be disabled.
   // We can't focus it when it's disabled, so we need to re-run ourselves when
   // we've finished leaving customize mode.
   if (CustomizationHandler.isExitingCustomizeMode) {
-    gNavToolbox.addEventListener("aftercustomization", function afterCustomize() {
-      gNavToolbox.removeEventListener("aftercustomization", afterCustomize);
+    gNavToolbox.addEventListener("aftercustomization", function() {
       focusAndSelectUrlBar();
-    });
+    }, {once: true});
 
     return true;
   }
 
   if (gURLBar) {
     if (window.fullScreen)
       FullScreen.showNavToolbox();
 
--- a/browser/base/content/contentSearchUI.js
+++ b/browser/base/content/contentSearchUI.js
@@ -848,20 +848,19 @@ ContentSearchUIController.prototype = {
       let uri;
       if (engine.iconBuffer) {
         uri = this._getFaviconURIFromBuffer(engine.iconBuffer);
       } else {
         uri = this._getImageURIForCurrentResolution(
           "chrome://browser/skin/search-engine-placeholder.png");
       }
       img.setAttribute("src", uri);
-      img.addEventListener("load", function imgLoad() {
-        img.removeEventListener("load", imgLoad);
+      img.addEventListener("load", function() {
         URL.revokeObjectURL(uri);
-      });
+      }, {once: true});
       button.appendChild(img);
       button.style.width = buttonWidth + "px";
       button.setAttribute("title", engine.name);
 
       button.engineName = engine.name;
       button.addEventListener("click", this);
       button.addEventListener("mousemove", this);
 
--- a/browser/base/content/newtab/customize.js
+++ b/browser/base/content/newtab/customize.js
@@ -27,20 +27,19 @@ var gCustomize = {
     this._nodes.classic.addEventListener("click", this);
     this._nodes.enhanced.addEventListener("click", this);
     this._nodes.learn.addEventListener("click", this);
 
     this.updateSelected();
   },
 
   hidePanel: function() {
-    this._nodes.overlay.addEventListener("transitionend", function onTransitionEnd() {
-      gCustomize._nodes.overlay.removeEventListener("transitionend", onTransitionEnd);
+    this._nodes.overlay.addEventListener("transitionend", function() {
       gCustomize._nodes.overlay.style.display = "none";
-    });
+    }, {once: true});
     this._nodes.overlay.style.opacity = 0;
     this._nodes.button.removeAttribute("active");
     this._nodes.panel.removeAttribute("open");
     document.removeEventListener("click", this);
     document.removeEventListener("keydown", this);
   },
 
   showPanel: function(event) {
--- a/browser/base/content/sync/utils.js
+++ b/browser/base/content/sync/utils.js
@@ -106,35 +106,33 @@ var gSyncUtils = {
     let pp = document.getElementById(elid).value;
 
     // Create an invisible iframe whose contents we can print.
     let iframe = document.createElement("iframe");
     iframe.setAttribute("src", "chrome://browser/content/sync/key.xhtml");
     iframe.collapsed = true;
     document.documentElement.appendChild(iframe);
     iframe.contentWindow.addEventListener("load", function() {
-      iframe.contentWindow.removeEventListener("load", arguments.callee);
-
       // Insert the Sync Key into the page.
       let el = iframe.contentDocument.getElementById("synckey");
       el.firstChild.nodeValue = pp;
 
       // Insert the TOS and Privacy Policy URLs into the page.
       let termsURL = Weave.Svc.Prefs.get("termsURL");
       el = iframe.contentDocument.getElementById("tosLink");
       el.setAttribute("href", termsURL);
       el.firstChild.nodeValue = termsURL;
 
       let privacyURL = Weave.Svc.Prefs.get("privacyURL");
       el = iframe.contentDocument.getElementById("ppLink");
       el.setAttribute("href", privacyURL);
       el.firstChild.nodeValue = privacyURL;
 
       callback(iframe);
-    });
+    }, {once: true});
   },
 
   /**
    * Print passphrase backup document.
    *
    * @param elid : ID of the form element containing the passphrase.
    */
   passphrasePrint(elid) {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1109,20 +1109,19 @@
 
             this.mCurrentBrowser = newBrowser;
             this.mCurrentTab = this.tabContainer.selectedItem;
             this.showTab(this.mCurrentTab);
 
             var forwardButtonContainer = document.getElementById("urlbar-wrapper");
             if (forwardButtonContainer) {
               forwardButtonContainer.setAttribute("switchingtabs", "true");
-              window.addEventListener("MozAfterPaint", function removeSwitchingtabsAttr() {
-                window.removeEventListener("MozAfterPaint", removeSwitchingtabsAttr);
+              window.addEventListener("MozAfterPaint", function() {
                 forwardButtonContainer.removeAttribute("switchingtabs");
-              });
+              }, {once: true});
             }
 
             this._appendStatusPanel();
 
             if (updateBlockedPopups)
               this.mCurrentBrowser.updateBlockedPopups();
 
             // Update the URL bar.
--- a/browser/base/content/test/alerts/head.js
+++ b/browser/base/content/test/alerts/head.js
@@ -1,22 +1,21 @@
 function promiseAlertWindow() {
   return new Promise(function(resolve) {
     let listener = {
       onOpenWindow(window) {
         let alertWindow = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
-        alertWindow.addEventListener("load", function onLoad() {
-          alertWindow.removeEventListener("load", onLoad);
+        alertWindow.addEventListener("load", function() {
           let windowType = alertWindow.document.documentElement.getAttribute("windowtype");
           if (windowType != "alert:alert") {
             return;
           }
           Services.wm.removeListener(listener);
           resolve(alertWindow);
-        });
+        }, {once: true});
       },
     };
     Services.wm.addListener(listener);
   });
 }
 
 /**
  * Similar to `BrowserTestUtils.closeWindow`, but
--- a/browser/base/content/test/general/browser_aboutHome.js
+++ b/browser/base/content/test/general/browser_aboutHome.js
@@ -560,19 +560,17 @@ function* withSnippetsMap(setupFn, testF
       return ContentTask.spawn(browser, {
         setupFnSource,
         version: AboutHomeUtils.snippetsVersion,
       }, function* (args) {
         return new Promise(resolve => {
           let document = content.document;
           // We're not using Promise-based listeners, because they resolve asynchronously.
           // The snippets test setup code relies on synchronous behaviour here.
-          document.addEventListener("AboutHomeLoadSnippets", function loadSnippets() {
-            document.removeEventListener("AboutHomeLoadSnippets", loadSnippets);
-
+          document.addEventListener("AboutHomeLoadSnippets", function() {
             let updateSnippets;
             if (args.setupFnSource) {
               updateSnippets = eval(`(() => (${args.setupFnSource}))()`);
             }
 
             content.wrappedJSObject.ensureSnippetsMapThen(snippetsMap => {
               snippetsMap = Cu.waiveXrays(snippetsMap);
               info("Got snippets map: " +
@@ -589,17 +587,17 @@ function* withSnippetsMap(setupFn, testF
                 updateSnippets(snippetsMap);
               }
 
               // Tack it to the global object
               content.gSnippetsMap = snippetsMap;
 
               resolve();
             });
-          });
+          }, {once: true});
         });
       });
     };
 
     // We'd like to listen to the 'AboutHomeLoadSnippets' event on a fresh
     // document as soon as technically possible, so we use webProgress.
     let promise = new Promise(resolve => {
       let wpl = {
--- a/browser/base/content/test/general/browser_backButtonFitts.js
+++ b/browser/base/content/test/general/browser_backButtonFitts.js
@@ -7,20 +7,19 @@ add_task(function* () {
   yield BrowserTestUtils.openNewForegroundTab(gBrowser, firstLocation);
 
   yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
     // Push the state before maximizing the window and clicking below.
     content.history.pushState("page2", "page2", "page2");
 
     // While in the child process, add a listener for the popstate event here. This
     // event will fire when the mouse click happens.
-    content.addEventListener("popstate", function onPopState() {
-      content.removeEventListener("popstate", onPopState);
+    content.addEventListener("popstate", function() {
       sendAsyncMessage("Test:PopStateOccurred", { location: content.document.location.href });
-    });
+    }, {once: true});
   });
 
   window.maximize();
 
   // Find where the nav-bar is vertically.
   var navBar = document.getElementById("nav-bar");
   var boundingRect = navBar.getBoundingClientRect();
   var yPixel = boundingRect.top + Math.floor(boundingRect.height / 2);
--- a/browser/base/content/test/general/browser_bug321000.js
+++ b/browser/base/content/test/general/browser_bug321000.js
@@ -63,18 +63,17 @@ function test_paste(aCurrentTest) {
 
   // Focus the window.
   window.focus();
   gBrowser.selectedBrowser.focus();
 
   // Focus the element and wait for focus event.
   info("About to focus " + element.id);
   element.addEventListener("focus", function() {
-    element.removeEventListener("focus", arguments.callee);
     executeSoon(function() {
       // Pasting is async because the Accel+V codepath ends up going through
       // nsDocumentViewer::FireClipboardEvent.
       info("Pasting into " + element.id);
       EventUtils.synthesizeKey("v", { accelKey: true });
     });
-  });
+  }, {once: true});
   element.focus();
 }
--- a/browser/base/content/test/general/browser_bug406216.js
+++ b/browser/base/content/test/general/browser_bug406216.js
@@ -20,35 +20,33 @@ function test() {
 }
 
 function addTab(aURI, aIndex) {
   var tab = gBrowser.addTab(aURI);
   if (aIndex == 0)
     gBrowser.removeTab(gBrowser.tabs[0], {skipPermitUnload: true});
 
   tab.linkedBrowser.addEventListener("load", function(event) {
-    event.currentTarget.removeEventListener("load", arguments.callee, true);
     if (++count == URIS.length)
       executeSoon(doTabsTest);
-  }, true);
+  }, {capture: true, once: true});
 }
 
 function doTabsTest() {
   is(gBrowser.tabs.length, URIS.length, "Correctly opened all expected tabs");
 
   // sample of "close related tabs" feature
   gBrowser.tabContainer.addEventListener("TabClose", function(event) {
-    event.currentTarget.removeEventListener("TabClose", arguments.callee, true);
     var closedTab = event.originalTarget;
     var scheme = closedTab.linkedBrowser.currentURI.scheme;
     Array.slice(gBrowser.tabs).forEach(function(aTab) {
       if (aTab != closedTab && aTab.linkedBrowser.currentURI.scheme == scheme)
         gBrowser.removeTab(aTab, {skipPermitUnload: true});
     });
-  }, true);
+  }, {capture: true, once: true});
 
   gBrowser.removeTab(gBrowser.tabs[0], {skipPermitUnload: true});
   is(gBrowser.tabs.length, 1, "Related tabs are not closed unexpectedly");
 
   gBrowser.addTab("about:blank");
   gBrowser.removeTab(gBrowser.tabs[0], {skipPermitUnload: true});
   finish();
 }
--- a/browser/base/content/test/general/browser_bug432599.js
+++ b/browser/base/content/test/general/browser_bug432599.js
@@ -39,20 +39,19 @@ function add_bookmark(aURI, aTitle) {
                                               aTitle);
 }
 
 // test bug 432599
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
-    gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
+  gBrowser.selectedBrowser.addEventListener("load", function() {
     waitForStarChange(false, initTest);
-  }, true);
+  }, {capture: true, once: true});
 
   content.location = testURL;
 }
 
 function initTest() {
   // First, bookmark the page.
   bookmarkId = add_bookmark(makeURI(testURL), "Bug 432599 Test");
 
--- a/browser/base/content/test/general/browser_bug460146.js
+++ b/browser/base/content/test/general/browser_bug460146.js
@@ -1,40 +1,37 @@
 /* Check proper image url retrieval from all kinds of elements/styles */
 
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = gBrowser.addTab();
 
   gBrowser.selectedBrowser.addEventListener("load", function() {
-    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-
     var pageInfo = BrowserPageInfo(gBrowser.selectedBrowser.currentURI.spec,
                                    "mediaTab");
 
     pageInfo.addEventListener("load", function() {
-      pageInfo.removeEventListener("load", arguments.callee, true);
       pageInfo.onFinished.push(function() {
         executeSoon(function() {
           var imageTree = pageInfo.document.getElementById("imagetree");
           var imageRowsNum = imageTree.view.rowCount;
 
           ok(imageTree, "Image tree is null (media tab is broken)");
 
           ok(imageRowsNum == 7, "Number of images listed: " +
                                 imageRowsNum + ", should be 7");
 
           pageInfo.close();
           gBrowser.removeCurrentTab();
           finish();
         });
       });
-    }, true);
-  }, true);
+    }, {capture: true, once: true});
+  }, {capture: true, once: true});
 
   content.location =
     "data:text/html," +
     "<html>" +
     "  <head>" +
     "    <title>Test for media tab</title>" +
     "    <link rel='shortcut icon' href='file:///dummy_icon.ico'>" + // Icon
     "  </head>" +
--- a/browser/base/content/test/general/browser_bug479408.js
+++ b/browser/base/content/test/general/browser_bug479408.js
@@ -1,17 +1,15 @@
 function test() {
   waitForExplicitFinish();
   let tab = gBrowser.selectedTab = gBrowser.addTab(
     "http://mochi.test:8888/browser/browser/base/content/test/general/browser_bug479408_sample.html");
 
   gBrowser.addEventListener("DOMLinkAdded", function(aEvent) {
-    gBrowser.removeEventListener("DOMLinkAdded", arguments.callee, true);
-
     executeSoon(function() {
       ok(!tab.linkedBrowser.engines,
          "the subframe's search engine wasn't detected");
 
       gBrowser.removeTab(tab);
       finish();
     });
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/base/content/test/general/browser_bug491431.js
+++ b/browser/base/content/test/general/browser_bug491431.js
@@ -7,28 +7,26 @@ var testPage = "data:text/plain,test bug
 function test() {
   waitForExplicitFinish();
 
   let newWin, tabA, tabB;
 
   // test normal close
   tabA = gBrowser.addTab(testPage);
   gBrowser.tabContainer.addEventListener("TabClose", function(firstTabCloseEvent) {
-    gBrowser.tabContainer.removeEventListener("TabClose", arguments.callee, true);
     ok(!firstTabCloseEvent.detail.adoptedBy, "This was a normal tab close");
 
     // test tab close by moving
     tabB = gBrowser.addTab(testPage);
     gBrowser.tabContainer.addEventListener("TabClose", function(secondTabCloseEvent) {
-      gBrowser.tabContainer.removeEventListener("TabClose", arguments.callee, true);
       executeSoon(function() {
         ok(secondTabCloseEvent.detail.adoptedBy, "This was a tab closed by moving");
 
         // cleanup
         newWin.close();
         executeSoon(finish);
       });
-    }, true);
+    }, {capture: true, once: true});
     newWin = gBrowser.replaceTabWithWindow(tabB);
-  }, true);
+  }, {capture: true, once: true});
   gBrowser.removeTab(tabA);
 }
 
--- a/browser/base/content/test/general/browser_bug517902.js
+++ b/browser/base/content/test/general/browser_bug517902.js
@@ -1,40 +1,37 @@
 /* Make sure that "View Image Info" loads the correct image data */
 
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = gBrowser.addTab();
 
   gBrowser.selectedBrowser.addEventListener("load", function() {
-    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-
     var doc = gBrowser.contentDocument;
     var testImg = doc.getElementById("test-image");
     var pageInfo = BrowserPageInfo(gBrowser.selectedBrowser.currentURI.spec,
                                    "mediaTab", testImg);
 
     pageInfo.addEventListener("load", function() {
-      pageInfo.removeEventListener("load", arguments.callee, true);
       pageInfo.onFinished.push(function() {
         executeSoon(function() {
           var pageInfoImg = pageInfo.document.getElementById("thepreviewimage");
 
           is(pageInfoImg.src, testImg.src, "selected image has the correct source");
           is(pageInfoImg.width, testImg.width, "selected image has the correct width");
           is(pageInfoImg.height, testImg.height, "selected image has the correct height");
 
           pageInfo.close();
           gBrowser.removeCurrentTab();
           finish();
         });
       });
-    }, true);
-  }, true);
+    }, {capture: true, once: true});
+  }, {capture: true, once: true});
 
   content.location =
     "data:text/html," +
     "<style type='text/css'>%23test-image,%23not-test-image {background-image: url('about:logo?c');}</style>" +
     "<img src='about:logo?b' height=300 width=350 alt=2 id='not-test-image'>" +
     "<img src='about:logo?b' height=300 width=350 alt=2>" +
     "<img src='about:logo?a' height=200 width=250>" +
     "<img src='about:logo?b' height=200 width=250 alt=1>" +
--- a/browser/base/content/test/general/browser_bug553455.js
+++ b/browser/base/content/test/general/browser_bug553455.js
@@ -56,20 +56,19 @@ function waitForProgressNotification(aPa
       }, topic, false);
     });
 
     let panelEventPromise;
     if (aPanelOpen) {
       panelEventPromise = Promise.resolve();
     } else {
       panelEventPromise = new Promise(resolve => {
-        PopupNotifications.panel.addEventListener("popupshowing", function eventListener() {
-          PopupNotifications.panel.removeEventListener("popupshowing", eventListener);
+        PopupNotifications.panel.addEventListener("popupshowing", function() {
           resolve();
-        });
+        }, {once: true});
       });
     }
 
     yield observerPromise;
     yield panelEventPromise;
 
     info("Saw a notification");
     ok(PopupNotifications.isPanelOpen, "Panel should be open");
@@ -129,20 +128,19 @@ function waitForNotification(aId, aExpec
 
     return PopupNotifications.panel;
   });
 }
 
 function waitForNotificationClose() {
   return new Promise(resolve => {
     info("Waiting for notification to close");
-    PopupNotifications.panel.addEventListener("popuphidden", function listener() {
-      PopupNotifications.panel.removeEventListener("popuphidden", listener);
+    PopupNotifications.panel.addEventListener("popuphidden", function() {
       resolve();
-    });
+    }, {once: true});
   });
 }
 
 function waitForInstallDialog() {
   return Task.spawn(function* () {
     if (Preferences.get("xpinstall.customConfirmationUI", false)) {
       let panel = yield waitForNotification("addon-install-confirmation");
       return panel.childNodes[0];
--- a/browser/base/content/test/general/browser_bug581242.js
+++ b/browser/base/content/test/general/browser_bug581242.js
@@ -7,15 +7,14 @@ function test() {
   let blanktab = gBrowser.addTab();
   gBrowser.selectedTab = blanktab;
   BrowserOpenAddonsMgr();
 
   is(blanktab, gBrowser.selectedTab, "Current tab should be blank tab");
   // Verify that about:addons loads
   waitForExplicitFinish();
   gBrowser.selectedBrowser.addEventListener("load", function() {
-    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
     let browser = blanktab.linkedBrowser;
     is(browser.currentURI.spec, "about:addons", "about:addons should load into blank tab.");
     gBrowser.removeTab(blanktab);
     finish();
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/base/content/test/general/browser_bug581253.js
+++ b/browser/base/content/test/general/browser_bug581253.js
@@ -12,28 +12,26 @@ function test() {
     if (timerID > 0) {
       clearTimeout(timerID);
     }
   });
   waitForExplicitFinish();
 
   let tab = gBrowser.selectedTab = gBrowser.addTab();
   tab.linkedBrowser.addEventListener("load", (function(event) {
-    tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
     let uri = makeURI(testURL);
     let bmTxn =
       new PlacesCreateBookmarkTransaction(uri,
                                           PlacesUtils.unfiledBookmarksFolderId,
                                           -1, "", null, []);
     PlacesUtils.transactionManager.doTransaction(bmTxn);
 
     ok(PlacesUtils.bookmarks.isBookmarked(uri), "the test url is bookmarked");
     waitForStarChange(true, onStarred);
-  }), true);
+  }), {capture: true, once: true});
 
   content.location = testURL;
 }
 
 function waitForStarChange(aValue, aCallback) {
   let expectedStatus = aValue ? BookmarkingUI.STATUS_STARRED
                               : BookmarkingUI.STATUS_UNSTARRED;
   if (BookmarkingUI.status == BookmarkingUI.STATUS_UPDATING ||
--- a/browser/base/content/test/general/browser_bug592338.js
+++ b/browser/base/content/test/general/browser_bug592338.js
@@ -5,19 +5,18 @@
 const TESTROOT = "http://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/";
 
 var tempScope = {};
 Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", tempScope);
 var LightweightThemeManager = tempScope.LightweightThemeManager;
 
 function wait_for_notification(aCallback) {
   PopupNotifications.panel.addEventListener("popupshown", function() {
-    PopupNotifications.panel.removeEventListener("popupshown", arguments.callee);
     aCallback(PopupNotifications.panel);
-  });
+  }, {once: true});
 }
 
 var TESTS = [
 function test_install_http() {
   is(LightweightThemeManager.currentTheme, null, "Should be no lightweight theme selected");
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.org/"), "install", pm.ALLOW_ACTION);
--- a/browser/base/content/test/general/browser_bug623893.js
+++ b/browser/base/content/test/general/browser_bug623893.js
@@ -25,23 +25,21 @@ function runTests() {
 }
 
 function duplicate(delta, msg, cb) {
   var start = gBrowser.sessionHistory.index;
 
   duplicateTabIn(gBrowser.selectedTab, "tab", delta);
   let tab = gBrowser.selectedTab;
 
-  tab.addEventListener("SSTabRestored", function tabRestoredListener() {
-    tab.removeEventListener("SSTabRestored", tabRestoredListener);
+  tab.addEventListener("SSTabRestored", function() {
     is(gBrowser.sessionHistory.index, start + delta, msg);
     executeSoon(cb);
-  });
+  }, {once: true});
 }
 
 function loadAndWait(url, cb) {
   gBrowser.selectedBrowser.addEventListener("load", function() {
-    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
     executeSoon(cb);
-  }, true);
+  }, {capture: true, once: true});
 
   gBrowser.loadURI(url);
 }
--- a/browser/base/content/test/general/browser_bug664672.js
+++ b/browser/base/content/test/general/browser_bug664672.js
@@ -1,19 +1,17 @@
 function test() {
   waitForExplicitFinish();
 
   var tab = gBrowser.addTab();
 
   tab.addEventListener("TabClose", function() {
-    tab.removeEventListener("TabClose", arguments.callee);
-
     ok(tab.linkedBrowser, "linkedBrowser should still exist during the TabClose event");
 
     executeSoon(function() {
       ok(!tab.linkedBrowser, "linkedBrowser should be gone after the TabClose event");
 
       finish();
     });
-  });
+  }, {once: true});
 
   gBrowser.removeTab(tab);
 }
--- a/browser/base/content/test/general/browser_bug678392.js
+++ b/browser/base/content/test/general/browser_bug678392.js
@@ -30,20 +30,19 @@ function test() {
   is(gHistorySwipeAnimation.active, true, "History swipe animation support " +
      "was successfully initialized when supported.");
 
   cleanupArray();
   load(gBrowser.selectedTab, HTTPROOT + "browser_bug678392-2.html", test0);
 }
 
 function load(aTab, aUrl, aCallback) {
-  aTab.linkedBrowser.addEventListener("load", function onload(aEvent) {
-    aEvent.currentTarget.removeEventListener("load", onload, true);
+  aTab.linkedBrowser.addEventListener("load", function(aEvent) {
     waitForFocus(aCallback, content);
-  }, true);
+  }, {capture: true, once: true});
   aTab.linkedBrowser.loadURI(aUrl);
 }
 
 function cleanupArray() {
   let arr = gHistorySwipeAnimation._trackedSnapshots;
   while (arr.length > 0) {
     delete arr[0].browser.snapshots[arr[0].index]; // delete actual snapshot
     arr.splice(0, 1);
--- a/browser/base/content/test/general/browser_bug734076.js
+++ b/browser/base/content/test/general/browser_bug734076.js
@@ -60,20 +60,19 @@ add_task(function* () {
         return ContentTask.spawn(gBrowser.selectedBrowser, { writeDomainURL }, function* (arg) {
           let doc = content.document;
           let iframe = doc.createElement("iframe");
           iframe.setAttribute("src", arg.writeDomainURL);
           doc.body.insertBefore(iframe, doc.body.firstChild);
 
           // Wait for the iframe to load.
           return new Promise(resolve => {
-            iframe.addEventListener("load", function onload() {
-              iframe.removeEventListener("load", onload, true);
+            iframe.addEventListener("load", function() {
               resolve("context-showonlythisframe");
-            }, true);
+            }, {capture: true, once: true});
           });
         });
       },
       verify() {
         return ContentTask.spawn(gBrowser.selectedBrowser, null, function* (arg) {
           Assert.ok(!content.document.body.textContent,
             "no domain was inherited for 'show only this frame'");
         });
--- a/browser/base/content/test/general/browser_bug749738.js
+++ b/browser/base/content/test/general/browser_bug749738.js
@@ -23,14 +23,13 @@ function test() {
     } catch (e) {
       ok(false, "findbar.close threw exception: " + e);
     }
     finish();
   });
 }
 
 function load(aTab, aUrl, aCallback) {
-  aTab.linkedBrowser.addEventListener("load", function onload(aEvent) {
-    aEvent.currentTarget.removeEventListener("load", onload, true);
+  aTab.linkedBrowser.addEventListener("load", function(aEvent) {
     waitForFocus(aCallback, content);
-  }, true);
+  }, {capture: true, once: true});
   aTab.linkedBrowser.loadURI(aUrl);
 }
--- a/browser/base/content/test/general/browser_bug767836_perwindowpb.js
+++ b/browser/base/content/test/general/browser_bug767836_perwindowpb.js
@@ -78,13 +78,12 @@ function openNewTab(aWindow, aCallback) 
   aWindow.BrowserOpenTab();
 
   let browser = aWindow.gBrowser.selectedBrowser;
   if (browser.contentDocument.readyState === "complete") {
     executeSoon(aCallback);
     return;
   }
 
-  browser.addEventListener("load", function onLoad() {
-    browser.removeEventListener("load", onLoad, true);
+  browser.addEventListener("load", function() {
     executeSoon(aCallback);
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/base/content/test/general/browser_bug817947.js
+++ b/browser/base/content/test/general/browser_bug817947.js
@@ -43,13 +43,12 @@ function preparePendingTab(aCallback) {
         ok(tab.hasAttribute("pending"), "tab should be pending");
         aCallback(tab);
       });
     });
   });
 }
 
 function whenLoaded(aElement, aCallback) {
-  aElement.addEventListener("load", function onLoad() {
-    aElement.removeEventListener("load", onLoad, true);
+  aElement.addEventListener("load", function() {
     executeSoon(aCallback);
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/base/content/test/general/browser_bug832435.js
+++ b/browser/base/content/test/general/browser_bug832435.js
@@ -2,22 +2,21 @@
  * 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(true, "Starting up");
 
   gBrowser.selectedBrowser.focus();
-  gURLBar.addEventListener("focus", function onFocus() {
-    gURLBar.removeEventListener("focus", onFocus);
+  gURLBar.addEventListener("focus", function() {
     ok(true, "Invoked onfocus handler");
     EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true });
 
     // javscript: URIs are evaluated async.
     SimpleTest.executeSoon(function() {
       ok(true, "Evaluated without crashing");
       finish();
     });
-  });
+  }, {once: true});
   gURLBar.inputField.value = "javascript: var foo = '11111111'; ";
   gURLBar.focus();
 }
--- a/browser/base/content/test/general/browser_clipboard_pastefile.js
+++ b/browser/base/content/test/general/browser_clipboard_pastefile.js
@@ -5,24 +5,23 @@ add_task(function*() {
   var textbox = document.createElement("textbox");
   document.documentElement.appendChild(textbox);
 
   textbox.focus();
   textbox.value = "Text";
   textbox.select();
 
   yield new Promise((resolve, reject) => {
-    textbox.addEventListener("copy", function copyEvent(event) {
-      textbox.removeEventListener("copy", copyEvent, true);
+    textbox.addEventListener("copy", function(event) {
       event.clipboardData.setData("text/plain", "Alternate");
       // For this test, it doesn't matter that the file isn't actually a file.
       event.clipboardData.setData("application/x-moz-file", "Sample");
       event.preventDefault();
       resolve();
-    }, true)
+    }, {capture: true, once: true})
 
     EventUtils.synthesizeKey("c", { accelKey: true });
   });
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
               "https://example.com/browser/browser/base/content/test/general/clipboard_pastefile.html");
   let browser = tab.linkedBrowser;
 
@@ -35,28 +34,26 @@ add_task(function*() {
   let output = yield ContentTask.spawn(browser, { }, function* (arg) {
     return content.document.getElementById("output").textContent;
   });
   is(output, "Passed", "Paste file");
 
   textbox.focus();
 
   yield new Promise((resolve, reject) => {
-    textbox.addEventListener("paste", function copyEvent(event) {
-      textbox.removeEventListener("paste", copyEvent, true);
-
+    textbox.addEventListener("paste", function(event) {
       let dt = event.clipboardData;
       is(dt.types.length, 3, "number of types");
       ok(dt.types.includes("text/plain"), "text/plain exists in types");
       ok(dt.mozTypesAt(0).contains("text/plain"), "text/plain exists in mozTypesAt");
       is(dt.getData("text/plain"), "Alternate", "text/plain returned in getData");
       is(dt.mozGetDataAt("text/plain", 0), "Alternate", "text/plain returned in mozGetDataAt");
 
       resolve();
-    }, true);
+    }, {capture: true, once: true});
 
     EventUtils.synthesizeKey("v", { accelKey: true });
   });
 
   document.documentElement.removeChild(textbox);
 
   yield BrowserTestUtils.removeTab(tab);
 });
--- a/browser/base/content/test/general/browser_close_dependent_tabs.js
+++ b/browser/base/content/test/general/browser_close_dependent_tabs.js
@@ -2,21 +2,20 @@ add_task(function* () {
   yield 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 bcp(e) {
-        browser.removeEventListener("BrowserChangedProcess", bcp);
+      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() {
--- a/browser/base/content/test/general/browser_datachoices_notification.js
+++ b/browser/base/content/test/general/browser_datachoices_notification.js
@@ -40,20 +40,19 @@ function promiseNextTick() {
 
 /**
  * Wait for a notification to be shown in a notification box.
  * @param {Object} aNotificationBox The notification box.
  * @return {Promise} Resolved when the notification is displayed.
  */
 function promiseWaitForAlertActive(aNotificationBox) {
   let deferred = PromiseUtils.defer();
-  aNotificationBox.addEventListener("AlertActive", function onActive() {
-    aNotificationBox.removeEventListener("AlertActive", onActive, true);
+  aNotificationBox.addEventListener("AlertActive", function() {
     deferred.resolve();
-  });
+  }, {once: true});
   return deferred.promise;
 }
 
 /**
  * Wait for a notification to be closed.
  * @param {Object} aNotification The notification.
  * @return {Promise} Resolved when the notification is closed.
  */
--- a/browser/base/content/test/general/browser_discovery.js
+++ b/browser/base/content/test/general/browser_discovery.js
@@ -1,30 +1,28 @@
 var browser;
 
 function doc() {
   return browser.contentDocument;
 }
 
 function setHandlerFunc(aResultFunc) {
   gBrowser.addEventListener("DOMLinkAdded", function(event) {
-    gBrowser.removeEventListener("DOMLinkAdded", arguments.callee);
     executeSoon(aResultFunc);
-  });
+  }, {once: true});
 }
 
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = gBrowser.addTab();
   browser = gBrowser.selectedBrowser;
   browser.addEventListener("load", function(event) {
-    event.currentTarget.removeEventListener("load", arguments.callee, true);
     iconDiscovery();
-  }, true);
+  }, {capture: true, once: true});
   var rootDir = getRootDirectory(gTestPath);
   content.location = rootDir + "discovery.html";
 }
 
 var iconDiscoveryTests = [
   { text: "rel icon discovered" },
   { rel: "abcdefg icon qwerty", text: "rel may contain additional rels separated by spaces" },
   { rel: "ICON", text: "rel is case insensitive" },
--- a/browser/base/content/test/general/browser_documentnavigation.js
+++ b/browser/base/content/test/general/browser_documentnavigation.js
@@ -43,28 +43,26 @@ function* expectFocusOnF6(backward, expe
       }
 
       if (!contentExpectedElement) {
         sendSyncMessage("BrowserTest:FocusChanged",
                         { details : "expected element " + arg.expectedElementId + " not found" });
         return;
       }
 
-      contentExpectedElement.addEventListener("focus", function focusReceived() {
-        contentExpectedElement.removeEventListener("focus", focusReceived, true);
-
+      contentExpectedElement.addEventListener("focus", function() {
         const contentFM = Components.classes["@mozilla.org/focus-manager;1"].
                             getService(Components.interfaces.nsIFocusManager);
         let details = contentFM.focusedWindow.document.documentElement.id;
         if (contentFM.focusedElement) {
           details += "," + contentFM.focusedElement.id;
         }
 
         sendSyncMessage("BrowserTest:FocusChanged", { details });
-      }, true);
+      }, {capture: true, once: true});
     });
   }
 
   EventUtils.synthesizeKey("VK_F6", { shiftKey: backward });
   yield focusPromise;
 
   if (typeof expectedElement == "string") {
     expectedElement = fm.focusedWindow.document.getElementById(expectedElement);
--- a/browser/base/content/test/general/browser_focusonkeydown.js
+++ b/browser/base/content/test/general/browser_focusonkeydown.js
@@ -1,25 +1,23 @@
 add_task(function *() {
   let keyUps = 0;
 
   yield BrowserTestUtils.openNewForegroundTab(gBrowser, "data:text/html,<body>");
 
   gURLBar.focus();
 
-  window.addEventListener("keyup", function countKeyUps(event) {
-    window.removeEventListener("keyup", countKeyUps, true);
+  window.addEventListener("keyup", function(event) {
     if (event.originalTarget == gURLBar.inputField) {
       keyUps++;
     }
-  }, true);
+  }, {capture: true, once: true});
 
-  gURLBar.addEventListener("keydown", function redirectFocus(event) {
-    gURLBar.removeEventListener("keydown", redirectFocus, true);
+  gURLBar.addEventListener("keydown", function(event) {
     gBrowser.selectedBrowser.focus();
-  }, true);
+  }, {capture: true, once: true});
 
   EventUtils.synthesizeKey("v", { });
 
   is(keyUps, 1, "Key up fired at url bar");
 
   gBrowser.removeCurrentTab();
 });
--- a/browser/base/content/test/general/browser_hide_removing.js
+++ b/browser/base/content/test/general/browser_hide_removing.js
@@ -9,23 +9,21 @@ function test() {
 
   // Add a tab that will get removed and hidden
   let testTab = gBrowser.addTab("about:blank", {skipAnimation: true});
   is(gBrowser.visibleTabs.length, 2, "just added a tab, so 2 tabs");
   gBrowser.selectedTab = testTab;
 
   let numVisBeforeHide, numVisAfterHide;
   gBrowser.tabContainer.addEventListener("TabSelect", function() {
-    gBrowser.tabContainer.removeEventListener("TabSelect", arguments.callee);
-
     // While the next tab is being selected, hide the removing tab
     numVisBeforeHide = gBrowser.visibleTabs.length;
     gBrowser.hideTab(testTab);
     numVisAfterHide = gBrowser.visibleTabs.length;
-  });
+  }, {once: true});
   gBrowser.removeTab(testTab, {animate: true});
 
   // Make sure the tab gets removed at the end of the animation by polling
   (function checkRemoved() {
     return setTimeout(function() {
       if (gBrowser.tabs.length != 1) {
         checkRemoved();
         return;
--- a/browser/base/content/test/general/browser_keywordBookmarklets.js
+++ b/browser/base/content/test/general/browser_keywordBookmarklets.js
@@ -41,14 +41,13 @@ add_task(function* test_keyword_bookmark
   } else {
     ok(gBrowser.contentPrincipal.equals(originalPrincipal),
        "javascript bookmarklet should inherit principal");
   }
 });
 
 function* promisePageShow() {
   return new Promise(resolve => {
-    gBrowser.selectedBrowser.addEventListener("pageshow", function listen() {
-      gBrowser.selectedBrowser.removeEventListener("pageshow", listen);
+    gBrowser.selectedBrowser.addEventListener("pageshow", function() {
       resolve();
-    });
+    }, {once: true});
   });
 }
--- a/browser/base/content/test/general/browser_keywordSearch.js
+++ b/browser/base/content/test/general/browser_keywordSearch.js
@@ -20,19 +20,18 @@ function test() {
   waitForExplicitFinish();
 
   let windowObserver = {
     observe(aSubject, aTopic, aData) {
       if (aTopic == "domwindowopened") {
         ok(false, "Alert window opened");
         let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
         win.addEventListener("load", function() {
-          win.removeEventListener("load", arguments.callee);
           win.close();
-        });
+        }, {once: true});
         executeSoon(finish);
       }
     }
   };
 
   Services.ww.registerNotification(windowObserver);
 
   let tab = gBrowser.selectedTab = gBrowser.addTab();
--- a/browser/base/content/test/general/browser_newwindow_focus.js
+++ b/browser/base/content/test/general/browser_newwindow_focus.js
@@ -18,20 +18,19 @@ const PAGE = `data:text/html,<a id="targ
  * Promises infrastructure.
  */
 function promiseNewWindow() {
   return new Promise((resolve) => {
     let observer = (subject, topic, data) => {
       if (topic == "domwindowopened") {
         Services.ww.unregisterNotification(observer);
         let win = subject.QueryInterface(Ci.nsIDOMWindow);
-        win.addEventListener("load", function onLoad() {
-          win.removeEventListener("load", onLoad);
+        win.addEventListener("load", function() {
           resolve(win);
-        });
+        }, {once: true});
       }
     };
 
     Services.ww.registerNotification(observer);
   });
 }
 
 /**
--- a/browser/base/content/test/general/browser_offlineQuotaNotification.js
+++ b/browser/base/content/test/general/browser_offlineQuotaNotification.js
@@ -63,33 +63,31 @@ function test() {
     gotCached.then(function() {
       // We got cached - now we should have provoked the quota warning.
       let notification = PopupNotifications.getNotification("offline-app-usage");
       ok(notification, "have offline-app-usage notification");
       // select the default action - this should cause the preferences
       // tab to open - which we track via an "Initialized" event.
       PopupNotifications.panel.firstElementChild.button.click();
       let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
-      newTabBrowser.addEventListener("Initialized", function PrefInit() {
-        newTabBrowser.removeEventListener("Initialized", PrefInit, true);
+      newTabBrowser.addEventListener("Initialized", function() {
         executeSoon(function() {
           checkInContentPreferences(newTabBrowser.contentWindow);
         })
-      }, true);
+      }, {capture: true, once: true});
     });
     onCachedAttached.then(function() {
       Services.prefs.setIntPref("offline-apps.quota.warn", 1);
 
       // Click the notification panel's "Allow" button.  This should kick
       // off updates which will call our oncached handler above.
       PopupNotifications.panel.firstElementChild.button.click();
     });
   });
 }
 
 function promiseNotification() {
   return new Promise(resolve => {
-    PopupNotifications.panel.addEventListener("popupshown", function onShown() {
-      PopupNotifications.panel.removeEventListener("popupshown", onShown);
+    PopupNotifications.panel.addEventListener("popupshown", function() {
       resolve();
-    });
+    }, {once: true});
   });
 }
--- a/browser/base/content/test/general/browser_pageInfo.js
+++ b/browser/base/content/test/general/browser_pageInfo.js
@@ -1,20 +1,18 @@
 function test() {
   waitForExplicitFinish();
 
   var pageInfo;
 
   gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", function loadListener() {
-    gBrowser.selectedBrowser.removeEventListener("load", loadListener, true);
-
+  gBrowser.selectedBrowser.addEventListener("load", function() {
     Services.obs.addObserver(observer, "page-info-dialog-loaded", false);
     pageInfo = BrowserPageInfo();
-  }, true);
+  }, {capture: true, once: true});
   content.location =
     "https://example.com/browser/browser/base/content/test/general/feed_tab.html";
 
   function observer(win, topic, data) {
     Services.obs.removeObserver(observer, "page-info-dialog-loaded");
     pageInfo.onFinished.push(handlePageInfo);
   }
 
--- a/browser/base/content/test/general/browser_sanitizeDialog.js
+++ b/browser/base/content/test/general/browser_sanitizeDialog.js
@@ -781,25 +781,23 @@ WindowHelper.prototype = {
         return;
 
       Services.ww.unregisterNotification(windowObserver);
 
       var loaded = false;
       let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
 
       win.addEventListener("load", function onload(event) {
-        win.removeEventListener("load", onload);
-
         if (win.name !== "SanitizeDialog")
           return;
 
         wh.win = win;
         loaded = true;
         executeSoon(() => wh.onload());
-      });
+      }, {once: true});
 
       win.addEventListener("unload", function onunload(event) {
         if (win.name !== "SanitizeDialog") {
           win.removeEventListener("unload", onunload);
           return;
         }
 
         // Why is unload fired before load?
--- a/browser/base/content/test/general/browser_save_link_when_window_navigates.js
+++ b/browser/base/content/test/general/browser_save_link_when_window_navigates.js
@@ -99,30 +99,28 @@ var windowObserver = {
   },
   observe(aSubject, aTopic, aData) {
     if (aTopic != "domwindowopened") {
       return;
     }
 
     let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
 
-    win.addEventListener("load", function onLoad(event) {
-      win.removeEventListener("load", onLoad);
-
+    win.addEventListener("load", function(event) {
       if (win.location == UCT_URI) {
         SimpleTest.executeSoon(function() {
           if (windowObserver._callback) {
             windowObserver._callback(win);
             delete windowObserver._callback;
           } else {
             ok(false, "Unexpected UCT dialog!");
           }
         });
       }
-    });
+    }, {once: true});
   }
 };
 
 Services.ww.registerNotification(windowObserver);
 
 function test() {
   waitForExplicitFinish();
 
--- a/browser/base/content/test/general/browser_selectpopup.js
+++ b/browser/base/content/test/general/browser_selectpopup.js
@@ -324,20 +324,19 @@ add_task(function*() {
         let elem;
         if (contentStep[0] == "select") {
           changedWin = content.document.getElementById("frame").contentWindow;
           elem = changedWin.document.getElementById("select");
         } else {
           elem = content.document.getElementById(contentStep[0]);
         }
 
-        changedWin.addEventListener("MozAfterPaint", function onPaint() {
-          changedWin.removeEventListener("MozAfterPaint", onPaint);
+        changedWin.addEventListener("MozAfterPaint", function() {
           resolve();
-        });
+        }, {once: true});
 
         elem.style = contentStep[1];
         elem.getBoundingClientRect();
       });
     });
 
     yield openSelectPopup(selectPopup);
 
@@ -670,21 +669,20 @@ add_task(function* test_mousemove_correc
 
   let selectPopup = document.getElementById("ContentSelectDropdown").menupopup;
 
   let popupShownPromise = BrowserTestUtils.waitForEvent(selectPopup, "popupshown");
   yield BrowserTestUtils.synthesizeMouseAtCenter("#one", { type: "mousedown" }, gBrowser.selectedBrowser);
   yield popupShownPromise;
 
   yield new Promise(resolve => {
-    window.addEventListener("mousemove", function checkForMouseMove(event) {
-      window.removeEventListener("mousemove", checkForMouseMove, true);
+    window.addEventListener("mousemove", function(event) {
       is(event.target.localName.indexOf("menu"), 0, "mouse over menu");
       resolve();
-    }, true);
+    }, {capture: true, once: true});
 
     EventUtils.synthesizeMouseAtCenter(selectPopup.firstChild, { type: "mousemove" });
   });
 
   yield BrowserTestUtils.synthesizeMouseAtCenter("#one", { type: "mouseup" }, gBrowser.selectedBrowser);
 
   yield hideSelectPopup(selectPopup);
 
--- a/browser/base/content/test/general/browser_subframe_favicons_not_used.js
+++ b/browser/base/content/test/general/browser_subframe_favicons_not_used.js
@@ -3,18 +3,16 @@
 function test() {
   waitForExplicitFinish();
 
   let testPath = getRootDirectory(gTestPath);
 
   let tab = gBrowser.addTab(testPath + "file_bug970276_popup1.html");
 
   tab.linkedBrowser.addEventListener("load", function() {
-    tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
     let expectedIcon = testPath + "file_bug970276_favicon1.ico";
     is(gBrowser.getIcon(tab), expectedIcon, "Correct icon.");
 
     gBrowser.removeTab(tab);
 
     finish();
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/base/content/test/general/browser_tabfocus.js
+++ b/browser/base/content/test/general/browser_tabfocus.js
@@ -219,20 +219,19 @@ add_task(function*() {
                          "main-window", "tab2", true,
                          "focusing tab element");
   yield* expectFocusShiftAfterTabSwitch(tab1, "main-window", "tab1", true,
                                         "tab change when selected tab element was focused");
 
   let switchWaiter;
   if (gMultiProcessBrowser) {
     switchWaiter = new Promise((resolve, reject) => {
-      gBrowser.addEventListener("TabSwitchDone", function listener() {
-        gBrowser.removeEventListener("TabSwitchDone", listener);
+      gBrowser.addEventListener("TabSwitchDone", function() {
         executeSoon(resolve);
-      });
+      }, {once: true});
     });
   }
 
   yield* expectFocusShiftAfterTabSwitch(tab2, "main-window", "tab2", true,
                                         "another tab change when selected tab element was focused");
 
   // When this a remote browser, wait for the paint on the second browser so that
   // any post tab-switching stuff has time to complete before blurring the tab.
@@ -321,20 +320,19 @@ add_task(function*() {
                          "focus button");
 
   yield promiseTabLoadEvent(tab1, "data:text/html," + escape(testPage3));
 
   // now go back again
   gURLBar.focus();
 
   yield new Promise((resolve, reject) => {
-    window.addEventListener("pageshow", function navigationOccured(event) {
-      window.removeEventListener("pageshow", navigationOccured, true);
+    window.addEventListener("pageshow", function(event) {
       resolve();
-    }, true);
+    }, {capture: true, once: true});
     document.getElementById("Browser:Back").doCommand();
   });
 
   is(window.document.activeElement, gURLBar.inputField, "urlbar still focused after navigating back");
 
   // Document navigation with F6 does not yet work in mutli-process browsers.
   if (!gMultiProcessBrowser) {
     gURLBar.focus();
--- a/browser/base/content/test/general/browser_tabs_isActive.js
+++ b/browser/base/content/test/general/browser_tabs_isActive.js
@@ -2,20 +2,19 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test for the docshell active state of local and remote browsers.
 
 const kTestPage = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
 
 function promiseNewTabSwitched() {
   return new Promise(resolve => {
-    gBrowser.addEventListener("TabSwitchDone", function onSwitch() {
-      gBrowser.removeEventListener("TabSwitchDone", onSwitch);
+    gBrowser.addEventListener("TabSwitchDone", function() {
       executeSoon(resolve);
-    });
+    }, {once: true});
   });
 }
 
 function getParentTabState(aTab) {
   return aTab.linkedBrowser.docShellIsActive;
 }
 
 function getChildTabState(aTab) {
--- a/browser/base/content/test/general/browser_visibleTabs_bookmarkAllTabs.js
+++ b/browser/base/content/test/general/browser_visibleTabs_bookmarkAllTabs.js
@@ -14,17 +14,16 @@ function test() {
   let testTab1 = gBrowser.addTab();
   is(gBrowser.visibleTabs.length, 2, "2 tabs should be open");
   is(Disabled(), true, "Bookmark All Tabs should be disabled since there are two tabs with the same address");
 
   let testTab2 = gBrowser.addTab("about:mozilla");
   is(gBrowser.visibleTabs.length, 3, "3 tabs should be open");
   // Wait for tab load, the code checks for currentURI.
   testTab2.linkedBrowser.addEventListener("load", function() {
-    testTab2.linkedBrowser.removeEventListener("load", arguments.callee, true);
     is(Disabled(), false, "Bookmark All Tabs should be enabled since there are two tabs with different addresses");
 
     // Hide the original tab
     gBrowser.selectedTab = testTab2;
     gBrowser.showOnlyTheseTabs([testTab2]);
     is(gBrowser.visibleTabs.length, 1, "1 tab should be visible");
     is(Disabled(), true, "Bookmark All Tabs should be disabled as there is only one visible tab");
 
@@ -47,17 +46,17 @@ function test() {
     gBrowser.removeTab(testTab1);
     gBrowser.removeTab(pinned);
     is(gBrowser.visibleTabs.length, 1, "only orig is left and visible");
     is(gBrowser.tabs.length, 1, "sanity check that it matches");
     is(Disabled(), true, "Bookmark All Tabs should be hidden");
     is(gBrowser.selectedTab, origTab, "got the orig tab");
     is(origTab.hidden, false, "and it's not hidden -- visible!");
     finish();
-  }, true);
+  }, {capture: true, once: true});
 }
 
 function Disabled() {
   updateTabContextMenu();
   return document.getElementById("Browser:BookmarkAllTabs").getAttribute("disabled") == "true";
 }
 
 function Hidden() {
--- a/browser/base/content/test/general/contentSearchUI.js
+++ b/browser/base/content/test/general/contentSearchUI.js
@@ -89,20 +89,19 @@ var messageHandlers = {
                      ...gController._oneOffButtons,
                      content.document.getElementById("contentSearchSettingsButton")];
       row = allElts[itemIndex];
     }
     let event = {
       type: "mousemove",
       clickcount: 0,
     }
-    row.addEventListener("mousemove", function handler() {
-      row.removeEventListener("mousemove", handler);
+    row.addEventListener("mousemove", function() {
       ack("mousemove");
-    });
+    }, {once: true});
     content.synthesizeMouseAtCenter(row, event);
   },
 
   click(arg) {
     let eltIdx = typeof(arg) == "object" ? arg.eltIdx : arg;
     let row;
     if (eltIdx == -1) {
       row = gController._table.firstChild;
--- a/browser/base/content/test/general/file_fullscreen-window-open.html
+++ b/browser/base/content/test/general/file_fullscreen-window-open.html
@@ -1,20 +1,18 @@
 <!DOCTYPE html>
 <html>
   <head>
     <title>Test for window.open() when browser is in fullscreen</title>
   </head>
   <body>
     <script>
-      window.addEventListener("load", function onLoad() {
-        window.removeEventListener("load", onLoad, true);
-
+      window.addEventListener("load", function() {
         document.getElementById("test").addEventListener("click", onClick, true);
-      }, true);
+      }, {capture: true, once: true});
 
       function onClick(aEvent) {
         aEvent.preventDefault();
 
         var dataStr = aEvent.target.getAttribute("data-test-param");
         var data = JSON.parse(dataStr);
         window.open(data.uri, data.title, data.option);
       }
--- a/browser/base/content/test/general/head.js
+++ b/browser/base/content/test/general/head.js
@@ -81,29 +81,27 @@ function updateTabContextMenu(tab, onOpe
 }
 
 function openToolbarCustomizationUI(aCallback, aBrowserWin) {
   if (!aBrowserWin)
     aBrowserWin = window;
 
   aBrowserWin.gCustomizeMode.enter();
 
-  aBrowserWin.gNavToolbox.addEventListener("customizationready", function UI_loaded() {
-    aBrowserWin.gNavToolbox.removeEventListener("customizationready", UI_loaded);
+  aBrowserWin.gNavToolbox.addEventListener("customizationready", function() {
     executeSoon(function() {
       aCallback(aBrowserWin)
     });
-  });
+  }, {once: true});
 }
 
 function closeToolbarCustomizationUI(aCallback, aBrowserWin) {
-  aBrowserWin.gNavToolbox.addEventListener("aftercustomization", function unloaded() {
-    aBrowserWin.gNavToolbox.removeEventListener("aftercustomization", unloaded);
+  aBrowserWin.gNavToolbox.addEventListener("aftercustomization", function() {
     executeSoon(aCallback);
-  });
+  }, {once: true});
 
   aBrowserWin.gCustomizeMode.exit();
 }
 
 function waitForCondition(condition, nextTest, errorMsg, retryTimes) {
   retryTimes = typeof retryTimes !== "undefined" ? retryTimes : 30;
   var tries = 0;
   var interval = setInterval(function() {
@@ -230,20 +228,19 @@ function setAndUpdateBlocklist(aURL, aCa
 }
 
 function resetBlocklist() {
   Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL);
 }
 
 function whenNewWindowLoaded(aOptions, aCallback) {
   let win = OpenBrowserWindow(aOptions);
-  win.addEventListener("load", function onLoad() {
-    win.removeEventListener("load", onLoad);
+  win.addEventListener("load", function() {
     aCallback(win);
-  });
+  }, {once: true});
 }
 
 function promiseWindowWillBeClosed(win) {
   return new Promise((resolve, reject) => {
     Services.obs.addObserver(function observe(subject, topic) {
       if (subject == win) {
         Services.obs.removeObserver(observe, topic);
         resolve();
@@ -266,20 +263,19 @@ function promiseOpenAndLoadWindow(aOptio
       if (aSubject != win) {
         return;
       }
       Services.obs.removeObserver(onDS, "browser-delayed-startup-finished");
       deferred.resolve(win);
     }, "browser-delayed-startup-finished", false);
 
   } else {
-    win.addEventListener("load", function onLoad() {
-      win.removeEventListener("load", onLoad);
+    win.addEventListener("load", function() {
       deferred.resolve(win);
-    });
+    }, {once: true});
   }
   return deferred.promise;
 }
 
 /**
  * Waits for all pending async statements on the default connection, before
  * proceeding with aCallback.
  *
@@ -569,22 +565,21 @@ var FullZoomHelper = {
 
   BACK: 0,
   FORWARD: 1,
   navigate: function navigate(direction) {
     return new Promise(resolve => {
       let didPs = false;
       let didZoom = false;
 
-      gBrowser.addEventListener("pageshow", function listener(event) {
-        gBrowser.removeEventListener("pageshow", listener, true);
+      gBrowser.addEventListener("pageshow", function(event) {
         didPs = true;
         if (didZoom)
           resolve();
-      }, true);
+      }, {capture: true, once: true});
 
       if (direction == this.BACK)
         gBrowser.goBack();
       else if (direction == this.FORWARD)
         gBrowser.goForward();
 
       this.waitForLocationChange().then(function() {
         didZoom = true;
--- a/browser/base/content/test/newtab/head.js
+++ b/browser/base/content/test/newtab/head.js
@@ -423,20 +423,19 @@ function* simulateExternalDrop(aDestInde
         let target = content.gGrid.cells[dropIndex].node;
         target.dispatchEvent(event);
 
         iframe.remove();
 
         resolve();
       }
 
-      iframe.addEventListener("load", function onLoad() {
-        iframe.removeEventListener("load", onLoad);
+      iframe.addEventListener("load", function() {
         content.setTimeout(iframeLoaded, 0);
-      });
+      }, {once: true});
 
       iframe.setAttribute("src", url);
       iframe.style.width = "50px";
       iframe.style.height = "50px";
       iframe.style.position = "absolute";
       iframe.style.zIndex = 50;
 
       // the frame has to be attached to a visible element
--- a/browser/base/content/test/plugins/head.js
+++ b/browser/base/content/test/plugins/head.js
@@ -358,20 +358,19 @@ function promiseForNotificationBar(notif
  * @param callback
  *        A function to be called when the notification has been reshown
  */
 function waitForNotificationShown(notification, callback) {
   if (PopupNotifications.panel.state == "open") {
     executeSoon(callback);
     return;
   }
-  PopupNotifications.panel.addEventListener("popupshown", function onShown(e) {
-    PopupNotifications.panel.removeEventListener("popupshown", onShown);
+  PopupNotifications.panel.addEventListener("popupshown", function(e) {
     callback();
-  });
+  }, {once: true});
   notification.reshow();
 }
 
 function promiseForNotificationShown(notification) {
   return new Promise((resolve) => {
     waitForNotificationShown(notification, resolve);
   });
 }
--- a/browser/base/content/test/popupNotifications/head.js
+++ b/browser/base/content/test/popupNotifications/head.js
@@ -281,24 +281,23 @@ function triggerSecondaryCommand(popup, 
   if (index == 0) {
     EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
     return;
   }
 
   // Extra secondary actions appear in a menu.
   notification.secondaryButton.nextSibling.nextSibling.focus();
 
-  popup.addEventListener("popupshown", function handle() {
-    popup.removeEventListener("popupshown", handle);
+  popup.addEventListener("popupshown", function() {
     info("Command popup open for notification " + notification.id);
     // Press down until the desired command is selected. Decrease index by one
     // since the secondary action was handled above.
     for (let i = 0; i <= index - 1; i++) {
       EventUtils.synthesizeKey("VK_DOWN", {});
     }
     // Activate
     EventUtils.synthesizeKey("VK_RETURN", {});
-  });
+  }, {once: true});
 
   // One down event to open the popup
   info("Open the popup to trigger secondary command for notification " + notification.id);
   EventUtils.synthesizeKey("VK_DOWN", { altKey: !navigator.platform.includes("Mac") });
 }
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab.js
+++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab.js
@@ -20,33 +20,30 @@ function startNewTabTestCase(aTestNumber
 
       checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
                                     startNewTabTestCase);
     });
 
     let menu = gTestWindow.document.getElementById("context-openlinkinusercontext-menu");
 
     let menupopup = menu.menupopup;
-    menu.addEventListener("popupshown", function onPopupShown() {
-      menu.removeEventListener("popupshown", onPopupShown);
-
+    menu.addEventListener("popupshown", function() {
       is(menupopup.nodeType, Node.ELEMENT_NODE, "We have a menupopup.");
       ok(menupopup.firstChild, "We have a first container entry.");
 
       let firstContext = menupopup.firstChild;
       is(firstContext.nodeType, Node.ELEMENT_NODE, "We have a first container entry.");
       ok(firstContext.hasAttribute("data-usercontextid"), "We have a usercontextid value.");
 
-      aContextMenu.addEventListener("popuphidden", function onPopupHidden() {
-        aContextMenu.removeEventListener("popuphidden", onPopupHidden);
+      aContextMenu.addEventListener("popuphidden", function() {
         firstContext.doCommand();
-      });
+      }, {once: true});
 
       aContextMenu.hidePopup();
-    });
+    }, {once: true});
 
     menupopup.showPopup();
   });
 }
 
 function test() {
   waitForExplicitFinish();
 
--- a/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab3.js
+++ b/browser/base/content/test/referrer/browser_referrer_open_link_in_container_tab3.js
@@ -23,34 +23,31 @@ function startNewTabTestCase(aTestNumber
 
       checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
                                     startNewTabTestCase, { userContextId: 2 });
     });
 
     let menu = gTestWindow.document.getElementById("context-openlinkinusercontext-menu");
 
     let menupopup = menu.menupopup;
-    menu.addEventListener("popupshown", function onPopupShown() {
-      menu.removeEventListener("popupshown", onPopupShown);
-
+    menu.addEventListener("popupshown", function() {
       is(menupopup.nodeType, Node.ELEMENT_NODE, "We have a menupopup.");
       ok(menupopup.firstChild, "We have a first container entry.");
 
       let firstContext = menupopup.firstChild;
       is(firstContext.nodeType, Node.ELEMENT_NODE, "We have a first container entry.");
       ok(firstContext.hasAttribute("data-usercontextid"), "We have a usercontextid value.");
       is("0", firstContext.getAttribute("data-usercontextid"), "We have the right usercontextid value.");
 
-      aContextMenu.addEventListener("popuphidden", function onPopupHidden() {
-        aContextMenu.removeEventListener("popuphidden", onPopupHidden);
+      aContextMenu.addEventListener("popuphidden", function() {
         firstContext.doCommand();
-      });
+      }, {once: true});
 
       aContextMenu.hidePopup();
-    });
+    }, {once: true});
 
     menupopup.showPopup();
   });
 }
 
 function test() {
   waitForExplicitFinish();
 
--- a/browser/base/content/test/social/browser_blocklist.js
+++ b/browser/base/content/test/social/browser_blocklist.js
@@ -152,35 +152,32 @@ var tests = {
     let listener = {
       _window: null,
       onOpenWindow(aXULWindow) {
         Services.wm.removeListener(this);
         this._window = aXULWindow;
         let domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                                   .getInterface(Ci.nsIDOMWindow);
 
-        domwindow.addEventListener("load", function _load() {
-          domwindow.removeEventListener("load", _load);
-
-          domwindow.addEventListener("unload", function _unload() {
-            domwindow.removeEventListener("unload", _unload);
+        domwindow.addEventListener("load", function() {
+          domwindow.addEventListener("unload", function() {
             info("blocklist window was closed");
             Services.wm.removeListener(listener);
             next();
-          });
+          }, {once: true});
 
           is(domwindow.document.location.href, URI_EXTENSION_BLOCKLIST_DIALOG, "dialog opened and focused");
           // wait until after load to cancel so the dialog has initalized. we
           // don't want to accept here since that restarts the browser.
           executeSoon(() => {
             let cancelButton = domwindow.document.documentElement.getButton("cancel");
             info("***** hit the cancel button\n");
             cancelButton.doCommand();
           });
-        });
+        }, {once: true});
       },
       onCloseWindow(aXULWindow) { },
       onWindowTitleChange(aXULWindow, aNewTitle) { }
     };
 
     Services.wm.addListener(listener);
 
     setManifestPref("social.manifest.blocked", manifest_bad);
--- a/browser/base/content/test/social/browser_share.js
+++ b/browser/base/content/test/social/browser_share.js
@@ -365,25 +365,24 @@ var tests = {
         ensureFrameLoaded(SocialShare.iframe).then(() => {
           // send keys to the input field.  An unexpected failure will happen
           // if the onbeforeunload handler is fired.
           EventUtils.sendKey("f");
           EventUtils.sendKey("a");
           EventUtils.sendKey("i");
           EventUtils.sendKey("l");
 
-          SocialShare.panel.addEventListener("popuphidden", function hidden(evt) {
-            SocialShare.panel.removeEventListener("popuphidden", hidden);
+          SocialShare.panel.addEventListener("popuphidden", function(evt) {
             let topwin = Services.wm.getMostRecentWindow(null);
             is(topwin, window, "no dialog is open");
 
             BrowserTestUtils.removeTab(testTab).then(() => {
               SocialService.disableProvider(manifest.origin, next);
             });
-          });
+          }, {once: true});
           SocialShare.iframe.messageManager.sendAsyncMessage("closeself", {});
         });
 
         let shareButton = SocialShare.shareButton;
         // verify the attribute for proper css
         ok(!shareButton.hasAttribute("disabled"), "share button is enabled");
         // button should be visible
         is(shareButton.hidden, false, "share button is visible");
--- a/browser/base/content/test/social/browser_social_activation.js
+++ b/browser/base/content/test/social/browser_social_activation.js
@@ -237,18 +237,17 @@ var tests = {
     });
   },
 
   testAddonManagerDoubleInstall(next) {
     // Create a new tab and load about:addons
     let addonsTab = gBrowser.addTab();
     gBrowser.selectedTab = addonsTab;
     BrowserOpenAddonsMgr("addons://list/service");
-    gBrowser.selectedBrowser.addEventListener("load", function tabLoad() {
-      gBrowser.selectedBrowser.removeEventListener("load", tabLoad, true);
+    gBrowser.selectedBrowser.addEventListener("load", function() {
       is(addonsTab.linkedBrowser.currentURI.spec, "about:addons", "about:addons should load into blank tab.");
 
       activateOneProvider(gProviders[0], true, function() {
         info("first activation completed");
         is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_postActivation.html", "postActivationURL loaded");
         BrowserTestUtils.removeTab(gBrowser.selectedTab).then(() => {
           is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_activate_basic.html", "activation page selected");
           BrowserTestUtils.removeTab(gBrowser.selectedTab).then(() => {
@@ -272,11 +271,11 @@ var tests = {
                     BrowserTestUtils.removeTab(addonsTab).then(next);
                   });
                 });
               });
             });
           });
         });
       });
-    }, true);
+    }, {capture: true, once: true});
   }
 }
--- a/browser/base/content/test/urlbar/browser_URLBarSetURI.js
+++ b/browser/base/content/test/urlbar/browser_URLBarSetURI.js
@@ -76,25 +76,23 @@ function loadTabInWindow(win, callback) 
 }
 
 function openToolbarCustomizationUI(aCallback, aBrowserWin) {
   if (!aBrowserWin)
     aBrowserWin = window;
 
   aBrowserWin.gCustomizeMode.enter();
 
-  aBrowserWin.gNavToolbox.addEventListener("customizationready", function UI_loaded() {
-    aBrowserWin.gNavToolbox.removeEventListener("customizationready", UI_loaded);
+  aBrowserWin.gNavToolbox.addEventListener("customizationready", function() {
     executeSoon(function() {
       aCallback(aBrowserWin)
     });
-  });
+  }, {once: true});
 }
 
 function closeToolbarCustomizationUI(aCallback, aBrowserWin) {
-  aBrowserWin.gNavToolbox.addEventListener("aftercustomization", function unloaded() {
-    aBrowserWin.gNavToolbox.removeEventListener("aftercustomization", unloaded);
+  aBrowserWin.gNavToolbox.addEventListener("aftercustomization", function() {
     executeSoon(aCallback);
-  });
+  }, {once: true});
 
   aBrowserWin.gCustomizeMode.exit();
 }
 
--- a/browser/base/content/test/urlbar/browser_bug1104165-switchtab-decodeuri.js
+++ b/browser/base/content/test/urlbar/browser_bug1104165-switchtab-decodeuri.js
@@ -11,19 +11,18 @@ add_task(function* test_switchtab_decode
 
   info("Select autocomplete popup entry");
   EventUtils.synthesizeKey("VK_DOWN", {});
   ok(gURLBar.value.startsWith("moz-action:switchtab"), "switch to tab entry found");
 
   info("switch-to-tab");
   yield new Promise((resolve, reject) => {
     // In case of success it should switch tab.
-    gBrowser.tabContainer.addEventListener("TabSelect", function select() {
-      gBrowser.tabContainer.removeEventListener("TabSelect", select);
+    gBrowser.tabContainer.addEventListener("TabSelect", function() {
       is(gBrowser.selectedTab, tab, "Should have switched to the right tab");
       resolve();
-    });
+    }, {once: true});
     EventUtils.synthesizeKey("VK_RETURN", { });
   });
 
   gBrowser.removeCurrentTab();
   yield PlacesTestUtils.clearHistory();
 });
--- a/browser/base/content/test/urlbar/browser_bug304198.js
+++ b/browser/base/content/test/urlbar/browser_bug304198.js
@@ -40,19 +40,18 @@ add_task(function* () {
     yield BrowserTestUtils.switchTab(gBrowser, fullURLTab);
     is(gURLBar.textValue, testURL, "gURLBar.textValue should be testURL after switching back to fullURLTab");
   }
 
   function urlbarBackspace() {
     return new Promise((resolve, reject) => {
       gBrowser.selectedBrowser.focus();
       gURLBar.addEventListener("input", function() {
-        gURLBar.removeEventListener("input", arguments.callee);
         resolve();
-      });
+      }, {once: true});
       gURLBar.focus();
       EventUtils.synthesizeKey("VK_BACK_SPACE", {});
     });
   }
 
   function* prepareDeletedURLTab() {
     yield BrowserTestUtils.switchTab(gBrowser, deletedURLTab);
     is(gURLBar.textValue, testURL, "gURLBar.textValue should be testURL after initial switch to deletedURLTab");
--- a/browser/base/content/test/urlbar/browser_locationBarCommand.js
+++ b/browser/base/content/test/urlbar/browser_locationBarCommand.js
@@ -191,20 +191,19 @@ function* promiseOpenNewTab(url = "about
   gBrowser.selectedTab = tab;
   yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   yield tabSwitchPromise;
   return tab;
 }
 
 function promiseNewTabSwitched() {
   return new Promise(resolve => {
-    gBrowser.addEventListener("TabSwitchDone", function onSwitch() {
-      gBrowser.removeEventListener("TabSwitchDone", onSwitch);
+    gBrowser.addEventListener("TabSwitchDone", function() {
       executeSoon(resolve);
-    });
+    }, {once: true});
   });
 }
 
 function promiseCheckChildNoFocusedElement(browser) {
   if (!gMultiProcessBrowser) {
     Assert.equal(Services.focus.focusedElement, null, "There should be no focused element");
     return null;
   }
--- a/browser/base/content/test/urlbar/browser_locationBarExternalLoad.js
+++ b/browser/base/content/test/urlbar/browser_locationBarExternalLoad.js
@@ -17,20 +17,19 @@ function urlClick(url) {
   gURLBar.value = url;
   gURLBar.focus();
   let goButton = document.getElementById("urlbar-go-button");
   EventUtils.synthesizeMouseAtCenter(goButton, {});
 }
 
 function promiseNewTabSwitched() {
   return new Promise(resolve => {
-    gBrowser.addEventListener("TabSwitchDone", function onSwitch() {
-      gBrowser.removeEventListener("TabSwitchDone", onSwitch);
+    gBrowser.addEventListener("TabSwitchDone", function() {
       executeSoon(resolve);
-    });
+    }, {once: true});
   });
 }
 
 function* testURL(url, loadFunc, endFunc) {
   let tabSwitchedPromise = promiseNewTabSwitched();
   let tab = gBrowser.selectedTab = gBrowser.addTab();
   let browser = gBrowser.selectedBrowser;
 
--- a/browser/base/content/test/urlbar/browser_urlbarAboutHomeLoading.js
+++ b/browser/base/content/test/urlbar/browser_urlbarAboutHomeLoading.js
@@ -6,40 +6,38 @@ const {TabStateFlusher} = Cu.import("res
 /**
  * Test what happens if loading a URL that should clear the
  * location bar after a parent process URL.
  */
 add_task(function* clearURLBarAfterParentProcessURL() {
   let tab = yield new Promise(resolve => {
     gBrowser.selectedTab = gBrowser.addTab("about:preferences");
     let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
-    newTabBrowser.addEventListener("Initialized", function onInit() {
-      newTabBrowser.removeEventListener("Initialized", onInit, true);
+    newTabBrowser.addEventListener("Initialized", function() {
       resolve(gBrowser.selectedTab);
-    }, true);
+    }, {capture: true, once: true});
   });
   document.getElementById("home-button").click();
   yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   is(gURLBar.value, "", "URL bar should be empty");
   is(tab.linkedBrowser.userTypedValue, null, "The browser should have no recorded userTypedValue");
   yield BrowserTestUtils.removeTab(tab);
 });
 
 /**
  * Same as above, but open the tab without passing the URL immediately
  * which changes behaviour in tabbrowser.xml.
  */
 add_task(function* clearURLBarAfterParentProcessURLInExistingTab() {
   let tab = yield new Promise(resolve => {
     gBrowser.selectedTab = gBrowser.addTab();
     let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
-    newTabBrowser.addEventListener("Initialized", function onInit() {
-      newTabBrowser.removeEventListener("Initialized", onInit, true);
+    newTabBrowser.addEventListener("Initialized", function() {
       resolve(gBrowser.selectedTab);
-    }, true);
+    }, {capture: true, once: true});
     newTabBrowser.loadURI("about:preferences");
   });
   document.getElementById("home-button").click();
   yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   is(gURLBar.value, "", "URL bar should be empty");
   is(tab.linkedBrowser.userTypedValue, null, "The browser should have no recorded userTypedValue");
   yield BrowserTestUtils.removeTab(tab);
 });
--- a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestionsNotification.js
+++ b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestionsNotification.js
@@ -239,16 +239,15 @@ function suggestionsPresent() {
 function assertVisible(visible, win = window) {
   let style =
     win.getComputedStyle(win.gURLBar.popup.searchSuggestionsNotification);
   Assert.equal(style.visibility, visible ? "visible" : "collapse");
 }
 
 function promiseTransition(win = window) {
   return new Promise(resolve => {
-    win.gURLBar.popup.addEventListener("transitionend", function onEnd() {
-      win.gURLBar.popup.removeEventListener("transitionend", onEnd, true);
+    win.gURLBar.popup.addEventListener("transitionend", function() {
       // The urlbar needs to handle the transitionend first, but that happens
       // naturally since promises are resolved at the end of the current tick.
       resolve();
-    }, true);
+    }, {capture: true, once: true});
   });
 }
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media.js
@@ -583,19 +583,17 @@ function test() {
   waitForExplicitFinish();
 
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
   let browser = tab.linkedBrowser;
 
   browser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
 
-  browser.addEventListener("load", function onload() {
-    browser.removeEventListener("load", onload, true);
-
+  browser.addEventListener("load", function() {
     is(PopupNotifications._currentNotifications.length, 0,
        "should start the test without any prior popup notification");
     ok(gIdentityHandler._identityPopup.hidden,
        "should start the test with the control center hidden");
 
     Task.spawn(function* () {
       yield SpecialPowers.pushPrefEnv({"set": [[PREF_PERMISSION_FAKE, true]]});
 
@@ -606,14 +604,14 @@ function test() {
         // Cleanup before the next test
         yield expectNoObserverCalled();
       }
     }).then(finish, ex => {
      Cu.reportError(ex);
      ok(false, "Unexpected Exception: " + ex);
      finish();
     });
-  }, true);
+  }, {capture: true, once: true});
   let rootDir = getRootDirectory(gTestPath);
   rootDir = rootDir.replace("chrome://mochitests/content/",
                             "https://example.com/");
   content.location = rootDir + "get_user_media.html";
 }
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_anim.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_anim.js
@@ -80,32 +80,30 @@ function test() {
   waitForExplicitFinish();
 
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
   let browser = tab.linkedBrowser;
 
   browser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
 
-  browser.addEventListener("load", function onload() {
-    browser.removeEventListener("load", onload, true);
-
+  browser.addEventListener("load", function() {
     is(PopupNotifications._currentNotifications.length, 0,
        "should start the test without any prior popup notification");
 
     Task.spawn(function* () {
       yield SpecialPowers.pushPrefEnv({"set": [[PREF_PERMISSION_FAKE, true]]});
 
       for (let testCase of gTests) {
         info(testCase.desc);
         yield testCase.run();
       }
     }).then(finish, ex => {
      Cu.reportError(ex);
      ok(false, "Unexpected Exception: " + ex);
      finish();
     });
-  }, true);
+  }, {capture: true, once: true});
   let rootDir = getRootDirectory(gTestPath);
   rootDir = rootDir.replace("chrome://mochitests/content/",
                             "https://example.com/");
   content.location = rootDir + "get_user_media.html";
 }
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_in_frame.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_in_frame.js
@@ -220,19 +220,17 @@ function test() {
   waitForExplicitFinish();
 
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
   let browser = tab.linkedBrowser;
 
   browser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
 
-  browser.addEventListener("load", function onload() {
-    browser.removeEventListener("load", onload, true);
-
+  browser.addEventListener("load", function() {
     is(PopupNotifications._currentNotifications.length, 0,
        "should start the test without any prior popup notification");
 
     Task.spawn(function* () {
       yield SpecialPowers.pushPrefEnv({"set": [[PREF_PERMISSION_FAKE, true]]});
 
       for (let testCase of gTests) {
         info(testCase.desc);
@@ -241,15 +239,15 @@ function test() {
         // Cleanup before the next test
         yield expectNoObserverCalled();
       }
     }).then(finish, ex => {
      Cu.reportError(ex);
      ok(false, "Unexpected Exception: " + ex);
      finish();
     });
-  }, true);
+  }, {capture: true, once: true});
   let rootDir = getRootDirectory(gTestPath);
   rootDir = rootDir.replace("chrome://mochitests/content/",
                             "https://example.com/");
   let url = rootDir + "get_user_media.html";
   content.location = 'data:text/html,<iframe id="frame1" src="' + url + '"></iframe><iframe id="frame2" src="' + url + '"></iframe>'
 }
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_screen.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_screen.js
@@ -581,19 +581,17 @@ function test() {
   waitForExplicitFinish();
 
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
   let browser = tab.linkedBrowser;
 
   browser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
 
-  browser.addEventListener("load", function onload() {
-    browser.removeEventListener("load", onload, true);
-
+  browser.addEventListener("load", function() {
     is(PopupNotifications._currentNotifications.length, 0,
        "should start the test without any prior popup notification");
     ok(gIdentityHandler._identityPopup.hidden,
        "should start the test with the control center hidden");
 
     Task.spawn(function* () {
       yield SpecialPowers.pushPrefEnv({"set": [[PREF_PERMISSION_FAKE, true]]});
 
@@ -604,14 +602,14 @@ function test() {
         // Cleanup before the next test
         yield expectNoObserverCalled();
       }
     }).then(finish, ex => {
      Cu.reportError(ex);
      ok(false, "Unexpected Exception: " + ex);
      finish();
     });
-  }, true);
+  }, {capture: true, once: true});
   let rootDir = getRootDirectory(gTestPath);
   rootDir = rootDir.replace("chrome://mochitests/content/",
                             "https://example.com/");
   content.location = rootDir + "get_user_media.html";
 }
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_tear_off_tab.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_tear_off_tab.js
@@ -73,19 +73,17 @@ function runTest() {
   gBrowser.addTab();
 
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
   let browser = tab.linkedBrowser;
 
   browser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
 
-  browser.addEventListener("load", function onload() {
-    browser.removeEventListener("load", onload, true);
-
+  browser.addEventListener("load", function() {
     is(PopupNotifications._currentNotifications.length, 0,
        "should start the test without any prior popup notification");
     ok(gIdentityHandler._identityPopup.hidden,
        "should start the test with the control center hidden");
 
     Task.spawn(function* () {
       yield SpecialPowers.pushPrefEnv({"set": [[PREF_PERMISSION_FAKE, true]]});
 
@@ -96,14 +94,14 @@ function runTest() {
         // Cleanup before the next test
         yield expectNoObserverCalled();
       }
     }).then(finish, ex => {
      Cu.reportError(ex);
      ok(false, "Unexpected Exception: " + ex);
      finish();
     });
-  }, true);
+  }, {capture: true, once: true});
   let rootDir = getRootDirectory(gTestPath);
   rootDir = rootDir.replace("chrome://mochitests/content/",
                             "https://example.com/");
   content.location = rootDir + "get_user_media.html";
 }
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access.js
@@ -255,19 +255,17 @@ function test() {
   waitForExplicitFinish();
 
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
   let browser = tab.linkedBrowser;
 
   browser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
 
-  browser.addEventListener("load", function onload() {
-    browser.removeEventListener("load", onload, true);
-
+  browser.addEventListener("load", function() {
     is(PopupNotifications._currentNotifications.length, 0,
        "should start the test without any prior popup notification");
     ok(gIdentityHandler._identityPopup.hidden,
        "should start the test with the control center hidden");
 
     Task.spawn(function* () {
       yield SpecialPowers.pushPrefEnv({"set": [[PREF_PERMISSION_FAKE, true]]});
 
@@ -278,14 +276,14 @@ function test() {
         // Cleanup before the next test
         yield expectNoObserverCalled();
       }
     }).then(finish, ex => {
      Cu.reportError(ex);
      ok(false, "Unexpected Exception: " + ex);
      finish();
     });
-  }, true);
+  }, {capture: true, once: true});
   let rootDir = getRootDirectory(gTestPath);
   rootDir = rootDir.replace("chrome://mochitests/content/",
                             "https://example.com/");
   content.location = rootDir + "get_user_media.html";
 }
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access_in_frame.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access_in_frame.js
@@ -214,19 +214,17 @@ function test() {
   waitForExplicitFinish();
 
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
   let browser = tab.linkedBrowser;
 
   browser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
 
-  browser.addEventListener("load", function onload() {
-    browser.removeEventListener("load", onload, true);
-
+  browser.addEventListener("load", function() {
     is(PopupNotifications._currentNotifications.length, 0,
        "should start the test without any prior popup notification");
 
     Task.spawn(function* () {
       yield SpecialPowers.pushPrefEnv({"set": [[PREF_PERMISSION_FAKE, true]]});
 
       for (let testCase of gTests) {
         info(testCase.desc);
@@ -235,14 +233,14 @@ function test() {
         // Cleanup before the next test
         yield expectNoObserverCalled();
       }
     }).then(finish, ex => {
      Cu.reportError(ex);
      ok(false, "Unexpected Exception: " + ex);
      finish();
     });
-  }, true);
+  }, {capture: true, once: true});
   let rootDir = getRootDirectory(gTestPath);
   rootDir = rootDir.replace("chrome://mochitests/content/",
                             "https://example.com/");
   content.location = rootDir + "get_user_media_in_frame.html";
 }
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access_tear_off_tab.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_unprompted_access_tear_off_tab.js
@@ -66,19 +66,17 @@ function runTest() {
   gBrowser.addTab();
 
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
   let browser = tab.linkedBrowser;
 
   browser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
 
-  browser.addEventListener("load", function onload() {
-    browser.removeEventListener("load", onload, true);
-
+  browser.addEventListener("load", function() {
     is(PopupNotifications._currentNotifications.length, 0,
        "should start the test without any prior popup notification");
     ok(gIdentityHandler._identityPopup.hidden,
        "should start the test with the control center hidden");
 
     Task.spawn(function* () {
       yield SpecialPowers.pushPrefEnv({"set": [[PREF_PERMISSION_FAKE, true]]});
 
@@ -89,14 +87,14 @@ function runTest() {
         // Cleanup before the next test
         yield expectNoObserverCalled();
       }
     }).then(finish, ex => {
      Cu.reportError(ex);
      ok(false, "Unexpected Exception: " + ex);
      finish();
     });
-  }, true);
+  }, {capture: true, once: true});
   let rootDir = getRootDirectory(gTestPath);
   rootDir = rootDir.replace("chrome://mochitests/content/",
                             "https://example.com/");
   content.location = rootDir + "get_user_media.html";
 }
--- a/browser/base/content/test/webrtc/browser_webrtc_hooks.js
+++ b/browser/base/content/test/webrtc/browser_webrtc_hooks.js
@@ -328,19 +328,17 @@ var gTests = [
 
 function test() {
   waitForExplicitFinish();
 
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
   let browser = tab.linkedBrowser;
 
-  browser.addEventListener("load", function onload() {
-    browser.removeEventListener("load", onload, true);
-
+  browser.addEventListener("load", function() {
     is(PopupNotifications._currentNotifications.length, 0,
        "should start the test without any prior popup notification");
     ok(gIdentityHandler._identityPopup.hidden,
        "should start the test with the control center hidden");
 
     Task.spawn(function* () {
       yield SpecialPowers.pushPrefEnv({"set": [[PREF_PERMISSION_FAKE, true]]});
 
@@ -351,13 +349,13 @@ function test() {
         // Make sure the test cleaned up after itself.
         is(webrtcUI.peerConnectionBlockers.size, 0, "Peer connection blockers list is empty");
       }
     }).then(finish, ex => {
      Cu.reportError(ex);
      ok(false, "Unexpected Exception: " + ex);
      finish();
     });
-  }, true);
+  }, {capture: true, once: true});
   let rootDir = getRootDirectory(gTestPath);
   rootDir = rootDir.replace("chrome://mochitests/content", ORIGIN);
   content.location = rootDir + "get_user_media.html";
 }
--- a/browser/base/content/test/webrtc/head.js
+++ b/browser/base/content/test/webrtc/head.js
@@ -44,27 +44,25 @@ function promiseWaitForCondition(aCondit
  * @return {Promise} resolved when the window exists.
  * @resolves to the window
  */
 function promiseWindow(url) {
   info("expecting a " + url + " window");
   return new Promise(resolve => {
     Services.obs.addObserver(function obs(win) {
       win.QueryInterface(Ci.nsIDOMWindow);
-      win.addEventListener("load", function loadHandler() {
-        win.removeEventListener("load", loadHandler);
-
+      win.addEventListener("load", function() {
         if (win.location.href !== url) {
           info("ignoring a window with this url: " + win.location.href);
           return;
         }
 
         Services.obs.removeObserver(obs, "domwindowopened");
         resolve(win);
-      });
+      }, {once: true});
     }, "domwindowopened", false);
   });
 }
 
 function whenDelayedStartupFinished(aWindow) {
   return new Promise(resolve => {
     info("Waiting for delayed startup to finish");
     Services.obs.addObserver(function observer(aSubject, aTopic) {
@@ -270,25 +268,23 @@ function promiseMessage(aMessage, aActio
     aAction();
 
   return promise;
 }
 
 function promisePopupNotificationShown(aName, aAction) {
   let deferred = Promise.defer();
 
-  PopupNotifications.panel.addEventListener("popupshown", function popupNotifShown() {
-    PopupNotifications.panel.removeEventListener("popupshown", popupNotifShown);
-
+  PopupNotifications.panel.addEventListener("popupshown", function() {
     ok(!!PopupNotifications.getNotification(aName), aName + " notification shown");
     ok(PopupNotifications.isPanelOpen, "notification panel open");
     ok(!!PopupNotifications.panel.firstChild, "notification panel populated");
 
     deferred.resolve();
-  });
+  }, {once: true});
 
   if (aAction)
     aAction();
 
   return deferred.promise;
 }
 
 function promisePopupNotification(aName) {
--- a/browser/components/contextualidentity/test/browser/browser_middleClick.js
+++ b/browser/components/contextualidentity/test/browser/browser_middleClick.js
@@ -21,20 +21,19 @@ add_task(function* () {
       anchor.setAttribute("href", uri);
       anchor.appendChild(content.document.createTextNode("click me!"));
       content.document.body.appendChild(anchor);
     }
   );
 
   info("Synthesize a mouse click and wait for a new tab...");
   let newTab = yield new Promise((resolve, reject) => {
-    gBrowser.tabContainer.addEventListener("TabOpen", function onTabOpen(openEvent) {
-      gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen);
+    gBrowser.tabContainer.addEventListener("TabOpen", function(openEvent) {
       resolve(openEvent.target);
-    })
+    }, {once: true})
 
     BrowserTestUtils.synthesizeMouseAtCenter("#clickMe", { button: 1 }, browser);
   });
 
   is(newTab.getAttribute("usercontextid"), 1, "Correct UserContextId?");
 
   yield BrowserTestUtils.removeTab(tab);
   yield BrowserTestUtils.removeTab(newTab);
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -4132,22 +4132,21 @@ OverflowableToolbar.prototype = {
       this._panel.hidden = false;
       let contextMenu = doc.getElementById(this._panel.getAttribute("context"));
       gELS.addSystemEventListener(contextMenu, "command", this, true);
       let anchor = doc.getAnonymousElementByAttribute(this._chevron, "class", "toolbarbutton-icon");
       this._panel.openPopup(anchor || this._chevron);
       this._chevron.open = true;
 
       let overflowableToolbarInstance = this;
-      this._panel.addEventListener("popupshown", function onPopupShown(aEvent) {
-        this.removeEventListener("popupshown", onPopupShown);
+      this._panel.addEventListener("popupshown", function(aEvent) {
         this.addEventListener("dragover", overflowableToolbarInstance);
         this.addEventListener("dragend", overflowableToolbarInstance);
         resolve();
-      });
+      }, {once: true});
     });
   },
 
   _onClickChevron(aEvent) {
     if (this._chevron.open) {
       this._panel.hidePopup();
       this._chevron.open = false;
     } else {
--- a/browser/components/customizableui/ScrollbarSampler.jsm
+++ b/browser/components/customizableui/ScrollbarSampler.jsm
@@ -39,27 +39,26 @@ this.ScrollbarSampler = {
     iframe.setAttribute("srcdoc", '<body style="overflow-y: scroll"></body>');
     hdoc.appendChild(iframe);
 
     let cwindow = iframe.contentWindow;
     let utils = cwindow.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIDOMWindowUtils);
 
     return new Promise(resolve => {
-      cwindow.addEventListener("load", function onLoad(aEvent) {
-        cwindow.removeEventListener("load", onLoad);
+      cwindow.addEventListener("load", function(aEvent) {
         let sbWidth = {};
         try {
           utils.getScrollbarSize(true, sbWidth, {});
         } catch (e) {
           Cu.reportError("Could not sample scrollbar size: " + e + " -- " +
                          e.stack);
           sbWidth.value = 0;
         }
         // Minimum width of 10 so that we have enough padding:
         sbWidth.value = Math.max(sbWidth.value, 10);
         resolve(sbWidth.value);
         iframe.remove();
-      });
+      }, {once: true});
     });
   }
 };
 Object.freeze(this.ScrollbarSampler);
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -147,20 +147,19 @@ const PanelUI = {
         let anchor;
         if (!aEvent ||
             aEvent.type == "command") {
           anchor = this.menuButton;
         } else {
           anchor = aEvent.target;
         }
 
-        this.panel.addEventListener("popupshown", function onPopupShown() {
-          this.removeEventListener("popupshown", onPopupShown);
+        this.panel.addEventListener("popupshown", function() {
           resolve();
-        });
+        }, {once: true});
 
         let iconAnchor =
           document.getAnonymousElementByAttribute(anchor, "class",
                                                   "toolbarbutton-icon");
         this.panel.openPopup(iconAnchor || anchor);
       }, (reason) => {
         console.error("Error showing the PanelUI menu", reason);
       });
--- a/browser/components/customizableui/test/browser_947914_button_newPrivateWindow.js
+++ b/browser/components/customizableui/test/browser_947914_button_newPrivateWindow.js
@@ -12,23 +12,22 @@ add_task(function*() {
 
   let windowWasHandled = false;
   let privateWindow = null;
 
   let observerWindowOpened = {
     observe(aSubject, aTopic, aData) {
       if (aTopic == "domwindowopened") {
         privateWindow = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
-        privateWindow.addEventListener("load", function newWindowHandler() {
-          privateWindow.removeEventListener("load", newWindowHandler);
+        privateWindow.addEventListener("load", function() {
           is(privateWindow.location.href, "chrome://browser/content/browser.xul",
              "A new browser window was opened");
           ok(PrivateBrowsingUtils.isWindowPrivate(privateWindow), "Window is private");
           windowWasHandled = true;
-        });
+        }, {once: true});
       }
     }
   }
 
   Services.ww.registerNotification(observerWindowOpened);
 
   let privateBrowsingButton = document.getElementById("privatebrowsing-button");
   ok(privateBrowsingButton, "Private browsing button exists in Panel Menu");
--- a/browser/components/customizableui/test/browser_947914_button_newWindow.js
+++ b/browser/components/customizableui/test/browser_947914_button_newWindow.js
@@ -11,23 +11,22 @@ add_task(function*() {
 
   let windowWasHandled = false;
   let newWindow = null;
 
   let observerWindowOpened = {
     observe(aSubject, aTopic, aData) {
       if (aTopic == "domwindowopened") {
         newWindow = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
-        newWindow.addEventListener("load", function newWindowHandler() {
-          newWindow.removeEventListener("load", newWindowHandler);
+        newWindow.addEventListener("load", function() {
           is(newWindow.location.href, "chrome://browser/content/browser.xul",
              "A new browser window was opened");
           ok(!PrivateBrowsingUtils.isWindowPrivate(newWindow), "Window is not private");
           windowWasHandled = true;
-        });
+        }, {once: true});
       }
     }
   }
 
   Services.ww.registerNotification(observerWindowOpened);
 
   let newWindowButton = document.getElementById("new-window-button");
   ok(newWindowButton, "New Window button exists in Panel Menu");
--- a/browser/components/customizableui/test/browser_967000_button_sync.js
+++ b/browser/components/customizableui/test/browser_967000_button_sync.js
@@ -160,20 +160,19 @@ add_task(function* () {
       yield PanelUI.show();
       EventUtils.sendMouseEvent({ type: "click", button }, link, window);
       // the panel should have been closed.
       ok(!isPanelUIOpen(), "click closed the panel");
       // should be a new tab - wait for the load.
       is(gBrowser.tabs.length, 2, "there's a new tab");
       yield new Promise(resolve => {
         if (gBrowser.selectedBrowser.currentURI.spec == "about:blank") {
-          gBrowser.selectedBrowser.addEventListener("load", function listener(e) {
-            gBrowser.selectedBrowser.removeEventListener("load", listener, true);
+          gBrowser.selectedBrowser.addEventListener("load", function(e) {
             resolve();
-          }, true);
+          }, {capture: true, once: true});
           return;
         }
         // the new tab has already transitioned away from about:blank so we
         // are good to go.
         resolve();
       });
 
       let os = link.getAttribute("mobile-promo-os");
--- a/browser/components/customizableui/test/head.js
+++ b/browser/components/customizableui/test/head.js
@@ -248,30 +248,28 @@ function openAndLoadWindow(aOptions, aWa
       if (aSubject != win) {
         return;
       }
       Services.obs.removeObserver(onDS, "browser-delayed-startup-finished");
       deferred.resolve(win);
     }, "browser-delayed-startup-finished", false);
 
   } else {
-    win.addEventListener("load", function onLoad() {
-      win.removeEventListener("load", onLoad);
+    win.addEventListener("load", function() {
       deferred.resolve(win);
-    });
+    }, {once: true});
   }
   return deferred.promise;
 }
 
 function promiseWindowClosed(win) {
   let deferred = Promise.defer();
-  win.addEventListener("unload", function onunload() {
-    win.removeEventListener("unload", onunload);
+  win.addEventListener("unload", function() {
     deferred.resolve();
-  });
+  }, {once: true});
   win.close();
   return deferred.promise;
 }
 
 function promisePanelShown(win) {
   let panelEl = win.PanelUI.panel;
   return promisePanelElementShown(win, panelEl);
 }
--- a/browser/components/downloads/DownloadsCommon.jsm
+++ b/browser/components/downloads/DownloadsCommon.jsm
@@ -623,28 +623,27 @@ this.DownloadsCommon = {
         break;
     }
     message += "\n\n" + s.unblockTip2;
 
     Services.ww.registerNotification(function onOpen(subj, topic) {
       if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) {
         // Make sure to listen for "DOMContentLoaded" because it is fired
         // before the "load" event.
-        subj.addEventListener("DOMContentLoaded", function onLoad() {
-          subj.removeEventListener("DOMContentLoaded", onLoad);
+        subj.addEventListener("DOMContentLoaded", function() {
           if (subj.document.documentURI ==
               "chrome://global/content/commonDialog.xul") {
             Services.ww.unregisterNotification(onOpen);
             let dialog = subj.document.getElementById("commonDialog");
             if (dialog) {
               // Change the dialog to use a warning icon.
               dialog.classList.add("alert-dialog");
             }
           }
-        });
+        }, {once: true});
       }
     });
 
     let rv = Services.prompt.confirmEx(window, title, message, buttonFlags,
                                        firstButtonText, null,
                                        s.unblockButtonConfirmBlock, null, {});
     return [firstButtonAction, "cancel", "confirmBlock"][rv];
   }),
--- a/browser/components/downloads/test/browser/browser_downloads_panel_block.js
+++ b/browser/components/downloads/test/browser/browser_downloads_panel_block.js
@@ -128,20 +128,19 @@ function* openPanel() {
 }
 
 function promisePanelHidden() {
   return new Promise(resolve => {
     if (!DownloadsPanel.panel || DownloadsPanel.panel.state == "closed") {
       resolve();
       return;
     }
-    DownloadsPanel.panel.addEventListener("popuphidden", function onHidden() {
-      DownloadsPanel.panel.removeEventListener("popuphidden", onHidden);
+    DownloadsPanel.panel.addEventListener("popuphidden", function() {
       setTimeout(resolve, 0);
-    });
+    }, {once: true});
   });
 }
 
 function makeDownload(verdict) {
   return {
     state: nsIDM.DOWNLOAD_DIRTY,
     hasBlockedData: true,
     errorObj: {
--- a/browser/components/downloads/test/browser/head.js
+++ b/browser/components/downloads/test/browser/head.js
@@ -41,20 +41,19 @@ registerCleanupFunction(function () {
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Asynchronous support subroutines
 
 function promiseOpenAndLoadWindow(aOptions)
 {
   return new Promise((resolve, reject) => {
     let win = OpenBrowserWindow(aOptions);
-    win.addEventListener("load", function onLoad() {
-      win.removeEventListener("load", onLoad);
+    win.addEventListener("load", function() {
       resolve(win);
-    });
+    }, {once: true});
   });
 }
 
 /**
  * Waits for a load (or custom) event to finish in a given tab. If provided
  * load an uri into the tab.
  *
  * @param tab
@@ -272,27 +271,26 @@ function openLibrary(aLeftPaneRoot) {
 
 function promiseAlertDialogOpen(buttonAction) {
   return new Promise(resolve => {
     Services.ww.registerNotification(function onOpen(subj, topic, data) {
       if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) {
         // The test listens for the "load" event which guarantees that the alert
         // class has already been added (it is added when "DOMContentLoaded" is
         // fired).
-        subj.addEventListener("load", function onLoad() {
-          subj.removeEventListener("load", onLoad);
+        subj.addEventListener("load", function() {
           if (subj.document.documentURI ==
               "chrome://global/content/commonDialog.xul") {
             Services.ww.unregisterNotification(onOpen);
 
             let dialog = subj.document.getElementById("commonDialog");
             ok(dialog.classList.contains("alert-dialog"),
                "The dialog element should contain an alert class.");
 
             let doc = subj.document.documentElement;
             doc.getButton(buttonAction).click();
             resolve();
           }
-        });
+        }, {once: true});
       }
     });
   });
 }
--- a/browser/components/extensions/ext-tabs.js
+++ b/browser/components/extensions/ext-tabs.js
@@ -947,33 +947,31 @@ extensions.registerSchemaAPI("tabs", "ad
 
         let gBrowser = tab.ownerGlobal.gBrowser;
         let newTab = gBrowser.duplicateTab(tab);
 
         return new Promise(resolve => {
           // We need to use SSTabRestoring because any attributes set before
           // are ignored. SSTabRestored is too late and results in a jump in
           // the UI. See http://bit.ly/session-store-api for more information.
-          newTab.addEventListener("SSTabRestoring", function listener() {
+          newTab.addEventListener("SSTabRestoring", function() {
             // As the tab is restoring, move it to the correct position.
-            newTab.removeEventListener("SSTabRestoring", listener);
             // Pinned tabs that are duplicated are inserted
             // after the existing pinned tab and pinned.
             if (tab.pinned) {
               gBrowser.pinTab(newTab);
             }
             gBrowser.moveTabTo(newTab, tab._tPos + 1);
-          });
+          }, {once: true});
 
-          newTab.addEventListener("SSTabRestored", function listener() {
+          newTab.addEventListener("SSTabRestored", function() {
             // Once it has been restored, select it and return the promise.
-            newTab.removeEventListener("SSTabRestored", listener);
             gBrowser.selectedTab = newTab;
             return resolve(TabManager.convert(extension, newTab));
-          });
+          }, {once: true});
         });
       },
 
       getZoom(tabId) {
         let tab = tabId ? TabManager.getTab(tabId, context) : TabManager.activeTab;
 
         let {ZoomManager} = tab.ownerGlobal;
         let zoom = ZoomManager.getZoomForBrowser(tab.linkedBrowser);
--- a/browser/components/extensions/ext-utils.js
+++ b/browser/components/extensions/ext-utils.js
@@ -42,20 +42,19 @@ global.makeWidgetId = id => {
   return id.replace(/[^a-z0-9_-]/g, "_");
 };
 
 function promisePopupShown(popup) {
   return new Promise(resolve => {
     if (popup.state == "open") {
       resolve();
     } else {
-      popup.addEventListener("popupshown", function onPopupShown(event) {
-        popup.removeEventListener("popupshown", onPopupShown);
+      popup.addEventListener("popupshown", function(event) {
         resolve();
-      });
+      }, {once: true});
     }
   });
 }
 
 XPCOMUtils.defineLazyGetter(this, "popupStylesheets", () => {
   let stylesheets = ["chrome://browser/content/extension.css"];
 
   if (AppConstants.platform === "macosx") {
--- a/browser/components/extensions/ext-windows.js
+++ b/browser/components/extensions/ext-windows.js
@@ -160,23 +160,22 @@ extensions.registerSchemaAPI("windows", 
         let window = Services.ww.openWindow(null, "chrome://browser/content/browser.xul", "_blank",
                                             features.join(","), args);
 
         WindowManager.updateGeometry(window, createData);
 
         // TODO: focused, type
 
         return new Promise(resolve => {
-          window.addEventListener("load", function listener() {
-            window.removeEventListener("load", listener);
+          window.addEventListener("load", function() {
             if (["maximized", "normal"].includes(createData.state)) {
               window.document.documentElement.setAttribute("sizemode", createData.state);
             }
             resolve(promiseObserved("browser-delayed-startup-finished", win => win == window));
-          });
+          }, {once: true});
         }).then(() => {
           // Some states only work after delayed-startup-finished
           if (["minimized", "fullscreen", "docked"].includes(createData.state)) {
             WindowManager.setState(window, createData.state);
           }
           if (allowScriptsToClose) {
             for (let {linkedBrowser} of window.gBrowser.tabs) {
               onXULFrameLoaderCreated({target: linkedBrowser});
--- a/browser/components/extensions/test/browser/head.js
+++ b/browser/components/extensions/test/browser/head.js
@@ -51,20 +51,19 @@ function makeWidgetId(id) {
 
 var focusWindow = Task.async(function* focusWindow(win) {
   let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
   if (fm.activeWindow == win) {
     return;
   }
 
   let promise = new Promise(resolve => {
-    win.addEventListener("focus", function listener() {
-      win.removeEventListener("focus", listener, true);
+    win.addEventListener("focus", function() {
       resolve();
-    }, true);
+    }, {capture: true, once: true});
   });
 
   win.focus();
   yield promise;
 });
 
 let img = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==";
 var imageBuffer = Uint8Array.from(atob(img), byte => byte.charCodeAt(0)).buffer;
--- a/browser/components/newtab/tests/browser/browser_PreviewProvider.js
+++ b/browser/components/newtab/tests/browser/browser_PreviewProvider.js
@@ -33,26 +33,25 @@ function pixelsForDataURI(dataURI, optio
     if (!height) {
       height = 100;
     }
 
     let htmlns = "http://www.w3.org/1999/xhtml";
     let img = document.createElementNS(htmlns, "img");
     img.setAttribute("src", dataURI);
 
-    img.addEventListener("load", function onLoad() {
-      img.removeEventListener("load", onLoad, true);
+    img.addEventListener("load", function() {
       let canvas = document.createElementNS(htmlns, "canvas");
       canvas.setAttribute("width", width);
       canvas.setAttribute("height", height);
       let ctx = canvas.getContext("2d");
       ctx.drawImage(img, 0, 0, width, height);
       let result = ctx.getImageData(0, 0, width, height).data;
       resolve(result);
-    });
+    }, {once: true});
   });
 }
 
 function* chunk_four(listData) {
   let index = 0;
   while (index < listData.length) {
     yield listData.slice(index, index + 5);
     index += 4;
--- a/browser/components/originattributes/test/browser/head.js
+++ b/browser/components/originattributes/test/browser/head.js
@@ -137,20 +137,19 @@ function* openTabInFirstParty(aURL, aFir
         frameElement = iframe;
       } else {
         ok(false, "Invalid frame type.");
         break;
       }
 
       // Wait for the frame to be loaded.
       yield new Promise(done => {
-        frameElement.addEventListener("load", function loadEnd() {
-          frameElement.removeEventListener("load", loadEnd, true);
+        frameElement.addEventListener("load", function() {
           done();
-        }, true);
+        }, {capture: true, once: true});
 
         // If it is the deepest layer, we load the target URL. Otherwise, we
         // load a basic page.
         if (numOfLayers === arg.frames.length) {
           frameElement.setAttribute("src", arg.url);
         } else {
           frameElement.setAttribute("src", arg.basicFrameSrc);
         }
--- a/browser/components/places/tests/browser/browser_555547.js
+++ b/browser/components/places/tests/browser/browser_555547.js
@@ -51,16 +51,15 @@ add_task(function* test() {
   if (wasCollapsed) {
     yield promiseSetToolbarVisibility(toolbar, false);
   }
 });
 
 function promiseLoadedSidebar(cmd) {
   return new Promise(resolve => {
     let sidebar = document.getElementById("sidebar");
-    sidebar.addEventListener("load", function onLoad() {
-      sidebar.removeEventListener("load", onLoad, true);
+    sidebar.addEventListener("load", function() {
       resolve(sidebar);
-    }, true);
+    }, {capture: true, once: true});
 
     SidebarUI.show(cmd);
   });
 }
--- a/browser/components/places/tests/browser/browser_bookmarksProperties.js
+++ b/browser/components/places/tests/browser/browser_bookmarksProperties.js
@@ -83,23 +83,22 @@ gTests.push({
   },
 
   run() {
     // open tags autocomplete and press enter
     var tagsField = this.window.document.getElementById("editBMPanel_tagsField");
     var self = this;
 
     this.window.addEventListener("unload", function(event) {
-      self.window.removeEventListener("unload", arguments.callee, true);
       tagsField.popup.removeEventListener("popuphidden", popupListener, true);
       ok(self._cleanShutdown, "Dialog window should not be closed by pressing Enter on the autocomplete popup");
       executeSoon(function() {
         self.finish();
       });
-    }, true);
+    }, {capture: true, once: true});
 
     var popupListener = {
       handleEvent(aEvent) {
         switch (aEvent.type) {
           case "popuphidden":
             // Everything worked fine, we can stop observing the window.
             self._cleanShutdown = true;
             self.window.document.documentElement.cancelDialog();
@@ -184,23 +183,22 @@ gTests.push({
   },
 
   run() {
     // open tags autocomplete and press enter
     var tagsField = this.window.document.getElementById("editBMPanel_tagsField");
     var self = this;
 
     this.window.addEventListener("unload", function(event) {
-      self.window.removeEventListener("unload", arguments.callee, true);
       tagsField.popup.removeEventListener("popuphidden", popupListener, true);
       ok(self._cleanShutdown, "Dialog window should not be closed by pressing Escape on the autocomplete popup");
       executeSoon(function() {
         self.finish();
       });
-    }, true);
+    }, {capture: true, once: true});
 
     var popupListener = {
       handleEvent(aEvent) {
         switch (aEvent.type) {
           case "popuphidden":
             // Everything worked fine.
             self._cleanShutdown = true;
             self.window.document.documentElement.cancelDialog();
@@ -279,22 +277,21 @@ gTests.push({
 
   run() {
     // Open folder selector.
     var foldersExpander = this.window.document.getElementById("editBMPanel_foldersExpander");
     var folderTree = this.window.document.getElementById("editBMPanel_folderTree");
     var self = this;
 
     this.window.addEventListener("unload", function(event) {
-      self.window.removeEventListener("unload", arguments.callee, true);
       ok(self._cleanShutdown, "Dialog window should not be closed by pressing ESC in folder name textbox");
       executeSoon(function() {
         self.finish();
       });
-    }, true);
+    }, {capture: true, once: true});
 
     folderTree.addEventListener("DOMAttrModified", function onDOMAttrModified(event) {
       if (event.attrName != "place")
         return;
       folderTree.removeEventListener("DOMAttrModified", arguments.callee);
       executeSoon(function() {
         // Create a new folder.
         var newFolderButton = self.window.document.getElementById("editBMPanel_newFolderButton");
@@ -365,20 +362,19 @@ function runNextTest() {
 
 /**
  * Global functions to run a test in Properties dialog context.
  */
 
 function execute_test_in_sidebar() {
     var sidebar = document.getElementById("sidebar");
     sidebar.addEventListener("load", function() {
-      sidebar.removeEventListener("load", arguments.callee, true);
       // Need to executeSoon since the tree is initialized on sidebar load.
       executeSoon(open_properties_dialog);
-    }, true);
+    }, {capture: true, once: true});
     SidebarUI.show(gCurrentTest.sidebar);
 }
 
 function open_properties_dialog() {
     var sidebar = document.getElementById("sidebar");
 
     // If this is history sidebar, set the required view.
     if (gCurrentTest.sidebar == SIDEBAR_HISTORY_ID)
--- a/browser/components/places/tests/browser/browser_forgetthissite_single.js
+++ b/browser/components/places/tests/browser/browser_forgetthissite_single.js
@@ -65,14 +65,13 @@ var testForgetThisSiteVisibility = Task.
   contextmenu.hidePopup();
 
   // Close the library window.
   yield promiseLibraryClosed(organizer);
 });
 
 function promisePopupShown(popup) {
   return new Promise(resolve => {
-    popup.addEventListener("popupshown", function onShown() {
-      popup.removeEventListener("popupshown", onShown, true);
+    popup.addEventListener("popupshown", function() {
       resolve();
-    }, true);
+    }, {capture: true, once: true});
   });
 }
--- a/browser/components/places/tests/browser/browser_sidebarpanels_click.js
+++ b/browser/components/places/tests/browser/browser_sidebarpanels_click.js
@@ -75,17 +75,16 @@ function test() {
   });
 
   function testPlacesPanel(preFunc, postFunc) {
     currentTest.init(function() {
       SidebarUI.show(currentTest.sidebarName);
     });
 
     sidebar.addEventListener("load", function() {
-      sidebar.removeEventListener("load", arguments.callee, true);
       executeSoon(function() {
         currentTest.prepare();
 
         if (preFunc)
           preFunc();
 
         function observer(aSubject, aTopic, aData) {
           info("alert dialog observed as expected");
@@ -110,17 +109,17 @@ function test() {
         synthesizeClickOnSelectedTreeCell(tree);
         // Now, wait for the observer to catch the alert dialog.
         // If something goes wrong, the test will time out at this stage.
         // Note that for the history sidebar, the URL itself is not opened,
         // and Places will show the load-js-data-url-error prompt as an alert
         // box, which means that the click actually worked, so it's good enough
         // for the purpose of this test.
       });
-    }, true);
+    }, {capture: true, once: true});
   }
 
   function changeSidebarDirection(aDirection) {
     sidebar.contentDocument.documentElement.style.direction = aDirection;
   }
 
   function runNextTest() {
     // Remove eventual tabs created by previous sub-tests.
--- a/browser/components/places/tests/browser/browser_views_liveupdate.js
+++ b/browser/components/places/tests/browser/browser_views_liveupdate.js
@@ -28,20 +28,19 @@ function openBookmarksSidebar() {
   // Open bookmarks menu.
   var popup = document.getElementById("bookmarksMenuPopup");
   ok(popup, "Menu popup element exists");
   fakeOpenPopup(popup);
 
   // Open bookmarks sidebar.
   var sidebar = document.getElementById("sidebar");
   sidebar.addEventListener("load", function() {
-    sidebar.removeEventListener("load", arguments.callee, true);
     // Need to executeSoon since the tree is initialized on sidebar load.
     executeSoon(startTest);
-  }, true);
+  }, {capture: true, once: true});
   SidebarUI.show("viewBookmarksSidebar");
 }
 
 /**
  * Simulates popup opening causing it to populate.
  * We cannot just use menu.open, since it would not work on Mac due to native menubar.
  */
 function fakeOpenPopup(aPopup) {
--- a/browser/components/places/tests/browser/head.js
+++ b/browser/components/places/tests/browser/head.js
@@ -55,20 +55,19 @@ function promiseLibrary(aLeftPaneRoot) {
       openLibrary(resolve, aLeftPaneRoot);
     }
   });
 }
 
 function promiseLibraryClosed(organizer) {
   return new Promise(resolve => {
     // Wait for the Organizer window to actually be closed
-    organizer.addEventListener("unload", function onUnload() {
-      organizer.removeEventListener("unload", onUnload);
+    organizer.addEventListener("unload", function() {
       resolve();
-    });
+    }, {once: true});
 
     // Close Library window.
     organizer.close();
   });
 }
 
 /**
  * Waits for a clipboard operation to complete, looking for the expected type.
@@ -281,25 +280,24 @@ function isToolbarVisible(aToolbar) {
  *        the task to execute once the dialog is open
  */
 var withBookmarksDialog = Task.async(function* (autoCancel, openFn, taskFn) {
   let closed = false;
   let dialogPromise = new Promise(resolve => {
     Services.ww.registerNotification(function winObserver(subject, topic, data) {
       if (topic == "domwindowopened") {
         let win = subject.QueryInterface(Ci.nsIDOMWindow);
-        win.addEventListener("load", function load() {
-          win.removeEventListener("load", load);
+        win.addEventListener("load", function() {
           ok(win.location.href.startsWith("chrome://browser/content/places/bookmarkProperties"),
              "The bookmark properties dialog is open");
           // This is needed for the overlay.
           waitForFocus(() => {
             resolve(win);
           }, win);
-        });
+        }, {once: true});
       } else if (topic == "domwindowclosed") {
         Services.ww.unregisterNotification(winObserver);
         closed = true;
       }
     });
   });
 
   info("withBookmarksDialog: opening the dialog");
@@ -433,20 +431,19 @@ function fillBookmarkTextField(id, text,
  * @param taskFn
  *        The task to execute once the sidebar is ready. Will get the Places
  *        tree view as input.
  */
 var withSidebarTree = Task.async(function* (type, taskFn) {
   let sidebar = document.getElementById("sidebar");
   info("withSidebarTree: waiting sidebar load");
   let sidebarLoadedPromise = new Promise(resolve => {
-    sidebar.addEventListener("load", function load() {
-      sidebar.removeEventListener("load", load, true);
+    sidebar.addEventListener("load", function() {
       resolve();
-    }, true);
+    }, {capture: true, once: true});
   });
   let sidebarId = type == "bookmarks" ? "viewBookmarksSidebar"
                                       : "viewHistorySidebar";
   SidebarUI.show(sidebarId);
   yield sidebarLoadedPromise;
 
   let treeId = type == "bookmarks" ? "bookmarks-view"
                                    : "historyTree";
--- a/browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js
+++ b/browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js
@@ -23,21 +23,19 @@ add_task(function*() {
   is(prefs.selectedPane, "paneGeneral", "General pane is selected by default");
 });
 
 function openPreferencesViaHash(aPane) {
   let deferred = Promise.defer();
   gBrowser.selectedTab = gBrowser.addTab("about:preferences" + (aPane ? "#" + aPane : ""));
   let newTabBrowser = gBrowser.selectedBrowser;
 
-  newTabBrowser.addEventListener("Initialized", function PrefInit() {
-    newTabBrowser.removeEventListener("Initialized", PrefInit, true);
-    newTabBrowser.contentWindow.addEventListener("load", function prefLoad() {
-      newTabBrowser.contentWindow.removeEventListener("load", prefLoad);
+  newTabBrowser.addEventListener("Initialized", function() {
+    newTabBrowser.contentWindow.addEventListener("load", function() {
       let win = gBrowser.contentWindow;
       let selectedPane = win.history.state;
       gBrowser.removeCurrentTab();
       deferred.resolve({selectedPane});
-    });
-  }, true);
+    }, {once: true});
+  }, {capture: true, once: true});
 
   return deferred.promise;
 }
--- a/browser/components/preferences/in-content/tests/head.js
+++ b/browser/components/preferences/in-content/tests/head.js
@@ -28,19 +28,18 @@ function is_element_hidden(aElement, aMs
   isnot(aElement, null, "Element should not be null, when checking visibility");
   ok(is_hidden(aElement), aMsg);
 }
 
 function open_preferences(aCallback) {
   gBrowser.selectedTab = gBrowser.addTab("about:preferences");
   let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
   newTabBrowser.addEventListener("Initialized", function() {
-    newTabBrowser.removeEventListener("Initialized", arguments.callee, true);
     aCallback(gBrowser.contentWindow);
-  }, true);
+  }, {capture: true, once: true});
 }
 
 function openAndLoadSubDialog(aURL, aFeatures = null, aParams = null, aClosingCallback = null) {
   let promise = promiseLoadSubDialog(aURL);
   content.gSubDialog.open(aURL, aFeatures, aParams, aClosingCallback);
   return promise;
 }
 
@@ -121,29 +120,27 @@ function waitForEvent(aSubject, aEventNa
 }
 
 function openPreferencesViaOpenPreferencesAPI(aPane, aAdvancedTab, aOptions) {
   let deferred = Promise.defer();
   gBrowser.selectedTab = gBrowser.addTab("about:blank");
   openPreferences(aPane, aAdvancedTab ? {advancedTab: aAdvancedTab} : undefined);
   let newTabBrowser = gBrowser.selectedBrowser;
 
-  newTabBrowser.addEventListener("Initialized", function PrefInit() {
-    newTabBrowser.removeEventListener("Initialized", PrefInit, true);
-    newTabBrowser.contentWindow.addEventListener("load", function prefLoad() {
-      newTabBrowser.contentWindow.removeEventListener("load", prefLoad);
+  newTabBrowser.addEventListener("Initialized", function() {
+    newTabBrowser.contentWindow.addEventListener("load", function() {
       let win = gBrowser.contentWindow;
       let selectedPane = win.history.state;
       let doc = win.document;
       let selectedAdvancedTab = aAdvancedTab && doc.getElementById("advancedPrefs").selectedTab.id;
       if (!aOptions || !aOptions.leaveOpen)
         gBrowser.removeCurrentTab();
       deferred.resolve({selectedPane, selectedAdvancedTab});
-    });
-  }, true);
+    }, {once: true});
+  }, {capture: true, once: true});
 
   return deferred.promise;
 }
 
 function waitForCondition(aConditionFn, aMaxTries = 50, aCheckInterval = 100) {
   return new Promise((resolve, reject) => {
     function tryNow() {
       tries++;
@@ -163,21 +160,20 @@ function waitForCondition(aConditionFn, 
     tryAgain();
   });
 }
 
 function promiseAlertDialogOpen(buttonAction) {
   return new Promise(resolve => {
     Services.ww.registerNotification(function onOpen(subj, topic, data) {
       if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) {
-        subj.addEventListener("load", function onLoad() {
-          subj.removeEventListener("load", onLoad);
+        subj.addEventListener("load", function() {
           if (subj.document.documentURI == "chrome://global/content/commonDialog.xul") {
             Services.ww.unregisterNotification(onOpen);
             let doc = subj.document.documentElement;
             doc.getButton(buttonAction).click();
             resolve();
           }
-        });
+        }, {once: true});
       }
     });
   });
 }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cache.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cache.js
@@ -109,30 +109,28 @@ function get_cache_for_private_window ()
     executeSoon(function() {
 
       ok(true, "The private window got loaded");
 
       let tab = win.gBrowser.addTab("http://example.org");
       win.gBrowser.selectedTab = tab;
       let newTabBrowser = win.gBrowser.getBrowserForTab(tab);
 
-      newTabBrowser.addEventListener("load", function eventHandler() {
-        newTabBrowser.removeEventListener("load", eventHandler, true);
-
+      newTabBrowser.addEventListener("load", function() {
         executeSoon(function() {
 
           getStorageEntryCount("private", function(nrEntriesP) {
             ok(nrEntriesP >= 1, "Memory cache reports some entries from example.org domain");
 
             getStorageEntryCount("regular", function(nrEntriesR2) {
               is(nrEntriesR2, 0, "Disk cache reports 0KB and has no entries");
 
               cleanup();
 
               win.close();
               finish();
             });
           });
         });
-      }, true);
+      }, {capture: true, once: true});
     });
   });
 }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
@@ -9,20 +9,19 @@
 function test() {
   const EXCEPTIONS_DLG_URL = 'chrome://pippki/content/exceptionDialog.xul';
   const EXCEPTIONS_DLG_FEATURES = 'chrome,centerscreen';
   const INVALID_CERT_LOCATION = 'https://nocert.example.com/';
   waitForExplicitFinish();
 
   // open a private browsing window
   var pbWin = OpenBrowserWindow({private: true});
-  pbWin.addEventListener("load", function onLoad() {
-    pbWin.removeEventListener("load", onLoad);
+  pbWin.addEventListener("load", function() {
     doTest();
-  });
+  }, {once: true});
 
   // Test the certificate exceptions dialog
   function doTest() {
     let params = {
       exceptionAdded : false,
       location: INVALID_CERT_LOCATION,
       prefetchCert: true,
     };
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_opendir.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_opendir.js
@@ -3,21 +3,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This test makes sure that the last open directory used inside the private
 // browsing mode is not remembered after leaving that mode.
 
 var windowsToClose = [];
 function testOnWindow(options, callback) {
   var win = OpenBrowserWindow(options);
-  win.addEventListener("load", function onLoad() {
-    win.removeEventListener("load", onLoad);
+  win.addEventListener("load", function() {
     windowsToClose.push(win);
     callback(win);
-  });
+  }, {once: true});
 }
 
 registerCleanupFunction(function() {
   windowsToClose.forEach(function(win) {
     win.close();
   });
 });
 
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js
@@ -11,18 +11,16 @@ add_task(function* test() {
 
   registerCleanupFunction(() => {
     gPrefService.setBoolPref("dom.disable_open_during_load", oldPopupPolicy);
   });
 
   function testPopupBlockerMenuItem(aExpectedDisabled, aWindow, aCallback) {
 
     aWindow.gBrowser.addEventListener("DOMUpdatePageReport", function() {
-      aWindow.gBrowser.removeEventListener("DOMUpdatePageReport", arguments.callee);
-
       executeSoon(function() {
         let notification = aWindow.gBrowser.getNotificationBox().getNotificationWithValue("popup-blocked");
         ok(notification, "The notification box should be displayed");
 
         function checkMenuItem(callback) {
           dump("CMI: in\n");
           aWindow.document.addEventListener("popupshown", function(event) {
             dump("CMI: popupshown\n");
@@ -41,17 +39,17 @@ add_task(function* test() {
         }
 
         checkMenuItem(function() {
           aCallback();
         });
         notification.querySelector("button").doCommand();
       });
 
-    });
+    }, {once: true});
 
     aWindow.gBrowser.selectedBrowser.loadURI(testURI);
   }
 
   let win1 = yield BrowserTestUtils.openNewBrowserWindow();
   yield new Promise(resolve => waitForFocus(resolve, win1));
   yield new Promise(resolve => testPopupBlockerMenuItem(false, win1, resolve));
 
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_theming.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_theming.js
@@ -3,21 +3,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This test makes sure that privatebrowsingmode attribute of the window is correctly
 // adjusted based on whether the window is a private window.
 
 var windowsToClose = [];
 function testOnWindow(options, callback) {
   var win = OpenBrowserWindow(options);
-  win.addEventListener("load", function onLoad() {
-    win.removeEventListener("load", onLoad);
+  win.addEventListener("load", function() {
     windowsToClose.push(win);
     executeSoon(() => callback(win));
-  });
+  }, {once: true});
 }
 
 registerCleanupFunction(function() {
   windowsToClose.forEach(function(win) {
     win.close();
   });
 });
 
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
@@ -9,47 +9,44 @@ function test() {
   // initialization
   waitForExplicitFinish();
   let windowsToClose = [];
   let testURI = "about:blank";
   let pbMenuItem;
   let cmd;
 
   function doTest(aIsPrivateMode, aWindow, aCallback) {
-    aWindow.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
-      aWindow.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
-
+    aWindow.gBrowser.selectedBrowser.addEventListener("load", function() {
       ok(aWindow.gPrivateBrowsingUI, "The gPrivateBrowsingUI object exists");
 
       pbMenuItem = aWindow.document.getElementById("menu_newPrivateWindow");
       ok(pbMenuItem, "The Private Browsing menu item exists");
 
       cmd = aWindow.document.getElementById("Tools:PrivateBrowsing");
       isnot(cmd, null, "XUL command object for the private browsing service exists");
 
       is(pbMenuItem.getAttribute("label"), "New Private Window",
         "The Private Browsing menu item should read \"New Private Window\"");
       is(PrivateBrowsingUtils.isWindowPrivate(aWindow), aIsPrivateMode,
         "PrivateBrowsingUtils should report the correct per-window private browsing status (privateBrowsing should be " +
         aIsPrivateMode + ")");
 
       aCallback();
-    }, true);
+    }, {capture: true, once: true});
 
     aWindow.gBrowser.selectedBrowser.loadURI(testURI);
   };
 
   function openPrivateBrowsingModeByUI(aWindow, aCallback) {
     Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
       aSubject.addEventListener("load", function() {
-        aSubject.removeEventListener("load", arguments.callee);
-          Services.obs.removeObserver(observer, "domwindowopened");
+        Services.obs.removeObserver(observer, "domwindowopened");
           windowsToClose.push(aSubject);
           aCallback(aSubject);
-      });
+      }, {once: true});
     }, "domwindowopened", false);
 
     cmd = aWindow.document.getElementById("Tools:PrivateBrowsing");
     var func = new Function("", cmd.getAttribute("oncommand"));
     func.call(cmd);
   };
 
   function testOnWindow(aOptions, aCallback) {
--- a/browser/components/privatebrowsing/test/browser/head.js
+++ b/browser/components/privatebrowsing/test/browser/head.js
@@ -17,20 +17,19 @@ function whenNewWindowLoaded(aOptions, a
 }
 
 function openWindow(aParent, aOptions, a3) {
   let { Promise: { defer } } = Components.utils.import("resource://gre/modules/Promise.jsm", {});
   let { promise, resolve } = defer();
 
   let win = aParent.OpenBrowserWindow(aOptions);
 
-  win.addEventListener("load", function onLoad() {
-    win.removeEventListener("load", onLoad);
+  win.addEventListener("load", function() {
     resolve(win);
-  });
+  }, {once: true});
 
   return promise;
 }
 
 function newDirectory() {
   let FileUtils =
     Cu.import("resource://gre/modules/FileUtils.jsm", {}).FileUtils;
   let tmpDir = FileUtils.getDir("TmpD", [], true);
--- a/browser/components/search/test/browser_abouthome_behavior.js
+++ b/browser/components/search/test/browser_abouthome_behavior.js
@@ -131,14 +131,13 @@ function test() {
   registerCleanupFunction(function() {
     Services.search.currentEngine = previouslySelectedEngine;
     gBrowser.removeProgressListener(listener);
     gBrowser.removeTab(tab);
     if (gMutationObserver)
       gMutationObserver.disconnect();
   });
 
-  tab.linkedBrowser.addEventListener("load", function load() {
-    tab.linkedBrowser.removeEventListener("load", load, true);
+  tab.linkedBrowser.addEventListener("load", function() {
     gBrowser.addProgressListener(listener);
     nextTest();
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/components/search/test/browser_amazon_behavior.js
+++ b/browser/components/search/test/browser_amazon_behavior.js
@@ -152,14 +152,13 @@ function test() {
 
   registerCleanupFunction(function() {
     engine.alias = undefined;
     gBrowser.removeProgressListener(listener);
     gBrowser.removeTab(tab);
     Services.search.currentEngine = previouslySelectedEngine;
   });
 
-  tab.linkedBrowser.addEventListener("load", function load() {
-    tab.linkedBrowser.removeEventListener("load", load, true);
+  tab.linkedBrowser.addEventListener("load", function() {
     gBrowser.addProgressListener(listener);
     nextTest();
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/components/search/test/browser_bing_behavior.js
+++ b/browser/components/search/test/browser_bing_behavior.js
@@ -152,14 +152,13 @@ function test() {
 
   registerCleanupFunction(function() {
     engine.alias = undefined;
     gBrowser.removeProgressListener(listener);
     gBrowser.removeTab(tab);
     Services.search.currentEngine = previouslySelectedEngine;
   });
 
-  tab.linkedBrowser.addEventListener("load", function load() {
-    tab.linkedBrowser.removeEventListener("load", load, true);
+  tab.linkedBrowser.addEventListener("load", function() {
     gBrowser.addProgressListener(listener);
     nextTest();
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/components/search/test/browser_contextmenu.js
+++ b/browser/components/search/test/browser_contextmenu.js
@@ -54,20 +54,19 @@ add_task(function* () {
 
   contextMenu = document.getElementById("contentAreaContextMenu");
   ok(contextMenu, "Got context menu XUL");
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "data:text/plain;charset=utf8,test%20search");
 
   yield ContentTask.spawn(tab.linkedBrowser, "", function*() {
     return new Promise(resolve => {
-      content.document.addEventListener("selectionchange", function selectionChanged() {
-        content.document.removeEventListener("selectionchange", selectionChanged);
+      content.document.addEventListener("selectionchange", function() {
         resolve();
-      });
+      }, {once: true});
       content.document.getSelection().selectAllChildren(content.document.body);
     });
   });
 
   var eventDetails = { type: "contextmenu", button: 2 };
 
   let popupPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
   BrowserTestUtils.synthesizeMouseAtCenter("body", eventDetails, gBrowser.selectedBrowser);
--- a/browser/components/search/test/browser_ddg_behavior.js
+++ b/browser/components/search/test/browser_ddg_behavior.js
@@ -152,14 +152,13 @@ function test() {
 
   registerCleanupFunction(function() {
     engine.alias = undefined;
     gBrowser.removeProgressListener(listener);
     gBrowser.removeTab(tab);
     Services.search.currentEngine = previouslySelectedEngine;
   });
 
-  tab.linkedBrowser.addEventListener("load", function load() {
-    tab.linkedBrowser.removeEventListener("load", load, true);
+  tab.linkedBrowser.addEventListener("load", function() {
     gBrowser.addProgressListener(listener);
     nextTest();
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/components/search/test/browser_google_behavior.js
+++ b/browser/components/search/test/browser_google_behavior.js
@@ -150,14 +150,13 @@ function test() {
 
   registerCleanupFunction(function() {
     engine.alias = undefined;
     gBrowser.removeProgressListener(listener);
     gBrowser.removeTab(tab);
     Services.search.currentEngine = previouslySelectedEngine;
   });
 
-  tab.linkedBrowser.addEventListener("load", function load() {
-    tab.linkedBrowser.removeEventListener("load", load, true);
+  tab.linkedBrowser.addEventListener("load", function() {
     gBrowser.addProgressListener(listener);
     nextTest();
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/components/search/test/browser_yahoo_behavior.js
+++ b/browser/components/search/test/browser_yahoo_behavior.js
@@ -152,14 +152,13 @@ function test() {
 
   registerCleanupFunction(function() {
     engine.alias = undefined;
     gBrowser.removeProgressListener(listener);
     gBrowser.removeTab(tab);
     Services.search.currentEngine = previouslySelectedEngine;
   });
 
-  tab.linkedBrowser.addEventListener("load", function load() {
-    tab.linkedBrowser.removeEventListener("load", load, true);
+  tab.linkedBrowser.addEventListener("load", function() {
     gBrowser.addProgressListener(listener);
     nextTest();
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/components/sessionstore/test/browser_464620_b.html
+++ b/browser/components/sessionstore/test/browser_464620_b.html
@@ -24,19 +24,18 @@
 
   function step() {
     frames[0].document.designMode = "on";
     if (firstPass)
       return;
 
     var body = frames[0].document.body;
     body.addEventListener("DOMNodeInserted", function() {
-      body.removeEventListener("DOMNodeInserted", arguments.callee, true);
       xss();
-    }, true);
+    }, {capture: true, once: true});
   }
 
   function xss() {
     var documentInjected = false;
     document.getElementsByTagName("iframe")[1].onload =
       function() { documentInjected = true; };
     frames[1].location = targetUrl;
 
--- a/browser/components/sessionstore/test/browser_466937_sample.html
+++ b/browser/components/sessionstore/test/browser_466937_sample.html
@@ -5,18 +5,17 @@
 <title>Test for bug 466937</title>
 
 <input id="thief" value="/home/user/secret">
 <input type="file" id="reverse_thief">
 <input type="file" id="bystander">
 
 <script>
   window.addEventListener("DOMContentLoaded", function() {
-    window.removeEventListener("DOMContentLoaded", arguments.callee);
     if (!document.location.hash) {
       document.location.hash = "#ready";
     }
     else {
       document.getElementById("thief").type = "file";
       document.getElementById("reverse_thief").type = "text";
     }
-  });
+  }, {once: true});
 </script>
--- a/browser/components/sessionstore/test/browser_514751.js
+++ b/browser/components/sessionstore/test/browser_514751.js
@@ -15,24 +15,22 @@ function test() {
           {}
         ]
       }]
     }]
   };
 
   var theWin = openDialog(location, "", "chrome,all,dialog=no");
   theWin.addEventListener("load", function () {
-    theWin.removeEventListener("load", arguments.callee);
-
     executeSoon(function () {
       var gotError = false;
       try {
         ss.setWindowState(theWin, JSON.stringify(state), true);
       } catch (e) {
         if (/NS_ERROR_MALFORMED_URI/.test(e))
           gotError = true;
       }
       ok(!gotError, "Didn't get a malformed URI error.");
       BrowserTestUtils.closeWindow(theWin).then(finish);
     });
-  });
+  }, {once: true});
 }
 
--- a/browser/components/sessionstore/test/browser_580512.js
+++ b/browser/components/sessionstore/test/browser_580512.js
@@ -51,17 +51,16 @@ function checkSecondWin(win) {
 function openWinWithCb(cb, argURIs, expectedURIs) {
   if (!expectedURIs)
     expectedURIs = argURIs;
 
   var win = openDialog(getBrowserURL(), "_blank",
                        "chrome,all,dialog=no", argURIs.join("|"));
 
   win.addEventListener("load", function () {
-    win.removeEventListener("load", arguments.callee);
     info("the window loaded");
 
     var expectedLoads = expectedURIs.length;
 
     win.gBrowser.addTabsProgressListener({
       onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
         if (aRequest &&
             aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
@@ -72,10 +71,10 @@ function openWinWithCb(cb, argURIs, expe
           info("all tabs loaded");
           is(win.gBrowser.tabs.length, expectedURIs.length, "didn't load any unexpected tabs");
           executeSoon(function () {
             cb(win);
           });
         }
       }
     });
-  });
+  }, {once: true});
 }
--- a/browser/components/sessionstore/test/browser_586068-browser_state_interrupted.js
+++ b/browser/components/sessionstore/test/browser_586068-browser_state_interrupted.js
@@ -90,21 +90,20 @@ add_task(function* test() {
       resolve();
     });
   });
 
   // We also want to catch the extra windows (there should be 2), so we need to observe domwindowopened
   Services.ww.registerNotification(function observer(aSubject, aTopic, aData) {
     if (aTopic == "domwindowopened") {
       let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      win.addEventListener("load", function onLoad() {
-        win.removeEventListener("load", onLoad);
+      win.addEventListener("load", function() {
         Services.ww.unregisterNotification(observer);
         win.gBrowser.addTabsProgressListener(gProgressListener);
-      });
+      }, {once: true});
     }
   });
 
   let backupState = ss.getBrowserState();
   ss.setBrowserState(JSON.stringify(state1));
   yield promiseRestoringTabs;
 
   // Cleanup.
--- a/browser/components/sessionstore/test/browser_586068-multi_window.js
+++ b/browser/components/sessionstore/test/browser_586068-multi_window.js
@@ -47,21 +47,20 @@ add_task(function* test() {
       }
     });
   });
 
   // We also want to catch the 2nd window, so we need to observe domwindowopened
   Services.ww.registerNotification(function observer(aSubject, aTopic, aData) {
     if (aTopic == "domwindowopened") {
       let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      win.addEventListener("load", function onLoad() {
-        win.removeEventListener("load", onLoad);
+      win.addEventListener("load", function() {
         Services.ww.unregisterNotification(observer);
         win.gBrowser.addTabsProgressListener(gProgressListener);
-      });
+      }, {once: true});
     }
   });
 
   let backupState = ss.getBrowserState();
   ss.setBrowserState(JSON.stringify(state));
   yield promiseRestoringTabs;
 
   // Cleanup.
--- a/browser/components/sessionstore/test/browser_588426.js
+++ b/browser/components/sessionstore/test/browser_588426.js
@@ -21,21 +21,18 @@ function test() {
     finish();
   });
 }
 
 function newWindowWithState(state, callback) {
   let opts = "chrome,all,dialog=no,height=800,width=800";
   let win = window.openDialog(getBrowserURL(), "_blank", opts);
 
-  win.addEventListener("load", function onLoad() {
-    win.removeEventListener("load", onLoad);
-
+  win.addEventListener("load", function() {
     executeSoon(function () {
-      win.addEventListener("SSWindowStateReady", function onReady() {
-        win.removeEventListener("SSWindowStateReady", onReady);
+      win.addEventListener("SSWindowStateReady", function() {
         promiseTabRestored(win.gBrowser.tabs[0]).then(() => callback(win));
-      });
+      }, {once: true});
 
       ss.setWindowState(win, JSON.stringify(state), true);
     });
-  });
+  }, {once: true});
 }
--- a/browser/components/sessionstore/test/browser_589246.js
+++ b/browser/components/sessionstore/test/browser_589246.js
@@ -156,52 +156,47 @@ function onStateRestored(aSubject, aTopi
   Services.obs.removeObserver(onStateRestored, "sessionstore-browser-state-restored");
 
   // change this window's windowtype so that closing a new window will trigger
   // browser-lastwindow-close-granted.
   document.documentElement.setAttribute("windowtype", "navigator:testrunner");
 
   let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "http://example.com");
   newWin.addEventListener("load", function(aEvent) {
-    newWin.removeEventListener("load", arguments.callee);
-
     promiseBrowserLoaded(newWin.gBrowser.selectedBrowser).then(() => {
       // pin this tab
       if (shouldPinTab)
         newWin.gBrowser.pinTab(newWin.gBrowser.selectedTab);
 
       newWin.addEventListener("unload", function () {
-        newWin.removeEventListener("unload", arguments.callee);
         onWindowUnloaded();
-      });
+      }, {once: true});
       // Open a new tab as well. On Windows/Linux this will be restored when the
       // new window is opened below (in onWindowUnloaded). On OS X we'll just
       // restore the pinned tabs, leaving the unpinned tab in the closedWindowsData.
       if (shouldOpenTabs) {
         let newTab = newWin.gBrowser.addTab("about:config");
         let newTab2 = newWin.gBrowser.addTab("about:buildconfig");
 
         newTab.linkedBrowser.addEventListener("load", function() {
-          newTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-
           if (shouldCloseTab == "one") {
             newWin.gBrowser.removeTab(newTab2);
           }
           else if (shouldCloseTab == "both") {
             newWin.gBrowser.removeTab(newTab);
             newWin.gBrowser.removeTab(newTab2);
           }
           newWin.BrowserTryToCloseWindow();
-        }, true);
+        }, {capture: true, once: true});
       }
       else {
         newWin.BrowserTryToCloseWindow();
       }
     });
-  });
+  }, {once: true});
 }
 
 // This will be called before the window is actually closed
 function onLastWindowClosed(aSubject, aTopic, aData) {
   info("test #" + testNum + ": onLastWindowClosed");
   Services.obs.removeObserver(onLastWindowClosed, "browser-lastwindow-close-granted");
   gotLastWindowClosedTopic = true;
 }
@@ -214,27 +209,23 @@ function onWindowUnloaded() {
   info("test #" + testNum + ": onWindowClosed");
   ok(gotLastWindowClosedTopic, "test #" + testNum + ": browser-lastwindow-close-granted was notified prior");
 
   let previousClosedWindowData = ss.getClosedWindowData();
 
   // Now we want to open a new window
   let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:mozilla");
   newWin.addEventListener("load", function(aEvent) {
-    newWin.removeEventListener("load", arguments.callee);
-
     newWin.gBrowser.selectedBrowser.addEventListener("load", function () {
-      newWin.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
-
       // Good enough for checking the state
       afterTestCallback(previousClosedWindowData, ss.getClosedWindowData());
       afterTestCleanup(newWin);
-    }, true);
+    }, {capture: true, once: true});
 
-  });
+  }, {once: true});
 }
 
 function afterTestCleanup(aNewWin) {
   executeSoon(function() {
     BrowserTestUtils.closeWindow(aNewWin).then(() => {
       document.documentElement.setAttribute("windowtype", originalWindowType);
       runNextTestOrFinish();
     });
--- a/browser/components/sessionstore/test/browser_590563.js
+++ b/browser/components/sessionstore/test/browser_590563.js
@@ -50,25 +50,22 @@ function middleClickTest(win) {
   is(win.gBrowser.visibleTabs.length, 3,
      "The total number of visible tabs should be 3 after restoring 2 tabs by middle click");
 }
 
 function newWindowWithState(state, callback) {
   let opts = "chrome,all,dialog=no,height=800,width=800";
   let win = window.openDialog(getBrowserURL(), "_blank", opts);
 
-  win.addEventListener("load", function onLoad() {
-    win.removeEventListener("load", onLoad);
-
+  win.addEventListener("load", function() {
     let tab = win.gBrowser.selectedTab;
 
     // The form data will be restored before SSTabRestored, so we want to listen
     // for that on the currently selected tab (it will be reused)
-    tab.addEventListener("SSTabRestored", function onRestored() {
-      tab.removeEventListener("SSTabRestored", onRestored, true);
+    tab.addEventListener("SSTabRestored", function() {
       callback(win);
-    }, true);
+    }, {capture: true, once: true});
 
     executeSoon(function () {
       ss.setWindowState(win, JSON.stringify(state), true);
     });
-  });
+  }, {once: true});
 }
--- a/browser/components/sessionstore/test/browser_615394-SSWindowState_events.js
+++ b/browser/components/sessionstore/test/browser_615394-SSWindowState_events.js
@@ -256,25 +256,23 @@ function test_setBrowserState() {
 
   // waitForBrowserState does it's own observing for windows, but doesn't attach
   // the listeners we want here, so do it ourselves.
   let newWindow;
   function windowObserver(aSubject, aTopic, aData) {
     if (aTopic == "domwindowopened") {
       newWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
       newWindow.addEventListener("load", function() {
-        newWindow.removeEventListener("load", arguments.callee);
-
         Services.ww.unregisterNotification(windowObserver);
 
         windowEvents[getOuterWindowID(newWindow)] = { busyEventCount: 0, readyEventCount: 0 };
 
         newWindow.addEventListener("SSWindowStateBusy", onSSWindowStateBusy);
         newWindow.addEventListener("SSWindowStateReady", onSSWindowStateReady);
-      });
+      }, {once: true});
     }
   }
 
   function onSSWindowStateBusy(aEvent) {
     windowEvents[getOuterWindowID(aEvent.originalTarget)].busyEventCount++;
   }
 
   function onSSWindowStateReady(aEvent) {
@@ -321,20 +319,18 @@ function test_undoCloseWindow() {
     // Close the window which isn't window
     BrowserTestUtils.closeWindow(newWindow).then(() => {
       // Now give it time to close
       reopenedWindow = ss.undoCloseWindow(0);
       reopenedWindow.addEventListener("SSWindowStateBusy", onSSWindowStateBusy);
       reopenedWindow.addEventListener("SSWindowStateReady", onSSWindowStateReady);
 
       reopenedWindow.addEventListener("load", function() {
-        reopenedWindow.removeEventListener("load", arguments.callee);
-
         reopenedWindow.gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored);
-      });
+      }, {once: true});
     });
   });
 
   let busyEventCount = 0,
       readyEventCount = 0,
       tabRestoredCount = 0;
   // These will listen to the reopened closed window...
   function onSSWindowStateBusy(aEvent) {
--- a/browser/components/sessionstore/test/browser_628270.js
+++ b/browser/components/sessionstore/test/browser_628270.js
@@ -40,13 +40,12 @@ function test() {
         gBrowser.removeTab(tab);
         finish();
       });
     });
   });
 }
 
 function whenTabIsLoaded(tab, callback) {
-  tab.linkedBrowser.addEventListener("load", function onLoad() {
-    tab.linkedBrowser.removeEventListener("load", onLoad, true);
+  tab.linkedBrowser.addEventListener("load", function() {
     callback();
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/components/sessionstore/test/browser_636279.js
+++ b/browser/components/sessionstore/test/browser_636279.js
@@ -20,19 +20,17 @@ function test() {
   registerCleanupFunction(function () {
     TabsProgressListener.uninit();
     ss.setBrowserState(stateBackup);
   });
 
 
   TabsProgressListener.init();
 
-  window.addEventListener("SSWindowStateReady", function onReady() {
-    window.removeEventListener("SSWindowStateReady", onReady);
-
+  window.addEventListener("SSWindowStateReady", function() {
     let firstProgress = true;
 
     TabsProgressListener.setCallback(function (needsRestore, isRestoring) {
       if (firstProgress) {
         firstProgress = false;
         is(isRestoring, 3, "restoring 3 tabs concurrently");
       } else {
         ok(isRestoring <= 3, "restoring max. 2 tabs concurrently");
@@ -40,17 +38,17 @@ function test() {
 
       if (0 == needsRestore) {
         TabsProgressListener.unsetCallback();
         waitForFocus(finish);
       }
     });
 
     ss.setBrowserState(JSON.stringify(state));
-  });
+  }, {once: true});
 
   ss.setBrowserState(JSON.stringify(statePinned));
 }
 
 function countTabs() {
   let needsRestore = 0, isRestoring = 0;
   let windowsEnum = Services.wm.getEnumerator("navigator:browser");
 
--- a/browser/components/sessionstore/test/browser_644409-scratchpads.js
+++ b/browser/components/sessionstore/test/browser_644409-scratchpads.js
@@ -33,32 +33,30 @@ function test() {
   Services.ww.registerNotification(windowObserver);
 
   ss.setBrowserState(JSON.stringify(testState));
 }
 
 function windowObserver(aSubject, aTopic, aData) {
   if (aTopic == "domwindowopened") {
     let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-    win.addEventListener("load", function onLoad() {
-      win.removeEventListener("load", onLoad);
-
+    win.addEventListener("load", function() {
       if (win.Scratchpad) {
         win.Scratchpad.addObserver({
           onReady: function() {
             win.Scratchpad.removeObserver(this);
 
             let state = win.Scratchpad.getState();
             BrowserTestUtils.closeWindow(win).then(() => {
               addState(state);
             });
           },
         });
       }
-    });
+    }, {once: true});
   }
 }
 
 function statesMatch(restored, states) {
   return states.every(function(state) {
     return restored.some(function(restoredState) {
       return state.filename == restoredState.filename &&
              state.text == restoredState.text &&
--- a/browser/components/sessionstore/test/browser_659591.js
+++ b/browser/components/sessionstore/test/browser_659591.js
@@ -6,28 +6,26 @@ function test() {
 
   let eventReceived = false;
 
   registerCleanupFunction(function () {
     ok(eventReceived, "SSWindowClosing event received");
   });
 
   newWindow(function (win) {
-    win.addEventListener("SSWindowClosing", function onWindowClosing() {
-      win.removeEventListener("SSWindowClosing", onWindowClosing);
+    win.addEventListener("SSWindowClosing", function() {
       eventReceived = true;
-    });
+    }, {once: true});
 
     BrowserTestUtils.closeWindow(win).then(() => {
       waitForFocus(finish);
     });
   });
 }
 
 function newWindow(callback) {
   let opts = "chrome,all,dialog=no,height=800,width=800";
   let win = window.openDialog(getBrowserURL(), "_blank", opts);
 
-  win.addEventListener("load", function onLoad() {
-    win.removeEventListener("load", onLoad);
+  win.addEventListener("load", function() {
     executeSoon(() => callback(win));
-  });
+  }, {once: true});
 }
--- a/browser/components/sessionstore/test/browser_662812.js
+++ b/browser/components/sessionstore/test/browser_662812.js
@@ -1,36 +1,31 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 function test() {
   waitForExplicitFinish();
 
-  window.addEventListener("SSWindowStateBusy", function onBusy() {
-    window.removeEventListener("SSWindowStateBusy", onBusy);
-
+  window.addEventListener("SSWindowStateBusy", function() {
     let state = JSON.parse(ss.getWindowState(window));
     ok(state.windows[0].busy, "window is busy");
 
-    window.addEventListener("SSWindowStateReady", function onReady() {
-      window.removeEventListener("SSWindowStateReady", onReady);
-
+    window.addEventListener("SSWindowStateReady", function() {
       let state = JSON.parse(ss.getWindowState(window));
       ok(!state.windows[0].busy, "window is not busy");
 
       executeSoon(() => {
         gBrowser.removeTab(gBrowser.tabs[1]);
         finish();
       });
-    });
-  });
+    }, {once: true});
+  }, {once: true});
 
   // create a new tab
   let tab = gBrowser.addTab("about:mozilla");
   let browser = tab.linkedBrowser;
 
   // close and restore it
-  browser.addEventListener("load", function onLoad() {
-    browser.removeEventListener("load", onLoad, true);
+  browser.addEventListener("load", function() {
     gBrowser.removeTab(tab);
     ss.undoCloseTab(window, 0);
-  }, true);
+  }, {capture: true, once: true});
 }
--- a/browser/components/sessionstore/test/browser_grouped_session_store.js
+++ b/browser/components/sessionstore/test/browser_grouped_session_store.js
@@ -39,20 +39,19 @@ add_task(function* () {
     return new Promise(resolve => {
       let locChangeListener = {
         onLocationChange: () => {
           gBrowser.removeProgressListener(locChangeListener);
           resolve();
         },
       };
 
-      browser.addEventListener("BrowserChangedProcess", function bcp(e) {
-        browser.removeEventListener("BrowserChangedProcess", bcp);
+      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].
   yield BrowserTestUtils.withNewTab({ gBrowser, url: URIs[0] }, function* (browser1) {
--- a/browser/components/sessionstore/test/browser_windowRestore_perwindowpb.js
+++ b/browser/components/sessionstore/test/browser_windowRestore_perwindowpb.js
@@ -9,18 +9,17 @@ function test() {
 
   // Purging the list of closed windows
   forgetClosedWindows();
 
   // Load a private window, then close it 
   // and verify it doesn't get remembered for restoring
   whenNewWindowLoaded({private: true}, function (win) {
     info("The private window got loaded");
-    win.addEventListener("SSWindowClosing", function onclosing() {
-      win.removeEventListener("SSWindowClosing", onclosing);
+    win.addEventListener("SSWindowClosing", function() {
       executeSoon(function () {
         is(ss.getClosedWindowCount(), 0,
             "The private window should not have been stored");
       });
-    });
+    }, {once: true});
     BrowserTestUtils.closeWindow(win).then(finish);
   });
 }
--- a/browser/components/sessionstore/test/head.js
+++ b/browser/components/sessionstore/test/head.js
@@ -63,20 +63,19 @@ function provideWindow(aCallback, aURL, 
   let win = openDialog(getBrowserURL(), "", aFeatures || "chrome,all,dialog=no", aURL || "about:blank");
   whenWindowLoaded(win, function onWindowLoaded(aWin) {
     if (!aURL) {
       info("Loaded a blank window.");
       callbackSoon(aWin);
       return;
     }
 
-    aWin.gBrowser.selectedBrowser.addEventListener("load", function selectedBrowserLoadListener() {
-      aWin.gBrowser.selectedBrowser.removeEventListener("load", selectedBrowserLoadListener, true);
+    aWin.gBrowser.selectedBrowser.addEventListener("load", function() {
       callbackSoon(aWin);
-    }, true);
+    }, {capture: true, once: true});
   });
 }
 
 // This assumes that tests will at least have some state/entries
 function waitForBrowserState(aState, aSetStateCallback) {
   if (typeof aState == "string") {
     aState = JSON.parse(aState);
   }
@@ -118,28 +117,26 @@ function waitForBrowserState(aState, aSe
   }
 
   // Used to add our listener to further windows so we can catch SSTabRestored
   // coming from them when creating a multi-window state.
   function windowObserver(aSubject, aTopic, aData) {
     if (aTopic == "domwindowopened") {
       let newWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
       newWindow.addEventListener("load", function() {
-        newWindow.removeEventListener("load", arguments.callee);
-
         if (++windowsOpen == expectedWindows) {
           Services.ww.unregisterNotification(windowObserver);
           windowObserving = false;
         }
 
         // Track this window so we can remove the progress listener later
         windows.push(newWindow);
         // Add the progress listener
         newWindow.gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, true);
-      });
+      }, {once: true});
     }
   }
 
   // We only want to register the notification if we expect more than 1 window
   if (expectedWindows > 1) {
     registerCleanupFunction(function() {
       if (windowObserving) {
         Services.ww.unregisterNotification(windowObserver);
@@ -283,22 +280,21 @@ var promiseForEachSessionRestoreFile = T
   }
 });
 
 function promiseBrowserLoaded(aBrowser, ignoreSubFrames = true, wantLoad = null) {
   return BrowserTestUtils.browserLoaded(aBrowser, !ignoreSubFrames, wantLoad);
 }
 
 function whenWindowLoaded(aWindow, aCallback = next) {
-  aWindow.addEventListener("load", function windowLoadListener(